Home | History | Annotate | Download | only in source
      1 /*****************************************************************************/
      2 // Copyright 2006-2007 Adobe Systems Incorporated
      3 // All Rights Reserved.
      4 //
      5 // NOTICE:  Adobe permits you to use, modify, and distribute this file in
      6 // accordance with the terms of the Adobe license agreement accompanying it.
      7 /*****************************************************************************/
      8 
      9 /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_stream.h#2 $ */
     10 /* $DateTime: 2012/06/01 07:28:57 $ */
     11 /* $Change: 832715 $ */
     12 /* $Author: tknoll $ */
     13 
     14 /** Data stream abstraction for serializing and deserializing sequences of
     15  *  basic types and RAW image data.
     16  */
     17 
     18 /*****************************************************************************/
     19 
     20 #ifndef __dng_stream__
     21 #define __dng_stream__
     22 
     23 /*****************************************************************************/
     24 
     25 #include "dng_classes.h"
     26 #include "dng_types.h"
     27 #include "dng_memory.h"
     28 #include "dng_rational.h"
     29 #include "dng_utils.h"
     30 
     31 /*****************************************************************************/
     32 
     33 // Constants for invalid offset in streams.
     34 
     35 const uint64 kDNGStreamInvalidOffset = (uint64) (int64) -1;
     36 
     37 /*****************************************************************************/
     38 
     39 /// Base stream abstraction. Has support for going between stream and pointer
     40 /// abstraction.
     41 
     42 class dng_stream
     43 	{
     44 
     45 	public:
     46 
     47 		enum
     48 			{
     49 
     50 			kSmallBufferSize =  4 * 1024,
     51 			kBigBufferSize   = 64 * 1024,
     52 
     53 			kDefaultBufferSize = kSmallBufferSize
     54 
     55 			};
     56 
     57 	private:
     58 
     59 		bool fSwapBytes;
     60 
     61 		bool fHaveLength;
     62 
     63 		uint64 fLength;
     64 
     65 		const uint64 fOffsetInOriginalFile;
     66 
     67 		uint64 fPosition;
     68 
     69 		dng_memory_data fMemBlock;
     70 
     71 		uint8 *fBuffer;
     72 
     73 		uint32 fBufferSize;
     74 
     75 		uint64 fBufferStart;
     76 		uint64 fBufferEnd;
     77 		uint64 fBufferLimit;
     78 
     79 		bool fBufferDirty;
     80 
     81 		dng_abort_sniffer *fSniffer;
     82 
     83 	protected:
     84 
     85 		dng_stream (dng_abort_sniffer *sniffer = NULL,
     86 					uint32 bufferSize = kDefaultBufferSize,
     87 					uint64 offsetInOriginalFile = kDNGStreamInvalidOffset);
     88 
     89 		virtual uint64 DoGetLength ();
     90 
     91 		virtual void DoRead (void *data,
     92 							 uint32 count,
     93 							 uint64 offset);
     94 
     95 		virtual void DoSetLength (uint64 length);
     96 
     97 		virtual void DoWrite (const void *data,
     98 							  uint32 count,
     99 							  uint64 offset);
    100 
    101 	public:
    102 
    103 		/// Construct a stream with initial data.
    104 		/// \param data Pointer to initial contents of stream.
    105 		/// \param count Number of bytes data is valid for.
    106 		/// \param offsetInOriginalFile If data came from a file originally,
    107 		/// offset can be saved here for later use.
    108 
    109 		dng_stream (const void *data,
    110 					uint32 count,
    111 					uint64 offsetInOriginalFile = kDNGStreamInvalidOffset);
    112 
    113 		virtual ~dng_stream ();
    114 
    115 		/// Getter for whether stream is swapping byte order on input/output.
    116 		/// \retval If true, data will be swapped on input/output.
    117 
    118 		bool SwapBytes () const
    119 			{
    120 			return fSwapBytes;
    121 			}
    122 
    123 		/// Setter for whether stream is swapping byte order on input/output.
    124 		/// \param swapBytes If true, stream will swap byte order on input or
    125 		/// output for future reads/writes.
    126 
    127 		void SetSwapBytes (bool swapBytes)
    128 			{
    129 			fSwapBytes = swapBytes;
    130 			}
    131 
    132 		/// Getter for whether data in stream is big endian.
    133 		/// \retval If true, data in stream is big endian.
    134 
    135 		bool BigEndian () const;
    136 
    137 		/// Setter for whether data in stream is big endian.
    138 		/// \param bigEndian If true, data in stream is big endian.
    139 
    140 		void SetBigEndian (bool bigEndian = true);
    141 
    142 		/// Getter for whether data in stream is big endian.
    143 		/// \retval If true, data in stream is big endian.
    144 
    145 		bool LittleEndian () const
    146 			{
    147 			return !BigEndian ();
    148 			}
    149 
    150 		/// Setter for whether data in stream is big endian.
    151 		/// \param littleEndian If true, data in stream is big endian.
    152 
    153 		void SetLittleEndian (bool littleEndian = true)
    154 			{
    155 			SetBigEndian (!littleEndian);
    156 			}
    157 
    158 		/// Returns the size of the buffer used by the stream.
    159 
    160 		uint32 BufferSize () const
    161 			{
    162 			return fBufferSize;
    163 			}
    164 
    165 		/// Getter for length of data in stream.
    166 		/// \retval Length of readable data in stream.
    167 
    168 		uint64 Length ()
    169 			{
    170 
    171 			if (!fHaveLength)
    172 				{
    173 
    174 				fLength = DoGetLength ();
    175 
    176 				fHaveLength = true;
    177 
    178 				}
    179 
    180 			return fLength;
    181 
    182 			}
    183 
    184 		/// Getter for current offset in stream.
    185 		/// \retval current offset from start of stream.
    186 
    187 		uint64 Position () const
    188 			{
    189 			return fPosition;
    190 			}
    191 
    192 		/// Getter for current position in original file, taking into account
    193 		/// OffsetInOriginalFile stream data was taken from.
    194 		/// \retval kInvalidOffset if no offset in original file is set, sum
    195 		/// of offset in original file and current position otherwise.
    196 
    197 		uint64 PositionInOriginalFile () const;
    198 
    199 		/// Getter for offset in original file.
    200 		/// \retval kInvalidOffset if no offset in original file is set,
    201 		/// offset in original file otherwise.
    202 
    203 		uint64 OffsetInOriginalFile () const;
    204 
    205 		/// Return pointer to stream contents if the stream is entirely
    206 		/// available as a single memory block, NULL otherwise.
    207 
    208 		const void * Data () const;
    209 
    210 		/// Return the entire stream as a single memory block.
    211 		/// This works for all streams, but requires copying the data to a new buffer.
    212 		/// \param allocator Allocator used to allocate memory.
    213 
    214 		dng_memory_block * AsMemoryBlock (dng_memory_allocator &allocator);
    215 
    216 		/// Seek to a new position in stream for reading.
    217 
    218 		void SetReadPosition (uint64 offset);
    219 
    220 		/// Skip forward in stream.
    221 		/// \param delta Number of bytes to skip forward.
    222 
    223 		void Skip (uint64 delta)
    224 			{
    225 			SetReadPosition (Position () + delta);
    226 			}
    227 
    228 		/// Get data from stream. Exception is thrown and no data is read if
    229 		/// insufficient data available in stream.
    230 		/// \param data Buffer to put data into. Must be valid for count bytes.
    231 		/// \param count Bytes of data to read.
    232 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    233 		/// if not enough data in stream.
    234 
    235 		void Get (void *data, uint32 count);
    236 
    237 		/// Seek to a new position in stream for writing.
    238 
    239 		void SetWritePosition (uint64 offset);
    240 
    241 		/// Force any stored data in stream to be written to underlying storage.
    242 
    243 		void Flush ();
    244 
    245 		/// Set length of available data.
    246 		/// \param length Number of bytes of avialble data in stream.
    247 
    248 		void SetLength (uint64 length);
    249 
    250 		/// Write data to stream.
    251 		/// \param data Buffer of data to write to stream.
    252 		/// \param count Bytes of in data.
    253 
    254 		void Put (const void *data, uint32 count);
    255 
    256 		/// Get an unsigned 8-bit integer from stream and advance read position.
    257 		/// \retval One unsigned 8-bit integer.
    258 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    259 		/// if not enough data in stream.
    260 
    261 		uint8 Get_uint8 ()
    262 			{
    263 
    264 			// Fast check to see if in buffer
    265 
    266 			if (fPosition >= fBufferStart && fPosition < fBufferEnd)
    267 				{
    268 
    269 				return fBuffer [fPosition++ - fBufferStart];
    270 
    271 				}
    272 
    273 			// Not in buffer, let main routine do the work.
    274 
    275 			uint8 x;
    276 
    277 			Get (&x, 1);
    278 
    279 			return x;
    280 
    281 			}
    282 
    283 		/// Put an unsigned 8-bit integer to stream and advance write position.
    284 		/// \param x One unsigned 8-bit integer.
    285 
    286 		void Put_uint8 (uint8 x)
    287 			{
    288 
    289 			if (fBufferDirty               &&
    290 			    fPosition  >= fBufferStart &&
    291 				fPosition  <= fBufferEnd   &&
    292 				fPosition  <  fBufferLimit)
    293 				{
    294 
    295 				fBuffer [fPosition - fBufferStart] = x;
    296 
    297 				fPosition++;
    298 
    299 				if (fBufferEnd < fPosition)
    300 					fBufferEnd = fPosition;
    301 
    302 				fLength = Max_uint64 (Length (), fPosition);
    303 
    304 				}
    305 
    306 			else
    307 				{
    308 
    309 				Put (&x, 1);
    310 
    311 				}
    312 
    313 			}
    314 
    315 		/// Get an unsigned 16-bit integer from stream and advance read position.
    316 		/// Byte swap if byte swapping is turned on.
    317 		/// \retval One unsigned 16-bit integer.
    318 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    319 		/// if not enough data in stream.
    320 
    321 		uint16 Get_uint16 ();
    322 
    323 		/// Put an unsigned 16-bit integer to stream and advance write position.
    324 		/// Byte swap if byte swapping is turned on.
    325 		/// \param x One unsigned 16-bit integer.
    326 
    327 		void Put_uint16 (uint16 x);
    328 
    329 		/// Get an unsigned 32-bit integer from stream and advance read position.
    330 		/// Byte swap if byte swapping is turned on.
    331 		/// \retval One unsigned 32-bit integer.
    332 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    333 		/// if not enough data in stream.
    334 
    335 		uint32 Get_uint32 ();
    336 
    337 		/// Put an unsigned 32-bit integer to stream and advance write position.
    338 		/// Byte swap if byte swapping is turned on.
    339 		/// \param x One unsigned 32-bit integer.
    340 
    341 		void Put_uint32 (uint32 x);
    342 
    343 		/// Get an unsigned 64-bit integer from stream and advance read position.
    344 		/// Byte swap if byte swapping is turned on.
    345 		/// \retval One unsigned 64-bit integer.
    346 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    347 		/// if not enough data in stream.
    348 
    349 		uint64 Get_uint64 ();
    350 
    351 		/// Put an unsigned 64-bit integer to stream and advance write position.
    352 		/// Byte swap if byte swapping is turned on.
    353 		/// \param x One unsigned 64-bit integer.
    354 
    355 		void Put_uint64 (uint64 x);
    356 
    357 		/// Get one 8-bit integer from stream and advance read position.
    358 		/// \retval One 8-bit integer.
    359 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    360 		/// if not enough data in stream.
    361 
    362 		int8 Get_int8 ()
    363 			{
    364 			return (int8) Get_uint8 ();
    365 			}
    366 
    367 		/// Put one 8-bit integer to stream and advance write position.
    368 		/// \param x One  8-bit integer.
    369 
    370 		void Put_int8 (int8 x)
    371 			{
    372 			Put_uint8 ((uint8) x);
    373 			}
    374 
    375 		/// Get one 16-bit integer from stream and advance read position.
    376 		/// Byte swap if byte swapping is turned on.
    377 		/// \retval One 16-bit integer.
    378 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    379 		/// if not enough data in stream.
    380 
    381 		int16 Get_int16 ()
    382 			{
    383 			return (int16) Get_uint16 ();
    384 			}
    385 
    386 		/// Put one 16-bit integer to stream and advance write position.
    387 		/// Byte swap if byte swapping is turned on.
    388 		/// \param x One 16-bit integer.
    389 
    390 		void Put_int16 (int16 x)
    391 			{
    392 			Put_uint16 ((uint16) x);
    393 			}
    394 
    395 		/// Get one 32-bit integer from stream and advance read position.
    396 		/// Byte swap if byte swapping is turned on.
    397 		/// \retval One 32-bit integer.
    398 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    399 		/// if not enough data in stream.
    400 
    401 		int32 Get_int32 ()
    402 			{
    403 			return (int32) Get_uint32 ();
    404 			}
    405 
    406 		/// Put one 32-bit integer to stream and advance write position.
    407 		/// Byte swap if byte swapping is turned on.
    408 		/// \param x One 32-bit integer.
    409 
    410 		void Put_int32 (int32 x)
    411 			{
    412 			Put_uint32 ((uint32) x);
    413 			}
    414 
    415 		/// Get one 64-bit integer from stream and advance read position.
    416 		/// Byte swap if byte swapping is turned on.
    417 		/// \retval One 64-bit integer.
    418 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    419 		/// if not enough data in stream.
    420 
    421 		int64 Get_int64 ()
    422 			{
    423 			return (int64) Get_uint64 ();
    424 			}
    425 
    426 		/// Put one 64-bit integer to stream and advance write position.
    427 		/// Byte swap if byte swapping is turned on.
    428 		/// \param x One 64-bit integer.
    429 
    430 		void Put_int64 (int64 x)
    431 			{
    432 			Put_uint64 ((uint64) x);
    433 			}
    434 
    435 		/// Get one 32-bit IEEE floating-point number from stream and advance
    436 		/// read position. Byte swap if byte swapping is turned on.
    437 		/// \retval One 32-bit IEEE floating-point number.
    438 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    439 		/// if not enough data in stream.
    440 
    441 		real32 Get_real32 ();
    442 
    443 		/// Put one 32-bit IEEE floating-point number to stream and advance write
    444 		/// position. Byte swap if byte swapping is turned on.
    445 		/// \param x One 32-bit IEEE floating-point number.
    446 
    447 		void Put_real32 (real32 x);
    448 
    449 		/// Get one 64-bit IEEE floating-point number from stream and advance
    450 		/// read position. Byte swap if byte swapping is turned on.
    451 		/// \retval One 64-bit IEEE floating-point number .
    452 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    453 		/// if not enough data in stream.
    454 
    455 		real64 Get_real64 ();
    456 
    457 		/// Put one 64-bit IEEE floating-point number to stream and advance write
    458 		/// position. Byte swap if byte swapping is turned on.
    459 		/// \param x One64-bit IEEE floating-point number.
    460 
    461 		void Put_real64 (real64 x);
    462 
    463 		/// Get an 8-bit character string from stream and advance read position.
    464 		/// Routine always reads until a NUL character (8-bits of zero) is read.
    465 		/// (That is, only maxLength bytes will be returned in buffer, but the
    466 		/// stream is always advanced until a NUL is read or EOF is reached.)
    467 		/// \param data Buffer in which string is returned.
    468 		/// \param maxLength Maximum number of bytes to place in buffer.
    469 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    470 		/// if stream runs out before NUL is seen.
    471 
    472 		void Get_CString (char *data,
    473 						  uint32 maxLength);
    474 
    475 		/// Get a 16-bit character string from stream and advance read position.
    476 		/// 16-bit characters are truncated to 8-bits.
    477 		/// Routine always reads until a NUL character (16-bits of zero) is read.
    478 		/// (That is, only maxLength bytes will be returned in buffer, but the
    479 		/// stream is always advanced until a NUL is read or EOF is reached.)
    480 		/// \param data Buffer to place string in.
    481 		/// \param maxLength Maximum number of bytes to place in buffer.
    482 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    483 		/// if stream runs out before NUL is seen.
    484 
    485 		void Get_UString (char *data,
    486 						  uint32 maxLength);
    487 
    488 		/// Writes the specified number of zero bytes to stream.
    489 		/// \param count Number of zero bytes to write.
    490 
    491 		void PutZeros (uint64 count);
    492 
    493 		/// Writes zeros to align the stream position to a multiple of 2.
    494 
    495 		void PadAlign2 ();
    496 
    497 		/// Writes zeros to align the stream position to a multiple of 4.
    498 
    499 		void PadAlign4 ();
    500 
    501 		/// Get a value of size indicated by tag type from stream and advance
    502 		/// read position. Byte swap if byte swapping is turned on and tag type
    503 		/// is larger than a byte. Value is returned as an unsigned 32-bit integer.
    504 		/// \param tagType Tag type of data stored in stream.
    505 		/// \retval One unsigned 32-bit integer.
    506 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    507 		/// if not enough data in stream.
    508 
    509 		uint32 TagValue_uint32 (uint32 tagType);
    510 
    511 		/// Get a value of size indicated by tag type from stream and advance read
    512 		/// position. Byte swap if byte swapping is turned on and tag type is larger
    513 		/// than a byte. Value is returned as a 32-bit integer.
    514 		/// \param tagType Tag type of data stored in stream.
    515 		/// \retval One 32-bit integer.
    516 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    517 		/// if not enough data in stream.
    518 
    519 		int32 TagValue_int32 (uint32 tagType);
    520 
    521 		/// Get a value of size indicated by tag type from stream and advance read
    522 		/// position. Byte swap if byte swapping is turned on and tag type is larger
    523 		/// than a byte. Value is returned as a dng_urational.
    524 		/// \param tagType Tag type of data stored in stream.
    525 		/// \retval One dng_urational.
    526 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    527 		/// if not enough data in stream.
    528 
    529 		dng_urational TagValue_urational (uint32 tagType);
    530 
    531 		/// Get a value of size indicated by tag type from stream and advance read
    532 		/// position. Byte swap if byte swapping is turned on and tag type is larger
    533 		/// than a byte. Value is returned as a dng_srational.
    534 		/// \param tagType Tag type of data stored in stream.
    535 		/// \retval One dng_srational.
    536 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    537 		/// if not enough data in stream.
    538 
    539 		dng_srational TagValue_srational (uint32 tagType);
    540 
    541 		/// Get a value of size indicated by tag type from stream and advance read
    542 		/// position. Byte swap if byte swapping is turned on and tag type is larger
    543 		/// than a byte. Value is returned as a 64-bit IEEE floating-point number.
    544 		/// \param tagType Tag type of data stored in stream.
    545 		/// \retval One 64-bit IEEE floating-point number.
    546 		/// \exception dng_exception with fErrorCode equal to dng_error_end_of_file
    547 		/// if not enough data in stream.
    548 
    549 		real64 TagValue_real64 (uint32 tagType);
    550 
    551 		/// Getter for sniffer associated with stream.
    552 		/// \retval The sniffer for this stream.
    553 
    554 		dng_abort_sniffer * Sniffer () const
    555 			{
    556 			return fSniffer;
    557 			}
    558 
    559 		/// Putter for sniffer associated with stream.
    560 		/// \param sniffer The new sniffer to use (or NULL for none).
    561 
    562 		void SetSniffer (dng_abort_sniffer *sniffer)
    563 			{
    564 			fSniffer = sniffer;
    565 			}
    566 
    567 		/// Copy a specified number of bytes to a target stream.
    568 		/// \param dstStream The target stream.
    569 		/// \param count The number of bytes to copy.
    570 
    571 		virtual void CopyToStream (dng_stream &dstStream,
    572 								   uint64 count);
    573 
    574 		/// Makes the target stream a copy of this stream.
    575 		/// \param dstStream The target stream.
    576 
    577 		void DuplicateStream (dng_stream &dstStream);
    578 
    579 	private:
    580 
    581 		// Hidden copy constructor and assignment operator.
    582 
    583 		dng_stream (const dng_stream &stream);
    584 
    585 		dng_stream & operator= (const dng_stream &stream);
    586 
    587 	};
    588 
    589 /*****************************************************************************/
    590 
    591 class TempBigEndian
    592 	{
    593 
    594 	private:
    595 
    596 		dng_stream & fStream;
    597 
    598 		bool fOldSwap;
    599 
    600 	public:
    601 
    602 		TempBigEndian (dng_stream &stream,
    603 					   bool bigEndian = true);
    604 
    605 		virtual ~TempBigEndian ();
    606 
    607 	};
    608 
    609 /*****************************************************************************/
    610 
    611 class TempLittleEndian: public TempBigEndian
    612 	{
    613 
    614 	public:
    615 
    616 		TempLittleEndian (dng_stream &stream,
    617 						  bool littleEndian = true)
    618 
    619 			:	TempBigEndian (stream, !littleEndian)
    620 
    621 			{
    622 			}
    623 
    624 		virtual ~TempLittleEndian ()
    625 			{
    626 			}
    627 
    628 	};
    629 
    630 /*****************************************************************************/
    631 
    632 class TempStreamSniffer
    633 	{
    634 
    635 	private:
    636 
    637 		dng_stream & fStream;
    638 
    639 		dng_abort_sniffer *fOldSniffer;
    640 
    641 	public:
    642 
    643 		TempStreamSniffer (dng_stream &stream,
    644 					       dng_abort_sniffer *sniffer);
    645 
    646 		virtual ~TempStreamSniffer ();
    647 
    648 	private:
    649 
    650 		// Hidden copy constructor and assignment operator.
    651 
    652 		TempStreamSniffer (const TempStreamSniffer &temp);
    653 
    654 		TempStreamSniffer & operator= (const TempStreamSniffer &temp);
    655 
    656 	};
    657 
    658 /*****************************************************************************/
    659 
    660 class PreserveStreamReadPosition
    661 	{
    662 
    663 	private:
    664 
    665 		dng_stream & fStream;
    666 
    667 		uint64 fPosition;
    668 
    669 	public:
    670 
    671 		PreserveStreamReadPosition (dng_stream &stream)
    672 
    673 			:	fStream	  (stream)
    674 			,	fPosition (stream.Position ())
    675 
    676 			{
    677 			}
    678 
    679 		~PreserveStreamReadPosition ()
    680 			{
    681 			fStream.SetReadPosition (fPosition);
    682 			}
    683 
    684 	private:
    685 
    686 		// Hidden copy constructor and assignment operator.
    687 
    688 		PreserveStreamReadPosition (const PreserveStreamReadPosition &rhs);
    689 
    690 		PreserveStreamReadPosition & operator= (const PreserveStreamReadPosition &rhs);
    691 
    692 	};
    693 
    694 /*****************************************************************************/
    695 
    696 #endif
    697 
    698 /*****************************************************************************/
    699