Author: post
Date: 2012-08-11 15:21:15 +0200 (Sat, 11 Aug 2012)
New Revision: 448

Modified:
   RawSpeed/DngOpcodes.cpp
   RawSpeed/DngOpcodes.h
Log:
Add more (untested) DNG opcodes.

Modified: RawSpeed/DngOpcodes.cpp
===================================================================
--- RawSpeed/DngOpcodes.cpp     2012-08-05 15:20:38 UTC (rev 447)
+++ RawSpeed/DngOpcodes.cpp     2012-08-11 13:21:15 UTC (rev 448)
@@ -43,11 +43,25 @@
     {
       case 6:
         mOpcodes.push_back(new OpcodeTrimBounds(&data[bytes_used], entry_size 
- bytes_used, &opcode_used));
+        break;
       case 7:
         mOpcodes.push_back(new OpcodeMapTable(&data[bytes_used], entry_size - 
bytes_used, &opcode_used));
+        break;
       case 8:
         mOpcodes.push_back(new OpcodeMapPolynomial(&data[bytes_used], 
entry_size - bytes_used, &opcode_used));
         break;
+      case 10:
+        mOpcodes.push_back(new OpcodeDeltaPerRow(&data[bytes_used], entry_size 
- bytes_used, &opcode_used));
+        break;
+      case 11:
+        mOpcodes.push_back(new OpcodeDeltaPerCol(&data[bytes_used], entry_size 
- bytes_used, &opcode_used));
+        break;
+      case 12:
+        mOpcodes.push_back(new OpcodeScalePerRow(&data[bytes_used], entry_size 
- bytes_used, &opcode_used));
+        break;
+      case 13:
+        mOpcodes.push_back(new OpcodeScalePerCol(&data[bytes_used], entry_size 
- bytes_used, &opcode_used));
+        break;
       default:
         ThrowRDE("DngOpcodes: Unsupported Opcode: %d", code);
     }
@@ -246,4 +260,336 @@
   }
 }
 
