File indexing completed on 2025-01-19 03:55:17
0001 /*****************************************************************************/ 0002 // Copyright 2006-2019 Adobe Systems Incorporated 0003 // All Rights Reserved. 0004 // 0005 // NOTICE: Adobe permits you to use, modify, and distribute this file in 0006 // accordance with the terms of the Adobe license agreement accompanying it. 0007 /*****************************************************************************/ 0008 0009 /** Data stream abstraction for serializing and deserializing sequences of 0010 * basic types and RAW image data. 0011 */ 0012 0013 /*****************************************************************************/ 0014 0015 #ifndef __dng_stream__ 0016 #define __dng_stream__ 0017 0018 /*****************************************************************************/ 0019 0020 #include "dng_auto_ptr.h" 0021 #include "dng_classes.h" 0022 #include "dng_types.h" 0023 #include "dng_memory.h" 0024 #include "dng_rational.h" 0025 #include "dng_uncopyable.h" 0026 #include "dng_utils.h" 0027 0028 /*****************************************************************************/ 0029 0030 // Constants for invalid offset in streams. 0031 0032 const uint64 kDNGStreamInvalidOffset = (uint64) (int64) -1; 0033 0034 /*****************************************************************************/ 0035 0036 /// Base stream abstraction. Has support for going between stream and pointer 0037 /// abstraction. 0038 0039 class dng_stream: private dng_uncopyable 0040 { 0041 0042 public: 0043 0044 enum 0045 { 0046 0047 kSmallBufferSize = 8 * 1024, 0048 kBigBufferSize = 64 * 1024, 0049 0050 kDefaultBufferSize = kSmallBufferSize 0051 0052 }; 0053 0054 private: 0055 0056 bool fSwapBytes; 0057 0058 bool fHaveLength; 0059 0060 uint64 fLength; 0061 0062 const uint64 fOffsetInOriginalFile; 0063 0064 uint64 fPosition; 0065 0066 AutoPtr<dng_memory_block> fMemBlock; 0067 0068 uint8 *fBuffer; 0069 0070 uint32 fBufferSize; 0071 0072 uint64 fBufferStart; 0073 uint64 fBufferEnd; 0074 uint64 fBufferLimit; 0075 0076 bool fBufferDirty; 0077 0078 dng_abort_sniffer *fSniffer; 0079 0080 protected: 0081 0082 dng_stream (dng_abort_sniffer *sniffer = NULL, 0083 uint32 bufferSize = kDefaultBufferSize, 0084 uint64 offsetInOriginalFile = kDNGStreamInvalidOffset); 0085 0086 virtual uint64 DoGetLength (); 0087 0088 virtual void DoRead (void *data, 0089 uint32 count, 0090 uint64 offset); 0091 0092 virtual void DoSetLength (uint64 length); 0093 0094 virtual void DoWrite (const void *data, 0095 uint32 count, 0096 uint64 offset); 0097 0098 public: 0099 0100 /// Construct a stream with initial data. 0101 /// \param data Pointer to initial contents of stream. 0102 /// \param count Number of bytes data is valid for. 0103 /// \param offsetInOriginalFile If data came from a file originally, 0104 /// offset can be saved here for later use. 0105 0106 dng_stream (const void *data, 0107 uint32 count, 0108 uint64 offsetInOriginalFile = kDNGStreamInvalidOffset); 0109 0110 virtual ~dng_stream (); 0111 0112 /// Getter for whether stream is swapping byte order on input/output. 0113 /// \retval If true, data will be swapped on input/output. 0114 0115 bool SwapBytes () const 0116 { 0117 return fSwapBytes; 0118 } 0119 0120 /// Setter for whether stream is swapping byte order on input/output. 0121 /// \param swapBytes If true, stream will swap byte order on input or 0122 /// output for future reads/writes. 0123 0124 void SetSwapBytes (bool swapBytes) 0125 { 0126 fSwapBytes = swapBytes; 0127 } 0128 0129 /// Getter for whether data in stream is big endian. 0130 /// \retval If true, data in stream is big endian. 0131 0132 bool BigEndian () const; 0133 0134 /// Setter for whether data in stream is big endian. 0135 /// \param bigEndian If true, data in stream is big endian. 0136 0137 void SetBigEndian (bool bigEndian = true); 0138 0139 /// Getter for whether data in stream is big endian. 0140 /// \retval If true, data in stream is big endian. 0141 0142 bool LittleEndian () const 0143 { 0144 return !BigEndian (); 0145 } 0146 0147 /// Setter for whether data in stream is big endian. 0148 /// \param littleEndian If true, data in stream is big endian. 0149 0150 void SetLittleEndian (bool littleEndian = true) 0151 { 0152 SetBigEndian (!littleEndian); 0153 } 0154 0155 /// Returns the size of the buffer used by the stream. 0156 0157 uint32 BufferSize () const 0158 { 0159 return fBufferSize; 0160 } 0161 0162 /// Change the buffer size on the stream, if possible. 0163 0164 void SetBufferSize (dng_memory_allocator &allocator, 0165 uint32 newBufferSize); 0166 0167 /// Getter for length of data in stream. 0168 /// \retval Length of readable data in stream. 0169 0170 uint64 Length () 0171 { 0172 0173 if (!fHaveLength) 0174 { 0175 0176 fLength = DoGetLength (); 0177 0178 fHaveLength = true; 0179 0180 } 0181 0182 return fLength; 0183 0184 } 0185 0186 /// Getter for current offset in stream. 0187 /// \retval current offset from start of stream. 0188 0189 uint64 Position () const 0190 { 0191 return fPosition; 0192 } 0193 0194 /// Getter for current position in original file, taking into account 0195 /// OffsetInOriginalFile stream data was taken from. 0196 /// \retval kInvalidOffset if no offset in original file is set, sum 0197 /// of offset in original file and current position otherwise. 0198 0199 uint64 PositionInOriginalFile () const; 0200 0201 /// Getter for offset in original file. 0202 /// \retval kInvalidOffset if no offset in original file is set, 0203 /// offset in original file otherwise. 0204 0205 uint64 OffsetInOriginalFile () const; 0206 0207 /// Return pointer to stream contents if the stream is entirely 0208 /// available as a single memory block, NULL otherwise. 0209 0210 const void * Data () const; 0211 0212 /// Return the entire stream as a single memory block. 0213 /// This works for all streams, but requires copying the data to a new buffer. 0214 /// \param allocator Allocator used to allocate memory. 0215 0216 dng_memory_block * AsMemoryBlock (dng_memory_allocator &allocator); 0217 0218 /// Seek to a new position in stream for reading. 0219 0220 void SetReadPosition (uint64 offset); 0221 0222 /// Skip forward in stream. 0223 /// \param delta Number of bytes to skip forward. 0224 0225 void Skip (uint64 delta) 0226 { 0227 SetReadPosition (Position () + delta); 0228 } 0229 0230 /// Quick check to see if data range in completely buffered. 0231 0232 bool DataInBuffer (uint32 count, 0233 uint64 offset) 0234 { 0235 return (offset >= fBufferStart && 0236 offset + count <= fBufferEnd); 0237 } 0238 0239 /// Get data from stream. Exception is thrown and no data is read if 0240 /// insufficient data available in stream. 0241 /// \param data Buffer to put data into. Must be valid for count bytes. 0242 /// \param count Bytes of data to read. 0243 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0244 /// if not enough data in stream. 0245 0246 void Get (void *data, uint32 count, uint32 maxOverRead=0); 0247 0248 /// Seek to a new position in stream for writing. 0249 0250 void SetWritePosition (uint64 offset); 0251 0252 /// Force any stored data in stream to be written to underlying storage. 0253 0254 void Flush (); 0255 0256 /// Set length of available data. 0257 /// \param length Number of bytes of avialble data in stream. 0258 0259 void SetLength (uint64 length); 0260 0261 /// Write data to stream. 0262 /// \param data Buffer of data to write to stream. 0263 /// \param count Bytes of in data. 0264 0265 void Put (const void *data, uint32 count); 0266 0267 /// Get an unsigned 8-bit integer from stream and advance read position. 0268 /// \retval One unsigned 8-bit integer. 0269 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0270 /// if not enough data in stream. 0271 0272 uint8 Get_uint8 () 0273 { 0274 0275 // Fast check to see if in buffer 0276 0277 if (fPosition >= fBufferStart && fPosition < fBufferEnd) 0278 { 0279 0280 return fBuffer [fPosition++ - fBufferStart]; 0281 0282 } 0283 0284 // Not in buffer, let main routine do the work. 0285 0286 uint8 x; 0287 0288 Get (&x, 1); 0289 0290 return x; 0291 0292 } 0293 0294 /// Put an unsigned 8-bit integer to stream and advance write position. 0295 /// \param x One unsigned 8-bit integer. 0296 0297 void Put_uint8 (uint8 x) 0298 { 0299 0300 if (fBufferDirty && 0301 fPosition >= fBufferStart && 0302 fPosition <= fBufferEnd && 0303 fPosition < fBufferLimit) 0304 { 0305 0306 fBuffer [fPosition - fBufferStart] = x; 0307 0308 fPosition++; 0309 0310 if (fBufferEnd < fPosition) 0311 fBufferEnd = fPosition; 0312 0313 fLength = Max_uint64 (Length (), fPosition); 0314 0315 } 0316 0317 else 0318 { 0319 0320 Put (&x, 1); 0321 0322 } 0323 0324 } 0325 0326 /// Get an unsigned 16-bit integer from stream and advance read position. 0327 /// Byte swap if byte swapping is turned on. 0328 /// \retval One unsigned 16-bit integer. 0329 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0330 /// if not enough data in stream. 0331 0332 uint16 Get_uint16 (); 0333 0334 /// Put an unsigned 16-bit integer to stream and advance write position. 0335 /// Byte swap if byte swapping is turned on. 0336 /// \param x One unsigned 16-bit integer. 0337 0338 void Put_uint16 (uint16 x); 0339 0340 /// Get an unsigned 32-bit integer from stream and advance read position. 0341 /// Byte swap if byte swapping is turned on. 0342 /// \retval One unsigned 32-bit integer. 0343 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0344 /// if not enough data in stream. 0345 0346 uint32 Get_uint32(); 0347 0348 #if !qDNGBigEndian 0349 inline // ep, enable compiler inlining 0350 uint32 Get_uint32_LE () 0351 { 0352 0353 uint32 x; 0354 0355 Get (&x, 4, 3); // Allow 3-byte overread (undefined data returned but not used) 0356 0357 // No check for fSwapBytes 0358 0359 return x; 0360 0361 } 0362 #endif 0363 0364 /// Put an unsigned 32-bit integer to stream and advance write position. 0365 /// Byte swap if byte swapping is turned on. 0366 /// \param x One unsigned 32-bit integer. 0367 0368 void Put_uint32 (uint32 x); 0369 0370 /// Get an unsigned 64-bit integer from stream and advance read position. 0371 /// Byte swap if byte swapping is turned on. 0372 /// \retval One unsigned 64-bit integer. 0373 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0374 /// if not enough data in stream. 0375 0376 uint64 Get_uint64 (); 0377 0378 /// Put an unsigned 64-bit integer to stream and advance write position. 0379 /// Byte swap if byte swapping is turned on. 0380 /// \param x One unsigned 64-bit integer. 0381 0382 void Put_uint64 (uint64 x); 0383 0384 /// Get one 8-bit integer from stream and advance read position. 0385 /// \retval One 8-bit integer. 0386 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0387 /// if not enough data in stream. 0388 0389 int8 Get_int8 () 0390 { 0391 return (int8) Get_uint8 (); 0392 } 0393 0394 /// Put one 8-bit integer to stream and advance write position. 0395 /// \param x One 8-bit integer. 0396 0397 void Put_int8 (int8 x) 0398 { 0399 Put_uint8 ((uint8) x); 0400 } 0401 0402 /// Get one 16-bit integer from stream and advance read position. 0403 /// Byte swap if byte swapping is turned on. 0404 /// \retval One 16-bit integer. 0405 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0406 /// if not enough data in stream. 0407 0408 int16 Get_int16 () 0409 { 0410 return (int16) Get_uint16 (); 0411 } 0412 0413 /// Put one 16-bit integer to stream and advance write position. 0414 /// Byte swap if byte swapping is turned on. 0415 /// \param x One 16-bit integer. 0416 0417 void Put_int16 (int16 x) 0418 { 0419 Put_uint16 ((uint16) x); 0420 } 0421 0422 /// Get one 32-bit integer from stream and advance read position. 0423 /// Byte swap if byte swapping is turned on. 0424 /// \retval One 32-bit integer. 0425 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0426 /// if not enough data in stream. 0427 0428 int32 Get_int32 () 0429 { 0430 return (int32) Get_uint32 (); 0431 } 0432 0433 /// Put one 32-bit integer to stream and advance write position. 0434 /// Byte swap if byte swapping is turned on. 0435 /// \param x One 32-bit integer. 0436 0437 void Put_int32 (int32 x) 0438 { 0439 Put_uint32 ((uint32) x); 0440 } 0441 0442 /// Get one 64-bit integer from stream and advance read position. 0443 /// Byte swap if byte swapping is turned on. 0444 /// \retval One 64-bit integer. 0445 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0446 /// if not enough data in stream. 0447 0448 int64 Get_int64 () 0449 { 0450 return (int64) Get_uint64 (); 0451 } 0452 0453 /// Put one 64-bit integer to stream and advance write position. 0454 /// Byte swap if byte swapping is turned on. 0455 /// \param x One 64-bit integer. 0456 0457 void Put_int64 (int64 x) 0458 { 0459 Put_uint64 ((uint64) x); 0460 } 0461 0462 /// Get one 32-bit IEEE floating-point number from stream and advance 0463 /// read position. Byte swap if byte swapping is turned on. 0464 /// \retval One 32-bit IEEE floating-point number. 0465 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0466 /// if not enough data in stream. 0467 0468 real32 Get_real32 (); 0469 0470 /// Put one 32-bit IEEE floating-point number to stream and advance write 0471 /// position. Byte swap if byte swapping is turned on. 0472 /// \param x One 32-bit IEEE floating-point number. 0473 0474 void Put_real32 (real32 x); 0475 0476 /// Get one 64-bit IEEE floating-point number from stream and advance 0477 /// read position. Byte swap if byte swapping is turned on. 0478 /// \retval One 64-bit IEEE floating-point number . 0479 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0480 /// if not enough data in stream. 0481 0482 real64 Get_real64 (); 0483 0484 /// Put one 64-bit IEEE floating-point number to stream and advance write 0485 /// position. Byte swap if byte swapping is turned on. 0486 /// \param x One64-bit IEEE floating-point number. 0487 0488 void Put_real64 (real64 x); 0489 0490 /// Get an 8-bit character string from stream and advance read position. 0491 /// Routine always reads until a NUL character (8-bits of zero) is read. 0492 /// (That is, only maxLength bytes will be returned in buffer, but the 0493 /// stream is always advanced until a NUL is read or EOF is reached.) 0494 /// \param data Buffer in which string is returned. 0495 /// \param maxLength Maximum number of bytes to place in buffer. 0496 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0497 /// if stream runs out before NUL is seen. 0498 0499 void Get_CString (char *data, 0500 uint32 maxLength); 0501 0502 /// Get a 16-bit character string from stream and advance read position. 0503 /// 16-bit characters are truncated to 8-bits. 0504 /// Routine always reads until a NUL character (16-bits of zero) is read. 0505 /// (That is, only maxLength bytes will be returned in buffer, but the 0506 /// stream is always advanced until a NUL is read or EOF is reached.) 0507 /// \param data Buffer to place string in. 0508 /// \param maxLength Maximum number of bytes to place in buffer. 0509 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0510 /// if stream runs out before NUL is seen. 0511 0512 void Get_UString (char *data, 0513 uint32 maxLength); 0514 0515 /// Writes the specified number of zero bytes to stream. 0516 /// \param count Number of zero bytes to write. 0517 0518 void PutZeros (uint64 count); 0519 0520 /// Writes zeros to align the stream position to a multiple of 2. 0521 0522 void PadAlign2 (); 0523 0524 /// Writes zeros to align the stream position to a multiple of 4. 0525 0526 void PadAlign4 (); 0527 0528 /// Get a value of size indicated by tag type from stream and advance 0529 /// read position. Byte swap if byte swapping is turned on and tag type 0530 /// is larger than a byte. Value is returned as an unsigned 32-bit integer. 0531 /// \param tagType Tag type of data stored in stream. 0532 /// \retval One unsigned 32-bit integer. 0533 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0534 /// if not enough data in stream. 0535 0536 uint32 TagValue_uint32 (uint32 tagType); 0537 0538 /// Get a value of size indicated by tag type from stream and advance read 0539 /// position. Byte swap if byte swapping is turned on and tag type is larger 0540 /// than a byte. Value is returned as a 32-bit integer. 0541 /// \param tagType Tag type of data stored in stream. 0542 /// \retval One 32-bit integer. 0543 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0544 /// if not enough data in stream. 0545 0546 int32 TagValue_int32 (uint32 tagType); 0547 0548 /// Get a value of size indicated by tag type from stream and advance read 0549 /// position. Byte swap if byte swapping is turned on and tag type is larger 0550 /// than a byte. Value is returned as a dng_urational. 0551 /// \param tagType Tag type of data stored in stream. 0552 /// \retval One dng_urational. 0553 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0554 /// if not enough data in stream. 0555 0556 dng_urational TagValue_urational (uint32 tagType); 0557 0558 /// Get a value of size indicated by tag type from stream and advance read 0559 /// position. Byte swap if byte swapping is turned on and tag type is larger 0560 /// than a byte. Value is returned as a dng_srational. 0561 /// \param tagType Tag type of data stored in stream. 0562 /// \retval One dng_srational. 0563 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0564 /// if not enough data in stream. 0565 0566 dng_srational TagValue_srational (uint32 tagType); 0567 0568 /// Get a value of size indicated by tag type from stream and advance read 0569 /// position. Byte swap if byte swapping is turned on and tag type is larger 0570 /// than a byte. Value is returned as a 64-bit IEEE floating-point number. 0571 /// \param tagType Tag type of data stored in stream. 0572 /// \retval One 64-bit IEEE floating-point number. 0573 /// \exception dng_exception with fErrorCode equal to dng_error_end_of_file 0574 /// if not enough data in stream. 0575 0576 real64 TagValue_real64 (uint32 tagType); 0577 0578 /// Getter for sniffer associated with stream. 0579 /// \retval The sniffer for this stream. 0580 0581 dng_abort_sniffer * Sniffer () const 0582 { 0583 return fSniffer; 0584 } 0585 0586 /// Putter for sniffer associated with stream. 0587 /// \param sniffer The new sniffer to use (or NULL for none). 0588 0589 void SetSniffer (dng_abort_sniffer *sniffer) 0590 { 0591 fSniffer = sniffer; 0592 } 0593 0594 /// Copy a specified number of bytes to a target stream. 0595 /// \param dstStream The target stream. 0596 /// \param count The number of bytes to copy. 0597 0598 virtual void CopyToStream (dng_stream &dstStream, 0599 uint64 count); 0600 0601 /// Makes the target stream a copy of this stream. 0602 /// \param dstStream The target stream. 0603 0604 void DuplicateStream (dng_stream &dstStream); 0605 0606 }; 0607 0608 /*****************************************************************************/ 0609 0610 class dng_stream_double_buffered : public dng_stream 0611 { 0612 0613 private: 0614 0615 dng_stream &fStream; 0616 0617 public: 0618 0619 dng_stream_double_buffered (dng_stream &stream, 0620 uint32 bufferSize = kDefaultBufferSize) 0621 0622 : dng_stream ((dng_abort_sniffer *) NULL, 0623 bufferSize, 0624 stream.OffsetInOriginalFile ()) 0625 0626 , fStream (stream) 0627 0628 { 0629 SetBigEndian (fStream.BigEndian ()); 0630 } 0631 0632 protected: 0633 0634 virtual uint64 DoGetLength () 0635 { 0636 return fStream.Length (); 0637 } 0638 0639 virtual void DoRead (void *data, 0640 uint32 count, 0641 uint64 offset) 0642 { 0643 fStream.SetReadPosition (offset); 0644 fStream.Get (data, count); 0645 } 0646 0647 }; 0648 0649 /*****************************************************************************/ 0650 0651 class dng_stream_contiguous_read_hint 0652 { 0653 0654 private: 0655 0656 dng_stream &fStream; 0657 0658 dng_memory_allocator &fAllocator; 0659 0660 uint32 fOldBufferSize; 0661 0662 public: 0663 0664 dng_stream_contiguous_read_hint (dng_stream &stream, 0665 dng_memory_allocator &allocator, 0666 uint64 offset, 0667 uint64 count); 0668 0669 ~dng_stream_contiguous_read_hint (); 0670 0671 }; 0672 0673 /*****************************************************************************/ 0674 0675 class TempBigEndian 0676 { 0677 0678 private: 0679 0680 dng_stream & fStream; 0681 0682 bool fOldSwap; 0683 0684 public: 0685 0686 TempBigEndian (dng_stream &stream, 0687 bool bigEndian = true); 0688 0689 virtual ~TempBigEndian (); 0690 0691 }; 0692 0693 /*****************************************************************************/ 0694 0695 class TempLittleEndian: public TempBigEndian 0696 { 0697 0698 public: 0699 0700 TempLittleEndian (dng_stream &stream, 0701 bool littleEndian = true) 0702 0703 : TempBigEndian (stream, !littleEndian) 0704 0705 { 0706 } 0707 0708 virtual ~TempLittleEndian () 0709 { 0710 } 0711 0712 }; 0713 0714 /*****************************************************************************/ 0715 0716 class TempStreamSniffer: private dng_uncopyable 0717 { 0718 0719 private: 0720 0721 dng_stream & fStream; 0722 0723 dng_abort_sniffer *fOldSniffer; 0724 0725 public: 0726 0727 TempStreamSniffer (dng_stream &stream, 0728 dng_abort_sniffer *sniffer); 0729 0730 ~TempStreamSniffer (); 0731 0732 }; 0733 0734 /*****************************************************************************/ 0735 0736 class PreserveStreamReadPosition: private dng_uncopyable 0737 { 0738 0739 private: 0740 0741 dng_stream & fStream; 0742 0743 uint64 fPosition; 0744 0745 public: 0746 0747 PreserveStreamReadPosition (dng_stream &stream) 0748 0749 : fStream (stream) 0750 , fPosition (stream.Position ()) 0751 0752 { 0753 } 0754 0755 ~PreserveStreamReadPosition () 0756 { 0757 fStream.SetReadPosition (fPosition); 0758 } 0759 0760 }; 0761 0762 /*****************************************************************************/ 0763 0764 #endif 0765 0766 /*****************************************************************************/