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