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