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