16e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
26e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// Copyright 2006-2012 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_utils.cpp#3 $ */
106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $DateTime: 2012/08/12 15:38:38 $ */
116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $Change: 842799 $ */
126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $Author: tknoll $ */
136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_utils.h"
176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_area_task.h"
196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_assertions.h"
206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_bottlenecks.h"
216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_exceptions.h"
226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_host.h"
236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_image.h"
246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_flags.h"
256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_point.h"
266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_rect.h"
276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_safe_arithmetic.h"
286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_tag_types.h"
296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_tile_iterator.h"
306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#if qMacOS
322dd7464aac6607e6b74065579d546dd0de0a86b7Kinan Hakim#include <TargetConditionals.h>
332dd7464aac6607e6b74065579d546dd0de0a86b7Kinan Hakim#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
342dd7464aac6607e6b74065579d546dd0de0a86b7Kinan Hakim#include <MobileCoreServices/MobileCoreServices.h>
352dd7464aac6607e6b74065579d546dd0de0a86b7Kinan Hakim#else
366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include <CoreServices/CoreServices.h>
372dd7464aac6607e6b74065579d546dd0de0a86b7Kinan Hakim#endif  // TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
382dd7464aac6607e6b74065579d546dd0de0a86b7Kinan Hakim#endif  // qMacOS
396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#if qiPhone || qMacOS
416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// these provide timers
426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include <mach/mach.h>
436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include <mach/mach_time.h>
446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#endif
456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#if qWinOS
476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include <windows.h>
486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#else
496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include <sys/time.h>
506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include <stdarg.h> // for va_start/va_end
516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#endif
526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#if qDNGDebug
566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#if qMacOS
606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#define DNG_DEBUG_BREAK __asm__ volatile ("int3")
616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#elif qWinOS
626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNG64Bit
636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// no inline assembly on Win 64-bit, so use DebugBreak
646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		#define DNG_DEBUG_BREAK DebugBreak()
656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#else
666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		#define DNG_DEBUG_BREAK __asm__ volatile ("int3")
676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#elif qiPhone
696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// simulator is running on Intel
706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qiPhoneSimulator
716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		#define DNG_DEBUG_BREAK __asm__ volatile ("int3")
726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#else
736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// The debugger doesn't restore program counter after this is called.
746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//   Caller must move program counter past line to continue.
756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// As of iOS5/xCode 4.2, recovery may not be possible.
766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		#define DNG_DEBUG_BREAK __asm__ volatile ("bkpt 1")
776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#elif qAndroid
796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#define DNG_DEBUG_BREAK __asm__ volatile ("bkpt 1")
806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#elif qLinux
816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#define DNG_DEBUG_BREAK __asm__ volatile ("int3")
826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#else
836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#define DNG_DEBUG_BREAK
846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#endif
856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool gPrintAsserts   = true;
896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool gBreakOnAsserts = true;
906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_show_message (const char *s)
946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qDNGPrintMessages
976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// display the message
996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (gPrintAsserts)
1006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fprintf (stderr, "%s\n", s);
1016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#elif qiPhone || qAndroid || qLinux
1036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (gPrintAsserts)
1056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fprintf (stderr, "%s\n", s);
1066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// iOS doesn't print a message to the console like DebugStr and MessageBox do, so we have to do both
1086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// You'll have to advance the program counter manually past this statement
1096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (gBreakOnAsserts)
1106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		DNG_DEBUG_BREAK;
1116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#elif qMacOS
1136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (gBreakOnAsserts)
1156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// truncate the to 255 chars
1176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		char ss [256];
1186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 len = strlen (s);
1206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (len > 255)
1216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			len = 255;
1226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		strncpy (&(ss [1]), s, len );
1236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ss [0] = (unsigned char) len;
1246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		DebugStr ((unsigned char *) ss);
1266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	 else if (gPrintAsserts)
1286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fprintf (stderr, "%s\n", s);
1306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#elif qWinOS
1336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// display a dialog
1356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// This is not thread safe.  Multiple message boxes can be launched.
1366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Should also be launched in its own thread so main msg queue isn't thrown off.
1376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (gBreakOnAsserts)
1386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		MessageBoxA (NULL, (LPSTR) s, NULL, MB_OK);
1396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	else if (gPrintAsserts)
1406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fprintf (stderr, "%s\n", s);
1416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
1436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
1456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_show_message_f (const char *fmt, ... )
1496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
1506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	char buffer [1024];
1526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	va_list ap;
1546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	va_start (ap, fmt);
1556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	vsnprintf (buffer, sizeof (buffer), fmt, ap);
1576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	va_end (ap);
1596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_show_message (buffer);
1616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
1636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#endif
1676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimuint32 ComputeBufferSize(uint32 pixelType, const dng_point &tileSize,
1716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 uint32 numPlanes, PaddingType paddingType)
1726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim{
174c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener
1756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Convert tile size to uint32.
1766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (tileSize.h < 0 || tileSize.v < 0)
1776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowMemoryFull("Negative tile size");
1796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 tileSizeH = static_cast<uint32>(tileSize.h);
1816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 tileSizeV = static_cast<uint32>(tileSize.v);
1826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 pixelSize = TagTypeSize(pixelType);
1846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Add padding to width if necessary.
1866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	uint32 paddedWidth = tileSizeH;
1876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (paddingType == pad16Bytes)
1886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (!RoundUpForPixelSize(paddedWidth, pixelSize, &paddedWidth))
1906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
1916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			  ThrowMemoryFull("Arithmetic overflow computing buffer size");
1926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
1936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Compute buffer size.
1966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	uint32 bufferSize;
1976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (!SafeUint32Mult(paddedWidth, tileSizeV, &bufferSize) ||
1986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		!SafeUint32Mult(bufferSize, pixelSize, &bufferSize) ||
1996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		!SafeUint32Mult(bufferSize, numPlanes, &bufferSize))
2006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
2016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowMemoryFull("Arithmetic overflow computing buffer size");
2026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
2036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return bufferSize;
2056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim}
2066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
2086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 TickTimeInSeconds ()
2106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
2116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qWinOS
2136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// One might think it prudent to cache the frequency here, however
2156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// low-power CPU modes can, and do, change the value returned.
2166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Thus the frequencey needs to be retrieved each time.
2176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Note that the frequency changing can cause the return
2196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// result to jump backwards, which is why the TickCountInSeconds
2206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// (below) also exists.
2216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Just plug in laptop when doing timings to minimize this.
2236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//  QPC/QPH is a slow call compared to rtdsc.
2246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qImagecore
2266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// You should be plugged-in when measuring.
2286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	static real64 freqMultiplier = 0.0;
2306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (freqMultiplier == 0.0)
2326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
2336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		LARGE_INTEGER freq;
2356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		QueryPerformanceFrequency (&freq);
2376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		freqMultiplier = 1.0 / (real64) freq.QuadPart;
2396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
2416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#else
2436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	LARGE_INTEGER freq;
2456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	QueryPerformanceFrequency (&freq);
2476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	real64 freqMultiplier = 1.0 / (real64) freq.QuadPart;
2496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif	// qImagecore
2516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	LARGE_INTEGER cycles;
2536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	QueryPerformanceCounter (&cycles);
2556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return (real64) cycles.QuadPart * freqMultiplier;
2576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#elif qiPhone || qMacOS
2596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//  this is switching Mac to high performance timer
2616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//  and this is also the timer for iPhone
2626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// assume frequency is unchanging, requesting frequency every time call
2646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//   is too slow.  multiple cores, different frequency ?
2656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	static real64 freqMultiplier = 0.0;
2676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (freqMultiplier == 0.0)
2686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
2696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		mach_timebase_info_data_t freq;
2706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		mach_timebase_info(&freq);
2716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		// converts from nanos to micros
2736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		//  numer = 125, denom = 3 * 1000
2746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		freqMultiplier = ((real64)freq.numer / (real64)freq.denom) * 1.0e-9;
2756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
2766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return mach_absolute_time() * freqMultiplier;
2786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#elif qAndroid || qLinux
2806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	//this is a fast timer to nanos
2826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim    struct timespec now;
2836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	clock_gettime(CLOCK_MONOTONIC, &now);
2846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return now.tv_sec + (real64)now.tv_nsec * 1.0e-9;
2856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#else
2876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	// Perhaps a better call exists. (e.g. avoid adjtime effects)
2896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	struct timeval tv;
2916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	gettimeofday (&tv, NULL);
2936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return tv.tv_sec + (real64)tv.tv_usec * 1.0e-6;
2956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
2976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
2996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 TickCountInSeconds ()
3036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#if qWinOS
3066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return GetTickCount () * (1.0 / 1000.0);
3086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#elif qMacOS
3106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
311ca34c1bf7ed72c4a028a6ccac8dc8833e4f7c0f7Kinan Hakim	#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
312ca34c1bf7ed72c4a028a6ccac8dc8833e4f7c0f7Kinan Hakim	// TODO: Needs implementation.
313ca34c1bf7ed72c4a028a6ccac8dc8833e4f7c0f7Kinan Hakim	ThrowProgramError ("TickCountInSeconds() not implemented on iOS");
314ca34c1bf7ed72c4a028a6ccac8dc8833e4f7c0f7Kinan Hakim	return 0;
315c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener	#else
3166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return TickCount () * (1.0 / 60.0);
317ca34c1bf7ed72c4a028a6ccac8dc8833e4f7c0f7Kinan Hakim	#endif  // TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
3186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#else
3206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return TickTimeInSeconds ();
3226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	#endif
3246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimbool gDNGShowTimers = true;
3306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_timer::dng_timer (const char *message)
3326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	fMessage   (message             )
3346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fStartTime (TickTimeInSeconds ())
3356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_timer::~dng_timer ()
3436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (!gDNGShowTimers)
3466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		return;
3476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	real64 totalTime = TickTimeInSeconds () - fStartTime;
3496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fprintf (stderr, "%s: %0.3f sec\n", fMessage, totalTime);
3516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 MaxSquaredDistancePointToRect (const dng_point_real64 &point,
3576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									  const dng_rect_real64 &rect)
3586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	real64 distSqr = DistanceSquared (point,
3616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									  rect.TL ());
3626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	distSqr = Max_real64 (distSqr,
3646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						  DistanceSquared (point,
3656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										   rect.BL ()));
3666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	distSqr = Max_real64 (distSqr,
3686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						  DistanceSquared (point,
3696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										   rect.BR ()));
3706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	distSqr = Max_real64 (distSqr,
3726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						  DistanceSquared (point,
3736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										   rect.TR ()));
3746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return distSqr;
3766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimreal64 MaxDistancePointToRect (const dng_point_real64 &point,
3826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							   const dng_rect_real64 &rect)
3836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return sqrt (MaxSquaredDistancePointToRect (point,
3866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim												rect));
3876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
3896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
3916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_dither::dng_dither ()
3936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	fNoiseBuffer ()
3956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
3976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
3986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const uint32 kSeed = 1;
3996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fNoiseBuffer.Allocate (kRNGSize2D * sizeof (uint16));
4016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	uint16 *buffer = fNoiseBuffer.Buffer_uint16 ();
4036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	uint32 seed = kSeed;
4056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 i = 0; i < kRNGSize2D; i++)
4076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
4086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		seed = DNG_Random (seed);
4106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		buffer [i] = (uint16) (seed);
4126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
4146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
4166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/******************************************************************************/
4186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimconst dng_dither & dng_dither::Get ()
4206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
4216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	static dng_dither dither;
4236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return dither;
4256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
4276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
4296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid HistogramArea (dng_host & /* host */,
4316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					const dng_image &image,
4326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					const dng_rect &area,
4336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					uint32 *hist,
4346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					uint32 maxValue,
4356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					uint32 plane)
4366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
4376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (image.PixelType () == ttShort, "Unsupported pixel type");
4396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DoZeroBytes (hist, (maxValue + 1) * (uint32) sizeof (uint32));
4416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_rect tile;
4436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_tile_iterator iter (image, area);
4456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	while (iter.GetOneTile (tile))
4476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
4486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dng_const_tile_buffer buffer (image, tile);
4506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const void *sPtr = buffer.ConstPixel (tile.t,
4526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											  tile.l,
4536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											  plane);
4546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 count0 = 1;
4566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 count1 = tile.H ();
4576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 count2 = tile.W ();
4586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		int32 step0 = 0;
4606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		int32 step1 = buffer.fRowStep;
4616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		int32 step2 = buffer.fColStep;
4626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		OptimizeOrder (sPtr,
4646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					   buffer.fPixelSize,
4656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					   count0,
4666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					   count1,
4676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					   count2,
4686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					   step0,
4696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					   step1,
4706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					   step2);
4716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		DNG_ASSERT (count0 == 1, "OptimizeOrder logic error");
4736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const uint16 *s1 = (const uint16 *) sPtr;
4756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		for (uint32 row = 0; row < count1; row++)
4776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
4786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			if (maxValue == 0x0FFFF && step2 == 1)
4806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
4816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				for (uint32 col = 0; col < count2; col++)
4836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
4846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					uint32 x = s1 [col];
4866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					hist [x] ++;
4886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
4906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
4926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			else
4946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
4956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const uint16 *s2 = s1;
4976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
4986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				for (uint32 col = 0; col < count2; col++)
4996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
5006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					uint32 x = s2 [0];
5026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					if (x <= maxValue)
5046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						{
5056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						hist [x] ++;
5076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						}
5096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					s2 += step2;
5116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
5136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
5156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			s1 += step1;
5176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
5196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
5216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
5236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
5256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimclass dng_limit_float_depth_task: public dng_area_task
5276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
5286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	private:
5306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const dng_image &fSrcImage;
5326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dng_image &fDstImage;
5346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 fBitDepth;
5366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		real32 fScale;
5386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	public:
5406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dng_limit_float_depth_task (const dng_image &srcImage,
5426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									dng_image &dstImage,
5436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									uint32 bitDepth,
5446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									real32 scale);
5456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		virtual dng_rect RepeatingTile1 () const
5476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
5486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			return fSrcImage.RepeatingTile ();
5496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
5506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		virtual dng_rect RepeatingTile2 () const
5526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
5536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			return fDstImage.RepeatingTile ();
5546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
5556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		virtual void Process (uint32 threadIndex,
5576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							  const dng_rect &tile,
5586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							  dng_abort_sniffer *sniffer);
5596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	};
5616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
5636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_limit_float_depth_task::dng_limit_float_depth_task (const dng_image &srcImage,
5656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														dng_image &dstImage,
5666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														uint32 bitDepth,
5676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim														real32 scale)
5686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	fSrcImage (srcImage)
5706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fDstImage (dstImage)
5716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fBitDepth (bitDepth)
5726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fScale    (scale)
5736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
5756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
5776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
5796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_limit_float_depth_task::Process (uint32 /* threadIndex */,
5816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										  const dng_rect &tile,
5826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim										  dng_abort_sniffer * /* sniffer */)
5836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
5846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_const_tile_buffer srcBuffer (fSrcImage, tile);
5866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_dirty_tile_buffer dstBuffer (fDstImage, tile);
5876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	uint32 count0 = tile.H ();
5896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	uint32 count1 = tile.W ();
5906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	uint32 count2 = fDstImage.Planes ();
5916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	int32 sStep0 = srcBuffer.fRowStep;
5936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	int32 sStep1 = srcBuffer.fColStep;
5946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	int32 sStep2 = srcBuffer.fPlaneStep;
5956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
5966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	int32 dStep0 = dstBuffer.fRowStep;
5976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	int32 dStep1 = dstBuffer.fColStep;
5986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	int32 dStep2 = dstBuffer.fPlaneStep;
5996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const void *sPtr = srcBuffer.ConstPixel (tile.t,
6016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											 tile.l,
6026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											 0);
6036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		  void *dPtr = dstBuffer.DirtyPixel (tile.t,
6056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											 tile.l,
6066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim											 0);
6076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	OptimizeOrder (sPtr,
6096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			       dPtr,
6106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   srcBuffer.fPixelSize,
6116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   dstBuffer.fPixelSize,
6126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   count0,
6136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   count1,
6146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   count2,
6156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   sStep0,
6166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   sStep1,
6176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   sStep2,
6186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   dStep0,
6196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   dStep1,
6206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				   dStep2);
6216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	const real32 *sPtr0 = (const real32 *) sPtr;
6236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		  real32 *dPtr0 = (      real32 *) dPtr;
6246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	real32 scale = fScale;
6266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	bool limit16 = (fBitDepth == 16);
6286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	bool limit24 = (fBitDepth == 24);
6296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	for (uint32 index0 = 0; index0 < count0; index0++)
6316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
6326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const real32 *sPtr1 = sPtr0;
6346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			  real32 *dPtr1 = dPtr0;
6356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		for (uint32 index1 = 0; index1 < count1; index1++)
6376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
6386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// If the scale is a NOP, and the data is packed solid, we can just do memory
6406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// copy.
6416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			if (scale == 1.0f && sStep2 == 1 && dStep2 == 1)
6436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
6446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				if (dPtr1 != sPtr1)			// srcImage != dstImage
6466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
6476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					memcpy (dPtr1, sPtr1, count2 * (uint32) sizeof (real32));
6496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
6516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
6536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			else
6556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
6566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				const real32 *sPtr2 = sPtr1;
6586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  real32 *dPtr2 = dPtr1;
6596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				for (uint32 index2 = 0; index2 < count2; index2++)
6616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
6626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					real32 x = sPtr2 [0];
6646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					x *= scale;
6666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					dPtr2 [0] = x;
6686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					sPtr2 += sStep2;
6706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					dPtr2 += dStep2;
6716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
6736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
6756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			// The data is now in the destination buffer.
6776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			if (limit16)
6796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
6806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				uint32 *dPtr2 = (uint32 *) dPtr1;
6826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				for (uint32 index2 = 0; index2 < count2; index2++)
6846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
6856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					uint32 x = dPtr2 [0];
6876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					uint16 y = DNG_FloatToHalf (x);
6896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					x = DNG_HalfToFloat (y);
6916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					dPtr2 [0] = x;
6936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					dPtr2 += dStep2;
6956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
6976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
6986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
6996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			else if (limit24)
7016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
7026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				uint32 *dPtr2 = (uint32 *) dPtr1;
7046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				for (uint32 index2 = 0; index2 < count2; index2++)
7066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					{
7076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					uint32 x = dPtr2 [0];
7096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					uint8 temp [3];
7116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					DNG_FloatToFP24 (x, temp);
7136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					x = DNG_FP24ToFloat (temp);
7156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					dPtr2 [0] = x;
7176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					dPtr2 += dStep2;
7196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					}
7216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
7236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			sPtr1 += sStep1;
7256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			dPtr1 += dStep1;
7266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
7286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		sPtr0 += sStep0;
7306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dPtr0 += dStep0;
7316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
7336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
7356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/******************************************************************************/
7376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid LimitFloatBitDepth (dng_host &host,
7396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 const dng_image &srcImage,
7406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 dng_image &dstImage,
7416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 uint32 bitDepth,
7426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						 real32 scale)
7436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
7446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (srcImage.PixelType () == ttFloat, "Floating point image expected");
7466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DNG_ASSERT (dstImage.PixelType () == ttFloat, "Floating point image expected");
7476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	dng_limit_float_depth_task task (srcImage,
7496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									 dstImage,
7506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									 bitDepth,
7516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									 scale);
7526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	host.PerformAreaTask (task, dstImage.Bounds ());
7546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
7566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
7576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
758