1 #ifndef IMAGE_IO_JPEG_JPEG_MARKER_H_ // NOLINT 2 #define IMAGE_IO_JPEG_JPEG_MARKER_H_ // NOLINT 3 4 #include <bitset> 5 #include <string> 6 7 #include "image_io/base/types.h" 8 9 namespace photos_editing_formats { 10 namespace image_io { 11 12 /// The size of the array that would be needed to reference all marker types. 13 const size_t kJpegMarkerArraySize = 256; 14 15 /// A JpegMarker begins each JpegSegment in a JPEG file. The first byte of a 16 /// marker is 0xFF, and the second byte is the marker type value. Bytes with 17 /// values 0x00 and 0xFF indicate not a JpegMarker, but a zero byte or fill 18 /// byte, respectively. That is the sequence FF00 must be interpreted as a 19 /// single byte with a 0 value. The specification says that multiple fill bytes 20 /// may appear before a valid marker start: FFFFFFDA - the leading FFFF should 21 /// be ignored. 22 class JpegMarker { 23 public: 24 /// The length of the marker in the JPEG file. One byte for the 0xFF value, 25 /// and one byte for the marker type. 26 static const size_t kLength = 2; 27 28 /// The offset from the start of the JpegMarker that contains the marker type. 29 static const size_t kTypeOffset = 1; 30 31 /// The special byte value that may start a marker. 32 static const Byte kStart = 0xFF; 33 34 /// Special marker type values referenced elsewhere in the code. 35 static const Byte kZERO = 0; 36 static const Byte kSOS = 0xDA; 37 static const Byte kSOI = 0xD8; 38 static const Byte kEOI = 0xD9; 39 static const Byte kAPP0 = 0xE0; 40 static const Byte kAPP1 = 0xE1; 41 static const Byte kAPP2 = 0xE2; 42 static const Byte kFILL = 0xFF; 43 44 /// A set of bits, one for each type of marker. 45 using Flags = std::bitset<kJpegMarkerArraySize>; 46 47 /// Creates a JpegMarker with the given type value. JpegMarker(Byte type)48 explicit JpegMarker(Byte type) : type_(type) {} 49 50 JpegMarker() = delete; 51 52 /// Not all byte values are used to represent markers. Bytes with values 0x00 53 /// and 0xFF indicate a zero byte or fill byte, respectively. 54 /// @return Whether this is a valid marker. IsValid()55 bool IsValid() const { return type_ != kZERO && type_ != kFILL; } 56 57 /// @return The type of the marker. GetType()58 Byte GetType() const { return type_; } 59 60 /// @return The name of the marker type. 61 const std::string GetName() const; 62 63 /// @param prefix A prefix for the returned string. 64 /// @return The <prefix>XX hex string representation of the type. 65 const std::string GetHexString(const std::string& prefix) const; 66 67 /// Some markers have two extra bytes that indicate the size of the segment's 68 /// data payload. See https://www.w3.org/Graphics/JPEG/itu-t81.pdf, Table B-2. 69 /// @return Whether this marker type has such a variable length payload. 70 bool HasVariablePayloadSize() const; 71 72 /// Some markers are delimiters in an otherwise continuous stream of bytes in 73 /// the JPEG file. See https://www.w3.org/Graphics/JPEG/itu-t81.pdf, Section 74 /// B.2.1. 75 /// @return Whether this is an entropy segment delimiter marker. 76 bool IsEntropySegmentDelimiter() const; 77 78 private: 79 /// The type value of the marker. 80 Byte type_; 81 }; 82 83 } // namespace image_io 84 } // namespace photos_editing_formats 85 86 #endif // IMAGE_IO_JPEG_JPEG_MARKER_H_ // NOLINT 87