You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
366 lines
7.3 KiB
366 lines
7.3 KiB
/*****************************************************************************/
|
|
// 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"
|
|
|
|
/*****************************************************************************/
|
|
|
|
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 = SafeUint32Mult(hueDivisions, fHueStep);
|
|
|
|
uint32 size = SafeUint32Mult(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 ();
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|