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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
media / parsers / jpeg_parser.h [blame]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_PARSERS_JPEG_PARSER_H_
#define MEDIA_PARSERS_JPEG_PARSER_H_
#include <stddef.h>
#include <stdint.h>
#include "base/containers/span.h"
#include "media/base/media_export.h"
namespace media {
// It's not a full featured JPEG parser implementation. It only parses JPEG
// baseline sequential process (invalid or progressive JPEGs should fail but not
// crash). For explanations of each struct and its members, see JPEG
// specification at http://www.w3.org/Graphics/JPEG/itu-t81.pdf.
enum JpegMarker {
JPEG_SOF0 = 0xC0, // start of frame (baseline)
JPEG_SOF1 = 0xC1, // start of frame (extended sequential)
JPEG_SOF2 = 0xC2, // start of frame (progressive)
JPEG_SOF3 = 0xC3, // start of frame (lossless))
JPEG_DHT = 0xC4, // define huffman table
JPEG_SOF5 = 0xC5, // start of frame (differential, sequential)
JPEG_SOF6 = 0xC6, // start of frame (differential, progressive)
JPEG_SOF7 = 0xC7, // start of frame (differential, lossless)
JPEG_SOF9 = 0xC9, // start of frame (arithmetic coding, extended)
JPEG_SOF10 = 0xCA, // start of frame (arithmetic coding, progressive)
JPEG_SOF11 = 0xCB, // start of frame (arithmetic coding, lossless)
JPEG_SOF13 = 0xCD, // start of frame (differential, arithmetic, sequential)
JPEG_SOF14 = 0xCE, // start of frame (differential, arithmetic, progressive)
JPEG_SOF15 = 0xCF, // start of frame (differential, arithmetic, lossless)
JPEG_RST0 = 0xD0, // restart
JPEG_RST1 = 0xD1, // restart
JPEG_RST2 = 0xD2, // restart
JPEG_RST3 = 0xD3, // restart
JPEG_RST4 = 0xD4, // restart
JPEG_RST5 = 0xD5, // restart
JPEG_RST6 = 0xD6, // restart
JPEG_RST7 = 0xD7, // restart
JPEG_SOI = 0xD8, // start of image
JPEG_EOI = 0xD9, // end of image
JPEG_SOS = 0xDA, // start of scan
JPEG_DQT = 0xDB, // define quantization table
JPEG_DRI = 0xDD, // define restart internal
JPEG_APP0 = 0xE0, // start of application segment (APP0)
JPEG_APP1 = 0xE1, // start of application segment (APP1)
JPEG_MARKER_PREFIX = 0xFF, // jpeg marker prefix
};
// JPEG format uses 2 bytes to denote the size of a segment, and the size
// includes the 2 bytes used for specifying it. Therefore, maximum data size
// allowed is: 65535 - 2 = 65533.
constexpr size_t kMaxMarkerSizeAllowed = 65533;
// JPEG header only uses 2 bytes to represent width and height.
constexpr int kMaxDimension = 65535;
constexpr size_t kDctSize = 64;
constexpr size_t kNumDcRunSizeBits = 16;
constexpr size_t kNumAcRunSizeBits = 16;
constexpr size_t kNumDcCodeWordsHuffVal = 12;
constexpr size_t kNumAcCodeWordsHuffVal = 162;
constexpr size_t kJpegDefaultHeaderSize =
67 + (kDctSize * 2) + (kNumDcRunSizeBits * 2) +
(kNumDcCodeWordsHuffVal * 2) + (kNumAcRunSizeBits * 2) +
(kNumAcCodeWordsHuffVal * 2);
constexpr size_t kJFIFApp0Size = 16;
constexpr size_t kJFIFApp1HeaderSize = 4;
const size_t kJpegMaxHuffmanTableNumBaseline = 2;
const size_t kJpegMaxComponents = 4;
const size_t kJpegMaxQuantizationTableNum = 4;
// Parsing result of JPEG DHT marker.
struct JpegHuffmanTable {
bool valid;
uint8_t code_length[16];
uint8_t code_value[162];
};
// K.3.3.1 "Specification of typical tables for DC difference coding"
MEDIA_EXPORT
extern const JpegHuffmanTable kDefaultDcTable[kJpegMaxHuffmanTableNumBaseline];
// K.3.3.2 "Specification of typical tables for AC coefficient coding"
MEDIA_EXPORT
extern const JpegHuffmanTable kDefaultAcTable[kJpegMaxHuffmanTableNumBaseline];
// Parsing result of JPEG DQT marker.
struct JpegQuantizationTable {
bool valid;
uint8_t value[kDctSize]; // baseline only supports 8 bits quantization table
};
MEDIA_EXPORT extern const uint8_t kZigZag8x8[64];
// Table K.1 Luminance quantization table
// Table K.2 Chrominance quantization table
MEDIA_EXPORT
extern const JpegQuantizationTable kDefaultQuantTable[2];
// Parsing result of a JPEG component.
struct JpegComponent {
uint8_t id;
uint8_t horizontal_sampling_factor;
uint8_t vertical_sampling_factor;
uint8_t quantization_table_selector;
};
// Parsing result of a JPEG SOF marker.
struct JpegFrameHeader {
uint16_t visible_width;
uint16_t visible_height;
uint16_t coded_width;
uint16_t coded_height;
uint8_t num_components;
JpegComponent components[kJpegMaxComponents];
};
// Parsing result of JPEG SOS marker.
struct JpegScanHeader {
uint8_t num_components;
struct Component {
uint8_t component_selector;
uint8_t dc_selector;
uint8_t ac_selector;
} components[kJpegMaxComponents];
};
struct JpegParseResult {
JpegFrameHeader frame_header;
JpegHuffmanTable dc_table[kJpegMaxHuffmanTableNumBaseline];
JpegHuffmanTable ac_table[kJpegMaxHuffmanTableNumBaseline];
JpegQuantizationTable q_table[kJpegMaxQuantizationTableNum];
uint16_t restart_interval;
JpegScanHeader scan;
const char* data;
// The size of compressed data of the first image.
size_t data_size;
// The size of the first entire image including header.
size_t image_size;
};
// Parses JPEG picture in |buffer| with |length|. Returns true iff header is
// valid and JPEG baseline sequential process is present. If parsed
// successfully, |result| is the parsed result.
MEDIA_EXPORT
bool ParseJpegPicture(base::span<const uint8_t> buffer,
JpegParseResult* result);
// Parses the first image of JPEG stream in |buffer| with |length|. Returns
// true iff header is valid and JPEG baseline sequential process is present.
// If parsed successfully, |result| is the parsed result.
MEDIA_EXPORT
bool ParseJpegStream(base::span<const uint8_t> buffer, JpegParseResult* result);
} // namespace media
#endif // MEDIA_PARSERS_JPEG_PARSER_H_