]> Creatis software - gdcm.git/commitdiff
ENH: Add support for broken JPEG implementation in DICOMObjects
authormalaterre <malaterre>
Wed, 18 Jan 2006 21:08:03 +0000 (21:08 +0000)
committermalaterre <malaterre>
Wed, 18 Jan 2006 21:08:03 +0000 (21:08 +0000)
src/gdcmjpeg/CMakeLists.txt
src/gdcmjpeg/jddiffct.c
src/gdcmjpeg/jdpred.c
src/gdcmjpeg/jlossls.h
src/gdcmjpeg/jmorecfg.h.in

index 0a208e1b053d93aed84793b722cd0ccbe99b8f0d..8a0641cfb0be91deba59ad8c73fa2678b4d17ac4 100644 (file)
@@ -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)
 
index 6dc61e44569788272aeed1e7f109171656c1c375..68ed1cc40e84363162eda688a7df34a75674cafa 100644 (file)
@@ -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);
     }
   }
 
index 4704fc4f9c3491959c56b1a6fcfe873f35e5253b..abe003e17eccf0085a2e53ce63fb502ae4a4d9da 100644 (file)
  * 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)
index 2feccd6d73f850b98d36a32196b74db0cc752d1f..9b391bda1c37b5e700bfb37f8b71788e56beb6c4 100644 (file)
@@ -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)
 
 
index c728d94604d74369fe7afc5e3d15456fa2e5ed2b..550e0480145dcc054ce9bf62a7699ea04cff96d7 100644 (file)
@@ -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: */