+/***************** OpcodeDeltaPerRow   ****************/
+
+OpcodeDeltaPerRow::OpcodeDeltaPerRow(const uchar8* parameters, int 
param_max_bytes, uint32 *bytes_used )
+{
+  if (param_max_bytes < 36)
+    ThrowRDE("OpcodeDeltaPerRow: Not enough data to read parameters, only %d 
bytes left.", param_max_bytes);
+  mAoi.setAbsolute(getLong(&parameters[4]), getLong(&parameters[0]), 
getLong(&parameters[12]), getLong(&parameters[8]));
+  mFirstPlane = getLong(&parameters[16]);
+  mPlanes = getLong(&parameters[20]);
+  mRowPitch = getLong(&parameters[24]);
+  mColPitch = getLong(&parameters[28]);
+  if (mFirstPlane < 0)
+    ThrowRDE("OpcodeDeltaPerRow: Negative first plane");
+  if (mPlanes <= 0)
+    ThrowRDE("OpcodeDeltaPerRow: Negative number of planes");
+  if (mRowPitch <= 0 || mColPitch <= 0)
+    ThrowRDE("OpcodeDeltaPerRow: Invalid Pitch");
+
+  mCount = getLong(&parameters[32]);
+  *bytes_used = 36;
+  if (param_max_bytes < 36 + (mCount*4))
+    ThrowRDE("OpcodeDeltaPerRow: Not enough data to read parameters, only %d 
bytes left.", param_max_bytes);
+  if (mAoi.getHeight() != mCount)
+    ThrowRDE("OpcodeDeltaPerRow: Element count (%d) does not match height of 
area (%d).", mCount, mAoi.getHeight());
+
+  for (int i = 0; i <= mCount; i++)
+    mDelta[i] = getFloat(&parameters[36+4*i]);
+  *bytes_used += 4*mCount;
+  mFlags = MultiThreaded;
+}
+
+
+RawImage& OpcodeDeltaPerRow::createOutput( RawImage &in )
+{
+  if (mFirstPlane > (int)in->getCpp())
+    ThrowRDE("OpcodeDeltaPerRow: Not that many planes in actual image");
+
+  if (mFirstPlane+mPlanes > (int)in->getCpp())
+    ThrowRDE("OpcodeDeltaPerRow: Not that many planes in actual image");
+
+  return in;
+}
+
+void OpcodeDeltaPerRow::apply( RawImage &in, RawImage &out, int startY, int 
endY )
+{
+  if (in->getDataType() == TYPE_USHORT16) {
+    int cpp = out->getCpp();
+    for (int y = startY; y < endY; y += mRowPitch) {
+      ushort16 *src = (ushort16*)out->getData(mAoi.getLeft(), y);
+      // Add offset, so this is always first plane
+      src+=mFirstPlane;
+      int delta = (int)(65535.0f * mDelta[y]);
+      for (int x = 0; x < mAoi.getWidth(); x += mColPitch) {
+        for (int p = 0; p < mPlanes; p++)
+        {
+          src[x*cpp+p] = clampbits(16,delta + src[x*cpp+p]);
+        }
+      }
+    }
+  } else {
+    int cpp = out->getCpp();
+    for (int y = startY; y < endY; y += mRowPitch) {
+      float *src = (float*)out->getData(mAoi.getLeft(), y);
+      // Add offset, so this is always first plane
+      src+=mFirstPlane;
+      float delta = mDelta[y];
+      for (int x = 0; x < mAoi.getWidth(); x += mColPitch) {
+        for (int p = 0; p < mPlanes; p++)
+        {
+          src[x*cpp+p] = delta + src[x*cpp+p];
+        }
+      }
+    }
+  }
+}
+
+/***************** OpcodeDeltaPerCol   ****************/
+
+OpcodeDeltaPerCol::OpcodeDeltaPerCol(const uchar8* parameters, int 
param_max_bytes, uint32 *bytes_used )
+{
+  if (param_max_bytes < 36)
+    ThrowRDE("OpcodeDeltaPerCol: Not enough data to read parameters, only %d 
bytes left.", param_max_bytes);
+  mAoi.setAbsolute(getLong(&parameters[4]), getLong(&parameters[0]), 
getLong(&parameters[12]), getLong(&parameters[8]));
+  mFirstPlane = getLong(&parameters[16]);
+  mPlanes = getLong(&parameters[20]);
+  mRowPitch = getLong(&parameters[24]);
+  mColPitch = getLong(&parameters[28]);
+  if (mFirstPlane < 0)
+    ThrowRDE("OpcodeDeltaPerCol: Negative first plane");
+  if (mPlanes <= 0)
+    ThrowRDE("OpcodeDeltaPerCol: Negative number of planes");
+  if (mRowPitch <= 0 || mColPitch <= 0)
+    ThrowRDE("OpcodeDeltaPerCol: Invalid Pitch");
+
+  mCount = getLong(&parameters[32]);
+  *bytes_used = 36;
+  if (param_max_bytes < 36 + (mCount*4))
+    ThrowRDE("OpcodeDeltaPerCol: Not enough data to read parameters, only %d 
bytes left.", param_max_bytes);
+  if (mAoi.getWidth() != mCount)
+    ThrowRDE("OpcodeDeltaPerRow: Element count (%d) does not match width of 
area (%d).", mCount, mAoi.getWidth());
+
+  for (int i = 0; i <= mCount; i++)
+    mDelta[i] = getFloat(&parameters[36+4*i]);
+  *bytes_used += 4*mCount;
+  mFlags = MultiThreaded;
+  mDeltaX = NULL;
+}
+
+OpcodeDeltaPerCol::~OpcodeDeltaPerCol( void )
+{
+  if (mDeltaX)
+    delete[] mDeltaX;
+  mDeltaX = NULL;
+}
+
+
+RawImage& OpcodeDeltaPerCol::createOutput( RawImage &in )
+{
+  if (mFirstPlane > (int)in->getCpp())
+    ThrowRDE("OpcodeDeltaPerCol: Not that many planes in actual image");
+
+  if (mFirstPlane+mPlanes > (int)in->getCpp())
+    ThrowRDE("OpcodeDeltaPerCol: Not that many planes in actual image");
+
+  if (in->getDataType() == TYPE_USHORT16) {
+    if (mDeltaX)
+      delete[] mDeltaX;
+    int w = mAoi.getWidth();
+    mDeltaX = new int[w];
+    for (int i = 0; i < w; i++)
+      mDeltaX[i] = (int)(65535.0f * mDelta[i] + 0.5f);
+  }
+  return in;
+}
+
+void OpcodeDeltaPerCol::apply( RawImage &in, RawImage &out, int startY, int 
endY )
+{
+  if (in->getDataType() == TYPE_USHORT16) {
+    int cpp = out->getCpp();
+    for (int y = startY; y < endY; y += mRowPitch) {
+      ushort16 *src = (ushort16*)out->getData(mAoi.getLeft(), y);
+      // Add offset, so this is always first plane
+      src+=mFirstPlane;
+      for (int x = 0; x < mAoi.getWidth(); x += mColPitch) {
+        for (int p = 0; p < mPlanes; p++)
+        {
+          src[x*cpp+p] = clampbits(16, mDeltaX[x] + src[x*cpp+p]);
+        }
+      }
+    }
+  } else {
+    int cpp = out->getCpp();
+    for (int y = startY; y < endY; y += mRowPitch) {
+      float *src = (float*)out->getData(mAoi.getLeft(), y);
+      // Add offset, so this is always first plane
+      src+=mFirstPlane;
+      for (int x = 0; x < mAoi.getWidth(); x += mColPitch) {
+        for (int p = 0; p < mPlanes; p++)
+        {
+          src[x*cpp+p] = mDelta[x] + src[x*cpp+p];
+        }
+      }
+    }
+  }
+}
+
+/***************** OpcodeScalePerRow   ****************/
+
+OpcodeScalePerRow::OpcodeScalePerRow(const uchar8* parameters, int 
param_max_bytes, uint32 *bytes_used )
+{
+  if (param_max_bytes < 36)
+    ThrowRDE("OpcodeScalePerRow: Not enough data to read parameters, only %d 
bytes left.", param_max_bytes);
+  mAoi.setAbsolute(getLong(&parameters[4]), getLong(&parameters[0]), 
getLong(&parameters[12]), getLong(&parameters[8]));
+  mFirstPlane = getLong(&parameters[16]);
+  mPlanes = getLong(&parameters[20]);
+  mRowPitch = getLong(&parameters[24]);
+  mColPitch = getLong(&parameters[28]);
+  if (mFirstPlane < 0)
+    ThrowRDE("OpcodeScalePerRow: Negative first plane");
+  if (mPlanes <= 0)
+    ThrowRDE("OpcodeScalePerRow: Negative number of planes");
+  if (mRowPitch <= 0 || mColPitch <= 0)
+    ThrowRDE("OpcodeScalePerRow: Invalid Pitch");
+
+  mCount = getLong(&parameters[32]);
+  *bytes_used = 36;
+  if (param_max_bytes < 36 + (mCount*4))
+    ThrowRDE("OpcodeScalePerRow: Not enough data to read parameters, only %d 
bytes left.", param_max_bytes);
+  if (mAoi.getHeight() != mCount)
+    ThrowRDE("OpcodeScalePerRow: Element count (%d) does not match height of 
area (%d).", mCount, mAoi.getHeight());
+
+  for (int i = 0; i <= mCount; i++)
+    mDelta[i] = getFloat(&parameters[36+4*i]);
+  *bytes_used += 4*mCount;
+  mFlags = MultiThreaded;
+}
+
+
+RawImage& OpcodeScalePerRow::createOutput( RawImage &in )
+{
+  if (mFirstPlane > (int)in->getCpp())
+    ThrowRDE("OpcodeScalePerRow: Not that many planes in actual image");
+
+  if (mFirstPlane+mPlanes > (int)in->getCpp())
+    ThrowRDE("OpcodeScalePerRow: Not that many planes in actual image");
+
+  return in;
+}
+
+void OpcodeScalePerRow::apply( RawImage &in, RawImage &out, int startY, int 
endY )
+{
+  if (in->getDataType() == TYPE_USHORT16) {
+    int cpp = out->getCpp();
+    for (int y = startY; y < endY; y += mRowPitch) {
+      ushort16 *src = (ushort16*)out->getData(mAoi.getLeft(), y);
+      // Add offset, so this is always first plane
+      src+=mFirstPlane;
+      int delta = (int)(1024.0f * mDelta[y]);
+      for (int x = 0; x < mAoi.getWidth(); x += mColPitch) {
+        for (int p = 0; p < mPlanes; p++)
+        {
+          src[x*cpp+p] = clampbits(16,(delta * src[x*cpp+p] + 512) >> 10);
+        }
+      }
+    }
+  } else {
+    int cpp = out->getCpp();
+    for (int y = startY; y < endY; y += mRowPitch) {
+      float *src = (float*)out->getData(mAoi.getLeft(), y);
+      // Add offset, so this is always first plane
+      src+=mFirstPlane;
+      float delta = mDelta[y];
+      for (int x = 0; x < mAoi.getWidth(); x += mColPitch) {
+        for (int p = 0; p < mPlanes; p++)
+        {
+          src[x*cpp+p] = delta * src[x*cpp+p];
+        }
+      }
+    }
+  }
+}
+
+/***************** OpcodeScalePerCol   ****************/
+
+OpcodeScalePerCol::OpcodeScalePerCol(const uchar8* parameters, int 
param_max_bytes, uint32 *bytes_used )
+{
+  if (param_max_bytes < 36)
+    ThrowRDE("OpcodeScalePerCol: Not enough data to read parameters, only %d 
bytes left.", param_max_bytes);
+  mAoi.setAbsolute(getLong(&parameters[4]), getLong(&parameters[0]), 
getLong(&parameters[12]), getLong(&parameters[8]));
+  mFirstPlane = getLong(&parameters[16]);
+  mPlanes = getLong(&parameters[20]);
+  mRowPitch = getLong(&parameters[24]);
+  mColPitch = getLong(&parameters[28]);
+  if (mFirstPlane < 0)
+    ThrowRDE("OpcodeScalePerCol: Negative first plane");
+  if (mPlanes <= 0)
+    ThrowRDE("OpcodeScalePerCol: Negative number of planes");
+  if (mRowPitch <= 0 || mColPitch <= 0)
+    ThrowRDE("OpcodeScalePerCol: Invalid Pitch");
+
+  mCount = getLong(&parameters[32]);
+  *bytes_used = 36;
+  if (param_max_bytes < 36 + (mCount*4))
+    ThrowRDE("OpcodeScalePerCol: Not enough data to read parameters, only %d 
bytes left.", param_max_bytes);
+  if (mAoi.getWidth() != mCount)
+    ThrowRDE("OpcodeScalePerCol: Element count (%d) does not match width of 
area (%d).", mCount, mAoi.getWidth());
+
+  for (int i = 0; i <= mCount; i++)
+    mDelta[i] = getFloat(&parameters[36+4*i]);
+  *bytes_used += 4*mCount;
+  mFlags = MultiThreaded;
+  mDeltaX = NULL;
+}
+
+OpcodeScalePerCol::~OpcodeScalePerCol( void )
+{
+  if (mDeltaX)
+    delete[] mDeltaX;
+  mDeltaX = NULL;
+}
+
+
+RawImage& OpcodeScalePerCol::createOutput( RawImage &in )
+{
+  if (mFirstPlane > (int)in->getCpp())
+    ThrowRDE("OpcodeScalePerCol: Not that many planes in actual image");
+
+  if (mFirstPlane+mPlanes > (int)in->getCpp())
+    ThrowRDE("OpcodeScalePerCol: Not that many planes in actual image");
+
+  if (in->getDataType() == TYPE_USHORT16) {
+    if (mDeltaX)
+      delete[] mDeltaX;
+    int w = mAoi.getWidth();
+    mDeltaX = new int[w];
+    for (int i = 0; i < w; i++)
+      mDeltaX[i] = (int)(1024.0f * mDelta[i]);
+  }
+  return in;
+}
+
+void OpcodeScalePerCol::apply( RawImage &in, RawImage &out, int startY, int 
endY )
+{
+  if (in->getDataType() == TYPE_USHORT16) {
+    int cpp = out->getCpp();
+    for (int y = startY; y < endY; y += mRowPitch) {
+      ushort16 *src = (ushort16*)out->getData(mAoi.getLeft(), y);
+      // Add offset, so this is always first plane
+      src+=mFirstPlane;
+      for (int x = 0; x < mAoi.getWidth(); x += mColPitch) {
+        for (int p = 0; p < mPlanes; p++)
+        {
+          src[x*cpp+p] = clampbits(16, (mDeltaX[x] * src[x*cpp+p] + 512) >> 
10);
+        }
+      }
+    }
+  } else {
+    int cpp = out->getCpp();
+    for (int y = startY; y < endY; y += mRowPitch) {
+      float *src = (float*)out->getData(mAoi.getLeft(), y);
+      // Add offset, so this is always first plane
+      src+=mFirstPlane;
+      for (int x = 0; x < mAoi.getWidth(); x += mColPitch) {
+        for (int p = 0; p < mPlanes; p++)
+        {
+          src[x*cpp+p] = mDelta[x] * src[x*cpp+p];
+        }
+      }
+    }
+  }
+}
+
 } // namespace RawSpeed 

Modified: RawSpeed/DngOpcodes.h
===================================================================
--- RawSpeed/DngOpcodes.h       2012-08-05 15:20:38 UTC (rev 447)
+++ RawSpeed/DngOpcodes.h       2012-08-11 13:21:15 UTC (rev 448)
@@ -66,6 +66,15 @@
      tmp[i] = ptr[7-i];
     return ret;
   }
+  float getFloat(const uchar8 *ptr) {
+    if (host == big)
+      return *(float*)ptr;
+    float ret;
+    uchar8 *tmp = (uchar8*)&ret;
+    for (int i = 0; i < 4; i++)
+      tmp[i] = ptr[3-i];
+    return ret;
+  }
   ushort16 getUshort(const uchar8 *ptr) {
     if (host == big)
       return *(ushort16*)ptr;
@@ -128,7 +137,56 @@
   ushort16 mLookup[65535];
 };
 
+class OpcodeDeltaPerRow: public DngOpcode
+{
+public:
+  OpcodeDeltaPerRow(const uchar8* parameters, int param_max_bytes, uint32 
*bytes_used);
+  virtual ~OpcodeDeltaPerRow(void) {};
+  virtual RawImage& createOutput(RawImage &in);
+  virtual void apply(RawImage &in, RawImage &out, int startY, int endY);
+private:
+  int mFirstPlane, mPlanes, mRowPitch, mColPitch, mCount;
+  float* mDelta;
+};
 
+class OpcodeDeltaPerCol: public DngOpcode
+{
+public:
+  OpcodeDeltaPerCol(const uchar8* parameters, int param_max_bytes, uint32 
*bytes_used);
+  virtual ~OpcodeDeltaPerCol(void);
+  virtual RawImage& createOutput(RawImage &in);
+  virtual void apply(RawImage &in, RawImage &out, int startY, int endY);
+private:
+  int mFirstPlane, mPlanes, mRowPitch, mColPitch, mCount;
+  float* mDelta;
+  int* mDeltaX;
+};
+
+class OpcodeScalePerRow: public DngOpcode
+{
+public:
+  OpcodeScalePerRow(const uchar8* parameters, int param_max_bytes, uint32 
*bytes_used);
+  virtual ~OpcodeScalePerRow(void) {};
+  virtual RawImage& createOutput(RawImage &in);
+  virtual void apply(RawImage &in, RawImage &out, int startY, int endY);
+private:
+  int mFirstPlane, mPlanes, mRowPitch, mColPitch, mCount;
+  float* mDelta;
+};
+
+class OpcodeScalePerCol: public DngOpcode
+{
+public:
+  OpcodeScalePerCol(const uchar8* parameters, int param_max_bytes, uint32 
*bytes_used);
+  virtual ~OpcodeScalePerCol(void);
+  virtual RawImage& createOutput(RawImage &in);
+  virtual void apply(RawImage &in, RawImage &out, int startY, int endY);
+private:
+  int mFirstPlane, mPlanes, mRowPitch, mColPitch, mCount;
+  float* mDelta;
+  int* mDeltaX;
+};
+
 } // namespace RawSpeed 
 
 #endif // DNG_OPCODES_H
\ No newline at end of file


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

Reply via email to