You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
5.6 KiB
270 lines
5.6 KiB
/*****************************************************************************/
|
|
// Copyright 2006-2007 Adobe Systems Incorporated
|
|
// All Rights Reserved.
|
|
//
|
|
// NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
// accordance with the terms of the Adobe license agreement accompanying it.
|
|
/*****************************************************************************/
|
|
|
|
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_memory_stream.cpp#1 $ */
|
|
/* $DateTime: 2012/05/30 13:28:51 $ */
|
|
/* $Change: 832332 $ */
|
|
/* $Author: tknoll $ */
|
|
|
|
/*****************************************************************************/
|
|
|
|
#include "dng_memory_stream.h"
|
|
|
|
#include "dng_bottlenecks.h"
|
|
#include "dng_exceptions.h"
|
|
#include "dng_safe_arithmetic.h"
|
|
#include "dng_utils.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
dng_memory_stream::dng_memory_stream (dng_memory_allocator &allocator,
|
|
dng_abort_sniffer *sniffer,
|
|
uint32 pageSize)
|
|
|
|
: dng_stream (sniffer,
|
|
kDefaultBufferSize,
|
|
kDNGStreamInvalidOffset)
|
|
|
|
, fAllocator (allocator)
|
|
, fPageSize (pageSize )
|
|
|
|
, fPageCount (0)
|
|
, fPagesAllocated (0)
|
|
, fPageList (NULL)
|
|
|
|
, fMemoryStreamLength (0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
dng_memory_stream::~dng_memory_stream ()
|
|
{
|
|
|
|
if (fPageList)
|
|
{
|
|
|
|
for (uint32 index = 0; index < fPageCount; index++)
|
|
{
|
|
|
|
delete fPageList [index];
|
|
|
|
}
|
|
|
|
free (fPageList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
uint64 dng_memory_stream::DoGetLength ()
|
|
{
|
|
|
|
return fMemoryStreamLength;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void dng_memory_stream::DoRead (void *data,
|
|
uint32 count,
|
|
uint64 offset)
|
|
{
|
|
|
|
if (offset + count > fMemoryStreamLength)
|
|
{
|
|
|
|
ThrowEndOfFile ();
|
|
|
|
}
|
|
|
|
uint64 baseOffset = offset;
|
|
|
|
while (count)
|
|
{
|
|
|
|
uint32 pageIndex = (uint32) (offset / fPageSize);
|
|
uint32 pageOffset = (uint32) (offset % fPageSize);
|
|
|
|
uint32 blockCount = Min_uint32 (fPageSize - pageOffset, count);
|
|
|
|
const uint8 *sPtr = fPageList [pageIndex]->Buffer_uint8 () +
|
|
pageOffset;
|
|
|
|
uint8 *dPtr = ((uint8 *) data) + (uint32) (offset - baseOffset);
|
|
|
|
DoCopyBytes (sPtr, dPtr, blockCount);
|
|
|
|
offset += blockCount;
|
|
count -= blockCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void dng_memory_stream::DoSetLength (uint64 length)
|
|
{
|
|
|
|
while (length > fPageCount * (uint64) fPageSize)
|
|
{
|
|
|
|
if (fPageCount == fPagesAllocated)
|
|
{
|
|
|
|
uint32 newSizeTemp1 = 0, newSizeTemp2 = 0;
|
|
if (!SafeUint32Add (fPagesAllocated, 32u, &newSizeTemp1) ||
|
|
!SafeUint32Mult (fPagesAllocated, 2u, &newSizeTemp2))
|
|
{
|
|
ThrowMemoryFull ("Arithmetic overflow in DoSetLength()");
|
|
}
|
|
uint32 newSize = Max_uint32 (newSizeTemp1, newSizeTemp2);
|
|
uint32 numBytes;
|
|
if (!SafeUint32Mult (newSize, sizeof (dng_memory_block *),
|
|
&numBytes))
|
|
{
|
|
ThrowMemoryFull ("Arithmetic overflow in DoSetLength()");
|
|
}
|
|
|
|
dng_memory_block **list = (dng_memory_block **) malloc (numBytes);
|
|
|
|
if (!list)
|
|
{
|
|
|
|
ThrowMemoryFull ();
|
|
|
|
}
|
|
|
|
if (fPageCount)
|
|
{
|
|
|
|
// The multiplication here is safe against overflow. fPageCount
|
|
// can never reach a value that is large enough to cause
|
|
// overflow because the computation of numBytes above would fail
|
|
// before a list of that size could be allocated.
|
|
DoCopyBytes (fPageList,
|
|
list,
|
|
fPageCount * (uint32) sizeof (dng_memory_block *));
|
|
|
|
}
|
|
|
|
if (fPageList)
|
|
{
|
|
|
|
free (fPageList);
|
|
|
|
}
|
|
|
|
fPageList = list;
|
|
|
|
fPagesAllocated = newSize;
|
|
|
|
}
|
|
|
|
fPageList [fPageCount] = fAllocator.Allocate (fPageSize);
|
|
|
|
fPageCount++;
|
|
|
|
}
|
|
|
|
fMemoryStreamLength = length;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void dng_memory_stream::DoWrite (const void *data,
|
|
uint32 count,
|
|
uint64 offset)
|
|
{
|
|
|
|
DoSetLength (Max_uint64 (fMemoryStreamLength,
|
|
offset + count));
|
|
|
|
uint64 baseOffset = offset;
|
|
|
|
while (count)
|
|
{
|
|
|
|
uint32 pageIndex = (uint32) (offset / fPageSize);
|
|
uint32 pageOffset = (uint32) (offset % fPageSize);
|
|
|
|
uint32 blockCount = Min_uint32 (fPageSize - pageOffset, count);
|
|
|
|
const uint8 *sPtr = ((const uint8 *) data) + (uint32) (offset - baseOffset);
|
|
|
|
uint8 *dPtr = fPageList [pageIndex]->Buffer_uint8 () +
|
|
pageOffset;
|
|
|
|
DoCopyBytes (sPtr, dPtr, blockCount);
|
|
|
|
offset += blockCount;
|
|
count -= blockCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void dng_memory_stream::CopyToStream (dng_stream &dstStream,
|
|
uint64 count)
|
|
{
|
|
|
|
if (count < kBigBufferSize)
|
|
{
|
|
|
|
dng_stream::CopyToStream (dstStream, count);
|
|
|
|
}
|
|
|
|
else
|
|
{
|
|
|
|
Flush ();
|
|
|
|
uint64 offset = Position ();
|
|
|
|
if (offset + count > Length ())
|
|
{
|
|
|
|
ThrowEndOfFile ();
|
|
|
|
}
|
|
|
|
while (count)
|
|
{
|
|
|
|
uint32 pageIndex = (uint32) (offset / fPageSize);
|
|
uint32 pageOffset = (uint32) (offset % fPageSize);
|
|
|
|
uint32 blockCount = (uint32) Min_uint64 (fPageSize - pageOffset, count);
|
|
|
|
const uint8 *sPtr = fPageList [pageIndex]->Buffer_uint8 () +
|
|
pageOffset;
|
|
|
|
dstStream.Put (sPtr, blockCount);
|
|
|
|
offset += blockCount;
|
|
count -= blockCount;
|
|
|
|
}
|
|
|
|
SetReadPosition (offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|