From e3c9d317b1abe6968db2dd328cb1a61315d6854f Mon Sep 17 00:00:00 2001 From: Mike Goslin Date: Fri, 17 Nov 2000 02:25:09 +0000 Subject: [PATCH] *** empty log message *** --- .../pnmimagetypes/config_pnmimagetypes.cxx | 2 + .../src/pnmimagetypes/config_pnmimagetypes.h | 1 + panda/src/pnmimagetypes/pnmFileTypeJPG.h | 1 + .../pnmimagetypes/pnmFileTypeJPGReader.cxx | 14 ++- .../pnmimagetypes/pnmFileTypeJPGWriter.cxx | 114 ++++++++++++++++++ 5 files changed, 127 insertions(+), 5 deletions(-) diff --git a/panda/src/pnmimagetypes/config_pnmimagetypes.cxx b/panda/src/pnmimagetypes/config_pnmimagetypes.cxx index 5a5a351890..c577f459bc 100644 --- a/panda/src/pnmimagetypes/config_pnmimagetypes.cxx +++ b/panda/src/pnmimagetypes/config_pnmimagetypes.cxx @@ -55,6 +55,8 @@ IMGHeaderType img_header_type; const int img_xsize = config_pnmimagetypes.GetInt("img-xsize", 0); const int img_ysize = config_pnmimagetypes.GetInt("img-ysize", 0); +const int jpeg_quality = config_pnmimagetypes.GetInt("jpeg-quality", 75); + ConfigureFn(config_pnmimagetypes) { PNMFileTypePNM::init_type(); PNMFileTypeSGI::init_type(); diff --git a/panda/src/pnmimagetypes/config_pnmimagetypes.h b/panda/src/pnmimagetypes/config_pnmimagetypes.h index 22099db0ee..8974b87062 100644 --- a/panda/src/pnmimagetypes/config_pnmimagetypes.h +++ b/panda/src/pnmimagetypes/config_pnmimagetypes.h @@ -26,6 +26,7 @@ extern const double radiance_gamma_correction; extern const int radiance_brightness_adjustment; extern const int yuv_xsize; extern const int yuv_ysize; +extern const int jpeg_quality; enum IMGHeaderType { IHT_none, diff --git a/panda/src/pnmimagetypes/pnmFileTypeJPG.h b/panda/src/pnmimagetypes/pnmFileTypeJPG.h index c98386753e..0268bae4f5 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeJPG.h +++ b/panda/src/pnmimagetypes/pnmFileTypeJPG.h @@ -42,6 +42,7 @@ public: class Reader : public PNMReader { public: Reader(PNMFileType *type, FILE *file, bool owns_file, string magic_number); + ~Reader(void); virtual int read_data(xel *array, xelval *alpha); diff --git a/panda/src/pnmimagetypes/pnmFileTypeJPGReader.cxx b/panda/src/pnmimagetypes/pnmFileTypeJPGReader.cxx index 720e18f492..7e3532f926 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeJPGReader.cxx +++ b/panda/src/pnmimagetypes/pnmFileTypeJPGReader.cxx @@ -59,6 +59,15 @@ Reader(PNMFileType *type, FILE *file, bool owns_file, string magic_number) : _maxval = MAXJSAMPLE; } +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG::Reader::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PNMFileTypeJPG::Reader:: +~Reader(void) { + jpeg_destroy_decompress(&_cinfo); +} //////////////////////////////////////////////////////////////////// // Function: PNMFileTypeJPG::Reader::read_data @@ -133,11 +142,6 @@ read_data(xel *array, xelval *) { /* We can ignore the return value since suspension is not possible * with the stdio data source. - /* Step 8: Release JPEG decompression object */ - - /* This is an important step since it will release a good deal of memory. */ - jpeg_destroy_decompress(&_cinfo); - /* At this point you may want to check to see whether any corrupt-data * warnings occurred (test whether jerr.pub.num_warnings is nonzero). */ diff --git a/panda/src/pnmimagetypes/pnmFileTypeJPGWriter.cxx b/panda/src/pnmimagetypes/pnmFileTypeJPGWriter.cxx index e83e4d2242..b681b92775 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeJPGWriter.cxx +++ b/panda/src/pnmimagetypes/pnmFileTypeJPGWriter.cxx @@ -53,5 +53,119 @@ write_data(xel *array, xelval *) { return 0; } + /* This struct contains the JPEG compression parameters and pointers to + * working space (which is allocated as needed by the JPEG library). + * It is possible to have several such structures, representing multiple + * compression/decompression processes, in existence at once. We refer + * to any one struct (and its associated working data) as a "JPEG object". + */ + struct jpeg_compress_struct cinfo; + /* This struct represents a JPEG error handler. It is declared separately + * because applications often want to supply a specialized error handler + * (see the second half of this file for an example). But here we just + * take the easy way out and use the standard error handler, which will + * print a message on stderr and call exit() if compression fails. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + struct jpeg_error_mgr jerr; + /* More stuff */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ + + /* Step 1: allocate and initialize JPEG compression object */ + + /* We have to set up the error handler first, in case the initialization + * step fails. (Unlikely, but it could happen if you are out of memory.) + * This routine fills in the contents of struct jerr, and returns jerr's + * address which we place into the link field in cinfo. + */ + cinfo.err = jpeg_std_error(&jerr); + + /* Now we can initialize the JPEG compression object. */ + jpeg_create_compress(&cinfo); + + /* Step 2: specify data destination (eg, a file) */ + /* Note: steps 2 and 3 can be done in either order. */ + + /* Here we use the library-supplied code to send compressed data to a + * stdio stream. You can also write your own code to do something else. + * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that + * requires it in order to write binary files. + */ + jpeg_stdio_dest(&cinfo, _file); + + /* Step 3: set parameters for compression */ + + /* First we supply a description of the input image. + * Four fields of the cinfo struct must be filled in: + */ + cinfo.image_width = _x_size; /* image width and height, in pixels */ + cinfo.image_height = _y_size; + if (is_grayscale()) + cinfo.input_components = 1; + else + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + /* Now use the library's routine to set default compression parameters. + * (You must set at least cinfo.in_color_space before calling this, + * since the defaults depend on the source color space.) + */ + jpeg_set_defaults(&cinfo); + /* Now you can set any non-default parameters you wish to. + * Here we just illustrate the use of quality (quantization table) scaling: + */ + jpeg_set_quality(&cinfo, jpeg_quality, TRUE /* limit to baseline-JPEG values */); + + /* Step 4: Start compressor */ + + /* TRUE ensures that we will write a complete interchange-JPEG file. + * Pass TRUE unless you are very sure of what you're doing. + */ + jpeg_start_compress(&cinfo, TRUE); + + /* Step 5: while (scan lines remain to be written) */ + /* jpeg_write_scanlines(...); */ + + /* Here we use the library's state variable cinfo.next_scanline as the + * loop counter, so that we don't have to keep track ourselves. + * To keep things simple, we pass one scanline per call; you can pass + * more if you wish, though. + */ + row_stride = _x_size * cinfo.input_components; /* JSAMPLEs per row in image_buffer */ + + int x = 0; + JSAMPROW row = new JSAMPLE[row_stride]; + while (cinfo.next_scanline < cinfo.image_height) { + /* jpeg_write_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could pass + * more than one scanline at a time if that's more convenient. + */ + for (int i = 0; i < row_stride; i += cinfo.input_components) { + if (cinfo.input_components == 1) { + row[i] = (JSAMPLE)(MAXJSAMPLE * PPM_GETB(array[x])/_maxval); + } else { + row[i] = (JSAMPLE)(MAXJSAMPLE * PPM_GETR(array[x])/_maxval); + row[i+1] = (JSAMPLE)(MAXJSAMPLE * PPM_GETG(array[x])/_maxval); + row[i+2] = (JSAMPLE)(MAXJSAMPLE * PPM_GETB(array[x])/_maxval); + } + x++; + } + //row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; + //(void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + row_pointer[0] = row; + (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + delete row; + + /* Step 6: Finish compression */ + + jpeg_finish_compress(&cinfo); + + /* Step 7: release JPEG compression object */ + + /* This is an important step since it will release a good deal of memory. */ + jpeg_destroy_compress(&cinfo); + return _y_size; }