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(¶meters[4]), getLong(¶meters[0]),
getLong(¶meters[12]), getLong(¶meters[8]));
+ mFirstPlane = getLong(¶meters[16]);
+ mPlanes = getLong(¶meters[20]);
+ mRowPitch = getLong(¶meters[24]);
+ mColPitch = getLong(¶meters[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(¶meters[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(¶meters[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(¶meters[4]), getLong(¶meters[0]),
getLong(¶meters[12]), getLong(¶meters[8]));
+ mFirstPlane = getLong(¶meters[16]);
+ mPlanes = getLong(¶meters[20]);
+ mRowPitch = getLong(¶meters[24]);
+ mColPitch = getLong(¶meters[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(¶meters[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(¶meters[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(¶meters[4]), getLong(¶meters[0]),
getLong(¶meters[12]), getLong(¶meters[8]));
+ mFirstPlane = getLong(¶meters[16]);
+ mPlanes = getLong(¶meters[20]);
+ mRowPitch = getLong(¶meters[24]);
+ mColPitch = getLong(¶meters[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(¶meters[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(¶meters[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(¶meters[4]), getLong(¶meters[0]),
getLong(¶meters[12]), getLong(¶meters[8]));
+ mFirstPlane = getLong(¶meters[16]);
+ mPlanes = getLong(¶meters[20]);
+ mRowPitch = getLong(¶meters[24]);
+ mColPitch = getLong(¶meters[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(¶meters[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(¶meters[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