blob: b5144aba8ffc392889cbe77ace3bf496b87f6f8e [file] [log] [blame]
Ed Tanous93f987d2017-04-17 17:52:36 -07001#pragma once
2
Ed Tanousb078cf32017-04-18 14:51:21 -07003#include <string.h>
Ed Tanous93f987d2017-04-17 17:52:36 -07004#include <array>
5#include <aspeed/JTABLES.H>
Ed Tanous1ff48782017-04-18 12:45:08 -07006#include <ast_video_types.hpp>
7#include <cassert>
8#include <cstdint>
Ed Tanousb078cf32017-04-18 14:51:21 -07009#include <iostream>
10#include <vector>
Ed Tanous93f987d2017-04-17 17:52:36 -070011
Ed Tanousd5f39992017-04-18 13:41:22 -070012/*
Ed Tanous1ff48782017-04-18 12:45:08 -070013template <class T, class Compare>
14constexpr const T &clamp(const T &v, const T &lo, const T &hi, Compare comp) {
15 return assert(!comp(hi, lo)), comp(v, lo) ? lo : comp(hi, v) ? hi : v;
16}
17
18template <class T>
19constexpr const T &clamp(const T &v, const T &lo, const T &hi) {
20 return clamp(v, lo, hi, std::less<>());
21}
Ed Tanousd5f39992017-04-18 13:41:22 -070022*/
Ed Tanous93f987d2017-04-17 17:52:36 -070023namespace AstVideo {
24
Ed Tanous93f987d2017-04-17 17:52:36 -070025struct COLOR_CACHE {
Ed Tanousd5f39992017-04-18 13:41:22 -070026 COLOR_CACHE() {
27 for (int i = 0; i < 4; i++) {
28 Index[i] = i;
29 }
30 Color[0] = 0x008080;
31 Color[1] = 0xFF8080;
32 Color[2] = 0x808080;
33 Color[3] = 0xC08080;
34 }
35
Ed Tanous93f987d2017-04-17 17:52:36 -070036 unsigned long Color[4];
37 unsigned char Index[4];
38 unsigned char BitMapBits;
39};
40
41struct RGB {
42 unsigned char B;
43 unsigned char G;
44 unsigned char R;
45 unsigned char Reserved;
46};
47
48enum class JpgBlock {
49 JPEG_NO_SKIP_CODE = 0x00,
50 JPEG_SKIP_CODE = 0x08,
51
52 JPEG_PASS2_CODE = 0x02,
53 JPEG_SKIP_PASS2_CODE = 0x0A,
54
55 LOW_JPEG_NO_SKIP_CODE = 0x04,
56 LOW_JPEG_SKIP_CODE = 0x0C,
57
58 VQ_NO_SKIP_1_COLOR_CODE = 0x05,
59 VQ_SKIP_1_COLOR_CODE = 0x0D,
60
61 VQ_NO_SKIP_2_COLOR_CODE = 0x06,
62 VQ_SKIP_2_COLOR_CODE = 0x0E,
63
64 VQ_NO_SKIP_4_COLOR_CODE = 0x07,
65 VQ_SKIP_4_COLOR_CODE = 0x0F,
66
67 FRAME_END_CODE = 0x09,
68
69};
70
71class AstJpegDecoder {
72 public:
73 AstJpegDecoder() {
74 // TODO(ed) figure out how to init this in the constructor
Ed Tanous9140a672017-04-24 17:01:32 -070075 YUVBuffer.resize(1920 * 1200);
76 OutBuffer.resize(1920 * 1200);
Ed Tanous93f987d2017-04-17 17:52:36 -070077 for (auto &r : OutBuffer) {
78 r.R = 0x00;
79 r.G = 0x00;
80 r.B = 0x00;
81 r.Reserved = 0xAA;
82 }
Ed Tanousd5f39992017-04-18 13:41:22 -070083
84 int qfactor = 16;
85
86 SCALEFACTOR = qfactor;
87 SCALEFACTORUV = qfactor;
88 ADVANCESCALEFACTOR = 16;
89 ADVANCESCALEFACTORUV = 16;
Ed Tanous93f987d2017-04-17 17:52:36 -070090 init_jpg_table();
91 }
92
93 void load_quant_table(std::array<long, 64> &quant_table) {
94 float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
95 1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
96 uint8_t j, row, col;
97 uint8_t tempQT[64];
98
99 // Load quantization coefficients from JPG file, scale them for DCT and
100 // reorder
101 // from zig-zag order
102 switch (Y_selector) {
103 case 0:
104 std_luminance_qt = Tbl_000Y;
105 break;
106 case 1:
107 std_luminance_qt = Tbl_014Y;
108 break;
109 case 2:
110 std_luminance_qt = Tbl_029Y;
111 break;
112 case 3:
113 std_luminance_qt = Tbl_043Y;
114 break;
115 case 4:
116 std_luminance_qt = Tbl_057Y;
117 break;
118 case 5:
119 std_luminance_qt = Tbl_071Y;
120 break;
121 case 6:
122 std_luminance_qt = Tbl_086Y;
123 break;
124 case 7:
125 std_luminance_qt = Tbl_100Y;
126 break;
127 }
128 set_quant_table(std_luminance_qt, (uint8_t)SCALEFACTOR, tempQT);
129
130 for (j = 0; j <= 63; j++) quant_table[j] = tempQT[zigzag[j]];
131 j = 0;
132 for (row = 0; row <= 7; row++)
133 for (col = 0; col <= 7; col++) {
134 quant_table[j] =
135 (long)((quant_table[j] * scalefactor[row] * scalefactor[col]) *
136 65536);
137 j++;
138 }
139 byte_pos += 64;
140 }
141
142 void load_quant_tableCb(std::array<long, 64> &quant_table) {
143 float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
144 1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
145 uint8_t j, row, col;
146 uint8_t tempQT[64];
147
148 // Load quantization coefficients from JPG file, scale them for DCT and
149 // reorder from zig-zag order
150 if (Mapping == 0) {
151 switch (UV_selector) {
152 case 0:
153 std_chrominance_qt = Tbl_000Y;
154 break;
155 case 1:
156 std_chrominance_qt = Tbl_014Y;
157 break;
158 case 2:
159 std_chrominance_qt = Tbl_029Y;
160 break;
161 case 3:
162 std_chrominance_qt = Tbl_043Y;
163 break;
164 case 4:
165 std_chrominance_qt = Tbl_057Y;
166 break;
167 case 5:
168 std_chrominance_qt = Tbl_071Y;
169 break;
170 case 6:
171 std_chrominance_qt = Tbl_086Y;
172 break;
173 case 7:
174 std_chrominance_qt = Tbl_100Y;
175 break;
176 }
177 } else {
178 switch (UV_selector) {
179 case 0:
180 std_chrominance_qt = Tbl_000UV;
181 break;
182 case 1:
183 std_chrominance_qt = Tbl_014UV;
184 break;
185 case 2:
186 std_chrominance_qt = Tbl_029UV;
187 break;
188 case 3:
189 std_chrominance_qt = Tbl_043UV;
190 break;
191 case 4:
192 std_chrominance_qt = Tbl_057UV;
193 break;
194 case 5:
195 std_chrominance_qt = Tbl_071UV;
196 break;
197 case 6:
198 std_chrominance_qt = Tbl_086UV;
199 break;
200 case 7:
201 std_chrominance_qt = Tbl_100UV;
202 break;
203 }
204 }
205 set_quant_table(std_chrominance_qt, (uint8_t)SCALEFACTORUV, tempQT);
206
207 for (j = 0; j <= 63; j++) {
208 quant_table[j] = tempQT[zigzag[j]];
209 }
210 j = 0;
211 for (row = 0; row <= 7; row++) {
212 for (col = 0; col <= 7; col++) {
213 quant_table[j] =
214 (long)((quant_table[j] * scalefactor[row] * scalefactor[col]) *
215 65536);
216 j++;
217 }
218 }
219 byte_pos += 64;
220 }
221 // Note: Added for Dual_JPEG
222 void load_advance_quant_table(std::array<long, 64> &quant_table) {
223 float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
224 1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
225 uint8_t j, row, col;
226 uint8_t tempQT[64];
227
228 // Load quantization coefficients from JPG file, scale them for DCT and
229 // reorder
230 // from zig-zag order
231 switch (advance_selector) {
232 case 0:
233 std_luminance_qt = Tbl_000Y;
234 break;
235 case 1:
236 std_luminance_qt = Tbl_014Y;
237 break;
238 case 2:
239 std_luminance_qt = Tbl_029Y;
240 break;
241 case 3:
242 std_luminance_qt = Tbl_043Y;
243 break;
244 case 4:
245 std_luminance_qt = Tbl_057Y;
246 break;
247 case 5:
248 std_luminance_qt = Tbl_071Y;
249 break;
250 case 6:
251 std_luminance_qt = Tbl_086Y;
252 break;
253 case 7:
254 std_luminance_qt = Tbl_100Y;
255 break;
256 }
257 // Note: pass ADVANCE SCALE FACTOR to sub-function in Dual-JPEG
258 set_quant_table(std_luminance_qt, (uint8_t)ADVANCESCALEFACTOR, tempQT);
259
260 for (j = 0; j <= 63; j++) quant_table[j] = tempQT[zigzag[j]];
261 j = 0;
262 for (row = 0; row <= 7; row++)
263 for (col = 0; col <= 7; col++) {
264 quant_table[j] =
265 (long)((quant_table[j] * scalefactor[row] * scalefactor[col]) *
266 65536);
267 j++;
268 }
269 byte_pos += 64;
270 }
271
272 // Note: Added for Dual-JPEG
273 void load_advance_quant_tableCb(std::array<long, 64> &quant_table) {
274 float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
275 1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
276 uint8_t j, row, col;
277 uint8_t tempQT[64];
278
279 // Load quantization coefficients from JPG file, scale them for DCT and
280 // reorder
281 // from zig-zag order
282 if (Mapping == 1) {
283 switch (advance_selector) {
284 case 0:
285 std_chrominance_qt = Tbl_000Y;
286 break;
287 case 1:
288 std_chrominance_qt = Tbl_014Y;
289 break;
290 case 2:
291 std_chrominance_qt = Tbl_029Y;
292 break;
293 case 3:
294 std_chrominance_qt = Tbl_043Y;
295 break;
296 case 4:
297 std_chrominance_qt = Tbl_057Y;
298 break;
299 case 5:
300 std_chrominance_qt = Tbl_071Y;
301 break;
302 case 6:
303 std_chrominance_qt = Tbl_086Y;
304 break;
305 case 7:
306 std_chrominance_qt = Tbl_100Y;
307 break;
308 }
309 } else {
310 switch (advance_selector) {
311 case 0:
312 std_chrominance_qt = Tbl_000UV;
313 break;
314 case 1:
315 std_chrominance_qt = Tbl_014UV;
316 break;
317 case 2:
318 std_chrominance_qt = Tbl_029UV;
319 break;
320 case 3:
321 std_chrominance_qt = Tbl_043UV;
322 break;
323 case 4:
324 std_chrominance_qt = Tbl_057UV;
325 break;
326 case 5:
327 std_chrominance_qt = Tbl_071UV;
328 break;
329 case 6:
330 std_chrominance_qt = Tbl_086UV;
331 break;
332 case 7:
333 std_chrominance_qt = Tbl_100UV;
334 break;
335 }
336 }
337 // Note: pass ADVANCE SCALE FACTOR to sub-function in Dual-JPEG
338 set_quant_table(std_chrominance_qt, (uint8_t)ADVANCESCALEFACTORUV, tempQT);
339
340 for (j = 0; j <= 63; j++) quant_table[j] = tempQT[zigzag[j]];
341 j = 0;
342 for (row = 0; row <= 7; row++)
343 for (col = 0; col <= 7; col++) {
344 quant_table[j] =
345 (long)((quant_table[j] * scalefactor[row] * scalefactor[col]) *
346 65536);
347 j++;
348 }
349 byte_pos += 64;
350 }
351
352 void IDCT_transform(short *coef, uint8_t *data, uint8_t nBlock) {
353#define FIX_1_082392200 ((int)277) /* FIX(1.082392200) */
354#define FIX_1_414213562 ((int)362) /* FIX(1.414213562) */
355#define FIX_1_847759065 ((int)473) /* FIX(1.847759065) */
356#define FIX_2_613125930 ((int)669) /* FIX(2.613125930) */
357
358#define MULTIPLY(var, cons) ((int)((var) * (cons)) >> 8)
359
360 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
361 int tmp10, tmp11, tmp12, tmp13;
362 int z5, z10, z11, z12, z13;
363 int workspace[64]; /* buffers data between passes */
364
365 short *inptr = coef;
366 long *quantptr;
367 int *wsptr = workspace;
368 unsigned char *outptr;
369 unsigned char *r_limit = rlimit_table + 128;
370 int ctr, dcval, DCTSIZE = 8;
371
372 quantptr = &QT[nBlock][0];
373
374 // Pass 1: process columns from input (inptr), store into work array(wsptr)
375
376 for (ctr = 8; ctr > 0; ctr--) {
377 /* Due to quantization, we will usually find that many of the input
378 * coefficients are zero, especially the AC terms. We can exploit this
379 * by short-circuiting the IDCT calculation for any column in which all
380 * the AC terms are zero. In that case each output is equal to the
381 * DC coefficient (with scale factor as needed).
382 * With typical images and quantization tables, half or more of the
383 * column DCT calculations can be simplified this way.
384 */
385
386 if ((inptr[DCTSIZE * 1] | inptr[DCTSIZE * 2] | inptr[DCTSIZE * 3] |
387 inptr[DCTSIZE * 4] | inptr[DCTSIZE * 5] | inptr[DCTSIZE * 6] |
388 inptr[DCTSIZE * 7]) == 0) {
389 /* AC terms all zero */
390 dcval = (int)((inptr[DCTSIZE * 0] * quantptr[DCTSIZE * 0]) >> 16);
391
392 wsptr[DCTSIZE * 0] = dcval;
393 wsptr[DCTSIZE * 1] = dcval;
394 wsptr[DCTSIZE * 2] = dcval;
395 wsptr[DCTSIZE * 3] = dcval;
396 wsptr[DCTSIZE * 4] = dcval;
397 wsptr[DCTSIZE * 5] = dcval;
398 wsptr[DCTSIZE * 6] = dcval;
399 wsptr[DCTSIZE * 7] = dcval;
400
401 inptr++; /* advance pointers to next column */
402 quantptr++;
403 wsptr++;
404 continue;
405 }
406
407 /* Even part */
408
409 tmp0 = (inptr[DCTSIZE * 0] * quantptr[DCTSIZE * 0]) >> 16;
410 tmp1 = (inptr[DCTSIZE * 2] * quantptr[DCTSIZE * 2]) >> 16;
411 tmp2 = (inptr[DCTSIZE * 4] * quantptr[DCTSIZE * 4]) >> 16;
412 tmp3 = (inptr[DCTSIZE * 6] * quantptr[DCTSIZE * 6]) >> 16;
413
414 tmp10 = tmp0 + tmp2; /* phase 3 */
415 tmp11 = tmp0 - tmp2;
416
417 tmp13 = tmp1 + tmp3; /* phases 5-3 */
418 tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
419
420 tmp0 = tmp10 + tmp13; /* phase 2 */
421 tmp3 = tmp10 - tmp13;
422 tmp1 = tmp11 + tmp12;
423 tmp2 = tmp11 - tmp12;
424
425 /* Odd part */
426
427 tmp4 = (inptr[DCTSIZE * 1] * quantptr[DCTSIZE * 1]) >> 16;
428 tmp5 = (inptr[DCTSIZE * 3] * quantptr[DCTSIZE * 3]) >> 16;
429 tmp6 = (inptr[DCTSIZE * 5] * quantptr[DCTSIZE * 5]) >> 16;
430 tmp7 = (inptr[DCTSIZE * 7] * quantptr[DCTSIZE * 7]) >> 16;
431
432 z13 = tmp6 + tmp5; /* phase 6 */
433 z10 = tmp6 - tmp5;
434 z11 = tmp4 + tmp7;
435 z12 = tmp4 - tmp7;
436
437 tmp7 = z11 + z13; /* phase 5 */
438 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
439
440 z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
441 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
442 tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; /* -2*(c2+c6) */
443
444 tmp6 = tmp12 - tmp7; /* phase 2 */
445 tmp5 = tmp11 - tmp6;
446 tmp4 = tmp10 + tmp5;
447
448 wsptr[DCTSIZE * 0] = (int)(tmp0 + tmp7);
449 wsptr[DCTSIZE * 7] = (int)(tmp0 - tmp7);
450 wsptr[DCTSIZE * 1] = (int)(tmp1 + tmp6);
451 wsptr[DCTSIZE * 6] = (int)(tmp1 - tmp6);
452 wsptr[DCTSIZE * 2] = (int)(tmp2 + tmp5);
453 wsptr[DCTSIZE * 5] = (int)(tmp2 - tmp5);
454 wsptr[DCTSIZE * 4] = (int)(tmp3 + tmp4);
455 wsptr[DCTSIZE * 3] = (int)(tmp3 - tmp4);
456
457 inptr++; /* advance pointers to next column */
458 quantptr++;
459 wsptr++;
460 }
461
462/* Pass 2: process rows from work array, store into output array. */
463/* Note that we must descale the results by a factor of 8 == 2**3, */
464/* and also undo the PASS1_BITS scaling. */
465
466//#define RANGE_MASK 1023; //2 bits wider than legal samples
467#define PASS1_BITS 0
468#define IDESCALE(x, n) ((int)((x) >> n))
469
470 wsptr = workspace;
471 for (ctr = 0; ctr < DCTSIZE; ctr++) {
472 outptr = data + ctr * 8;
473
474 /* Rows of zeroes can be exploited in the same way as we did with columns.
475 * However, the column calculation has created many nonzero AC terms, so
476 * the simplification applies less often (typically 5% to 10% of the time).
477 * On machines with very fast multiplication, it's possible that the
478 * test takes more time than it's worth. In that case this section
479 * may be commented out.
480 */
481 /* Even part */
482
483 tmp10 = ((int)wsptr[0] + (int)wsptr[4]);
484 tmp11 = ((int)wsptr[0] - (int)wsptr[4]);
485
486 tmp13 = ((int)wsptr[2] + (int)wsptr[6]);
487 tmp12 = MULTIPLY((int)wsptr[2] - (int)wsptr[6], FIX_1_414213562) - tmp13;
488
489 tmp0 = tmp10 + tmp13;
490 tmp3 = tmp10 - tmp13;
491 tmp1 = tmp11 + tmp12;
492 tmp2 = tmp11 - tmp12;
493
494 /* Odd part */
495
496 z13 = (int)wsptr[5] + (int)wsptr[3];
497 z10 = (int)wsptr[5] - (int)wsptr[3];
498 z11 = (int)wsptr[1] + (int)wsptr[7];
499 z12 = (int)wsptr[1] - (int)wsptr[7];
500
501 tmp7 = z11 + z13; /* phase 5 */
502 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
503
504 z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
505 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
506 tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; /* -2*(c2+c6) */
507
508 tmp6 = tmp12 - tmp7; /* phase 2 */
509 tmp5 = tmp11 - tmp6;
510 tmp4 = tmp10 + tmp5;
511
512 /* Final output stage: scale down by a factor of 8 and range-limit */
513
514 outptr[0] = r_limit[IDESCALE((tmp0 + tmp7), (PASS1_BITS + 3)) & 1023L];
515 outptr[7] = r_limit[IDESCALE((tmp0 - tmp7), (PASS1_BITS + 3)) & 1023L];
516 outptr[1] = r_limit[IDESCALE((tmp1 + tmp6), (PASS1_BITS + 3)) & 1023L];
517 outptr[6] = r_limit[IDESCALE((tmp1 - tmp6), (PASS1_BITS + 3)) & 1023L];
518 outptr[2] = r_limit[IDESCALE((tmp2 + tmp5), (PASS1_BITS + 3)) & 1023L];
519 outptr[5] = r_limit[IDESCALE((tmp2 - tmp5), (PASS1_BITS + 3)) & 1023L];
520 outptr[4] = r_limit[IDESCALE((tmp3 + tmp4), (PASS1_BITS + 3)) & 1023L];
521 outptr[3] = r_limit[IDESCALE((tmp3 - tmp4), (PASS1_BITS + 3)) & 1023L];
522
523 wsptr += DCTSIZE; /* advance pointer to next row */
524 }
525 }
526 void YUVToRGB(
527 int txb, int tyb,
528 unsigned char
529 *pYCbCr, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
530 struct RGB *pYUV, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
531 unsigned char
532 *pBgr // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
533 ) {
534 int i, j, pos, m, n;
535 unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
536 int y;
537 struct RGB *pByte;
538 int nBlocksInMcu = 6;
539 unsigned int pixel_x, pixel_y;
540
541 pByte = (struct RGB *)pBgr;
542 if (yuvmode == YuvMode::YUV444) {
543 py = pYCbCr;
544 pcb = pYCbCr + 64;
545 pcr = pcb + 64;
546
547 pixel_x = txb * 8;
548 pixel_y = tyb * 8;
549 pos = (pixel_y * WIDTH) + pixel_x;
550
551 for (j = 0; j < 8; j++) {
552 for (i = 0; i < 8; i++) {
553 m = ((j << 3) + i);
554 y = py[m];
555 cb = pcb[m];
556 cr = pcr[m];
557 n = pos + i;
558 // For 2Pass. Save the YUV value
559 pYUV[n].B = cb;
560 pYUV[n].G = y;
561 pYUV[n].R = cr;
Ed Tanousd5f39992017-04-18 13:41:22 -0700562 pByte[n].B = rlimit_table[m_Y[y] + m_CbToB[cb]];
563 pByte[n].G = rlimit_table[m_Y[y] + m_CbToG[cb] + m_CrToG[cr]];
564 pByte[n].R = rlimit_table[m_Y[y] + m_CrToR[cr]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700565 }
566 pos += WIDTH;
567 }
568 } else {
569 for (i = 0; i < nBlocksInMcu - 2; i++) py420[i] = pYCbCr + i * 64;
570 pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
571 pcr = pcb + 64;
572
573 pixel_x = txb * 16;
574 pixel_y = tyb * 16;
575 pos = (pixel_y * WIDTH) + pixel_x;
576
577 for (j = 0; j < 16; j++) {
578 for (i = 0; i < 16; i++) {
579 // block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
580 y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
581 m = ((j >> 1) << 3) + (i >> 1);
582 cb = pcb[m];
583 cr = pcr[m];
584 n = pos + i;
Ed Tanousd5f39992017-04-18 13:41:22 -0700585 pByte[n].B = rlimit_table[m_Y[y] + m_CbToB[cb]];
586 pByte[n].G = rlimit_table[m_Y[y] + m_CbToG[cb] + m_CrToG[cr]];
587 pByte[n].R = rlimit_table[m_Y[y] + m_CrToR[cr]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700588 }
589 pos += WIDTH;
590 }
591 }
592 }
593 void YUVToBuffer(
594 int txb, int tyb,
595 unsigned char
596 *pYCbCr, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
597 struct RGB
598 *pYUV, // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
599 unsigned char
600 *pBgr // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
601 ) {
602 int i, j, pos, m, n;
603 unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
604 int y;
605 struct RGB *pByte;
606 int nBlocksInMcu = 6;
607 unsigned int pixel_x, pixel_y;
608
609 pByte = (struct RGB *)pBgr;
610 if (yuvmode == YuvMode::YUV444) {
611 py = pYCbCr;
612 pcb = pYCbCr + 64;
613 pcr = pcb + 64;
614
615 pixel_x = txb * 8;
616 pixel_y = tyb * 8;
617 pos = (pixel_y * WIDTH) + pixel_x;
618
619 for (j = 0; j < 8; j++) {
620 for (i = 0; i < 8; i++) {
621 m = ((j << 3) + i);
622 n = pos + i;
623 y = pYUV[n].G + (py[m] - 128);
624 cb = pYUV[n].B + (pcb[m] - 128);
625 cr = pYUV[n].R + (pcr[m] - 128);
626 pYUV[n].B = cb;
627 pYUV[n].G = y;
628 pYUV[n].R = cr;
Ed Tanousd5f39992017-04-18 13:41:22 -0700629 pByte[n].B = rlimit_table[m_Y[y] + m_CbToB[cb]];
630 pByte[n].G = rlimit_table[m_Y[y] + m_CbToG[cb] + m_CrToG[cr]];
631 pByte[n].R = rlimit_table[m_Y[y] + m_CrToR[cr]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700632 }
633 pos += WIDTH;
634 }
635 } else {
636 for (i = 0; i < nBlocksInMcu - 2; i++) py420[i] = pYCbCr + i * 64;
637 pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
638 pcr = pcb + 64;
639
640 pixel_x = txb * 16;
641 pixel_y = tyb * 16;
642 pos = (pixel_y * WIDTH) + pixel_x;
643
644 for (j = 0; j < 16; j++) {
645 for (i = 0; i < 16; i++) {
646 // block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
647 y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
648 m = ((j >> 1) << 3) + (i >> 1);
649 cb = pcb[m];
650 cr = pcr[m];
651 n = pos + i;
Ed Tanousd5f39992017-04-18 13:41:22 -0700652 pByte[n].B = rlimit_table[m_Y[y] + m_CbToB[cb]];
653 pByte[n].G = rlimit_table[m_Y[y] + m_CbToG[cb] + m_CrToG[cr]];
654 pByte[n].R = rlimit_table[m_Y[y] + m_CrToR[cr]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700655 }
656 pos += WIDTH;
657 }
658 }
659 }
Ed Tanous1ff48782017-04-18 12:45:08 -0700660 void Decompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700661 unsigned char *ptr;
662 unsigned char byTileYuv[768] = {};
663
664 memset(DCT_coeff, 0, 384 * 2);
665 ptr = byTileYuv;
666 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 0);
667 IDCT_transform(DCT_coeff, ptr, QT_TableSelection);
668 ptr += 64;
669
670 if (yuvmode == YuvMode::YUV420) {
671 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 64);
672 IDCT_transform(DCT_coeff + 64, ptr, QT_TableSelection);
673 ptr += 64;
674
675 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 128);
676 IDCT_transform(DCT_coeff + 128, ptr, QT_TableSelection);
677 ptr += 64;
678
679 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 192);
680 IDCT_transform(DCT_coeff + 192, ptr, QT_TableSelection);
681 ptr += 64;
682
683 process_Huffman_data_unit(CbDC_nr, CbAC_nr, &DCCb, 256);
684 IDCT_transform(DCT_coeff + 256, ptr, QT_TableSelection + 1);
685 ptr += 64;
686
687 process_Huffman_data_unit(CrDC_nr, CrAC_nr, &DCCr, 320);
688 IDCT_transform(DCT_coeff + 320, ptr, QT_TableSelection + 1);
689 } else {
690 process_Huffman_data_unit(CbDC_nr, CbAC_nr, &DCCb, 64);
691 IDCT_transform(DCT_coeff + 64, ptr, QT_TableSelection + 1);
692 ptr += 64;
693
694 process_Huffman_data_unit(CrDC_nr, CrAC_nr, &DCCr, 128);
695 IDCT_transform(DCT_coeff + 128, ptr, QT_TableSelection + 1);
696 }
697
698 // YUVToRGB (txb, tyb, byTileYuv, (unsigned char *)outBuf);
699 // YUVBuffer for YUV record
700 YUVToRGB(txb, tyb, byTileYuv, YUVBuffer.data(), (unsigned char *)outBuf);
Ed Tanous93f987d2017-04-17 17:52:36 -0700701 }
702
Ed Tanous1ff48782017-04-18 12:45:08 -0700703 void Decompress_2PASS(int txb, int tyb, char *outBuf,
704 uint8_t QT_TableSelection) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700705 unsigned char *ptr;
706 unsigned char byTileYuv[768];
707 memset(DCT_coeff, 0, 384 * 2);
708
709 ptr = byTileYuv;
710 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 0);
711 IDCT_transform(DCT_coeff, ptr, QT_TableSelection);
712 ptr += 64;
713
714 process_Huffman_data_unit(CbDC_nr, CbAC_nr, &DCCb, 64);
715 IDCT_transform(DCT_coeff + 64, ptr, QT_TableSelection + 1);
716 ptr += 64;
717
718 process_Huffman_data_unit(CrDC_nr, CrAC_nr, &DCCr, 128);
719 IDCT_transform(DCT_coeff + 128, ptr, QT_TableSelection + 1);
720
721 YUVToBuffer(txb, tyb, byTileYuv, YUVBuffer.data(), (unsigned char *)outBuf);
722 // YUVToRGB (txb, tyb, byTileYuv, (unsigned char *)outBuf);
Ed Tanous93f987d2017-04-17 17:52:36 -0700723 }
724
Ed Tanous1ff48782017-04-18 12:45:08 -0700725 void VQ_Decompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection,
726 struct COLOR_CACHE *VQ) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700727 unsigned char *ptr, i;
728 unsigned char byTileYuv[192];
729 int Data;
730
731 ptr = byTileYuv;
732 if (VQ->BitMapBits == 0) {
733 for (i = 0; i < 64; i++) {
734 ptr[0] = (VQ->Color[VQ->Index[0]] & 0xFF0000) >> 16;
735 ptr[64] = (VQ->Color[VQ->Index[0]] & 0x00FF00) >> 8;
736 ptr[128] = VQ->Color[VQ->Index[0]] & 0x0000FF;
737 ptr += 1;
738 }
739 } else {
740 for (i = 0; i < 64; i++) {
741 Data = (int)lookKbits(VQ->BitMapBits);
742 ptr[0] = (VQ->Color[VQ->Index[Data]] & 0xFF0000) >> 16;
743 ptr[64] = (VQ->Color[VQ->Index[Data]] & 0x00FF00) >> 8;
744 ptr[128] = VQ->Color[VQ->Index[Data]] & 0x0000FF;
745 ptr += 1;
746 skipKbits(VQ->BitMapBits);
747 }
748 }
749 // YUVToRGB (txb, tyb, byTileYuv, (unsigned char *)outBuf);
750 YUVToRGB(txb, tyb, byTileYuv, YUVBuffer.data(), (unsigned char *)outBuf);
Ed Tanous93f987d2017-04-17 17:52:36 -0700751 }
752
753 void MoveBlockIndex(void) {
754 if (yuvmode == YuvMode::YUV444) {
755 txb++;
Ed Tanousb078cf32017-04-18 14:51:21 -0700756 if (txb >= (int)(WIDTH / 8)) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700757 tyb++;
Ed Tanousb078cf32017-04-18 14:51:21 -0700758 if (tyb >= (int)(HEIGHT / 8)) tyb = 0;
Ed Tanous93f987d2017-04-17 17:52:36 -0700759 txb = 0;
760 }
761 } else {
762 txb++;
Ed Tanousb078cf32017-04-18 14:51:21 -0700763 if (txb >= (int)(WIDTH / 16)) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700764 tyb++;
Ed Tanousb078cf32017-04-18 14:51:21 -0700765 if (tyb >= (int)(HEIGHT / 16)) tyb = 0;
Ed Tanous93f987d2017-04-17 17:52:36 -0700766 txb = 0;
767 }
768 }
769 }
770
Ed Tanous93f987d2017-04-17 17:52:36 -0700771 void Init_Color_Table() {
772 int i, x;
773 int nScale = 1L << 16; // equal to power(2,16)
774 int nHalf = nScale >> 1;
775
776#define FIX(x) ((int)((x)*nScale + 0.5))
777
778 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
779 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
780 /* Cr=>R value is nearest int to 1.597656 * x */
781 /* Cb=>B value is nearest int to 2.015625 * x */
782 /* Cr=>G value is scaled-up -0.8125 * x */
783 /* Cb=>G value is scaled-up -0.390625 * x */
784 for (i = 0, x = -128; i < 256; i++, x++) {
785 m_CrToR[i] = (int)(FIX(1.597656) * x + nHalf) >> 16;
786 m_CbToB[i] = (int)(FIX(2.015625) * x + nHalf) >> 16;
787 m_CrToG[i] = (int)(-FIX(0.8125) * x + nHalf) >> 16;
788 m_CbToG[i] = (int)(-FIX(0.390625) * x + nHalf) >> 16;
789 }
790 for (i = 0, x = -16; i < 256; i++, x++) {
791 m_Y[i] = (int)(FIX(1.164) * x + nHalf) >> 16;
792 }
793 // For Color Text Enchance Y Re-map. Recommend to disable in default
794 /*
795 for (i = 0; i < (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate);
796 i++) {
797 temp = (double)i /
798 VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate;
799 temp1 = 1.0 / VideoEngineInfo->INFData.Gamma1Parameter;
800 m_Y[i] =
801 (BYTE)(VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate * pow (temp,
802 temp1));
803 if (m_Y[i] > 255) m_Y[i] = 255;
804 }
805 for (i = (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate); i < 256;
806 i++) {
807 m_Y[i] =
808 (BYTE)((VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) + (256 -
809 VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) * ( pow((double)((i -
810 VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) / (256 -
811 (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate))), (1.0 /
812 VideoEngineInfo->INFData.Gamma2Parameter)) ));
813 if (m_Y[i] > 255) m_Y[i] = 255;
814 }
815 */
816 }
Ed Tanous9140a672017-04-24 17:01:32 -0700817 void load_Huffman_table(Huffman_table *HT, const unsigned char *nrcode,
818 const unsigned char *value,
819 const unsigned short int *Huff_code) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700820 unsigned char k, j, i;
821 unsigned int code, code_index;
822
823 for (j = 1; j <= 16; j++) {
824 HT->Length[j] = nrcode[j];
825 }
826 for (i = 0, k = 1; k <= 16; k++)
827 for (j = 0; j < HT->Length[k]; j++) {
828 HT->V[WORD_hi_lo(k, j)] = value[i];
829 i++;
830 }
831
832 code = 0;
833 for (k = 1; k <= 16; k++) {
834 HT->minor_code[k] = (unsigned short int)code;
835 for (j = 1; j <= HT->Length[k]; j++) code++;
836 HT->major_code[k] = (unsigned short int)(code - 1);
837 code *= 2;
838 if (HT->Length[k] == 0) {
839 HT->minor_code[k] = 0xFFFF;
840 HT->major_code[k] = 0;
841 }
842 }
843
844 HT->Len[0] = 2;
845 i = 2;
846
847 for (code_index = 1; code_index < 65535; code_index++) {
848 if (code_index < Huff_code[i]) {
849 HT->Len[code_index] = (unsigned char)Huff_code[i + 1];
850 } else {
851 i = i + 2;
852 HT->Len[code_index] = (unsigned char)Huff_code[i + 1];
853 }
854 }
855 }
856 void init_jpg_table() {
Ed Tanous93f987d2017-04-17 17:52:36 -0700857 Init_Color_Table();
858 prepare_range_limit_table();
859 load_Huffman_table(&HTDC[0], std_dc_luminance_nrcodes,
860 std_dc_luminance_values, DC_LUMINANCE_HUFFMANCODE);
861 load_Huffman_table(&HTAC[0], std_ac_luminance_nrcodes,
862 std_ac_luminance_values, AC_LUMINANCE_HUFFMANCODE);
863 load_Huffman_table(&HTDC[1], std_dc_chrominance_nrcodes,
864 std_dc_chrominance_values, DC_CHROMINANCE_HUFFMANCODE);
865 load_Huffman_table(&HTAC[1], std_ac_chrominance_nrcodes,
866 std_ac_chrominance_values, AC_CHROMINANCE_HUFFMANCODE);
867 }
868
869 void prepare_range_limit_table()
870 /* Allocate and fill in the sample_range_limit table */
871 {
872 int j;
873 rlimit_table = (unsigned char *)malloc(5 * 256L + 128);
874 /* First segment of "simple" table: limit[x] = 0 for x < 0 */
875 memset((void *)rlimit_table, 0, 256);
876 rlimit_table += 256; /* allow negative subscripts of simple table */
877 /* Main part of "simple" table: limit[x] = x */
878 for (j = 0; j < 256; j++) rlimit_table[j] = j;
879 /* End of simple table, rest of first half of post-IDCT table */
880 for (j = 256; j < 640; j++) rlimit_table[j] = 255;
881
882 /* Second half of post-IDCT table */
883 memset((void *)(rlimit_table + 640), 0, 384);
884 for (j = 0; j < 128; j++) rlimit_table[j + 1024] = j;
885 }
886
887 inline unsigned short int WORD_hi_lo(uint8_t byte_high, uint8_t byte_low) {
888 return (byte_high << 8) + byte_low;
889 }
890
891 // river
892 void process_Huffman_data_unit(uint8_t DC_nr, uint8_t AC_nr,
893 signed short int *previous_DC,
894 unsigned short int position) {
895 uint8_t nr = 0;
896 uint8_t k;
897 unsigned short int tmp_Hcode;
898 uint8_t size_val, count_0;
899 unsigned short int *min_code;
900 uint8_t *huff_values;
901 uint8_t byte_temp;
902
903 min_code = HTDC[DC_nr].minor_code;
904 // maj_code=HTDC[DC_nr].major_code;
905 huff_values = HTDC[DC_nr].V;
906
907 // DC
908 k = HTDC[DC_nr].Len[(unsigned short int)(codebuf >> 16)];
909 // river
910 // tmp_Hcode=lookKbits(k);
911 tmp_Hcode = (unsigned short int)(codebuf >> (32 - k));
912 skipKbits(k);
913 size_val = huff_values[WORD_hi_lo(k, (uint8_t)(tmp_Hcode - min_code[k]))];
914 if (size_val == 0)
915 DCT_coeff[position + 0] = *previous_DC;
916 else {
917 DCT_coeff[position + 0] = *previous_DC + getKbits(size_val);
918 *previous_DC = DCT_coeff[position + 0];
919 }
920
921 // Second, AC coefficient decoding
922 min_code = HTAC[AC_nr].minor_code;
923 // maj_code=HTAC[AC_nr].major_code;
924 huff_values = HTAC[AC_nr].V;
925
926 nr = 1; // AC coefficient
927 do {
928 k = HTAC[AC_nr].Len[(unsigned short int)(codebuf >> 16)];
929 tmp_Hcode = (unsigned short int)(codebuf >> (32 - k));
930 skipKbits(k);
931
932 byte_temp =
933 huff_values[WORD_hi_lo(k, (uint8_t)(tmp_Hcode - min_code[k]))];
934 size_val = byte_temp & 0xF;
935 count_0 = byte_temp >> 4;
936 if (size_val == 0) {
937 if (count_0 != 0xF) {
938 break;
939 }
940 nr += 16;
941 } else {
942 nr += count_0; // skip count_0 zeroes
943 DCT_coeff[position + dezigzag[nr++]] = getKbits(size_val);
944 }
945 } while (nr < 64);
946 }
947
948 unsigned short int lookKbits(uint8_t k) {
949 unsigned short int revcode;
950
951 revcode = (unsigned short int)(codebuf >> (32 - k));
952
953 return (revcode);
954 }
955
956 void skipKbits(uint8_t k) {
957 unsigned long readbuf;
958
959 if ((newbits - k) <= 0) {
960 readbuf = Buffer[buffer_index];
961 buffer_index++;
962 codebuf =
963 (codebuf << k) | ((newbuf | (readbuf >> (newbits))) >> (32 - k));
964 newbuf = readbuf << (k - newbits);
965 newbits = 32 + newbits - k;
966 } else {
967 codebuf = (codebuf << k) | (newbuf >> (32 - k));
968 newbuf = newbuf << k;
969 newbits -= k;
970 }
971 }
972
973 signed short int getKbits(uint8_t k) {
974 signed short int signed_wordvalue;
975
976 // river
977 // signed_wordvalue=lookKbits(k);
978 signed_wordvalue = (unsigned short int)(codebuf >> (32 - k));
979 if (((1L << (k - 1)) & signed_wordvalue) == 0) {
980 // neg_pow2 was previously defined as the below. It seemed silly to keep
981 // a table of values around for something
982 // THat's relatively easy to compute, so it was replaced with the
983 // appropriate math
984 // signed_wordvalue = signed_wordvalue - (0xFFFF >> (16 - k));
985 std::array<signed short int, 17> neg_pow2 = {
986 0, -1, -3, -7, -15, -31, -63, -127,
987 -255, -511, -1023, -2047, -4095, -8191, -16383, -32767};
988
989 signed_wordvalue = signed_wordvalue + neg_pow2[k];
990 }
991 skipKbits(k);
992 return signed_wordvalue;
993 }
994 int init_JPG_decoding() {
995 byte_pos = 0;
996 load_quant_table(QT[0]);
997 load_quant_tableCb(QT[1]);
998 // Note: Added for Dual-JPEG
999 load_advance_quant_table(QT[2]);
1000 load_advance_quant_tableCb(QT[3]);
1001 return 1;
1002 }
1003
Ed Tanous9140a672017-04-24 17:01:32 -07001004 void set_quant_table(const uint8_t *basic_table, uint8_t scale_factor,
Ed Tanous93f987d2017-04-17 17:52:36 -07001005 uint8_t *newtable)
1006 // Set quantization table and zigzag reorder it
1007 {
1008 uint8_t i;
1009 long temp;
1010 for (i = 0; i < 64; i++) {
1011 temp = ((long)(basic_table[i] * 16) / scale_factor);
1012 /* limit the values to the valid range */
1013 if (temp <= 0L) temp = 1L;
1014 if (temp > 255L) temp = 255L; /* limit to baseline range if requested */
1015 newtable[zigzag[i]] = (uint8_t)temp;
1016 }
1017 }
1018
1019 void updatereadbuf(uint32_t *codebuf, uint32_t *newbuf, int walks,
1020 int *newbits, std::vector<uint32_t> &Buffer) {
1021 unsigned long readbuf;
1022
1023 if ((*newbits - walks) <= 0) {
1024 readbuf = Buffer[buffer_index];
1025 buffer_index++;
1026 *codebuf = (*codebuf << walks) |
1027 ((*newbuf | (readbuf >> (*newbits))) >> (32 - walks));
1028 *newbuf = readbuf << (walks - *newbits);
1029 *newbits = 32 + *newbits - walks;
1030 } else {
1031 *codebuf = (*codebuf << walks) | (*newbuf >> (32 - walks));
1032 *newbuf = *newbuf << walks;
1033 *newbits -= walks;
1034 }
1035 }
1036
1037 uint32_t decode(std::vector<uint32_t> &buffer, unsigned long width,
1038 unsigned long height, YuvMode yuvmode_in, int y_selector,
1039 int uv_selector) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001040 COLOR_CACHE Decode_Color;
Ed Tanousb078cf32017-04-18 14:51:21 -07001041 if (width != USER_WIDTH || height != USER_HEIGHT || yuvmode_in != yuvmode ||
1042 y_selector != Y_selector || uv_selector != UV_selector) {
1043 yuvmode = yuvmode_in;
1044 Y_selector = y_selector; // 0-7
1045 UV_selector = uv_selector; // 0-7
1046 USER_HEIGHT = height;
1047 USER_WIDTH = width;
1048 WIDTH = width;
1049 HEIGHT = height;
Ed Tanous93f987d2017-04-17 17:52:36 -07001050
Ed Tanousb078cf32017-04-18 14:51:21 -07001051 // TODO(ed) Magic number section. Document appropriately
1052 advance_selector = 0; // 0-7
1053 Mapping = 0; // 0 or 1
Ed Tanous1ff48782017-04-18 12:45:08 -07001054
Ed Tanousb078cf32017-04-18 14:51:21 -07001055 if (yuvmode == YuvMode::YUV420) {
1056 if (WIDTH % 16) {
1057 WIDTH = WIDTH + 16 - (WIDTH % 16);
1058 }
1059 if (HEIGHT % 16) {
1060 HEIGHT = HEIGHT + 16 - (HEIGHT % 16);
1061 }
1062 } else {
1063 if (WIDTH % 8) {
1064 WIDTH = WIDTH + 8 - (WIDTH % 8);
1065 }
1066 if (HEIGHT % 8) {
1067 HEIGHT = HEIGHT + 8 - (HEIGHT % 8);
1068 }
1069 }
Ed Tanous93f987d2017-04-17 17:52:36 -07001070
Ed Tanouscc9e2c22017-04-18 14:32:02 -07001071 init_JPG_decoding();
1072 }
1073 // TODO(ed) cleanup cruft
Ed Tanous93f987d2017-04-17 17:52:36 -07001074 Buffer = buffer.data();
1075
1076 codebuf = buffer[0];
1077 newbuf = buffer[1];
1078 buffer_index = 2;
1079
1080 txb = tyb = 0;
1081 newbits = 32;
1082 DCY = DCCb = DCCr = 0;
1083
Ed Tanous1ff48782017-04-18 12:45:08 -07001084 static const uint32_t VQ_HEADER_MASK = 0x01;
1085 static const uint32_t VQ_NO_UPDATE_HEADER = 0x00;
1086 static const uint32_t VQ_UPDATE_HEADER = 0x01;
1087 static const int VQ_NO_UPDATE_LENGTH = 0x03;
1088 static const int VQ_UPDATE_LENGTH = 0x1B;
1089 static const uint32_t VQ_INDEX_MASK = 0x03;
1090 static const uint32_t VQ_COLOR_MASK = 0xFFFFFF;
1091
1092 static const int BLOCK_AST2100_START_LENGTH = 0x04;
1093 static const int BLOCK_AST2100_SKIP_LENGTH = 20; // S:1 H:3 X:8 Y:8
1094
Ed Tanous93f987d2017-04-17 17:52:36 -07001095 do {
1096 auto block_header = static_cast<JpgBlock>((codebuf >> 28) & 0xFF);
1097 switch (block_header) {
1098 case JpgBlock::JPEG_NO_SKIP_CODE:
1099 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_START_LENGTH, &newbits,
1100 buffer);
1101 Decompress(txb, tyb, (char *)OutBuffer.data(), 0);
1102 break;
1103 case JpgBlock::FRAME_END_CODE:
1104 return 0;
1105 break;
1106 case JpgBlock::JPEG_SKIP_CODE:
1107
1108 txb = (codebuf & 0x0FF00000) >> 20;
1109 tyb = (codebuf & 0x0FF000) >> 12;
1110
1111 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_SKIP_LENGTH, &newbits,
1112 buffer);
1113 Decompress(txb, tyb, (char *)OutBuffer.data(), 0);
1114 break;
1115 case JpgBlock::VQ_NO_SKIP_1_COLOR_CODE:
1116 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_START_LENGTH, &newbits,
1117 buffer);
1118 Decode_Color.BitMapBits = 0;
1119
Ed Tanousd5f39992017-04-18 13:41:22 -07001120 for (int i = 0; i < 1; i++) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001121 Decode_Color.Index[i] = ((codebuf >> 29) & VQ_INDEX_MASK);
1122 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1123 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1124 buffer);
1125 } else {
1126 Decode_Color.Color[Decode_Color.Index[i]] =
1127 ((codebuf >> 5) & VQ_COLOR_MASK);
1128 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1129 buffer);
1130 }
1131 }
1132 VQ_Decompress(txb, tyb, (char *)OutBuffer.data(), 0, &Decode_Color);
1133 break;
1134 case JpgBlock::VQ_SKIP_1_COLOR_CODE:
1135 txb = (codebuf & 0x0FF00000) >> 20;
1136 tyb = (codebuf & 0x0FF000) >> 12;
1137
1138 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_SKIP_LENGTH, &newbits,
1139 buffer);
1140 Decode_Color.BitMapBits = 0;
1141
Ed Tanousd5f39992017-04-18 13:41:22 -07001142 for (int i = 0; i < 1; i++) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001143 Decode_Color.Index[i] = ((codebuf >> 29) & VQ_INDEX_MASK);
1144 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1145 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1146 buffer);
1147 } else {
1148 Decode_Color.Color[Decode_Color.Index[i]] =
1149 ((codebuf >> 5) & VQ_COLOR_MASK);
1150 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1151 buffer);
1152 }
1153 }
1154 VQ_Decompress(txb, tyb, (char *)OutBuffer.data(), 0, &Decode_Color);
1155 break;
1156
1157 case JpgBlock::VQ_NO_SKIP_2_COLOR_CODE:
1158 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_START_LENGTH, &newbits,
1159 buffer);
1160 Decode_Color.BitMapBits = 1;
1161
Ed Tanousd5f39992017-04-18 13:41:22 -07001162 for (int i = 0; i < 2; i++) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001163 Decode_Color.Index[i] = ((codebuf >> 29) & VQ_INDEX_MASK);
1164 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1165 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1166 buffer);
1167 } else {
1168 Decode_Color.Color[Decode_Color.Index[i]] =
1169 ((codebuf >> 5) & VQ_COLOR_MASK);
1170 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1171 buffer);
1172 }
1173 }
1174 VQ_Decompress(txb, tyb, (char *)OutBuffer.data(), 0, &Decode_Color);
1175 break;
1176 case JpgBlock::VQ_SKIP_2_COLOR_CODE:
1177 txb = (codebuf & 0x0FF00000) >> 20;
1178 tyb = (codebuf & 0x0FF000) >> 12;
1179
1180 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_SKIP_LENGTH, &newbits,
1181 buffer);
1182 Decode_Color.BitMapBits = 1;
1183
Ed Tanousd5f39992017-04-18 13:41:22 -07001184 for (int i = 0; i < 2; i++) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001185 Decode_Color.Index[i] = ((codebuf >> 29) & VQ_INDEX_MASK);
1186 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1187 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1188 buffer);
1189 } else {
1190 Decode_Color.Color[Decode_Color.Index[i]] =
1191 ((codebuf >> 5) & VQ_COLOR_MASK);
1192 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1193 buffer);
1194 }
1195 }
1196 VQ_Decompress(txb, tyb, (char *)OutBuffer.data(), 0, &Decode_Color);
1197
1198 break;
1199 case JpgBlock::VQ_NO_SKIP_4_COLOR_CODE:
1200 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_START_LENGTH, &newbits,
1201 buffer);
1202 Decode_Color.BitMapBits = 2;
1203
Ed Tanousd5f39992017-04-18 13:41:22 -07001204 for (int i = 0; i < 4; i++) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001205 Decode_Color.Index[i] = ((codebuf >> 29) & VQ_INDEX_MASK);
1206 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1207 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1208 buffer);
1209 } else {
1210 Decode_Color.Color[Decode_Color.Index[i]] =
1211 ((codebuf >> 5) & VQ_COLOR_MASK);
1212 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1213 buffer);
1214 }
1215 }
1216 VQ_Decompress(txb, tyb, (char *)OutBuffer.data(), 0, &Decode_Color);
1217
1218 break;
1219
1220 case JpgBlock::VQ_SKIP_4_COLOR_CODE:
1221 txb = (codebuf & 0x0FF00000) >> 20;
1222 tyb = (codebuf & 0x0FF000) >> 12;
1223
1224 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_SKIP_LENGTH, &newbits,
1225 buffer);
1226 Decode_Color.BitMapBits = 2;
1227
Ed Tanousd5f39992017-04-18 13:41:22 -07001228 for (int i = 0; i < 4; i++) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001229 Decode_Color.Index[i] = ((codebuf >> 29) & VQ_INDEX_MASK);
1230 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1231 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1232 buffer);
1233 } else {
1234 Decode_Color.Color[Decode_Color.Index[i]] =
1235 ((codebuf >> 5) & VQ_COLOR_MASK);
1236 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1237 buffer);
1238 }
1239 }
1240 VQ_Decompress(txb, tyb, (char *)OutBuffer.data(), 0, &Decode_Color);
1241
1242 break;
1243 case JpgBlock::JPEG_SKIP_PASS2_CODE:
1244 txb = (codebuf & 0x0FF00000) >> 20;
1245 tyb = (codebuf & 0x0FF000) >> 12;
1246
1247 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_SKIP_LENGTH, &newbits,
1248 buffer);
1249 Decompress_2PASS(txb, tyb, (char *)OutBuffer.data(), 2);
1250
1251 break;
1252 default:
1253 // TODO(ed) propogate errors upstream
1254 return -1;
1255 break;
1256 }
1257 MoveBlockIndex();
1258
1259 } while (buffer_index <= buffer.size());
1260
1261 return -1;
1262 }
1263
1264#ifdef cimg_version
1265 void dump_to_bitmap_file() {
1266 cimg_library::CImg<unsigned char> image(WIDTH, HEIGHT, 1, 3);
1267 for (int y = 0; y < WIDTH; y++) {
1268 for (int x = 0; x < HEIGHT; x++) {
1269 auto pixel = OutBuffer[x + (y * WIDTH)];
1270 image(x, y, 0) = pixel.R;
1271 image(x, y, 1) = pixel.G;
1272 image(x, y, 2) = pixel.B;
1273 }
1274 }
1275 image.save("/tmp/file2.bmp");
1276 }
1277#endif
1278
1279 private:
1280 YuvMode yuvmode;
1281 // WIDTH and HEIGHT are the modes your display used
1282 unsigned long WIDTH;
1283 unsigned long HEIGHT;
Ed Tanousb078cf32017-04-18 14:51:21 -07001284 unsigned long USER_WIDTH;
1285 unsigned long USER_HEIGHT;
Ed Tanous93f987d2017-04-17 17:52:36 -07001286 unsigned char Y_selector;
1287 int SCALEFACTOR;
1288 int SCALEFACTORUV;
1289 int ADVANCESCALEFACTOR;
1290 int ADVANCESCALEFACTORUV;
1291 int Mapping;
1292 unsigned char UV_selector;
1293 unsigned char advance_selector;
Ed Tanous93f987d2017-04-17 17:52:36 -07001294 int byte_pos; // current byte position
1295
1296 // quantization tables, no more than 4 quantization tables
1297 std::array<std::array<long, 64>, 4> QT;
1298
1299 // DC huffman tables , no more than 4 (0..3)
1300 std::array<Huffman_table, 4> HTDC;
1301 // AC huffman tables (0..3)
1302 std::array<Huffman_table, 4> HTAC;
1303 std::array<int, 256> m_CrToR;
1304 std::array<int, 256> m_CbToB;
1305 std::array<int, 256> m_CrToG;
1306 std::array<int, 256> m_CbToG;
1307 std::array<int, 256> m_Y;
1308 unsigned long buffer_index;
1309 uint32_t codebuf, newbuf, readbuf;
Ed Tanous9140a672017-04-24 17:01:32 -07001310 const unsigned char *std_luminance_qt;
1311 const uint8_t *std_chrominance_qt;
Ed Tanous93f987d2017-04-17 17:52:36 -07001312
1313 signed short int DCY, DCCb, DCCr; // Coeficientii DC pentru Y,Cb,Cr
1314 signed short int DCT_coeff[384];
1315 // std::vector<signed short int> DCT_coeff; // Current DCT_coefficients
1316 // quantization table number for Y, Cb, Cr
1317 uint8_t YQ_nr = 0, CbQ_nr = 1, CrQ_nr = 1;
1318 // DC Huffman table number for Y,Cb, Cr
1319 uint8_t YDC_nr = 0, CbDC_nr = 1, CrDC_nr = 1;
1320 // AC Huffman table number for Y,Cb, Cr
1321 uint8_t YAC_nr = 0, CbAC_nr = 1, CrAC_nr = 1;
Ed Tanousd5f39992017-04-18 13:41:22 -07001322 int txb = 0;
1323 int tyb = 0;
Ed Tanous93f987d2017-04-17 17:52:36 -07001324 int newbits;
1325 uint8_t *rlimit_table;
1326 std::vector<RGB> YUVBuffer;
Ed Tanousd5f39992017-04-18 13:41:22 -07001327 // TODO(ed) this shouldn't exist. It is cruft that needs cleaning up
Ed Tanous93f987d2017-04-17 17:52:36 -07001328 uint32_t *Buffer;
1329
1330 public:
1331 std::vector<RGB> OutBuffer;
1332};
1333}