Coverage Report

Created: 2026-01-10 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dng_sdk/source/dng_stream.h
Line
Count
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
3.85M
      {
120
3.85M
      return fSwapBytes;
121
3.85M
      }
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
2.51M
      {
129
2.51M
      fSwapBytes = swapBytes;
130
2.51M
      }
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
9.48M
      {
147
9.48M
      return !BigEndian ();
148
9.48M
      }
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
92.6k
      {
155
92.6k
      SetBigEndian (!littleEndian);
156
92.6k
      }
157
      
158
    /// Returns the size of the buffer used by the stream.
159
    
160
    uint32 BufferSize () const
161
0
      {
162
0
      return fBufferSize;
163
0
      }
164
165
    /// Getter for length of data in stream.
166
    /// \retval Length of readable data in stream.
167
      
168
    uint64 Length ()
169
1.12G
      {
170
      
171
1.12G
      if (!fHaveLength)
172
224k
        {
173
        
174
224k
        fLength = DoGetLength ();
175
        
176
224k
        fHaveLength = true;
177
        
178
224k
        }
179
        
180
1.12G
      return fLength;
181
      
182
1.12G
      }
183
184
    /// Getter for current offset in stream.
185
    /// \retval current offset from start of stream.
186
187
    uint64 Position () const
188
143M
      {
189
143M
      return fPosition;
190
143M
      }
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
763k
      {
225
763k
      SetReadPosition (Position () + delta);
226
763k
      }
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
272M
      {
263
      
264
      // Fast check to see if in buffer
265
      
266
272M
      if (fPosition >= fBufferStart && fPosition < fBufferEnd)
267
267M
        {
268
        
269
267M
        return fBuffer [fPosition++ - fBufferStart];
270
        
271
267M
        }
272
        
273
      // Not in buffer, let main routine do the work.
274
      
275
5.10M
      uint8 x;
276
      
277
5.10M
      Get (&x, 1);
278
      
279
5.10M
      return x;
280
        
281
272M
      }
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
783M
      {
288
      
289
783M
      if (fBufferDirty               &&
290
783M
          fPosition  >= fBufferStart &&
291
783M
        fPosition  <= fBufferEnd   &&
292
783M
        fPosition  <  fBufferLimit)
293
782M
        {
294
        
295
782M
        fBuffer [fPosition - fBufferStart] = x;
296
        
297
782M
        fPosition++;
298
        
299
782M
        if (fBufferEnd < fPosition)
300
782M
          fBufferEnd = fPosition;
301
          
302
782M
        fLength = Max_uint64 (Length (), fPosition);
303
        
304
782M
        }
305
        
306
199k
      else
307
199k
        {
308
        
309
199k
        Put (&x, 1);
310
        
311
199k
        }
312
  
313
783M
      }
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
3.25M
      {
364
3.25M
      return (int8) Get_uint8 ();
365
3.25M
      }
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
0
      {
372
0
      Put_uint8 ((uint8) x);
373
0
      }
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
693k
      {
383
693k
      return (int16) Get_uint16 ();
384
693k
      }
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
0
      {
392
0
      Put_uint16 ((uint16) x);
393
0
      }
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
26.3M
      {
403
26.3M
      return (int32) Get_uint32 ();
404
26.3M
      }
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
56.4k
      {
412
56.4k
      Put_uint32 ((uint32) x);
413
56.4k
      }
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
0
      {
423
0
      return (int64) Get_uint64 ();
424
0
      }
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
0
      {
432
0
      Put_uint64 ((uint64) x);
433
0
      }
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
0
      {
556
0
      return fSniffer;
557
0
      }
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
0
      {
564
0
      fSniffer = sniffer;
565
0
      }
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
394
      : TempBigEndian (stream, !littleEndian)
620
      
621
394
      {
622
394
      }
623
  
624
    virtual ~TempLittleEndian ()
625
0
      {
626
0
      }
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
0
      {
677
0
      }
678
      
679
    ~PreserveStreamReadPosition ()
680
0
      {
681
0
      fStream.SetReadPosition (fPosition);
682
0
      }
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
/*****************************************************************************/