From a33271fe1b265854dd8ff69301a7e7777b04f2d1 Mon Sep 17 00:00:00 2001 From: malaterre Date: Wed, 18 Jan 2006 21:08:03 +0000 Subject: [PATCH] ENH: Add support for broken JPEG implementation in DICOMObjects --- src/gdcmjpeg/CMakeLists.txt | 4 +++ src/gdcmjpeg/jddiffct.c | 18 ++++++------ src/gdcmjpeg/jdpred.c | 55 ++++++++++++++++++++++++++++++++++++- src/gdcmjpeg/jlossls.h | 1 + src/gdcmjpeg/jmorecfg.h.in | 7 +++++ 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/gdcmjpeg/CMakeLists.txt b/src/gdcmjpeg/CMakeLists.txt index 0a208e1b..8a0641cf 100644 --- a/src/gdcmjpeg/CMakeLists.txt +++ b/src/gdcmjpeg/CMakeLists.txt @@ -94,6 +94,10 @@ IF (WIN32) ENDIF (BUILD_SHARED_LIBS) ENDIF (WIN32) +# By default support DICOMObjects bug, if this is a speed penalty for you +# you should consider disabling it +SET(SUPPORT_DICOMOBJECTS_BUG ON) + CONFIGURE_FILE(${GDCMJPEG_SOURCE_DIR}/.NoDartCoverage ${GDCMJPEG_BINARY_DIR}/.NoDartCoverage) diff --git a/src/gdcmjpeg/jddiffct.c b/src/gdcmjpeg/jddiffct.c index 6dc61e44..68ed1cc4 100644 --- a/src/gdcmjpeg/jddiffct.c +++ b/src/gdcmjpeg/jddiffct.c @@ -201,17 +201,17 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) compptr = cinfo->cur_comp_info[comp]; ci = compptr->component_index; for (row = 0, prev_row = compptr->v_samp_factor - 1; - row < (cinfo->input_iMCU_row == last_iMCU_row ? - compptr->last_row_height : compptr->v_samp_factor); - prev_row = row, row++) { + row < (cinfo->input_iMCU_row == last_iMCU_row ? + compptr->last_row_height : compptr->v_samp_factor); + prev_row = row, row++) { (*losslsd->predict_undifference[ci]) (cinfo, ci, - diff->diff_buf[ci][row], - diff->undiff_buf[ci][prev_row], - diff->undiff_buf[ci][row], - compptr->width_in_data_units); + diff->diff_buf[ci][row], + diff->undiff_buf[ci][prev_row], + diff->undiff_buf[ci][row], + compptr->width_in_data_units); (*losslsd->scaler_scale) (cinfo, diff->undiff_buf[ci][row], - output_buf[ci][row], - compptr->width_in_data_units); + output_buf[ci][row], + compptr->width_in_data_units); } } diff --git a/src/gdcmjpeg/jdpred.c b/src/gdcmjpeg/jdpred.c index 4704fc4f..abe003e1 100644 --- a/src/gdcmjpeg/jdpred.c +++ b/src/gdcmjpeg/jdpred.c @@ -72,6 +72,18 @@ * logically AND the result with 0xFFFF. */ +#define UNDIFFERENCE_2D_BUG(PREDICTOR) \ + Rb = GETJSAMPLE(prev_row[0]); \ + Ra = (diff_buf[0] + PREDICTOR2) & 0xFFFF; \ + undiff_buf[0] = Ra; \ + \ + for (xindex = 1; xindex < width; xindex++) { \ + Rc = Rb; \ + Rb = GETJSAMPLE(prev_row[xindex]); \ + Ra = (diff_buf[xindex] + PREDICTOR) & 0xFFFF; \ + undiff_buf[xindex] = Ra; \ + } + #define UNDIFFERENCE_2D(PREDICTOR) \ unsigned int xindex; \ int Ra, Rb, Rc; \ @@ -141,14 +153,55 @@ jpeg_undifference5(j_decompress_ptr cinfo, int comp_index, (void)cinfo;(void)comp_index;(void)diff_buf;(void)prev_row;(void)undiff_buf;(void)width; } +#ifdef SUPPORT_DICOMOBJECTS_BUG +/* uniitialized */ +static int dicomobjectsbug = -1; /* 0 == nobug, 1 == bug */ +#endif + METHODDEF(void) jpeg_undifference6(j_decompress_ptr cinfo, int comp_index, JDIFFROW diff_buf, JDIFFROW prev_row, JDIFFROW undiff_buf, JDIMENSION width) { +#ifdef SUPPORT_DICOMOBJECTS_BUG + unsigned int xindex; + int Ra, Rb, Rc; + int min, max, temp; + SHIFT_TEMPS + if( dicomobjectsbug == -1 ) + { + dicomobjectsbug = 0; /* no bug by default */ + + Rb = GETJSAMPLE(prev_row[0]); + Ra = (diff_buf[0] + PREDICTOR2) & 0xFFFF; + undiff_buf[0] = Ra; + min = max = undiff_buf[0]; + + for (xindex = 1; xindex < width; xindex++) { + Rc = Rb; + Rb = GETJSAMPLE(prev_row[xindex]); + Ra = (diff_buf[xindex] + PREDICTOR6) & 0xFFFF; + min = temp < min ? temp : min; + max = temp > max ? temp : max; + } + if( (max - min) > 50000) /* magic number */ + { + dicomobjectsbug = 1; + } + } + if(dicomobjectsbug) + { + UNDIFFERENCE_2D_BUG(PREDICTOR6_BUG); + } + else + { + UNDIFFERENCE_2D_BUG(PREDICTOR6); + } +#else SHIFT_TEMPS UNDIFFERENCE_2D(PREDICTOR6); - (void)cinfo;(void)comp_index;(void)diff_buf;(void)prev_row;(void)undiff_buf;(void)width; +#endif + (void)comp_index;(void)cinfo; } METHODDEF(void) diff --git a/src/gdcmjpeg/jlossls.h b/src/gdcmjpeg/jlossls.h index 2feccd6d..9b391bda 100644 --- a/src/gdcmjpeg/jlossls.h +++ b/src/gdcmjpeg/jlossls.h @@ -23,6 +23,7 @@ #define PREDICTOR4 (int) ((INT32) Ra + (INT32) Rb - (INT32) Rc) #define PREDICTOR5 (int) ((INT32) Ra + RIGHT_SHIFT((INT32) Rb - (INT32) Rc, 1)) #define PREDICTOR6 (int) ((INT32) Rb + RIGHT_SHIFT((INT32) Ra - (INT32) Rc, 1)) +#define PREDICTOR6_BUG (int) ((INT16) Rb + RIGHT_SHIFT((INT16) Ra - (INT16) Rc, 1)) #define PREDICTOR7 (int) RIGHT_SHIFT((INT32) Ra + (INT32) Rb, 1) diff --git a/src/gdcmjpeg/jmorecfg.h.in b/src/gdcmjpeg/jmorecfg.h.in index c728d946..550e0480 100644 --- a/src/gdcmjpeg/jmorecfg.h.in +++ b/src/gdcmjpeg/jmorecfg.h.in @@ -217,6 +217,13 @@ typedef unsigned int JDIMENSION; #cmakedefine JPEGDLL #cmakedefine JPEGSTATIC +/* For more info on this bug see: + * [Broken JPEG from GE station] on comp.protocols.dicom + * and official publication at: + * http://www.medicalconnections.co.uk/html/lossless_bug.html + */ +#cmakedefine SUPPORT_DICOMOBJECTS_BUG + /* a function called through method pointers: */ #define METHODDEF(type) static type /* a function used only in its module: */ -- 2.48.1