• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef IMAGE_IO_JPEG_JPEG_SEGMENT_BUILDER_H_  // NOLINT
2 #define IMAGE_IO_JPEG_JPEG_SEGMENT_BUILDER_H_  // NOLINT
3 
4 #include <string>
5 #include <vector>
6 
7 #include "image_io/base/byte_buffer.h"
8 #include "image_io/jpeg/jpeg_xmp_info.h"
9 
10 namespace photos_editing_formats {
11 namespace image_io {
12 
13 /// A helper to assemble the data in a JpegSegment. Currently this is only used
14 /// for testing purposes, but in the future may prove useful in the image_io
15 /// library itself.
16 class JpegSegmentBuilder {
17  public:
18   /// Sets the payload size value of the JpegSegment data in the byte buffer.
19   /// This function assumes that the byte buffer contains the data for exactly
20   /// one JpegSegment, and that the segment type has a variable payload size.
21   /// The byte buffer must have a size in the range [4:65535] for this to work.
22   /// @param byte_buffer The data defining the JpegSegment.
23   /// @return Whether the byte buffer's size was valid and the payload size set.
24   static bool SetPayloadSize(ByteBuffer* byte_buffer);
25 
26   /// @return The vector of ByteData.
GetByteData()27   const std::vector<ByteData>& GetByteData() const { return byte_data_; }
28 
29   /// @return The concatenated string values of all byte data, or an empty
30   ///     string if there are invalid byte data entries. Note that the string
31   ///     may have embedded null characters if there are any kAscii0 type
32   ///     byte data elements present.
33   std::string GetByteDataValues() const;
34 
35   /// Adds the byte data to the vector.
36   /// @param byte_data The byte data to add.
AddByteData(const ByteData & byte_data)37   void AddByteData(const ByteData& byte_data) {
38     byte_data_.push_back(byte_data);
39   }
40 
41   /// Adds a segment marker of the given type and payload size.
42   /// @param marker_type The type of segment marker to add.
43   /// @param size The size of the payload if the marker has a variable
44   ///     size payload. This value must be in the range [2:65535], although no
45   ///     check is performed to ensure that is the case.
46   void AddMarkerAndSize(Byte marker_type, size_t size);
47 
48   /// Adds a segment marker of the given type, and "0000" placeholder value if
49   /// the type has a variable payload size. The SetSizePlaceholder() function
50   /// can be called later to set the actual size of the segment.
51   /// @param marker_type The type of segment marker to add.
52   /// @return The index in the vector of ByteData where the marker was added.
53   size_t AddMarkerAndSizePlaceholder(Byte marker_type);
54 
55   /// Replacess the size of the segment marker that was previously added using
56   /// the AddMarkerAndSizePlaceholder() function. The first two bytes of the
57   /// ByteData at the given index must represent a valid JpegMarker that has
58   /// a variable length payload size.
59   /// @param index The index in the vector of ByteData set the size of.
60   /// @param size The size of the segment, including the size field itself.
61   ///     This value must be in the range [2:65535].
62   /// @return Whether the size was set successfully.
63   bool ReplaceSizePlaceholder(size_t index, size_t size);
64 
65   /// Adds the bytes that define an XMP header.
66   /// @param xmp_guid The guid value of the XMP data. If this value is not 32
67   ///     bytes long, it is either truncated or extended with 0s.
68   void AddExtendedXmpHeader(const std::string& xmp_guid);
69 
70   /// Adds the XMP syntax that appears at the start of an XMP segment. This
71   /// syntax appears after the XMP header in a segment, so this function should
72   /// be called after the AddExtendedXmpHeader() function.
73   void AddXmpMetaPrefix();
74 
75   /// Adds the XMP syntax that appears at the end of an XMP segment. This syntax
76   /// finishes the XMP data, so it should be the last function called when
77   /// assembling the data for such a segment.
78   void AddXmpMetaSuffix();
79 
80   /// Adds the RDF prefix that appears within the body of an XMP segment. This
81   /// syntax should be added before any XMP property names and values are added.
82   void AddRdfPrefix();
83 
84   /// Adds the RDF suffix that appears within the body of an XMP segment. This
85   /// syntax should be added after all XMP property names and values are added.
86   void AddRdfSuffix();
87 
88   /// Adds the RDF:Description prefix that appears within the body of an XMP
89   /// segment. This syntax should be added after the RDF prefix is added, but
90   /// before any XMP property names and values are added.
91   void AddRdfDescriptionPrefix();
92 
93   /// Adds the RDF:Description suffix that appears within the body of an XMP
94   /// segment. This syntax should be added after after all XMP property names
95   /// and values are added, but before the RDF syntax is added.
96   void AddRdfDescriptionSuffix();
97 
98   /// Adds the property name, and the '="' string that defines
99   /// the start of the name="value" string. After this call, you can
100   /// add the property value to the byte data vector, and then call the
101   /// AddXmpPropertySuffix() function to finish the definition.
102   /// @param property_name The name of the property to add.
103   void AddXmpPropertyPrefix(const std::string& property_name);
104 
105   /// Adds a final quote to finish off the definition of a name="value" string.
106   void AddXmpPropertySuffix();
107 
108   /// Adds the name="value" strings to define the XMP property name and value.
109   /// @param property_name The name of the property to add.
110   /// @param property_value The value of the property to add.
111   void AddXmpPropertyNameAndValue(const std::string& property_name,
112                                   const std::string& property_value);
113 
114   /// Adds segment marker and the extended XMP header for an APP1/XMP type
115   /// segment that as extended XMP data. After this call you can either all the
116   /// AddXmpAndRdfPrefixes() function (if this is the first extended segment, or
117   /// just continue adding the property value contained in this segment.
118   /// @param xmp_guid The guid value of the XMP data. If this value is not 32
119   ///     bytes long, it is either truncated or extended with 0s.
120   void AddApp1XmpMarkerAndXmpExtendedHeader(const std::string& xmp_guid);
121 
122   /// Adds segment marker and all the prefixes to start the xmpmeta/rdf section
123   /// of the segment. After this call property names and values can be added,
124   /// and optionally the section can be completed by calling the
125   /// AddXmpAndRdfSuffixes() function.
126   void AddXmpAndRdfPrefixes();
127 
128   /// Adds the suffixes to complete the definition of an APP1/XMP segment. Call
129   /// this function after the AddApp1XmpPrefixes() and after adding property
130   /// names and values to the byte data.
131   void AddXmpAndRdfSuffixes();
132 
133  private:
134   std::vector<ByteData> byte_data_;
135 };
136 
137 }  // namespace image_io
138 }  // namespace photos_editing_formats
139 
140 #endif // IMAGE_IO_JPEG_JPEG_SEGMENT_BUILDER_H_  // NOLINT
141