blob: 1d9d94b9938c18327c07c730bad46debc73cd9da
1 | #include <linux/kernel.h> |
2 | #include <linux/types.h> |
3 | #include <linux/vmalloc.h> |
4 | #include <linux/mm.h> |
5 | #include <linux/string.h> |
6 | |
7 | #include "aml_mjpeg_parser.h" |
8 | #include "../utils/get_bits.h" |
9 | #include "../utils/put_bits.h" |
10 | #include "../utils/golomb.h" |
11 | #include "../utils/common.h" |
12 | #include "utils.h" |
13 | |
14 | /* return the 8 bit start code value and update the search |
15 | state. Return -1 if no start code found */ |
16 | static int find_marker(const u8 **pbuf_ptr, const u8 *buf_end) |
17 | { |
18 | const u8 *buf_ptr; |
19 | u32 v, v2; |
20 | int val; |
21 | int skipped = 0; |
22 | |
23 | buf_ptr = *pbuf_ptr; |
24 | while (buf_end - buf_ptr > 1) { |
25 | v = *buf_ptr++; |
26 | v2 = *buf_ptr; |
27 | if ((v == 0xff) && (v2 >= 0xc0) && (v2 <= 0xfe) && buf_ptr < buf_end) { |
28 | val = *buf_ptr++; |
29 | goto found; |
30 | } |
31 | skipped++; |
32 | } |
33 | buf_ptr = buf_end; |
34 | val = -1; |
35 | found: |
36 | pr_info("find_marker skipped %d bytes\n", skipped); |
37 | *pbuf_ptr = buf_ptr; |
38 | |
39 | return val; |
40 | } |
41 | |
42 | int ff_mjpeg_find_marker(struct MJpegDecodeContext *s, |
43 | const u8 **buf_ptr, const u8 *buf_end, |
44 | const u8 **unescaped_buf_ptr, |
45 | int *unescaped_buf_size) |
46 | { |
47 | int start_code; |
48 | |
49 | start_code = find_marker(buf_ptr, buf_end); |
50 | |
51 | /* unescape buffer of SOS, use special treatment for JPEG-LS */ |
52 | if (start_code == SOS && !s->ls) { |
53 | const u8 *src = *buf_ptr; |
54 | const u8 *ptr = src; |
55 | u8 *dst = s->buffer; |
56 | |
57 | #define copy_data_segment(skip) do { \ |
58 | int length = (ptr - src) - (skip); \ |
59 | if (length > 0) { \ |
60 | memcpy(dst, src, length); \ |
61 | dst += length; \ |
62 | src = ptr; \ |
63 | } \ |
64 | } while (0) |
65 | |
66 | |
67 | while (ptr < buf_end) { |
68 | u8 x = *(ptr++); |
69 | |
70 | if (x == 0xff) { |
71 | int skip = 0; |
72 | while (ptr < buf_end && x == 0xff) { |
73 | x = *(ptr++); |
74 | skip++; |
75 | } |
76 | |
77 | /* 0xFF, 0xFF, ... */ |
78 | if (skip > 1) { |
79 | copy_data_segment(skip); |
80 | |
81 | /* decrement src as it is equal to ptr after the |
82 | * copy_data_segment macro and we might want to |
83 | * copy the current value of x later on */ |
84 | src--; |
85 | } |
86 | |
87 | if (x < 0xd0 || x > 0xd7) { |
88 | copy_data_segment(1); |
89 | if (x) |
90 | break; |
91 | } |
92 | } |
93 | if (src < ptr) |
94 | copy_data_segment(0); |
95 | } |
96 | #undef copy_data_segment |
97 | |
98 | *unescaped_buf_ptr = s->buffer; |
99 | *unescaped_buf_size = dst - s->buffer; |
100 | memset(s->buffer + *unescaped_buf_size, 0, |
101 | AV_INPUT_BUFFER_PADDING_SIZE); |
102 | |
103 | pr_info("escaping removed %d bytes\n", |
104 | (int)((buf_end - *buf_ptr) - (dst - s->buffer))); |
105 | } else if (start_code == SOS && s->ls) { |
106 | const u8 *src = *buf_ptr; |
107 | u8 *dst = s->buffer; |
108 | int bit_count = 0; |
109 | int t = 0, b = 0; |
110 | struct put_bits_context pb; |
111 | |
112 | /* find marker */ |
113 | while (src + t < buf_end) { |
114 | u8 x = src[t++]; |
115 | if (x == 0xff) { |
116 | while ((src + t < buf_end) && x == 0xff) |
117 | x = src[t++]; |
118 | if (x & 0x80) { |
119 | t -= FFMIN(2, t); |
120 | break; |
121 | } |
122 | } |
123 | } |
124 | bit_count = t * 8; |
125 | init_put_bits(&pb, dst, t); |
126 | |
127 | /* unescape bitstream */ |
128 | while (b < t) { |
129 | u8 x = src[b++]; |
130 | put_bits(&pb, 8, x); |
131 | if (x == 0xFF && b < t) { |
132 | x = src[b++]; |
133 | if (x & 0x80) { |
134 | pr_err("Invalid escape sequence\n"); |
135 | x &= 0x7f; |
136 | } |
137 | put_bits(&pb, 7, x); |
138 | bit_count--; |
139 | } |
140 | } |
141 | flush_put_bits(&pb); |
142 | |
143 | *unescaped_buf_ptr = dst; |
144 | *unescaped_buf_size = (bit_count + 7) >> 3; |
145 | memset(s->buffer + *unescaped_buf_size, 0, |
146 | AV_INPUT_BUFFER_PADDING_SIZE); |
147 | } else { |
148 | *unescaped_buf_ptr = *buf_ptr; |
149 | *unescaped_buf_size = buf_end - *buf_ptr; |
150 | } |
151 | |
152 | return start_code; |
153 | } |
154 | |
155 | |
156 | int ff_mjpeg_decode_sof(struct MJpegDecodeContext *s) |
157 | { |
158 | int len, nb_components, i, width, height, bits, size_change; |
159 | int h_count[MAX_COMPONENTS] = { 0 }; |
160 | int v_count[MAX_COMPONENTS] = { 0 }; |
161 | |
162 | s->cur_scan = 0; |
163 | memset(s->upscale_h, 0, sizeof(s->upscale_h)); |
164 | memset(s->upscale_v, 0, sizeof(s->upscale_v)); |
165 | |
166 | /* XXX: verify len field validity */ |
167 | len = get_bits(&s->gb, 16); |
168 | bits = get_bits(&s->gb, 8); |
169 | |
170 | if (bits > 16 || bits < 1) { |
171 | pr_err("bits %d is invalid\n", bits); |
172 | return -1; |
173 | } |
174 | |
175 | height = get_bits(&s->gb, 16); |
176 | width = get_bits(&s->gb, 16); |
177 | |
178 | pr_info("sof0: picture: %dx%d\n", width, height); |
179 | |
180 | nb_components = get_bits(&s->gb, 8); |
181 | if (nb_components <= 0 || |
182 | nb_components > MAX_COMPONENTS) |
183 | return -1; |
184 | |
185 | s->nb_components = nb_components; |
186 | s->h_max = 1; |
187 | s->v_max = 1; |
188 | for (i = 0; i < nb_components; i++) { |
189 | /* component id */ |
190 | s->component_id[i] = get_bits(&s->gb, 8) - 1; |
191 | h_count[i] = get_bits(&s->gb, 4); |
192 | v_count[i] = get_bits(&s->gb, 4); |
193 | /* compute hmax and vmax (only used in interleaved case) */ |
194 | if (h_count[i] > s->h_max) |
195 | s->h_max = h_count[i]; |
196 | if (v_count[i] > s->v_max) |
197 | s->v_max = v_count[i]; |
198 | s->quant_index[i] = get_bits(&s->gb, 8); |
199 | if (s->quant_index[i] >= 4) { |
200 | pr_err("quant_index is invalid\n"); |
201 | return -1; |
202 | } |
203 | if (!h_count[i] || !v_count[i]) { |
204 | pr_err("Invalid sampling factor in component %d %d:%d\n", |
205 | i, h_count[i], v_count[i]); |
206 | return -1; |
207 | } |
208 | |
209 | pr_info("component %d %d:%d id: %d quant:%d\n", |
210 | i, h_count[i], v_count[i], |
211 | s->component_id[i], s->quant_index[i]); |
212 | } |
213 | if (nb_components == 4 |
214 | && s->component_id[0] == 'C' - 1 |
215 | && s->component_id[1] == 'M' - 1 |
216 | && s->component_id[2] == 'Y' - 1 |
217 | && s->component_id[3] == 'K' - 1) |
218 | s->adobe_transform = 0; |
219 | |
220 | /* if different size, realloc/alloc picture */ |
221 | if (width != s->width || height != s->height || bits != s->bits || |
222 | memcmp(s->h_count, h_count, sizeof(h_count)) || |
223 | memcmp(s->v_count, v_count, sizeof(v_count))) { |
224 | size_change = 1; |
225 | |
226 | s->width = width; |
227 | s->height = height; |
228 | s->bits = bits; |
229 | memcpy(s->h_count, h_count, sizeof(h_count)); |
230 | memcpy(s->v_count, v_count, sizeof(v_count)); |
231 | s->interlaced = 0; |
232 | s->got_picture = 0; |
233 | } else { |
234 | size_change = 0; |
235 | } |
236 | |
237 | return 0; |
238 | } |
239 | |
240 | static int ff_mjpeg_decode_frame(u8 *buf, int buf_size, struct MJpegDecodeContext *s) |
241 | { |
242 | const u8 *buf_end, *buf_ptr; |
243 | const u8 *unescaped_buf_ptr; |
244 | int unescaped_buf_size; |
245 | int start_code; |
246 | int ret = 0; |
247 | |
248 | buf_ptr = buf; |
249 | buf_end = buf + buf_size; |
250 | while (buf_ptr < buf_end) { |
251 | /* find start next marker */ |
252 | start_code = ff_mjpeg_find_marker(s, &buf_ptr, buf_end, |
253 | &unescaped_buf_ptr, |
254 | &unescaped_buf_size); |
255 | /* EOF */ |
256 | if (start_code < 0) { |
257 | break; |
258 | } else if (unescaped_buf_size > INT_MAX / 8) { |
259 | pr_err("MJPEG packet 0x%x too big (%d/%d), corrupt data?\n", |
260 | start_code, unescaped_buf_size, buf_size); |
261 | return -1; |
262 | } |
263 | pr_info("marker=%x avail_size_in_buf=%d\n", |
264 | start_code, (int)(buf_end - buf_ptr)); |
265 | |
266 | ret = init_get_bits8(&s->gb, unescaped_buf_ptr, unescaped_buf_size); |
267 | if (ret < 0) { |
268 | pr_err("invalid buffer\n"); |
269 | goto fail; |
270 | } |
271 | |
272 | s->start_code = start_code; |
273 | pr_info("startcode: %X\n", start_code); |
274 | |
275 | switch (start_code) { |
276 | case SOF0: |
277 | case SOF1: |
278 | case SOF2: |
279 | case SOF3: |
280 | case SOF48: |
281 | case SOI: |
282 | case SOS: |
283 | case EOI: |
284 | break; |
285 | default: |
286 | goto skip; |
287 | } |
288 | |
289 | switch (start_code) { |
290 | case SOI: |
291 | s->restart_interval = 0; |
292 | s->restart_count = 0; |
293 | s->raw_image_buffer = buf_ptr; |
294 | s->raw_image_buffer_size = buf_end - buf_ptr; |
295 | /* nothing to do on SOI */ |
296 | break; |
297 | case SOF0: |
298 | case SOF1: |
299 | if (start_code == SOF0) |
300 | s->profile = FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT; |
301 | else |
302 | s->profile = FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT; |
303 | s->lossless = 0; |
304 | s->ls = 0; |
305 | s->progressive = 0; |
306 | if ((ret = ff_mjpeg_decode_sof(s)) < 0) |
307 | goto fail; |
308 | break; |
309 | case SOF2: |
310 | s->profile = FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT; |
311 | s->lossless = 0; |
312 | s->ls = 0; |
313 | s->progressive = 1; |
314 | if ((ret = ff_mjpeg_decode_sof(s)) < 0) |
315 | goto fail; |
316 | break; |
317 | case SOF3: |
318 | s->profile = FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS; |
319 | s->properties |= FF_CODEC_PROPERTY_LOSSLESS; |
320 | s->lossless = 1; |
321 | s->ls = 0; |
322 | s->progressive = 0; |
323 | if ((ret = ff_mjpeg_decode_sof(s)) < 0) |
324 | goto fail; |
325 | break; |
326 | case SOF48: |
327 | s->profile = FF_PROFILE_MJPEG_JPEG_LS; |
328 | s->properties |= FF_CODEC_PROPERTY_LOSSLESS; |
329 | s->lossless = 1; |
330 | s->ls = 1; |
331 | s->progressive = 0; |
332 | if ((ret = ff_mjpeg_decode_sof(s)) < 0) |
333 | goto fail; |
334 | break; |
335 | case EOI: |
336 | goto the_end; |
337 | case DHT: |
338 | case LSE: |
339 | case SOS: |
340 | case DRI: |
341 | case SOF5: |
342 | case SOF6: |
343 | case SOF7: |
344 | case SOF9: |
345 | case SOF10: |
346 | case SOF11: |
347 | case SOF13: |
348 | case SOF14: |
349 | case SOF15: |
350 | case JPG: |
351 | pr_err("mjpeg: unsupported coding type (%x)\n", start_code); |
352 | break; |
353 | } |
354 | skip: |
355 | /* eof process start code */ |
356 | buf_ptr += (get_bits_count(&s->gb) + 7) / 8; |
357 | pr_info("marker parser used %d bytes (%d bits)\n", |
358 | (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb)); |
359 | } |
360 | |
361 | pr_err("No JPEG data found in image\n"); |
362 | return -1; |
363 | fail: |
364 | s->got_picture = 0; |
365 | return ret; |
366 | the_end: |
367 | pr_info("decode frame unused %d bytes\n", (int)(buf_end - buf_ptr)); |
368 | |
369 | return 0; |
370 | } |
371 | |
372 | int mjpeg_decode_extradata_ps(u8 *buf, int size, struct mjpeg_param_sets *ps) |
373 | { |
374 | int ret; |
375 | |
376 | ps->head_parsed = false; |
377 | |
378 | ps->dec_ps.buf_size = size; |
379 | ps->dec_ps.buffer = vzalloc(size + AV_INPUT_BUFFER_PADDING_SIZE); |
380 | if (!ps->dec_ps.buffer) |
381 | return -1; |
382 | |
383 | ret = ff_mjpeg_decode_frame(buf, size, &ps->dec_ps); |
384 | if (ret) { |
385 | pr_err("parse extra data failed. err: %d\n", ret); |
386 | vfree(ps->dec_ps.buffer); |
387 | return ret; |
388 | } |
389 | |
390 | if (ps->dec_ps.width && ps->dec_ps.height) |
391 | ps->head_parsed = true; |
392 | |
393 | vfree(ps->dec_ps.buffer); |
394 | |
395 | return 0; |
396 | } |
397 | |
398 |