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 /*****************************************************************************/