Author: post
Date: 2013-04-01 19:53:25 +0200 (Mon, 01 Apr 2013)
New Revision: 532

Modified:
   RawSpeed/DngDecoder.cpp
   RawSpeed/DngOpcodes.cpp
   RawSpeed/DngOpcodes.h
   RawSpeed/RawDecoder.cpp
   RawSpeed/RawDecoder.h
Log:
Implement bad pixel mapping DNG Opcodes.

Modified: RawSpeed/DngDecoder.cpp
===================================================================
--- RawSpeed/DngDecoder.cpp     2013-03-25 20:57:33 UTC (rev 531)
+++ RawSpeed/DngDecoder.cpp     2013-04-01 17:53:25 UTC (rev 532)
@@ -379,6 +379,21 @@
   if (mRaw->dim.area() <= 0)
     ThrowRDE("DNG Decoder: No image left after crop");
 
+  // Apply stage 1 opcodes
+  if (applyStage1DngOpcodes) {
+    if (raw->hasEntry(OPCODELIST1))
+    {
+      // Apply stage 1 codes
+      try{
+        DngOpcodes codes(raw->getEntry(OPCODELIST1));
+        mRaw = codes.applyOpCodes(mRaw);
+      } catch (RawDecoderException &e) {
+        // We push back errors from the opcode parser, since the image may 
still be usable
+        mRaw->setError(e.what());
+      }
+    }
+  }
+
   // Linearization
   if (raw->hasEntry(LINEARIZATIONTABLE)) {
     const ushort16* intable = 
raw->getEntry(LINEARIZATIONTABLE)->getShortArray();

Modified: RawSpeed/DngOpcodes.cpp
===================================================================
--- RawSpeed/DngOpcodes.cpp     2013-03-25 20:57:33 UTC (rev 531)
+++ RawSpeed/DngOpcodes.cpp     2013-04-01 17:53:25 UTC (rev 532)
@@ -35,12 +35,18 @@
   for (uint32 i = 0; i < opcode_count; i++) {
     uint32 code = getULong(&data[bytes_used]);
     //uint32 version = getULong(&data[bytes_used+4]);
-    //uint32 flags = getULong(&data[bytes_used+8]);
+    uint32 flags = getULong(&data[bytes_used+8]);
     uint32 expected_size = getULong(&data[bytes_used+12]);
     bytes_used += 16;
     uint32 opcode_used = 0;
     switch (code)
     {
+      case 4:
+        mOpcodes.push_back(new OpcodeFixBadPixelsConstant(&data[bytes_used], 
entry_size - bytes_used, &opcode_used));
+        break;
+      case 5:
+        mOpcodes.push_back(new OpcodeFixBadPixelsList(&data[bytes_used], 
entry_size - bytes_used, &opcode_used));
+        break;
       case 6:
         mOpcodes.push_back(new OpcodeTrimBounds(&data[bytes_used], entry_size 
- bytes_used, &opcode_used));
         break;
@@ -63,7 +69,9 @@
         mOpcodes.push_back(new OpcodeScalePerCol(&data[bytes_used], entry_size 
- bytes_used, &opcode_used));
         break;
       default:
-        ThrowRDE("DngOpcodes: Unsupported Opcode: %d", code);
+        // Throw Error if not marked as optional
+        if (!(flags & 1))
+          ThrowRDE("DngOpcodes: Unsupported Opcode: %d", code);
     }
     if (opcode_used != expected_size)
       ThrowRDE("DngOpcodes: Inconsistent length of opcode");
@@ -101,6 +109,92 @@
   return img;
 }
 
+/***************** OpcodeFixBadPixelsConstant   ****************/
+
+OpcodeFixBadPixelsConstant::OpcodeFixBadPixelsConstant(const uchar8* 
parameters, int param_max_bytes, uint32 *bytes_used )
+{
+  if (param_max_bytes < 8)
+    ThrowRDE("OpcodeFixBadPixelsConstant: Not enough data to read parameters, 
only %d bytes left.", param_max_bytes);
+  mValue = getLong(&parameters[0]);
+  // Bayer Phase not used
+  *bytes_used = 8;
+  mFlags = MultiThreaded;
+}
+
+RawImage& OpcodeFixBadPixelsConstant::createOutput( RawImage &in )
+{
+  // These limitations are present within the DNG SDK as well.
+  if (in->getDataType() != TYPE_USHORT16)
+    ThrowRDE("OpcodeFixBadPixelsConstant: Only 16 bit images supported");
+
+  if (in->getCpp() > 1)
+    ThrowRDE("OpcodeFixBadPixelsConstant: This operation is only supported 
with 1 component");
+
+  return in;
+}
+
+void OpcodeFixBadPixelsConstant::apply( RawImage &in, RawImage &out, int 
startY, int endY )
+{
+  vector<uint32> bad_pos;
+  for (int y = startY; y < endY; y ++) {
+    ushort16* src = (ushort16*)out->getData(0, y);
+    for (int x = 0; x < in->dim.x; x++) {
+      if (src[x]== mValue) {
+        bad_pos.push_back(((uint32)x | (uint32)y<<16));
+      }
+    }
+  }
+  if (!bad_pos.empty()) {
+    pthread_mutex_lock(&out->mBadPixelMutex);
+    out->mBadPixelPositions.insert(out->mBadPixelPositions.end(), 
bad_pos.begin(), bad_pos.end());
+    pthread_mutex_unlock(&out->mBadPixelMutex);
+  }
+
+}
+
+/***************** OpcodeFixBadPixelsList   ****************/
+
+OpcodeFixBadPixelsList::OpcodeFixBadPixelsList( const uchar8* parameters, int 
param_max_bytes, uint32 *bytes_used )
+{
+  if (param_max_bytes < 12)
+    ThrowRDE("OpcodeFixBadPixelsList: Not enough data to read parameters, only 
%d bytes left.", param_max_bytes);
+  // Skip phase - we don't care
+  int BadPointCount = getLong(&parameters[4]);
+  int BadRectCount = getLong(&parameters[8]);
+  bytes_used[0] = 12; 
+  if (12 + BadPointCount * 8 + BadRectCount * 16 > param_max_bytes)
+    ThrowRDE("OpcodeFixBadPixelsList: Ran out parameter space, only %d bytes 
left.", param_max_bytes);
+
+  // Read points
+  for (int i = 0; i < BadPointCount; i++) {
+    uint32 BadPointRow = (uint32)getLong(&parameters[bytes_used[0]]);
+    uint32 BadPointCol = (uint32)getLong(&parameters[bytes_used[0]+4]);
+    bytes_used[0] += 8;
+    bad_pos.push_back(BadPointRow | (BadPointCol << 16));
+  }
+
+  // Read rects
+  for (int i = 0; i < BadRectCount; i++) {
+    uint32 BadRectTop = (uint32)getLong(&parameters[bytes_used[0]]);
+    uint32 BadRectLeft = (uint32)getLong(&parameters[bytes_used[0]+4]);
+    uint32 BadRectBottom = (uint32)getLong(&parameters[bytes_used[0]]);
+    uint32 BadRectRight = (uint32)getLong(&parameters[bytes_used[0]+4]);
+    bytes_used[0] += 16;
+    if (BadRectTop < BadRectBottom && BadRectLeft < BadRectRight) {
+      for (uint32 y = BadRectLeft; y <= BadRectRight; y++) {
+        for (uint32 x = BadRectTop; x <= BadRectBottom; x++) {
+          bad_pos.push_back(x | (y << 16));
+        }
+      }
+    }
+  }
+}
+
+void OpcodeFixBadPixelsList::apply( RawImage &in, RawImage &out, int startY, 
int endY )
+{
+  out->mBadPixelPositions.insert(out->mBadPixelPositions.end(), 
bad_pos.begin(), bad_pos.end());
+}
+
  /***************** OpcodeTrimBounds   ****************/
 
 OpcodeTrimBounds::OpcodeTrimBounds(const uchar8* parameters, int 
param_max_bytes, uint32 *bytes_used )
@@ -592,4 +686,5 @@
   }
 }
 
+
 } // namespace RawSpeed 

Modified: RawSpeed/DngOpcodes.h
===================================================================
--- RawSpeed/DngOpcodes.h       2013-03-25 20:57:33 UTC (rev 531)
+++ RawSpeed/DngOpcodes.h       2013-04-01 17:53:25 UTC (rev 532)
@@ -100,6 +100,29 @@
   }
 };
 
