[Rawstudio-commit] rawspeed r275 - RawSpeed

Klaus Post klauspost at gmail.com
Wed Sep 22 20:41:42 CEST 2010


Author: post
Date: 2010-09-22 20:41:42 +0200 (Wed, 22 Sep 2010)
New Revision: 275

Modified:
   RawSpeed/NefDecoder.cpp
   RawSpeed/NefDecoder.h
   RawSpeed/RawDecoder.cpp
   RawSpeed/RawDecoder.h
Log:
Add support for mangled Nikon Coolpix P6000 and P7000.

Modified: RawSpeed/NefDecoder.cpp
===================================================================
--- RawSpeed/NefDecoder.cpp	2010-09-13 17:42:32 UTC (rev 274)
+++ RawSpeed/NefDecoder.cpp	2010-09-22 18:41:42 UTC (rev 275)
@@ -27,7 +27,7 @@
 
 NefDecoder::NefDecoder(TiffIFD *rootIFD, FileMap* file) :
     RawDecoder(file), mRootIFD(rootIFD) {
-
+  decoderVersion = 1;
 }
 
 NefDecoder::~NefDecoder(void) {
@@ -188,7 +188,10 @@
     iPoint2D size(width, slice.h);
     iPoint2D pos(0, offY);
     try {
-      readUncompressedRaw(in, size, pos, width*bitPerPixel / 8, bitPerPixel, true);
+      if (hints.find(string("coolpixmangled")) == hints.end())
+        readUncompressedRaw(in, size, pos, width*bitPerPixel / 8, bitPerPixel, true);
+      else 
+        readCoolpixMangledRaw(in, size, pos, width*bitPerPixel / 8);
     } catch (RawDecoderException e) {
       if (i>0)
         errors.push_back(_strdup(e.what()));
@@ -204,6 +207,77 @@
   }
 }
 
+void NefDecoder::readCoolpixMangledRaw(ByteStream &input, iPoint2D& size, iPoint2D& offset, int inputPitch) {
+  uchar8* data = mRaw->getData();
+  uint32 outPitch = mRaw->pitch;
+  uint32 w = size.x;
+  uint32 h = size.y;
+  uint32 cpp = mRaw->getCpp();
+  uint32 bitPerPixel = 12;
+  if (input.getRemainSize() < (inputPitch*h)) {
+    if ((int)input.getRemainSize() > inputPitch)
+      h = input.getRemainSize() / inputPitch - 1;
+    else
+      ThrowIOE("readUncompressedRaw: Not enough data to decode a single line. Image file truncated.");
+  }
+
+  uint32 skipBits = inputPitch - w * bitPerPixel / 8;  // Skip per line
+  if (offset.y > mRaw->dim.y)
+    ThrowRDE("readUncompressedRaw: Invalid y offset");
+  if (offset.x + size.x > mRaw->dim.x)
+    ThrowRDE("readUncompressedRaw: Invalid x offset");
+
+  uint32 y = offset.y;
+  h = MIN(h + (uint32)offset.y, (uint32)mRaw->dim.y);
+  w *= cpp;
+  BitPumpMSB *in = new BitPumpMSB(&input);
+  for (; y < h; y++) {
+    ushort16* dest = (ushort16*) & data[offset.x*sizeof(ushort16)*cpp+y*outPitch];
+    int val;
+    int val2;
+    for (uint32 x = 0 ; x < w; x++) {
+      switch (x&7) {
+        case 0:
+          val = in->getBits(12);
+          break;
+        case 2:
+        case 5:
+          val2 = in->getBits(12);
+          val = dest[x-2];  // Swap this and pixel two to the left
+          dest[x-2] = val2;
+          break;
+        case 1:
+          val = in->getBits(12);
+          val = ((val&0xf)<<8) | (((val>>4)&0xf)<<4) | (((val>>8)&0xf));
+          break;
+        case 3:
+          val = in->getBits(4) << 8;
+          val2 = in->getBits(8) << 4;
+          val |= in->getBits(8);
+          val2 |= in->getBits(4);
+          dest[x] = val;
+          x++;
+          val= val2;
+          break;
+        case 6:
+          val = in->getBits(4);
+          val2 = in->getBits(4) << 8;
+          val |= in->getBits(8) << 4;
+          val2 |= in->getBits(4) <<4;
+          val2 |= in->getBits(4);
+          dest[x] = val;
+          x++;
+          val = val2;
+          break;
+        default:
+          val = 4096;
+          in->skipBits(12);
+      }
+      dest[x] = val;
+    }
+  }
+}
+
 void NefDecoder::DecodeD100Uncompressed() {
 
   ThrowRDE("NEF DEcoder: D100 uncompressed not supported");

Modified: RawSpeed/NefDecoder.h
===================================================================
--- RawSpeed/NefDecoder.h	2010-09-13 17:42:32 UTC (rev 274)
+++ RawSpeed/NefDecoder.h	2010-09-22 18:41:42 UTC (rev 275)
@@ -43,6 +43,7 @@
   bool D100IsCompressed(uint32 offset);
   void DecodeUncompressed();
   void DecodeD100Uncompressed();
+  void NefDecoder::readCoolpixMangledRaw(ByteStream &input, iPoint2D& size, iPoint2D& offset, int inputPitch);
 };
 
 class NefSlice {

Modified: RawSpeed/RawDecoder.cpp
===================================================================
--- RawSpeed/RawDecoder.cpp	2010-09-13 17:42:32 UTC (rev 274)
+++ RawSpeed/RawDecoder.cpp	2010-09-22 18:41:42 UTC (rev 275)
@@ -136,6 +136,8 @@
 
   if (cam->decoderVersion > decoderVersion)
     ThrowRDE("Camera not supported in this version. Update RawSpeed for support.");
+
+  hints = cam->hints;
 }
 
 void RawDecoder::setMetaData(CameraMetaData *meta, string make, string model, string mode) {
@@ -167,6 +169,7 @@
 
   mRaw->blackLevel = cam->black;
   mRaw->whitePoint = cam->white;
+
 }
 
 void RawDecoder::TrimSpaces(string& str) {

Modified: RawSpeed/RawDecoder.h
===================================================================
--- RawSpeed/RawDecoder.h	2010-09-13 17:42:32 UTC (rev 274)
+++ RawSpeed/RawDecoder.h	2010-09-22 18:41:42 UTC (rev 275)
@@ -127,6 +127,9 @@
   /* Higher number in camera xml file: Files for this camera will not be decoded */
   /* Higher number in code than xml: Image will be decoded. */
   int decoderVersion;
+
+  /* Hints set for the camera after checkCameraSupported has been called from the implementation*/
+   map<string,string> hints;
 };
 
 } // namespace RawSpeed




More information about the Rawstudio-commit mailing list