18e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
28e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener// Copyright 2008-2009 Adobe Systems Incorporated
38e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener// All Rights Reserved.
48e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener//
58e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener// NOTICE:  Adobe permits you to use, modify, and distribute this file in
68e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener// accordance with the terms of the Adobe license agreement accompanying it.
78e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
88e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
98e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_gain_map.cpp#1 $ */
108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/* $DateTime: 2012/05/30 13:28:51 $ */
118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/* $Change: 832332 $ */
128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/* $Author: tknoll $ */
138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_gain_map.h"
178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_exceptions.h"
198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_globals.h"
208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_host.h"
218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_pixel_buffer.h"
227841298310de58d0cddb212ac6295d9a27cf547cFlorian Kriener#include "dng_safe_arithmetic.h"
238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_stream.h"
248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_tag_values.h"
258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
288e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerclass dng_gain_map_interpolator
298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	private:
328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		const dng_gain_map &fMap;
348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		dng_point_real64 fScale;
368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		dng_point_real64 fOffset;
378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		int32 fColumn;
398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		int32 fPlane;
408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint32 fRowIndex1;
428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint32 fRowIndex2;
438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		real32 fRowFract;
448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		int32 fResetColumn;
468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		real32 fValueBase;
488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		real32 fValueStep;
498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		real32 fValueIndex;
508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	public:
528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		dng_gain_map_interpolator (const dng_gain_map &map,
548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								   const dng_rect &mapBounds,
558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								   int32 row,
568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								   int32 column,
578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								   uint32 plane);
588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		real32 Interpolate () const
608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			return fValueBase + fValueStep * fValueIndex;
638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		void Increment ()
678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			if (++fColumn >= fResetColumn)
708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				{
718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				ResetColumn ();
738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				}
758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			else
778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				{
788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				fValueIndex += 1.0f;
808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				}
828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	private:
868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		real32 InterpolateEntry (uint32 colIndex);
888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		void ResetColumn ();
908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	};
928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
958e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerdng_gain_map_interpolator::dng_gain_map_interpolator (const dng_gain_map &map,
968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener													  const dng_rect &mapBounds,
978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener													  int32 row,
988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener													  int32 column,
998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener													  uint32 plane)
1008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	:	fMap (map)
1028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fScale (1.0 / mapBounds.H (),
1048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				1.0 / mapBounds.W ())
1058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fOffset (0.5 - mapBounds.t,
1078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 0.5 - mapBounds.l)
1088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fColumn (column)
1108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fPlane  (plane)
1118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fRowIndex1 (0)
1138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fRowIndex2 (0)
1148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fRowFract  (0.0f)
1158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fResetColumn (0)
1178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fValueBase  (0.0f)
1198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fValueStep  (0.0f)
1208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fValueIndex (0.0f)
1218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
1238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	real64 rowIndexF = (fScale.v * (row + fOffset.v) -
1258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						fMap.Origin ().v) / fMap.Spacing ().v;
1268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (rowIndexF <= 0.0)
1288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		fRowIndex1 = 0;
1318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		fRowIndex2 = 0;
1328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		fRowFract = 0.0f;
1348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	else
1388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (fMap.Points ().v < 1)
1418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
1428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			ThrowProgramError ("Empty gain map");
1438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
1448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint32 lastRow = static_cast<uint32> (fMap.Points ().v - 1);
1458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (rowIndexF >= static_cast<real64> (lastRow))
1478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
1488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fRowIndex1 = lastRow;
1508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fRowIndex2 = fRowIndex1;
1518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fRowFract = 0.0f;
1538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
1558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		else
1578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
1588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			// If we got here, we know that rowIndexF can safely be converted to
1608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			// a uint32 and that static_cast<uint32> (rowIndexF) < lastRow. This
1618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			// implies fRowIndex2 <= lastRow below.
1628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fRowIndex1 = static_cast<uint32> (rowIndexF);
1638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fRowIndex2 = fRowIndex1 + 1;
1648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fRowFract = (real32) (rowIndexF - (real64) fRowIndex1);
1668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
1688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	ResetColumn ();
1728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
1748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
1768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1778e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerreal32 dng_gain_map_interpolator::InterpolateEntry (uint32 colIndex)
1788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
1798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	return fMap.Entry (fRowIndex1, colIndex, fPlane) * (1.0f - fRowFract) +
1818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		   fMap.Entry (fRowIndex2, colIndex, fPlane) * (       fRowFract);
1828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
1848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
1868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1878e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienervoid dng_gain_map_interpolator::ResetColumn ()
1888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
1898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	real64 colIndexF = ((fScale.h * (fColumn + fOffset.h)) -
1918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						fMap.Origin ().h) / fMap.Spacing ().h;
1928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (colIndexF <= 0.0)
1948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		fValueBase = InterpolateEntry (0);
1978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		fValueStep = 0.0f;
1998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		fResetColumn = (int32) ceil (fMap.Origin ().h / fScale.h - fOffset.h);
2018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
2038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	else
2058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
2068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (fMap.Points ().h < 1)
2088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
2098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			ThrowProgramError ("Empty gain map");
2108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
2118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint32 lastCol = static_cast<uint32> (fMap.Points ().h - 1);
2128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (colIndexF >= static_cast<real64> (lastCol))
2148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
2158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fValueBase = InterpolateEntry (lastCol);
2178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fValueStep = 0.0f;
2198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fResetColumn = 0x7FFFFFFF;
2218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
2238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		else
2258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
2268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			// If we got here, we know that colIndexF can safely be converted to
2288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			// a uint32 and that static_cast<uint32> (colIndexF) < lastCol. This
2298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			// implies colIndex + 1 <= lastCol, i.e. the argument to
2308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			// InterpolateEntry() below is valid.
2318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			uint32 colIndex = static_cast<uint32> (colIndexF);
2328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			real64 base  = InterpolateEntry (colIndex);
2338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			real64 delta = InterpolateEntry (colIndex + 1) - base;
2348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fValueBase = (real32) (base + delta * (colIndexF - (real64) colIndex));
2368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fValueStep = (real32) ((delta * fScale.h) / fMap.Spacing ().h);
2388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			fResetColumn = (int32) ceil (((colIndex + 1) * fMap.Spacing ().h +
2408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener										  fMap.Origin ().h) / fScale.h - fOffset.h);
2418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
2438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
2458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	fValueIndex = 0.0f;
2478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
2498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
2518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2528e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerdng_gain_map::dng_gain_map (dng_memory_allocator &allocator,
2538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							const dng_point &points,
2548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							const dng_point_real64 &spacing,
2558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							const dng_point_real64 &origin,
2568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							uint32 planes)
2578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	:	fPoints  (points)
2598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fSpacing (spacing)
2608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fOrigin  (origin)
2618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fPlanes  (planes)
2628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2637841298310de58d0cddb212ac6295d9a27cf547cFlorian Kriener	,	fRowStep (SafeUint32Mult(planes, points.h))
2648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fBuffer ()
2668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
2688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	fBuffer.Reset (allocator.Allocate (
2708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		ComputeBufferSize (ttFloat, fPoints, fPlanes, pad16Bytes)));
2718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
2738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
2758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2768e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerreal32 dng_gain_map::Interpolate (int32 row,
2778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								  int32 col,
2788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								  uint32 plane,
2798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								  const dng_rect &bounds) const
2808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
2818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	dng_gain_map_interpolator interp (*this,
2838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener									  bounds,
2848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener									  row,
2858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener									  col,
2868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener									  plane);
2878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	return interp.Interpolate ();
2898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
2918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
2938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2948e8939fc10ad63576a2785ba1333a23726b7e164Florian Krieneruint32 dng_gain_map::PutStreamSize () const
2958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
2968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	return 44 + fPoints.v * fPoints.h * fPlanes * 4;
2988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
3008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
3028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3038e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienervoid dng_gain_map::PutStream (dng_stream &stream) const
3048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
3058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_uint32 (fPoints.v);
3078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_uint32 (fPoints.h);
3088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_real64 (fSpacing.v);
3108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_real64 (fSpacing.h);
3118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_real64 (fOrigin.v);
3138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_real64 (fOrigin.h);
3148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_uint32 (fPlanes);
3168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	for (int32 rowIndex = 0; rowIndex < fPoints.v; rowIndex++)
3188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
3198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		for (int32 colIndex = 0; colIndex < fPoints.h; colIndex++)
3218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
3228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			for (uint32 plane = 0; plane < fPlanes; plane++)
3248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				{
3258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				stream.Put_real32 (Entry (rowIndex,
3278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener										  colIndex,
3288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener										  plane));
3298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				}
3318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
3338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
3358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
3378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
3398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3408e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerdng_gain_map * dng_gain_map::GetStream (dng_host &host,
3418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener										dng_stream &stream)
3428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
3438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	dng_point mapPoints;
3458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	mapPoints.v = stream.Get_uint32 ();
3478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	mapPoints.h = stream.Get_uint32 ();
3488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	dng_point_real64 mapSpacing;
3508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	mapSpacing.v = stream.Get_real64 ();
3528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	mapSpacing.h = stream.Get_real64 ();
3538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	dng_point_real64 mapOrigin;
3558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	mapOrigin.v = stream.Get_real64 ();
3578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	mapOrigin.h = stream.Get_real64 ();
3588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	uint32 mapPlanes = stream.Get_uint32 ();
3608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	#if qDNGValidate
3628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (gVerbose)
3648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
3658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		printf ("Points: v=%d, h=%d\n",
3678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				(int) mapPoints.v,
3688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				(int) mapPoints.h);
3698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		printf ("Spacing: v=%.6f, h=%.6f\n",
3718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				mapSpacing.v,
3728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				mapSpacing.h);
3738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		printf ("Origin: v=%.6f, h=%.6f\n",
3758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				mapOrigin.v,
3768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				mapOrigin.h);
3778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		printf ("Planes: %u\n",
3798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				(unsigned) mapPlanes);
3808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
3828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	#endif
3848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (mapPoints.v == 1)
3868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
3878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		mapSpacing.v = 1.0;
3888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		mapOrigin.v  = 0.0;
3898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
3908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (mapPoints.h == 1)
3928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
3938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		mapSpacing.h = 1.0;
3948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		mapOrigin.h  = 0.0;
3958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
3968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (mapPoints.v < 1 ||
3988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		mapPoints.h < 1 ||
3998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		mapSpacing.v <= 0.0 ||
4008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		mapSpacing.h <= 0.0 ||
4018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		mapPlanes < 1)
4028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
4038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		ThrowBadFormat ();
4048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
4058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	AutoPtr<dng_gain_map> map (new dng_gain_map (host.Allocator (),
4078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener												 mapPoints,
4088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener												 mapSpacing,
4098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener												 mapOrigin,
4108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener												 mapPlanes));
4118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	#if qDNGValidate
4138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	uint32 linesPrinted = 0;
4158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	uint32 linesSkipped = 0;
4168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	#endif
4188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	for (int32 rowIndex = 0; rowIndex < mapPoints.v; rowIndex++)
4208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
4218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		for (int32 colIndex = 0; colIndex < mapPoints.h; colIndex++)
4238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
4248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			for (uint32 plane = 0; plane < mapPlanes; plane++)
4268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				{
4278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				real32 x = stream.Get_real32 ();
4298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				map->Entry (rowIndex, colIndex, plane) = x;
4318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				#if qDNGValidate
4338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				if (gVerbose)
4358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
4368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					if (linesPrinted < gDumpLineLimit)
4388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
4398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						printf ("    Map [%3u] [%3u] [%u] = %.4f\n",
4418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								(unsigned) rowIndex,
4428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								(unsigned) colIndex,
4438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								(unsigned) plane,
4448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener								x);
4458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						linesPrinted++;
4478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
4498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					else
4518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						linesSkipped++;
4528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
4548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				#endif
4568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				}
4588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
4608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
4628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	#if qDNGValidate
4648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (linesSkipped)
4668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
4678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		printf ("    ... %u map entries skipped\n", (unsigned) linesSkipped);
4698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
4718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	#endif
4738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	return map.Release ();
4758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
4778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
4798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4808e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerdng_opcode_GainMap::dng_opcode_GainMap (const dng_area_spec &areaSpec,
4818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener										AutoPtr<dng_gain_map> &gainMap)
4828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	:	dng_inplace_opcode (dngOpcode_GainMap,
4848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						    dngVersion_1_3_0_0,
4858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						    kFlag_None)
4868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fAreaSpec (areaSpec)
4888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fGainMap ()
4908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
4928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	fGainMap.Reset (gainMap.Release ());
4948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
4968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
4988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4998e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerdng_opcode_GainMap::dng_opcode_GainMap (dng_host &host,
5008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener										dng_stream &stream)
5018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	:	dng_inplace_opcode (dngOpcode_GainMap,
5038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							stream,
5048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							"GainMap")
5058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fAreaSpec ()
5078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fGainMap ()
5098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
5118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	uint32 byteCount = stream.Get_uint32 ();
5138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	uint64 startPosition = stream.Position ();
5158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	fAreaSpec.GetData (stream);
5178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	fGainMap.Reset (dng_gain_map::GetStream (host, stream));
5198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (stream.Position () != startPosition + byteCount)
5218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
5228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		ThrowBadFormat ();
5238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
5248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
5268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
5288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5298e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienervoid dng_opcode_GainMap::PutData (dng_stream &stream) const
5308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
5318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_uint32 (dng_area_spec::kDataSize +
5338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					   fGainMap->PutStreamSize ());
5348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	fAreaSpec.PutData (stream);
5368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	fGainMap->PutStream (stream);
5388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
5408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
5428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5438e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienervoid dng_opcode_GainMap::ProcessArea (dng_negative & /* negative */,
5448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener									  uint32 /* threadIndex */,
5458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener									  dng_pixel_buffer &buffer,
5468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener									  const dng_rect &dstArea,
5478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener									  const dng_rect &imageBounds)
5488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
5498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	dng_rect overlap = fAreaSpec.Overlap (dstArea);
5518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (overlap.NotEmpty ())
5538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
5548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint32 cols = overlap.W ();
5568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint32 colPitch = fAreaSpec.ColPitch ();
5588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		for (uint32 plane = fAreaSpec.Plane ();
5608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			 plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
5618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			 plane < buffer.Planes ();
5628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			 plane++)
5638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
5648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			uint32 mapPlane = Min_uint32 (plane, fGainMap->Planes () - 1);
5668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ())
5688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				{
5698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane);
5718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				dng_gain_map_interpolator interp (*fGainMap,
5738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener												  imageBounds,
5748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener												  row,
5758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener												  overlap.l,
5768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener												  mapPlane);
5778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				for (uint32 col = 0; col < cols; col += colPitch)
5798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					real32 gain = interp.Interpolate ();
5828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					dPtr [col] = Min_real32 (dPtr [col] * gain, 1.0f);
5848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					for (uint32 j = 0; j < colPitch; j++)
5868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
5878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						interp.Increment ();
5888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
5898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				}
5938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
5958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
5978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
5998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
601