summaryrefslogtreecommitdiff
path: root/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c (plain)
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
15state. Return -1 if no start code found */
16static 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;
35found:
36 pr_info("find_marker skipped %d bytes\n", skipped);
37 *pbuf_ptr = buf_ptr;
38
39 return val;
40}
41
42int 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
156int 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
240static 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 }
354skip:
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;
363fail:
364 s->got_picture = 0;
365 return ret;
366the_end:
367 pr_info("decode frame unused %d bytes\n", (int)(buf_end - buf_ptr));
368
369 return 0;
370}
371
372int 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