summaryrefslogtreecommitdiff
path: root/includes/image_io/jpeg/jpeg_info_builder.h
blob: ee4d6114cbde0bc4706c656fcaa5f3ec523d5470 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#ifndef IMAGE_IO_JPEG_JPEG_INFO_BUILDER_H_  // NOLINT
#define IMAGE_IO_JPEG_JPEG_INFO_BUILDER_H_  // NOLINT

#include <set>
#include <string>
#include <vector>

#include "image_io/base/data_range.h"
#include "image_io/jpeg/jpeg_info.h"
#include "image_io/jpeg/jpeg_segment_processor.h"
#include "image_io/jpeg/jpeg_xmp_info_builder.h"

namespace photos_editing_formats {
namespace image_io {

/// JpegInfoBuilder is JpegSegmentProcessor that collects the location and type
/// of depth information in the JPEG file so that subsequent operations can
/// efficiently maniuplate it.
class JpegInfoBuilder : public JpegSegmentProcessor {
 public:
  JpegInfoBuilder();

  /// @return The JpegInfo with the depth information obtained from the
  ///     scanner as a result of processing the segments it processes.
  const JpegInfo& GetInfo() const { return jpeg_info_; }

  /// @param image_limit The max number of images to process. By default there
  ///     is no limit on the number of images processed.
  void SetImageLimit(int image_limit) { image_limit_ = image_limit; }

  /// By default the info builder does not capture the value of the segment in
  /// the segment infos contained in the @c JpegInfo object. Call this function
  /// to capture the bytes of the indicated segment types.
  /// @param type The type of segment info to capture the value of.
  void SetCaptureSegmentBytes(const std::string& segment_info_type);

  void Start(JpegScanner* scanner) override;
  void Process(JpegScanner* scanner, const JpegSegment& segment) override;
  void Finish(JpegScanner* scanner) override;

 private:
  /// @return True if the data members indicate Apple depth is present.
  bool HasAppleDepth() const;

  /// @return True if the data members indicate Apple matte is present.
  bool HasAppleMatte() const;

  /// @return True if the segment is a primary Xmp segment.
  bool IsPrimaryXmpSegment(const JpegSegment& segment) const;

  /// @return True if the segment is an extended Xmp segment.
  bool IsExtendedXmpSegment(const JpegSegment& segment) const;

  /// @return True if the segment is an Mpf segment.
  bool IsMpfSegment(const JpegSegment& segment) const;

  /// @return True if the segment is an Exif segment.
  bool IsExifSegment(const JpegSegment& segment) const;

  /// @return True if the segment is an Jfif segment.
  bool IsJfifSegment(const JpegSegment& segment) const;

  /// Captures the segment bytes into the a JpegSegmentInfo's byte vector if
  /// the SetCaptureSegmentBytes() has been called for the segment info type.
  /// @param type The type of segment info being processed.
  /// @param segment The segment being processed.
  /// @param bytes A vector to hold the segment bytes.
  void MaybeCaptureSegmentBytes(const std::string& type,
                                const JpegSegment& segment,
                                std::vector<Byte>* bytes) const;

  /// @return True if the segment's extended xmp guid matches the one from the
  ///     primary xmp segment.
  bool HasMatchingExtendedXmpGuid(const JpegSegment& segment) const;

  /// @return True if the segment contains the given id.
  bool HasId(const JpegSegment& segment, const char* id) const;

  /// Sets the primary segment guid value using properties in the given segment.
  /// @param The segment from which to obtain the primary xmp guid value.
  void SetPrimaryXmpGuid(const JpegSegment& segment);

  /// Sets the Xmp mime type using property values in the given segment.
  /// @param The segment from which to obtain the mime property value.
  /// @param xmp_info_type The type of xmp data that determines the mime
  ///     property name to look for.
  void SetXmpMimeType(const JpegSegment& segment,
                      JpegXmpInfo::Type xmp_info_type);

  /// The limit on the number of images to process. After this many images have
  /// been found, the Process() function will tell the JpegScanner to stop.
  int image_limit_;

  /// The number of images encountered in the JPEG file so far.
  int image_count_;

  /// The number of APP2/MPF segments encountered per image. One criterial used
  /// to determine if Apple depth data is present is that the first image has
  /// an APP2/MPF segment.
  std::vector<int> image_mpf_count_;

  /// The number of APP1/XMP segments encountered per image. Another criteria
  /// used to determine if Apple depth data is present is that the second or
  /// following image contains one of these segments.
  std::vector<int> image_xmp_apple_depth_count_;

  /// The number of APP1/XMP segments encountered per image. Another criteria
  /// used to determine if Apple matte data is present is that the second or
  /// following image contains one of these segments.
  std::vector<int> image_xmp_apple_matte_count_;

  /// The DataRange of the most recent SOI type segment. This is used to compute
  /// the range of the image that represents the Apple depth data.
  DataRange most_recent_soi_marker_range_;

  /// The GUID value of the APP1/XMP segments that contain GDepth/GImage data.
  std::string primary_xmp_guid_;

  /// Builder helpers for gdepth and gimage xmp type segments.
  JpegXmpInfoBuilder gdepth_info_builder_;
  JpegXmpInfoBuilder gimage_info_builder_;

  /// The collected data describing the type/location of data in the JPEG file.
  JpegInfo jpeg_info_;

  /// The types of the segment info type to capture the bytes of.
  std::set<std::string> capture_segment_bytes_types_;
};

}  // namespace image_io
}  // namespace photos_editing_formats

#endif // IMAGE_IO_JPEG_JPEG_INFO_BUILDER_H_  // NOLINT