1 #ifndef IMAGE_IO_JPEG_JPEG_SCANNER_H_  // NOLINT
2 #define IMAGE_IO_JPEG_JPEG_SCANNER_H_  // NOLINT
3 
4 #include <memory>
5 
6 #include "image_io/base/data_segment.h"
7 #include "image_io/base/data_source.h"
8 #include "image_io/base/message_handler.h"
9 #include "image_io/jpeg/jpeg_marker.h"
10 #include "image_io/jpeg/jpeg_segment_processor.h"
11 
12 namespace photos_editing_formats {
13 namespace image_io {
14 
15 /// JpegScanner reads DataSegments from a DataSource, finds interesting
16 /// JpegSegments and passes them on to a JpegSegmentProcessor for further
17 /// examination.
18 class JpegScanner {
19  public:
JpegScanner(MessageHandler * message_handler)20   explicit JpegScanner(MessageHandler* message_handler)
21       : message_handler_(message_handler),
22         data_source_(nullptr),
23         segment_processor_(nullptr),
24         current_location_(0),
25         done_(false),
26         has_error_(false) {}
27 
28   /// Called to start and run the scanner.
29   /// @param data_source The DataSource from which to obtain DataSegments.
30   /// @param segment_processor The processor of the JpegSegment instances.
31   void Run(DataSource* data_source, JpegSegmentProcessor* segment_processor);
32 
33   /// If the JpegSegmentProcessor determines that it has seen enough JpegSegment
34   /// instances, it can call this function to terminate the scanner prematurely.
SetDone()35   void SetDone() { done_ = true; }
36 
37   /// @return True if the done flag was set by SetDone(), else false.
IsDone()38   bool IsDone() const { return done_; }
39 
40   /// @return True if the scanner encountered errors.
HasError()41   bool HasError() const { return has_error_; }
42 
43   /// @return The DataSource from which DataSegments are being read.
GetDataSource()44   DataSource* GetDataSource() const { return data_source_; }
45 
46   /// JpegSegmentProcessor instances can call this function to inform the
47   /// scanner about the types of JpegSegment instances it is interested in.
48   /// The JpegScanner will not send any uninteresting segments to the processor.
UpdateInterestingMarkerFlags(const JpegMarker::Flags & marker_flags)49   void UpdateInterestingMarkerFlags(const JpegMarker::Flags& marker_flags) {
50     interesting_marker_flags_ = marker_flags;
51   }
52 
53  private:
54   /// Called from the Run() function to do the heavy lifting.
55   void FindAndProcessSegments();
56 
57   /// @param marker The marker of the JpegSegment under construction.
58   /// @param begin_location The start of the JpegSegment under construction.
59   /// @return The size of the segment payload of given marker type that starts
60   ///     at the specified location.
61   size_t GetPayloadSize(const JpegMarker& marker, size_t begin_location);
62 
63   /// @return The validated byte value at the given location.
64   ValidatedByte GetValidatedByte(size_t location);
65 
66   /// Calls GetValidatedByte() and returns its value if the byte is valid, else
67   /// sets the get_byte_error_ flag.
68   /// @return the byte value at the given location, or 0 if the byte is invalid.
69   Byte GetByte(size_t location);
70 
71   /// Asks the DataSource for the next DataSegment.
72   void GetNextSegment();
73 
74  private:
75   /// An optional message handler to write messages to.
76   MessageHandler* message_handler_;
77 
78   /// The DataSource from which DataSegments are obtained.
79   DataSource* data_source_;
80 
81   /// The JpegSegmentProcessor to which JpegSegments are sent.
82   JpegSegmentProcessor* segment_processor_;
83 
84   /// The JpegSegment types of interest to the JpegSegmentProcessor.
85   JpegMarker::Flags interesting_marker_flags_;
86 
87   /// Depending on the DataSource, a given JpegSegment may span up to two
88   /// DataSegments. These are they.
89   std::shared_ptr<DataSegment> current_segment_;
90   std::shared_ptr<DataSegment> next_segment_;
91 
92   /// The current location of the scanner  in the DataSource.
93   size_t current_location_;
94 
95   /// A flag that indicates the scanner is done, naturally or prematurely.
96   bool done_;
97 
98   /// A flag that indicates an error occurred while getting Byte data.
99   bool has_error_;
100 };
101 
102 }  // namespace image_io
103 }  // namespace photos_editing_formats
104 
105 #endif // IMAGE_IO_JPEG_JPEG_SCANNER_H_  // NOLINT
106