summaryrefslogtreecommitdiff
path: root/gpr/source/lib/dng_sdk/dng_misc_opcodes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gpr/source/lib/dng_sdk/dng_misc_opcodes.cpp')
-rw-r--r--gpr/source/lib/dng_sdk/dng_misc_opcodes.cpp1578
1 files changed, 1578 insertions, 0 deletions
diff --git a/gpr/source/lib/dng_sdk/dng_misc_opcodes.cpp b/gpr/source/lib/dng_sdk/dng_misc_opcodes.cpp
new file mode 100644
index 0000000..139b79f
--- /dev/null
+++ b/gpr/source/lib/dng_sdk/dng_misc_opcodes.cpp
@@ -0,0 +1,1578 @@
+/*****************************************************************************/
+// Copyright 2008-2009 Adobe Systems Incorporated
+// All Rights Reserved.
+//
+// NOTICE: Adobe permits you to use, modify, and distribute this file in
+// accordance with the terms of the Adobe license agreement accompanying it.
+/*****************************************************************************/
+
+/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_misc_opcodes.cpp#1 $ */
+/* $DateTime: 2012/05/30 13:28:51 $ */
+/* $Change: 832332 $ */
+/* $Author: tknoll $ */
+
+/*****************************************************************************/
+
+#include "dng_misc_opcodes.h"
+
+#include "dng_bottlenecks.h"
+#include "dng_exceptions.h"
+#include "dng_globals.h"
+#include "dng_host.h"
+#include "dng_image.h"
+#include "dng_rect.h"
+#include "dng_stream.h"
+#include "dng_tag_values.h"
+
+/*****************************************************************************/
+
+dng_opcode_TrimBounds::dng_opcode_TrimBounds (const dng_rect &bounds)
+
+ : dng_opcode (dngOpcode_TrimBounds,
+ dngVersion_1_3_0_0,
+ kFlag_None)
+
+ , fBounds (bounds)
+
+ {
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_TrimBounds::dng_opcode_TrimBounds (dng_stream &stream)
+
+ : dng_opcode (dngOpcode_TrimBounds,
+ stream,
+ "TrimBounds")
+
+ , fBounds ()
+
+ {
+
+ if (stream.Get_uint32 () != 16)
+ {
+ ThrowBadFormat ();
+ }
+
+ fBounds.t = stream.Get_int32 ();
+ fBounds.l = stream.Get_int32 ();
+ fBounds.b = stream.Get_int32 ();
+ fBounds.r = stream.Get_int32 ();
+
+ if (fBounds.IsEmpty ())
+ {
+ ThrowBadFormat ();
+ }
+
+ #if qDNGValidate
+
+ if (gVerbose)
+ {
+
+ printf ("Bounds: t=%d, l=%d, b=%d, r=%d\n",
+ (int) fBounds.t,
+ (int) fBounds.l,
+ (int) fBounds.b,
+ (int) fBounds.r);
+
+ }
+
+ #endif
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_TrimBounds::PutData (dng_stream &stream) const
+ {
+
+ stream.Put_uint32 (16);
+
+ stream.Put_int32 (fBounds.t);
+ stream.Put_int32 (fBounds.l);
+ stream.Put_int32 (fBounds.b);
+ stream.Put_int32 (fBounds.r);
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_TrimBounds::Apply (dng_host & /* host */,
+ dng_negative & /* negative */,
+ AutoPtr<dng_image> &image)
+ {
+
+ if (fBounds.IsEmpty () || (fBounds & image->Bounds ()) != fBounds)
+ {
+ ThrowBadFormat ();
+ }
+
+ image->Trim (fBounds);
+
+ }
+
+/*****************************************************************************/
+
+void dng_area_spec::GetData (dng_stream &stream)
+ {
+
+ fArea.t = stream.Get_int32 ();
+ fArea.l = stream.Get_int32 ();
+ fArea.b = stream.Get_int32 ();
+ fArea.r = stream.Get_int32 ();
+
+ fPlane = stream.Get_uint32 ();
+ fPlanes = stream.Get_uint32 ();
+
+ fRowPitch = stream.Get_uint32 ();
+ fColPitch = stream.Get_uint32 ();
+
+ if (fPlanes < 1)
+ {
+ ThrowBadFormat ();
+ }
+
+ if (fRowPitch < 1 || fColPitch < 1)
+ {
+ ThrowBadFormat ();
+ }
+
+ if (fArea.IsEmpty () && (fRowPitch != 1 || fColPitch != 1))
+ {
+ ThrowBadFormat ();
+ }
+
+ #if qDNGValidate
+
+ if (gVerbose)
+ {
+
+ printf ("AreaSpec: t=%d, l=%d, b=%d, r=%d, p=%u:%u, rp=%u, cp=%u\n",
+ (int) fArea.t,
+ (int) fArea.l,
+ (int) fArea.b,
+ (int) fArea.r,
+ (unsigned) fPlane,
+ (unsigned) fPlanes,
+ (unsigned) fRowPitch,
+ (unsigned) fColPitch);
+
+ }
+
+ #endif
+
+ }
+
+/*****************************************************************************/
+
+void dng_area_spec::PutData (dng_stream &stream) const
+ {
+
+ stream.Put_int32 (fArea.t);
+ stream.Put_int32 (fArea.l);
+ stream.Put_int32 (fArea.b);
+ stream.Put_int32 (fArea.r);
+
+ stream.Put_uint32 (fPlane);
+ stream.Put_uint32 (fPlanes);
+
+ stream.Put_uint32 (fRowPitch);
+ stream.Put_uint32 (fColPitch);
+
+ }
+
+/*****************************************************************************/
+
+dng_rect dng_area_spec::Overlap (const dng_rect &tile) const
+ {
+
+ // Special case - if the fArea is empty, then dng_area_spec covers
+ // the entire image, no matter how large it is.
+
+ if (fArea.IsEmpty ())
+ {
+ return tile;
+ }
+
+ dng_rect overlap = fArea & tile;
+
+ if (overlap.NotEmpty ())
+ {
+
+ overlap.t = fArea.t + ((overlap.t - fArea.t + fRowPitch - 1) / fRowPitch) * fRowPitch;
+ overlap.l = fArea.l + ((overlap.l - fArea.l + fColPitch - 1) / fColPitch) * fColPitch;
+
+ if (overlap.NotEmpty ())
+ {
+
+ overlap.b = overlap.t + ((overlap.H () - 1) / fRowPitch) * fRowPitch + 1;
+ overlap.r = overlap.l + ((overlap.W () - 1) / fColPitch) * fColPitch + 1;
+
+ return overlap;
+
+ }
+
+ }
+
+ return dng_rect ();
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_MapTable::dng_opcode_MapTable (dng_host &host,
+ const dng_area_spec &areaSpec,
+ const uint16 *table,
+ uint32 count)
+
+ : dng_inplace_opcode (dngOpcode_MapTable,
+ dngVersion_1_3_0_0,
+ kFlag_None)
+
+ , fAreaSpec (areaSpec)
+ , fTable ()
+ , fCount (count)
+
+ {
+
+ if (count == 0 || count > 0x10000)
+ {
+ ThrowProgramError ();
+ }
+
+ fTable.Reset (host.Allocate (0x10000 * sizeof (uint16)));
+
+ DoCopyBytes (table,
+ fTable->Buffer (),
+ count * (uint32) sizeof (uint16));
+
+ ReplicateLastEntry ();
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_MapTable::dng_opcode_MapTable (dng_host &host,
+ dng_stream &stream)
+
+ : dng_inplace_opcode (dngOpcode_MapTable,
+ stream,
+ "MapTable")
+
+ , fAreaSpec ()
+ , fTable ()
+ , fCount (0)
+
+ {
+
+ uint32 dataSize = stream.Get_uint32 ();
+
+ fAreaSpec.GetData (stream);
+
+ fCount = stream.Get_uint32 ();
+
+ if (dataSize != dng_area_spec::kDataSize + 4 + fCount * 2)
+ {
+ ThrowBadFormat ();
+ }
+
+ if (fCount == 0 || fCount > 0x10000)
+ {
+ ThrowBadFormat ();
+ }
+
+ fTable.Reset (host.Allocate (0x10000 * sizeof (uint16)));
+
+ uint16 *table = fTable->Buffer_uint16 ();
+
+ for (uint32 index = 0; index < fCount; index++)
+ {
+ table [index] = stream.Get_uint16 ();
+ }
+
+ ReplicateLastEntry ();
+
+ #if qDNGValidate
+
+ if (gVerbose)
+ {
+
+ printf ("Count: %u\n", (unsigned) fCount);
+
+ for (uint32 j = 0; j < fCount && j < gDumpLineLimit; j++)
+ {
+ printf (" Table [%5u] = %5u\n", (unsigned) j, (unsigned) table [j]);
+ }
+
+ if (fCount > gDumpLineLimit)
+ {
+ printf (" ... %u table entries skipped\n", (unsigned) (fCount - gDumpLineLimit));
+ }
+
+ }
+
+ #endif
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_MapTable::ReplicateLastEntry ()
+ {
+
+ uint16 *table = fTable->Buffer_uint16 ();
+
+ uint16 lastEntry = table [fCount];
+
+ for (uint32 index = fCount; index < 0x10000; index++)
+ {
+ table [index] = lastEntry;
+ }
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_MapTable::PutData (dng_stream &stream) const
+ {
+
+ stream.Put_uint32 (dng_area_spec::kDataSize + 4 + fCount * 2);
+
+ fAreaSpec.PutData (stream);
+
+ stream.Put_uint32 (fCount);
+
+ uint16 *table = fTable->Buffer_uint16 ();
+
+ for (uint32 index = 0; index < fCount; index++)
+ {
+ stream.Put_uint16 (table [index]);
+ }
+
+ }
+
+/*****************************************************************************/
+
+uint32 dng_opcode_MapTable::BufferPixelType (uint32 /* imagePixelType */)
+ {
+
+ return ttShort;
+
+ }
+
+/*****************************************************************************/
+
+dng_rect dng_opcode_MapTable::ModifiedBounds (const dng_rect &imageBounds)
+ {
+
+ return fAreaSpec.Overlap (imageBounds);
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_MapTable::ProcessArea (dng_negative & /* negative */,
+ uint32 /* threadIndex */,
+ dng_pixel_buffer &buffer,
+ const dng_rect &dstArea,
+ const dng_rect & /* imageBounds */)
+ {
+
+ dng_rect overlap = fAreaSpec.Overlap (dstArea);
+
+ if (overlap.NotEmpty ())
+ {
+
+ for (uint32 plane = fAreaSpec.Plane ();
+ plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
+ plane < buffer.Planes ();
+ plane++)
+ {
+
+ DoMapArea16 (buffer.DirtyPixel_uint16 (overlap.t, overlap.l, plane),
+ 1,
+ (overlap.H () + fAreaSpec.RowPitch () - 1) / fAreaSpec.RowPitch (),
+ (overlap.W () + fAreaSpec.ColPitch () - 1) / fAreaSpec.ColPitch (),
+ 0,
+ fAreaSpec.RowPitch () * buffer.RowStep (),
+ fAreaSpec.ColPitch (),
+ fTable->Buffer_uint16 ());
+
+ }
+
+ }
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_MapPolynomial::dng_opcode_MapPolynomial (const dng_area_spec &areaSpec,
+ uint32 degree,
+ const real64 *coefficient)
+
+ : dng_inplace_opcode (dngOpcode_MapPolynomial,
+ dngVersion_1_3_0_0,
+ kFlag_None)
+
+ , fAreaSpec (areaSpec)
+ , fDegree (degree)
+
+ {
+
+ for (uint32 j = 0; j <= kMaxDegree; j++)
+ {
+
+ if (j <= fDegree)
+ {
+ fCoefficient [j] = coefficient [j];
+ }
+
+ else
+ {
+ fCoefficient [j] = 0.0;
+ }
+
+ }
+
+ // Reduce degree if possible.
+
+ while (fDegree > 0 && fCoefficient [fDegree] == 0.0)
+ {
+ fDegree--;
+ }
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_MapPolynomial::dng_opcode_MapPolynomial (dng_stream &stream)
+
+ : dng_inplace_opcode (dngOpcode_MapPolynomial,
+ stream,
+ "MapPolynomial")
+
+ , fAreaSpec ()
+ , fDegree (0)
+
+ {
+
+ uint32 dataSize = stream.Get_uint32 ();
+
+ fAreaSpec.GetData (stream);
+
+ fDegree = stream.Get_uint32 ();
+
+ if (dataSize != dng_area_spec::kDataSize + 4 + (fDegree + 1) * 8)
+ {
+ ThrowBadFormat ();
+ }
+
+ if (fDegree > kMaxDegree)
+ {
+ ThrowBadFormat ();
+ }
+
+ for (uint32 j = 0; j <= kMaxDegree; j++)
+ {
+
+ if (j <= fDegree)
+ {
+ fCoefficient [j] = stream.Get_real64 ();
+ }
+ else
+ {
+ fCoefficient [j] = 0.0;
+ }
+
+ }
+
+ #if qDNGValidate
+
+ if (gVerbose)
+ {
+
+ for (uint32 k = 0; k <= fDegree; k++)
+ {
+ printf (" Coefficient [%u] = %f\n", (unsigned) k, fCoefficient [k]);
+ }
+
+ }
+
+ #endif
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_MapPolynomial::PutData (dng_stream &stream) const
+ {
+
+ stream.Put_uint32 (dng_area_spec::kDataSize + 4 + (fDegree + 1) * 8);
+
+ fAreaSpec.PutData (stream);
+
+ stream.Put_uint32 (fDegree);
+
+ for (uint32 j = 0; j <= fDegree; j++)
+ {
+ stream.Put_real64 (fCoefficient [j]);
+ }
+
+ }
+
+/*****************************************************************************/
+
+uint32 dng_opcode_MapPolynomial::BufferPixelType (uint32 imagePixelType)
+ {
+
+ // If we are operating on the stage 1 image, then we need
+ // to adjust the coefficients to convert from the image
+ // values to the 32-bit floating point values that this
+ // opcode operates on.
+
+ // If we are operating on the stage 2 or 3 image, the logical
+ // range of the image is already 0.0 to 1.0, so we don't
+ // need to adjust the values.
+
+ real64 scale32 = 1.0;
+
+ if (Stage () == 1)
+ {
+
+ switch (imagePixelType)
+ {
+
+ case ttFloat:
+ break;
+
+ case ttShort:
+ {
+ scale32 = (real64) 0xFFFF;
+ break;
+ }
+
+ case ttLong:
+ {
+ scale32 = (real64) 0xFFFFFFFF;
+ break;
+ }
+
+ default:
+ ThrowBadFormat ();
+
+ }
+
+ }
+
+ real64 factor32 = 1.0 / scale32;
+
+ for (uint32 j = 0; j <= kMaxDegree; j++)
+ {
+
+ fCoefficient32 [j] = (real32) (fCoefficient [j] * factor32);
+
+ factor32 *= scale32;
+
+ }
+
+ return ttFloat;
+
+ }
+
+/*****************************************************************************/
+
+dng_rect dng_opcode_MapPolynomial::ModifiedBounds (const dng_rect &imageBounds)
+ {
+
+ return fAreaSpec.Overlap (imageBounds);
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_MapPolynomial::ProcessArea (dng_negative & /* negative */,
+ uint32 /* threadIndex */,
+ dng_pixel_buffer &buffer,
+ const dng_rect &dstArea,
+ const dng_rect & /* imageBounds */)
+ {
+
+ dng_rect overlap = fAreaSpec.Overlap (dstArea);
+
+ if (overlap.NotEmpty ())
+ {
+
+ uint32 cols = overlap.W ();
+
+ uint32 colPitch = fAreaSpec.ColPitch ();
+
+ for (uint32 plane = fAreaSpec.Plane ();
+ plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
+ plane < buffer.Planes ();
+ plane++)
+ {
+
+ for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ())
+ {
+
+ real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane);
+
+ switch (fDegree)
+ {
+
+ case 0:
+ {
+
+ real32 y = Pin_real32 (0.0f,
+ fCoefficient32 [0],
+ 1.0f);
+
+ for (uint32 col = 0; col < cols; col += colPitch)
+ {
+
+ dPtr [col] = y;
+
+ }
+
+ break;
+
+ }
+
+ case 1:
+ {
+
+ real32 c0 = fCoefficient32 [0];
+ real32 c1 = fCoefficient32 [1];
+
+ if (c0 == 0.0f)
+ {
+
+ if (c1 > 0.0f)
+ {
+
+ for (uint32 col = 0; col < cols; col += colPitch)
+ {
+
+ real32 x = dPtr [col];
+
+ real32 y = c1 * x;
+
+ dPtr [col] = Min_real32 (y, 1.0f);
+
+ }
+
+ }
+
+ else
+ {
+
+ for (uint32 col = 0; col < cols; col += colPitch)
+ {
+
+ dPtr [col] = 0.0f;
+
+ }
+
+ }
+
+ }
+
+ else
+ {
+
+ for (uint32 col = 0; col < cols; col += colPitch)
+ {
+
+ real32 x = dPtr [col];
+
+ real32 y = c0 +
+ c1 * x;
+
+ dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
+
+ }
+
+ }
+
+ break;
+
+ }
+
+ case 2:
+ {
+
+ for (uint32 col = 0; col < cols; col += colPitch)
+ {
+
+ real32 x = dPtr [col];
+
+ real32 y = fCoefficient32 [0] + x *
+ (fCoefficient32 [1] + x *
+ (fCoefficient32 [2]));
+
+ dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
+
+ }
+
+ break;
+
+ }
+
+ case 3:
+ {
+
+ for (uint32 col = 0; col < cols; col += colPitch)
+ {
+
+ real32 x = dPtr [col];
+
+ real32 y = fCoefficient32 [0] + x *
+ (fCoefficient32 [1] + x *
+ (fCoefficient32 [2] + x *
+ (fCoefficient32 [3])));
+
+ dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
+
+ }
+
+ break;
+
+ }
+
+ case 4:
+ {
+
+ for (uint32 col = 0; col < cols; col += colPitch)
+ {
+
+ real32 x = dPtr [col];
+
+ real32 y = fCoefficient32 [0] + x *
+ (fCoefficient32 [1] + x *
+ (fCoefficient32 [2] + x *
+ (fCoefficient32 [3] + x *
+ (fCoefficient32 [4]))));
+
+ dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
+
+ }
+
+ break;
+
+ }
+
+ default:
+ {
+
+ for (uint32 col = 0; col < cols; col += colPitch)
+ {
+
+ real32 x = dPtr [col];
+
+ real32 y = fCoefficient32 [0];
+
+ real32 xx = x;
+
+ for (uint32 j = 1; j <= fDegree; j++)
+ {
+
+ y += fCoefficient32 [j] * xx;
+
+ xx *= x;
+
+ }
+
+ dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_DeltaPerRow::dng_opcode_DeltaPerRow (const dng_area_spec &areaSpec,
+ AutoPtr<dng_memory_block> &table)
+
+ : dng_inplace_opcode (dngOpcode_DeltaPerRow,
+ dngVersion_1_3_0_0,
+ kFlag_None)
+
+ , fAreaSpec (areaSpec)
+ , fTable ()
+ , fScale (1.0f)
+
+ {
+
+ fTable.Reset (table.Release ());
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_DeltaPerRow::dng_opcode_DeltaPerRow (dng_host &host,
+ dng_stream &stream)
+
+ : dng_inplace_opcode (dngOpcode_DeltaPerRow,
+ stream,
+ "DeltaPerRow")
+
+ , fAreaSpec ()
+ , fTable ()
+ , fScale (1.0f)
+
+ {
+
+ uint32 dataSize = stream.Get_uint32 ();
+
+ fAreaSpec.GetData (stream);
+
+ uint32 deltas = (fAreaSpec.Area ().H () +
+ fAreaSpec.RowPitch () - 1) /
+ fAreaSpec.RowPitch ();
+
+ if (deltas != stream.Get_uint32 ())
+ {
+ ThrowBadFormat ();
+ }
+
+ if (dataSize != dng_area_spec::kDataSize + 4 + deltas * 4)
+ {
+ ThrowBadFormat ();
+ }
+
+ fTable.Reset (host.Allocate (deltas * (uint32) sizeof (real32)));
+
+ real32 *table = fTable->Buffer_real32 ();
+
+ for (uint32 j = 0; j < deltas; j++)
+ {
+ table [j] = stream.Get_real32 ();
+ }
+
+ #if qDNGValidate
+
+ if (gVerbose)
+ {
+
+ printf ("Count: %u\n", (unsigned) deltas);
+
+ for (uint32 k = 0; k < deltas && k < gDumpLineLimit; k++)
+ {
+ printf (" Delta [%u] = %f\n", (unsigned) k, table [k]);
+ }
+
+ if (deltas > gDumpLineLimit)
+ {
+ printf (" ... %u deltas skipped\n", (unsigned) (deltas - gDumpLineLimit));
+ }
+
+ }
+
+ #endif
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_DeltaPerRow::PutData (dng_stream &stream) const
+ {
+
+ uint32 deltas = (fAreaSpec.Area ().H () +
+ fAreaSpec.RowPitch () - 1) /
+ fAreaSpec.RowPitch ();
+
+ stream.Put_uint32 (dng_area_spec::kDataSize + 4 + deltas * 4);
+
+ fAreaSpec.PutData (stream);
+
+ stream.Put_uint32 (deltas);
+
+ real32 *table = fTable->Buffer_real32 ();
+
+ for (uint32 j = 0; j < deltas; j++)
+ {
+ stream.Put_real32 (table [j]);
+ }
+
+ }
+
+/*****************************************************************************/
+
+uint32 dng_opcode_DeltaPerRow::BufferPixelType (uint32 imagePixelType)
+ {
+
+ real64 scale32 = 1.0;
+
+ switch (imagePixelType)
+ {
+
+ case ttFloat:
+ break;
+
+ case ttShort:
+ {
+ scale32 = (real64) 0xFFFF;
+ break;
+ }
+
+ case ttLong:
+ {
+ scale32 = (real64) 0xFFFFFFFF;
+ break;
+ }
+
+ default:
+ ThrowBadFormat ();
+
+ }
+
+ fScale = (real32) (1.0 / scale32);
+
+ return ttFloat;
+
+ }
+
+/*****************************************************************************/
+
+dng_rect dng_opcode_DeltaPerRow::ModifiedBounds (const dng_rect &imageBounds)
+ {
+
+ return fAreaSpec.Overlap (imageBounds);
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_DeltaPerRow::ProcessArea (dng_negative & /* negative */,
+ uint32 /* threadIndex */,
+ dng_pixel_buffer &buffer,
+ const dng_rect &dstArea,
+ const dng_rect & /* imageBounds */)
+ {
+
+ dng_rect overlap = fAreaSpec.Overlap (dstArea);
+
+ if (overlap.NotEmpty ())
+ {
+
+ uint32 cols = overlap.W ();
+
+ uint32 colPitch = fAreaSpec.ColPitch ();
+
+ for (uint32 plane = fAreaSpec.Plane ();
+ plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
+ plane < buffer.Planes ();
+ plane++)
+ {
+
+ const real32 *table = fTable->Buffer_real32 () +
+ ((overlap.t - fAreaSpec.Area ().t) /
+ fAreaSpec.RowPitch ());
+
+ for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ())
+ {
+
+ real32 rowDelta = *(table++) * fScale;
+
+ real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane);
+
+ for (uint32 col = 0; col < cols; col += colPitch)
+ {
+
+ real32 x = dPtr [col];
+
+ real32 y = x + rowDelta;
+
+ dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_DeltaPerColumn::dng_opcode_DeltaPerColumn (const dng_area_spec &areaSpec,
+ AutoPtr<dng_memory_block> &table)
+
+ : dng_inplace_opcode (dngOpcode_DeltaPerColumn,
+ dngVersion_1_3_0_0,
+ kFlag_None)
+
+ , fAreaSpec (areaSpec)
+ , fTable ()
+ , fScale (1.0f)
+
+ {
+
+ fTable.Reset (table.Release ());
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_DeltaPerColumn::dng_opcode_DeltaPerColumn (dng_host &host,
+ dng_stream &stream)
+
+ : dng_inplace_opcode (dngOpcode_DeltaPerColumn,
+ stream,
+ "DeltaPerColumn")
+
+ , fAreaSpec ()
+ , fTable ()
+ , fScale (1.0f)
+
+ {
+
+ uint32 dataSize = stream.Get_uint32 ();
+
+ fAreaSpec.GetData (stream);
+
+ uint32 deltas = (fAreaSpec.Area ().W () +
+ fAreaSpec.ColPitch () - 1) /
+ fAreaSpec.ColPitch ();
+
+ if (deltas != stream.Get_uint32 ())
+ {
+ ThrowBadFormat ();
+ }
+
+ if (dataSize != dng_area_spec::kDataSize + 4 + deltas * 4)
+ {
+ ThrowBadFormat ();
+ }
+
+ fTable.Reset (host.Allocate (deltas * (uint32) sizeof (real32)));
+
+ real32 *table = fTable->Buffer_real32 ();
+
+ for (uint32 j = 0; j < deltas; j++)
+ {
+ table [j] = stream.Get_real32 ();
+ }
+
+ #if qDNGValidate
+
+ if (gVerbose)
+ {
+
+ printf ("Count: %u\n", (unsigned) deltas);
+
+ for (uint32 k = 0; k < deltas && k < gDumpLineLimit; k++)
+ {
+ printf (" Delta [%u] = %f\n", (unsigned) k, table [k]);
+ }
+
+ if (deltas > gDumpLineLimit)
+ {
+ printf (" ... %u deltas skipped\n", (unsigned) (deltas - gDumpLineLimit));
+ }
+
+ }
+
+ #endif
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_DeltaPerColumn::PutData (dng_stream &stream) const
+ {
+
+ uint32 deltas = (fAreaSpec.Area ().W () +
+ fAreaSpec.ColPitch () - 1) /
+ fAreaSpec.ColPitch ();
+
+ stream.Put_uint32 (dng_area_spec::kDataSize + 4 + deltas * 4);
+
+ fAreaSpec.PutData (stream);
+
+ stream.Put_uint32 (deltas);
+
+ real32 *table = fTable->Buffer_real32 ();
+
+ for (uint32 j = 0; j < deltas; j++)
+ {
+ stream.Put_real32 (table [j]);
+ }
+
+ }
+
+/*****************************************************************************/
+
+uint32 dng_opcode_DeltaPerColumn::BufferPixelType (uint32 imagePixelType)
+ {
+
+ real64 scale32 = 1.0;
+
+ switch (imagePixelType)
+ {
+
+ case ttFloat:
+ break;
+
+ case ttShort:
+ {
+ scale32 = (real64) 0xFFFF;
+ break;
+ }
+
+ case ttLong:
+ {
+ scale32 = (real64) 0xFFFFFFFF;
+ break;
+ }
+
+ default:
+ ThrowBadFormat ();
+
+ }
+
+ fScale = (real32) (1.0 / scale32);
+
+ return ttFloat;
+
+ }
+
+/*****************************************************************************/
+
+dng_rect dng_opcode_DeltaPerColumn::ModifiedBounds (const dng_rect &imageBounds)
+ {
+
+ return fAreaSpec.Overlap (imageBounds);
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_DeltaPerColumn::ProcessArea (dng_negative & /* negative */,
+ uint32 /* threadIndex */,
+ dng_pixel_buffer &buffer,
+ const dng_rect &dstArea,
+ const dng_rect & /* imageBounds */)
+ {
+
+ dng_rect overlap = fAreaSpec.Overlap (dstArea);
+
+ if (overlap.NotEmpty ())
+ {
+
+ uint32 rows = (overlap.H () + fAreaSpec.RowPitch () - 1) /
+ fAreaSpec.RowPitch ();
+
+ int32 rowStep = buffer.RowStep () * fAreaSpec.RowPitch ();
+
+ for (uint32 plane = fAreaSpec.Plane ();
+ plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
+ plane < buffer.Planes ();
+ plane++)
+ {
+
+ const real32 *table = fTable->Buffer_real32 () +
+ ((overlap.l - fAreaSpec.Area ().l) /
+ fAreaSpec.ColPitch ());
+
+ for (int32 col = overlap.l; col < overlap.r; col += fAreaSpec.ColPitch ())
+ {
+
+ real32 colDelta = *(table++) * fScale;
+
+ real32 *dPtr = buffer.DirtyPixel_real32 (overlap.t, col, plane);
+
+ for (uint32 row = 0; row < rows; row++)
+ {
+
+ real32 x = dPtr [0];
+
+ real32 y = x + colDelta;
+
+ dPtr [0] = Pin_real32 (0.0f, y, 1.0f);
+
+ dPtr += rowStep;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_ScalePerRow::dng_opcode_ScalePerRow (const dng_area_spec &areaSpec,
+ AutoPtr<dng_memory_block> &table)
+
+ : dng_inplace_opcode (dngOpcode_ScalePerRow,
+ dngVersion_1_3_0_0,
+ kFlag_None)
+
+ , fAreaSpec (areaSpec)
+ , fTable ()
+
+ {
+
+ fTable.Reset (table.Release ());
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_ScalePerRow::dng_opcode_ScalePerRow (dng_host &host,
+ dng_stream &stream)
+
+ : dng_inplace_opcode (dngOpcode_ScalePerRow,
+ stream,
+ "ScalePerRow")
+
+ , fAreaSpec ()
+ , fTable ()
+
+ {
+
+ uint32 dataSize = stream.Get_uint32 ();
+
+ fAreaSpec.GetData (stream);
+
+ uint32 scales = (fAreaSpec.Area ().H () +
+ fAreaSpec.RowPitch () - 1) /
+ fAreaSpec.RowPitch ();
+
+ if (scales != stream.Get_uint32 ())
+ {
+ ThrowBadFormat ();
+ }
+
+ if (dataSize != dng_area_spec::kDataSize + 4 + scales * 4)
+ {
+ ThrowBadFormat ();
+ }
+
+ fTable.Reset (host.Allocate (scales * (uint32) sizeof (real32)));
+
+ real32 *table = fTable->Buffer_real32 ();
+
+ for (uint32 j = 0; j < scales; j++)
+ {
+ table [j] = stream.Get_real32 ();
+ }
+
+ #if qDNGValidate
+
+ if (gVerbose)
+ {
+
+ printf ("Count: %u\n", (unsigned) scales);
+
+ for (uint32 k = 0; k < scales && k < gDumpLineLimit; k++)
+ {
+ printf (" Scale [%u] = %f\n", (unsigned) k, table [k]);
+ }
+
+ if (scales > gDumpLineLimit)
+ {
+ printf (" ... %u scales skipped\n", (unsigned) (scales - gDumpLineLimit));
+ }
+
+ }
+
+ #endif
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_ScalePerRow::PutData (dng_stream &stream) const
+ {
+
+ uint32 scales = (fAreaSpec.Area ().H () +
+ fAreaSpec.RowPitch () - 1) /
+ fAreaSpec.RowPitch ();
+
+ stream.Put_uint32 (dng_area_spec::kDataSize + 4 + scales * 4);
+
+ fAreaSpec.PutData (stream);
+
+ stream.Put_uint32 (scales);
+
+ real32 *table = fTable->Buffer_real32 ();
+
+ for (uint32 j = 0; j < scales; j++)
+ {
+ stream.Put_real32 (table [j]);
+ }
+
+ }
+
+/*****************************************************************************/
+
+uint32 dng_opcode_ScalePerRow::BufferPixelType (uint32 /* imagePixelType */)
+ {
+
+ return ttFloat;
+
+ }
+
+/*****************************************************************************/
+
+dng_rect dng_opcode_ScalePerRow::ModifiedBounds (const dng_rect &imageBounds)
+ {
+
+ return fAreaSpec.Overlap (imageBounds);
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_ScalePerRow::ProcessArea (dng_negative & /* negative */,
+ uint32 /* threadIndex */,
+ dng_pixel_buffer &buffer,
+ const dng_rect &dstArea,
+ const dng_rect & /* imageBounds */)
+ {
+
+ dng_rect overlap = fAreaSpec.Overlap (dstArea);
+
+ if (overlap.NotEmpty ())
+ {
+
+ uint32 cols = overlap.W ();
+
+ uint32 colPitch = fAreaSpec.ColPitch ();
+
+ for (uint32 plane = fAreaSpec.Plane ();
+ plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
+ plane < buffer.Planes ();
+ plane++)
+ {
+
+ const real32 *table = fTable->Buffer_real32 () +
+ ((overlap.t - fAreaSpec.Area ().t) /
+ fAreaSpec.RowPitch ());
+
+ for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ())
+ {
+
+ real32 rowScale = *(table++);
+
+ real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane);
+
+ for (uint32 col = 0; col < cols; col += colPitch)
+ {
+
+ real32 x = dPtr [col];
+
+ real32 y = x * rowScale;
+
+ dPtr [col] = Min_real32 (y, 1.0f);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_ScalePerColumn::dng_opcode_ScalePerColumn (const dng_area_spec &areaSpec,
+ AutoPtr<dng_memory_block> &table)
+
+ : dng_inplace_opcode (dngOpcode_ScalePerColumn,
+ dngVersion_1_3_0_0,
+ kFlag_None)
+
+ , fAreaSpec (areaSpec)
+ , fTable ()
+
+ {
+
+ fTable.Reset (table.Release ());
+
+ }
+
+/*****************************************************************************/
+
+dng_opcode_ScalePerColumn::dng_opcode_ScalePerColumn (dng_host &host,
+ dng_stream &stream)
+
+ : dng_inplace_opcode (dngOpcode_ScalePerColumn,
+ stream,
+ "ScalePerColumn")
+
+ , fAreaSpec ()
+ , fTable ()
+
+ {
+
+ uint32 dataSize = stream.Get_uint32 ();
+
+ fAreaSpec.GetData (stream);
+
+ uint32 scales = (fAreaSpec.Area ().W () +
+ fAreaSpec.ColPitch () - 1) /
+ fAreaSpec.ColPitch ();
+
+ if (scales != stream.Get_uint32 ())
+ {
+ ThrowBadFormat ();
+ }
+
+ if (dataSize != dng_area_spec::kDataSize + 4 + scales * 4)
+ {
+ ThrowBadFormat ();
+ }
+
+ fTable.Reset (host.Allocate (scales * (uint32) sizeof (real32)));
+
+ real32 *table = fTable->Buffer_real32 ();
+
+ for (uint32 j = 0; j < scales; j++)
+ {
+ table [j] = stream.Get_real32 ();
+ }
+
+ #if qDNGValidate
+
+ if (gVerbose)
+ {
+
+ printf ("Count: %u\n", (unsigned) scales);
+
+ for (uint32 k = 0; k < scales && k < gDumpLineLimit; k++)
+ {
+ printf (" Scale [%u] = %f\n", (unsigned) k, table [k]);
+ }
+
+ if (scales > gDumpLineLimit)
+ {
+ printf (" ... %u deltas skipped\n", (unsigned) (scales - gDumpLineLimit));
+ }
+
+ }
+
+ #endif
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_ScalePerColumn::PutData (dng_stream &stream) const
+ {
+
+ uint32 scales = (fAreaSpec.Area ().W () +
+ fAreaSpec.ColPitch () - 1) /
+ fAreaSpec.ColPitch ();
+
+ stream.Put_uint32 (dng_area_spec::kDataSize + 4 + scales * 4);
+
+ fAreaSpec.PutData (stream);
+
+ stream.Put_uint32 (scales);
+
+ real32 *table = fTable->Buffer_real32 ();
+
+ for (uint32 j = 0; j < scales; j++)
+ {
+ stream.Put_real32 (table [j]);
+ }
+
+ }
+
+/*****************************************************************************/
+
+uint32 dng_opcode_ScalePerColumn::BufferPixelType (uint32 /* imagePixelType */)
+ {
+
+ return ttFloat;
+
+ }
+
+/*****************************************************************************/
+
+dng_rect dng_opcode_ScalePerColumn::ModifiedBounds (const dng_rect &imageBounds)
+ {
+
+ return fAreaSpec.Overlap (imageBounds);
+
+ }
+
+/*****************************************************************************/
+
+void dng_opcode_ScalePerColumn::ProcessArea (dng_negative & /* negative */,
+ uint32 /* threadIndex */,
+ dng_pixel_buffer &buffer,
+ const dng_rect &dstArea,
+ const dng_rect & /* imageBounds */)
+ {
+
+ dng_rect overlap = fAreaSpec.Overlap (dstArea);
+
+ if (overlap.NotEmpty ())
+ {
+
+ uint32 rows = (overlap.H () + fAreaSpec.RowPitch () - 1) /
+ fAreaSpec.RowPitch ();
+
+ int32 rowStep = buffer.RowStep () * fAreaSpec.RowPitch ();
+
+ for (uint32 plane = fAreaSpec.Plane ();
+ plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
+ plane < buffer.Planes ();
+ plane++)
+ {
+
+ const real32 *table = fTable->Buffer_real32 () +
+ ((overlap.l - fAreaSpec.Area ().l) /
+ fAreaSpec.ColPitch ());
+
+ for (int32 col = overlap.l; col < overlap.r; col += fAreaSpec.ColPitch ())
+ {
+
+ real32 colScale = *(table++);
+
+ real32 *dPtr = buffer.DirtyPixel_real32 (overlap.t, col, plane);
+
+ for (uint32 row = 0; row < rows; row++)
+ {
+
+ real32 x = dPtr [0];
+
+ real32 y = x * colScale;
+
+ dPtr [0] = Min_real32 (y, 1.0f);
+
+ dPtr += rowStep;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+/*****************************************************************************/