summaryrefslogtreecommitdiff
path: root/gpr/source/lib/dng_sdk/dng_hue_sat_map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gpr/source/lib/dng_sdk/dng_hue_sat_map.cpp')
-rw-r--r--gpr/source/lib/dng_sdk/dng_hue_sat_map.cpp367
1 files changed, 367 insertions, 0 deletions
diff --git a/gpr/source/lib/dng_sdk/dng_hue_sat_map.cpp b/gpr/source/lib/dng_sdk/dng_hue_sat_map.cpp
new file mode 100644
index 0000000..8fddcca
--- /dev/null
+++ b/gpr/source/lib/dng_sdk/dng_hue_sat_map.cpp
@@ -0,0 +1,367 @@
+/*****************************************************************************/
+// Copyright 2007 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_hue_sat_map.cpp#1 $ */
+/* $DateTime: 2012/05/30 13:28:51 $ */
+/* $Change: 832332 $ */
+/* $Author: tknoll $ */
+
+/*****************************************************************************/
+
+#include "dng_hue_sat_map.h"
+
+#include "dng_assertions.h"
+#include "dng_auto_ptr.h"
+#include "dng_bottlenecks.h"
+#include "dng_exceptions.h"
+#include "dng_host.h"
+
+#include "stdc_includes.h"
+
+/*****************************************************************************/
+
+dng_hue_sat_map::dng_hue_sat_map ()
+
+ : fHueDivisions (0)
+ , fSatDivisions (0)
+ , fValDivisions (0)
+ , fHueStep (0)
+ , fValStep (0)
+ , fDeltas ()
+
+ {
+
+ }
+
+/*****************************************************************************/
+
+dng_hue_sat_map::dng_hue_sat_map (const dng_hue_sat_map &src)
+
+ : fHueDivisions (0)
+ , fSatDivisions (0)
+ , fValDivisions (0)
+ , fHueStep (0)
+ , fValStep (0)
+ , fDeltas ()
+
+ {
+
+ *this = src;
+
+ }
+
+/*****************************************************************************/
+
+dng_hue_sat_map &dng_hue_sat_map::operator= (const dng_hue_sat_map &rhs)
+ {
+
+ if (this != &rhs)
+ {
+
+ if (!rhs.IsValid ())
+ {
+
+ SetInvalid ();
+
+ }
+
+ else
+ {
+
+ fHueDivisions = rhs.fHueDivisions;
+ fSatDivisions = rhs.fSatDivisions;
+ fValDivisions = rhs.fValDivisions;
+
+ fHueStep = rhs.fHueStep;
+ fValStep = rhs.fValStep;
+
+ fDeltas = rhs.fDeltas;
+
+ }
+
+ }
+
+ return *this;
+
+ }
+
+/*****************************************************************************/
+
+dng_hue_sat_map::~dng_hue_sat_map ()
+ {
+
+ }
+
+/*****************************************************************************/
+
+void dng_hue_sat_map::SetDivisions (uint32 hueDivisions,
+ uint32 satDivisions,
+ uint32 valDivisions)
+ {
+
+ DNG_ASSERT (hueDivisions >= 1, "Must have at least 1 hue division.");
+ DNG_ASSERT (satDivisions >= 2, "Must have at least 2 sat divisions.");
+
+ if (valDivisions == 0)
+ valDivisions = 1;
+
+ if (hueDivisions == fHueDivisions &&
+ satDivisions == fSatDivisions &&
+ valDivisions == fValDivisions)
+ {
+ return;
+ }
+
+ fHueDivisions = hueDivisions;
+ fSatDivisions = satDivisions;
+ fValDivisions = valDivisions;
+
+ fHueStep = satDivisions;
+ fValStep = hueDivisions * fHueStep;
+
+ uint32 size = DeltasCount () * (uint32) sizeof (HSBModify);
+
+ fDeltas.Allocate (size);
+
+ DoZeroBytes (fDeltas.Buffer (), size);
+
+ }
+
+/*****************************************************************************/
+
+void dng_hue_sat_map::GetDelta (uint32 hueDiv,
+ uint32 satDiv,
+ uint32 valDiv,
+ HSBModify &modify) const
+ {
+
+ if (hueDiv >= fHueDivisions ||
+ satDiv >= fSatDivisions ||
+ valDiv >= fValDivisions ||
+ fDeltas.Buffer () == NULL)
+ {
+
+ DNG_REPORT ("Bad parameters to dng_hue_sat_map::GetDelta");
+
+ ThrowProgramError ();
+
+ }
+
+ int32 offset = valDiv * fValStep +
+ hueDiv * fHueStep +
+ satDiv;
+
+ const HSBModify *deltas = GetConstDeltas ();
+
+ modify.fHueShift = deltas [offset].fHueShift;
+ modify.fSatScale = deltas [offset].fSatScale;
+ modify.fValScale = deltas [offset].fValScale;
+
+ }
+
+/*****************************************************************************/
+
+void dng_hue_sat_map::SetDeltaKnownWriteable (uint32 hueDiv,
+ uint32 satDiv,
+ uint32 valDiv,
+ const HSBModify &modify)
+ {
+
+ if (hueDiv >= fHueDivisions ||
+ satDiv >= fSatDivisions ||
+ valDiv >= fValDivisions ||
+ fDeltas.Buffer () == NULL)
+ {
+
+ DNG_REPORT ("Bad parameters to dng_hue_sat_map::SetDelta");
+
+ ThrowProgramError ();
+
+ }
+
+ // Set this entry.
+
+ int32 offset = valDiv * fValStep +
+ hueDiv * fHueStep +
+ satDiv;
+
+ SafeGetDeltas () [offset] = modify;
+
+ // The zero saturation entry is required to have a value scale
+ // of 1.0f.
+
+ if (satDiv == 0)
+ {
+
+ if (modify.fValScale != 1.0f)
+ {
+
+ #if qDNGValidate
+
+ ReportWarning ("Value scale for zero saturation entries must be 1.0");
+
+ #endif
+
+ SafeGetDeltas () [offset] . fValScale = 1.0f;
+
+ }
+
+ }
+
+ // If we are settings the first saturation entry and we have not
+ // set the zero saturation entry yet, fill in the zero saturation entry
+ // by extrapolating first saturation entry.
+
+ if (satDiv == 1)
+ {
+
+ HSBModify zeroSatModify;
+
+ GetDelta (hueDiv, 0, valDiv, zeroSatModify);
+
+ if (zeroSatModify.fValScale != 1.0f)
+ {
+
+ zeroSatModify.fHueShift = modify.fHueShift;
+ zeroSatModify.fSatScale = modify.fSatScale;
+ zeroSatModify.fValScale = 1.0f;
+
+ SetDelta (hueDiv, 0, valDiv, zeroSatModify);
+
+ }
+
+ }
+
+ }
+
+/*****************************************************************************/
+
+bool dng_hue_sat_map::operator== (const dng_hue_sat_map &rhs) const
+ {
+
+ if (fHueDivisions != rhs.fHueDivisions ||
+ fSatDivisions != rhs.fSatDivisions ||
+ fValDivisions != rhs.fValDivisions)
+ return false;
+
+ if (!IsValid ())
+ return true;
+
+ return memcmp (GetConstDeltas (),
+ rhs.GetConstDeltas (),
+ DeltasCount () * sizeof (HSBModify)) == 0;
+
+ }
+
+/*****************************************************************************/
+
+dng_hue_sat_map * dng_hue_sat_map::Interpolate (const dng_hue_sat_map &map1,
+ const dng_hue_sat_map &map2,
+ real64 weight1)
+ {
+
+ if (weight1 >= 1.0)
+ {
+
+ if (!map1.IsValid ())
+ {
+
+ DNG_REPORT ("map1 is not valid");
+
+ ThrowProgramError ();
+
+ }
+
+ return new dng_hue_sat_map (map1);
+
+ }
+
+ if (weight1 <= 0.0)
+ {
+
+ if (!map2.IsValid ())
+ {
+ DNG_REPORT ("map2 is not valid");
+
+ ThrowProgramError ();
+
+ }
+
+ return new dng_hue_sat_map (map2);
+
+ }
+
+ // Both maps must be valid if we are using both.
+
+ if (!map1.IsValid () || !map2.IsValid ())
+ {
+
+ DNG_REPORT ("map1 or map2 is not valid");
+
+ ThrowProgramError ();
+
+ }
+
+ // Must have the same dimensions.
+
+ if (map1.fHueDivisions != map2.fHueDivisions ||
+ map1.fSatDivisions != map2.fSatDivisions ||
+ map1.fValDivisions != map2.fValDivisions)
+ {
+
+ DNG_REPORT ("map1 and map2 have different sizes");
+
+ ThrowProgramError ();
+
+ }
+
+ // Make table to hold interpolated results.
+
+ AutoPtr<dng_hue_sat_map> result (new dng_hue_sat_map);
+
+ result->SetDivisions (map1.fHueDivisions,
+ map1.fSatDivisions,
+ map1.fValDivisions);
+
+ // Interpolate between the tables.
+
+ real32 w1 = (real32) weight1;
+ real32 w2 = 1.0f - w1;
+
+ const HSBModify *data1 = map1.GetConstDeltas ();
+ const HSBModify *data2 = map2.GetConstDeltas ();
+
+ HSBModify *data3 = result->SafeGetDeltas ();
+
+ uint32 count = map1.DeltasCount ();
+
+ for (uint32 index = 0; index < count; index++)
+ {
+
+ data3->fHueShift = w1 * data1->fHueShift +
+ w2 * data2->fHueShift;
+
+ data3->fSatScale = w1 * data1->fSatScale +
+ w2 * data2->fSatScale;
+
+ data3->fValScale = w1 * data1->fValScale +
+ w2 * data2->fValScale;
+
+ data1++;
+ data2++;
+ data3++;
+
+ }
+
+ // Return interpolated tables.
+
+ return result.Release ();
+
+ }
+
+/*****************************************************************************/