16e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
26e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// Copyright 2006-2007 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_memory_stream.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 "dng_memory_stream.h"
176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_bottlenecks.h"
196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_exceptions.h"
206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_safe_arithmetic.h"
216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_utils.h"
226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_memory_stream::dng_memory_stream (dng_memory_allocator &allocator,
266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									  dng_abort_sniffer *sniffer,
276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						   			  uint32 pageSize)
286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	:	dng_stream (sniffer,
306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					kDefaultBufferSize,
316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					kDNGStreamInvalidOffset)
326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fAllocator (allocator)
346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fPageSize  (pageSize )
356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fPageCount      (0)
376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fPagesAllocated (0)
386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fPageList       (NULL)
396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	,	fMemoryStreamLength (0)
416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_memory_stream::~dng_memory_stream ()
496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (fPageList)
526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		for (uint32 index = 0; index < fPageCount; index++)
556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			delete fPageList [index];
586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		free (fPageList);
626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimuint64 dng_memory_stream::DoGetLength ()
706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	return fMemoryStreamLength;
736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_memory_stream::DoRead (void *data,
796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							    uint32 count,
806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							    uint64 offset)
816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (offset + count > fMemoryStreamLength)
846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		ThrowEndOfFile ();
876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	uint64 baseOffset = offset;
916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	while (count)
936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 pageIndex  = (uint32) (offset / fPageSize);
966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 pageOffset = (uint32) (offset % fPageSize);
976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 blockCount = Min_uint32 (fPageSize - pageOffset, count);
996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const uint8 *sPtr = fPageList [pageIndex]->Buffer_uint8 () +
1016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim						    pageOffset;
1026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint8 *dPtr = ((uint8 *) data) + (uint32) (offset - baseOffset);
1046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		DoCopyBytes (sPtr, dPtr, blockCount);
1066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		offset += blockCount;
1086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		count  -= blockCount;
1096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
1136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_memory_stream::DoSetLength (uint64 length)
1176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
1186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	while (length > fPageCount * (uint64) fPageSize)
1206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (fPageCount == fPagesAllocated)
1236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
124c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener
1256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			uint32 newSizeTemp1 = 0, newSizeTemp2 = 0;
1266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			if (!SafeUint32Add (fPagesAllocated, 32u, &newSizeTemp1) ||
1276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				!SafeUint32Mult (fPagesAllocated, 2u, &newSizeTemp2))
1286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
1296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				ThrowMemoryFull ("Arithmetic overflow in DoSetLength()");
1306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
1316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			uint32 newSize = Max_uint32 (newSizeTemp1, newSizeTemp2);
1326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			uint32 numBytes;
1336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			if (!SafeUint32Mult (newSize, sizeof (dng_memory_block *),
1346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								 &numBytes))
1356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
1366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				ThrowMemoryFull ("Arithmetic overflow in DoSetLength()");
1376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
138c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener
1396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			dng_memory_block **list = (dng_memory_block **) malloc (numBytes);
140c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener
141c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener			if (!list)
1426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
1436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				ThrowMemoryFull ();
1456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
1476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			if (fPageCount)
1496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
1506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// The multiplication here is safe against overflow. fPageCount
1526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// can never reach a value that is large enough to cause
1536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// overflow because the computation of numBytes above would fail
1546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				// before a list of that size could be allocated.
1556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				DoCopyBytes (fPageList,
1566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							 list,
1576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							 fPageCount * (uint32) sizeof (dng_memory_block *));
1586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
1606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			if (fPageList)
1626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				{
1636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				free (fPageList);
1656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim				}
1676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			fPageList = list;
1696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			fPagesAllocated = newSize;
1716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
1736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fPageList [fPageCount] = fAllocator.Allocate (fPageSize);
1756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		fPageCount++;
1776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
1796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	fMemoryStreamLength = length;
1816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
1836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
1856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_memory_stream::DoWrite (const void *data,
1876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							     uint32 count,
1886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							     uint64 offset)
1896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
1906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	DoSetLength (Max_uint64 (fMemoryStreamLength,
1926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim							 offset + count));
1936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	uint64 baseOffset = offset;
1956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	while (count)
1976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
1986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
1996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 pageIndex  = (uint32) (offset / fPageSize);
2006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 pageOffset = (uint32) (offset % fPageSize);
2016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint32 blockCount = Min_uint32 (fPageSize - pageOffset, count);
2036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		const uint8 *sPtr = ((const uint8 *) data) + (uint32) (offset - baseOffset);
2056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint8 *dPtr = fPageList [pageIndex]->Buffer_uint8 () +
2076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim					  pageOffset;
2086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		DoCopyBytes (sPtr, dPtr, blockCount);
2106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		offset += blockCount;
2126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		count  -= blockCount;
2136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
2156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
2176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
2196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_memory_stream::CopyToStream (dng_stream &dstStream,
2216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim									  uint64 count)
2226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	{
2236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	if (count < kBigBufferSize)
2256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
2266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		dng_stream::CopyToStream (dstStream, count);
2286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
2306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	else
2326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		{
2336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		Flush ();
2356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		uint64 offset = Position ();
2376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		if (offset + count > Length ())
2396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
2406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			ThrowEndOfFile ();
2426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
2446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		while (count)
2466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			{
2476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			uint32 pageIndex  = (uint32) (offset / fPageSize);
2496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			uint32 pageOffset = (uint32) (offset % fPageSize);
2506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			uint32 blockCount = (uint32) Min_uint64 (fPageSize - pageOffset, count);
2526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			const uint8 *sPtr = fPageList [pageIndex]->Buffer_uint8 () +
2546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim								pageOffset;
2556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			dstStream.Put (sPtr, blockCount);
2576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			offset += blockCount;
2596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			count  -= blockCount;
2606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim			}
2626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		SetReadPosition (offset);
2646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim		}
2666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim	}
2686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim
2696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/
270