Author: post
Date: 2013-05-14 22:37:11 +0200 (Tue, 14 May 2013)
New Revision: 542

Modified:
   RawSpeed/Cr2Decoder.cpp
   RawSpeed/LJpegDecompressor.cpp
   RawSpeed/LJpegDecompressor.h
   RawSpeed/LJpegPlain.cpp
Log:
Fix Canon 6D mRaw image decoding for what seems like a firmware bug, where 
width and height is swapped.

Modified: RawSpeed/Cr2Decoder.cpp
===================================================================
--- RawSpeed/Cr2Decoder.cpp     2013-05-14 18:44:42 UTC (rev 541)
+++ RawSpeed/Cr2Decoder.cpp     2013-05-14 20:37:11 UTC (rev 542)
@@ -28,7 +28,7 @@
 
 Cr2Decoder::Cr2Decoder(TiffIFD *rootIFD, FileMap* file) :
     RawDecoder(file), mRootIFD(rootIFD) {
-  decoderVersion = 2;
+  decoderVersion = 3;
 }
 
 Cr2Decoder::~Cr2Decoder(void) {
@@ -82,6 +82,9 @@
 
   mRaw->dim = iPoint2D(slices[0].w, completeH);
 
+  // Fix for Canon 6D mRaw, which has flipped width & height for some part of 
the image
+  // In that case, we swap width and height, since this is the correct 
dimension
+  bool flipDims = false;
   if (raw->hasEntry((TiffTag)0xc6c5)) {
     ushort16 ss = raw->getEntry((TiffTag)0xc6c5)->getInt();
     // sRaw
@@ -90,6 +93,12 @@
       mRaw->setCpp(3);
       mRaw->isCFA = false;
     }
+    flipDims = mRaw->dim.x < mRaw->dim.y;
+    if (flipDims) {
+      int w = mRaw->dim.x;
+      mRaw->dim.x = mRaw->dim.y;
+      mRaw->dim.y = w;
+    }
   }
 
   mRaw->createData();
@@ -115,6 +124,7 @@
       LJpegPlain l(mFile, mRaw);
       l.addSlices(s_width);
       l.mUseBigtable = true;
+      l.mCanonFlipDim = flipDims;
       l.startDecoder(slice.offset, slice.count, 0, offY);
     } catch (RawDecoderException &e) {
       if (i == 0)

Modified: RawSpeed/LJpegDecompressor.cpp
===================================================================
--- RawSpeed/LJpegDecompressor.cpp      2013-05-14 18:44:42 UTC (rev 541)
+++ RawSpeed/LJpegDecompressor.cpp      2013-05-14 20:37:11 UTC (rev 542)
@@ -91,6 +91,7 @@
   mDNGCompatible = false;
   slicesW.clear();
   mUseBigtable = false;
+  mCanonFlipDim = false;
 }
 
 LJpegDecompressor::~LJpegDecompressor(void) {

Modified: RawSpeed/LJpegDecompressor.h
===================================================================
--- RawSpeed/LJpegDecompressor.h        2013-05-14 18:44:42 UTC (rev 541)
+++ RawSpeed/LJpegDecompressor.h        2013-05-14 20:37:11 UTC (rev 542)
@@ -171,6 +171,7 @@
   virtual void getSOF(SOFInfo* i, uint32 offset, uint32 size);
   bool mDNGCompatible;  // DNG v1.0.x compatibility
   bool mUseBigtable;    // Use only for large images
+  bool mCanonFlipDim;   // Fix Canon 6D mRaw where width/height is flipped
   virtual void addSlices(vector<int> slices) {slicesW=slices;};  // CR2 slices.
 protected:
   virtual void parseSOF(SOFInfo* i);

Modified: RawSpeed/LJpegPlain.cpp
===================================================================
--- RawSpeed/LJpegPlain.cpp     2013-05-14 18:44:42 UTC (rev 541)
+++ RawSpeed/LJpegPlain.cpp     2013-05-14 20:37:11 UTC (rev 542)
@@ -40,14 +40,27 @@
 }
 
 void LJpegPlain::decodeScan() {
+
+  // Fix for Canon 6D mRaw, which has flipped width & height for some part of 
the image
+  // We temporarily swap width and height for cropping.
+  if (mCanonFlipDim) {
+    uint32 w = frame.w;
+    frame.w = frame.h;
+    frame.h = w;
+  }
+
   // If image attempts to decode beyond the image bounds, strip it.
   if ((frame.w * frame.cps + offX * mRaw->getCpp()) > mRaw->dim.x * 
mRaw->getCpp())
     skipX = ((frame.w * frame.cps + offX * mRaw->getCpp()) - mRaw->dim.x * 
mRaw->getCpp()) / frame.cps;
   if (frame.h + offY > (uint32)mRaw->dim.y)
     skipY = frame.h + offY - mRaw->dim.y;
 
-//  _RPT1(0,"SlicesW:0x%x,\n",&slicesW);
-//  _RPT1(0,"Slices:%d\n",slicesW.size());
+  // Swap back (see above)
+  if (mCanonFlipDim) {
+    uint32 w = frame.w;
+    frame.w = frame.h;
+    frame.h = w;
+  }
 
   if (slicesW.empty())
     slicesW.push_back(frame.w*frame.cps);
@@ -74,6 +87,8 @@
                    frame.compInfo[1].superH == 1 && frame.compInfo[1].superV 
== 1 &&
                    frame.compInfo[2].superH == 1 && frame.compInfo[2].superV 
== 1) {
           // Something like Cr2 sRaw2, use fast decoder
+          if (mCanonFlipDim)
+            ThrowRDE("LJpegDecompressor::decodeScan: Cannot flip non 4:2:2 
subsampled images.");
           decodeScanLeft4_2_2();
           return;
         } else {
@@ -88,6 +103,9 @@
   }
 
   if (pred == 1) {
+    if (mCanonFlipDim)
+      ThrowRDE("LJpegDecompressor::decodeScan: Cannot flip non subsampled 
images.");
+
     if (frame.cps == 2)
       decodeScanLeft2Comps();
     else if (frame.cps == 3)
@@ -287,9 +305,11 @@
   mRaw->subsampling.y = 2;
 
   uchar8 *draw = mRaw->getData();
+  // Fix for Canon 6D mRaw, which has flipped width & height
+  uint32 real_h = mCanonFlipDim ? frame.w : frame.h;
 
   //Prepare slices (for CR2)
-  uint32 slices = (uint32)slicesW.size() * (frame.h - skipY) / 2;
+  uint32 slices = (uint32)slicesW.size() * (real_h - skipY) / 2;
   offset = new uint32[slices+1];
 
   uint32 t_y = 0;
@@ -307,7 +327,7 @@
     offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) * 
mRaw->pitch)) | (t_s << 28);
     _ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
     t_y += 2;
-    if (t_y >= (frame.h - skipY)) {
+    if (t_y >= (real_h- skipY)) {
       t_y = 0;
       t_x += slice_width[t_s++];
     }


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to