1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * V4L2 JPEG header parser helpers.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2019 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * For reference, see JPEG ITU-T.81 (ISO/IEC 10918-1) [1]
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * [1] https://www.w3.org/Graphics/JPEG/itu-t81.pdf
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <asm/unaligned.h>
13*4882a593Smuzhiyun #include <linux/errno.h>
14*4882a593Smuzhiyun #include <linux/kernel.h>
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/types.h>
17*4882a593Smuzhiyun #include <media/v4l2-jpeg.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun MODULE_DESCRIPTION("V4L2 JPEG header parser helpers");
20*4882a593Smuzhiyun MODULE_AUTHOR("Philipp Zabel <kernel@pengutronix.de>");
21*4882a593Smuzhiyun MODULE_LICENSE("GPL");
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun /* Table B.1 - Marker code assignments */
24*4882a593Smuzhiyun #define SOF0 0xffc0 /* start of frame */
25*4882a593Smuzhiyun #define SOF1 0xffc1
26*4882a593Smuzhiyun #define SOF2 0xffc2
27*4882a593Smuzhiyun #define SOF3 0xffc3
28*4882a593Smuzhiyun #define SOF5 0xffc5
29*4882a593Smuzhiyun #define SOF7 0xffc7
30*4882a593Smuzhiyun #define JPG 0xffc8 /* extensions */
31*4882a593Smuzhiyun #define SOF9 0xffc9
32*4882a593Smuzhiyun #define SOF11 0xffcb
33*4882a593Smuzhiyun #define SOF13 0xffcd
34*4882a593Smuzhiyun #define SOF15 0xffcf
35*4882a593Smuzhiyun #define DHT 0xffc4 /* huffman table */
36*4882a593Smuzhiyun #define DAC 0xffcc /* arithmetic coding conditioning */
37*4882a593Smuzhiyun #define RST0 0xffd0 /* restart */
38*4882a593Smuzhiyun #define RST7 0xffd7
39*4882a593Smuzhiyun #define SOI 0xffd8 /* start of image */
40*4882a593Smuzhiyun #define EOI 0xffd9 /* end of image */
41*4882a593Smuzhiyun #define SOS 0xffda /* start of stream */
42*4882a593Smuzhiyun #define DQT 0xffdb /* quantization table */
43*4882a593Smuzhiyun #define DNL 0xffdc /* number of lines */
44*4882a593Smuzhiyun #define DRI 0xffdd /* restart interval */
45*4882a593Smuzhiyun #define DHP 0xffde /* hierarchical progression */
46*4882a593Smuzhiyun #define EXP 0xffdf /* expand reference */
47*4882a593Smuzhiyun #define APP0 0xffe0 /* application data */
48*4882a593Smuzhiyun #define APP15 0xffef
49*4882a593Smuzhiyun #define JPG0 0xfff0 /* extensions */
50*4882a593Smuzhiyun #define JPG13 0xfffd
51*4882a593Smuzhiyun #define COM 0xfffe /* comment */
52*4882a593Smuzhiyun #define TEM 0xff01 /* temporary */
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun /**
55*4882a593Smuzhiyun * struct jpeg_stream - JPEG byte stream
56*4882a593Smuzhiyun * @curr: current position in stream
57*4882a593Smuzhiyun * @end: end position, after last byte
58*4882a593Smuzhiyun */
59*4882a593Smuzhiyun struct jpeg_stream {
60*4882a593Smuzhiyun u8 *curr;
61*4882a593Smuzhiyun u8 *end;
62*4882a593Smuzhiyun };
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /* returns a value that fits into u8, or negative error */
jpeg_get_byte(struct jpeg_stream * stream)65*4882a593Smuzhiyun static int jpeg_get_byte(struct jpeg_stream *stream)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun if (stream->curr >= stream->end)
68*4882a593Smuzhiyun return -EINVAL;
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun return *stream->curr++;
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun /* returns a value that fits into u16, or negative error */
jpeg_get_word_be(struct jpeg_stream * stream)74*4882a593Smuzhiyun static int jpeg_get_word_be(struct jpeg_stream *stream)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun u16 word;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun if (stream->curr + sizeof(__be16) > stream->end)
79*4882a593Smuzhiyun return -EINVAL;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun word = get_unaligned_be16(stream->curr);
82*4882a593Smuzhiyun stream->curr += sizeof(__be16);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun return word;
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun
jpeg_skip(struct jpeg_stream * stream,size_t len)87*4882a593Smuzhiyun static int jpeg_skip(struct jpeg_stream *stream, size_t len)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun if (stream->curr + len > stream->end)
90*4882a593Smuzhiyun return -EINVAL;
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun stream->curr += len;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun return 0;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun
jpeg_next_marker(struct jpeg_stream * stream)97*4882a593Smuzhiyun static int jpeg_next_marker(struct jpeg_stream *stream)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun int byte;
100*4882a593Smuzhiyun u16 marker = 0;
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun while ((byte = jpeg_get_byte(stream)) >= 0) {
103*4882a593Smuzhiyun marker = (marker << 8) | byte;
104*4882a593Smuzhiyun /* skip stuffing bytes and REServed markers */
105*4882a593Smuzhiyun if (marker == TEM || (marker > 0xffbf && marker < 0xffff))
106*4882a593Smuzhiyun return marker;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun return byte;
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun /* this does not advance the current position in the stream */
jpeg_reference_segment(struct jpeg_stream * stream,struct v4l2_jpeg_reference * segment)113*4882a593Smuzhiyun static int jpeg_reference_segment(struct jpeg_stream *stream,
114*4882a593Smuzhiyun struct v4l2_jpeg_reference *segment)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun u16 len;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun if (stream->curr + sizeof(__be16) > stream->end)
119*4882a593Smuzhiyun return -EINVAL;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun len = get_unaligned_be16(stream->curr);
122*4882a593Smuzhiyun if (stream->curr + len > stream->end)
123*4882a593Smuzhiyun return -EINVAL;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun segment->start = stream->curr;
126*4882a593Smuzhiyun segment->length = len;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun return 0;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
v4l2_jpeg_decode_subsampling(u8 nf,u8 h_v)131*4882a593Smuzhiyun static int v4l2_jpeg_decode_subsampling(u8 nf, u8 h_v)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun if (nf == 1)
134*4882a593Smuzhiyun return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun /* no chroma subsampling for 4-component images */
137*4882a593Smuzhiyun if (nf == 4 && h_v != 0x11)
138*4882a593Smuzhiyun return -EINVAL;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun switch (h_v) {
141*4882a593Smuzhiyun case 0x11:
142*4882a593Smuzhiyun return V4L2_JPEG_CHROMA_SUBSAMPLING_444;
143*4882a593Smuzhiyun case 0x21:
144*4882a593Smuzhiyun return V4L2_JPEG_CHROMA_SUBSAMPLING_422;
145*4882a593Smuzhiyun case 0x22:
146*4882a593Smuzhiyun return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
147*4882a593Smuzhiyun case 0x41:
148*4882a593Smuzhiyun return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
149*4882a593Smuzhiyun default:
150*4882a593Smuzhiyun return -EINVAL;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun
jpeg_parse_frame_header(struct jpeg_stream * stream,u16 sof_marker,struct v4l2_jpeg_frame_header * frame_header)154*4882a593Smuzhiyun static int jpeg_parse_frame_header(struct jpeg_stream *stream, u16 sof_marker,
155*4882a593Smuzhiyun struct v4l2_jpeg_frame_header *frame_header)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun int len = jpeg_get_word_be(stream);
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun if (len < 0)
160*4882a593Smuzhiyun return len;
161*4882a593Smuzhiyun /* Lf = 8 + 3 * Nf, Nf >= 1 */
162*4882a593Smuzhiyun if (len < 8 + 3)
163*4882a593Smuzhiyun return -EINVAL;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun if (frame_header) {
166*4882a593Smuzhiyun /* Table B.2 - Frame header parameter sizes and values */
167*4882a593Smuzhiyun int p, y, x, nf;
168*4882a593Smuzhiyun int i;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun p = jpeg_get_byte(stream);
171*4882a593Smuzhiyun if (p < 0)
172*4882a593Smuzhiyun return p;
173*4882a593Smuzhiyun /*
174*4882a593Smuzhiyun * Baseline DCT only supports 8-bit precision.
175*4882a593Smuzhiyun * Extended sequential DCT also supports 12-bit precision.
176*4882a593Smuzhiyun */
177*4882a593Smuzhiyun if (p != 8 && (p != 12 || sof_marker != SOF1))
178*4882a593Smuzhiyun return -EINVAL;
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun y = jpeg_get_word_be(stream);
181*4882a593Smuzhiyun if (y < 0)
182*4882a593Smuzhiyun return y;
183*4882a593Smuzhiyun if (y == 0)
184*4882a593Smuzhiyun return -EINVAL;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun x = jpeg_get_word_be(stream);
187*4882a593Smuzhiyun if (x < 0)
188*4882a593Smuzhiyun return x;
189*4882a593Smuzhiyun if (x == 0)
190*4882a593Smuzhiyun return -EINVAL;
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun nf = jpeg_get_byte(stream);
193*4882a593Smuzhiyun if (nf < 0)
194*4882a593Smuzhiyun return nf;
195*4882a593Smuzhiyun /*
196*4882a593Smuzhiyun * The spec allows 1 <= Nf <= 255, but we only support up to 4
197*4882a593Smuzhiyun * components.
198*4882a593Smuzhiyun */
199*4882a593Smuzhiyun if (nf < 1 || nf > V4L2_JPEG_MAX_COMPONENTS)
200*4882a593Smuzhiyun return -EINVAL;
201*4882a593Smuzhiyun if (len != 8 + 3 * nf)
202*4882a593Smuzhiyun return -EINVAL;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun frame_header->precision = p;
205*4882a593Smuzhiyun frame_header->height = y;
206*4882a593Smuzhiyun frame_header->width = x;
207*4882a593Smuzhiyun frame_header->num_components = nf;
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun for (i = 0; i < nf; i++) {
210*4882a593Smuzhiyun struct v4l2_jpeg_frame_component_spec *component;
211*4882a593Smuzhiyun int c, h_v, tq;
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun c = jpeg_get_byte(stream);
214*4882a593Smuzhiyun if (c < 0)
215*4882a593Smuzhiyun return c;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun h_v = jpeg_get_byte(stream);
218*4882a593Smuzhiyun if (h_v < 0)
219*4882a593Smuzhiyun return h_v;
220*4882a593Smuzhiyun if (i == 0) {
221*4882a593Smuzhiyun int subs;
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun subs = v4l2_jpeg_decode_subsampling(nf, h_v);
224*4882a593Smuzhiyun if (subs < 0)
225*4882a593Smuzhiyun return subs;
226*4882a593Smuzhiyun frame_header->subsampling = subs;
227*4882a593Smuzhiyun } else if (h_v != 0x11) {
228*4882a593Smuzhiyun /* all chroma sampling factors must be 1 */
229*4882a593Smuzhiyun return -EINVAL;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun tq = jpeg_get_byte(stream);
233*4882a593Smuzhiyun if (tq < 0)
234*4882a593Smuzhiyun return tq;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun component = &frame_header->component[i];
237*4882a593Smuzhiyun component->component_identifier = c;
238*4882a593Smuzhiyun component->horizontal_sampling_factor =
239*4882a593Smuzhiyun (h_v >> 4) & 0xf;
240*4882a593Smuzhiyun component->vertical_sampling_factor = h_v & 0xf;
241*4882a593Smuzhiyun component->quantization_table_selector = tq;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun } else {
244*4882a593Smuzhiyun return jpeg_skip(stream, len - 2);
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun return 0;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
jpeg_parse_scan_header(struct jpeg_stream * stream,struct v4l2_jpeg_scan_header * scan_header)250*4882a593Smuzhiyun static int jpeg_parse_scan_header(struct jpeg_stream *stream,
251*4882a593Smuzhiyun struct v4l2_jpeg_scan_header *scan_header)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun size_t skip;
254*4882a593Smuzhiyun int len = jpeg_get_word_be(stream);
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun if (len < 0)
257*4882a593Smuzhiyun return len;
258*4882a593Smuzhiyun /* Ls = 8 + 3 * Ns, Ns >= 1 */
259*4882a593Smuzhiyun if (len < 6 + 2)
260*4882a593Smuzhiyun return -EINVAL;
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun if (scan_header) {
263*4882a593Smuzhiyun int ns;
264*4882a593Smuzhiyun int i;
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun ns = jpeg_get_byte(stream);
267*4882a593Smuzhiyun if (ns < 0)
268*4882a593Smuzhiyun return ns;
269*4882a593Smuzhiyun if (ns < 1 || ns > 4 || len != 6 + 2 * ns)
270*4882a593Smuzhiyun return -EINVAL;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun scan_header->num_components = ns;
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun for (i = 0; i < ns; i++) {
275*4882a593Smuzhiyun struct v4l2_jpeg_scan_component_spec *component;
276*4882a593Smuzhiyun int cs, td_ta;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun cs = jpeg_get_byte(stream);
279*4882a593Smuzhiyun if (cs < 0)
280*4882a593Smuzhiyun return cs;
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun td_ta = jpeg_get_byte(stream);
283*4882a593Smuzhiyun if (td_ta < 0)
284*4882a593Smuzhiyun return td_ta;
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun component = &scan_header->component[i];
287*4882a593Smuzhiyun component->component_selector = cs;
288*4882a593Smuzhiyun component->dc_entropy_coding_table_selector =
289*4882a593Smuzhiyun (td_ta >> 4) & 0xf;
290*4882a593Smuzhiyun component->ac_entropy_coding_table_selector =
291*4882a593Smuzhiyun td_ta & 0xf;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun skip = 3; /* skip Ss, Se, Ah, and Al */
295*4882a593Smuzhiyun } else {
296*4882a593Smuzhiyun skip = len - 2;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun return jpeg_skip(stream, skip);
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun /* B.2.4.1 Quantization table-specification syntax */
jpeg_parse_quantization_tables(struct jpeg_stream * stream,u8 precision,struct v4l2_jpeg_reference * tables)303*4882a593Smuzhiyun static int jpeg_parse_quantization_tables(struct jpeg_stream *stream,
304*4882a593Smuzhiyun u8 precision,
305*4882a593Smuzhiyun struct v4l2_jpeg_reference *tables)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun int len = jpeg_get_word_be(stream);
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun if (len < 0)
310*4882a593Smuzhiyun return len;
311*4882a593Smuzhiyun /* Lq = 2 + n * 65 (for baseline DCT), n >= 1 */
312*4882a593Smuzhiyun if (len < 2 + 65)
313*4882a593Smuzhiyun return -EINVAL;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun len -= 2;
316*4882a593Smuzhiyun while (len >= 65) {
317*4882a593Smuzhiyun u8 pq, tq, *qk;
318*4882a593Smuzhiyun int ret;
319*4882a593Smuzhiyun int pq_tq = jpeg_get_byte(stream);
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun if (pq_tq < 0)
322*4882a593Smuzhiyun return pq_tq;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun /* quantization table element precision */
325*4882a593Smuzhiyun pq = (pq_tq >> 4) & 0xf;
326*4882a593Smuzhiyun /*
327*4882a593Smuzhiyun * Only 8-bit Qk values for 8-bit sample precision. Extended
328*4882a593Smuzhiyun * sequential DCT with 12-bit sample precision also supports
329*4882a593Smuzhiyun * 16-bit Qk values.
330*4882a593Smuzhiyun */
331*4882a593Smuzhiyun if (pq != 0 && (pq != 1 || precision != 12))
332*4882a593Smuzhiyun return -EINVAL;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun /* quantization table destination identifier */
335*4882a593Smuzhiyun tq = pq_tq & 0xf;
336*4882a593Smuzhiyun if (tq > 3)
337*4882a593Smuzhiyun return -EINVAL;
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun /* quantization table element */
340*4882a593Smuzhiyun qk = stream->curr;
341*4882a593Smuzhiyun ret = jpeg_skip(stream, pq ? 128 : 64);
342*4882a593Smuzhiyun if (ret < 0)
343*4882a593Smuzhiyun return -EINVAL;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun if (tables) {
346*4882a593Smuzhiyun tables[tq].start = qk;
347*4882a593Smuzhiyun tables[tq].length = pq ? 128 : 64;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun len -= pq ? 129 : 65;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun return 0;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun /* B.2.4.2 Huffman table-specification syntax */
jpeg_parse_huffman_tables(struct jpeg_stream * stream,struct v4l2_jpeg_reference * tables)357*4882a593Smuzhiyun static int jpeg_parse_huffman_tables(struct jpeg_stream *stream,
358*4882a593Smuzhiyun struct v4l2_jpeg_reference *tables)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun int mt;
361*4882a593Smuzhiyun int len = jpeg_get_word_be(stream);
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun if (len < 0)
364*4882a593Smuzhiyun return len;
365*4882a593Smuzhiyun /* Table B.5 - Huffman table specification parameter sizes and values */
366*4882a593Smuzhiyun if (len < 2 + 17)
367*4882a593Smuzhiyun return -EINVAL;
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun for (len -= 2; len >= 17; len -= 17 + mt) {
370*4882a593Smuzhiyun u8 tc, th, *table;
371*4882a593Smuzhiyun int tc_th = jpeg_get_byte(stream);
372*4882a593Smuzhiyun int i, ret;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun if (tc_th < 0)
375*4882a593Smuzhiyun return tc_th;
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun /* table class - 0 = DC, 1 = AC */
378*4882a593Smuzhiyun tc = (tc_th >> 4) & 0xf;
379*4882a593Smuzhiyun if (tc > 1)
380*4882a593Smuzhiyun return -EINVAL;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun /* huffman table destination identifier */
383*4882a593Smuzhiyun th = tc_th & 0xf;
384*4882a593Smuzhiyun /* only two Huffman tables for baseline DCT */
385*4882a593Smuzhiyun if (th > 1)
386*4882a593Smuzhiyun return -EINVAL;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun /* BITS - number of Huffman codes with length i */
389*4882a593Smuzhiyun table = stream->curr;
390*4882a593Smuzhiyun mt = 0;
391*4882a593Smuzhiyun for (i = 0; i < 16; i++) {
392*4882a593Smuzhiyun int li;
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun li = jpeg_get_byte(stream);
395*4882a593Smuzhiyun if (li < 0)
396*4882a593Smuzhiyun return li;
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun mt += li;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun /* HUFFVAL - values associated with each Huffman code */
401*4882a593Smuzhiyun ret = jpeg_skip(stream, mt);
402*4882a593Smuzhiyun if (ret < 0)
403*4882a593Smuzhiyun return ret;
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun if (tables) {
406*4882a593Smuzhiyun tables[(tc << 1) | th].start = table;
407*4882a593Smuzhiyun tables[(tc << 1) | th].length = stream->curr - table;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun return jpeg_skip(stream, len - 2);
412*4882a593Smuzhiyun }
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun /* B.2.4.4 Restart interval definition syntax */
jpeg_parse_restart_interval(struct jpeg_stream * stream,u16 * restart_interval)415*4882a593Smuzhiyun static int jpeg_parse_restart_interval(struct jpeg_stream *stream,
416*4882a593Smuzhiyun u16 *restart_interval)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun int len = jpeg_get_word_be(stream);
419*4882a593Smuzhiyun int ri;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun if (len < 0)
422*4882a593Smuzhiyun return len;
423*4882a593Smuzhiyun if (len != 4)
424*4882a593Smuzhiyun return -EINVAL;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun ri = jpeg_get_word_be(stream);
427*4882a593Smuzhiyun if (ri < 0)
428*4882a593Smuzhiyun return ri;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun *restart_interval = ri;
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun return 0;
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun
jpeg_skip_segment(struct jpeg_stream * stream)435*4882a593Smuzhiyun static int jpeg_skip_segment(struct jpeg_stream *stream)
436*4882a593Smuzhiyun {
437*4882a593Smuzhiyun int len = jpeg_get_word_be(stream);
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun if (len < 0)
440*4882a593Smuzhiyun return len;
441*4882a593Smuzhiyun if (len < 2)
442*4882a593Smuzhiyun return -EINVAL;
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun return jpeg_skip(stream, len - 2);
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun /**
448*4882a593Smuzhiyun * jpeg_parse_header - locate marker segments and optionally parse headers
449*4882a593Smuzhiyun * @buf: address of the JPEG buffer, should start with a SOI marker
450*4882a593Smuzhiyun * @len: length of the JPEG buffer
451*4882a593Smuzhiyun * @out: returns marker segment positions and optionally parsed headers
452*4882a593Smuzhiyun *
453*4882a593Smuzhiyun * The out->scan_header pointer must be initialized to NULL or point to a valid
454*4882a593Smuzhiyun * v4l2_jpeg_scan_header structure. The out->huffman_tables and
455*4882a593Smuzhiyun * out->quantization_tables pointers must be initialized to NULL or point to a
456*4882a593Smuzhiyun * valid array of 4 v4l2_jpeg_reference structures each.
457*4882a593Smuzhiyun *
458*4882a593Smuzhiyun * Returns 0 or negative error if parsing failed.
459*4882a593Smuzhiyun */
v4l2_jpeg_parse_header(void * buf,size_t len,struct v4l2_jpeg_header * out)460*4882a593Smuzhiyun int v4l2_jpeg_parse_header(void *buf, size_t len, struct v4l2_jpeg_header *out)
461*4882a593Smuzhiyun {
462*4882a593Smuzhiyun struct jpeg_stream stream;
463*4882a593Smuzhiyun int marker;
464*4882a593Smuzhiyun int ret = 0;
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun stream.curr = buf;
467*4882a593Smuzhiyun stream.end = stream.curr + len;
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun out->num_dht = 0;
470*4882a593Smuzhiyun out->num_dqt = 0;
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun /* the first marker must be SOI */
473*4882a593Smuzhiyun marker = jpeg_next_marker(&stream);
474*4882a593Smuzhiyun if (marker < 0)
475*4882a593Smuzhiyun return marker;
476*4882a593Smuzhiyun if (marker != SOI)
477*4882a593Smuzhiyun return -EINVAL;
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun /* loop through marker segments */
480*4882a593Smuzhiyun while ((marker = jpeg_next_marker(&stream)) >= 0) {
481*4882a593Smuzhiyun switch (marker) {
482*4882a593Smuzhiyun /* baseline DCT, extended sequential DCT */
483*4882a593Smuzhiyun case SOF0 ... SOF1:
484*4882a593Smuzhiyun ret = jpeg_reference_segment(&stream, &out->sof);
485*4882a593Smuzhiyun if (ret < 0)
486*4882a593Smuzhiyun return ret;
487*4882a593Smuzhiyun ret = jpeg_parse_frame_header(&stream, marker,
488*4882a593Smuzhiyun &out->frame);
489*4882a593Smuzhiyun break;
490*4882a593Smuzhiyun /* progressive, lossless */
491*4882a593Smuzhiyun case SOF2 ... SOF3:
492*4882a593Smuzhiyun /* differential coding */
493*4882a593Smuzhiyun case SOF5 ... SOF7:
494*4882a593Smuzhiyun /* arithmetic coding */
495*4882a593Smuzhiyun case SOF9 ... SOF11:
496*4882a593Smuzhiyun case SOF13 ... SOF15:
497*4882a593Smuzhiyun case DAC:
498*4882a593Smuzhiyun case TEM:
499*4882a593Smuzhiyun return -EINVAL;
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun case DHT:
502*4882a593Smuzhiyun ret = jpeg_reference_segment(&stream,
503*4882a593Smuzhiyun &out->dht[out->num_dht++ % 4]);
504*4882a593Smuzhiyun if (ret < 0)
505*4882a593Smuzhiyun return ret;
506*4882a593Smuzhiyun ret = jpeg_parse_huffman_tables(&stream,
507*4882a593Smuzhiyun out->huffman_tables);
508*4882a593Smuzhiyun break;
509*4882a593Smuzhiyun case DQT:
510*4882a593Smuzhiyun ret = jpeg_reference_segment(&stream,
511*4882a593Smuzhiyun &out->dqt[out->num_dqt++ % 4]);
512*4882a593Smuzhiyun if (ret < 0)
513*4882a593Smuzhiyun return ret;
514*4882a593Smuzhiyun ret = jpeg_parse_quantization_tables(&stream,
515*4882a593Smuzhiyun out->frame.precision,
516*4882a593Smuzhiyun out->quantization_tables);
517*4882a593Smuzhiyun break;
518*4882a593Smuzhiyun case DRI:
519*4882a593Smuzhiyun ret = jpeg_parse_restart_interval(&stream,
520*4882a593Smuzhiyun &out->restart_interval);
521*4882a593Smuzhiyun break;
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun case SOS:
524*4882a593Smuzhiyun ret = jpeg_reference_segment(&stream, &out->sos);
525*4882a593Smuzhiyun if (ret < 0)
526*4882a593Smuzhiyun return ret;
527*4882a593Smuzhiyun ret = jpeg_parse_scan_header(&stream, out->scan);
528*4882a593Smuzhiyun /*
529*4882a593Smuzhiyun * stop parsing, the scan header marks the beginning of
530*4882a593Smuzhiyun * the entropy coded segment
531*4882a593Smuzhiyun */
532*4882a593Smuzhiyun out->ecs_offset = stream.curr - (u8 *)buf;
533*4882a593Smuzhiyun return ret;
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun /* markers without parameters */
536*4882a593Smuzhiyun case RST0 ... RST7: /* restart */
537*4882a593Smuzhiyun case SOI: /* start of image */
538*4882a593Smuzhiyun case EOI: /* end of image */
539*4882a593Smuzhiyun break;
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun /* skip unknown or unsupported marker segments */
542*4882a593Smuzhiyun default:
543*4882a593Smuzhiyun ret = jpeg_skip_segment(&stream);
544*4882a593Smuzhiyun break;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun if (ret < 0)
547*4882a593Smuzhiyun return ret;
548*4882a593Smuzhiyun }
549*4882a593Smuzhiyun
550*4882a593Smuzhiyun return marker;
551*4882a593Smuzhiyun }
552*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_header);
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun /**
555*4882a593Smuzhiyun * v4l2_jpeg_parse_frame_header - parse frame header
556*4882a593Smuzhiyun * @buf: address of the frame header, after the SOF0 marker
557*4882a593Smuzhiyun * @len: length of the frame header
558*4882a593Smuzhiyun * @frame_header: returns the parsed frame header
559*4882a593Smuzhiyun *
560*4882a593Smuzhiyun * Returns 0 or negative error if parsing failed.
561*4882a593Smuzhiyun */
v4l2_jpeg_parse_frame_header(void * buf,size_t len,struct v4l2_jpeg_frame_header * frame_header)562*4882a593Smuzhiyun int v4l2_jpeg_parse_frame_header(void *buf, size_t len,
563*4882a593Smuzhiyun struct v4l2_jpeg_frame_header *frame_header)
564*4882a593Smuzhiyun {
565*4882a593Smuzhiyun struct jpeg_stream stream;
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun stream.curr = buf;
568*4882a593Smuzhiyun stream.end = stream.curr + len;
569*4882a593Smuzhiyun return jpeg_parse_frame_header(&stream, SOF0, frame_header);
570*4882a593Smuzhiyun }
571*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_frame_header);
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun /**
574*4882a593Smuzhiyun * v4l2_jpeg_parse_scan_header - parse scan header
575*4882a593Smuzhiyun * @buf: address of the scan header, after the SOS marker
576*4882a593Smuzhiyun * @len: length of the scan header
577*4882a593Smuzhiyun * @scan_header: returns the parsed scan header
578*4882a593Smuzhiyun *
579*4882a593Smuzhiyun * Returns 0 or negative error if parsing failed.
580*4882a593Smuzhiyun */
v4l2_jpeg_parse_scan_header(void * buf,size_t len,struct v4l2_jpeg_scan_header * scan_header)581*4882a593Smuzhiyun int v4l2_jpeg_parse_scan_header(void *buf, size_t len,
582*4882a593Smuzhiyun struct v4l2_jpeg_scan_header *scan_header)
583*4882a593Smuzhiyun {
584*4882a593Smuzhiyun struct jpeg_stream stream;
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun stream.curr = buf;
587*4882a593Smuzhiyun stream.end = stream.curr + len;
588*4882a593Smuzhiyun return jpeg_parse_scan_header(&stream, scan_header);
589*4882a593Smuzhiyun }
590*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_scan_header);
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun /**
593*4882a593Smuzhiyun * v4l2_jpeg_parse_quantization_tables - parse quantization tables segment
594*4882a593Smuzhiyun * @buf: address of the quantization table segment, after the DQT marker
595*4882a593Smuzhiyun * @len: length of the quantization table segment
596*4882a593Smuzhiyun * @precision: sample precision (P) in bits per component
597*4882a593Smuzhiyun * @q_tables: returns four references into the buffer for the
598*4882a593Smuzhiyun * four possible quantization table destinations
599*4882a593Smuzhiyun *
600*4882a593Smuzhiyun * Returns 0 or negative error if parsing failed.
601*4882a593Smuzhiyun */
v4l2_jpeg_parse_quantization_tables(void * buf,size_t len,u8 precision,struct v4l2_jpeg_reference * q_tables)602*4882a593Smuzhiyun int v4l2_jpeg_parse_quantization_tables(void *buf, size_t len, u8 precision,
603*4882a593Smuzhiyun struct v4l2_jpeg_reference *q_tables)
604*4882a593Smuzhiyun {
605*4882a593Smuzhiyun struct jpeg_stream stream;
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun stream.curr = buf;
608*4882a593Smuzhiyun stream.end = stream.curr + len;
609*4882a593Smuzhiyun return jpeg_parse_quantization_tables(&stream, precision, q_tables);
610*4882a593Smuzhiyun }
611*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_quantization_tables);
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun /**
614*4882a593Smuzhiyun * v4l2_jpeg_parse_huffman_tables - parse huffman tables segment
615*4882a593Smuzhiyun * @buf: address of the Huffman table segment, after the DHT marker
616*4882a593Smuzhiyun * @len: length of the Huffman table segment
617*4882a593Smuzhiyun * @huffman_tables: returns four references into the buffer for the
618*4882a593Smuzhiyun * four possible Huffman table destinations, in
619*4882a593Smuzhiyun * the order DC0, DC1, AC0, AC1
620*4882a593Smuzhiyun *
621*4882a593Smuzhiyun * Returns 0 or negative error if parsing failed.
622*4882a593Smuzhiyun */
v4l2_jpeg_parse_huffman_tables(void * buf,size_t len,struct v4l2_jpeg_reference * huffman_tables)623*4882a593Smuzhiyun int v4l2_jpeg_parse_huffman_tables(void *buf, size_t len,
624*4882a593Smuzhiyun struct v4l2_jpeg_reference *huffman_tables)
625*4882a593Smuzhiyun {
626*4882a593Smuzhiyun struct jpeg_stream stream;
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun stream.curr = buf;
629*4882a593Smuzhiyun stream.end = stream.curr + len;
630*4882a593Smuzhiyun return jpeg_parse_huffman_tables(&stream, huffman_tables);
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_huffman_tables);
633