+class OpcodeFixBadPixelsConstant: public DngOpcode
+{
+public:
+  OpcodeFixBadPixelsConstant(const uchar8* parameters, int param_max_bytes, 
uint32 *bytes_used);
+  virtual ~OpcodeFixBadPixelsConstant(void) {};
+  virtual RawImage& createOutput( RawImage &in );
+  virtual void apply(RawImage &in, RawImage &out, int startY, int endY);
+private:
+  int mValue;
+};
+
+
+class OpcodeFixBadPixelsList: public DngOpcode
+{
+public:
+  OpcodeFixBadPixelsList(const uchar8* parameters, int param_max_bytes, uint32 
*bytes_used);
+  virtual ~OpcodeFixBadPixelsList(void) {};
+  virtual void apply(RawImage &in, RawImage &out, int startY, int endY);
+private:
+  vector<uint32> bad_pos;
+};
+
+
 class OpcodeTrimBounds: public DngOpcode
 {
 public:
@@ -111,7 +134,6 @@
 };
 
 
-
 class OpcodeMapTable: public DngOpcode
 {
 public:

Modified: RawSpeed/RawDecoder.cpp
===================================================================
--- RawSpeed/RawDecoder.cpp     2013-03-25 20:57:33 UTC (rev 531)
+++ RawSpeed/RawDecoder.cpp     2013-04-01 17:53:25 UTC (rev 532)
@@ -28,6 +28,7 @@
   decoderVersion = 0;
   failOnUnknown = FALSE;
   interpolateBadPixels = TRUE;
+  applyStage1DngOpcodes = TRUE;
 }
 
 RawDecoder::~RawDecoder(void) {

Modified: RawSpeed/RawDecoder.h
===================================================================
--- RawSpeed/RawDecoder.h       2013-03-25 20:57:33 UTC (rev 531)
+++ RawSpeed/RawDecoder.h       2013-04-01 17:53:25 UTC (rev 532)
@@ -97,6 +97,10 @@
   /* If you disable this parameter, no bad pixel interpolation will be done */
   bool interpolateBadPixels;
 
+  /* Apply stage 1 DNG opcodes. */
+  /* This usually maps out bad pixels, etc */
+  bool applyStage1DngOpcodes;
+
 protected:
   /* Attempt to decode the image */
   /* A RawDecoderException will be thrown if the image cannot be decoded, */


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

Reply via email to