16e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
26e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// Copyright 2008 Adobe Systems Incorporated
36e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// All Rights Reserved.
46e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim//
56e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// NOTICE:	Adobe permits you to use, modify, and distribute this file in
66e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// accordance with the terms of the Adobe license agreement accompanying it.
76e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
86e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
96e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_lens_correction.cpp#1 $ */
106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $DateTime: 2012/05/30 13:28:51 $ */
116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $Change: 832332 $ */
126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $Author: tknoll $ */
136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include <cfloat>
176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include <limits.h>
186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_1d_table.h"
206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_assertions.h"
216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_bottlenecks.h"
226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_exceptions.h"
236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_filter_task.h"
246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_globals.h"
256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_host.h"
266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_image.h"
276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_lens_correction.h"
286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_negative.h"
296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_safe_arithmetic.h"
306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_sdk_limits.h"
316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_tag_values.h"
32c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener#include "dng_utils.h"
336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_warp_params::dng_warp_params ()
376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	fPlanes (1)
396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fCenter (0.5, 0.5)
406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_warp_params::dng_warp_params (uint32 planes,
486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								  const dng_point_real64 &center)
496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	fPlanes (planes)
516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fCenter (center)
526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (planes >= 1,			   "Too few planes." );
566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (planes <= kMaxColorPlanes, "Too many planes.");
576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (fCenter.h >= 0.0 && fCenter.h <= 1.0,
596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				"Center (horizontal) out of range.");
606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (fCenter.v >= 0.0 && fCenter.v <= 1.0,
626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				"Center (vertical) out of range.");
636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_warp_params::~dng_warp_params ()
696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params::IsNOPAll () const
766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return IsRadNOPAll () &&
796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		   IsTanNOPAll ();
806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params::IsNOP (uint32 plane) const
866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return IsRadNOP (plane) &&
896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		   IsTanNOP (plane);
906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params::IsRadNOPAll () const
966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fPlanes; plane++)
996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (!IsRadNOP (plane))
1026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
1036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			return false;
1046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
1056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return true;
1096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
1116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params::IsRadNOP (uint32 /* plane */) const
1156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
1166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return false;
1186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
1206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params::IsTanNOPAll () const
1246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
1256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fPlanes; plane++)
1276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (!IsTanNOP (plane))
1306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
1316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			return false;
1326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
1336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return true;
1376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
1396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params::IsTanNOP (uint32 /* plane */) const
1436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
1446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return false;
1466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
1486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params::IsValid () const
1526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
1536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (fPlanes < 1 || fPlanes > kMaxColorPlanes)
1556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		return false;
1586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (fCenter.h < 0.0 ||
1626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fCenter.h > 1.0 ||
1636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fCenter.v < 0.0 ||
1646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fCenter.v > 1.0)
1656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		return false;
1686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return true;
1726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
1746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params::IsValidForNegative (const dng_negative &negative) const
1786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
1796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (!IsValid ())
1816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		return false;
1836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if ((fPlanes != 1) &&
1866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		(fPlanes != negative.ColorChannels ()))
1876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		return false;
1896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return true;
1926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
1946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 dng_warp_params::EvaluateInverse (uint32 plane,
1986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										 real64 y) const
1996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
2006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 kMaxIterations = 30;
2026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 kNearZero		= 1.0e-10;
2036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	real64 x0 = 0.0;
2056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	real64 y0 = Evaluate (plane,
2066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						  x0);
2076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	real64 x1 = 1.0;
2096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	real64 y1 = Evaluate (plane,
2106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						  x1);
2116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 iteration = 0; iteration < kMaxIterations; iteration++)
2136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
2146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (Abs_real64 (y1 - y0) < kNearZero)
2166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
2176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			break;
2186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
2196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 x2 = Pin_real64 (0.0,
2216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									  x1 + (y - y1) * (x1 - x0) / (y1 - y0),
2226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									  1.0);
2236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 y2 = Evaluate (plane,
2256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									x2);
2266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		x0 = x1;
2286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		y0 = y1;
2296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		x1 = x2;
2316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		y1 = y2;
2326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
2346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return x1;
2366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
2386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
2406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_point_real64 dng_warp_params::EvaluateTangential2 (uint32 plane,
2426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													   const dng_point_real64 &diff) const
2436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
2446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 dvdv = diff.v * diff.v;
2466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 dhdh = diff.h * diff.h;
2476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 rr = dvdv + dhdh;
2496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_point_real64 diffSqr (dvdv,
2516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							  dhdh);
2526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return EvaluateTangential (plane,
2546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							   rr,
2556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							   diff,
2566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							   diffSqr);
2576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
2596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
2616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_point_real64 dng_warp_params::EvaluateTangential3 (uint32 plane,
2636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													   real64 r2,
2646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													   const dng_point_real64 &diff) const
2656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
2666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_point_real64 diffSqr (diff.v * diff.v,
2686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							  diff.h * diff.h);
2696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return EvaluateTangential (plane,
2716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							   r2,
2726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							   diff,
2736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							   diffSqr);
2746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
2766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
2786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_warp_params::Dump () const
2806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
2816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNGValidate
2836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	printf ("Planes: %u\n", (unsigned) fPlanes);
2856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	printf ("  Optical center:\n"
2876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			"    h = %.6lf\n"
2886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			"    v = %.6lf\n",
2896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			fCenter.h,
2906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			fCenter.v);
2916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
2936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
2956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
2976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_warp_params_rectilinear::dng_warp_params_rectilinear ()
2996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_warp_params ()
3016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < kMaxColorPlanes; plane++)
3056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
3066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fRadParams [plane] = dng_vector (4);
3086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fTanParams [plane] = dng_vector (2);
3096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fRadParams [plane][0] = 1.0;
3116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
3136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_warp_params_rectilinear::dng_warp_params_rectilinear (uint32 planes,
3196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														  const dng_vector radParams [],
3206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														  const dng_vector tanParams [],
3216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														  const dng_point_real64 &center)
3226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_warp_params (planes,
3246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 center)
3256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 i = 0; i < fPlanes; i++)
3296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
3306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fRadParams [i] = radParams [i];
3316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fTanParams [i] = tanParams [i];
3326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
3336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_warp_params_rectilinear::~dng_warp_params_rectilinear ()
3396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params_rectilinear::IsRadNOP (uint32 plane) const
3466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (plane < fPlanes, "plane out of range.");
3496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_vector &r = fRadParams [plane];
3516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return (r [0] == 1.0 &&
3536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			r [1] == 0.0 &&
3546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			r [2] == 0.0 &&
3556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			r [3] == 0.0);
3566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params_rectilinear::IsTanNOP (uint32 plane) const
3626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (plane < fPlanes, "plane out of range.");
3656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_vector &t = fTanParams [plane];
3676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return (t [0] == 0.0 &&
3696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			t [1] == 0.0);
3706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params_rectilinear::IsValid () const
3766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fPlanes; plane++)
3796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
3806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (fRadParams [plane].Count () != 4)
3826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
3836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			return false;
3846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
3856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (fTanParams [plane].Count () < 2)
3876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
3886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			return false;
3896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
3906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
3926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return dng_warp_params::IsValid ();
3946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_warp_params_rectilinear::PropagateToAllPlanes (uint32 totalPlanes)
4006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
4016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = fPlanes; plane < totalPlanes; plane++)
4036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
4046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fRadParams [plane] = fRadParams [0];
4066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fTanParams [plane] = fTanParams [0];
4076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
4096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
4116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
4136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 dng_warp_params_rectilinear::Evaluate (uint32 plane,
4156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											  real64 x) const
4166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
4176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_vector &K = fRadParams [plane]; // Coefficients.
4196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 x2 = x * x;
4216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return x * (K [0] + x2 * (K [1] + x2 * (K [2] + x2 * K [3])));
4236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
4256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
4276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 dng_warp_params_rectilinear::EvaluateRatio (uint32 plane,
4296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												   real64 r2) const
4306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
4316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_vector &K = fRadParams [plane]; // Coefficients.
4336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return K [0] + r2 * (K [1] + r2 * (K [2] + r2 * K [3]));
4356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
4376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
4396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_point_real64 dng_warp_params_rectilinear::EvaluateTangential (uint32 plane,
4416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																  real64 r2,
4426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																  const dng_point_real64 &diff,
4436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																  const dng_point_real64 &diff2) const
4446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
4456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 kt0 = fTanParams [plane][0];
4476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 kt1 = fTanParams [plane][1];
4486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 dh = diff.h;
4506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 dv = diff.v;
4516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 dhdh = diff2.h;
4536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 dvdv = diff2.v;
4546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return dng_point_real64 (kt0 * (r2 + 2.0 * dvdv) + (2.0 * kt1 * dh * dv),  // v
4566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							 kt1 * (r2 + 2.0 * dhdh) + (2.0 * kt0 * dh * dv)); // h
4576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
4596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
4616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 dng_warp_params_rectilinear::MaxSrcRadiusGap (real64 maxDstGap) const
4636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
4646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	real64 maxSrcGap = 0.0;
4666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fPlanes; plane++)
4686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
4696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const dng_vector &coefs = fRadParams [plane];
4716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 k3 = coefs [1];
4736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 k5 = coefs [2];
4746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 k7 = coefs [3];
4756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//
4776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	Let f (r) be the radius warp function. Consider the function
4786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//
4796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	  gap (r) = f (r + maxDstGap) - f (r)
4806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//
4816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	We wish to maximize gap (r) over the domain [0, 1 - maxDstGap]. This will
4826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	give us a reasonable upper bound on the src tile size, independent of
4836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	dstBounds.
4846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//
4856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	As usual, we maximize gap (r) by examining its critical points, i.e., by
4866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	considering the roots of its derivative which lie in the domain [0, 1 -
4876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	maxDstGap]. gap' (r) is a 5th-order polynomial. One of its roots is
4886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	-maxDstGap / 2, which is negative and hence lies outside the domain of
4896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	interest. This leaves 4 other possible roots. We solve for these
4906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//	analytically below.
4916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//
4926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real64 roots [4];
4946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 numRoots = 0;
4956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (k7 == 0.0)
4976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
4986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			if (k5 == 0.0)
5006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
5016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// No roots in [0,1].
5036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
5056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			else
5076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
5086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// k7 is zero, but k5 is non-zero. At most two real roots.
5106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const real64 discrim = 25.0 * (-6.0 * k3 * k5 - 5.0 * k5 * maxDstGap * maxDstGap);
5126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				if (discrim >= 0.0)
5146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
5156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					// Two real roots.
5176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					const real64 scale	  =	 0.1 * k5;
5196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					const real64 offset	  = -5.0 * maxDstGap * k5;
5206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					const real64 sDiscrim =	 sqrt (discrim);
5216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					roots [numRoots++] = scale * (offset + sDiscrim);
5236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					roots [numRoots++] = scale * (offset - sDiscrim);
5246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
5266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
5286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
5306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		else
5326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
5336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// k7 is non-zero. Up to 4 real roots.
5356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const real64 d	= maxDstGap;
5376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const real64 d2 = d	 * d;
5386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const real64 d4 = d2 * d2;
5396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const real64 discrim = 25.0 * k5 * k5
5416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								 - 63.0 * k3 * k7
5426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								 + 35.0 * d2 * k5 * k7
5436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								 + 49.0 * d4 * k7 * k7;
5446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			if (discrim >= 0.0)
5466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
5476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const real64 sDiscrim = 4.0 * k7 * sqrt (discrim);
5496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const real64 offset = -20.0 * k5 * k7 - 35.0 * d2 * k7 * k7;
5516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const real64 discrim1 = offset - sDiscrim;
5536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const real64 discrim2 = offset + sDiscrim;
5546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const real64 scale = sqrt (21.0) / (42.0 * k7);
5566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				if (discrim1 >= 0.0)
5586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
5596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					const real64 offset1 = -d * 0.5;
5616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					const real64 sDiscrim1 = scale * sqrt (discrim1);
5626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					roots [numRoots++] = offset1 + sDiscrim1;
5646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					roots [numRoots++] = offset1 - sDiscrim1;
5656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
5676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				if (discrim2 >= 0.0)
5696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
5706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					const real64 offset2 = -d * 0.5;
5726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					const real64 sDiscrim2 = scale * sqrt (discrim2);
5736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					roots [numRoots++] = offset2 + sDiscrim2;
5756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					roots [numRoots++] = offset2 - sDiscrim2;
5766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
5786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
5806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
5826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real64 planeMaxSrcGap = 0.0;
5846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// Examine the endpoints.
5866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
5886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// Check left endpoint: f (maxDstGap) - f (0). Remember that f (0) == 0.
5906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const real64 gap1 = Evaluate (plane, maxDstGap);
5926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			planeMaxSrcGap = Max_real64 (planeMaxSrcGap, gap1);
5946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// Check right endpoint: f (1) - f (1 - maxDstGap).
5966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const real64 gap2 = Evaluate (plane, 1.0)
5986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							  - Evaluate (plane, 1.0 - maxDstGap);
5996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			planeMaxSrcGap = Max_real64 (planeMaxSrcGap, gap2);
6016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
6036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// Examine the roots we found, if any.
6056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		for (uint32 i = 0; i < numRoots; i++)
6076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
6086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const real64 r = roots [i];
6106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			if (r > 0.0 && r < 1.0 - maxDstGap)
6126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
6136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const real64 gap = Evaluate (plane, r + maxDstGap)
6156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								 - Evaluate (plane, r);
6166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				planeMaxSrcGap = Max_real64 (planeMaxSrcGap, gap);
6186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
6206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
6226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		maxSrcGap = Max_real64 (maxSrcGap,
6246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								planeMaxSrcGap);
6256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
6276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return maxSrcGap;
6296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
6316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
6336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_point_real64 dng_warp_params_rectilinear::MaxSrcTanGap (dng_point_real64 minDst,
6356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim															dng_point_real64 maxDst) const
6366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
6376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 v [] = { minDst.v, maxDst.v, 0.0 };
6396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 h [] = { minDst.h, maxDst.h, 0.0 };
6406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_point_real64 maxGap;
6426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fPlanes; plane++)
6446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
6456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real64 hMin = +FLT_MAX;
6476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real64 hMax = -FLT_MAX;
6486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real64 vMin = +FLT_MAX;
6506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real64 vMax = -FLT_MAX;
6516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		for (uint32 i = 0; i < 3; i++)
6536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
6546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			for (uint32 j = 0; j < 3; j++)
6566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
6576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				dng_point_real64 dstDiff (v [i],
6596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										  h [j]);
6606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				dng_point_real64 srcDiff = EvaluateTangential2 (plane,
6626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																dstDiff);
6636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				hMin = Min_real64 (hMin, srcDiff.h);
6656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				hMax = Max_real64 (hMax, srcDiff.h);
6666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				vMin = Min_real64 (vMin, srcDiff.v);
6686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				vMax = Max_real64 (vMax, srcDiff.v);
6696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
6716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
6736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 hGap = hMax - hMin;
6756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 vGap = vMax - vMin;
6766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		maxGap.h = Max_real64 (maxGap.h, hGap);
6786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		maxGap.v = Max_real64 (maxGap.v, vGap);
6796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
6816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return maxGap;
6836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
6856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
6876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_warp_params_rectilinear::Dump () const
6896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
6906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNGValidate
6926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_warp_params::Dump ();
6946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fPlanes; plane++)
6966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
6976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		printf ("  Plane %u:\n", (unsigned) plane);
6996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		printf ("    Radial params:     %.6lf, %.6lf, %.6lf, %.6lf\n",
7016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fRadParams [plane][0],
7026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fRadParams [plane][1],
7036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fRadParams [plane][2],
7046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fRadParams [plane][3]);
7056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		printf ("    Tangential params: %.6lf, %.6lf\n",
7076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fTanParams [plane][0],
7086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fTanParams [plane][1]);
7096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
7116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
7136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
7156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
7176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_warp_params_fisheye::dng_warp_params_fisheye ()
7196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_warp_params ()
7216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
7236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < kMaxColorPlanes; plane++)
7256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
7266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fRadParams [plane] = dng_vector (4);
7286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
7306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
7326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
7346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_warp_params_fisheye::dng_warp_params_fisheye (uint32 planes,
7366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												  const dng_vector radParams [],
7376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												  const dng_point_real64 &center)
7386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_warp_params (planes, center)
7406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
7426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 i = 0; i < fPlanes; i++)
7446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
7456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fRadParams [i] = radParams [i];
7476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
7496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
7516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
7536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_warp_params_fisheye::~dng_warp_params_fisheye ()
7556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
7566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
7586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
7606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params_fisheye::IsRadNOP (uint32 /* plane */) const
7626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
7636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return false;
7656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
7676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
7696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params_fisheye::IsTanNOP (uint32 /* plane */) const
7716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
7726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return true;
7746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
7766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
7786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_warp_params_fisheye::IsValid () const
7806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
7816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fPlanes; plane++)
7836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
7846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (fRadParams [plane].Count () != 4)
7866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
7876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			return false;
7886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
7896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
7916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return dng_warp_params::IsValid ();
7936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
7956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
7976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_warp_params_fisheye::PropagateToAllPlanes (uint32 totalPlanes)
7996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
8006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = fPlanes; plane < totalPlanes; plane++)
8026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
8036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fRadParams [plane] = fRadParams [0];
8056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
8076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
8096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
8116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 dng_warp_params_fisheye::Evaluate (uint32 plane,
8136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										  real64 r) const
8146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
8156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 t = atan (r);
8176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_vector &K = fRadParams [plane];
8196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 t2 = t * t;
8216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return t * (K [0] + t2 * (K [1] + t2 * (K [2] + t2 * K [3])));
8236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
8256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
8276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 dng_warp_params_fisheye::EvaluateRatio (uint32 plane,
8296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											   real64 rSqr) const
8306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
8316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 eps = 1.0e-12;
8336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (rSqr < eps)
8356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
8366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// r is very close to zero.
8386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		return 1.0;
8406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
8426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 r = sqrt (rSqr);
8446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return Evaluate (plane, r) / r;
8466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
8486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
8506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_point_real64 dng_warp_params_fisheye::EvaluateTangential (uint32 /* plane */,
8526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim															  real64 /* r2 */,
8536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim															  const dng_point_real64 & /* diff */,
8546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim															  const dng_point_real64 & /* diff2 */) const
8556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
8566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// This fisheye model does not support tangential warping.
8586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	ThrowProgramError ();
8606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return dng_point_real64 (0.0, 0.0);
8626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
8646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
8666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 dng_warp_params_fisheye::MaxSrcRadiusGap (real64 maxDstGap) const
8686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
8696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//
8716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//	Let f (r) be the radius warp function. Consider the function
8726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//
8736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//	  gap (r) = f (r + maxDstGap) - f (r)
8746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//
8756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//	We wish to maximize gap (r) over the domain [0, 1 - maxDstGap]. This will
8766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//	give us a reasonable upper bound on the src tile size, independent of
8776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//	dstBounds.
8786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//
8796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//	Ideally, we'd like to maximize gap (r) by examining its critical points,
8806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//	i.e., by considering the roots of its derivative which lie in the domain [0,
8816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//	1 - maxDstGap]. However, gap' (r) is too complex to find its roots
8826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//	analytically.
8836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//
8846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	real64 maxSrcGap = 0.0;
8866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_REQUIRE (maxDstGap > 0.0, "maxDstGap must be positive.");
8886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 kMaxValue = 1.0 - maxDstGap;
8906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 kSteps = 128;
8926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 kNorm = kMaxValue / real64 (kSteps - 1);
8946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fPlanes; plane++)
8966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
8976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
8986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		for (uint32 i = 0; i < kSteps; i++)
8996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
9006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const real64 tt = i * kNorm;
9026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const real64 gap = Evaluate (plane, tt + maxDstGap)
9046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							 - Evaluate (plane, tt);
9056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			maxSrcGap = Max_real64 (maxSrcGap,
9076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									gap);
9086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
9106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
9126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return maxSrcGap;
9146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
9166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
9186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_point_real64 dng_warp_params_fisheye::MaxSrcTanGap (dng_point_real64 /* minDst */,
9206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														dng_point_real64 /* maxDst */) const
9216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
9226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// This fisheye model does not support tangential distortion.
9246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return dng_point_real64 (0.0, 0.0);
9266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
9286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
9306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_warp_params_fisheye::Dump () const
9326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
9336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNGValidate
9356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_warp_params::Dump ();
9376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fPlanes; plane++)
9396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
9406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		printf ("  Plane %u:\n", (unsigned) plane);
9426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		printf ("    Radial params:     %.6lf, %.6lf, %.6lf, %.6lf\n",
9446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fRadParams [plane][0],
9456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fRadParams [plane][1],
9466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fRadParams [plane][2],
9476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fRadParams [plane][3]);
9486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
9506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
9526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
9546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
9566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimclass dng_filter_warp: public dng_filter_task
9586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
9596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	protected:
9616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		AutoPtr<dng_warp_params> fParams;
9636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dng_point_real64 fCenter;
9656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dng_resample_weights_2d fWeights;
9676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real64 fNormRadius;
9696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real64 fInvNormRadius;
9706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		bool fIsRadNOP;
9726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		bool fIsTanNOP;
9736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 fPixelScaleV;
9756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 fPixelScaleVInv;
9766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	public:
9786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dng_filter_warp (const dng_image &srcImage,
9806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 dng_image &dstImage,
9816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 const dng_negative &negative,
9826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 AutoPtr<dng_warp_params> &params);
9836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		virtual void Initialize (dng_host &host);
9856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		virtual dng_rect SrcArea (const dng_rect &dstArea);
9876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		virtual dng_point SrcTileSize (const dng_point &dstTileSize);
9896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		virtual void ProcessArea (uint32 threadIndex,
9916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								  dng_pixel_buffer &srcBuffer,
9926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								  dng_pixel_buffer &dstBuffer);
9936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		virtual dng_point_real64 GetSrcPixelPosition (const dng_point_real64 &dst,
9956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													  uint32 plane);
9966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	};
9986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
9996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
10006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_filter_warp::dng_filter_warp (const dng_image &srcImage,
10026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								  dng_image &dstImage,
10036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								  const dng_negative &negative,
10046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								  AutoPtr<dng_warp_params> &params)
10056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_filter_task (srcImage,
10076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 dstImage)
10086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fParams			(params.Release ())
10106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fCenter			()
10126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fWeights		()
10146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fNormRadius		(1.0)
10166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fInvNormRadius	(1.0)
10176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fIsRadNOP		(false)
10196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fIsTanNOP		(false)
10206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fPixelScaleV	(1.0 / negative.PixelAspectRatio ())
10226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fPixelScaleVInv (1.0 / fPixelScaleV)
10236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
10256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Force float processing.
10276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fSrcPixelType = ttFloat;
10296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fDstPixelType = ttFloat;
10306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fIsRadNOP = fParams->IsRadNOPAll ();
10326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fIsTanNOP = fParams->IsTanNOPAll ();
10336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 negPlanes = negative.ColorChannels ();
10356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (negPlanes >= 1,				  "Too few planes." );
10376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (negPlanes <= kMaxColorPlanes, "Too many planes.");
10386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	(void) negPlanes;
10406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// At least one set of params must do something interesting.
10426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (fIsRadNOP && fIsTanNOP)
10446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
10456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowProgramError ();
10466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
10476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Make sure the warp params are valid for this negative.
10496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (!fParams->IsValidForNegative (negative))
10516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
10526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
10536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
10546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Compute center.
10566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_rect bounds = srcImage.Bounds ();
10586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fCenter.h = Lerp_real64 ((real64) bounds.l,
10606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							 (real64) bounds.r,
10616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							 fParams->fCenter.h);
10626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fCenter.v = Lerp_real64 ((real64) bounds.t,
10646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							 (real64) bounds.b,
10656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							 fParams->fCenter.v);
10666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Compute max pixel radius and derive various normalized radius values. Note
10686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// that when computing the max pixel radius, we must take into account the pixel
10696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// aspect ratio.
10706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
10726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dng_rect squareBounds (bounds);
10746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		squareBounds.b = squareBounds.t +
10766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 Round_int32 (fPixelScaleV * (real64) squareBounds.H ());
10776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const dng_point_real64 squareCenter (Lerp_real64 ((real64) squareBounds.t,
10796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														  (real64) squareBounds.b,
10806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														  fParams->fCenter.v),
10816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											 Lerp_real64 ((real64) squareBounds.l,
10836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														  (real64) squareBounds.r,
10846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														  fParams->fCenter.h));
10856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fNormRadius = MaxDistancePointToRect (squareCenter,
10876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											  squareBounds);
10886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fInvNormRadius = 1.0 / fNormRadius;
10906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
10926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Propagate warp params to other planes.
10946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fParams->PropagateToAllPlanes (fDstPlanes);
10966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
10986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
10996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
11006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_filter_warp::Initialize (dng_host &host)
11026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
11036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Make resample weights.
11056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_resample_function &kernel = dng_resample_bicubic::Get ();
11076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fWeights.Initialize (kernel,
11096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 host.Allocator ());
11106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
11126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
11146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_rect dng_filter_warp::SrcArea (const dng_rect &dstArea)
11166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
11176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Walk each pixel of the boundary of dstArea, map it to the uncorrected src
11196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// pixel position, and return the rectangle that contains all such src pixels.
11206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	int32 xMin = INT_MAX;
11226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	int32 xMax = INT_MIN;
11236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	int32 yMin = INT_MAX;
11246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	int32 yMax = INT_MIN;
11256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fDstPlanes; plane++)
11276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
11286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// Top and bottom edges.
11306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		for (int32 c = dstArea.l; c < dstArea.r; c++)
11326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
11336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// Top edge.
11356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
11376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const dng_point_real64 dst (dstArea.t, c);
11396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const dng_point_real64 src = GetSrcPixelPosition (dst, plane);
11416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1142c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener				const int32 y = ConvertDoubleToInt32 (floor (src.v));
11436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				yMin = Min_int32 (yMin, y);
11456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
11476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// Bottom edge.
11496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
11516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const dng_point_real64 dst (dstArea.b - 1, c);
11536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const dng_point_real64 src = GetSrcPixelPosition (dst, plane);
11556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1156c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener				const int32 y = ConvertDoubleToInt32 (ceil (src.v));
11576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				yMax = Max_int32 (yMax, y);
11596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
11616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
11636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// Left and right edges.
11656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		for (int32 r = dstArea.t; r < dstArea.b; r++)
11676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
11686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// Left edge.
11706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
11726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const dng_point_real64 dst (r, dstArea.l);
11746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const dng_point_real64 src = GetSrcPixelPosition (dst, plane);
11766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1177c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener				const int32 x = ConvertDoubleToInt32 (floor (src.h));
11786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				xMin = Min_int32 (xMin, x);
11806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
11826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// Right edge.
11846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
11866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const dng_point_real64 dst (r, dstArea.r - 1);
11886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const dng_point_real64 src = GetSrcPixelPosition (dst, plane);
11906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1191c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener				const int32 x = ConvertDoubleToInt32 (ceil (src.h));
11926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				xMax = Max_int32 (xMax, x);
11946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
11966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
11986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
11996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
12006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Pad each side by filter radius.
12026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1203c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	const int32 pad = ConvertUint32ToInt32(fWeights.Radius());
12046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1205c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	xMin = SafeInt32Sub(xMin, pad);
1206c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	yMin = SafeInt32Sub(yMin, pad);
1207c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	xMax = SafeInt32Add(xMax, pad);
1208c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	yMax = SafeInt32Add(yMax, pad);
12096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1210c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	xMax = SafeInt32Add(xMax, 1);
1211c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	yMax = SafeInt32Add(yMax, 1);
12126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_rect srcArea (yMin,
12146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							xMin,
12156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							yMax,
12166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							xMax);
12176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return srcArea;
12196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
12216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
12236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_point dng_filter_warp::SrcTileSize (const dng_point &dstTileSize)
12256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
12266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Obtain an upper bound on the source tile size. We'll do this by considering
12286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// upper bounds on the radial and tangential warp components separately, then add
12296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// them together. This is not a tight bound but is good enough because the
12306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// tangential terms are usually quite small.
12316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Get upper bound on src tile size from radial warp.
12336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_REQUIRE (dstTileSize.v > 0, "Invalid tile height.");
12356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_REQUIRE (dstTileSize.h > 0, "Invalid tile width.");
12366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 maxDstGap = fInvNormRadius * hypot ((real64) dstTileSize.h,
12386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													 (real64) dstTileSize.v);
12396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_point srcTileSize;
12416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (maxDstGap >= 1.0)
12436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
12446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// The proposed tile size is unusually large, i.e., its hypotenuse is larger
12466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// than the maximum radius. Bite the bullet and just return a tile size big
12476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// enough to process the whole image.
12486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		srcTileSize = SrcArea (fDstImage.Bounds ()).Size ();
12506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
12526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	else
12546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
12556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// maxDstGap < 1.0.
12576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 maxSrcGap = fParams->MaxSrcRadiusGap (maxDstGap);
12596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1260c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener		const int32 dim = ConvertDoubleToInt32 (ceil (maxSrcGap * fNormRadius));
12616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		srcTileSize = dng_point (dim, dim);
12636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
12656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1266c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	srcTileSize.h += ConvertUint32ToInt32(fWeights.Width());
1267c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	srcTileSize.v += ConvertUint32ToInt32(fWeights.Width());
12686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Get upper bound on src tile size from tangential warp.
12706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_rect_real64 bounds (fSrcImage.Bounds ());
12726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_point_real64 minDst ((bounds.t - fCenter.v) * fInvNormRadius,
12746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								   (bounds.l - fCenter.h) * fInvNormRadius);
12756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_point_real64 maxDst ((bounds.b - 1.0 - fCenter.v) * fInvNormRadius,
12776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								   (bounds.r - 1.0 - fCenter.h) * fInvNormRadius);
12786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_point_real64 srcTanGap = fParams->MaxSrcTanGap (minDst,
12806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim															  maxDst);
12816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Add the two bounds together.
12836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1284c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	srcTileSize.v += ConvertDoubleToInt32 (ceil (srcTanGap.v * fNormRadius));
1285c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	srcTileSize.h += ConvertDoubleToInt32 (ceil (srcTanGap.h * fNormRadius));
12866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return srcTileSize;
12886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
12906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
12926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_filter_warp::ProcessArea (uint32 /* threadIndex */,
12946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								   dng_pixel_buffer &srcBuffer,
12956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								   dng_pixel_buffer &dstBuffer)
12966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
12976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
12986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Prepare resample constants.
12996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const int32 wCount = fWeights.Width ();
13016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_point srcOffset (fWeights.Offset (),
13036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							   fWeights.Offset ());
13046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 numSubsamples = (real64) kResampleSubsampleCount2D;
13066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Prepare area and step constants.
13086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_rect srcArea = srcBuffer.fArea;
13106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_rect dstArea = dstBuffer.fArea;
13116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const int32 srcRowStep = (int32) srcBuffer.RowStep ();
13136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const int32 hMin = srcArea.l;
13156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const int32 hMax = SafeInt32Sub (SafeInt32Sub (srcArea.r, wCount), 1);
13166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const int32 vMin = srcArea.t;
13186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const int32 vMax = SafeInt32Sub (SafeInt32Sub (srcArea.b, wCount), 1);
13196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (hMax < hMin || vMax < vMin)
13216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
13226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ("Empty source area in dng_filter_warp.");
13246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
13266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Warp each plane.
13286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < dstBuffer.fPlanes; plane++)
13306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
13316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real32 *dPtr = dstBuffer.DirtyPixel_real32 (dstArea.t,
13336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													dstArea.l,
13346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													plane);
13356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		for (int32 dstRow = dstArea.t; dstRow < dstArea.b; dstRow++)
13376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
13386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			uint32 dstIndex = 0;
13406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			for (int32 dstCol = dstArea.l; dstCol < dstArea.r; dstCol++, dstIndex++)
13426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
13436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// Get destination (corrected) pixel position.
13456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const dng_point_real64 dPos ((real64) dstRow,
13476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											 (real64) dstCol);
13486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// Warp to source (uncorrected) pixel position.
13506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const dng_point_real64 sPos = GetSrcPixelPosition (dPos,
13526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																   plane);
13536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// Decompose into integer and fractional parts.
13556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1356c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener				dng_point sInt (ConvertDoubleToInt32 (floor (sPos.v)),
1357c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener								ConvertDoubleToInt32 (floor (sPos.h)));
13586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1359c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener				dng_point sFct (ConvertDoubleToInt32 ((sPos.v - (real64) sInt.v) * numSubsamples),
1360c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener								ConvertDoubleToInt32 ((sPos.h - (real64) sInt.h) * numSubsamples));
13616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// Add resample offset.
13636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				sInt = sInt + srcOffset;
13656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// Clip.
13676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				if (sInt.h < hMin)
13696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
13706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					sInt.h = hMin;
13716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					sFct.h = 0;
13726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
13736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				else if (sInt.h > hMax)
13756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
13766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					sInt.h = hMax;
13776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					sFct.h = 0;
13786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
13796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				if (sInt.v < vMin)
13816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
13826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					sInt.v = vMin;
13836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					sFct.v = 0;
13846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
13856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				else if (sInt.v > vMax)
13876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
13886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					sInt.v = vMax;
13896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					sFct.v = 0;
13906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
13916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// Perform 2D resample.
13936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const real32 *w = fWeights.Weights32 (sFct);
13956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
13966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const real32 *s = srcBuffer.ConstPixel_real32 (sInt.v,
13976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim															   sInt.h,
13986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim															   plane);
13996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				real32 total = 0.0f;
14016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				for (int32 i = 0; i < wCount; i++)
14036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
14046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					for (int32 j = 0; j < wCount; j++)
14066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						{
14076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						total += w [j] * s [j];
14096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						}
14116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					w += wCount;
14136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					s += srcRowStep;
14146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
14166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// Store final pixel value.
14186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				dPtr [dstIndex] = Pin_real32 (total);
14206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
14226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// Advance to next row.
14246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			dPtr += dstBuffer.RowStep ();
14266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
14286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
14306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
14326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
14346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_point_real64 dng_filter_warp::GetSrcPixelPosition (const dng_point_real64 &dst,
14366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													   uint32 plane)
14376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
14386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_point_real64 diff = dst - fCenter;
14406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_point_real64 diffNorm (diff.v * fInvNormRadius,
14426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									 diff.h * fInvNormRadius);
14436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_point_real64 diffNormScaled (diffNorm.v * fPixelScaleV,
14456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										   diffNorm.h);
14466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_point_real64 diffNormSqr (diffNormScaled.v * diffNormScaled.v,
14486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										diffNormScaled.h * diffNormScaled.h);
14496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 rr = Min_real64 (diffNormSqr.v + diffNormSqr.h,
14516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								  1.0);
14526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_point_real64 dSrc;
14546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (fIsTanNOP)
14566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
14576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// Radial only.
14596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 ratio = fParams->EvaluateRatio (plane,
14616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													 rr);
14626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dSrc.h = diff.h * ratio;
14646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dSrc.v = diff.v * ratio;
14656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
14676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	else if (fIsRadNOP)
14696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
14706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// Tangential only.
14726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const dng_point_real64 tan = fParams->EvaluateTangential (plane,
14746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																  rr,
14756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																  diffNormScaled,
14766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																  diffNormSqr);
14776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dSrc.h = diff.h + (fNormRadius * tan.h);
14796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dSrc.v = diff.v + (fNormRadius * tan.v * fPixelScaleVInv);
14806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
14826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	else
14846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
14856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// Radial and tangential.
14876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real64 ratio = fParams->EvaluateRatio (plane,
14896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													 rr);
14906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const dng_point_real64 tan = fParams->EvaluateTangential (plane,
14926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																  rr,
14936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																  diffNormScaled,
14946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim																  diffNormSqr);
14956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dSrc.h = fNormRadius * (diffNorm.h * ratio + tan.h);
14976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dSrc.v = fNormRadius * (diffNorm.v * ratio + tan.v * fPixelScaleVInv);
14986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
14996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
15006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return fCenter + dSrc;
15026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
15046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
15066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_opcode_WarpRectilinear::dng_opcode_WarpRectilinear (const dng_warp_params_rectilinear &params,
15086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														uint32 flags)
15096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_opcode (dngOpcode_WarpRectilinear,
15116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					dngVersion_1_3_0_0,
15126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					flags)
15136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fWarpParams (params)
15156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
15176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (!params.IsValid ())
15196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
15206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
15216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
15226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
15246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
15266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_opcode_WarpRectilinear::dng_opcode_WarpRectilinear (dng_stream &stream)
15286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_opcode (dngOpcode_WarpRectilinear,
15306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					stream,
15316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					"WarpRectilinear")
15326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fWarpParams ()
15346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
15366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Grab the size in bytes.
15386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 bytes = stream.Get_uint32 ();
15406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Grab the number of planes to warp.
15426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fWarpParams.fPlanes = stream.Get_uint32 ();
15446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Verify number of planes.
15466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (fWarpParams.fPlanes == 0 ||
15486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fPlanes > kMaxColorPlanes)
15496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
15506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
15516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
15526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Verify the size.
15546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (bytes != ParamBytes (fWarpParams.fPlanes))
15566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
15576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
15586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
15596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Read warp parameters for each plane.
15616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fWarpParams.fPlanes; plane++)
15636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
15646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fRadParams [plane][0] = stream.Get_real64 ();
15666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fRadParams [plane][1] = stream.Get_real64 ();
15676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fRadParams [plane][2] = stream.Get_real64 ();
15686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fRadParams [plane][3] = stream.Get_real64 ();
15696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fTanParams [plane][0] = stream.Get_real64 ();
15716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fTanParams [plane][1] = stream.Get_real64 ();
15726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
15746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Read the image center.
15766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fWarpParams.fCenter.h = stream.Get_real64 ();
15786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fWarpParams.fCenter.v = stream.Get_real64 ();
15796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNGValidate
15816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (gVerbose)
15836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
15846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.Dump ();
15866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
15886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
15906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (!fWarpParams.IsValid ())
15926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
15936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
15946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
15956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
15976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
15986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
15996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_opcode_WarpRectilinear::IsNOP () const
16016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
16026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return fWarpParams.IsNOPAll ();
16046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
16066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
16086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_opcode_WarpRectilinear::IsValidForNegative (const dng_negative &negative) const
16106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
16116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return fWarpParams.IsValidForNegative (negative);
16136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
16156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
16176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_opcode_WarpRectilinear::PutData (dng_stream &stream) const
16196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
16206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 bytes = ParamBytes (fWarpParams.fPlanes);
16226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_uint32 (bytes);
16246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_uint32 (fWarpParams.fPlanes);
16266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fWarpParams.fPlanes; plane++)
16286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
16296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fWarpParams.fRadParams [plane][0]);
16316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fWarpParams.fRadParams [plane][1]);
16326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fWarpParams.fRadParams [plane][2]);
16336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fWarpParams.fRadParams [plane][3]);
16346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fWarpParams.fTanParams [plane][0]);
16366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fWarpParams.fTanParams [plane][1]);
16376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
16396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_real64 (fWarpParams.fCenter.h);
16416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_real64 (fWarpParams.fCenter.v);
16426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
16446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
16466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_opcode_WarpRectilinear::Apply (dng_host &host,
16486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										dng_negative &negative,
16496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										AutoPtr<dng_image> &image)
16506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
16516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNGValidate
16536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_timer timer ("WarpRectilinear time");
16556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
16576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Allocate destination image.
16596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	AutoPtr<dng_image> dstImage (host.Make_dng_image (image->Bounds	   (),
16616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													  image->Planes	   (),
16626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													  image->PixelType ()));
16636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Warp the image.
16656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	AutoPtr<dng_warp_params> params (new dng_warp_params_rectilinear (fWarpParams));
16676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_filter_warp filter (*image,
16696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							*dstImage,
16706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							negative,
16716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							params);
16726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	filter.Initialize (host);
16746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	host.PerformAreaTask (filter,
16766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						  image->Bounds ());
16776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Return the new image.
16796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	image.Reset (dstImage.Release ());
16816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
16836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
16856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimuint32 dng_opcode_WarpRectilinear::ParamBytes (uint32 planes)
16876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
16886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return (1 * (uint32) sizeof (uint32)		 ) +  // Number of planes.
16906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		   (6 * (uint32) sizeof (real64) * planes) +  // Warp coefficients.
16916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		   (2 * (uint32) sizeof (real64)		 );	  // Optical center.
16926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
16946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
16966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
16976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_opcode_WarpFisheye::dng_opcode_WarpFisheye (const dng_warp_params_fisheye &params,
16986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												uint32 flags)
16996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_opcode (dngOpcode_WarpFisheye,
17016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					dngVersion_1_3_0_0,
17026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					flags)
17036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fWarpParams (params)
17056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
17076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (!params.IsValid ())
17096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
17106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
17116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
17126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
17146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
17166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_opcode_WarpFisheye::dng_opcode_WarpFisheye (dng_stream &stream)
17186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_opcode (dngOpcode_WarpFisheye,
17206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					stream,
17216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					"WarpFisheye")
17226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fWarpParams ()
17246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
17266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Grab the size in bytes.
17286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 bytes = stream.Get_uint32 ();
17306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Grab the number of planes to warp.
17326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fWarpParams.fPlanes = stream.Get_uint32 ();
17346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Verify number of planes.
17366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (fWarpParams.fPlanes == 0 ||
17386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fPlanes > kMaxColorPlanes)
17396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
17406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
17416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
17426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Verify the size.
17446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (bytes != ParamBytes (fWarpParams.fPlanes))
17466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
17476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
17486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
17496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Read warp parameters for each plane.
17516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fWarpParams.fPlanes; plane++)
17536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
17546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fRadParams [plane][0] = stream.Get_real64 ();
17566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fRadParams [plane][1] = stream.Get_real64 ();
17576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fRadParams [plane][2] = stream.Get_real64 ();
17586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.fRadParams [plane][3] = stream.Get_real64 ();
17596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
17616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Read the image center.
17636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fWarpParams.fCenter.h = stream.Get_real64 ();
17656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fWarpParams.fCenter.v = stream.Get_real64 ();
17666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNGValidate
17686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (gVerbose)
17706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
17716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fWarpParams.Dump ();
17736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
17756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
17776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (!fWarpParams.IsValid ())
17796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
17806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
17816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
17826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
17846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
17866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_opcode_WarpFisheye::IsNOP () const
17886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
17896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return fWarpParams.IsNOPAll ();
17916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
17936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
17956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_opcode_WarpFisheye::IsValidForNegative (const dng_negative &negative) const
17976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
17986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
17996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return fWarpParams.IsValidForNegative (negative);
18006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
18026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
18046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_opcode_WarpFisheye::PutData (dng_stream &stream) const
18066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
18076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 bytes = ParamBytes (fWarpParams.fPlanes);
18096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_uint32 (bytes);
18116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Write the number of planes.
18136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_uint32 (fWarpParams.fPlanes);
18156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Write the warp coefficients.
18176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 plane = 0; plane < fWarpParams.fPlanes; plane++)
18196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
18206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fWarpParams.fRadParams [plane][0]);
18226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fWarpParams.fRadParams [plane][1]);
18236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fWarpParams.fRadParams [plane][2]);
18246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fWarpParams.fRadParams [plane][3]);
18256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
18276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Write the optical center.
18296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_real64 (fWarpParams.fCenter.h);
18316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_real64 (fWarpParams.fCenter.v);
18326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
18346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
18366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_opcode_WarpFisheye::Apply (dng_host &host,
18386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									dng_negative &negative,
18396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									AutoPtr<dng_image> &image)
18406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
18416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNGValidate
18436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_timer timer ("WarpFisheye time");
18456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
18476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Allocate destination image.
18496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	AutoPtr<dng_image> dstImage (host.Make_dng_image (image->Bounds	   (),
18516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													  image->Planes	   (),
18526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													  image->PixelType ()));
18536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Warp the image.
18556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	AutoPtr<dng_warp_params> params (new dng_warp_params_fisheye (fWarpParams));
18576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_filter_warp filter (*image,
18596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							*dstImage,
18606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							negative,
18616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							params);
18626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	filter.Initialize (host);
18646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	host.PerformAreaTask (filter,
18666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						  image->Bounds ());
18676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Return the new image.
18696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	image.Reset (dstImage.Release ());
18716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
18736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
18756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimuint32 dng_opcode_WarpFisheye::ParamBytes (uint32 planes)
18776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
18786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return (1 * (uint32) sizeof (uint32)		 ) +	// Number of planes.
18806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		   (4 * (uint32) sizeof (real64) * planes) +	// Warp coefficients.
18816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		   (2 * (uint32) sizeof (real64)		 );		// Optical center.
18826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
18846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
18866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_vignette_radial_params::dng_vignette_radial_params ()
18886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	fParams (kNumTerms)
18906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fCenter (0.5, 0.5)
18916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
18936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
18956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
18976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
18986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_vignette_radial_params::dng_vignette_radial_params (const dng_std_vector<real64> &params,
18996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														const dng_point_real64 &center)
19006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	fParams (params)
19026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fCenter (center)
19036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
19056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
19076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
19096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_vignette_radial_params::IsNOP () const
19116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
19126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 i = 0; i < fParams.size (); i++)
19146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
19156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (fParams [i] != 0.0)
19176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
19186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			return false;
19196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
19206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
19226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return true;
19246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
19266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
19286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_vignette_radial_params::IsValid () const
19306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
19316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (fParams.size () != kNumTerms)
19336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
19346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		return false;
19356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
19366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (fCenter.h < 0.0 ||
19386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fCenter.h > 1.0 ||
19396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fCenter.v < 0.0 ||
19406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fCenter.v > 1.0)
19416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
19426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		return false;
19436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
19446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return true;
19466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
19486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
19506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_vignette_radial_params::Dump () const
19526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
19536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNGValidate
19556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	printf ("  Radial vignette params: ");
19576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 i = 0; i < fParams.size (); i++)
19596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
19606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		printf ("%s%.6lf",
19626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				(i == 0) ? "" : ", ",
19636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				fParams [i]);
19646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
19666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	printf ("\n");
19686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	printf ("  Optical center:\n"
19706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			"	 h = %.6lf\n"
19716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			"	 v = %.6lf\n",
19726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			fCenter.h,
19736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			fCenter.v);
19746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
19766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
19786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
19806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimclass dng_vignette_radial_function: public dng_1d_function
19826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
19836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	protected:
19856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const dng_vignette_radial_params fParams;
19876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	public:
19896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		explicit dng_vignette_radial_function (const dng_vignette_radial_params &params)
19916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			:	fParams (params)
19936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
19956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
19976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
19986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// x represents r^2, where r is the normalized Euclidean distance from the
19996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// optical center to a pixel. r lies in [0,1], so r^2 (and hence x) also lies
20006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// in [0,1].
20016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		virtual real64 Evaluate (real64 x) const
20036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
20046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			DNG_REQUIRE (fParams.fParams.size () == dng_vignette_radial_params::kNumTerms,
20066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 "Bad number of vignette opcode coefficients.");
20076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			real64 sum = 0.0;
20096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const dng_std_vector<real64> &v = fParams.fParams;
20116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			for (dng_std_vector<real64>::const_reverse_iterator i = v.rbegin (); i != v.rend (); i++)
20136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
20146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				sum = x * ((*i) + sum);
20156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
20166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			sum += 1.0;
20186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			return sum;
20206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
20226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	};
20246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
20266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_opcode_FixVignetteRadial::dng_opcode_FixVignetteRadial (const dng_vignette_radial_params &params,
20286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim															uint32 flags)
20296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	: 	dng_inplace_opcode (dngOpcode_FixVignetteRadial,
20316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							dngVersion_1_3_0_0,
20326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							flags)
20336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fParams (params)
20356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fImagePlanes (1)
20376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fSrcOriginH (0)
20396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fSrcOriginV (0)
20406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fSrcStepH (0)
20426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fSrcStepV (0)
20436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fTableInputBits  (0)
20456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fTableOutputBits (0)
20466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fGainTable ()
20486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
20506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (!params.IsValid ())
20526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
20536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
20546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
20556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
20576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
20596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_opcode_FixVignetteRadial::dng_opcode_FixVignetteRadial (dng_stream &stream)
20616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_inplace_opcode (dngOpcode_FixVignetteRadial,
20636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							stream,
20646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							"FixVignetteRadial")
20656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fParams ()
20676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fImagePlanes (1)
20696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fSrcOriginH (0)
20716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fSrcOriginV (0)
20726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fSrcStepH (0)
20746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fSrcStepV (0)
20756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fTableInputBits  (0)
20776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fTableOutputBits (0)
20786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fGainTable ()
20806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
20826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Grab the size in bytes.
20846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 bytes = stream.Get_uint32 ();
20866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Verify the size.
20886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (bytes != ParamBytes ())
20906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
20916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
20926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
20936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Read vignette coefficients.
20956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fParams.fParams = dng_std_vector<real64> (dng_vignette_radial_params::kNumTerms);
20976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
20986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 i = 0; i < dng_vignette_radial_params::kNumTerms; i++)
20996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
21006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fParams.fParams [i] = stream.Get_real64 ();
21016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
21026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Read the image center.
21046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fParams.fCenter.h = stream.Get_real64 ();
21066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fParams.fCenter.v = stream.Get_real64 ();
21076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Debug.
21096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNGValidate
21116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (gVerbose)
21136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
21146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fParams.Dump ();
21166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
21186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
21206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (!fParams.IsValid ())
21226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
21236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
21246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
21256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
21276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
21296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_opcode_FixVignetteRadial::IsNOP () const
21316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
21326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return fParams.IsNOP ();
21346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
21366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
21386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool dng_opcode_FixVignetteRadial::IsValidForNegative (const dng_negative & /* negative */) const
21406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
21416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return fParams.IsValid ();
21436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
21456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
21476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_opcode_FixVignetteRadial::PutData (dng_stream &stream) const
21496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
21506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 bytes = ParamBytes ();
21526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_uint32 (bytes);
21546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_REQUIRE (fParams.fParams.size () == dng_vignette_radial_params::kNumTerms,
21566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				 "Bad number of vignette opcode coefficients.");
21576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 i = 0; i < dng_vignette_radial_params::kNumTerms; i++)
21596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
21606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		stream.Put_real64 (fParams.fParams [i]);
21616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
21626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_real64 (fParams.fCenter.h);
21646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	stream.Put_real64 (fParams.fCenter.v);
21656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
21676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
21696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_opcode_FixVignetteRadial::Prepare (dng_negative &negative,
21716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											uint32 threadCount,
21726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											const dng_point &tileSize,
21736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											const dng_rect &imageBounds,
21746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											uint32 imagePlanes,
21756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											uint32 bufferPixelType,
21766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											dng_memory_allocator &allocator)
21776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
21786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// This opcode is restricted to 32-bit images.
21806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (bufferPixelType != ttFloat)
21826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
21836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowBadFormat ();
21846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
21856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Sanity check number of planes.
21876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (imagePlanes >= 1 && imagePlanes <= kMaxColorPlanes,
21896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				"Bad number of planes.");
21906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (imagePlanes < 1 || imagePlanes > kMaxColorPlanes)
21926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
21936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowProgramError ();
21946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
21956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fImagePlanes = imagePlanes;
21976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
21986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Set the vignette correction curve.
21996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_vignette_radial_function curve (fParams);
22016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Grab the destination image area.
22036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_rect_real64 bounds (imageBounds);
22056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Determine the optical center and maximum radius in pixel coordinates.
22076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_point_real64 centerPixel (Lerp_real64 (bounds.t,
22096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													 bounds.b,
22106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													 fParams.fCenter.v),
22116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										Lerp_real64 (bounds.l,
22136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													 bounds.r,
22146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													 fParams.fCenter.h));
22156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 pixelScaleV = 1.0 / negative.PixelAspectRatio ();
22176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 maxRadius = hypot (Max_real64 (Abs_real64 (centerPixel.v - bounds.t),
22196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												Abs_real64 (centerPixel.v - bounds.b)) * pixelScaleV,
22206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									Max_real64 (Abs_real64 (centerPixel.h - bounds.l),
22226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												Abs_real64 (centerPixel.h - bounds.r)));
22236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const dng_point_real64 radius (maxRadius,
22256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								   maxRadius);
22266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Find origin and scale.
22286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 pixelScaleH = 1.0;
22306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fSrcOriginH = Real64ToFixed64 (-centerPixel.h * pixelScaleH / radius.h);
22326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fSrcOriginV = Real64ToFixed64 (-centerPixel.v * pixelScaleV / radius.v);
22336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fSrcStepH = Real64ToFixed64 (pixelScaleH / radius.h);
22356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fSrcStepV = Real64ToFixed64 (pixelScaleV / radius.v);
22366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Adjust for pixel centers.
22386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fSrcOriginH += fSrcStepH >> 1;
22406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fSrcOriginV += fSrcStepV >> 1;
22416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Evaluate 32-bit vignette correction table.
22436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_1d_table table32;
22456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	table32.Initialize (allocator,
22476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						curve,
22486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						false);
22496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Find maximum scale factor.
22516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real64 maxScale = Max_real32 (table32.Interpolate (0.0f),
22536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										table32.Interpolate (1.0f));
22546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Find table input bits.
22566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fTableInputBits = 16;
22586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Find table output bits.
22606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fTableOutputBits = 15;
22626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	while ((1 << fTableOutputBits) * maxScale > 65535.0)
22646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
22656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fTableOutputBits--;
22666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
22676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Allocate 16-bit scale table.
22696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 tableEntries = (1 << fTableInputBits) + 1;
22716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fGainTable.Reset (allocator.Allocate (tableEntries * (uint32) sizeof (uint16)));
22736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	uint16 *table16 = fGainTable->Buffer_uint16 ();
22756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Interpolate 32-bit table into 16-bit table.
22776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real32 scale0 = 1.0f / (1 << fTableInputBits );
22796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real32 scale1 = 1.0f * (1 << fTableOutputBits);
22806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 index = 0; index < tableEntries; index++)
22826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
22836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real32 x = index * scale0;
22856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real32 y = table32.Interpolate (x) * scale1;
22876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		table16 [index] = (uint16) Round_uint32 (y);
22896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
22916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Prepare vignette mask buffers.
22936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
22956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
22966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const uint32 pixelType = ttShort;
22976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const uint32 bufferSize = ComputeBufferSize(pixelType, tileSize,
22986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim													imagePlanes, pad16Bytes);
22996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		for (uint32 threadIndex = 0; threadIndex < threadCount; threadIndex++)
23016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
23026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			fMaskBuffers [threadIndex] . Reset (allocator.Allocate (bufferSize));
23046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
23066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
23086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
23106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
23126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_opcode_FixVignetteRadial::ProcessArea (dng_negative & /* negative */,
23146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												uint32 threadIndex,
23156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												dng_pixel_buffer &buffer,
23166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												const dng_rect &dstArea,
23176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												const dng_rect & /* imageBounds */)
23186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
23196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Setup mask pixel buffer.
23216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_pixel_buffer maskPixelBuffer(dstArea, 0, fImagePlanes, ttShort,
23236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									 pcRowInterleavedAlign16,
23246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									 fMaskBuffers [threadIndex]->Buffer ());
23256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Compute mask.
23276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DoVignetteMask16 (maskPixelBuffer.DirtyPixel_uint16 (dstArea.t, dstArea.l),
23296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  dstArea.H (),
23306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  dstArea.W (),
23316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  maskPixelBuffer.RowStep (),
23326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  fSrcOriginH + fSrcStepH * dstArea.l,
23336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  fSrcOriginV + fSrcStepV * dstArea.t,
23346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  fSrcStepH,
23356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  fSrcStepV,
23366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  fTableInputBits,
23376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  fGainTable->Buffer_uint16 ());
23386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Apply mask.
23406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DoVignette32 (buffer.DirtyPixel_real32 (dstArea.t, dstArea.l),
23426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				  maskPixelBuffer.ConstPixel_uint16 (dstArea.t, dstArea.l),
23436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				  dstArea.H (),
23446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				  dstArea.W (),
23456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				  fImagePlanes,
23466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				  buffer.RowStep (),
23476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				  buffer.PlaneStep (),
23486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				  maskPixelBuffer.RowStep (),
23496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				  fTableOutputBits);
23506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
23526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
23546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimuint32 dng_opcode_FixVignetteRadial::ParamBytes ()
23566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
23576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 N = dng_vignette_radial_params::kNumTerms;
23596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return ((N * sizeof (real64)) +	 // Vignette coefficients.
23616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			(2 * sizeof (real64)));	 // Optical center.
23626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
23646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
23656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
2366