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.
269 lines
5.6 KiB
269 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); |
|
|
|
} |
|
|
|
} |
|
|
|
/*****************************************************************************/
|
|
|