| /*****************************************************************************/ |
| // Copyright 2006-2008 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_1d_table.cpp#1 $ */ |
| /* $DateTime: 2012/05/30 13:28:51 $ */ |
| /* $Change: 832332 $ */ |
| /* $Author: tknoll $ */ |
| |
| /*****************************************************************************/ |
| |
| #include "dng_1d_table.h" |
| |
| #include "dng_1d_function.h" |
| #include "dng_memory.h" |
| #include "dng_utils.h" |
| |
| /*****************************************************************************/ |
| |
| dng_1d_table::dng_1d_table () |
| |
| : fBuffer () |
| , fTable (NULL) |
| |
| { |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| dng_1d_table::~dng_1d_table () |
| { |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| void dng_1d_table::SubDivide (const dng_1d_function &function, |
| uint32 lower, |
| uint32 upper, |
| real32 maxDelta) |
| { |
| |
| uint32 range = upper - lower; |
| |
| bool subDivide = (range > (kTableSize >> 8)); |
| |
| if (!subDivide) |
| { |
| |
| real32 delta = Abs_real32 (fTable [upper] - |
| fTable [lower]); |
| |
| if (delta > maxDelta) |
| { |
| |
| subDivide = true; |
| |
| } |
| |
| } |
| |
| if (subDivide) |
| { |
| |
| uint32 middle = (lower + upper) >> 1; |
| |
| fTable [middle] = (real32) function.Evaluate (middle * (1.0 / (real64) kTableSize)); |
| |
| if (range > 2) |
| { |
| |
| SubDivide (function, lower, middle, maxDelta); |
| |
| SubDivide (function, middle, upper, maxDelta); |
| |
| } |
| |
| } |
| |
| else |
| { |
| |
| real64 y0 = fTable [lower]; |
| real64 y1 = fTable [upper]; |
| |
| real64 delta = (y1 - y0) / (real64) range; |
| |
| for (uint32 j = lower + 1; j < upper; j++) |
| { |
| |
| y0 += delta; |
| |
| fTable [j] = (real32) y0; |
| |
| } |
| |
| } |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| void dng_1d_table::Initialize (dng_memory_allocator &allocator, |
| const dng_1d_function &function, |
| bool subSample) |
| { |
| |
| fBuffer.Reset (allocator.Allocate ((kTableSize + 2) * sizeof (real32))); |
| |
| fTable = fBuffer->Buffer_real32 (); |
| |
| if (subSample) |
| { |
| |
| fTable [0 ] = (real32) function.Evaluate (0.0); |
| fTable [kTableSize] = (real32) function.Evaluate (1.0); |
| |
| real32 maxDelta = Max_real32 (Abs_real32 (fTable [kTableSize] - |
| fTable [0 ]), 1.0f) * |
| (1.0f / 256.0f); |
| |
| SubDivide (function, |
| 0, |
| kTableSize, |
| maxDelta); |
| |
| } |
| |
| else |
| { |
| |
| for (uint32 j = 0; j <= kTableSize; j++) |
| { |
| |
| real64 x = j * (1.0 / (real64) kTableSize); |
| |
| real64 y = function.Evaluate (x); |
| |
| fTable [j] = (real32) y; |
| |
| } |
| |
| } |
| |
| fTable [kTableSize + 1] = fTable [kTableSize]; |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| void dng_1d_table::Expand16 (uint16 *table16) const |
| { |
| |
| real64 step = (real64) kTableSize / 65535.0; |
| |
| real64 y0 = fTable [0]; |
| real64 y1 = fTable [1]; |
| |
| real64 base = y0 * 65535.0 + 0.5; |
| real64 slope = (y1 - y0) * 65535.0; |
| |
| uint32 index = 1; |
| real64 fract = 0.0; |
| |
| for (uint32 j = 0; j < 0x10000; j++) |
| { |
| |
| table16 [j] = (uint16) (base + slope * fract); |
| |
| fract += step; |
| |
| if (fract > 1.0) |
| { |
| |
| index += 1; |
| fract -= 1.0; |
| |
| y0 = y1; |
| y1 = fTable [index]; |
| |
| base = y0 * 65535.0 + 0.5; |
| slope = (y1 - y0) * 65535.0; |
| |
| } |
| |
| } |
| |
| } |
| |
| /*****************************************************************************/ |