xref: /OK3568_Linux_fs/kernel/drivers/media/v4l2-core/v4l2-jpeg.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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