X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmJpeg.cxx;h=f4e8862c31f16ac27785ec35bddd575664d0b73a;hb=df832cf7f90b4ca5aca2f628c1756fb276779fac;hp=762de9d4f70e69dc2d6dd688d469873308b52f0f;hpb=3e82e8b67eddf5d4b95b6aa2a2e2615aced4c452;p=gdcm.git diff --git a/src/gdcmJpeg.cxx b/src/gdcmJpeg.cxx index 762de9d4..f4e8862c 100644 --- a/src/gdcmJpeg.cxx +++ b/src/gdcmJpeg.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmJpeg.cxx,v $ Language: C++ - Date: $Date: 2005/02/02 10:02:18 $ - Version: $Revision: 1.40 $ + Date: $Date: 2007/08/30 17:37:16 $ + Version: $Revision: 1.59 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -39,28 +39,35 @@ #include #include + +#if defined(__BORLANDC__) + #include // for memset +#endif + #include "jdatasrc.cxx" #include "jdatadst.cxx" -namespace gdcm +namespace GDCM_NAME_SPACE { /** - * \brief routine for JPEG decompression - * @param fp pointer to an already open file descriptor + * \brief routine for JPEG decompression + * @param fp pointer to an already open file descriptor * 8 significant bits per pixel * @param im_buf Points to array (of R,G,B-order) data to compress * @param quality compression quality - * @param image_height Number of rows in image + * @param image_height Number of rows in image * @param image_width Number of columns in image * @return 1 on success, 0 on error */ - -bool gdcm_write_JPEG_file (std::ofstream *fp, void *im_buf, - int image_width, int image_height, int quality) -{ - JSAMPLE *image_buffer = (JSAMPLE*) im_buf; +bool gdcm_write_JPEG_file (std::ostream *fp, char *inputdata, size_t inputlength, + int image_width, int image_height, int numZ, + int sample_pixel, int bitsallocated, int quality) +{ + (void)bitsallocated; + struct jpeg_compress_struct cinfo; + int row_stride; /* physical row width in image buffer */ /* This struct contains the JPEG compression parameters and pointers to * working space (which is allocated as needed by the JPEG library). @@ -68,7 +75,7 @@ bool gdcm_write_JPEG_file (std::ofstream *fp, void *im_buf, * 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; + //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 @@ -79,9 +86,6 @@ bool gdcm_write_JPEG_file (std::ofstream *fp, void *im_buf, */ struct jpeg_error_mgr jerr; /* More stuff */ - //FILE* outfile; /* target FILE* / - 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 */ @@ -97,17 +101,8 @@ bool gdcm_write_JPEG_file (std::ofstream *fp, void *im_buf, /* 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. - */ - // if ((outfile = fopen(filename, "wb")) == NULL) { - // fprintf(stderr, "can't open %s\n", filename); - // exit(1); - // - // } - jpeg_stdio_dest(&cinfo, fp); + int fragment_size = static_cast< int >( inputlength ); + jpeg_stdio_dest(&cinfo, fp, fragment_size, 1); /* Step 3: set parameters for compression */ @@ -116,13 +111,36 @@ bool gdcm_write_JPEG_file (std::ofstream *fp, void *im_buf, */ cinfo.image_width = image_width;/* image width and height, in pixels */ cinfo.image_height = image_height; - cinfo.input_components = 3; /* # of color components per pixel */ - cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + if ( sample_pixel == 3 ) + { + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + } + else + { + cinfo.input_components = 1; /* # of color components per pixel */ + cinfo.in_color_space = JCS_GRAYSCALE; /* 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); + /* + * http://www.koders.com/c/fid80DBBF1D49D004EF71CE7C493C34610C4F17D3D3.aspx + * http://studio.imagemagick.org/pipermail/magick-users/2002-September/004685.html + * You need to set -quality 101 or greater. If quality is 100 or less you + * get regular JPEG output. This is not explained in the documentation, only + * in the comments in coder/jpeg.c. When you have configured libjpeg with + * lossless support, then + * + * quality=predictor*100 + point_transform + * + * If you don't know what these values should be, just use 101. + * They only affect the compression ratio, not the image appearance, + * which is lossless. + */ + jpeg_simple_lossless (&cinfo, 1, 0); /* Now you can set any non-default parameters you wish to. * Here we just illustrate the use of quality (quantization table) scaling: */ @@ -143,25 +161,57 @@ bool gdcm_write_JPEG_file (std::ofstream *fp, void *im_buf, * To keep things simple, we pass one scanline per call; you can pass * more if you wish, though. */ - row_stride = image_width * 3;/* JSAMPLEs per row in image_buffer */ + if (sample_pixel == 3) + { + row_stride = image_width * 3;/* JSAMPLEs per row in image_buffer */ + } + else + { + assert( sample_pixel == 1 ); + row_stride = image_width * 1;/* JSAMPLEs per row in image_buffer */ + } + + (void)numZ; + + uint8_t* input_buffer = (uint8_t*)inputdata; + //uint8_t *pbuffer = input_buffer; + //int i; + //for(i=0; itellp(); +// std::cerr << "DIFF: " << end-beg << std::endl; + +// JpegPair &jp = v[i]; +// jp.second = end-beg; + //beg = end; // + // } /* Step 6: Finish compression */ jpeg_finish_compress(&cinfo); - - /* After finish_compress, we can close the output file. */ - - // fclose(fp); --> the caller will close (multiframe treatement) /* Step 7: release JPEG compression object */ @@ -170,10 +220,9 @@ bool gdcm_write_JPEG_file (std::ofstream *fp, void *im_buf, /* And we're done! */ - return true; //??? + return true; } - //----------------------------------------------------------------------------- struct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ @@ -185,6 +234,7 @@ typedef struct my_error_mgr* my_error_ptr; /* * Here's the routine that will replace the standard error_exit method: */ +extern "C" { METHODDEF(void) my_error_exit (j_common_ptr cinfo) { /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ my_error_ptr myerr = (my_error_ptr) cinfo->err; @@ -197,9 +247,21 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo) { longjmp(myerr->setjmp_buffer, 1); } +//METHODDEF(void) my_output_message (j_common_ptr cinfo) +//{ +// char buffer[JMSG_LENGTH_MAX]; +// +// /* Create the message */ +// (*cinfo->err->format_message) (cinfo, buffer); +// +// // Custom display message, we could be more fancy and throw an exception: +// gdcmStaticErrorMacro( buffer ); +//} + +} //----------------------------------------------------------------------------- - /** +/** * \brief routine for JPEG decompression * @param fp pointer to an already open file descriptor * 8 significant bits per pixel @@ -243,8 +305,11 @@ bool JPEGFragment::ReadJPEGFile (std::ifstream *fp, void *image_buffer, int &sta // We set up the normal JPEG error routines, then override error_exit. cinfo.err = jpeg_std_error(&jerr.pub); + // for any jpeg error call my_error_exit jerr.pub.error_exit = my_error_exit; - + // for any output message call my_output_message + //jerr.pub.output_message = my_output_message; + // Establish the setjmp return context for my_error_exit to use. if (setjmp(jerr.setjmp_buffer)) { @@ -256,7 +321,7 @@ bool JPEGFragment::ReadJPEGFile (std::ifstream *fp, void *image_buffer, int &sta return 0; } // Now we can initialize the JPEG decompression object. - if( statesuspension == 0 ) + if ( statesuspension == 0 ) { jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, fp, this, 1); @@ -267,17 +332,17 @@ bool JPEGFragment::ReadJPEGFile (std::ifstream *fp, void *image_buffer, int &sta } // Step 3: read file parameters with jpeg_read_header() - if( statesuspension < 2 ) + if ( statesuspension < 2 ) { - if( jpeg_read_header(&cinfo, TRUE) == JPEG_SUSPENDED ) + if ( jpeg_read_header(&cinfo, TRUE) == JPEG_SUSPENDED ) { // Suspension in jpeg_read_header statesuspension = 2; } - + // Step 4: set parameters for decompression // prevent the library from performing any color space conversion - if( cinfo.process == JPROC_LOSSLESS ) + if ( cinfo.process == JPROC_LOSSLESS ) { cinfo.jpeg_color_space = JCS_UNKNOWN; cinfo.out_color_space = JCS_UNKNOWN; @@ -285,9 +350,9 @@ bool JPEGFragment::ReadJPEGFile (std::ifstream *fp, void *image_buffer, int &sta } // Step 5: Start decompressor - if(statesuspension < 3 ) + if (statesuspension < 3 ) { - if( jpeg_start_decompress(&cinfo) == FALSE ) + if ( jpeg_start_decompress(&cinfo) == FALSE ) { // Suspension: jpeg_start_decompress statesuspension = 3; @@ -315,14 +380,14 @@ bool JPEGFragment::ReadJPEGFile (std::ifstream *fp, void *image_buffer, int &sta while (cinfo.output_scanline < cinfo.output_height) { - if( jpeg_read_scanlines(&cinfo, buffer, 1) == 0 ) + if ( jpeg_read_scanlines(&cinfo, buffer, 1) == 0 ) { // Suspension in jpeg_read_scanlines statesuspension = 3; return true; } // The ijg has no notion of big endian, therefore always swap the jpeg stream -#if defined(GDCM_WORDS_BIGENDIAN) && (CMAKE_BITS_IN_JSAMPLE != 8) +#if (defined(GDCM_WORDS_BIGENDIAN) || defined(GDCM_FORCE_BIGENDIAN_EMULATION)) && (CMAKE_BITS_IN_JSAMPLE != 8) uint16_t *buffer16 = (uint16_t*)*buffer; uint16_t *pimage16 = (uint16_t*)pImage; for(unsigned int i=0;i