xref: /aosp_15_r20/external/dng_sdk/source/dng_stream.cpp (revision fd1fabb72dbdf09ea7034f531e6f8e9f57334c8d)
1*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2*fd1fabb7SAndroid Build Coastguard Worker // Copyright 2006-2007 Adobe Systems Incorporated
3*fd1fabb7SAndroid Build Coastguard Worker // All Rights Reserved.
4*fd1fabb7SAndroid Build Coastguard Worker //
5*fd1fabb7SAndroid Build Coastguard Worker // NOTICE:  Adobe permits you to use, modify, and distribute this file in
6*fd1fabb7SAndroid Build Coastguard Worker // accordance with the terms of the Adobe license agreement accompanying it.
7*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
8*fd1fabb7SAndroid Build Coastguard Worker 
9*fd1fabb7SAndroid Build Coastguard Worker /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_stream.cpp#2 $ */
10*fd1fabb7SAndroid Build Coastguard Worker /* $DateTime: 2012/06/01 07:28:57 $ */
11*fd1fabb7SAndroid Build Coastguard Worker /* $Change: 832715 $ */
12*fd1fabb7SAndroid Build Coastguard Worker /* $Author: tknoll $ */
13*fd1fabb7SAndroid Build Coastguard Worker 
14*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
15*fd1fabb7SAndroid Build Coastguard Worker 
16*fd1fabb7SAndroid Build Coastguard Worker #include "dng_stream.h"
17*fd1fabb7SAndroid Build Coastguard Worker 
18*fd1fabb7SAndroid Build Coastguard Worker #include "dng_abort_sniffer.h"
19*fd1fabb7SAndroid Build Coastguard Worker #include "dng_auto_ptr.h"
20*fd1fabb7SAndroid Build Coastguard Worker #include "dng_bottlenecks.h"
21*fd1fabb7SAndroid Build Coastguard Worker #include "dng_exceptions.h"
22*fd1fabb7SAndroid Build Coastguard Worker #include "dng_flags.h"
23*fd1fabb7SAndroid Build Coastguard Worker #include "dng_memory.h"
24*fd1fabb7SAndroid Build Coastguard Worker #include "dng_tag_types.h"
25*fd1fabb7SAndroid Build Coastguard Worker 
26*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
27*fd1fabb7SAndroid Build Coastguard Worker 
dng_stream(dng_abort_sniffer * sniffer,uint32 bufferSize,uint64 offsetInOriginalFile)28*fd1fabb7SAndroid Build Coastguard Worker dng_stream::dng_stream (dng_abort_sniffer *sniffer,
29*fd1fabb7SAndroid Build Coastguard Worker 						uint32 bufferSize,
30*fd1fabb7SAndroid Build Coastguard Worker 						uint64 offsetInOriginalFile)
31*fd1fabb7SAndroid Build Coastguard Worker 
32*fd1fabb7SAndroid Build Coastguard Worker 	:	fSwapBytes			  (false)
33*fd1fabb7SAndroid Build Coastguard Worker 	,	fHaveLength			  (false)
34*fd1fabb7SAndroid Build Coastguard Worker 	,	fLength				  (0)
35*fd1fabb7SAndroid Build Coastguard Worker 	,	fOffsetInOriginalFile (offsetInOriginalFile)
36*fd1fabb7SAndroid Build Coastguard Worker 	,	fPosition			  (0)
37*fd1fabb7SAndroid Build Coastguard Worker 	,	fMemBlock			  (bufferSize)
38*fd1fabb7SAndroid Build Coastguard Worker 	,	fBuffer				  (fMemBlock.Buffer_uint8 ())
39*fd1fabb7SAndroid Build Coastguard Worker 	,	fBufferSize			  (bufferSize)
40*fd1fabb7SAndroid Build Coastguard Worker 	,	fBufferStart		  (0)
41*fd1fabb7SAndroid Build Coastguard Worker 	,	fBufferEnd			  (0)
42*fd1fabb7SAndroid Build Coastguard Worker 	,	fBufferLimit		  (bufferSize)
43*fd1fabb7SAndroid Build Coastguard Worker 	,	fBufferDirty		  (false)
44*fd1fabb7SAndroid Build Coastguard Worker 	,	fSniffer			  (sniffer)
45*fd1fabb7SAndroid Build Coastguard Worker 
46*fd1fabb7SAndroid Build Coastguard Worker 	{
47*fd1fabb7SAndroid Build Coastguard Worker 
48*fd1fabb7SAndroid Build Coastguard Worker 	}
49*fd1fabb7SAndroid Build Coastguard Worker 
50*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
51*fd1fabb7SAndroid Build Coastguard Worker 
dng_stream(const void * data,uint32 count,uint64 offsetInOriginalFile)52*fd1fabb7SAndroid Build Coastguard Worker dng_stream::dng_stream (const void *data,
53*fd1fabb7SAndroid Build Coastguard Worker 						uint32 count,
54*fd1fabb7SAndroid Build Coastguard Worker 						uint64 offsetInOriginalFile)
55*fd1fabb7SAndroid Build Coastguard Worker 
56*fd1fabb7SAndroid Build Coastguard Worker 	:	fSwapBytes			  (false)
57*fd1fabb7SAndroid Build Coastguard Worker 	,	fHaveLength			  (true)
58*fd1fabb7SAndroid Build Coastguard Worker 	,	fLength				  (count)
59*fd1fabb7SAndroid Build Coastguard Worker 	,	fOffsetInOriginalFile (offsetInOriginalFile)
60*fd1fabb7SAndroid Build Coastguard Worker 	,	fPosition			  (0)
61*fd1fabb7SAndroid Build Coastguard Worker 	,	fMemBlock			  ()
62*fd1fabb7SAndroid Build Coastguard Worker 	,	fBuffer				  ((uint8 *) data)
63*fd1fabb7SAndroid Build Coastguard Worker 	,	fBufferSize			  (count)
64*fd1fabb7SAndroid Build Coastguard Worker 	,	fBufferStart		  (0)
65*fd1fabb7SAndroid Build Coastguard Worker 	,	fBufferEnd			  (count)
66*fd1fabb7SAndroid Build Coastguard Worker 	,	fBufferLimit		  (count)
67*fd1fabb7SAndroid Build Coastguard Worker 	,	fBufferDirty		  (false)
68*fd1fabb7SAndroid Build Coastguard Worker 	,	fSniffer			  (NULL)
69*fd1fabb7SAndroid Build Coastguard Worker 
70*fd1fabb7SAndroid Build Coastguard Worker 	{
71*fd1fabb7SAndroid Build Coastguard Worker 
72*fd1fabb7SAndroid Build Coastguard Worker 	}
73*fd1fabb7SAndroid Build Coastguard Worker 
74*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
75*fd1fabb7SAndroid Build Coastguard Worker 
~dng_stream()76*fd1fabb7SAndroid Build Coastguard Worker dng_stream::~dng_stream ()
77*fd1fabb7SAndroid Build Coastguard Worker 	{
78*fd1fabb7SAndroid Build Coastguard Worker 
79*fd1fabb7SAndroid Build Coastguard Worker 	}
80*fd1fabb7SAndroid Build Coastguard Worker 
81*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
82*fd1fabb7SAndroid Build Coastguard Worker 
DoGetLength()83*fd1fabb7SAndroid Build Coastguard Worker uint64 dng_stream::DoGetLength ()
84*fd1fabb7SAndroid Build Coastguard Worker 	{
85*fd1fabb7SAndroid Build Coastguard Worker 
86*fd1fabb7SAndroid Build Coastguard Worker 	ThrowProgramError ();
87*fd1fabb7SAndroid Build Coastguard Worker 
88*fd1fabb7SAndroid Build Coastguard Worker 	return 0;
89*fd1fabb7SAndroid Build Coastguard Worker 
90*fd1fabb7SAndroid Build Coastguard Worker 	}
91*fd1fabb7SAndroid Build Coastguard Worker 
92*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
93*fd1fabb7SAndroid Build Coastguard Worker 
DoRead(void *,uint32,uint64)94*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::DoRead (void * /* data */,
95*fd1fabb7SAndroid Build Coastguard Worker 						 uint32 /* count */,
96*fd1fabb7SAndroid Build Coastguard Worker 						 uint64 /* offset */)
97*fd1fabb7SAndroid Build Coastguard Worker 	{
98*fd1fabb7SAndroid Build Coastguard Worker 
99*fd1fabb7SAndroid Build Coastguard Worker 	ThrowProgramError ();
100*fd1fabb7SAndroid Build Coastguard Worker 
101*fd1fabb7SAndroid Build Coastguard Worker 	}
102*fd1fabb7SAndroid Build Coastguard Worker 
103*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
104*fd1fabb7SAndroid Build Coastguard Worker 
DoSetLength(uint64)105*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::DoSetLength (uint64 /* length */)
106*fd1fabb7SAndroid Build Coastguard Worker 	{
107*fd1fabb7SAndroid Build Coastguard Worker 
108*fd1fabb7SAndroid Build Coastguard Worker 	ThrowProgramError ();
109*fd1fabb7SAndroid Build Coastguard Worker 
110*fd1fabb7SAndroid Build Coastguard Worker 	}
111*fd1fabb7SAndroid Build Coastguard Worker 
112*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
113*fd1fabb7SAndroid Build Coastguard Worker 
DoWrite(const void *,uint32,uint64)114*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::DoWrite (const void * /* data */,
115*fd1fabb7SAndroid Build Coastguard Worker 						  uint32 /* count */,
116*fd1fabb7SAndroid Build Coastguard Worker 						  uint64 /* offset */)
117*fd1fabb7SAndroid Build Coastguard Worker 	{
118*fd1fabb7SAndroid Build Coastguard Worker 
119*fd1fabb7SAndroid Build Coastguard Worker 	ThrowProgramError ();
120*fd1fabb7SAndroid Build Coastguard Worker 
121*fd1fabb7SAndroid Build Coastguard Worker 	}
122*fd1fabb7SAndroid Build Coastguard Worker 
123*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
124*fd1fabb7SAndroid Build Coastguard Worker 
BigEndian() const125*fd1fabb7SAndroid Build Coastguard Worker bool dng_stream::BigEndian () const
126*fd1fabb7SAndroid Build Coastguard Worker 	{
127*fd1fabb7SAndroid Build Coastguard Worker 
128*fd1fabb7SAndroid Build Coastguard Worker 	return fSwapBytes != (!!qDNGBigEndian);
129*fd1fabb7SAndroid Build Coastguard Worker 
130*fd1fabb7SAndroid Build Coastguard Worker 	}
131*fd1fabb7SAndroid Build Coastguard Worker 
132*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
133*fd1fabb7SAndroid Build Coastguard Worker 
SetBigEndian(bool bigEndian)134*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::SetBigEndian (bool bigEndian)
135*fd1fabb7SAndroid Build Coastguard Worker 	{
136*fd1fabb7SAndroid Build Coastguard Worker 
137*fd1fabb7SAndroid Build Coastguard Worker 	fSwapBytes = (bigEndian != (!!qDNGBigEndian));
138*fd1fabb7SAndroid Build Coastguard Worker 
139*fd1fabb7SAndroid Build Coastguard Worker 	}
140*fd1fabb7SAndroid Build Coastguard Worker 
141*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
142*fd1fabb7SAndroid Build Coastguard Worker 
Data() const143*fd1fabb7SAndroid Build Coastguard Worker const void * dng_stream::Data () const
144*fd1fabb7SAndroid Build Coastguard Worker 	{
145*fd1fabb7SAndroid Build Coastguard Worker 
146*fd1fabb7SAndroid Build Coastguard Worker 	if (fBufferStart == 0 && fHaveLength && fBufferEnd == fLength)
147*fd1fabb7SAndroid Build Coastguard Worker 		{
148*fd1fabb7SAndroid Build Coastguard Worker 
149*fd1fabb7SAndroid Build Coastguard Worker 		return fBuffer;
150*fd1fabb7SAndroid Build Coastguard Worker 
151*fd1fabb7SAndroid Build Coastguard Worker 		}
152*fd1fabb7SAndroid Build Coastguard Worker 
153*fd1fabb7SAndroid Build Coastguard Worker 	return NULL;
154*fd1fabb7SAndroid Build Coastguard Worker 
155*fd1fabb7SAndroid Build Coastguard Worker 	}
156*fd1fabb7SAndroid Build Coastguard Worker 
157*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
158*fd1fabb7SAndroid Build Coastguard Worker 
AsMemoryBlock(dng_memory_allocator & allocator)159*fd1fabb7SAndroid Build Coastguard Worker dng_memory_block * dng_stream::AsMemoryBlock (dng_memory_allocator &allocator)
160*fd1fabb7SAndroid Build Coastguard Worker 	{
161*fd1fabb7SAndroid Build Coastguard Worker 
162*fd1fabb7SAndroid Build Coastguard Worker 	Flush ();
163*fd1fabb7SAndroid Build Coastguard Worker 
164*fd1fabb7SAndroid Build Coastguard Worker 	uint64 len64 = Length ();
165*fd1fabb7SAndroid Build Coastguard Worker 
166*fd1fabb7SAndroid Build Coastguard Worker 	if (len64 > 0xFFFFFFFF)
167*fd1fabb7SAndroid Build Coastguard Worker 		{
168*fd1fabb7SAndroid Build Coastguard Worker 		ThrowProgramError ();
169*fd1fabb7SAndroid Build Coastguard Worker 		}
170*fd1fabb7SAndroid Build Coastguard Worker 
171*fd1fabb7SAndroid Build Coastguard Worker 	uint32 len = (uint32) len64;
172*fd1fabb7SAndroid Build Coastguard Worker 
173*fd1fabb7SAndroid Build Coastguard Worker 	AutoPtr<dng_memory_block> block (allocator.Allocate (len));
174*fd1fabb7SAndroid Build Coastguard Worker 
175*fd1fabb7SAndroid Build Coastguard Worker 	if (len)
176*fd1fabb7SAndroid Build Coastguard Worker 		{
177*fd1fabb7SAndroid Build Coastguard Worker 
178*fd1fabb7SAndroid Build Coastguard Worker 		SetReadPosition (0);
179*fd1fabb7SAndroid Build Coastguard Worker 
180*fd1fabb7SAndroid Build Coastguard Worker 		Get (block->Buffer (), len);
181*fd1fabb7SAndroid Build Coastguard Worker 
182*fd1fabb7SAndroid Build Coastguard Worker 		}
183*fd1fabb7SAndroid Build Coastguard Worker 
184*fd1fabb7SAndroid Build Coastguard Worker 	return block.Release ();
185*fd1fabb7SAndroid Build Coastguard Worker 
186*fd1fabb7SAndroid Build Coastguard Worker 	}
187*fd1fabb7SAndroid Build Coastguard Worker 
188*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
189*fd1fabb7SAndroid Build Coastguard Worker 
SetReadPosition(uint64 offset)190*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::SetReadPosition (uint64 offset)
191*fd1fabb7SAndroid Build Coastguard Worker 	{
192*fd1fabb7SAndroid Build Coastguard Worker 
193*fd1fabb7SAndroid Build Coastguard Worker 	fPosition = offset;
194*fd1fabb7SAndroid Build Coastguard Worker 
195*fd1fabb7SAndroid Build Coastguard Worker 	if (fPosition > Length ())
196*fd1fabb7SAndroid Build Coastguard Worker 		{
197*fd1fabb7SAndroid Build Coastguard Worker 
198*fd1fabb7SAndroid Build Coastguard Worker 		ThrowEndOfFile ();
199*fd1fabb7SAndroid Build Coastguard Worker 
200*fd1fabb7SAndroid Build Coastguard Worker 		}
201*fd1fabb7SAndroid Build Coastguard Worker 
202*fd1fabb7SAndroid Build Coastguard Worker 	}
203*fd1fabb7SAndroid Build Coastguard Worker 
204*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
205*fd1fabb7SAndroid Build Coastguard Worker 
OffsetInOriginalFile() const206*fd1fabb7SAndroid Build Coastguard Worker uint64 dng_stream::OffsetInOriginalFile () const
207*fd1fabb7SAndroid Build Coastguard Worker 	{
208*fd1fabb7SAndroid Build Coastguard Worker 
209*fd1fabb7SAndroid Build Coastguard Worker 	return fOffsetInOriginalFile;
210*fd1fabb7SAndroid Build Coastguard Worker 
211*fd1fabb7SAndroid Build Coastguard Worker 	}
212*fd1fabb7SAndroid Build Coastguard Worker 
213*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
214*fd1fabb7SAndroid Build Coastguard Worker 
PositionInOriginalFile() const215*fd1fabb7SAndroid Build Coastguard Worker uint64 dng_stream::PositionInOriginalFile () const
216*fd1fabb7SAndroid Build Coastguard Worker 	{
217*fd1fabb7SAndroid Build Coastguard Worker 
218*fd1fabb7SAndroid Build Coastguard Worker 	if (fOffsetInOriginalFile == kDNGStreamInvalidOffset)
219*fd1fabb7SAndroid Build Coastguard Worker 		return kDNGStreamInvalidOffset;
220*fd1fabb7SAndroid Build Coastguard Worker 
221*fd1fabb7SAndroid Build Coastguard Worker 	return fOffsetInOriginalFile + Position ();
222*fd1fabb7SAndroid Build Coastguard Worker 
223*fd1fabb7SAndroid Build Coastguard Worker 	}
224*fd1fabb7SAndroid Build Coastguard Worker 
225*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
226*fd1fabb7SAndroid Build Coastguard Worker 
Get(void * data,uint32 count)227*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::Get (void *data, uint32 count)
228*fd1fabb7SAndroid Build Coastguard Worker 	{
229*fd1fabb7SAndroid Build Coastguard Worker 
230*fd1fabb7SAndroid Build Coastguard Worker 	while (count)
231*fd1fabb7SAndroid Build Coastguard Worker 		{
232*fd1fabb7SAndroid Build Coastguard Worker 
233*fd1fabb7SAndroid Build Coastguard Worker 		// See if the request is totally inside buffer.
234*fd1fabb7SAndroid Build Coastguard Worker 
235*fd1fabb7SAndroid Build Coastguard Worker 		if (fPosition >= fBufferStart && fPosition + count <= fBufferEnd)
236*fd1fabb7SAndroid Build Coastguard Worker 			{
237*fd1fabb7SAndroid Build Coastguard Worker 
238*fd1fabb7SAndroid Build Coastguard Worker 			DoCopyBytes (fBuffer + (uint32) (fPosition - fBufferStart),
239*fd1fabb7SAndroid Build Coastguard Worker 						 data,
240*fd1fabb7SAndroid Build Coastguard Worker 						 count);
241*fd1fabb7SAndroid Build Coastguard Worker 
242*fd1fabb7SAndroid Build Coastguard Worker 			fPosition += count;
243*fd1fabb7SAndroid Build Coastguard Worker 
244*fd1fabb7SAndroid Build Coastguard Worker 			return;
245*fd1fabb7SAndroid Build Coastguard Worker 
246*fd1fabb7SAndroid Build Coastguard Worker 			}
247*fd1fabb7SAndroid Build Coastguard Worker 
248*fd1fabb7SAndroid Build Coastguard Worker 		// See if first part of request is inside buffer.
249*fd1fabb7SAndroid Build Coastguard Worker 
250*fd1fabb7SAndroid Build Coastguard Worker 		if (fPosition >= fBufferStart && fPosition < fBufferEnd)
251*fd1fabb7SAndroid Build Coastguard Worker 			{
252*fd1fabb7SAndroid Build Coastguard Worker 
253*fd1fabb7SAndroid Build Coastguard Worker 			uint32 block = (uint32) (fBufferEnd - fPosition);
254*fd1fabb7SAndroid Build Coastguard Worker 
255*fd1fabb7SAndroid Build Coastguard Worker 			DoCopyBytes (fBuffer + (fPosition - fBufferStart),
256*fd1fabb7SAndroid Build Coastguard Worker 						 data,
257*fd1fabb7SAndroid Build Coastguard Worker 						 block);
258*fd1fabb7SAndroid Build Coastguard Worker 
259*fd1fabb7SAndroid Build Coastguard Worker 			count -= block;
260*fd1fabb7SAndroid Build Coastguard Worker 
261*fd1fabb7SAndroid Build Coastguard Worker 			data = (void *) (((char *) data) + block);
262*fd1fabb7SAndroid Build Coastguard Worker 
263*fd1fabb7SAndroid Build Coastguard Worker 			fPosition += block;
264*fd1fabb7SAndroid Build Coastguard Worker 
265*fd1fabb7SAndroid Build Coastguard Worker 			}
266*fd1fabb7SAndroid Build Coastguard Worker 
267*fd1fabb7SAndroid Build Coastguard Worker 		// Flush buffer if dirty.
268*fd1fabb7SAndroid Build Coastguard Worker 
269*fd1fabb7SAndroid Build Coastguard Worker 		Flush ();
270*fd1fabb7SAndroid Build Coastguard Worker 
271*fd1fabb7SAndroid Build Coastguard Worker 		// Do large reads unbuffered.
272*fd1fabb7SAndroid Build Coastguard Worker 
273*fd1fabb7SAndroid Build Coastguard Worker 		if (count > fBufferSize)
274*fd1fabb7SAndroid Build Coastguard Worker 			{
275*fd1fabb7SAndroid Build Coastguard Worker 
276*fd1fabb7SAndroid Build Coastguard Worker 			if (fPosition + count > Length ())
277*fd1fabb7SAndroid Build Coastguard Worker 				{
278*fd1fabb7SAndroid Build Coastguard Worker 
279*fd1fabb7SAndroid Build Coastguard Worker 				ThrowEndOfFile ();
280*fd1fabb7SAndroid Build Coastguard Worker 
281*fd1fabb7SAndroid Build Coastguard Worker 				}
282*fd1fabb7SAndroid Build Coastguard Worker 
283*fd1fabb7SAndroid Build Coastguard Worker 			DoRead (data,
284*fd1fabb7SAndroid Build Coastguard Worker 					count,
285*fd1fabb7SAndroid Build Coastguard Worker 					fPosition);
286*fd1fabb7SAndroid Build Coastguard Worker 
287*fd1fabb7SAndroid Build Coastguard Worker 			fPosition += count;
288*fd1fabb7SAndroid Build Coastguard Worker 
289*fd1fabb7SAndroid Build Coastguard Worker 			return;
290*fd1fabb7SAndroid Build Coastguard Worker 
291*fd1fabb7SAndroid Build Coastguard Worker 			}
292*fd1fabb7SAndroid Build Coastguard Worker 
293*fd1fabb7SAndroid Build Coastguard Worker 		// Figure out new buffer range.
294*fd1fabb7SAndroid Build Coastguard Worker 
295*fd1fabb7SAndroid Build Coastguard Worker 		fBufferStart = fPosition;
296*fd1fabb7SAndroid Build Coastguard Worker 
297*fd1fabb7SAndroid Build Coastguard Worker 		if (fBufferSize >= 4096)
298*fd1fabb7SAndroid Build Coastguard Worker 			{
299*fd1fabb7SAndroid Build Coastguard Worker 
300*fd1fabb7SAndroid Build Coastguard Worker 			// Align to a 4K file block.
301*fd1fabb7SAndroid Build Coastguard Worker 
302*fd1fabb7SAndroid Build Coastguard Worker 			fBufferStart &= (uint64) ~((int64) 4095);
303*fd1fabb7SAndroid Build Coastguard Worker 
304*fd1fabb7SAndroid Build Coastguard Worker 			}
305*fd1fabb7SAndroid Build Coastguard Worker 
306*fd1fabb7SAndroid Build Coastguard Worker 		fBufferEnd = Min_uint64 (fBufferStart + fBufferSize, Length ());
307*fd1fabb7SAndroid Build Coastguard Worker 
308*fd1fabb7SAndroid Build Coastguard Worker 		if (fBufferEnd <= fPosition)
309*fd1fabb7SAndroid Build Coastguard Worker 			{
310*fd1fabb7SAndroid Build Coastguard Worker 
311*fd1fabb7SAndroid Build Coastguard Worker 			ThrowEndOfFile ();
312*fd1fabb7SAndroid Build Coastguard Worker 
313*fd1fabb7SAndroid Build Coastguard Worker 			}
314*fd1fabb7SAndroid Build Coastguard Worker 
315*fd1fabb7SAndroid Build Coastguard Worker 		// Read data into buffer.
316*fd1fabb7SAndroid Build Coastguard Worker 
317*fd1fabb7SAndroid Build Coastguard Worker 		dng_abort_sniffer::SniffForAbort (fSniffer);
318*fd1fabb7SAndroid Build Coastguard Worker 
319*fd1fabb7SAndroid Build Coastguard Worker 		DoRead (fBuffer,
320*fd1fabb7SAndroid Build Coastguard Worker 				(uint32) (fBufferEnd - fBufferStart),
321*fd1fabb7SAndroid Build Coastguard Worker 				fBufferStart);
322*fd1fabb7SAndroid Build Coastguard Worker 
323*fd1fabb7SAndroid Build Coastguard Worker 		}
324*fd1fabb7SAndroid Build Coastguard Worker 
325*fd1fabb7SAndroid Build Coastguard Worker 	}
326*fd1fabb7SAndroid Build Coastguard Worker 
327*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
328*fd1fabb7SAndroid Build Coastguard Worker 
SetWritePosition(uint64 offset)329*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::SetWritePosition (uint64 offset)
330*fd1fabb7SAndroid Build Coastguard Worker 	{
331*fd1fabb7SAndroid Build Coastguard Worker 
332*fd1fabb7SAndroid Build Coastguard Worker 	fPosition = offset;
333*fd1fabb7SAndroid Build Coastguard Worker 
334*fd1fabb7SAndroid Build Coastguard Worker 	}
335*fd1fabb7SAndroid Build Coastguard Worker 
336*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
337*fd1fabb7SAndroid Build Coastguard Worker 
Flush()338*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::Flush ()
339*fd1fabb7SAndroid Build Coastguard Worker 	{
340*fd1fabb7SAndroid Build Coastguard Worker 
341*fd1fabb7SAndroid Build Coastguard Worker 	if (fBufferDirty)
342*fd1fabb7SAndroid Build Coastguard Worker 		{
343*fd1fabb7SAndroid Build Coastguard Worker 
344*fd1fabb7SAndroid Build Coastguard Worker 		dng_abort_sniffer::SniffForAbort (fSniffer);
345*fd1fabb7SAndroid Build Coastguard Worker 
346*fd1fabb7SAndroid Build Coastguard Worker 		DoWrite (fBuffer,
347*fd1fabb7SAndroid Build Coastguard Worker 				 (uint32) (fBufferEnd - fBufferStart),
348*fd1fabb7SAndroid Build Coastguard Worker 				 fBufferStart);
349*fd1fabb7SAndroid Build Coastguard Worker 
350*fd1fabb7SAndroid Build Coastguard Worker 		fBufferStart = 0;
351*fd1fabb7SAndroid Build Coastguard Worker 		fBufferEnd   = 0;
352*fd1fabb7SAndroid Build Coastguard Worker 		fBufferLimit = fBufferSize;
353*fd1fabb7SAndroid Build Coastguard Worker 
354*fd1fabb7SAndroid Build Coastguard Worker 		fBufferDirty = false;
355*fd1fabb7SAndroid Build Coastguard Worker 
356*fd1fabb7SAndroid Build Coastguard Worker 		}
357*fd1fabb7SAndroid Build Coastguard Worker 
358*fd1fabb7SAndroid Build Coastguard Worker 	}
359*fd1fabb7SAndroid Build Coastguard Worker 
360*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
361*fd1fabb7SAndroid Build Coastguard Worker 
SetLength(uint64 length)362*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::SetLength (uint64 length)
363*fd1fabb7SAndroid Build Coastguard Worker 	{
364*fd1fabb7SAndroid Build Coastguard Worker 
365*fd1fabb7SAndroid Build Coastguard Worker 	Flush ();
366*fd1fabb7SAndroid Build Coastguard Worker 
367*fd1fabb7SAndroid Build Coastguard Worker 	if (Length () != length)
368*fd1fabb7SAndroid Build Coastguard Worker 		{
369*fd1fabb7SAndroid Build Coastguard Worker 
370*fd1fabb7SAndroid Build Coastguard Worker 		DoSetLength (length);
371*fd1fabb7SAndroid Build Coastguard Worker 
372*fd1fabb7SAndroid Build Coastguard Worker 		fLength = length;
373*fd1fabb7SAndroid Build Coastguard Worker 
374*fd1fabb7SAndroid Build Coastguard Worker 		}
375*fd1fabb7SAndroid Build Coastguard Worker 
376*fd1fabb7SAndroid Build Coastguard Worker 	}
377*fd1fabb7SAndroid Build Coastguard Worker 
378*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
379*fd1fabb7SAndroid Build Coastguard Worker 
Put(const void * data,uint32 count)380*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::Put (const void *data,
381*fd1fabb7SAndroid Build Coastguard Worker 					  uint32 count)
382*fd1fabb7SAndroid Build Coastguard Worker 	{
383*fd1fabb7SAndroid Build Coastguard Worker 
384*fd1fabb7SAndroid Build Coastguard Worker 	// See if we can replace or append to the existing buffer.
385*fd1fabb7SAndroid Build Coastguard Worker 
386*fd1fabb7SAndroid Build Coastguard Worker 	uint64 endPosition = fPosition + count;
387*fd1fabb7SAndroid Build Coastguard Worker 
388*fd1fabb7SAndroid Build Coastguard Worker 	if (fBufferDirty                &&
389*fd1fabb7SAndroid Build Coastguard Worker 		fPosition   >= fBufferStart &&
390*fd1fabb7SAndroid Build Coastguard Worker 		fPosition   <= fBufferEnd   &&
391*fd1fabb7SAndroid Build Coastguard Worker 		endPosition <= fBufferLimit)
392*fd1fabb7SAndroid Build Coastguard Worker 		{
393*fd1fabb7SAndroid Build Coastguard Worker 
394*fd1fabb7SAndroid Build Coastguard Worker 		DoCopyBytes (data,
395*fd1fabb7SAndroid Build Coastguard Worker 					 fBuffer + (uint32) (fPosition - fBufferStart),
396*fd1fabb7SAndroid Build Coastguard Worker 				     count);
397*fd1fabb7SAndroid Build Coastguard Worker 
398*fd1fabb7SAndroid Build Coastguard Worker 		if (fBufferEnd < endPosition)
399*fd1fabb7SAndroid Build Coastguard Worker 			fBufferEnd = endPosition;
400*fd1fabb7SAndroid Build Coastguard Worker 
401*fd1fabb7SAndroid Build Coastguard Worker 		}
402*fd1fabb7SAndroid Build Coastguard Worker 
403*fd1fabb7SAndroid Build Coastguard Worker 	// Else we need to write to the file.
404*fd1fabb7SAndroid Build Coastguard Worker 
405*fd1fabb7SAndroid Build Coastguard Worker 	else
406*fd1fabb7SAndroid Build Coastguard Worker 		{
407*fd1fabb7SAndroid Build Coastguard Worker 
408*fd1fabb7SAndroid Build Coastguard Worker 		// Write existing buffer.
409*fd1fabb7SAndroid Build Coastguard Worker 
410*fd1fabb7SAndroid Build Coastguard Worker 		Flush ();
411*fd1fabb7SAndroid Build Coastguard Worker 
412*fd1fabb7SAndroid Build Coastguard Worker 		// Write large blocks unbuffered.
413*fd1fabb7SAndroid Build Coastguard Worker 
414*fd1fabb7SAndroid Build Coastguard Worker 		if (count >= fBufferSize)
415*fd1fabb7SAndroid Build Coastguard Worker 			{
416*fd1fabb7SAndroid Build Coastguard Worker 
417*fd1fabb7SAndroid Build Coastguard Worker 			dng_abort_sniffer::SniffForAbort (fSniffer);
418*fd1fabb7SAndroid Build Coastguard Worker 
419*fd1fabb7SAndroid Build Coastguard Worker 			DoWrite (data, count, fPosition);
420*fd1fabb7SAndroid Build Coastguard Worker 
421*fd1fabb7SAndroid Build Coastguard Worker 			}
422*fd1fabb7SAndroid Build Coastguard Worker 
423*fd1fabb7SAndroid Build Coastguard Worker 		// Start a new buffer with small blocks.
424*fd1fabb7SAndroid Build Coastguard Worker 
425*fd1fabb7SAndroid Build Coastguard Worker 		else
426*fd1fabb7SAndroid Build Coastguard Worker 			{
427*fd1fabb7SAndroid Build Coastguard Worker 
428*fd1fabb7SAndroid Build Coastguard Worker 			fBufferDirty = true;
429*fd1fabb7SAndroid Build Coastguard Worker 
430*fd1fabb7SAndroid Build Coastguard Worker 			fBufferStart = fPosition;
431*fd1fabb7SAndroid Build Coastguard Worker 			fBufferEnd   = endPosition;
432*fd1fabb7SAndroid Build Coastguard Worker 			fBufferLimit = fBufferStart + fBufferSize;
433*fd1fabb7SAndroid Build Coastguard Worker 
434*fd1fabb7SAndroid Build Coastguard Worker 			DoCopyBytes (data,
435*fd1fabb7SAndroid Build Coastguard Worker 						 fBuffer,
436*fd1fabb7SAndroid Build Coastguard Worker 					     count);
437*fd1fabb7SAndroid Build Coastguard Worker 
438*fd1fabb7SAndroid Build Coastguard Worker 			}
439*fd1fabb7SAndroid Build Coastguard Worker 
440*fd1fabb7SAndroid Build Coastguard Worker 		}
441*fd1fabb7SAndroid Build Coastguard Worker 
442*fd1fabb7SAndroid Build Coastguard Worker 	fPosition = endPosition;
443*fd1fabb7SAndroid Build Coastguard Worker 
444*fd1fabb7SAndroid Build Coastguard Worker 	fLength = Max_uint64 (Length (), fPosition);
445*fd1fabb7SAndroid Build Coastguard Worker 
446*fd1fabb7SAndroid Build Coastguard Worker 	}
447*fd1fabb7SAndroid Build Coastguard Worker 
448*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
449*fd1fabb7SAndroid Build Coastguard Worker 
Get_uint16()450*fd1fabb7SAndroid Build Coastguard Worker uint16 dng_stream::Get_uint16 ()
451*fd1fabb7SAndroid Build Coastguard Worker 	{
452*fd1fabb7SAndroid Build Coastguard Worker 
453*fd1fabb7SAndroid Build Coastguard Worker 	uint16 x;
454*fd1fabb7SAndroid Build Coastguard Worker 
455*fd1fabb7SAndroid Build Coastguard Worker 	Get (&x, 2);
456*fd1fabb7SAndroid Build Coastguard Worker 
457*fd1fabb7SAndroid Build Coastguard Worker 	if (fSwapBytes)
458*fd1fabb7SAndroid Build Coastguard Worker 		{
459*fd1fabb7SAndroid Build Coastguard Worker 
460*fd1fabb7SAndroid Build Coastguard Worker 		x = SwapBytes16 (x);
461*fd1fabb7SAndroid Build Coastguard Worker 
462*fd1fabb7SAndroid Build Coastguard Worker 		}
463*fd1fabb7SAndroid Build Coastguard Worker 
464*fd1fabb7SAndroid Build Coastguard Worker 	return x;
465*fd1fabb7SAndroid Build Coastguard Worker 
466*fd1fabb7SAndroid Build Coastguard Worker 	}
467*fd1fabb7SAndroid Build Coastguard Worker 
468*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
469*fd1fabb7SAndroid Build Coastguard Worker 
Put_uint16(uint16 x)470*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::Put_uint16 (uint16 x)
471*fd1fabb7SAndroid Build Coastguard Worker 	{
472*fd1fabb7SAndroid Build Coastguard Worker 
473*fd1fabb7SAndroid Build Coastguard Worker 	if (fSwapBytes)
474*fd1fabb7SAndroid Build Coastguard Worker 		{
475*fd1fabb7SAndroid Build Coastguard Worker 
476*fd1fabb7SAndroid Build Coastguard Worker 		x = SwapBytes16 (x);
477*fd1fabb7SAndroid Build Coastguard Worker 
478*fd1fabb7SAndroid Build Coastguard Worker 		}
479*fd1fabb7SAndroid Build Coastguard Worker 
480*fd1fabb7SAndroid Build Coastguard Worker 	Put (&x, 2);
481*fd1fabb7SAndroid Build Coastguard Worker 
482*fd1fabb7SAndroid Build Coastguard Worker 	}
483*fd1fabb7SAndroid Build Coastguard Worker 
484*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
485*fd1fabb7SAndroid Build Coastguard Worker 
Get_uint32()486*fd1fabb7SAndroid Build Coastguard Worker uint32 dng_stream::Get_uint32 ()
487*fd1fabb7SAndroid Build Coastguard Worker 	{
488*fd1fabb7SAndroid Build Coastguard Worker 
489*fd1fabb7SAndroid Build Coastguard Worker 	uint32 x;
490*fd1fabb7SAndroid Build Coastguard Worker 
491*fd1fabb7SAndroid Build Coastguard Worker 	Get (&x, 4);
492*fd1fabb7SAndroid Build Coastguard Worker 
493*fd1fabb7SAndroid Build Coastguard Worker 	if (fSwapBytes)
494*fd1fabb7SAndroid Build Coastguard Worker 		{
495*fd1fabb7SAndroid Build Coastguard Worker 
496*fd1fabb7SAndroid Build Coastguard Worker 		x = SwapBytes32 (x);
497*fd1fabb7SAndroid Build Coastguard Worker 
498*fd1fabb7SAndroid Build Coastguard Worker 		}
499*fd1fabb7SAndroid Build Coastguard Worker 
500*fd1fabb7SAndroid Build Coastguard Worker 	return x;
501*fd1fabb7SAndroid Build Coastguard Worker 
502*fd1fabb7SAndroid Build Coastguard Worker 	}
503*fd1fabb7SAndroid Build Coastguard Worker 
504*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
505*fd1fabb7SAndroid Build Coastguard Worker 
Put_uint32(uint32 x)506*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::Put_uint32 (uint32 x)
507*fd1fabb7SAndroid Build Coastguard Worker 	{
508*fd1fabb7SAndroid Build Coastguard Worker 
509*fd1fabb7SAndroid Build Coastguard Worker 	if (fSwapBytes)
510*fd1fabb7SAndroid Build Coastguard Worker 		{
511*fd1fabb7SAndroid Build Coastguard Worker 
512*fd1fabb7SAndroid Build Coastguard Worker 		x = SwapBytes32 (x);
513*fd1fabb7SAndroid Build Coastguard Worker 
514*fd1fabb7SAndroid Build Coastguard Worker 		}
515*fd1fabb7SAndroid Build Coastguard Worker 
516*fd1fabb7SAndroid Build Coastguard Worker 	Put (&x, 4);
517*fd1fabb7SAndroid Build Coastguard Worker 
518*fd1fabb7SAndroid Build Coastguard Worker 	}
519*fd1fabb7SAndroid Build Coastguard Worker 
520*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
521*fd1fabb7SAndroid Build Coastguard Worker 
Get_uint64()522*fd1fabb7SAndroid Build Coastguard Worker uint64 dng_stream::Get_uint64 ()
523*fd1fabb7SAndroid Build Coastguard Worker 	{
524*fd1fabb7SAndroid Build Coastguard Worker 
525*fd1fabb7SAndroid Build Coastguard Worker 	if (fSwapBytes)
526*fd1fabb7SAndroid Build Coastguard Worker 		{
527*fd1fabb7SAndroid Build Coastguard Worker 
528*fd1fabb7SAndroid Build Coastguard Worker 		union
529*fd1fabb7SAndroid Build Coastguard Worker 			{
530*fd1fabb7SAndroid Build Coastguard Worker 			uint32 u32 [2];
531*fd1fabb7SAndroid Build Coastguard Worker 			uint64 u64;
532*fd1fabb7SAndroid Build Coastguard Worker 			} u;
533*fd1fabb7SAndroid Build Coastguard Worker 
534*fd1fabb7SAndroid Build Coastguard Worker 		u.u32 [1] = Get_uint32 ();
535*fd1fabb7SAndroid Build Coastguard Worker 		u.u32 [0] = Get_uint32 ();
536*fd1fabb7SAndroid Build Coastguard Worker 
537*fd1fabb7SAndroid Build Coastguard Worker 		return u.u64;
538*fd1fabb7SAndroid Build Coastguard Worker 
539*fd1fabb7SAndroid Build Coastguard Worker 		}
540*fd1fabb7SAndroid Build Coastguard Worker 
541*fd1fabb7SAndroid Build Coastguard Worker 	uint64 x;
542*fd1fabb7SAndroid Build Coastguard Worker 
543*fd1fabb7SAndroid Build Coastguard Worker 	Get (&x, 8);
544*fd1fabb7SAndroid Build Coastguard Worker 
545*fd1fabb7SAndroid Build Coastguard Worker 	return x;
546*fd1fabb7SAndroid Build Coastguard Worker 
547*fd1fabb7SAndroid Build Coastguard Worker 	}
548*fd1fabb7SAndroid Build Coastguard Worker 
549*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
550*fd1fabb7SAndroid Build Coastguard Worker 
Put_uint64(uint64 x)551*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::Put_uint64 (uint64 x)
552*fd1fabb7SAndroid Build Coastguard Worker 	{
553*fd1fabb7SAndroid Build Coastguard Worker 
554*fd1fabb7SAndroid Build Coastguard Worker 	if (fSwapBytes)
555*fd1fabb7SAndroid Build Coastguard Worker 		{
556*fd1fabb7SAndroid Build Coastguard Worker 
557*fd1fabb7SAndroid Build Coastguard Worker 		union
558*fd1fabb7SAndroid Build Coastguard Worker 			{
559*fd1fabb7SAndroid Build Coastguard Worker 			uint32 u32 [2];
560*fd1fabb7SAndroid Build Coastguard Worker 			uint64 u64;
561*fd1fabb7SAndroid Build Coastguard Worker 			} u;
562*fd1fabb7SAndroid Build Coastguard Worker 
563*fd1fabb7SAndroid Build Coastguard Worker 		u.u64 = x;
564*fd1fabb7SAndroid Build Coastguard Worker 
565*fd1fabb7SAndroid Build Coastguard Worker 		Put_uint32 (u.u32 [1]);
566*fd1fabb7SAndroid Build Coastguard Worker 		Put_uint32 (u.u32 [0]);
567*fd1fabb7SAndroid Build Coastguard Worker 
568*fd1fabb7SAndroid Build Coastguard Worker 		}
569*fd1fabb7SAndroid Build Coastguard Worker 
570*fd1fabb7SAndroid Build Coastguard Worker 	else
571*fd1fabb7SAndroid Build Coastguard Worker 		{
572*fd1fabb7SAndroid Build Coastguard Worker 
573*fd1fabb7SAndroid Build Coastguard Worker 		Put (&x, 8);
574*fd1fabb7SAndroid Build Coastguard Worker 
575*fd1fabb7SAndroid Build Coastguard Worker 		}
576*fd1fabb7SAndroid Build Coastguard Worker 
577*fd1fabb7SAndroid Build Coastguard Worker 	}
578*fd1fabb7SAndroid Build Coastguard Worker 
579*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
580*fd1fabb7SAndroid Build Coastguard Worker 
Get_real32()581*fd1fabb7SAndroid Build Coastguard Worker real32 dng_stream::Get_real32 ()
582*fd1fabb7SAndroid Build Coastguard Worker 	{
583*fd1fabb7SAndroid Build Coastguard Worker 
584*fd1fabb7SAndroid Build Coastguard Worker 	union
585*fd1fabb7SAndroid Build Coastguard Worker 		{
586*fd1fabb7SAndroid Build Coastguard Worker 		uint32 i;
587*fd1fabb7SAndroid Build Coastguard Worker 		real32 r;
588*fd1fabb7SAndroid Build Coastguard Worker 		} u;
589*fd1fabb7SAndroid Build Coastguard Worker 
590*fd1fabb7SAndroid Build Coastguard Worker 	u.i = Get_uint32 ();
591*fd1fabb7SAndroid Build Coastguard Worker 
592*fd1fabb7SAndroid Build Coastguard Worker 	return u.r;
593*fd1fabb7SAndroid Build Coastguard Worker 
594*fd1fabb7SAndroid Build Coastguard Worker 	}
595*fd1fabb7SAndroid Build Coastguard Worker 
596*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
597*fd1fabb7SAndroid Build Coastguard Worker 
Put_real32(real32 x)598*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::Put_real32 (real32 x)
599*fd1fabb7SAndroid Build Coastguard Worker 	{
600*fd1fabb7SAndroid Build Coastguard Worker 
601*fd1fabb7SAndroid Build Coastguard Worker 	if (fSwapBytes)
602*fd1fabb7SAndroid Build Coastguard Worker 		{
603*fd1fabb7SAndroid Build Coastguard Worker 
604*fd1fabb7SAndroid Build Coastguard Worker 		union
605*fd1fabb7SAndroid Build Coastguard Worker 			{
606*fd1fabb7SAndroid Build Coastguard Worker 			uint32 i;
607*fd1fabb7SAndroid Build Coastguard Worker 			real32 r;
608*fd1fabb7SAndroid Build Coastguard Worker 			} u;
609*fd1fabb7SAndroid Build Coastguard Worker 
610*fd1fabb7SAndroid Build Coastguard Worker 		u.r = x;
611*fd1fabb7SAndroid Build Coastguard Worker 
612*fd1fabb7SAndroid Build Coastguard Worker 		Put_uint32 (u.i);
613*fd1fabb7SAndroid Build Coastguard Worker 
614*fd1fabb7SAndroid Build Coastguard Worker 		}
615*fd1fabb7SAndroid Build Coastguard Worker 
616*fd1fabb7SAndroid Build Coastguard Worker 	else
617*fd1fabb7SAndroid Build Coastguard Worker 		{
618*fd1fabb7SAndroid Build Coastguard Worker 
619*fd1fabb7SAndroid Build Coastguard Worker 		Put (&x, 4);
620*fd1fabb7SAndroid Build Coastguard Worker 
621*fd1fabb7SAndroid Build Coastguard Worker 		}
622*fd1fabb7SAndroid Build Coastguard Worker 
623*fd1fabb7SAndroid Build Coastguard Worker 	}
624*fd1fabb7SAndroid Build Coastguard Worker 
625*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
626*fd1fabb7SAndroid Build Coastguard Worker 
Get_real64()627*fd1fabb7SAndroid Build Coastguard Worker real64 dng_stream::Get_real64 ()
628*fd1fabb7SAndroid Build Coastguard Worker 	{
629*fd1fabb7SAndroid Build Coastguard Worker 
630*fd1fabb7SAndroid Build Coastguard Worker 	if (fSwapBytes)
631*fd1fabb7SAndroid Build Coastguard Worker 		{
632*fd1fabb7SAndroid Build Coastguard Worker 
633*fd1fabb7SAndroid Build Coastguard Worker 		union
634*fd1fabb7SAndroid Build Coastguard Worker 			{
635*fd1fabb7SAndroid Build Coastguard Worker 			uint32 i [2];
636*fd1fabb7SAndroid Build Coastguard Worker 			real64 r;
637*fd1fabb7SAndroid Build Coastguard Worker 			} u;
638*fd1fabb7SAndroid Build Coastguard Worker 
639*fd1fabb7SAndroid Build Coastguard Worker 		u.i [1] = Get_uint32 ();
640*fd1fabb7SAndroid Build Coastguard Worker 		u.i [0] = Get_uint32 ();
641*fd1fabb7SAndroid Build Coastguard Worker 
642*fd1fabb7SAndroid Build Coastguard Worker 		return u.r;
643*fd1fabb7SAndroid Build Coastguard Worker 
644*fd1fabb7SAndroid Build Coastguard Worker 		}
645*fd1fabb7SAndroid Build Coastguard Worker 
646*fd1fabb7SAndroid Build Coastguard Worker 	real64 x;
647*fd1fabb7SAndroid Build Coastguard Worker 
648*fd1fabb7SAndroid Build Coastguard Worker 	Get (&x, 8);
649*fd1fabb7SAndroid Build Coastguard Worker 
650*fd1fabb7SAndroid Build Coastguard Worker 	return x;
651*fd1fabb7SAndroid Build Coastguard Worker 
652*fd1fabb7SAndroid Build Coastguard Worker 	}
653*fd1fabb7SAndroid Build Coastguard Worker 
654*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
655*fd1fabb7SAndroid Build Coastguard Worker 
Put_real64(real64 x)656*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::Put_real64 (real64 x)
657*fd1fabb7SAndroid Build Coastguard Worker 	{
658*fd1fabb7SAndroid Build Coastguard Worker 
659*fd1fabb7SAndroid Build Coastguard Worker 	if (fSwapBytes)
660*fd1fabb7SAndroid Build Coastguard Worker 		{
661*fd1fabb7SAndroid Build Coastguard Worker 
662*fd1fabb7SAndroid Build Coastguard Worker 		union
663*fd1fabb7SAndroid Build Coastguard Worker 			{
664*fd1fabb7SAndroid Build Coastguard Worker 			uint32 i [2];
665*fd1fabb7SAndroid Build Coastguard Worker 			real64 r;
666*fd1fabb7SAndroid Build Coastguard Worker 			} u;
667*fd1fabb7SAndroid Build Coastguard Worker 
668*fd1fabb7SAndroid Build Coastguard Worker 		u.r = x;
669*fd1fabb7SAndroid Build Coastguard Worker 
670*fd1fabb7SAndroid Build Coastguard Worker 		Put_uint32 (u.i [1]);
671*fd1fabb7SAndroid Build Coastguard Worker 		Put_uint32 (u.i [0]);
672*fd1fabb7SAndroid Build Coastguard Worker 
673*fd1fabb7SAndroid Build Coastguard Worker 		}
674*fd1fabb7SAndroid Build Coastguard Worker 
675*fd1fabb7SAndroid Build Coastguard Worker 	else
676*fd1fabb7SAndroid Build Coastguard Worker 		{
677*fd1fabb7SAndroid Build Coastguard Worker 
678*fd1fabb7SAndroid Build Coastguard Worker 		Put (&x, 8);
679*fd1fabb7SAndroid Build Coastguard Worker 
680*fd1fabb7SAndroid Build Coastguard Worker 		}
681*fd1fabb7SAndroid Build Coastguard Worker 
682*fd1fabb7SAndroid Build Coastguard Worker 	}
683*fd1fabb7SAndroid Build Coastguard Worker 
684*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
685*fd1fabb7SAndroid Build Coastguard Worker 
Get_CString(char * data,uint32 maxLength)686*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::Get_CString (char *data, uint32 maxLength)
687*fd1fabb7SAndroid Build Coastguard Worker 	{
688*fd1fabb7SAndroid Build Coastguard Worker 
689*fd1fabb7SAndroid Build Coastguard Worker 	memset (data, 0, maxLength);
690*fd1fabb7SAndroid Build Coastguard Worker 
691*fd1fabb7SAndroid Build Coastguard Worker 	uint32 index = 0;
692*fd1fabb7SAndroid Build Coastguard Worker 
693*fd1fabb7SAndroid Build Coastguard Worker 	while (true)
694*fd1fabb7SAndroid Build Coastguard Worker 		{
695*fd1fabb7SAndroid Build Coastguard Worker 
696*fd1fabb7SAndroid Build Coastguard Worker 		char c = (char) Get_uint8 ();
697*fd1fabb7SAndroid Build Coastguard Worker 
698*fd1fabb7SAndroid Build Coastguard Worker 		if (index + 1 < maxLength)
699*fd1fabb7SAndroid Build Coastguard Worker 			data [index++] = c;
700*fd1fabb7SAndroid Build Coastguard Worker 
701*fd1fabb7SAndroid Build Coastguard Worker 		if (c == 0)
702*fd1fabb7SAndroid Build Coastguard Worker 			break;
703*fd1fabb7SAndroid Build Coastguard Worker 
704*fd1fabb7SAndroid Build Coastguard Worker 		}
705*fd1fabb7SAndroid Build Coastguard Worker 
706*fd1fabb7SAndroid Build Coastguard Worker 	}
707*fd1fabb7SAndroid Build Coastguard Worker 
708*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
709*fd1fabb7SAndroid Build Coastguard Worker 
Get_UString(char * data,uint32 maxLength)710*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::Get_UString (char *data, uint32 maxLength)
711*fd1fabb7SAndroid Build Coastguard Worker 	{
712*fd1fabb7SAndroid Build Coastguard Worker 
713*fd1fabb7SAndroid Build Coastguard Worker 	memset (data, 0, maxLength);
714*fd1fabb7SAndroid Build Coastguard Worker 
715*fd1fabb7SAndroid Build Coastguard Worker 	uint32 index = 0;
716*fd1fabb7SAndroid Build Coastguard Worker 
717*fd1fabb7SAndroid Build Coastguard Worker 	while (true)
718*fd1fabb7SAndroid Build Coastguard Worker 		{
719*fd1fabb7SAndroid Build Coastguard Worker 
720*fd1fabb7SAndroid Build Coastguard Worker 		char c = (char) Get_uint16 ();
721*fd1fabb7SAndroid Build Coastguard Worker 
722*fd1fabb7SAndroid Build Coastguard Worker 		if (index + 1 < maxLength)
723*fd1fabb7SAndroid Build Coastguard Worker 			data [index++] = (char) c;
724*fd1fabb7SAndroid Build Coastguard Worker 
725*fd1fabb7SAndroid Build Coastguard Worker 		if (c == 0)
726*fd1fabb7SAndroid Build Coastguard Worker 			break;
727*fd1fabb7SAndroid Build Coastguard Worker 
728*fd1fabb7SAndroid Build Coastguard Worker 		}
729*fd1fabb7SAndroid Build Coastguard Worker 
730*fd1fabb7SAndroid Build Coastguard Worker 	}
731*fd1fabb7SAndroid Build Coastguard Worker 
732*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
733*fd1fabb7SAndroid Build Coastguard Worker 
PutZeros(uint64 count)734*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::PutZeros (uint64 count)
735*fd1fabb7SAndroid Build Coastguard Worker 	{
736*fd1fabb7SAndroid Build Coastguard Worker 
737*fd1fabb7SAndroid Build Coastguard Worker 	const uint32 kZeroBufferSize = 4096;
738*fd1fabb7SAndroid Build Coastguard Worker 
739*fd1fabb7SAndroid Build Coastguard Worker 	if (count >= kZeroBufferSize)
740*fd1fabb7SAndroid Build Coastguard Worker 		{
741*fd1fabb7SAndroid Build Coastguard Worker 
742*fd1fabb7SAndroid Build Coastguard Worker 		dng_memory_data zeroBuffer (kZeroBufferSize);
743*fd1fabb7SAndroid Build Coastguard Worker 
744*fd1fabb7SAndroid Build Coastguard Worker 		DoZeroBytes (zeroBuffer.Buffer (),
745*fd1fabb7SAndroid Build Coastguard Worker 					 kZeroBufferSize);
746*fd1fabb7SAndroid Build Coastguard Worker 
747*fd1fabb7SAndroid Build Coastguard Worker 		while (count)
748*fd1fabb7SAndroid Build Coastguard Worker 			{
749*fd1fabb7SAndroid Build Coastguard Worker 
750*fd1fabb7SAndroid Build Coastguard Worker 			uint64 blockSize = Min_uint64 (count, kZeroBufferSize);
751*fd1fabb7SAndroid Build Coastguard Worker 
752*fd1fabb7SAndroid Build Coastguard Worker 			Put (zeroBuffer.Buffer (), (uint32) blockSize);
753*fd1fabb7SAndroid Build Coastguard Worker 
754*fd1fabb7SAndroid Build Coastguard Worker 			count -= blockSize;
755*fd1fabb7SAndroid Build Coastguard Worker 
756*fd1fabb7SAndroid Build Coastguard Worker 			}
757*fd1fabb7SAndroid Build Coastguard Worker 
758*fd1fabb7SAndroid Build Coastguard Worker 		}
759*fd1fabb7SAndroid Build Coastguard Worker 
760*fd1fabb7SAndroid Build Coastguard Worker 	else
761*fd1fabb7SAndroid Build Coastguard Worker 		{
762*fd1fabb7SAndroid Build Coastguard Worker 
763*fd1fabb7SAndroid Build Coastguard Worker 		uint32 count32 = (uint32) count;
764*fd1fabb7SAndroid Build Coastguard Worker 
765*fd1fabb7SAndroid Build Coastguard Worker 		for (uint32 j = 0; j < count32; j++)
766*fd1fabb7SAndroid Build Coastguard Worker 			{
767*fd1fabb7SAndroid Build Coastguard Worker 
768*fd1fabb7SAndroid Build Coastguard Worker 			Put_uint8 (0);
769*fd1fabb7SAndroid Build Coastguard Worker 
770*fd1fabb7SAndroid Build Coastguard Worker 			}
771*fd1fabb7SAndroid Build Coastguard Worker 
772*fd1fabb7SAndroid Build Coastguard Worker 		}
773*fd1fabb7SAndroid Build Coastguard Worker 
774*fd1fabb7SAndroid Build Coastguard Worker 	}
775*fd1fabb7SAndroid Build Coastguard Worker 
776*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
777*fd1fabb7SAndroid Build Coastguard Worker 
PadAlign2()778*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::PadAlign2 ()
779*fd1fabb7SAndroid Build Coastguard Worker 	{
780*fd1fabb7SAndroid Build Coastguard Worker 
781*fd1fabb7SAndroid Build Coastguard Worker 	PutZeros (Position () & 1);
782*fd1fabb7SAndroid Build Coastguard Worker 
783*fd1fabb7SAndroid Build Coastguard Worker 	}
784*fd1fabb7SAndroid Build Coastguard Worker 
785*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
786*fd1fabb7SAndroid Build Coastguard Worker 
PadAlign4()787*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::PadAlign4 ()
788*fd1fabb7SAndroid Build Coastguard Worker 	{
789*fd1fabb7SAndroid Build Coastguard Worker 
790*fd1fabb7SAndroid Build Coastguard Worker 	PutZeros ((4 - (Position () & 3)) & 3);
791*fd1fabb7SAndroid Build Coastguard Worker 
792*fd1fabb7SAndroid Build Coastguard Worker 	}
793*fd1fabb7SAndroid Build Coastguard Worker 
794*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
795*fd1fabb7SAndroid Build Coastguard Worker 
TagValue_uint32(uint32 tagType)796*fd1fabb7SAndroid Build Coastguard Worker uint32 dng_stream::TagValue_uint32 (uint32 tagType)
797*fd1fabb7SAndroid Build Coastguard Worker 	{
798*fd1fabb7SAndroid Build Coastguard Worker 
799*fd1fabb7SAndroid Build Coastguard Worker 	switch (tagType)
800*fd1fabb7SAndroid Build Coastguard Worker 		{
801*fd1fabb7SAndroid Build Coastguard Worker 
802*fd1fabb7SAndroid Build Coastguard Worker 		case ttByte:
803*fd1fabb7SAndroid Build Coastguard Worker 			return (uint32) Get_uint8 ();
804*fd1fabb7SAndroid Build Coastguard Worker 
805*fd1fabb7SAndroid Build Coastguard Worker 		case ttShort:
806*fd1fabb7SAndroid Build Coastguard Worker 			return (uint32) Get_uint16 ();
807*fd1fabb7SAndroid Build Coastguard Worker 
808*fd1fabb7SAndroid Build Coastguard Worker 		case ttLong:
809*fd1fabb7SAndroid Build Coastguard Worker 		case ttIFD:
810*fd1fabb7SAndroid Build Coastguard Worker 			return Get_uint32 ();
811*fd1fabb7SAndroid Build Coastguard Worker 
812*fd1fabb7SAndroid Build Coastguard Worker 		}
813*fd1fabb7SAndroid Build Coastguard Worker 
814*fd1fabb7SAndroid Build Coastguard Worker 	real64 x = TagValue_real64 (tagType);
815*fd1fabb7SAndroid Build Coastguard Worker 
816*fd1fabb7SAndroid Build Coastguard Worker 	if (x < 0.0)
817*fd1fabb7SAndroid Build Coastguard Worker 		x = 0.0;
818*fd1fabb7SAndroid Build Coastguard Worker 
819*fd1fabb7SAndroid Build Coastguard Worker 	if (x > (real64) 0xFFFFFFFF)
820*fd1fabb7SAndroid Build Coastguard Worker 		x = (real64) 0xFFFFFFFF;
821*fd1fabb7SAndroid Build Coastguard Worker 
822*fd1fabb7SAndroid Build Coastguard Worker 	return ConvertDoubleToUint32(x + 0.5);
823*fd1fabb7SAndroid Build Coastguard Worker 
824*fd1fabb7SAndroid Build Coastguard Worker 	}
825*fd1fabb7SAndroid Build Coastguard Worker 
826*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
827*fd1fabb7SAndroid Build Coastguard Worker 
TagValue_int32(uint32 tagType)828*fd1fabb7SAndroid Build Coastguard Worker int32 dng_stream::TagValue_int32 (uint32 tagType)
829*fd1fabb7SAndroid Build Coastguard Worker 	{
830*fd1fabb7SAndroid Build Coastguard Worker 
831*fd1fabb7SAndroid Build Coastguard Worker 	switch (tagType)
832*fd1fabb7SAndroid Build Coastguard Worker 		{
833*fd1fabb7SAndroid Build Coastguard Worker 
834*fd1fabb7SAndroid Build Coastguard Worker 		case ttSByte:
835*fd1fabb7SAndroid Build Coastguard Worker 			return (int32) Get_int8 ();
836*fd1fabb7SAndroid Build Coastguard Worker 
837*fd1fabb7SAndroid Build Coastguard Worker 		case ttSShort:
838*fd1fabb7SAndroid Build Coastguard Worker 			return (int32) Get_int16 ();
839*fd1fabb7SAndroid Build Coastguard Worker 
840*fd1fabb7SAndroid Build Coastguard Worker 		case ttSLong:
841*fd1fabb7SAndroid Build Coastguard Worker 			return Get_int32 ();
842*fd1fabb7SAndroid Build Coastguard Worker 
843*fd1fabb7SAndroid Build Coastguard Worker 		}
844*fd1fabb7SAndroid Build Coastguard Worker 
845*fd1fabb7SAndroid Build Coastguard Worker 	real64 x = TagValue_real64 (tagType);
846*fd1fabb7SAndroid Build Coastguard Worker 
847*fd1fabb7SAndroid Build Coastguard Worker 	if (x < 0.0)
848*fd1fabb7SAndroid Build Coastguard Worker 		{
849*fd1fabb7SAndroid Build Coastguard Worker 
850*fd1fabb7SAndroid Build Coastguard Worker 		if (x < -2147483648.0)
851*fd1fabb7SAndroid Build Coastguard Worker 			x = -2147483648.0;
852*fd1fabb7SAndroid Build Coastguard Worker 
853*fd1fabb7SAndroid Build Coastguard Worker 		return ConvertDoubleToInt32(x - 0.5);
854*fd1fabb7SAndroid Build Coastguard Worker 
855*fd1fabb7SAndroid Build Coastguard Worker 		}
856*fd1fabb7SAndroid Build Coastguard Worker 
857*fd1fabb7SAndroid Build Coastguard Worker 	else
858*fd1fabb7SAndroid Build Coastguard Worker 		{
859*fd1fabb7SAndroid Build Coastguard Worker 
860*fd1fabb7SAndroid Build Coastguard Worker 		if (x > 2147483647.0)
861*fd1fabb7SAndroid Build Coastguard Worker 			x = 2147483647.0;
862*fd1fabb7SAndroid Build Coastguard Worker 
863*fd1fabb7SAndroid Build Coastguard Worker 		return ConvertDoubleToInt32(x + 0.5);
864*fd1fabb7SAndroid Build Coastguard Worker 
865*fd1fabb7SAndroid Build Coastguard Worker 		}
866*fd1fabb7SAndroid Build Coastguard Worker 
867*fd1fabb7SAndroid Build Coastguard Worker 	}
868*fd1fabb7SAndroid Build Coastguard Worker 
869*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
870*fd1fabb7SAndroid Build Coastguard Worker 
TagValue_urational(uint32 tagType)871*fd1fabb7SAndroid Build Coastguard Worker dng_urational dng_stream::TagValue_urational (uint32 tagType)
872*fd1fabb7SAndroid Build Coastguard Worker 	{
873*fd1fabb7SAndroid Build Coastguard Worker 
874*fd1fabb7SAndroid Build Coastguard Worker 	dng_urational result;
875*fd1fabb7SAndroid Build Coastguard Worker 
876*fd1fabb7SAndroid Build Coastguard Worker 	result.n = 0;
877*fd1fabb7SAndroid Build Coastguard Worker 	result.d = 1;
878*fd1fabb7SAndroid Build Coastguard Worker 
879*fd1fabb7SAndroid Build Coastguard Worker 	switch (tagType)
880*fd1fabb7SAndroid Build Coastguard Worker 		{
881*fd1fabb7SAndroid Build Coastguard Worker 
882*fd1fabb7SAndroid Build Coastguard Worker 		case ttRational:
883*fd1fabb7SAndroid Build Coastguard Worker 			{
884*fd1fabb7SAndroid Build Coastguard Worker 
885*fd1fabb7SAndroid Build Coastguard Worker 			result.n = Get_uint32 ();
886*fd1fabb7SAndroid Build Coastguard Worker 			result.d = Get_uint32 ();
887*fd1fabb7SAndroid Build Coastguard Worker 
888*fd1fabb7SAndroid Build Coastguard Worker 			break;
889*fd1fabb7SAndroid Build Coastguard Worker 
890*fd1fabb7SAndroid Build Coastguard Worker 			}
891*fd1fabb7SAndroid Build Coastguard Worker 
892*fd1fabb7SAndroid Build Coastguard Worker 		case ttSRational:
893*fd1fabb7SAndroid Build Coastguard Worker 			{
894*fd1fabb7SAndroid Build Coastguard Worker 
895*fd1fabb7SAndroid Build Coastguard Worker 			int32 n = Get_int32 ();
896*fd1fabb7SAndroid Build Coastguard Worker 			int32 d = Get_int32 ();
897*fd1fabb7SAndroid Build Coastguard Worker 
898*fd1fabb7SAndroid Build Coastguard Worker 			if ((n < 0) == (d < 0))
899*fd1fabb7SAndroid Build Coastguard Worker 				{
900*fd1fabb7SAndroid Build Coastguard Worker 
901*fd1fabb7SAndroid Build Coastguard Worker 				if (d < 0)
902*fd1fabb7SAndroid Build Coastguard Worker 					{
903*fd1fabb7SAndroid Build Coastguard Worker 					result.n = (uint32) ((int64) n * -1);
904*fd1fabb7SAndroid Build Coastguard Worker 					result.d = (uint32) ((int64) d * -1);
905*fd1fabb7SAndroid Build Coastguard Worker 					}
906*fd1fabb7SAndroid Build Coastguard Worker 				else
907*fd1fabb7SAndroid Build Coastguard Worker 					{
908*fd1fabb7SAndroid Build Coastguard Worker 					result.n = (uint32) n;
909*fd1fabb7SAndroid Build Coastguard Worker 					result.d = (uint32) d;
910*fd1fabb7SAndroid Build Coastguard Worker 					}
911*fd1fabb7SAndroid Build Coastguard Worker 
912*fd1fabb7SAndroid Build Coastguard Worker 				}
913*fd1fabb7SAndroid Build Coastguard Worker 
914*fd1fabb7SAndroid Build Coastguard Worker 			break;
915*fd1fabb7SAndroid Build Coastguard Worker 
916*fd1fabb7SAndroid Build Coastguard Worker 			}
917*fd1fabb7SAndroid Build Coastguard Worker 
918*fd1fabb7SAndroid Build Coastguard Worker 		case ttByte:
919*fd1fabb7SAndroid Build Coastguard Worker 		case ttShort:
920*fd1fabb7SAndroid Build Coastguard Worker 		case ttLong:
921*fd1fabb7SAndroid Build Coastguard Worker 		case ttIFD:
922*fd1fabb7SAndroid Build Coastguard Worker 			{
923*fd1fabb7SAndroid Build Coastguard Worker 
924*fd1fabb7SAndroid Build Coastguard Worker 			result.n = TagValue_uint32 (tagType);
925*fd1fabb7SAndroid Build Coastguard Worker 
926*fd1fabb7SAndroid Build Coastguard Worker 			break;
927*fd1fabb7SAndroid Build Coastguard Worker 
928*fd1fabb7SAndroid Build Coastguard Worker 			}
929*fd1fabb7SAndroid Build Coastguard Worker 
930*fd1fabb7SAndroid Build Coastguard Worker 		case ttSByte:
931*fd1fabb7SAndroid Build Coastguard Worker 		case ttSShort:
932*fd1fabb7SAndroid Build Coastguard Worker 		case ttSLong:
933*fd1fabb7SAndroid Build Coastguard Worker 			{
934*fd1fabb7SAndroid Build Coastguard Worker 
935*fd1fabb7SAndroid Build Coastguard Worker 			int32 n = TagValue_int32 (tagType);
936*fd1fabb7SAndroid Build Coastguard Worker 
937*fd1fabb7SAndroid Build Coastguard Worker 			if (n > 0)
938*fd1fabb7SAndroid Build Coastguard Worker 				{
939*fd1fabb7SAndroid Build Coastguard Worker 				result.n = (uint32) n;
940*fd1fabb7SAndroid Build Coastguard Worker 				}
941*fd1fabb7SAndroid Build Coastguard Worker 
942*fd1fabb7SAndroid Build Coastguard Worker 			break;
943*fd1fabb7SAndroid Build Coastguard Worker 
944*fd1fabb7SAndroid Build Coastguard Worker 			}
945*fd1fabb7SAndroid Build Coastguard Worker 
946*fd1fabb7SAndroid Build Coastguard Worker 		default:
947*fd1fabb7SAndroid Build Coastguard Worker 			{
948*fd1fabb7SAndroid Build Coastguard Worker 
949*fd1fabb7SAndroid Build Coastguard Worker 			real64 x = TagValue_real64 (tagType);
950*fd1fabb7SAndroid Build Coastguard Worker 
951*fd1fabb7SAndroid Build Coastguard Worker 			if (x > 0.0)
952*fd1fabb7SAndroid Build Coastguard Worker 				{
953*fd1fabb7SAndroid Build Coastguard Worker 
954*fd1fabb7SAndroid Build Coastguard Worker 				while (result.d < 10000 && x < 1000000)
955*fd1fabb7SAndroid Build Coastguard Worker 					{
956*fd1fabb7SAndroid Build Coastguard Worker 
957*fd1fabb7SAndroid Build Coastguard Worker 					result.d *= 10;
958*fd1fabb7SAndroid Build Coastguard Worker 
959*fd1fabb7SAndroid Build Coastguard Worker 					x *= 10.0;
960*fd1fabb7SAndroid Build Coastguard Worker 
961*fd1fabb7SAndroid Build Coastguard Worker 					}
962*fd1fabb7SAndroid Build Coastguard Worker 
963*fd1fabb7SAndroid Build Coastguard Worker 				result.n = ConvertDoubleToUint32(x + 0.5);
964*fd1fabb7SAndroid Build Coastguard Worker 
965*fd1fabb7SAndroid Build Coastguard Worker 				}
966*fd1fabb7SAndroid Build Coastguard Worker 
967*fd1fabb7SAndroid Build Coastguard Worker 			}
968*fd1fabb7SAndroid Build Coastguard Worker 
969*fd1fabb7SAndroid Build Coastguard Worker 		}
970*fd1fabb7SAndroid Build Coastguard Worker 
971*fd1fabb7SAndroid Build Coastguard Worker 	return result;
972*fd1fabb7SAndroid Build Coastguard Worker 
973*fd1fabb7SAndroid Build Coastguard Worker 	}
974*fd1fabb7SAndroid Build Coastguard Worker 
975*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
976*fd1fabb7SAndroid Build Coastguard Worker 
TagValue_srational(uint32 tagType)977*fd1fabb7SAndroid Build Coastguard Worker dng_srational dng_stream::TagValue_srational (uint32 tagType)
978*fd1fabb7SAndroid Build Coastguard Worker 	{
979*fd1fabb7SAndroid Build Coastguard Worker 
980*fd1fabb7SAndroid Build Coastguard Worker 	dng_srational result;
981*fd1fabb7SAndroid Build Coastguard Worker 
982*fd1fabb7SAndroid Build Coastguard Worker 	result.n = 0;
983*fd1fabb7SAndroid Build Coastguard Worker 	result.d = 1;
984*fd1fabb7SAndroid Build Coastguard Worker 
985*fd1fabb7SAndroid Build Coastguard Worker 	switch (tagType)
986*fd1fabb7SAndroid Build Coastguard Worker 		{
987*fd1fabb7SAndroid Build Coastguard Worker 
988*fd1fabb7SAndroid Build Coastguard Worker 		case ttSRational:
989*fd1fabb7SAndroid Build Coastguard Worker 			{
990*fd1fabb7SAndroid Build Coastguard Worker 
991*fd1fabb7SAndroid Build Coastguard Worker 			result.n = Get_int32 ();
992*fd1fabb7SAndroid Build Coastguard Worker 			result.d = Get_int32 ();
993*fd1fabb7SAndroid Build Coastguard Worker 
994*fd1fabb7SAndroid Build Coastguard Worker 			break;
995*fd1fabb7SAndroid Build Coastguard Worker 
996*fd1fabb7SAndroid Build Coastguard Worker 			}
997*fd1fabb7SAndroid Build Coastguard Worker 
998*fd1fabb7SAndroid Build Coastguard Worker 		default:
999*fd1fabb7SAndroid Build Coastguard Worker 			{
1000*fd1fabb7SAndroid Build Coastguard Worker 
1001*fd1fabb7SAndroid Build Coastguard Worker 			real64 x = TagValue_real64 (tagType);
1002*fd1fabb7SAndroid Build Coastguard Worker 
1003*fd1fabb7SAndroid Build Coastguard Worker 			if (x > 0.0)
1004*fd1fabb7SAndroid Build Coastguard Worker 				{
1005*fd1fabb7SAndroid Build Coastguard Worker 
1006*fd1fabb7SAndroid Build Coastguard Worker 				while (result.d < 10000 && x < 1000000.0)
1007*fd1fabb7SAndroid Build Coastguard Worker 					{
1008*fd1fabb7SAndroid Build Coastguard Worker 
1009*fd1fabb7SAndroid Build Coastguard Worker 					result.d *= 10;
1010*fd1fabb7SAndroid Build Coastguard Worker 
1011*fd1fabb7SAndroid Build Coastguard Worker 					x *= 10.0;
1012*fd1fabb7SAndroid Build Coastguard Worker 
1013*fd1fabb7SAndroid Build Coastguard Worker 					}
1014*fd1fabb7SAndroid Build Coastguard Worker 
1015*fd1fabb7SAndroid Build Coastguard Worker 				result.n = ConvertDoubleToInt32(x + 0.5);
1016*fd1fabb7SAndroid Build Coastguard Worker 
1017*fd1fabb7SAndroid Build Coastguard Worker 				}
1018*fd1fabb7SAndroid Build Coastguard Worker 
1019*fd1fabb7SAndroid Build Coastguard Worker 			else
1020*fd1fabb7SAndroid Build Coastguard Worker 				{
1021*fd1fabb7SAndroid Build Coastguard Worker 
1022*fd1fabb7SAndroid Build Coastguard Worker 				while (result.d < 10000 && x > -1000000.0)
1023*fd1fabb7SAndroid Build Coastguard Worker 					{
1024*fd1fabb7SAndroid Build Coastguard Worker 
1025*fd1fabb7SAndroid Build Coastguard Worker 					result.d *= 10;
1026*fd1fabb7SAndroid Build Coastguard Worker 
1027*fd1fabb7SAndroid Build Coastguard Worker 					x *= 10.0;
1028*fd1fabb7SAndroid Build Coastguard Worker 
1029*fd1fabb7SAndroid Build Coastguard Worker 					}
1030*fd1fabb7SAndroid Build Coastguard Worker 
1031*fd1fabb7SAndroid Build Coastguard Worker 				result.n = ConvertDoubleToInt32(x - 0.5);
1032*fd1fabb7SAndroid Build Coastguard Worker 
1033*fd1fabb7SAndroid Build Coastguard Worker 				}
1034*fd1fabb7SAndroid Build Coastguard Worker 
1035*fd1fabb7SAndroid Build Coastguard Worker 			}
1036*fd1fabb7SAndroid Build Coastguard Worker 
1037*fd1fabb7SAndroid Build Coastguard Worker 		}
1038*fd1fabb7SAndroid Build Coastguard Worker 
1039*fd1fabb7SAndroid Build Coastguard Worker 	return result;
1040*fd1fabb7SAndroid Build Coastguard Worker 
1041*fd1fabb7SAndroid Build Coastguard Worker 	}
1042*fd1fabb7SAndroid Build Coastguard Worker 
1043*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1044*fd1fabb7SAndroid Build Coastguard Worker 
TagValue_real64(uint32 tagType)1045*fd1fabb7SAndroid Build Coastguard Worker real64 dng_stream::TagValue_real64 (uint32 tagType)
1046*fd1fabb7SAndroid Build Coastguard Worker 	{
1047*fd1fabb7SAndroid Build Coastguard Worker 
1048*fd1fabb7SAndroid Build Coastguard Worker 	switch (tagType)
1049*fd1fabb7SAndroid Build Coastguard Worker 		{
1050*fd1fabb7SAndroid Build Coastguard Worker 
1051*fd1fabb7SAndroid Build Coastguard Worker 		case ttByte:
1052*fd1fabb7SAndroid Build Coastguard Worker 		case ttShort:
1053*fd1fabb7SAndroid Build Coastguard Worker 		case ttLong:
1054*fd1fabb7SAndroid Build Coastguard Worker 		case ttIFD:
1055*fd1fabb7SAndroid Build Coastguard Worker 			return (real64) TagValue_uint32 (tagType);
1056*fd1fabb7SAndroid Build Coastguard Worker 
1057*fd1fabb7SAndroid Build Coastguard Worker 		case ttSByte:
1058*fd1fabb7SAndroid Build Coastguard Worker 		case ttSShort:
1059*fd1fabb7SAndroid Build Coastguard Worker 		case ttSLong:
1060*fd1fabb7SAndroid Build Coastguard Worker 			return (real64) TagValue_int32 (tagType);
1061*fd1fabb7SAndroid Build Coastguard Worker 
1062*fd1fabb7SAndroid Build Coastguard Worker 		case ttRational:
1063*fd1fabb7SAndroid Build Coastguard Worker 			{
1064*fd1fabb7SAndroid Build Coastguard Worker 
1065*fd1fabb7SAndroid Build Coastguard Worker 			uint32 n = Get_uint32 ();
1066*fd1fabb7SAndroid Build Coastguard Worker 			uint32 d = Get_uint32 ();
1067*fd1fabb7SAndroid Build Coastguard Worker 
1068*fd1fabb7SAndroid Build Coastguard Worker 			if (d == 0)
1069*fd1fabb7SAndroid Build Coastguard Worker 				return 0.0;
1070*fd1fabb7SAndroid Build Coastguard Worker 			else
1071*fd1fabb7SAndroid Build Coastguard Worker 				return (real64) n / (real64) d;
1072*fd1fabb7SAndroid Build Coastguard Worker 
1073*fd1fabb7SAndroid Build Coastguard Worker 			}
1074*fd1fabb7SAndroid Build Coastguard Worker 
1075*fd1fabb7SAndroid Build Coastguard Worker 		case ttSRational:
1076*fd1fabb7SAndroid Build Coastguard Worker 			{
1077*fd1fabb7SAndroid Build Coastguard Worker 
1078*fd1fabb7SAndroid Build Coastguard Worker 			int32 n = Get_int32 ();
1079*fd1fabb7SAndroid Build Coastguard Worker 			int32 d = Get_int32 ();
1080*fd1fabb7SAndroid Build Coastguard Worker 
1081*fd1fabb7SAndroid Build Coastguard Worker 			if (d == 0)
1082*fd1fabb7SAndroid Build Coastguard Worker 				return 0.0;
1083*fd1fabb7SAndroid Build Coastguard Worker 			else
1084*fd1fabb7SAndroid Build Coastguard Worker 				return (real64) n / (real64) d;
1085*fd1fabb7SAndroid Build Coastguard Worker 
1086*fd1fabb7SAndroid Build Coastguard Worker 			}
1087*fd1fabb7SAndroid Build Coastguard Worker 
1088*fd1fabb7SAndroid Build Coastguard Worker 		case ttFloat:
1089*fd1fabb7SAndroid Build Coastguard Worker 			return (real64) Get_real32 ();
1090*fd1fabb7SAndroid Build Coastguard Worker 
1091*fd1fabb7SAndroid Build Coastguard Worker 		case ttDouble:
1092*fd1fabb7SAndroid Build Coastguard Worker 			return Get_real64 ();
1093*fd1fabb7SAndroid Build Coastguard Worker 
1094*fd1fabb7SAndroid Build Coastguard Worker 		}
1095*fd1fabb7SAndroid Build Coastguard Worker 
1096*fd1fabb7SAndroid Build Coastguard Worker 	return 0.0;
1097*fd1fabb7SAndroid Build Coastguard Worker 
1098*fd1fabb7SAndroid Build Coastguard Worker 	}
1099*fd1fabb7SAndroid Build Coastguard Worker 
1100*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1101*fd1fabb7SAndroid Build Coastguard Worker 
CopyToStream(dng_stream & dstStream,uint64 count)1102*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::CopyToStream (dng_stream &dstStream,
1103*fd1fabb7SAndroid Build Coastguard Worker 							   uint64 count)
1104*fd1fabb7SAndroid Build Coastguard Worker 	{
1105*fd1fabb7SAndroid Build Coastguard Worker 
1106*fd1fabb7SAndroid Build Coastguard Worker 	uint8 smallBuffer [1024];
1107*fd1fabb7SAndroid Build Coastguard Worker 
1108*fd1fabb7SAndroid Build Coastguard Worker 	if (count <= sizeof (smallBuffer))
1109*fd1fabb7SAndroid Build Coastguard Worker 		{
1110*fd1fabb7SAndroid Build Coastguard Worker 
1111*fd1fabb7SAndroid Build Coastguard Worker 		Get (smallBuffer, (uint32) count);
1112*fd1fabb7SAndroid Build Coastguard Worker 
1113*fd1fabb7SAndroid Build Coastguard Worker 		dstStream.Put (smallBuffer, (uint32) count);
1114*fd1fabb7SAndroid Build Coastguard Worker 
1115*fd1fabb7SAndroid Build Coastguard Worker 		}
1116*fd1fabb7SAndroid Build Coastguard Worker 
1117*fd1fabb7SAndroid Build Coastguard Worker 	else
1118*fd1fabb7SAndroid Build Coastguard Worker 		{
1119*fd1fabb7SAndroid Build Coastguard Worker 
1120*fd1fabb7SAndroid Build Coastguard Worker 		const uint32 bigBufferSize = (uint32) Min_uint64 (kBigBufferSize,
1121*fd1fabb7SAndroid Build Coastguard Worker 													      count);
1122*fd1fabb7SAndroid Build Coastguard Worker 
1123*fd1fabb7SAndroid Build Coastguard Worker 		dng_memory_data bigBuffer (bigBufferSize);
1124*fd1fabb7SAndroid Build Coastguard Worker 
1125*fd1fabb7SAndroid Build Coastguard Worker 		while (count)
1126*fd1fabb7SAndroid Build Coastguard Worker 			{
1127*fd1fabb7SAndroid Build Coastguard Worker 
1128*fd1fabb7SAndroid Build Coastguard Worker 			uint32 blockCount = (uint32) Min_uint64 (bigBufferSize,
1129*fd1fabb7SAndroid Build Coastguard Worker 													 count);
1130*fd1fabb7SAndroid Build Coastguard Worker 
1131*fd1fabb7SAndroid Build Coastguard Worker 			Get (bigBuffer.Buffer (),
1132*fd1fabb7SAndroid Build Coastguard Worker 				 blockCount);
1133*fd1fabb7SAndroid Build Coastguard Worker 
1134*fd1fabb7SAndroid Build Coastguard Worker 			dstStream.Put (bigBuffer.Buffer (),
1135*fd1fabb7SAndroid Build Coastguard Worker 						   blockCount);
1136*fd1fabb7SAndroid Build Coastguard Worker 
1137*fd1fabb7SAndroid Build Coastguard Worker 			count -= blockCount;
1138*fd1fabb7SAndroid Build Coastguard Worker 
1139*fd1fabb7SAndroid Build Coastguard Worker 			}
1140*fd1fabb7SAndroid Build Coastguard Worker 
1141*fd1fabb7SAndroid Build Coastguard Worker 		}
1142*fd1fabb7SAndroid Build Coastguard Worker 
1143*fd1fabb7SAndroid Build Coastguard Worker 	}
1144*fd1fabb7SAndroid Build Coastguard Worker 
1145*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1146*fd1fabb7SAndroid Build Coastguard Worker 
DuplicateStream(dng_stream & dstStream)1147*fd1fabb7SAndroid Build Coastguard Worker void dng_stream::DuplicateStream (dng_stream &dstStream)
1148*fd1fabb7SAndroid Build Coastguard Worker 	{
1149*fd1fabb7SAndroid Build Coastguard Worker 
1150*fd1fabb7SAndroid Build Coastguard Worker 	// Turn off sniffers for this operation.
1151*fd1fabb7SAndroid Build Coastguard Worker 
1152*fd1fabb7SAndroid Build Coastguard Worker 	TempStreamSniffer noSniffer1 (*this    , NULL);
1153*fd1fabb7SAndroid Build Coastguard Worker 	TempStreamSniffer noSniffer2 (dstStream, NULL);
1154*fd1fabb7SAndroid Build Coastguard Worker 
1155*fd1fabb7SAndroid Build Coastguard Worker 	// First grow the destination stream if required, in an attempt to
1156*fd1fabb7SAndroid Build Coastguard Worker 	// reserve any needed space before overwriting the existing data.
1157*fd1fabb7SAndroid Build Coastguard Worker 
1158*fd1fabb7SAndroid Build Coastguard Worker 	if (dstStream.Length () < Length ())
1159*fd1fabb7SAndroid Build Coastguard Worker 		{
1160*fd1fabb7SAndroid Build Coastguard Worker 		dstStream.SetLength (Length ());
1161*fd1fabb7SAndroid Build Coastguard Worker 		}
1162*fd1fabb7SAndroid Build Coastguard Worker 
1163*fd1fabb7SAndroid Build Coastguard Worker 	SetReadPosition (0);
1164*fd1fabb7SAndroid Build Coastguard Worker 
1165*fd1fabb7SAndroid Build Coastguard Worker 	dstStream.SetWritePosition (0);
1166*fd1fabb7SAndroid Build Coastguard Worker 
1167*fd1fabb7SAndroid Build Coastguard Worker 	CopyToStream (dstStream, Length ());
1168*fd1fabb7SAndroid Build Coastguard Worker 
1169*fd1fabb7SAndroid Build Coastguard Worker 	dstStream.Flush ();
1170*fd1fabb7SAndroid Build Coastguard Worker 
1171*fd1fabb7SAndroid Build Coastguard Worker 	dstStream.SetLength (Length ());
1172*fd1fabb7SAndroid Build Coastguard Worker 
1173*fd1fabb7SAndroid Build Coastguard Worker 	}
1174*fd1fabb7SAndroid Build Coastguard Worker 
1175*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1176*fd1fabb7SAndroid Build Coastguard Worker 
TempBigEndian(dng_stream & stream,bool bigEndian)1177*fd1fabb7SAndroid Build Coastguard Worker TempBigEndian::TempBigEndian (dng_stream &stream,
1178*fd1fabb7SAndroid Build Coastguard Worker 						 	  bool bigEndian)
1179*fd1fabb7SAndroid Build Coastguard Worker 
1180*fd1fabb7SAndroid Build Coastguard Worker 	:	fStream  (stream)
1181*fd1fabb7SAndroid Build Coastguard Worker 	,	fOldSwap (stream.SwapBytes ())
1182*fd1fabb7SAndroid Build Coastguard Worker 
1183*fd1fabb7SAndroid Build Coastguard Worker 	{
1184*fd1fabb7SAndroid Build Coastguard Worker 
1185*fd1fabb7SAndroid Build Coastguard Worker 	fStream.SetBigEndian (bigEndian);
1186*fd1fabb7SAndroid Build Coastguard Worker 
1187*fd1fabb7SAndroid Build Coastguard Worker 	}
1188*fd1fabb7SAndroid Build Coastguard Worker 
1189*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1190*fd1fabb7SAndroid Build Coastguard Worker 
~TempBigEndian()1191*fd1fabb7SAndroid Build Coastguard Worker TempBigEndian::~TempBigEndian ()
1192*fd1fabb7SAndroid Build Coastguard Worker 	{
1193*fd1fabb7SAndroid Build Coastguard Worker 
1194*fd1fabb7SAndroid Build Coastguard Worker 	fStream.SetSwapBytes (fOldSwap);
1195*fd1fabb7SAndroid Build Coastguard Worker 
1196*fd1fabb7SAndroid Build Coastguard Worker 	}
1197*fd1fabb7SAndroid Build Coastguard Worker 
1198*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1199*fd1fabb7SAndroid Build Coastguard Worker 
TempStreamSniffer(dng_stream & stream,dng_abort_sniffer * sniffer)1200*fd1fabb7SAndroid Build Coastguard Worker TempStreamSniffer::TempStreamSniffer (dng_stream &stream,
1201*fd1fabb7SAndroid Build Coastguard Worker 									  dng_abort_sniffer *sniffer)
1202*fd1fabb7SAndroid Build Coastguard Worker 
1203*fd1fabb7SAndroid Build Coastguard Worker 	:	fStream     (stream)
1204*fd1fabb7SAndroid Build Coastguard Worker 	,	fOldSniffer (stream.Sniffer ())
1205*fd1fabb7SAndroid Build Coastguard Worker 
1206*fd1fabb7SAndroid Build Coastguard Worker 	{
1207*fd1fabb7SAndroid Build Coastguard Worker 
1208*fd1fabb7SAndroid Build Coastguard Worker 	fStream.SetSniffer (sniffer);
1209*fd1fabb7SAndroid Build Coastguard Worker 
1210*fd1fabb7SAndroid Build Coastguard Worker 	}
1211*fd1fabb7SAndroid Build Coastguard Worker 
1212*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1213*fd1fabb7SAndroid Build Coastguard Worker 
~TempStreamSniffer()1214*fd1fabb7SAndroid Build Coastguard Worker TempStreamSniffer::~TempStreamSniffer ()
1215*fd1fabb7SAndroid Build Coastguard Worker 	{
1216*fd1fabb7SAndroid Build Coastguard Worker 
1217*fd1fabb7SAndroid Build Coastguard Worker 	fStream.SetSniffer (fOldSniffer);
1218*fd1fabb7SAndroid Build Coastguard Worker 
1219*fd1fabb7SAndroid Build Coastguard Worker 	}
1220*fd1fabb7SAndroid Build Coastguard Worker 
1221*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1222