blob: d2a482ab74c8c3d1438549340a724aedf672a2c1 [file] [log] [blame]
Ed Tanous93f987d2017-04-17 17:52:36 -07001#pragma once
2
Ed Tanous911ac312017-08-15 09:37:42 -07003#include <ast_video_types.hpp>
Ed Tanous93f987d2017-04-17 17:52:36 -07004#include <array>
5#include <aspeed/JTABLES.H>
Ed Tanous1ff48782017-04-18 12:45:08 -07006#include <cassert>
7#include <cstdint>
Ed Tanous911ac312017-08-15 09:37:42 -07008#include <cstring>
Ed Tanousb078cf32017-04-18 14:51:21 -07009#include <iostream>
10#include <vector>
Ed Tanous93f987d2017-04-17 17:52:36 -070011
Ed Tanous93f987d2017-04-17 17:52:36 -070012namespace AstVideo {
13
Ed Tanous93f987d2017-04-17 17:52:36 -070014struct COLOR_CACHE {
Ed Tanous911ac312017-08-15 09:37:42 -070015 COLOR_CACHE()
16 : Color{0x008080, 0xFF8080, 0x808080, 0xC08080}, Index{0, 1, 2, 3} {}
Ed Tanousd5f39992017-04-18 13:41:22 -070017
Ed Tanous93f987d2017-04-17 17:52:36 -070018 unsigned long Color[4];
19 unsigned char Index[4];
Ed Tanous911ac312017-08-15 09:37:42 -070020 unsigned char BitMapBits{};
Ed Tanous93f987d2017-04-17 17:52:36 -070021};
22
23struct RGB {
24 unsigned char B;
25 unsigned char G;
26 unsigned char R;
27 unsigned char Reserved;
28};
29
30enum class JpgBlock {
31 JPEG_NO_SKIP_CODE = 0x00,
32 JPEG_SKIP_CODE = 0x08,
33
34 JPEG_PASS2_CODE = 0x02,
35 JPEG_SKIP_PASS2_CODE = 0x0A,
36
37 LOW_JPEG_NO_SKIP_CODE = 0x04,
38 LOW_JPEG_SKIP_CODE = 0x0C,
39
40 VQ_NO_SKIP_1_COLOR_CODE = 0x05,
41 VQ_SKIP_1_COLOR_CODE = 0x0D,
42
43 VQ_NO_SKIP_2_COLOR_CODE = 0x06,
44 VQ_SKIP_2_COLOR_CODE = 0x0E,
45
46 VQ_NO_SKIP_4_COLOR_CODE = 0x07,
47 VQ_SKIP_4_COLOR_CODE = 0x0F,
48
49 FRAME_END_CODE = 0x09,
50
51};
52
53class AstJpegDecoder {
54 public:
55 AstJpegDecoder() {
56 // TODO(ed) figure out how to init this in the constructor
Ed Tanous9140a672017-04-24 17:01:32 -070057 YUVBuffer.resize(1920 * 1200);
58 OutBuffer.resize(1920 * 1200);
Ed Tanous93f987d2017-04-17 17:52:36 -070059 for (auto &r : OutBuffer) {
60 r.R = 0x00;
61 r.G = 0x00;
62 r.B = 0x00;
63 r.Reserved = 0xAA;
64 }
Ed Tanousd5f39992017-04-18 13:41:22 -070065
66 int qfactor = 16;
67
68 SCALEFACTOR = qfactor;
69 SCALEFACTORUV = qfactor;
70 ADVANCESCALEFACTOR = 16;
71 ADVANCESCALEFACTORUV = 16;
Ed Tanous93f987d2017-04-17 17:52:36 -070072 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;
Ed Tanous911ac312017-08-15 09:37:42 -070079 std::array<uint8_t, 64> tempQT{};
Ed Tanous93f987d2017-04-17 17:52:36 -070080
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 }
Ed Tanous911ac312017-08-15 09:37:42 -0700110 set_quant_table(std_luminance_qt, static_cast<uint8_t>(SCALEFACTOR),
111 tempQT);
Ed Tanous93f987d2017-04-17 17:52:36 -0700112
Ed Tanous911ac312017-08-15 09:37:42 -0700113 for (j = 0; j <= 63; j++) {
114 quant_table[j] = tempQT[zigzag[j]];
115 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700116 j = 0;
Ed Tanous911ac312017-08-15 09:37:42 -0700117 for (row = 0; row <= 7; row++) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700118 for (col = 0; col <= 7; col++) {
Ed Tanous911ac312017-08-15 09:37:42 -0700119 quant_table[j] = static_cast<long>(
120 (quant_table[j] * scalefactor[row] * scalefactor[col]) * 65536);
Ed Tanous93f987d2017-04-17 17:52:36 -0700121 j++;
122 }
Ed Tanous911ac312017-08-15 09:37:42 -0700123 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700124 byte_pos += 64;
125 }
126
127 void load_quant_tableCb(std::array<long, 64> &quant_table) {
128 float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
129 1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
130 uint8_t j, row, col;
Ed Tanous911ac312017-08-15 09:37:42 -0700131 std::array<uint8_t, 64> tempQT{};
Ed Tanous93f987d2017-04-17 17:52:36 -0700132
133 // Load quantization coefficients from JPG file, scale them for DCT and
134 // reorder from zig-zag order
135 if (Mapping == 0) {
136 switch (UV_selector) {
137 case 0:
138 std_chrominance_qt = Tbl_000Y;
139 break;
140 case 1:
141 std_chrominance_qt = Tbl_014Y;
142 break;
143 case 2:
144 std_chrominance_qt = Tbl_029Y;
145 break;
146 case 3:
147 std_chrominance_qt = Tbl_043Y;
148 break;
149 case 4:
150 std_chrominance_qt = Tbl_057Y;
151 break;
152 case 5:
153 std_chrominance_qt = Tbl_071Y;
154 break;
155 case 6:
156 std_chrominance_qt = Tbl_086Y;
157 break;
158 case 7:
159 std_chrominance_qt = Tbl_100Y;
160 break;
161 }
162 } else {
163 switch (UV_selector) {
164 case 0:
165 std_chrominance_qt = Tbl_000UV;
166 break;
167 case 1:
168 std_chrominance_qt = Tbl_014UV;
169 break;
170 case 2:
171 std_chrominance_qt = Tbl_029UV;
172 break;
173 case 3:
174 std_chrominance_qt = Tbl_043UV;
175 break;
176 case 4:
177 std_chrominance_qt = Tbl_057UV;
178 break;
179 case 5:
180 std_chrominance_qt = Tbl_071UV;
181 break;
182 case 6:
183 std_chrominance_qt = Tbl_086UV;
184 break;
185 case 7:
186 std_chrominance_qt = Tbl_100UV;
187 break;
188 }
189 }
Ed Tanous911ac312017-08-15 09:37:42 -0700190 set_quant_table(std_chrominance_qt, static_cast<uint8_t>(SCALEFACTORUV),
191 tempQT);
Ed Tanous93f987d2017-04-17 17:52:36 -0700192
193 for (j = 0; j <= 63; j++) {
194 quant_table[j] = tempQT[zigzag[j]];
195 }
196 j = 0;
197 for (row = 0; row <= 7; row++) {
198 for (col = 0; col <= 7; col++) {
Ed Tanous911ac312017-08-15 09:37:42 -0700199 quant_table[j] = static_cast<long>(
200 (quant_table[j] * scalefactor[row] * scalefactor[col]) * 65536);
Ed Tanous93f987d2017-04-17 17:52:36 -0700201 j++;
202 }
203 }
204 byte_pos += 64;
205 }
206 // Note: Added for Dual_JPEG
207 void load_advance_quant_table(std::array<long, 64> &quant_table) {
208 float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
209 1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
210 uint8_t j, row, col;
Ed Tanous911ac312017-08-15 09:37:42 -0700211 std::array<uint8_t, 64> tempQT{};
Ed Tanous93f987d2017-04-17 17:52:36 -0700212
213 // Load quantization coefficients from JPG file, scale them for DCT and
214 // reorder
215 // from zig-zag order
216 switch (advance_selector) {
217 case 0:
218 std_luminance_qt = Tbl_000Y;
219 break;
220 case 1:
221 std_luminance_qt = Tbl_014Y;
222 break;
223 case 2:
224 std_luminance_qt = Tbl_029Y;
225 break;
226 case 3:
227 std_luminance_qt = Tbl_043Y;
228 break;
229 case 4:
230 std_luminance_qt = Tbl_057Y;
231 break;
232 case 5:
233 std_luminance_qt = Tbl_071Y;
234 break;
235 case 6:
236 std_luminance_qt = Tbl_086Y;
237 break;
238 case 7:
239 std_luminance_qt = Tbl_100Y;
240 break;
241 }
242 // Note: pass ADVANCE SCALE FACTOR to sub-function in Dual-JPEG
Ed Tanous911ac312017-08-15 09:37:42 -0700243 set_quant_table(std_luminance_qt, static_cast<uint8_t>(ADVANCESCALEFACTOR),
244 tempQT);
Ed Tanous93f987d2017-04-17 17:52:36 -0700245
Ed Tanous911ac312017-08-15 09:37:42 -0700246 for (j = 0; j <= 63; j++) {
247 quant_table[j] = tempQT[zigzag[j]];
248 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700249 j = 0;
Ed Tanous911ac312017-08-15 09:37:42 -0700250 for (row = 0; row <= 7; row++) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700251 for (col = 0; col <= 7; col++) {
Ed Tanous911ac312017-08-15 09:37:42 -0700252 quant_table[j] = static_cast<long>(
253 (quant_table[j] * scalefactor[row] * scalefactor[col]) * 65536);
Ed Tanous93f987d2017-04-17 17:52:36 -0700254 j++;
255 }
Ed Tanous911ac312017-08-15 09:37:42 -0700256 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700257 byte_pos += 64;
258 }
259
260 // Note: Added for Dual-JPEG
261 void load_advance_quant_tableCb(std::array<long, 64> &quant_table) {
262 float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
263 1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
264 uint8_t j, row, col;
Ed Tanous911ac312017-08-15 09:37:42 -0700265 std::array<uint8_t, 64> tempQT{};
Ed Tanous93f987d2017-04-17 17:52:36 -0700266
267 // Load quantization coefficients from JPG file, scale them for DCT and
268 // reorder
269 // from zig-zag order
270 if (Mapping == 1) {
271 switch (advance_selector) {
272 case 0:
273 std_chrominance_qt = Tbl_000Y;
274 break;
275 case 1:
276 std_chrominance_qt = Tbl_014Y;
277 break;
278 case 2:
279 std_chrominance_qt = Tbl_029Y;
280 break;
281 case 3:
282 std_chrominance_qt = Tbl_043Y;
283 break;
284 case 4:
285 std_chrominance_qt = Tbl_057Y;
286 break;
287 case 5:
288 std_chrominance_qt = Tbl_071Y;
289 break;
290 case 6:
291 std_chrominance_qt = Tbl_086Y;
292 break;
293 case 7:
294 std_chrominance_qt = Tbl_100Y;
295 break;
296 }
297 } else {
298 switch (advance_selector) {
299 case 0:
300 std_chrominance_qt = Tbl_000UV;
301 break;
302 case 1:
303 std_chrominance_qt = Tbl_014UV;
304 break;
305 case 2:
306 std_chrominance_qt = Tbl_029UV;
307 break;
308 case 3:
309 std_chrominance_qt = Tbl_043UV;
310 break;
311 case 4:
312 std_chrominance_qt = Tbl_057UV;
313 break;
314 case 5:
315 std_chrominance_qt = Tbl_071UV;
316 break;
317 case 6:
318 std_chrominance_qt = Tbl_086UV;
319 break;
320 case 7:
321 std_chrominance_qt = Tbl_100UV;
322 break;
323 }
324 }
325 // Note: pass ADVANCE SCALE FACTOR to sub-function in Dual-JPEG
Ed Tanous911ac312017-08-15 09:37:42 -0700326 set_quant_table(std_chrominance_qt,
327 static_cast<uint8_t>(ADVANCESCALEFACTORUV), tempQT);
Ed Tanous93f987d2017-04-17 17:52:36 -0700328
Ed Tanous911ac312017-08-15 09:37:42 -0700329 for (j = 0; j <= 63; j++) {
330 quant_table[j] = tempQT[zigzag[j]];
331 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700332 j = 0;
Ed Tanous911ac312017-08-15 09:37:42 -0700333 for (row = 0; row <= 7; row++) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700334 for (col = 0; col <= 7; col++) {
Ed Tanous911ac312017-08-15 09:37:42 -0700335 quant_table[j] = static_cast<long>(
336 (quant_table[j] * scalefactor[row] * scalefactor[col]) * 65536);
Ed Tanous93f987d2017-04-17 17:52:36 -0700337 j++;
338 }
Ed Tanous911ac312017-08-15 09:37:42 -0700339 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700340 byte_pos += 64;
341 }
342
343 void IDCT_transform(short *coef, uint8_t *data, uint8_t nBlock) {
344#define FIX_1_082392200 ((int)277) /* FIX(1.082392200) */
345#define FIX_1_414213562 ((int)362) /* FIX(1.414213562) */
346#define FIX_1_847759065 ((int)473) /* FIX(1.847759065) */
347#define FIX_2_613125930 ((int)669) /* FIX(2.613125930) */
348
349#define MULTIPLY(var, cons) ((int)((var) * (cons)) >> 8)
350
351 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
352 int tmp10, tmp11, tmp12, tmp13;
353 int z5, z10, z11, z12, z13;
354 int workspace[64]; /* buffers data between passes */
355
356 short *inptr = coef;
357 long *quantptr;
358 int *wsptr = workspace;
359 unsigned char *outptr;
360 unsigned char *r_limit = rlimit_table + 128;
361 int ctr, dcval, DCTSIZE = 8;
362
363 quantptr = &QT[nBlock][0];
364
365 // Pass 1: process columns from input (inptr), store into work array(wsptr)
366
367 for (ctr = 8; ctr > 0; ctr--) {
368 /* Due to quantization, we will usually find that many of the input
369 * coefficients are zero, especially the AC terms. We can exploit this
370 * by short-circuiting the IDCT calculation for any column in which all
371 * the AC terms are zero. In that case each output is equal to the
372 * DC coefficient (with scale factor as needed).
373 * With typical images and quantization tables, half or more of the
374 * column DCT calculations can be simplified this way.
375 */
376
377 if ((inptr[DCTSIZE * 1] | inptr[DCTSIZE * 2] | inptr[DCTSIZE * 3] |
378 inptr[DCTSIZE * 4] | inptr[DCTSIZE * 5] | inptr[DCTSIZE * 6] |
379 inptr[DCTSIZE * 7]) == 0) {
380 /* AC terms all zero */
Ed Tanous911ac312017-08-15 09:37:42 -0700381 dcval = static_cast<int>((inptr[DCTSIZE * 0] * quantptr[DCTSIZE * 0]) >>
382 16);
Ed Tanous93f987d2017-04-17 17:52:36 -0700383
384 wsptr[DCTSIZE * 0] = dcval;
385 wsptr[DCTSIZE * 1] = dcval;
386 wsptr[DCTSIZE * 2] = dcval;
387 wsptr[DCTSIZE * 3] = dcval;
388 wsptr[DCTSIZE * 4] = dcval;
389 wsptr[DCTSIZE * 5] = dcval;
390 wsptr[DCTSIZE * 6] = dcval;
391 wsptr[DCTSIZE * 7] = dcval;
392
393 inptr++; /* advance pointers to next column */
394 quantptr++;
395 wsptr++;
396 continue;
397 }
398
399 /* Even part */
400
401 tmp0 = (inptr[DCTSIZE * 0] * quantptr[DCTSIZE * 0]) >> 16;
402 tmp1 = (inptr[DCTSIZE * 2] * quantptr[DCTSIZE * 2]) >> 16;
403 tmp2 = (inptr[DCTSIZE * 4] * quantptr[DCTSIZE * 4]) >> 16;
404 tmp3 = (inptr[DCTSIZE * 6] * quantptr[DCTSIZE * 6]) >> 16;
405
406 tmp10 = tmp0 + tmp2; /* phase 3 */
407 tmp11 = tmp0 - tmp2;
408
409 tmp13 = tmp1 + tmp3; /* phases 5-3 */
410 tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
411
412 tmp0 = tmp10 + tmp13; /* phase 2 */
413 tmp3 = tmp10 - tmp13;
414 tmp1 = tmp11 + tmp12;
415 tmp2 = tmp11 - tmp12;
416
417 /* Odd part */
418
419 tmp4 = (inptr[DCTSIZE * 1] * quantptr[DCTSIZE * 1]) >> 16;
420 tmp5 = (inptr[DCTSIZE * 3] * quantptr[DCTSIZE * 3]) >> 16;
421 tmp6 = (inptr[DCTSIZE * 5] * quantptr[DCTSIZE * 5]) >> 16;
422 tmp7 = (inptr[DCTSIZE * 7] * quantptr[DCTSIZE * 7]) >> 16;
423
424 z13 = tmp6 + tmp5; /* phase 6 */
425 z10 = tmp6 - tmp5;
426 z11 = tmp4 + tmp7;
427 z12 = tmp4 - tmp7;
428
429 tmp7 = z11 + z13; /* phase 5 */
430 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
431
432 z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
433 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
434 tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; /* -2*(c2+c6) */
435
436 tmp6 = tmp12 - tmp7; /* phase 2 */
437 tmp5 = tmp11 - tmp6;
438 tmp4 = tmp10 + tmp5;
439
Ed Tanous911ac312017-08-15 09:37:42 -0700440 wsptr[DCTSIZE * 0] = (tmp0 + tmp7);
441 wsptr[DCTSIZE * 7] = (tmp0 - tmp7);
442 wsptr[DCTSIZE * 1] = (tmp1 + tmp6);
443 wsptr[DCTSIZE * 6] = (tmp1 - tmp6);
444 wsptr[DCTSIZE * 2] = (tmp2 + tmp5);
445 wsptr[DCTSIZE * 5] = (tmp2 - tmp5);
446 wsptr[DCTSIZE * 4] = (tmp3 + tmp4);
447 wsptr[DCTSIZE * 3] = (tmp3 - tmp4);
Ed Tanous93f987d2017-04-17 17:52:36 -0700448
449 inptr++; /* advance pointers to next column */
450 quantptr++;
451 wsptr++;
452 }
453
454/* Pass 2: process rows from work array, store into output array. */
455/* Note that we must descale the results by a factor of 8 == 2**3, */
456/* and also undo the PASS1_BITS scaling. */
457
458//#define RANGE_MASK 1023; //2 bits wider than legal samples
459#define PASS1_BITS 0
Ed Tanous911ac312017-08-15 09:37:42 -0700460#define IDESCALE(x, n) ((int)((x) >> (n)))
Ed Tanous93f987d2017-04-17 17:52:36 -0700461
462 wsptr = workspace;
463 for (ctr = 0; ctr < DCTSIZE; ctr++) {
464 outptr = data + ctr * 8;
465
466 /* Rows of zeroes can be exploited in the same way as we did with columns.
467 * However, the column calculation has created many nonzero AC terms, so
468 * the simplification applies less often (typically 5% to 10% of the time).
469 * On machines with very fast multiplication, it's possible that the
470 * test takes more time than it's worth. In that case this section
471 * may be commented out.
472 */
473 /* Even part */
474
Ed Tanous911ac312017-08-15 09:37:42 -0700475 tmp10 = (wsptr[0] + wsptr[4]);
476 tmp11 = (wsptr[0] - wsptr[4]);
Ed Tanous93f987d2017-04-17 17:52:36 -0700477
Ed Tanous911ac312017-08-15 09:37:42 -0700478 tmp13 = (wsptr[2] + wsptr[6]);
Ed Tanous93f987d2017-04-17 17:52:36 -0700479 tmp12 = MULTIPLY((int)wsptr[2] - (int)wsptr[6], FIX_1_414213562) - tmp13;
480
481 tmp0 = tmp10 + tmp13;
482 tmp3 = tmp10 - tmp13;
483 tmp1 = tmp11 + tmp12;
484 tmp2 = tmp11 - tmp12;
485
486 /* Odd part */
487
Ed Tanous911ac312017-08-15 09:37:42 -0700488 z13 = wsptr[5] + wsptr[3];
489 z10 = wsptr[5] - wsptr[3];
490 z11 = wsptr[1] + wsptr[7];
491 z12 = wsptr[1] - wsptr[7];
Ed Tanous93f987d2017-04-17 17:52:36 -0700492
493 tmp7 = z11 + z13; /* phase 5 */
494 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
495
496 z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
497 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
498 tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; /* -2*(c2+c6) */
499
500 tmp6 = tmp12 - tmp7; /* phase 2 */
501 tmp5 = tmp11 - tmp6;
502 tmp4 = tmp10 + tmp5;
503
504 /* Final output stage: scale down by a factor of 8 and range-limit */
505
506 outptr[0] = r_limit[IDESCALE((tmp0 + tmp7), (PASS1_BITS + 3)) & 1023L];
507 outptr[7] = r_limit[IDESCALE((tmp0 - tmp7), (PASS1_BITS + 3)) & 1023L];
508 outptr[1] = r_limit[IDESCALE((tmp1 + tmp6), (PASS1_BITS + 3)) & 1023L];
509 outptr[6] = r_limit[IDESCALE((tmp1 - tmp6), (PASS1_BITS + 3)) & 1023L];
510 outptr[2] = r_limit[IDESCALE((tmp2 + tmp5), (PASS1_BITS + 3)) & 1023L];
511 outptr[5] = r_limit[IDESCALE((tmp2 - tmp5), (PASS1_BITS + 3)) & 1023L];
512 outptr[4] = r_limit[IDESCALE((tmp3 + tmp4), (PASS1_BITS + 3)) & 1023L];
513 outptr[3] = r_limit[IDESCALE((tmp3 - tmp4), (PASS1_BITS + 3)) & 1023L];
514
515 wsptr += DCTSIZE; /* advance pointer to next row */
516 }
517 }
518 void YUVToRGB(
519 int txb, int tyb,
520 unsigned char
521 *pYCbCr, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
522 struct RGB *pYUV, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
523 unsigned char
524 *pBgr // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
525 ) {
526 int i, j, pos, m, n;
527 unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
528 int y;
529 struct RGB *pByte;
530 int nBlocksInMcu = 6;
531 unsigned int pixel_x, pixel_y;
532
Ed Tanous911ac312017-08-15 09:37:42 -0700533 pByte = reinterpret_cast<struct RGB *>(pBgr);
Ed Tanous93f987d2017-04-17 17:52:36 -0700534 if (yuvmode == YuvMode::YUV444) {
535 py = pYCbCr;
536 pcb = pYCbCr + 64;
537 pcr = pcb + 64;
538
539 pixel_x = txb * 8;
540 pixel_y = tyb * 8;
541 pos = (pixel_y * WIDTH) + pixel_x;
542
543 for (j = 0; j < 8; j++) {
544 for (i = 0; i < 8; i++) {
545 m = ((j << 3) + i);
546 y = py[m];
547 cb = pcb[m];
548 cr = pcr[m];
549 n = pos + i;
550 // For 2Pass. Save the YUV value
551 pYUV[n].B = cb;
552 pYUV[n].G = y;
553 pYUV[n].R = cr;
Ed Tanousd5f39992017-04-18 13:41:22 -0700554 pByte[n].B = rlimit_table[m_Y[y] + m_CbToB[cb]];
555 pByte[n].G = rlimit_table[m_Y[y] + m_CbToG[cb] + m_CrToG[cr]];
556 pByte[n].R = rlimit_table[m_Y[y] + m_CrToR[cr]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700557 }
558 pos += WIDTH;
559 }
560 } else {
Ed Tanous911ac312017-08-15 09:37:42 -0700561 for (i = 0; i < nBlocksInMcu - 2; i++) {
562 py420[i] = pYCbCr + i * 64;
563 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700564 pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
565 pcr = pcb + 64;
566
567 pixel_x = txb * 16;
568 pixel_y = tyb * 16;
569 pos = (pixel_y * WIDTH) + pixel_x;
570
571 for (j = 0; j < 16; j++) {
572 for (i = 0; i < 16; i++) {
573 // block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
574 y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
575 m = ((j >> 1) << 3) + (i >> 1);
576 cb = pcb[m];
577 cr = pcr[m];
578 n = pos + i;
Ed Tanousd5f39992017-04-18 13:41:22 -0700579 pByte[n].B = rlimit_table[m_Y[y] + m_CbToB[cb]];
580 pByte[n].G = rlimit_table[m_Y[y] + m_CbToG[cb] + m_CrToG[cr]];
581 pByte[n].R = rlimit_table[m_Y[y] + m_CrToR[cr]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700582 }
583 pos += WIDTH;
584 }
585 }
586 }
587 void YUVToBuffer(
588 int txb, int tyb,
589 unsigned char
590 *pYCbCr, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
591 struct RGB
592 *pYUV, // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
593 unsigned char
594 *pBgr // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
595 ) {
596 int i, j, pos, m, n;
597 unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
598 int y;
599 struct RGB *pByte;
600 int nBlocksInMcu = 6;
601 unsigned int pixel_x, pixel_y;
602
Ed Tanous911ac312017-08-15 09:37:42 -0700603 pByte = reinterpret_cast<struct RGB *>(pBgr);
Ed Tanous93f987d2017-04-17 17:52:36 -0700604 if (yuvmode == YuvMode::YUV444) {
605 py = pYCbCr;
606 pcb = pYCbCr + 64;
607 pcr = pcb + 64;
608
609 pixel_x = txb * 8;
610 pixel_y = tyb * 8;
611 pos = (pixel_y * WIDTH) + pixel_x;
612
613 for (j = 0; j < 8; j++) {
614 for (i = 0; i < 8; i++) {
615 m = ((j << 3) + i);
616 n = pos + i;
617 y = pYUV[n].G + (py[m] - 128);
618 cb = pYUV[n].B + (pcb[m] - 128);
619 cr = pYUV[n].R + (pcr[m] - 128);
620 pYUV[n].B = cb;
621 pYUV[n].G = y;
622 pYUV[n].R = cr;
Ed Tanousd5f39992017-04-18 13:41:22 -0700623 pByte[n].B = rlimit_table[m_Y[y] + m_CbToB[cb]];
624 pByte[n].G = rlimit_table[m_Y[y] + m_CbToG[cb] + m_CrToG[cr]];
625 pByte[n].R = rlimit_table[m_Y[y] + m_CrToR[cr]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700626 }
627 pos += WIDTH;
628 }
629 } else {
Ed Tanous911ac312017-08-15 09:37:42 -0700630 for (i = 0; i < nBlocksInMcu - 2; i++) {
631 py420[i] = pYCbCr + i * 64;
632 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700633 pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
634 pcr = pcb + 64;
635
636 pixel_x = txb * 16;
637 pixel_y = tyb * 16;
638 pos = (pixel_y * WIDTH) + pixel_x;
639
640 for (j = 0; j < 16; j++) {
641 for (i = 0; i < 16; i++) {
642 // block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
643 y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
644 m = ((j >> 1) << 3) + (i >> 1);
645 cb = pcb[m];
646 cr = pcr[m];
647 n = pos + i;
Ed Tanousd5f39992017-04-18 13:41:22 -0700648 pByte[n].B = rlimit_table[m_Y[y] + m_CbToB[cb]];
649 pByte[n].G = rlimit_table[m_Y[y] + m_CbToG[cb] + m_CrToG[cr]];
650 pByte[n].R = rlimit_table[m_Y[y] + m_CrToR[cr]];
Ed Tanous93f987d2017-04-17 17:52:36 -0700651 }
652 pos += WIDTH;
653 }
654 }
655 }
Ed Tanous1ff48782017-04-18 12:45:08 -0700656 void Decompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700657 unsigned char *ptr;
658 unsigned char byTileYuv[768] = {};
659
660 memset(DCT_coeff, 0, 384 * 2);
661 ptr = byTileYuv;
662 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 0);
663 IDCT_transform(DCT_coeff, ptr, QT_TableSelection);
664 ptr += 64;
665
666 if (yuvmode == YuvMode::YUV420) {
667 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 64);
668 IDCT_transform(DCT_coeff + 64, ptr, QT_TableSelection);
669 ptr += 64;
670
671 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 128);
672 IDCT_transform(DCT_coeff + 128, ptr, QT_TableSelection);
673 ptr += 64;
674
675 process_Huffman_data_unit(YDC_nr, YAC_nr, &DCY, 192);
676 IDCT_transform(DCT_coeff + 192, ptr, QT_TableSelection);
677 ptr += 64;
678
679 process_Huffman_data_unit(CbDC_nr, CbAC_nr, &DCCb, 256);
680 IDCT_transform(DCT_coeff + 256, ptr, QT_TableSelection + 1);
681 ptr += 64;
682
683 process_Huffman_data_unit(CrDC_nr, CrAC_nr, &DCCr, 320);
684 IDCT_transform(DCT_coeff + 320, ptr, QT_TableSelection + 1);
685 } else {
686 process_Huffman_data_unit(CbDC_nr, CbAC_nr, &DCCb, 64);
687 IDCT_transform(DCT_coeff + 64, ptr, QT_TableSelection + 1);
688 ptr += 64;
689
690 process_Huffman_data_unit(CrDC_nr, CrAC_nr, &DCCr, 128);
691 IDCT_transform(DCT_coeff + 128, ptr, QT_TableSelection + 1);
692 }
693
694 // YUVToRGB (txb, tyb, byTileYuv, (unsigned char *)outBuf);
695 // YUVBuffer for YUV record
Ed Tanous911ac312017-08-15 09:37:42 -0700696 YUVToRGB(txb, tyb, byTileYuv, YUVBuffer.data(),
697 reinterpret_cast<unsigned char *>(outBuf));
Ed Tanous93f987d2017-04-17 17:52:36 -0700698 }
699
Ed Tanous1ff48782017-04-18 12:45:08 -0700700 void Decompress_2PASS(int txb, int tyb, char *outBuf,
701 uint8_t QT_TableSelection) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700702 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
Ed Tanous911ac312017-08-15 09:37:42 -0700718 YUVToBuffer(txb, tyb, byTileYuv, YUVBuffer.data(),
719 reinterpret_cast<unsigned char *>(outBuf));
Ed Tanous93f987d2017-04-17 17:52:36 -0700720 // YUVToRGB (txb, tyb, byTileYuv, (unsigned char *)outBuf);
Ed Tanous93f987d2017-04-17 17:52:36 -0700721 }
722
Ed Tanous1ff48782017-04-18 12:45:08 -0700723 void VQ_Decompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection,
724 struct COLOR_CACHE *VQ) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700725 unsigned char *ptr, i;
726 unsigned char byTileYuv[192];
727 int Data;
728
729 ptr = byTileYuv;
730 if (VQ->BitMapBits == 0) {
731 for (i = 0; i < 64; i++) {
732 ptr[0] = (VQ->Color[VQ->Index[0]] & 0xFF0000) >> 16;
733 ptr[64] = (VQ->Color[VQ->Index[0]] & 0x00FF00) >> 8;
734 ptr[128] = VQ->Color[VQ->Index[0]] & 0x0000FF;
735 ptr += 1;
736 }
737 } else {
738 for (i = 0; i < 64; i++) {
Ed Tanous911ac312017-08-15 09:37:42 -0700739 Data = static_cast<int>(lookKbits(VQ->BitMapBits));
Ed Tanous93f987d2017-04-17 17:52:36 -0700740 ptr[0] = (VQ->Color[VQ->Index[Data]] & 0xFF0000) >> 16;
741 ptr[64] = (VQ->Color[VQ->Index[Data]] & 0x00FF00) >> 8;
742 ptr[128] = VQ->Color[VQ->Index[Data]] & 0x0000FF;
743 ptr += 1;
744 skipKbits(VQ->BitMapBits);
745 }
746 }
747 // YUVToRGB (txb, tyb, byTileYuv, (unsigned char *)outBuf);
Ed Tanous911ac312017-08-15 09:37:42 -0700748 YUVToRGB(txb, tyb, byTileYuv, YUVBuffer.data(),
749 reinterpret_cast<unsigned char *>(outBuf));
Ed Tanous93f987d2017-04-17 17:52:36 -0700750 }
751
Ed Tanous911ac312017-08-15 09:37:42 -0700752 void MoveBlockIndex() {
Ed Tanous93f987d2017-04-17 17:52:36 -0700753 if (yuvmode == YuvMode::YUV444) {
754 txb++;
Ed Tanous911ac312017-08-15 09:37:42 -0700755 if (txb >= static_cast<int>(WIDTH / 8)) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700756 tyb++;
Ed Tanous911ac312017-08-15 09:37:42 -0700757 if (tyb >= static_cast<int>(HEIGHT / 8)) {
758 tyb = 0;
759 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700760 txb = 0;
761 }
762 } else {
763 txb++;
Ed Tanous911ac312017-08-15 09:37:42 -0700764 if (txb >= static_cast<int>(WIDTH / 16)) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700765 tyb++;
Ed Tanous911ac312017-08-15 09:37:42 -0700766 if (tyb >= static_cast<int>(HEIGHT / 16)) {
767 tyb = 0;
768 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700769 txb = 0;
770 }
771 }
772 }
773
Ed Tanous93f987d2017-04-17 17:52:36 -0700774 void Init_Color_Table() {
775 int i, x;
776 int nScale = 1L << 16; // equal to power(2,16)
777 int nHalf = nScale >> 1;
778
779#define FIX(x) ((int)((x)*nScale + 0.5))
780
781 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
782 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
783 /* Cr=>R value is nearest int to 1.597656 * x */
784 /* Cb=>B value is nearest int to 2.015625 * x */
785 /* Cr=>G value is scaled-up -0.8125 * x */
786 /* Cb=>G value is scaled-up -0.390625 * x */
787 for (i = 0, x = -128; i < 256; i++, x++) {
Ed Tanous911ac312017-08-15 09:37:42 -0700788 m_CrToR[i] = (FIX(1.597656) * x + nHalf) >> 16;
789 m_CbToB[i] = (FIX(2.015625) * x + nHalf) >> 16;
790 m_CrToG[i] = (-FIX(0.8125) * x + nHalf) >> 16;
791 m_CbToG[i] = (-FIX(0.390625) * x + nHalf) >> 16;
Ed Tanous93f987d2017-04-17 17:52:36 -0700792 }
793 for (i = 0, x = -16; i < 256; i++, x++) {
Ed Tanous911ac312017-08-15 09:37:42 -0700794 m_Y[i] = (FIX(1.164) * x + nHalf) >> 16;
Ed Tanous93f987d2017-04-17 17:52:36 -0700795 }
796 // For Color Text Enchance Y Re-map. Recommend to disable in default
797 /*
798 for (i = 0; i < (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate);
799 i++) {
800 temp = (double)i /
801 VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate;
802 temp1 = 1.0 / VideoEngineInfo->INFData.Gamma1Parameter;
803 m_Y[i] =
804 (BYTE)(VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate * pow (temp,
805 temp1));
806 if (m_Y[i] > 255) m_Y[i] = 255;
807 }
808 for (i = (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate); i < 256;
809 i++) {
810 m_Y[i] =
811 (BYTE)((VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) + (256 -
812 VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) * ( pow((double)((i -
813 VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) / (256 -
814 (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate))), (1.0 /
815 VideoEngineInfo->INFData.Gamma2Parameter)) ));
816 if (m_Y[i] > 255) m_Y[i] = 255;
817 }
818 */
819 }
Ed Tanous9140a672017-04-24 17:01:32 -0700820 void load_Huffman_table(Huffman_table *HT, const unsigned char *nrcode,
821 const unsigned char *value,
822 const unsigned short int *Huff_code) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700823 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 }
Ed Tanous911ac312017-08-15 09:37:42 -0700829 for (i = 0, k = 1; k <= 16; k++) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700830 for (j = 0; j < HT->Length[k]; j++) {
831 HT->V[WORD_hi_lo(k, j)] = value[i];
832 i++;
833 }
Ed Tanous911ac312017-08-15 09:37:42 -0700834 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700835
836 code = 0;
837 for (k = 1; k <= 16; k++) {
Ed Tanous911ac312017-08-15 09:37:42 -0700838 HT->minor_code[k] = static_cast<unsigned short int>(code);
839 for (j = 1; j <= HT->Length[k]; j++) {
840 code++;
841 }
842 HT->major_code[k] = static_cast<unsigned short int>(code - 1);
Ed Tanous93f987d2017-04-17 17:52:36 -0700843 code *= 2;
844 if (HT->Length[k] == 0) {
845 HT->minor_code[k] = 0xFFFF;
846 HT->major_code[k] = 0;
847 }
848 }
849
850 HT->Len[0] = 2;
851 i = 2;
852
853 for (code_index = 1; code_index < 65535; code_index++) {
854 if (code_index < Huff_code[i]) {
Ed Tanous911ac312017-08-15 09:37:42 -0700855 HT->Len[code_index] = static_cast<unsigned char>(Huff_code[i + 1]);
Ed Tanous93f987d2017-04-17 17:52:36 -0700856 } else {
857 i = i + 2;
Ed Tanous911ac312017-08-15 09:37:42 -0700858 HT->Len[code_index] = static_cast<unsigned char>(Huff_code[i + 1]);
Ed Tanous93f987d2017-04-17 17:52:36 -0700859 }
860 }
861 }
862 void init_jpg_table() {
Ed Tanous93f987d2017-04-17 17:52:36 -0700863 Init_Color_Table();
864 prepare_range_limit_table();
865 load_Huffman_table(&HTDC[0], std_dc_luminance_nrcodes,
866 std_dc_luminance_values, DC_LUMINANCE_HUFFMANCODE);
867 load_Huffman_table(&HTAC[0], std_ac_luminance_nrcodes,
868 std_ac_luminance_values, AC_LUMINANCE_HUFFMANCODE);
869 load_Huffman_table(&HTDC[1], std_dc_chrominance_nrcodes,
870 std_dc_chrominance_values, DC_CHROMINANCE_HUFFMANCODE);
871 load_Huffman_table(&HTAC[1], std_ac_chrominance_nrcodes,
872 std_ac_chrominance_values, AC_CHROMINANCE_HUFFMANCODE);
873 }
874
875 void prepare_range_limit_table()
876 /* Allocate and fill in the sample_range_limit table */
877 {
878 int j;
Ed Tanous911ac312017-08-15 09:37:42 -0700879 rlimit_table = reinterpret_cast<unsigned char *>(malloc(5 * 256L + 128));
Ed Tanous93f987d2017-04-17 17:52:36 -0700880 /* First segment of "simple" table: limit[x] = 0 for x < 0 */
881 memset((void *)rlimit_table, 0, 256);
882 rlimit_table += 256; /* allow negative subscripts of simple table */
883 /* Main part of "simple" table: limit[x] = x */
Ed Tanous911ac312017-08-15 09:37:42 -0700884 for (j = 0; j < 256; j++) {
885 rlimit_table[j] = j;
886 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700887 /* End of simple table, rest of first half of post-IDCT table */
Ed Tanous911ac312017-08-15 09:37:42 -0700888 for (j = 256; j < 640; j++) {
889 rlimit_table[j] = 255;
890 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700891
892 /* Second half of post-IDCT table */
893 memset((void *)(rlimit_table + 640), 0, 384);
Ed Tanous911ac312017-08-15 09:37:42 -0700894 for (j = 0; j < 128; j++) {
895 rlimit_table[j + 1024] = j;
896 }
Ed Tanous93f987d2017-04-17 17:52:36 -0700897 }
898
899 inline unsigned short int WORD_hi_lo(uint8_t byte_high, uint8_t byte_low) {
900 return (byte_high << 8) + byte_low;
901 }
902
903 // river
904 void process_Huffman_data_unit(uint8_t DC_nr, uint8_t AC_nr,
905 signed short int *previous_DC,
906 unsigned short int position) {
907 uint8_t nr = 0;
908 uint8_t k;
909 unsigned short int tmp_Hcode;
910 uint8_t size_val, count_0;
911 unsigned short int *min_code;
912 uint8_t *huff_values;
913 uint8_t byte_temp;
914
915 min_code = HTDC[DC_nr].minor_code;
916 // maj_code=HTDC[DC_nr].major_code;
917 huff_values = HTDC[DC_nr].V;
918
919 // DC
Ed Tanous911ac312017-08-15 09:37:42 -0700920 k = HTDC[DC_nr].Len[static_cast<unsigned short int>(codebuf >> 16)];
Ed Tanous93f987d2017-04-17 17:52:36 -0700921 // river
922 // tmp_Hcode=lookKbits(k);
Ed Tanous911ac312017-08-15 09:37:42 -0700923 tmp_Hcode = static_cast<unsigned short int>(codebuf >> (32 - k));
Ed Tanous93f987d2017-04-17 17:52:36 -0700924 skipKbits(k);
Ed Tanous911ac312017-08-15 09:37:42 -0700925 size_val = huff_values[WORD_hi_lo(
926 k, static_cast<uint8_t>(tmp_Hcode - min_code[k]))];
927 if (size_val == 0) {
Ed Tanous93f987d2017-04-17 17:52:36 -0700928 DCT_coeff[position + 0] = *previous_DC;
Ed Tanous911ac312017-08-15 09:37:42 -0700929 } else {
Ed Tanous93f987d2017-04-17 17:52:36 -0700930 DCT_coeff[position + 0] = *previous_DC + getKbits(size_val);
931 *previous_DC = DCT_coeff[position + 0];
932 }
933
934 // Second, AC coefficient decoding
935 min_code = HTAC[AC_nr].minor_code;
936 // maj_code=HTAC[AC_nr].major_code;
937 huff_values = HTAC[AC_nr].V;
938
939 nr = 1; // AC coefficient
940 do {
Ed Tanous911ac312017-08-15 09:37:42 -0700941 k = HTAC[AC_nr].Len[static_cast<unsigned short int>(codebuf >> 16)];
942 tmp_Hcode = static_cast<unsigned short int>(codebuf >> (32 - k));
Ed Tanous93f987d2017-04-17 17:52:36 -0700943 skipKbits(k);
944
Ed Tanous911ac312017-08-15 09:37:42 -0700945 byte_temp = huff_values[WORD_hi_lo(
946 k, static_cast<uint8_t>(tmp_Hcode - min_code[k]))];
Ed Tanous93f987d2017-04-17 17:52:36 -0700947 size_val = byte_temp & 0xF;
948 count_0 = byte_temp >> 4;
949 if (size_val == 0) {
950 if (count_0 != 0xF) {
951 break;
952 }
953 nr += 16;
954 } else {
955 nr += count_0; // skip count_0 zeroes
956 DCT_coeff[position + dezigzag[nr++]] = getKbits(size_val);
957 }
958 } while (nr < 64);
959 }
960
961 unsigned short int lookKbits(uint8_t k) {
962 unsigned short int revcode;
963
Ed Tanous911ac312017-08-15 09:37:42 -0700964 revcode = static_cast<unsigned short int>(codebuf >> (32 - k));
Ed Tanous93f987d2017-04-17 17:52:36 -0700965
966 return (revcode);
967 }
968
969 void skipKbits(uint8_t k) {
970 unsigned long readbuf;
971
972 if ((newbits - k) <= 0) {
973 readbuf = Buffer[buffer_index];
974 buffer_index++;
975 codebuf =
976 (codebuf << k) | ((newbuf | (readbuf >> (newbits))) >> (32 - k));
977 newbuf = readbuf << (k - newbits);
978 newbits = 32 + newbits - k;
979 } else {
980 codebuf = (codebuf << k) | (newbuf >> (32 - k));
981 newbuf = newbuf << k;
982 newbits -= k;
983 }
984 }
985
986 signed short int getKbits(uint8_t k) {
987 signed short int signed_wordvalue;
988
989 // river
990 // signed_wordvalue=lookKbits(k);
Ed Tanous911ac312017-08-15 09:37:42 -0700991 signed_wordvalue = static_cast<unsigned short int>(codebuf >> (32 - k));
Ed Tanous93f987d2017-04-17 17:52:36 -0700992 if (((1L << (k - 1)) & signed_wordvalue) == 0) {
993 // neg_pow2 was previously defined as the below. It seemed silly to keep
994 // a table of values around for something
995 // THat's relatively easy to compute, so it was replaced with the
996 // appropriate math
997 // signed_wordvalue = signed_wordvalue - (0xFFFF >> (16 - k));
998 std::array<signed short int, 17> neg_pow2 = {
999 0, -1, -3, -7, -15, -31, -63, -127,
1000 -255, -511, -1023, -2047, -4095, -8191, -16383, -32767};
1001
1002 signed_wordvalue = signed_wordvalue + neg_pow2[k];
1003 }
1004 skipKbits(k);
1005 return signed_wordvalue;
1006 }
1007 int init_JPG_decoding() {
1008 byte_pos = 0;
1009 load_quant_table(QT[0]);
1010 load_quant_tableCb(QT[1]);
1011 // Note: Added for Dual-JPEG
1012 load_advance_quant_table(QT[2]);
1013 load_advance_quant_tableCb(QT[3]);
1014 return 1;
1015 }
1016
Ed Tanous9140a672017-04-24 17:01:32 -07001017 void set_quant_table(const uint8_t *basic_table, uint8_t scale_factor,
Ed Tanous911ac312017-08-15 09:37:42 -07001018 std::array<uint8_t, 64>& newtable)
Ed Tanous93f987d2017-04-17 17:52:36 -07001019 // Set quantization table and zigzag reorder it
1020 {
1021 uint8_t i;
1022 long temp;
1023 for (i = 0; i < 64; i++) {
Ed Tanous911ac312017-08-15 09:37:42 -07001024 temp = (static_cast<long>(basic_table[i] * 16) / scale_factor);
Ed Tanous93f987d2017-04-17 17:52:36 -07001025 /* limit the values to the valid range */
Ed Tanous911ac312017-08-15 09:37:42 -07001026 if (temp <= 0L) {
1027 temp = 1L;
1028 }
1029 if (temp > 255L) {
1030 temp = 255L; /* limit to baseline range if requested */
1031 }
1032 newtable[zigzag[i]] = static_cast<uint8_t>(temp);
Ed Tanous93f987d2017-04-17 17:52:36 -07001033 }
1034 }
1035
1036 void updatereadbuf(uint32_t *codebuf, uint32_t *newbuf, int walks,
1037 int *newbits, std::vector<uint32_t> &Buffer) {
1038 unsigned long readbuf;
1039
1040 if ((*newbits - walks) <= 0) {
1041 readbuf = Buffer[buffer_index];
1042 buffer_index++;
1043 *codebuf = (*codebuf << walks) |
1044 ((*newbuf | (readbuf >> (*newbits))) >> (32 - walks));
1045 *newbuf = readbuf << (walks - *newbits);
1046 *newbits = 32 + *newbits - walks;
1047 } else {
1048 *codebuf = (*codebuf << walks) | (*newbuf >> (32 - walks));
1049 *newbuf = *newbuf << walks;
1050 *newbits -= walks;
1051 }
1052 }
1053
1054 uint32_t decode(std::vector<uint32_t> &buffer, unsigned long width,
1055 unsigned long height, YuvMode yuvmode_in, int y_selector,
1056 int uv_selector) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001057 COLOR_CACHE Decode_Color;
Ed Tanousb078cf32017-04-18 14:51:21 -07001058 if (width != USER_WIDTH || height != USER_HEIGHT || yuvmode_in != yuvmode ||
1059 y_selector != Y_selector || uv_selector != UV_selector) {
1060 yuvmode = yuvmode_in;
1061 Y_selector = y_selector; // 0-7
1062 UV_selector = uv_selector; // 0-7
1063 USER_HEIGHT = height;
1064 USER_WIDTH = width;
1065 WIDTH = width;
1066 HEIGHT = height;
Ed Tanous93f987d2017-04-17 17:52:36 -07001067
Ed Tanousb078cf32017-04-18 14:51:21 -07001068 // TODO(ed) Magic number section. Document appropriately
1069 advance_selector = 0; // 0-7
1070 Mapping = 0; // 0 or 1
Ed Tanous1ff48782017-04-18 12:45:08 -07001071
Ed Tanousb078cf32017-04-18 14:51:21 -07001072 if (yuvmode == YuvMode::YUV420) {
Ed Tanous911ac312017-08-15 09:37:42 -07001073 if ((WIDTH % 16) != 0u) {
Ed Tanousb078cf32017-04-18 14:51:21 -07001074 WIDTH = WIDTH + 16 - (WIDTH % 16);
1075 }
Ed Tanous911ac312017-08-15 09:37:42 -07001076 if ((HEIGHT % 16) != 0u) {
Ed Tanousb078cf32017-04-18 14:51:21 -07001077 HEIGHT = HEIGHT + 16 - (HEIGHT % 16);
1078 }
1079 } else {
Ed Tanous911ac312017-08-15 09:37:42 -07001080 if ((WIDTH % 8) != 0u) {
Ed Tanousb078cf32017-04-18 14:51:21 -07001081 WIDTH = WIDTH + 8 - (WIDTH % 8);
1082 }
Ed Tanous911ac312017-08-15 09:37:42 -07001083 if ((HEIGHT % 8) != 0u) {
Ed Tanousb078cf32017-04-18 14:51:21 -07001084 HEIGHT = HEIGHT + 8 - (HEIGHT % 8);
1085 }
1086 }
Ed Tanous93f987d2017-04-17 17:52:36 -07001087
Ed Tanouscc9e2c22017-04-18 14:32:02 -07001088 init_JPG_decoding();
1089 }
1090 // TODO(ed) cleanup cruft
Ed Tanous93f987d2017-04-17 17:52:36 -07001091 Buffer = buffer.data();
1092
1093 codebuf = buffer[0];
1094 newbuf = buffer[1];
1095 buffer_index = 2;
1096
1097 txb = tyb = 0;
1098 newbits = 32;
1099 DCY = DCCb = DCCr = 0;
1100
Ed Tanous1ff48782017-04-18 12:45:08 -07001101 static const uint32_t VQ_HEADER_MASK = 0x01;
1102 static const uint32_t VQ_NO_UPDATE_HEADER = 0x00;
1103 static const uint32_t VQ_UPDATE_HEADER = 0x01;
1104 static const int VQ_NO_UPDATE_LENGTH = 0x03;
1105 static const int VQ_UPDATE_LENGTH = 0x1B;
1106 static const uint32_t VQ_INDEX_MASK = 0x03;
1107 static const uint32_t VQ_COLOR_MASK = 0xFFFFFF;
1108
1109 static const int BLOCK_AST2100_START_LENGTH = 0x04;
1110 static const int BLOCK_AST2100_SKIP_LENGTH = 20; // S:1 H:3 X:8 Y:8
1111
Ed Tanous93f987d2017-04-17 17:52:36 -07001112 do {
1113 auto block_header = static_cast<JpgBlock>((codebuf >> 28) & 0xFF);
1114 switch (block_header) {
1115 case JpgBlock::JPEG_NO_SKIP_CODE:
1116 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_START_LENGTH, &newbits,
1117 buffer);
Ed Tanous911ac312017-08-15 09:37:42 -07001118 Decompress(txb, tyb, reinterpret_cast<char *>(OutBuffer.data()), 0);
Ed Tanous93f987d2017-04-17 17:52:36 -07001119 break;
1120 case JpgBlock::FRAME_END_CODE:
1121 return 0;
1122 break;
1123 case JpgBlock::JPEG_SKIP_CODE:
1124
1125 txb = (codebuf & 0x0FF00000) >> 20;
1126 tyb = (codebuf & 0x0FF000) >> 12;
1127
1128 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_SKIP_LENGTH, &newbits,
1129 buffer);
Ed Tanous911ac312017-08-15 09:37:42 -07001130 Decompress(txb, tyb, reinterpret_cast<char *>(OutBuffer.data()), 0);
Ed Tanous93f987d2017-04-17 17:52:36 -07001131 break;
1132 case JpgBlock::VQ_NO_SKIP_1_COLOR_CODE:
1133 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_START_LENGTH, &newbits,
1134 buffer);
1135 Decode_Color.BitMapBits = 0;
1136
Ed Tanousd5f39992017-04-18 13:41:22 -07001137 for (int i = 0; i < 1; i++) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001138 Decode_Color.Index[i] = ((codebuf >> 29) & VQ_INDEX_MASK);
1139 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1140 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1141 buffer);
1142 } else {
1143 Decode_Color.Color[Decode_Color.Index[i]] =
1144 ((codebuf >> 5) & VQ_COLOR_MASK);
1145 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1146 buffer);
1147 }
1148 }
Ed Tanous911ac312017-08-15 09:37:42 -07001149 VQ_Decompress(txb, tyb, reinterpret_cast<char *>(OutBuffer.data()), 0,
1150 &Decode_Color);
Ed Tanous93f987d2017-04-17 17:52:36 -07001151 break;
1152 case JpgBlock::VQ_SKIP_1_COLOR_CODE:
1153 txb = (codebuf & 0x0FF00000) >> 20;
1154 tyb = (codebuf & 0x0FF000) >> 12;
1155
1156 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_SKIP_LENGTH, &newbits,
1157 buffer);
1158 Decode_Color.BitMapBits = 0;
1159
Ed Tanousd5f39992017-04-18 13:41:22 -07001160 for (int i = 0; i < 1; i++) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001161 Decode_Color.Index[i] = ((codebuf >> 29) & VQ_INDEX_MASK);
1162 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1163 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1164 buffer);
1165 } else {
1166 Decode_Color.Color[Decode_Color.Index[i]] =
1167 ((codebuf >> 5) & VQ_COLOR_MASK);
1168 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1169 buffer);
1170 }
1171 }
Ed Tanous911ac312017-08-15 09:37:42 -07001172 VQ_Decompress(txb, tyb, reinterpret_cast<char *>(OutBuffer.data()), 0,
1173 &Decode_Color);
Ed Tanous93f987d2017-04-17 17:52:36 -07001174 break;
1175
1176 case JpgBlock::VQ_NO_SKIP_2_COLOR_CODE:
1177 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_START_LENGTH, &newbits,
1178 buffer);
1179 Decode_Color.BitMapBits = 1;
1180
Ed Tanousd5f39992017-04-18 13:41:22 -07001181 for (int i = 0; i < 2; i++) {
Ed Tanous93f987d2017-04-17 17:52:36 -07001182 Decode_Color.Index[i] = ((codebuf >> 29) & VQ_INDEX_MASK);
1183 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1184 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1185 buffer);
1186 } else {
1187 Decode_Color.Color[Decode_Color.Index[i]] =
1188 ((codebuf >> 5) & VQ_COLOR_MASK);
1189 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1190 buffer);
1191 }
1192 }
Ed Tanous911ac312017-08-15 09:37:42 -07001193 VQ_Decompress(txb, tyb, reinterpret_cast<char *>(OutBuffer.data()), 0,
1194 &Decode_Color);
Ed Tanous93f987d2017-04-17 17:52:36 -07001195 break;
1196 case JpgBlock::VQ_SKIP_2_COLOR_CODE:
1197 txb = (codebuf & 0x0FF00000) >> 20;
1198 tyb = (codebuf & 0x0FF000) >> 12;
1199
1200 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_SKIP_LENGTH, &newbits,
1201 buffer);
1202 Decode_Color.BitMapBits = 1;
1203
Ed Tanousd5f39992017-04-18 13:41:22 -07001204 for (int i = 0; i < 2; 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 }
Ed Tanous911ac312017-08-15 09:37:42 -07001216 VQ_Decompress(txb, tyb, reinterpret_cast<char *>(OutBuffer.data()), 0,
1217 &Decode_Color);
Ed Tanous93f987d2017-04-17 17:52:36 -07001218
1219 break;
1220 case JpgBlock::VQ_NO_SKIP_4_COLOR_CODE:
1221 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_START_LENGTH, &newbits,
1222 buffer);
1223 Decode_Color.BitMapBits = 2;
1224
Ed Tanous911ac312017-08-15 09:37:42 -07001225 for (unsigned char &i : Decode_Color.Index) {
1226 i = ((codebuf >> 29) & VQ_INDEX_MASK);
Ed Tanous93f987d2017-04-17 17:52:36 -07001227 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1228 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1229 buffer);
1230 } else {
Ed Tanous911ac312017-08-15 09:37:42 -07001231 Decode_Color.Color[i] = ((codebuf >> 5) & VQ_COLOR_MASK);
Ed Tanous93f987d2017-04-17 17:52:36 -07001232 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1233 buffer);
1234 }
1235 }
Ed Tanous911ac312017-08-15 09:37:42 -07001236 VQ_Decompress(txb, tyb, reinterpret_cast<char *>(OutBuffer.data()), 0,
1237 &Decode_Color);
Ed Tanous93f987d2017-04-17 17:52:36 -07001238
1239 break;
1240
1241 case JpgBlock::VQ_SKIP_4_COLOR_CODE:
1242 txb = (codebuf & 0x0FF00000) >> 20;
1243 tyb = (codebuf & 0x0FF000) >> 12;
1244
1245 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_SKIP_LENGTH, &newbits,
1246 buffer);
1247 Decode_Color.BitMapBits = 2;
1248
Ed Tanous911ac312017-08-15 09:37:42 -07001249 for (unsigned char &i : Decode_Color.Index) {
1250 i = ((codebuf >> 29) & VQ_INDEX_MASK);
Ed Tanous93f987d2017-04-17 17:52:36 -07001251 if (((codebuf >> 31) & VQ_HEADER_MASK) == VQ_NO_UPDATE_HEADER) {
1252 updatereadbuf(&codebuf, &newbuf, VQ_NO_UPDATE_LENGTH, &newbits,
1253 buffer);
1254 } else {
Ed Tanous911ac312017-08-15 09:37:42 -07001255 Decode_Color.Color[i] = ((codebuf >> 5) & VQ_COLOR_MASK);
Ed Tanous93f987d2017-04-17 17:52:36 -07001256 updatereadbuf(&codebuf, &newbuf, VQ_UPDATE_LENGTH, &newbits,
1257 buffer);
1258 }
1259 }
Ed Tanous911ac312017-08-15 09:37:42 -07001260 VQ_Decompress(txb, tyb, reinterpret_cast<char *>(OutBuffer.data()), 0,
1261 &Decode_Color);
Ed Tanous93f987d2017-04-17 17:52:36 -07001262
1263 break;
1264 case JpgBlock::JPEG_SKIP_PASS2_CODE:
1265 txb = (codebuf & 0x0FF00000) >> 20;
1266 tyb = (codebuf & 0x0FF000) >> 12;
1267
1268 updatereadbuf(&codebuf, &newbuf, BLOCK_AST2100_SKIP_LENGTH, &newbits,
1269 buffer);
Ed Tanous911ac312017-08-15 09:37:42 -07001270 Decompress_2PASS(txb, tyb, reinterpret_cast<char *>(OutBuffer.data()),
1271 2);
Ed Tanous93f987d2017-04-17 17:52:36 -07001272
1273 break;
1274 default:
1275 // TODO(ed) propogate errors upstream
1276 return -1;
1277 break;
1278 }
1279 MoveBlockIndex();
1280
1281 } while (buffer_index <= buffer.size());
1282
1283 return -1;
1284 }
1285
1286#ifdef cimg_version
1287 void dump_to_bitmap_file() {
1288 cimg_library::CImg<unsigned char> image(WIDTH, HEIGHT, 1, 3);
1289 for (int y = 0; y < WIDTH; y++) {
1290 for (int x = 0; x < HEIGHT; x++) {
1291 auto pixel = OutBuffer[x + (y * WIDTH)];
1292 image(x, y, 0) = pixel.R;
1293 image(x, y, 1) = pixel.G;
1294 image(x, y, 2) = pixel.B;
1295 }
1296 }
1297 image.save("/tmp/file2.bmp");
1298 }
1299#endif
1300
1301 private:
Ed Tanous911ac312017-08-15 09:37:42 -07001302 YuvMode yuvmode{};
Ed Tanous93f987d2017-04-17 17:52:36 -07001303 // WIDTH and HEIGHT are the modes your display used
Ed Tanous911ac312017-08-15 09:37:42 -07001304 unsigned long WIDTH{};
1305 unsigned long HEIGHT{};
1306 unsigned long USER_WIDTH{};
1307 unsigned long USER_HEIGHT{};
1308 unsigned char Y_selector{};
Ed Tanous93f987d2017-04-17 17:52:36 -07001309 int SCALEFACTOR;
1310 int SCALEFACTORUV;
1311 int ADVANCESCALEFACTOR;
1312 int ADVANCESCALEFACTORUV;
Ed Tanous911ac312017-08-15 09:37:42 -07001313 int Mapping{};
1314 unsigned char UV_selector{};
1315 unsigned char advance_selector{};
1316 int byte_pos{}; // current byte position
Ed Tanous93f987d2017-04-17 17:52:36 -07001317
1318 // quantization tables, no more than 4 quantization tables
Ed Tanous911ac312017-08-15 09:37:42 -07001319 std::array<std::array<long, 64>, 4> QT{};
Ed Tanous93f987d2017-04-17 17:52:36 -07001320
1321 // DC huffman tables , no more than 4 (0..3)
Ed Tanous911ac312017-08-15 09:37:42 -07001322 std::array<Huffman_table, 4> HTDC{};
Ed Tanous93f987d2017-04-17 17:52:36 -07001323 // AC huffman tables (0..3)
Ed Tanous911ac312017-08-15 09:37:42 -07001324 std::array<Huffman_table, 4> HTAC{};
1325 std::array<int, 256> m_CrToR{};
1326 std::array<int, 256> m_CbToB{};
1327 std::array<int, 256> m_CrToG{};
1328 std::array<int, 256> m_CbToG{};
1329 std::array<int, 256> m_Y{};
1330 unsigned long buffer_index{};
1331 uint32_t codebuf{}, newbuf{}, readbuf{};
1332 const unsigned char *std_luminance_qt{};
1333 const uint8_t *std_chrominance_qt{};
Ed Tanous93f987d2017-04-17 17:52:36 -07001334
Ed Tanous911ac312017-08-15 09:37:42 -07001335 signed short int DCY{}, DCCb{}, DCCr{}; // Coeficientii DC pentru Y,Cb,Cr
1336 signed short int DCT_coeff[384]{};
Ed Tanous93f987d2017-04-17 17:52:36 -07001337 // std::vector<signed short int> DCT_coeff; // Current DCT_coefficients
1338 // quantization table number for Y, Cb, Cr
1339 uint8_t YQ_nr = 0, CbQ_nr = 1, CrQ_nr = 1;
1340 // DC Huffman table number for Y,Cb, Cr
1341 uint8_t YDC_nr = 0, CbDC_nr = 1, CrDC_nr = 1;
1342 // AC Huffman table number for Y,Cb, Cr
1343 uint8_t YAC_nr = 0, CbAC_nr = 1, CrAC_nr = 1;
Ed Tanousd5f39992017-04-18 13:41:22 -07001344 int txb = 0;
1345 int tyb = 0;
Ed Tanous911ac312017-08-15 09:37:42 -07001346 int newbits{};
1347 uint8_t *rlimit_table{};
Ed Tanous93f987d2017-04-17 17:52:36 -07001348 std::vector<RGB> YUVBuffer;
Ed Tanousd5f39992017-04-18 13:41:22 -07001349 // TODO(ed) this shouldn't exist. It is cruft that needs cleaning up
Ed Tanous911ac312017-08-15 09:37:42 -07001350 uint32_t *Buffer{};
Ed Tanous93f987d2017-04-17 17:52:36 -07001351
1352 public:
1353 std::vector<RGB> OutBuffer;
1354};
Ed Tanous911ac312017-08-15 09:37:42 -07001355} // namespace AstVideo