blob: 507382dd250b78347d22c05fc34ba94e6633f424 [file] [log] [blame]
#ifndef IMAGE_IO_JPEG_JPEG_MARKER_H_ // NOLINT
#define IMAGE_IO_JPEG_JPEG_MARKER_H_ // NOLINT
#include <bitset>
#include <string>
#include "image_io/base/types.h"
namespace photos_editing_formats {
namespace image_io {
/// The size of the array that would be needed to reference all marker types.
const size_t kJpegMarkerArraySize = 256;
/// A JpegMarker begins each JpegSegment in a JPEG file. The first byte of a
/// marker is 0xFF, and the second byte is the marker type value. Bytes with
/// values 0x00 and 0xFF indicate not a JpegMarker, but a zero byte or fill
/// byte, respectively. That is the sequence FF00 must be interpreted as a
/// single byte with a 0 value. The specification says that multiple fill bytes
/// may appear before a valid marker start: FFFFFFDA - the leading FFFF should
/// be ignored.
class JpegMarker {
public:
/// The length of the marker in the JPEG file. One byte for the 0xFF value,
/// and one byte for the marker type.
static const size_t kLength = 2;
/// The offset from the start of the JpegMarker that contains the marker type.
static const size_t kTypeOffset = 1;
/// The special byte value that may start a marker.
static const Byte kStart = 0xFF;
/// Special marker type values referenced elsewhere in the code.
static const Byte kZERO = 0;
static const Byte kSOS = 0xDA;
static const Byte kSOI = 0xD8;
static const Byte kEOI = 0xD9;
static const Byte kAPP0 = 0xE0;
static const Byte kAPP1 = 0xE1;
static const Byte kAPP2 = 0xE2;
static const Byte kFILL = 0xFF;
/// A set of bits, one for each type of marker.
using Flags = std::bitset<kJpegMarkerArraySize>;
/// Creates a JpegMarker with the given type value.
explicit JpegMarker(Byte type) : type_(type) {}
JpegMarker() = delete;
/// Not all byte values are used to represent markers. Bytes with values 0x00
/// and 0xFF indicate a zero byte or fill byte, respectively.
/// @return Whether this is a valid marker.
bool IsValid() const { return type_ != kZERO && type_ != kFILL; }
/// @return The type of the marker.
Byte GetType() const { return type_; }
/// @return The name of the marker type.
const std::string GetName() const;
/// @param prefix A prefix for the returned string.
/// @return The <prefix>XX hex string representation of the type.
const std::string GetHexString(const std::string& prefix) const;
/// Some markers have two extra bytes that indicate the size of the segment's
/// data payload. See https://www.w3.org/Graphics/JPEG/itu-t81.pdf, Table B-2.
/// @return Whether this marker type has such a variable length payload.
bool HasVariablePayloadSize() const;
/// Some markers are delimiters in an otherwise continuous stream of bytes in
/// the JPEG file. See https://www.w3.org/Graphics/JPEG/itu-t81.pdf, Section
/// B.2.1.
/// @return Whether this is an entropy segment delimiter marker.
bool IsEntropySegmentDelimiter() const;
private:
/// The type value of the marker.
Byte type_;
};
} // namespace image_io
} // namespace photos_editing_formats
#endif // IMAGE_IO_JPEG_JPEG_MARKER_H_ // NOLINT