blob: 4036423f3abcbd28dc818318610eefe139a3775b [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 Tanousd5f39992017-04-18 13:41:22 -07009#include <g3log/g3log.hpp>
Ed Tanousb078cf32017-04-18 14:51:21 -070010#include <iostream>
11#include <vector>
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]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700589 }
590 pos += WIDTH;
591 }
592 }
593 }
594 void YUVToBuffer(
595 int txb, int tyb,
596 unsigned char
597 *pYCbCr, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
598 struct RGB
599 *pYUV, // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
600 unsigned char
601 *pBgr // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
602 ) {
603 int i, j, pos, m, n;
604 unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
605 int y;
606 struct RGB *pByte;
607 int nBlocksInMcu = 6;
608 unsigned int pixel_x, pixel_y;
609
610 pByte = (struct RGB *)pBgr;
611 if (yuvmode == YuvMode::YUV444) {
612 py = pYCbCr;
613 pcb = pYCbCr + 64;
614 pcr = pcb + 64;
615
616 pixel_x = txb * 8;
617 pixel_y = tyb * 8;
618 pos = (pixel_y * WIDTH) + pixel_x;
619
620 for (j = 0; j < 8; j++) {
621 for (i = 0; i < 8; i++) {
622 m = ((j << 3) + i);
623 n = pos + i;
624 y = pYUV[n].G + (py[m] - 128);
625 cb = pYUV[n].B + (pcb[m] - 128);
626 cr = pYUV[n].R + (pcr[m] - 128);
627 pYUV[n].B = cb;
628 pYUV[n].G = y;
629 pYUV[n].R = cr;
Ed Tanousd5f39992017-04-18 13:41:22 -0700630 pByte[n].B = rlimit_table[m_Y[y] + m_CbToB[cb]];
631 pByte[n].G = rlimit_table[m_Y[y] + m_CbToG[cb] + m_CrToG[cr]];
632 pByte[n].R = rlimit_table[m_Y[y] + m_CrToR[cr]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700633 }
634 pos += WIDTH;
635 }
636 } else {
637 for (i = 0; i < nBlocksInMcu - 2; i++) py420[i] = pYCbCr + i * 64;
638 pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
639 pcr = pcb + 64;
640
641 pixel_x = txb * 16;
642 pixel_y = tyb * 16;
643 pos = (pixel_y * WIDTH) + pixel_x;
644
645 for (j = 0; j < 16; j++) {
646 for (i = 0; i < 16; i++) {
647 // block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
648 y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
649 m = ((j >> 1) << 3) + (i >> 1);
650 cb = pcb[m];
651 cr = pcr[m];
652 n = pos + i;
Ed Tanousd5f39992017-04-18 13:41:22 -0700653 pByte[n].B = rlimit_table[m_Y[y] + m_CbToB[cb]];
654 pByte[n].G = rlimit_table[m_Y[y] + m_CbToG[cb] + m_CrToG[cr]];
655 pByte[n].R = rlimit_table[m_Y[y] + m_CrToR[cr]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700656 }
657 pos += WIDTH;
658 }
659 }
660 }
Ed Tanous1ff48782017-04-18 12:45:08 -0700661 void Decompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700662 unsigned char *ptr;
663 unsigned char byTileYuv[768] = {};
664
665 memset(DCT_coeff, 0, 384 * 2);
666 ptr = byTileYuv;
667 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 0);
668 IDCT_transform(DCT_coeff, ptr, QT_TableSelection);
669 ptr += 64;
670
671 if (yuvmode == YuvMode::YUV420) {
672 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 64);
673 IDCT_transform(DCT_coeff + 64, ptr, QT_TableSelection);
674 ptr += 64;
675
676 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 128);
677 IDCT_transform(DCT_coeff + 128, ptr, QT_TableSelection);
678 ptr += 64;
679
680 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 192);
681 IDCT_transform(DCT_coeff + 192, ptr, QT_TableSelection);
682 ptr += 64;
683
684 process_Huffman_data_unit(CbDC_nr, CbAC_nr, &DCCb, 256);
685 IDCT_transform(DCT_coeff + 256, ptr, QT_TableSelection + 1);
686 ptr += 64;
687
688 process_Huffman_data_unit(CrDC_nr, CrAC_nr, &DCCr, 320);
689 IDCT_transform(DCT_coeff + 320, ptr, QT_TableSelection + 1);
690 } else {
691 process_Huffman_data_unit(CbDC_nr, CbAC_nr, &DCCb, 64);
692 IDCT_transform(DCT_coeff + 64, ptr, QT_TableSelection + 1);
693 ptr += 64;
694
695 process_Huffman_data_unit(CrDC_nr, CrAC_nr, &DCCr, 128);
696 IDCT_transform(DCT_coeff + 128, ptr, QT_TableSelection + 1);
697 }
698
699 // YUVToRGB (txb, tyb, byTileYuv, (unsigned char *)outBuf);
700 // YUVBuffer for YUV record
701 YUVToRGB(txb, tyb, byTileYuv, YUVBuffer.data(), (unsigned char *)outBuf);
Ed Tanous93f987d2017-04-17 17:52:36 -0700702 }
703
Ed Tanous1ff48782017-04-18 12:45:08 -0700704 void Decompress_2PASS(int txb, int tyb, char *outBuf,
705 uint8_t QT_TableSelection) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700706 unsigned char *ptr;
707 unsigned char byTileYuv[768];
708 memset(DCT_coeff, 0, 384 * 2);
709
710 ptr = byTileYuv;
711 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 0);
712 IDCT_transform(DCT_coeff, ptr, QT_TableSelection);
713 ptr += 64;
714
715 process_Huffman_data_unit(CbDC_nr, CbAC_nr, &DCCb, 64);
716 IDCT_transform(DCT_coeff + 64, ptr, QT_TableSelection + 1);
717 ptr += 64;
718
719 process_Huffman_data_unit(CrDC_nr, CrAC_nr, &DCCr, 128);
720 IDCT_transform(DCT_coeff + 128, ptr, QT_TableSelection + 1);
721
722 YUVToBuffer(txb, tyb, byTileYuv, YUVBuffer.data(), (unsigned char *)outBuf);
723 // YUVToRGB (txb, tyb, byTileYuv, (unsigned char *)outBuf);
Ed Tanous93f987d2017-04-17 17:52:36 -0700724 }
725
Ed Tanous1ff48782017-04-18 12:45:08 -0700726 void VQ_Decompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection,
727 struct COLOR_CACHE *VQ) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700728 unsigned char *ptr, i;
729 unsigned char byTileYuv[192];
730 int Data;
731
732 ptr = byTileYuv;
733 if (VQ->BitMapBits == 0) {
734 for (i = 0; i < 64; i++) {
735 ptr[0] = (VQ->Color[VQ->Index[0]] & 0xFF0000) >> 16;
736 ptr[64] = (VQ->Color[VQ->Index[0]] & 0x00FF00) >> 8;
737 ptr[128] = VQ->Color[VQ->Index[0]] & 0x0000FF;
738 ptr += 1;
739 }
740 } else {
741 for (i = 0; i < 64; i++) {
742 Data = (int)lookKbits(VQ->BitMapBits);
743 ptr[0] = (VQ->Color[VQ->Index[Data]] & 0xFF0000) >> 16;
744 ptr[64] = (VQ->Color[VQ->Index[Data]] & 0x00FF00) >> 8;
745 ptr[128] = VQ->Color[VQ->Index[Data]] & 0x0000FF;
746 ptr += 1;
747 skipKbits(VQ->BitMapBits);
748 }
749 }
750 // YUVToRGB (txb, tyb, byTileYuv, (unsigned char *)outBuf);
751 YUVToRGB(txb, tyb, byTileYuv, YUVBuffer.data(), (unsigned char *)outBuf);
Ed Tanous93f987d2017-04-17 17:52:36 -0700752 }
753
754 void MoveBlockIndex(void) {
755 if (yuvmode == YuvMode::YUV444) {
756 txb++;
Ed Tanousb078cf32017-04-18 14:51:21 -0700757 if (txb >= (int)(WIDTH / 8)) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700758 tyb++;
Ed Tanousb078cf32017-04-18 14:51:21 -0700759 if (tyb >= (int)(HEIGHT / 8)) tyb = 0;
Ed Tanous93f987d2017-04-17 17:52:36 -0700760 txb = 0;
761 }
762 } else {
763 txb++;
Ed Tanousb078cf32017-04-18 14:51:21 -0700764 if (txb >= (int)(WIDTH / 16)) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700765 tyb++;
Ed Tanousb078cf32017-04-18 14:51:21 -0700766 if (tyb >= (int)(HEIGHT / 16)) tyb = 0;
Ed Tanous93f987d2017-04-17 17:52:36 -0700767 txb = 0;
768 }
769 }
770 }
771
Ed Tanous93f987d2017-04-17 17:52:36 -0700772 void Init_Color_Table() {
773 int i, x;
774 int nScale = 1L << 16; // equal to power(2,16)
775 int nHalf = nScale >> 1;
776
777#define FIX(x) ((int)((x)*nScale + 0.5))
778
779 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
780 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
781 /* Cr=>R value is nearest int to 1.597656 * x */
782 /* Cb=>B value is nearest int to 2.015625 * x */
783 /* Cr=>G value is scaled-up -0.8125 * x */
784 /* Cb=>G value is scaled-up -0.390625 * x */
785 for (i = 0, x = -128; i < 256; i++, x++) {
786 m_CrToR[i] = (int)(FIX(1.597656) * x + nHalf) >> 16;
787 m_CbToB[i] = (int)(FIX(2.015625) * x + nHalf) >> 16;
788 m_CrToG[i] = (int)(-FIX(0.8125) * x + nHalf) >> 16;
789 m_CbToG[i] = (int)(-FIX(0.390625) * x + nHalf) >> 16;
790 }
791 for (i = 0, x = -16; i < 256; i++, x++) {
792 m_Y[i] = (int)(FIX(1.164) * x + nHalf) >> 16;
793 }
794 // For Color Text Enchance Y Re-map. Recommend to disable in default
795 /*
796 for (i = 0; i < (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate);
797 i++) {
798 temp = (double)i /
799 VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate;
800 temp1 = 1.0 / VideoEngineInfo->INFData.Gamma1Parameter;
801 m_Y[i] =
802 (BYTE)(VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate * pow (temp,
803 temp1));
804 if (m_Y[i] > 255) m_Y[i] = 255;
805 }
806 for (i = (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate); i < 256;
807 i++) {
808 m_Y[i] =
809 (BYTE)((VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) + (256 -
810 VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) * ( pow((double)((i -
811 VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) / (256 -
812 (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate))), (1.0 /
813 VideoEngineInfo->INFData.Gamma2Parameter)) ));
814 if (m_Y[i] > 255) m_Y[i] = 255;
815 }
816 */
817 }
818 void load_Huffman_table(Huffman_table *HT, unsigned char *nrcode,
819 unsigned char *value, unsigned short int *Huff_code) {
820 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
1004 void set_quant_table(uint8_t *basic_table, uint8_t scale_factor,
1005 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;
1310 uint8_t *std_luminance_qt;
1311 uint8_t *std_chrominance_qt;
1312
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}