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