diff options
author | Roman Artiukhin <bahusdrive@gmail.com> | 2024-10-09 17:31:17 +0300 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2024-10-14 09:19:34 -0400 |
commit | 64ad7354b6bbc61782935f64873afdf2c0a18bc1 (patch) | |
tree | 8a63030501dbb910a88cacfeae150bd068fb6c2a | |
parent | 772eff8ca6268fc613637d25cb7056419af48442 (diff) | |
download | rockbox-64ad7354b6bbc61782935f64873afdf2c0a18bc1.tar.gz rockbox-64ad7354b6bbc61782935f64873afdf2c0a18bc1.zip |
imageviewer: Initial support for JPEG progressive images. Add lib sources
Added unmodified files from RAINBOW library by Attila Tarpai
Full sources:
https://github.com/Halicery/vc_rainbow
Change-Id: I356486b6a332aa3f610ddcae57f8a2044653b051
-rw-r--r-- | apps/plugins/imageviewer/jpegp/GETC.h | 56 | ||||
-rw-r--r-- | apps/plugins/imageviewer/jpegp/idct.c | 134 | ||||
-rw-r--r-- | apps/plugins/imageviewer/jpegp/idct.h | 6 | ||||
-rw-r--r-- | apps/plugins/imageviewer/jpegp/jpeg81.c | 995 | ||||
-rw-r--r-- | apps/plugins/imageviewer/jpegp/jpeg81.h | 147 | ||||
-rw-r--r-- | docs/CREDITS | 1 |
6 files changed, 1339 insertions, 0 deletions
diff --git a/apps/plugins/imageviewer/jpegp/GETC.h b/apps/plugins/imageviewer/jpegp/GETC.h new file mode 100644 index 0000000000..d17cdb9857 --- /dev/null +++ b/apps/plugins/imageviewer/jpegp/GETC.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | "GETC" Interface for byte input (i.e. started as a wrapper for getc()) | ||
3 | |||
4 | For image- and video decoders I needed a transparent mechanism for | ||
5 | opening and reading the input data: | ||
6 | |||
7 | - either from streams (eg. coded video) | ||
8 | - or preloaded into memory (eg. small GIF/PNG images) | ||
9 | |||
10 | RAINBOW is only dependent on the GETC Interface for byte input. | ||
11 | |||
12 | File stream input is used during development and testing (FILEGETC.C). | ||
13 | In the OS image Rainbow can be linked with MEMGETC.C for memory input. | ||
14 | No other changes necessary in RAINBOW. | ||
15 | |||
16 | * Copyright (c) 2017 A. Tarpai | ||
17 | * | ||
18 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
19 | * of this software and associated documentation files (the "Software"), to deal | ||
20 | * in the Software without restriction, including without limitation the rights | ||
21 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
22 | * copies of the Software, and to permit persons to whom the Software is | ||
23 | * furnished to do so, subject to the following conditions: | ||
24 | * | ||
25 | * The above copyright notice and this permission notice shall be included in all | ||
26 | * copies or substantial portions of the Software. | ||
27 | * | ||
28 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
29 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
30 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
31 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
32 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
33 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
34 | * SOFTWARE. | ||
35 | */ | ||
36 | |||
37 | |||
38 | // For decoders | ||
39 | |||
40 | extern int GETC(); | ||
41 | |||
42 | // Multibyte helpers | ||
43 | extern int GETWbi(); // read word (16-bit) big-endian | ||
44 | extern int GETWli(); // little-endian | ||
45 | extern int GETDbi(); // read double word (32-bit) big-endian | ||
46 | extern int GETDli(); // little-endian | ||
47 | |||
48 | // positioning | ||
49 | extern void SEEK(int); // move relative to current | ||
50 | extern void POS(int); // move absolute position (TIFF) | ||
51 | extern int TELL(); // read actual position | ||
52 | |||
53 | |||
54 | // For RAINBOW clients to implement outside of Rainbow Library | ||
55 | extern void *OPEN(char*); | ||
56 | extern void CLOSE(); | ||
diff --git a/apps/plugins/imageviewer/jpegp/idct.c b/apps/plugins/imageviewer/jpegp/idct.c new file mode 100644 index 0000000000..7db1658546 --- /dev/null +++ b/apps/plugins/imageviewer/jpegp/idct.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /********************************************************************************** | ||
2 | * | ||
3 | * Scaled Integer 1-D IDCT based on the LLM-method that | ||
4 | * reduces the number of multiplications from 11 to to 6. | ||
5 | * Here further reduced to 3 using some dyadic decomposition. | ||
6 | * | ||
7 | * The real scaling vector: | ||
8 | * v[0] = v[4] = 1.0; | ||
9 | * v[2] = beta; | ||
10 | * v[6] = alpha; | ||
11 | * v[5] = v[3] = theta*M_SQRT2; | ||
12 | * v[1] = v[7] = theta; | ||
13 | * | ||
14 | * The integer scaling matrix is derived as SCALEM = [v vt] << 12. | ||
15 | * | ||
16 | * | ||
17 | * Copyright (c) 2017 A. Tarpai | ||
18 | * | ||
19 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
20 | * of this software and associated documentation files (the "Software"), to deal | ||
21 | * in the Software without restriction, including without limitation the rights | ||
22 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
23 | * copies of the Software, and to permit persons to whom the Software is | ||
24 | * furnished to do so, subject to the following conditions: | ||
25 | * | ||
26 | * The above copyright notice and this permission notice shall be included in all | ||
27 | * copies or substantial portions of the Software. | ||
28 | * | ||
29 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
30 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
31 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
32 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
33 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
34 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
35 | * SOFTWARE. | ||
36 | */ | ||
37 | |||
38 | |||
39 | int SCALEM[64] = { // theta,12 | ||
40 | 4096, 2276, 5352, 3218, 4096, 3218, 2217, 2276, | ||
41 | 2276, 1264, 2973, 1788, 2276, 1788, 1232, 1264, | ||
42 | 5352, 2973, 6992, 4205, 5352, 4205, 2896, 2973, | ||
43 | 3218, 1788, 4205, 2529, 3218, 2529, 1742, 1788, | ||
44 | 4096, 2276, 5352, 3218, 4096, 3218, 2217, 2276, | ||
45 | 3218, 1788, 4205, 2529, 3218, 2529, 1742, 1788, | ||
46 | 2217, 1232, 2896, 1742, 2217, 1742, 1200, 1232, | ||
47 | 2276, 1264, 2973, 1788, 2276, 1788, 1232, 1264, | ||
48 | }; | ||
49 | |||
50 | static unsigned char clip_table[3*256] = { | ||
51 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
52 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, | ||
53 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, | ||
54 | }; | ||
55 | unsigned char *CLIP = clip_table + 256; | ||
56 | |||
57 | |||
58 | #define XADD(a,b,c,d) p=a+b, n=a-b, a=p+d, b=n+c, c=n-c, d=p-d | ||
59 | |||
60 | static void idct1(int *F, int *f) | ||
61 | { | ||
62 | int p, n; | ||
63 | |||
64 | XADD(F[1],F[7],F[5],F[3]); | ||
65 | |||
66 | p= F[5]*45, n= F[3]*45; //XROT(F[5],F[3],90,542,362); | ||
67 | F[5]= ( n+p + (p<<2) + F[5] ) >> 7; // *181 = 45*4+1 | ||
68 | F[3]= ( n-p + (n<<2) + F[3] ) >> 7; // *181 | ||
69 | |||
70 | p=F[1]<<8, n=F[7]<<8; //XROT(F[1],F[7],256,639,127); | ||
71 | F[1]= ( n+p + (F[1]<<7) - F[1] ) >> 8; // *127 | ||
72 | F[7]= ( n-p + (F[7]<<7) - F[7] ) >> 8; // *127 | ||
73 | |||
74 | p= F[6]; | ||
75 | F[6]+= F[2]; | ||
76 | F[2]= ((F[2]-p) * 181 >> 7) - F[6]; | ||
77 | |||
78 | XADD(F[0],F[4],F[2],F[6]); | ||
79 | |||
80 | f[0*8]= F[0]+F[1]; | ||
81 | f[1*8]= F[4]+F[5]; | ||
82 | f[2*8]= F[2]+F[3]; | ||
83 | f[3*8]= F[6]+F[7]; | ||
84 | f[4*8]= F[6]-F[7]; | ||
85 | f[5*8]= F[2]-F[3]; | ||
86 | f[6*8]= F[4]-F[5]; | ||
87 | f[7*8]= F[0]-F[1]; | ||
88 | } | ||
89 | |||
90 | |||
91 | /////////////// SCALED INTEGER IDCT AND MODIFIED LLM METHOD /////////////////////////// | ||
92 | // | ||
93 | // Input: de-quantized coefficient block | ||
94 | |||
95 | extern void idct_s(int *t, short *y) | ||
96 | { | ||
97 | int i, R[64], C[64]; | ||
98 | R[0]= ( t[0] + 4 ) * SCALEM[0]; | ||
99 | for (i=1; i<64; i++) R[i] = t[i] * SCALEM[i]; | ||
100 | |||
101 | for (i=0; i<8; i++) idct1(R+i*8, C+i); | ||
102 | for (i=0; i<8; i++) idct1(C+i*8, R+i); | ||
103 | |||
104 | for (i=0; i<64; i++) y[i] = CLIP[ R[i] >> 15 ]; | ||
105 | } | ||
106 | |||
107 | |||
108 | /////////////// SCALED IDCT WITH DEQUANTIZATION IN ONE STEP ///////////////////////// | ||
109 | // | ||
110 | // Input: raw (un-zigzagged) coefficient block and the scaled quantization table | ||
111 | |||
112 | int zigzag[64] = { | ||
113 | 0,1,8,16,9,2,3,10, | ||
114 | 17,24,32,25,18,11,4,5, | ||
115 | 12,19,26,33,40,48,41,34, | ||
116 | 27,20,13,6,7,14,21,28, | ||
117 | 35,42,49,56,57,50,43,36, | ||
118 | 29,22,15,23,30,37,44,51, | ||
119 | 58,59,52,45,38,31,39,46, | ||
120 | 53,60,61,54,47,55,62,63, | ||
121 | }; | ||
122 | |||
123 | extern void idct_sq(short *coef, int *sq) | ||
124 | { | ||
125 | int i, R[64], C[64]; | ||
126 | R[0]= coef[0] * sq[0] + ((1024+4)<<12); // DC dequant + scale + level-shift + rounding bias | ||
127 | for (i=1; i<64; i++) R[zigzag[i]] = coef[i] * sq[i]; // AC dequant + scale (with zigzag) | ||
128 | |||
129 | for (i=0; i<8; i++) idct1(R+i*8, C+i); | ||
130 | for (i=0; i<8; i++) idct1(C+i*8, R+i); | ||
131 | |||
132 | for (i=0; i<64; i++) coef[i] = CLIP[ R[i] >> 15 ]; | ||
133 | } | ||
134 | |||
diff --git a/apps/plugins/imageviewer/jpegp/idct.h b/apps/plugins/imageviewer/jpegp/idct.h new file mode 100644 index 0000000000..3cc9c54a0b --- /dev/null +++ b/apps/plugins/imageviewer/jpegp/idct.h | |||
@@ -0,0 +1,6 @@ | |||
1 | extern void idct_sq(short *coef, int *q); // <-- scaled integer idct WITH de-quantization | ||
2 | extern void idct_s(int *t, short *y); // <-- scaled integer idct | ||
3 | |||
4 | extern int zigzag[64]; | ||
5 | extern int SCALEM[64]; | ||
6 | extern unsigned char *CLIP; | ||
diff --git a/apps/plugins/imageviewer/jpegp/jpeg81.c b/apps/plugins/imageviewer/jpegp/jpeg81.c new file mode 100644 index 0000000000..95e46dbd17 --- /dev/null +++ b/apps/plugins/imageviewer/jpegp/jpeg81.c | |||
@@ -0,0 +1,995 @@ | |||
1 | /************************************************************************ | ||
2 | jpeg81.c | ||
3 | |||
4 | An ITU T.81 JPEG coefficient-decoder - without de-quantization and IDCT. | ||
5 | Used for conformance testing of ITU T.83 data (a little verbose output). | ||
6 | Allocates full image coefficient buffer. | ||
7 | |||
8 | Supports: | ||
9 | - JPEG Interchange Format (JIF) | ||
10 | - DCT- and Lossless operation | ||
11 | - Huffman- and arithmetic coding | ||
12 | - Sequential- and progressive mode | ||
13 | - max. 4 components | ||
14 | - all sub-sampling | ||
15 | - 8/12 - bit samples for DCT | ||
16 | - 2-16 - bit for Lossless | ||
17 | |||
18 | It does not support the Hierarchial mode. | ||
19 | TODO: more error checking. | ||
20 | |||
21 | |||
22 | * Copyright (c) 2017 A. Tarpai | ||
23 | * | ||
24 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
25 | * of this software and associated documentation files (the "Software"), to deal | ||
26 | * in the Software without restriction, including without limitation the rights | ||
27 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
28 | * copies of the Software, and to permit persons to whom the Software is | ||
29 | * furnished to do so, subject to the following conditions: | ||
30 | * | ||
31 | * The above copyright notice and this permission notice shall be included in all | ||
32 | * copies or substantial portions of the Software. | ||
33 | * | ||
34 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
35 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
36 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
37 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
38 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
39 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
40 | * SOFTWARE. | ||
41 | */ | ||
42 | |||
43 | #include "GETC.h" | ||
44 | #include "jpeg81.h" | ||
45 | #include <malloc.h> // calloc() called once | ||
46 | #include <stdio.h> // debug only | ||
47 | |||
48 | |||
49 | ///////////////////////////////////////// LOSSLESS ///////////////////////////////////////// | ||
50 | |||
51 | static int P1(struct COMP *C, TSAMP *samp) // Px = Ra | ||
52 | { | ||
53 | return samp[-1]; | ||
54 | } | ||
55 | |||
56 | static int P2(struct COMP *C, TSAMP *samp) // Px = Rb | ||
57 | { | ||
58 | return samp[-C->du_width]; | ||
59 | } | ||
60 | |||
61 | static int P3(struct COMP *C, TSAMP *samp) // Px = Rc | ||
62 | { | ||
63 | return samp[-C->du_width-1]; | ||
64 | } | ||
65 | |||
66 | static int P4(struct COMP *C, TSAMP *samp) // Px = Ra + Rb – Rc | ||
67 | { | ||
68 | return samp[-1] + samp[-C->du_width] - samp[-C->du_width-1]; | ||
69 | } | ||
70 | |||
71 | static int P5(struct COMP *C, TSAMP *samp) // Px = Ra + ((Rb – Rc)/2) | ||
72 | { | ||
73 | return samp[-1] + ( (samp[-C->du_width] - samp[-C->du_width-1]) >> 1 ); | ||
74 | } | ||
75 | |||
76 | static int P6(struct COMP *C, TSAMP *samp) // Px = Rb + ((Ra – Rc)/2) | ||
77 | { | ||
78 | return samp[-C->du_width] + ( (samp[-1] - samp[-C->du_width-1]) >> 1 ); | ||
79 | } | ||
80 | |||
81 | static int P7(struct COMP *C, TSAMP *samp) // Px = (Ra + Rb)/2 | ||
82 | { | ||
83 | return (samp[-1] + samp[-C->du_width]) >> 1; | ||
84 | } | ||
85 | |||
86 | static int (*PN[])(struct COMP *C, TSAMP *samp) = { | ||
87 | 0, P1, P2, P3, P4, P5, P6, P7 | ||
88 | }; | ||
89 | |||
90 | static int Predx(struct JPEGD *j, struct COMP *C, int x, int y, TSAMP *samp) | ||
91 | { | ||
92 | int Px; | ||
93 | if (!x) { | ||
94 | if (y) Px= samp[-C->du_width]; // Px = Rb (P2) | ||
95 | else Px= 1<<(j->P-1); // 'P0' | ||
96 | } | ||
97 | else { | ||
98 | if (y) Px= PN[j->Ss](C, samp); // (PN) | ||
99 | else Px= samp[-1]; // Px = Ra (P1) | ||
100 | } | ||
101 | return Px; | ||
102 | } | ||
103 | |||
104 | |||
105 | //////////////////////////////////// HUFFMAN //////////////////////////////////////////////// | ||
106 | |||
107 | static int Byte_in_huff(struct JPEGD *j) | ||
108 | { | ||
109 | j->ScanByte = GETC(); | ||
110 | if ( 0xFF == j->ScanByte ) | ||
111 | { | ||
112 | int marker = GETC(); | ||
113 | if ( marker ) // DEBUG: ERR in Huffman: | ||
114 | { | ||
115 | printf("%08X: FF%02x\n", TELL()-2, marker); | ||
116 | printf("STREAM ERROR: marker found in Huffman ECS\n"); | ||
117 | } | ||
118 | //else skip zero-stuffing | ||
119 | } | ||
120 | return j->ScanByte; | ||
121 | } | ||
122 | |||
123 | static int GetBit(struct JPEGD *j) | ||
124 | { | ||
125 | if ( j->ScanBit ) return (j->ScanByte >> --j->ScanBit) & 1; | ||
126 | j->ScanBit=7; | ||
127 | return j->Byte_in(j) >> 7; // arith/huff | ||
128 | } | ||
129 | |||
130 | static int Getnbit(struct JPEGD *j, int n) // n>0 | ||
131 | { | ||
132 | int v= GetBit(j); | ||
133 | while (--n) v= 2*v + GetBit(j); | ||
134 | return v; | ||
135 | } | ||
136 | |||
137 | static int ReadDiff(struct JPEGD *j, int s) // JPEG magnitude stuff. One way to do this.. | ||
138 | { | ||
139 | int x= Getnbit(j, s); | ||
140 | if ( 0 == (x >> (s-1)) ) x= (-1<<s) - ~x; // 0xxxxxx means neg //x= ~x & ((1<<s)-1); | ||
141 | return x << j->Al; // point transform included PRED??? seems ok. | ||
142 | } | ||
143 | |||
144 | static int ReadHuffmanCode(struct JPEGD *j, int *pb) // index into the sym-table | ||
145 | { | ||
146 | int v= GetBit(j); | ||
147 | while ( v >= *pb ) v= 2*v + GetBit(j) - *pb++; | ||
148 | return v; | ||
149 | } | ||
150 | |||
151 | static void dc_succ_huff(struct JPEGD *j, struct COMP *sc, TCOEF *coef) | ||
152 | { | ||
153 | *coef |= GetBit(j) << j->Al; | ||
154 | } | ||
155 | |||
156 | static void dc_decode_huff(struct JPEGD *j, struct COMP *sc, TCOEF *coef) | ||
157 | { | ||
158 | int s= sc->DCS[ReadHuffmanCode(j, sc->DCB)]; | ||
159 | if (s) sc->DC+= ReadDiff(j, s); | ||
160 | *coef= sc->DC; | ||
161 | } | ||
162 | |||
163 | static void ac_decode_huff(struct JPEGD *j, struct COMP *sc, TCOEF *coef) | ||
164 | { | ||
165 | int k= j->Ss; | ||
166 | if (0==sc->EOBRUN) { | ||
167 | for (; ;k++) { | ||
168 | int s= sc->ACS[ReadHuffmanCode(j, sc->ACB)]; | ||
169 | int r= s>>4; | ||
170 | if ( s&=15 ) s= ReadDiff(j, s); | ||
171 | else { | ||
172 | if (r < 15) { // EOBn? | ||
173 | if (r) sc->EOBRUN= Getnbit(j, r) + ~(-1<<r); // ((1<<r)-1); -1 included | ||
174 | return; | ||
175 | }//else ZRL | ||
176 | } | ||
177 | k+=r; | ||
178 | coef[k]= s; | ||
179 | if (k==j->Se) return; | ||
180 | } | ||
181 | } | ||
182 | else sc->EOBRUN--; | ||
183 | } | ||
184 | |||
185 | static int ac_refine(struct JPEGD *j, TCOEF *coef) | ||
186 | { | ||
187 | if (*coef) if (GetBit(j)) *coef+= (*coef > 0)? j->Al2 : -j->Al2; | ||
188 | return *coef; | ||
189 | } | ||
190 | |||
191 | static void ac_succ_huff(struct JPEGD *j, struct COMP *sc, TCOEF *coef) | ||
192 | { | ||
193 | int k= j->Ss; | ||
194 | if (0==sc->EOBRUN) { | ||
195 | for (; ;k++) { | ||
196 | int s= sc->ACS[ReadHuffmanCode(j, sc->ACB)]; | ||
197 | int r= s>>4; | ||
198 | if ( s&=15 ) s= GetBit(j)? j->Al2 : -j->Al2; | ||
199 | else { | ||
200 | if (r < 15) { // EOBn? | ||
201 | if (r) sc->EOBRUN= Getnbit(j, r) + ~(-1<<r); //=((1<<r)-1), -1 included | ||
202 | break; | ||
203 | }//else ZRL | ||
204 | } | ||
205 | for (; ;k++) if (!ac_refine(j, coef+k)) if (!r--) break; | ||
206 | coef[k]= s; | ||
207 | if (k==j->Se) return; | ||
208 | } | ||
209 | } | ||
210 | else sc->EOBRUN--; | ||
211 | for (; k<=j->Se; k++) ac_refine(j, coef+k); // Refine EOBRUN | ||
212 | } | ||
213 | |||
214 | static void du_sequential_huff(struct JPEGD *j, struct COMP *sc, TCOEF *coef) | ||
215 | { | ||
216 | int s, k; | ||
217 | dc_decode_huff(j, sc, coef); | ||
218 | for (k=1; s=sc->ACS[ReadHuffmanCode(j, sc->ACB)]; k++) { // EOB? | ||
219 | k+= s>>4; | ||
220 | if (s==0xf0) continue; // ZRL | ||
221 | coef[k]= ReadDiff(j, s&15); | ||
222 | if (k==63) return; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | static void decode_lossless_huff(struct JPEGD *j, struct COMP *sc, int x, int y, TSAMP *samp) // TODO: Pt | ||
227 | { | ||
228 | int DIFF= sc->DCS[ReadHuffmanCode(j, sc->DCB)]; | ||
229 | *samp= Predx(j, sc, x, y, samp); | ||
230 | if (DIFF) *samp+= (DIFF==16)? 32768 : ReadDiff(j, DIFF); | ||
231 | } | ||
232 | |||
233 | |||
234 | static void Reset_decoder_huff(struct JPEGD *j) | ||
235 | { | ||
236 | int c; | ||
237 | for (c=0; c < j->Ns; c++) j->ScanComponents[c]->DC=0; // DC/EOBRUN | ||
238 | j->ScanBit=0; // trigger next byte read (skipping stuffing '1'-s) | ||
239 | } | ||
240 | |||
241 | static void Reset_decoder_huff_lossless(struct JPEGD *j) | ||
242 | { | ||
243 | j->LineNo=0; | ||
244 | j->ScanBit=0; // trigger next byte read | ||
245 | } | ||
246 | |||
247 | |||
248 | |||
249 | |||
250 | /////////////////////////////////// ARITHMETIC ////////////////////////////////////////////// | ||
251 | |||
252 | static int Byte_in_arith(struct JPEGD *j) | ||
253 | { | ||
254 | j->ScanByte = GETC(); | ||
255 | if ( 0xFF == j->ScanByte ) | ||
256 | { | ||
257 | if ( GETC() ) { // Marker detection | ||
258 | SEEK(-2); // Arith: "zero byte fed to decoder" | ||
259 | j->ScanBit=~0; // Seems like 8 was not enough.. TODO | ||
260 | j->ScanByte=0; | ||
261 | } | ||
262 | //else skip zero-stuffing | ||
263 | } | ||
264 | return j->ScanByte; | ||
265 | } | ||
266 | |||
267 | static void ResetStat(struct CABACSTATE *st, int n) // Initialize statistics areas | ||
268 | { | ||
269 | while (--n >= 0) st[n].valMPS= st[n].StateIdx=0; | ||
270 | } | ||
271 | |||
272 | static void InitDecoder(struct JPEGD *j) | ||
273 | { | ||
274 | j->ScanBit=0; // trigger next byte read | ||
275 | j->A=0; | ||
276 | j->C= Byte_in_arith(j) << 8; | ||
277 | j->C|= Byte_in_arith(j); | ||
278 | } | ||
279 | |||
280 | static void Reset_decoder_arith(struct JPEGD *j) | ||
281 | { | ||
282 | int c; | ||
283 | for (c=0; c < j->Ns; c++) | ||
284 | { | ||
285 | struct COMP *sc= j->ScanComponents[c]; | ||
286 | if (j->Se) ResetStat(sc->ACST+1, 245); // AC in Scan (+1 adjusted) | ||
287 | if (!j->Ss) // DC in Scan | ||
288 | { | ||
289 | ResetStat(sc->DCST, 49); | ||
290 | sc->DC= 0; | ||
291 | sc->DIFF= 0; // extra in Arith | ||
292 | } | ||
293 | } | ||
294 | InitDecoder(j); | ||
295 | } | ||
296 | |||
297 | static void Reset_decoder_arith_lossless(struct JPEGD *j) | ||
298 | { | ||
299 | int c; | ||
300 | for (c=0; c < j->Ns; c++) ResetStat(j->ScanComponents[c]->LLST, 158); | ||
301 | j->LineNo=0; // Special in lossless | ||
302 | InitDecoder(j); | ||
303 | } | ||
304 | |||
305 | |||
306 | static struct _STATE { | ||
307 | int Qe_Value, Next_Index_LPS, Next_Index_MPS, Switch_MPS; | ||
308 | } STATE[] = {{0x5A1D,1,1,1},{0x2586,14,2,0},{0x1114,16,3,0},{0x080B,18,4,0},{0x03D8,20,5,0},{0x01DA,23,6,0},{0x00E5,25,7,0},{0x006F,28,8,0},{0x0036,30,9,0},{0x001A,33,10,0},{0x000D,35,11,0},{0x0006,9,12,0},{0x0003,10,13,0},{0x0001,12,13,0},{0x5A7F,15,15,1},{0x3F25,36,16,0},{0x2CF2,38,17,0},{0x207C,39,18,0},{0x17B9,40,19,0},{0x1182,42,20,0},{0x0CEF,43,21,0},{0x09A1,45,22,0},{0x072F,46,23,0},{0x055C,48,24,0},{0x0406,49,25,0},{0x0303,51,26,0},{0x0240,52,27,0},{0x01B1,54,28,0},{0x0144,56,29,0},{0x00F5,57,30,0},{0x00B7,59,31,0},{0x008A,60,32,0},{0x0068,62,33,0},{0x004E,63,34,0},{0x003B,32,35,0},{0x002C,33,9,0},{0x5AE1,37,37,1},{0x484C,64,38,0},{0x3A0D,65,39,0},{0x2EF1,67,40,0},{0x261F,68,41,0},{0x1F33,69,42,0},{0x19A8,70,43,0},{0x1518,72,44,0},{0x1177,73,45,0},{0x0E74,74,46,0},{0x0BFB,75,47,0},{0x09F8,77,48,0},{0x0861,78,49,0},{0x0706,79,50,0},{0x05CD,48,51,0},{0x04DE,50,52,0},{0x040F,50,53,0},{0x0363,51,54,0},{0x02D4,52,55,0},{0x025C,53,56,0},{0x01F8,54,57,0},{0x01A4,55,58,0},{0x0160,56,59,0},{0x0125,57,60,0},{0x00F6,58,61,0},{0x00CB,59,62,0},{0x00AB,61,63,0},{0x008F,61,32,0},{0x5B12,65,65,1},{0x4D04,80,66,0},{0x412C,81,67,0},{0x37D8,82,68,0},{0x2FE8,83,69,0},{0x293C,84,70,0},{0x2379,86,71,0},{0x1EDF,87,72,0},{0x1AA9,87,73,0},{0x174E,72,74,0},{0x1424,72,75,0},{0x119C,74,76,0},{0x0F6B,74,77,0},{0x0D51,75,78,0},{0x0BB6,77,79,0},{0x0A40,77,48,0},{0x5832,80,81,1},{0x4D1C,88,82,0},{0x438E,89,83,0},{0x3BDD,90,84,0},{0x34EE,91,85,0},{0x2EAE,92,86,0},{0x299A,93,87,0},{0x2516,86,71,0},{0x5570,88,89,1},{0x4CA9,95,90,0},{0x44D9,96,91,0},{0x3E22,97,92,0},{0x3824,99,93,0},{0x32B4,99,94,0},{0x2E17,93,86,0},{0x56A8,95,96,1},{0x4F46,101,97,0},{0x47E5,102,98,0},{0x41CF,103,99,0},{0x3C3D,104,100,0},{0x375E,99,93,0},{0x5231,105,102,0},{0x4C0F,106,103,0},{0x4639,107,104,0},{0x415E,103,99,0},{0x5627,105,106,1},{0x50E7,108,107,0},{0x4B85,109,103,0},{0x5597,110,109,0},{0x504F,111,107,0},{0x5A10,110,111,1},{0x5522,112,109,0},{0x59EB,112,111,1}}; | ||
309 | |||
310 | static void Renorm(struct JPEGD *j) | ||
311 | { | ||
312 | do j->C= 2*j->C | GetBit(j); | ||
313 | while ( (short)(j->A*=2) >= 0); | ||
314 | } | ||
315 | |||
316 | static int tr_MPS(struct JPEGD *j, struct CABACSTATE *st) | ||
317 | { | ||
318 | Renorm(j); | ||
319 | st->StateIdx= STATE[ st->StateIdx ].Next_Index_MPS; | ||
320 | return st->valMPS; | ||
321 | } | ||
322 | |||
323 | static int tr_LPS(struct JPEGD *j, struct CABACSTATE *st) | ||
324 | { | ||
325 | int D= st->valMPS^1; | ||
326 | st->valMPS ^= STATE[ st->StateIdx ].Switch_MPS; | ||
327 | st->StateIdx= STATE[ st->StateIdx ].Next_Index_LPS; | ||
328 | Renorm(j); | ||
329 | return D; | ||
330 | } | ||
331 | |||
332 | static int DecodeBin(struct JPEGD *j, struct CABACSTATE *st) | ||
333 | { | ||
334 | unsigned short A= j->A - STATE[ st->StateIdx ].Qe_Value; | ||
335 | if ( j->C < A ) | ||
336 | { | ||
337 | j->A = A; | ||
338 | if ((short)A<0) return st->valMPS; | ||
339 | return ( A < STATE[ st->StateIdx ].Qe_Value )? tr_LPS(j, st) : tr_MPS(j, st); | ||
340 | } | ||
341 | j->C -= A; | ||
342 | j->A= STATE[ st->StateIdx ].Qe_Value; | ||
343 | return ( A < j->A )? tr_MPS(j, st) : tr_LPS(j, st); | ||
344 | } | ||
345 | |||
346 | static int DecodeFIX(struct JPEGD *j) | ||
347 | { | ||
348 | unsigned short A= j->A - 0x5A1D; | ||
349 | if ( j->C < A ) { | ||
350 | if ((short)(j->A = A)<0) return 0; | ||
351 | Renorm(j); | ||
352 | return ( A < 0x5A1D ) ? 1 : 0; | ||
353 | } | ||
354 | else { | ||
355 | j->C = 2*( j->C - A ) | GetBit(j); | ||
356 | j->A= 0x5A1D*2; | ||
357 | return ( A < 0x5A1D ) ? 0 : 1; | ||
358 | } | ||
359 | } | ||
360 | |||
361 | static int DC_Context(struct COMP *sc, int D) // DC + LOSSLESS | ||
362 | { | ||
363 | if (D < 0) { | ||
364 | if ( D < -sc->U ) return 16; // large neg | ||
365 | if ( D < -sc->L ) return 8; | ||
366 | } | ||
367 | else { | ||
368 | if ( D > sc->U ) return 12; // large pos | ||
369 | if ( D > sc->L ) return 4; | ||
370 | } | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static int Decode_V(struct JPEGD *j, struct CABACSTATE *ST, int SNSP, int X1, int X2) // DC/AC | ||
375 | { | ||
376 | int Sz, M; | ||
377 | if ( !DecodeBin(j, ST+SNSP) ) return 1; | ||
378 | if ( !DecodeBin(j, ST+X1) ) return 2; | ||
379 | M=2, ST+=X2; | ||
380 | while ( DecodeBin(j, ST) ) M <<= 1, ST++; | ||
381 | Sz= M; | ||
382 | ST += 14; | ||
383 | while (M>>=1) if (DecodeBin(j, ST)) Sz |= M; | ||
384 | return Sz+1; | ||
385 | } | ||
386 | |||
387 | static int Decode_DIFF(struct JPEGD *j, struct CABACSTATE *ST, int S0, int X1) // DC + LOSSLESS | ||
388 | { | ||
389 | if ( DecodeBin(j, ST+S0) ) // (S0) | ||
390 | { | ||
391 | int sign= DecodeBin(j, ST + S0 + 1); // (SS) | ||
392 | int DIFF= Decode_V(j, ST, S0 + 2 + sign, X1, X1+1); | ||
393 | return (sign)? -DIFF : DIFF; | ||
394 | } | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static void dc_decode_arith(struct JPEGD *j, struct COMP *sc, TCOEF *coef) | ||
399 | { | ||
400 | int S0= DC_Context(sc, sc->DIFF); | ||
401 | sc->DIFF= Decode_DIFF(j, sc->DCST, S0, 20); | ||
402 | sc->DC+= sc->DIFF << j->Al; | ||
403 | *coef= sc->DC; | ||
404 | } | ||
405 | |||
406 | static void ac_band(struct JPEGD *j, struct COMP *sc, TCOEF *coef, int k) // NB: we re-arrange contexts a little (so indexing simply by k) | ||
407 | { | ||
408 | while ( !DecodeBin(j, sc->ACST+k) ) // EOB? | ||
409 | { | ||
410 | int V, sign; | ||
411 | while ( !DecodeBin(j, sc->ACST+k+63) ) k++; // S0 | ||
412 | sign= DecodeFIX(j); | ||
413 | V= Decode_V(j, sc->ACST, k+126, k+126, (k>sc->Kx)? (217+1) : (189+1) ); | ||
414 | if (sign) V = -V; | ||
415 | coef[k]= V << j->Al; | ||
416 | if (k==j->Se) return; | ||
417 | k++; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | static void du_sequential_arith(struct JPEGD *j, struct COMP *sc, TCOEF *coef) | ||
422 | { | ||
423 | dc_decode_arith(j, sc, coef); | ||
424 | ac_band(j, sc, coef, 1); | ||
425 | } | ||
426 | |||
427 | static void ac_decode_arith(struct JPEGD *j, struct COMP *sc, TCOEF *coef) | ||
428 | { | ||
429 | ac_band(j, sc, coef, j->Ss); | ||
430 | } | ||
431 | |||
432 | static void dc_succ_arith(struct JPEGD *j, struct COMP *sc, TCOEF *coef) | ||
433 | { | ||
434 | *coef |= DecodeFIX(j) << j->Al; | ||
435 | } | ||
436 | |||
437 | static void ac_succ_arith(struct JPEGD *j, struct COMP *sc, TCOEF *coef) | ||
438 | { | ||
439 | int k= j->Ss; | ||
440 | int EOBx= j->Se; // actually index of last non-zero coeff already decoded in band | ||
441 | |||
442 | while ( !coef[EOBx] && EOBx >= k ) EOBx--; | ||
443 | |||
444 | for (; k <= EOBx; k++) | ||
445 | { | ||
446 | if ( coef[k]) | ||
447 | { | ||
448 | if (DecodeBin(j, sc->ACST+k+126)) coef[k] += (coef[k] > 0)? j->Al2 : -j->Al2; // SC: correction bit? | ||
449 | } | ||
450 | else | ||
451 | { | ||
452 | if (DecodeBin(j, sc->ACST+k+63)) coef[k]= DecodeFIX(j)? -j->Al2 : j->Al2; // New coeff? | ||
453 | } | ||
454 | } | ||
455 | |||
456 | for (; k <= j->Se && !DecodeBin(j, sc->ACST+k); k++) // SE: EOB? | ||
457 | { | ||
458 | while (!DecodeBin(j, sc->ACST+k+63)) k++; | ||
459 | coef[k]= DecodeFIX(j)? -j->Al2 : j->Al2; | ||
460 | } | ||
461 | } | ||
462 | |||
463 | static void decode_lossless_arith(struct JPEGD *j, struct COMP *sc, int x, int y, TSAMP *samp) // TODO: Pt | ||
464 | { | ||
465 | int Da= x? 5 * DC_Context(sc, sc->diffLeft[y]) : 0; | ||
466 | int Db= y? DC_Context(sc, sc->diffAbove[x]) : 0; | ||
467 | int DIFF= Decode_DIFF(j, sc->LLST, Da + Db, (Db>8)? 129 : 100); | ||
468 | sc->diffAbove[x]= DIFF; | ||
469 | sc->diffLeft[y]= DIFF; | ||
470 | *samp= Predx(j, sc, x, y, samp) + DIFF; | ||
471 | } | ||
472 | |||
473 | |||
474 | /////////////////////////// SCAN DECODING /////////////////////////////////////////////////////////////////////////////// | ||
475 | |||
476 | //static int LocateMarker(struct JPEGD *j) | ||
477 | |||
478 | static int NextMarker(struct JPEGD *j) // at expected location - this is not LocateMarker() | ||
479 | { | ||
480 | int Marker; | ||
481 | printf("%08X: ", TELL()); | ||
482 | while ( 0xFF == (Marker=GETC()) ) printf("FF"); // marker stuffing FF | ||
483 | printf("%02X ", Marker); | ||
484 | return Marker; | ||
485 | } | ||
486 | |||
487 | static void Ri(struct JPEGD *j, int n) | ||
488 | { | ||
489 | if (j->Ri) // Restart enabled? | ||
490 | { | ||
491 | if ( 0 == n % j->Ri ) | ||
492 | { | ||
493 | int Marker= NextMarker(j); | ||
494 | if ( (Marker & 0xf8) == 0xD0 ) // RSTn expected | ||
495 | { | ||
496 | printf("RST%d\n", Marker&7); | ||
497 | printf("%08X: ECS\n", TELL()); | ||
498 | } | ||
499 | else printf("STREAM ERROR: expected RSTn missing from ECS\n"); | ||
500 | j->Reset_decoder(j); | ||
501 | } | ||
502 | } | ||
503 | } | ||
504 | |||
505 | static void DecodeInterleaved_DCT(struct JPEGD *j) | ||
506 | { | ||
507 | int n=0, c, x, y; | ||
508 | |||
509 | for(;;) | ||
510 | { | ||
511 | int mcuy = n / j->mcu_width; | ||
512 | int mcux = n % j->mcu_width; | ||
513 | |||
514 | for (c=0; c < j->Ns; c++) | ||
515 | { | ||
516 | struct COMP *C= j->ScanComponents[c]; | ||
517 | DU *du= C->du + mcuy * C->du_width * C->Vi + mcux * C->Hi; | ||
518 | for (y=0; y<C->Vi; y++) for (x=0; x<C->Hi; x++) j->DecodeDataUnit(j, C, du[ C->du_width * y + x ]); // Huff/arith | ||
519 | } | ||
520 | |||
521 | if (++n==j->mcu_total) return; // We count MCU-s. No RST after the last | ||
522 | Ri(j, n); | ||
523 | } | ||
524 | } | ||
525 | |||
526 | static void DecodeSingle_DCT(struct JPEGD *j) | ||
527 | { | ||
528 | int n=0; | ||
529 | struct COMP *C= j->ScanComponents[0]; | ||
530 | |||
531 | for (;;) | ||
532 | { | ||
533 | j->DecodeDataUnit(j, C, C->du[ (n / C->du_w) * C->du_width + n % C->du_w ]); // Huff/arith | ||
534 | if ( ++n == C->du_size ) return; // We count DU-s. No RST after the last | ||
535 | Ri(j, n); | ||
536 | } | ||
537 | } | ||
538 | |||
539 | |||
540 | static void DecodeSingle_LL(struct JPEGD *j) | ||
541 | { | ||
542 | int n=0, x; | ||
543 | struct COMP *C= j->ScanComponents[0]; | ||
544 | TSAMP *samp= C->samp; | ||
545 | j->LineNo=0; | ||
546 | for (;;) | ||
547 | { | ||
548 | for (x=0; x < C->du_w; x++) j->decode_lossless(j, C, x, j->LineNo, samp+x); // Huff/arith | ||
549 | if ( (n+=C->du_w) == C->du_size ) return; // we count by lines | ||
550 | j->LineNo=1; | ||
551 | Ri(j, n); // Lossless restart interval is one mcu-line | ||
552 | samp+=C->du_width; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | |||
557 | static void DecodeInterleaved_LL(struct JPEGD *j) | ||
558 | { | ||
559 | int n=0, c; | ||
560 | int x, mcux; | ||
561 | int y, mcuy; | ||
562 | j->LineNo=0; | ||
563 | for (mcuy=0; ; mcuy++) | ||
564 | { | ||
565 | for (mcux=0; mcux < j->mcu_width; mcux++) | ||
566 | { | ||
567 | for (c=0; c < j->Ns; c++) | ||
568 | { | ||
569 | struct COMP *C= j->ScanComponents[c]; | ||
570 | int xs= mcux * C->Hi; | ||
571 | TSAMP *samp= C->samp + C->du_width * (mcuy * C->Vi) + xs; | ||
572 | |||
573 | for (y=0; y < C->Vi; y++, samp+=C->du_width) | ||
574 | { | ||
575 | for (x=0; x < C->Hi; x++) j->decode_lossless(j, C, xs+x, j->LineNo+y, samp + x); // Huff/arith | ||
576 | } | ||
577 | } | ||
578 | } | ||
579 | if ( (n+=j->mcu_width) == j->mcu_total ) return; // we count by lines | ||
580 | j->LineNo=1; | ||
581 | Ri(j, n); // Lossless restart interval is one mcu-line | ||
582 | } | ||
583 | } | ||
584 | |||
585 | |||
586 | |||
587 | ////////////////////////////// PARSING ////////////////////////////////////////////////////////////////////////////// | ||
588 | |||
589 | static char *SOFSTRING[] = { // debug | ||
590 | // non-differential, Huffman coding | ||
591 | "Baseline DCT", | ||
592 | "Huffman Extended sequential DCT", | ||
593 | "Huffman Progressive DCT", | ||
594 | "Huffman Lossless sequential", | ||
595 | // differential, Huffman coding (Hierarchial) | ||
596 | "", // DHT | ||
597 | "-Differential sequential DCT", | ||
598 | "-Differential progressive DCT", | ||
599 | "-Differential lossless (sequential)", | ||
600 | // non-differential, arithmetic coding | ||
601 | "", // JPG | ||
602 | "Arithmetic Extended sequential DCT", | ||
603 | "Arithmetic Progressive DCT", | ||
604 | "Arithmetic Lossless sequential", | ||
605 | // differential, arithmetic coding (Hierarchial) | ||
606 | "", // DAC | ||
607 | "-Arithmetic Differential sequential DCT", | ||
608 | "-Arithmetic Differential progressive DCT", | ||
609 | "-Arithmetic Differential lossless sequential", | ||
610 | |||
611 | }; | ||
612 | |||
613 | static int div_up(int a, int b) // ~ciel([a/b]) | ||
614 | { | ||
615 | return (a + b - 1) / b; | ||
616 | } | ||
617 | |||
618 | static int set_dim(struct JPEGD *j, int d) // d= 1 (LL) or 8 (DCT) | ||
619 | { | ||
620 | int i, TotalDU=0; | ||
621 | |||
622 | j->Hmax= j->Vmax= 0; | ||
623 | |||
624 | for (i=0; i<j->Nf; i++) // read component data, set Hmax/Vmax | ||
625 | { | ||
626 | struct COMP *C= j->Components + i; | ||
627 | |||
628 | C->Ci= GETC(); //Cid | ||
629 | C->Vi= GETC(); //HV | ||
630 | C->Hi= C->Vi>>4; | ||
631 | C->Vi&= 15; | ||
632 | C->Qi= GETC(); | ||
633 | |||
634 | if ( C->Hi > j->Hmax ) j->Hmax = C->Hi; | ||
635 | if ( C->Vi > j->Vmax ) j->Vmax = C->Vi; | ||
636 | |||
637 | printf(" Ci=%3d HV=%dx%d Qi=%d\n", C->Ci, C->Hi, C->Vi, C->Qi); | ||
638 | } | ||
639 | printf("\n"); | ||
640 | |||
641 | // Full Image MCU cover: | ||
642 | j->mcu_width= div_up(j->X, j->Hmax*d); | ||
643 | j->mcu_height= div_up(j->Y, j->Vmax*d); | ||
644 | j->mcu_total= j->mcu_width * j->mcu_height; | ||
645 | |||
646 | // now set parameters based on Hmax/Vmax | ||
647 | for (i=0; i<j->Nf; i++) | ||
648 | { | ||
649 | struct COMP *C= j->Components + i; | ||
650 | |||
651 | int xi= div_up(j->X*C->Hi, j->Hmax); // as Standard: sample rectangle (from image X,Y and Sampling factors) | ||
652 | int yi= div_up(j->Y*C->Vi, j->Vmax); // used to compute single scan 'coverage' | ||
653 | |||
654 | // Single scan DU-cover (LL: d=1) | ||
655 | C->du_w= div_up(xi, d); | ||
656 | C->du_h= div_up(yi, d); | ||
657 | C->du_size= C->du_w * C->du_h; | ||
658 | |||
659 | // Interleaved scan DU-cover | ||
660 | C->du_width= j->mcu_width*C->Hi; | ||
661 | C->du_total= C->du_width * j->mcu_height*C->Vi; | ||
662 | |||
663 | TotalDU+= C->du_total; | ||
664 | |||
665 | //printf(" %d\n", i); | ||
666 | //printf(" Sample: x=%d+%d (1:%d) y=%d+%d (1:%d)\n", C->xi, C->dux*8-C->xi, j->Hmax/C->Hi, C->yi, C->duy*8-C->yi, j->Vmax/C->Vi); | ||
667 | //printf(" 8x8 Data Unit: %d (X=%d Y=%d)\n", C->duN, C->dux, C->duy); | ||
668 | //printf(" MCU Data Unit: %d (X=%d Y=%d)\n", C->du_total, C->du_width, C->duyI); | ||
669 | // LL | ||
670 | //printf(" Sample: x=%d (1:%d) y=%d (1:%d)\n", C->du_xi, j->Hmax/C->Hi, C->du_yi, j->Vmax/C->Vi); | ||
671 | } | ||
672 | |||
673 | return TotalDU; | ||
674 | } | ||
675 | |||
676 | |||
677 | extern enum JPEGENUM JPEGDecode(struct JPEGD *j) | ||
678 | { | ||
679 | int marker, i; | ||
680 | |||
681 | j->jpeg_mem= 0; | ||
682 | marker = NextMarker(j); | ||
683 | if ( marker != 0xD8 ) return JPEGENUMERR_MISSING_SOI; | ||
684 | printf("SOI\n"); | ||
685 | |||
686 | // The 'Decoder_setup' procedure | ||
687 | j->Ri=0; | ||
688 | // Arithmetic capable Decoder this is: | ||
689 | // default DC bounds: L = 0 and U = 1, Kx=5 | ||
690 | j->U[0]= j->U[1]= j->U[2]= j->U[3]= 2; // 1<<U | ||
691 | j->L[0]= j->L[1]= j->L[2]= j->L[3]= 0; | ||
692 | j->Kx[0]= j->Kx[1]= j->Kx[2]= j->Kx[3]= 5; | ||
693 | |||
694 | // Set first to zero for scaled quantization | ||
695 | // Also for QT entry redefinition (not implemented, see remarks) | ||
696 | j->QT[0][0]=j->QT[1][0]=j->QT[2][0]=j->QT[3][0]=0; | ||
697 | |||
698 | for (;;) | ||
699 | { | ||
700 | marker = NextMarker(j); | ||
701 | |||
702 | if ( marker == 0xCC ) // DAC | ||
703 | { | ||
704 | int La= GETWbi(); | ||
705 | printf("DAC\n"); | ||
706 | printf(" Arithmetic Conditioning\n parameters:\n"); | ||
707 | for (La-=2; La; La-=2) | ||
708 | { | ||
709 | int CB= GETC(); | ||
710 | int Tc= CB>>4; | ||
711 | int Tb= CB&15; | ||
712 | int Cs= GETC(); | ||
713 | if (Tc) // AC | ||
714 | { | ||
715 | printf(" AC%d Kx=%d\n", Tb, Cs); | ||
716 | j->Kx[Tb]= Cs; | ||
717 | } | ||
718 | else | ||
719 | { | ||
720 | int L= Cs&15; | ||
721 | int U= Cs>>4; | ||
722 | printf(" DC%d L=%d U=%d\n", Tb, Cs&15, Cs>>4); | ||
723 | j->U[Tb]= 1<<U; | ||
724 | j->L[Tb]= L? 1 << (L-1) : 0; | ||
725 | } | ||
726 | } | ||
727 | } | ||
728 | else if ( marker == 0xC8 ) // T.851?? | ||
729 | { | ||
730 | return JPEGENUMERR_MARKERC8; | ||
731 | } | ||
732 | else if ( marker == 0xC4 ) // DHT | ||
733 | { | ||
734 | int N; | ||
735 | int Lh= GETWbi(); | ||
736 | printf("DHT\n"); | ||
737 | for (Lh-=2; Lh; Lh -= 17 + N) | ||
738 | { | ||
739 | int CH= GETC(); | ||
740 | int Tc= CH>>4; | ||
741 | int Th= CH&15; | ||
742 | int *B= j->HTB[Tc][Th]; | ||
743 | unsigned char *S= j->HTS[Tc][Th]; | ||
744 | printf(" %s%d\n", Tc?"AC":"DC", Th); | ||
745 | printf(" N: "); | ||
746 | for (i=N=0; i<16; i++) { | ||
747 | int n= GETC(); | ||
748 | N+= n; | ||
749 | printf("%d ", n); | ||
750 | B[i]= N; // running total | ||
751 | } | ||
752 | printf("\n"); | ||
753 | printf(" S: %d symbol bytes\n", N); | ||
754 | for (i=0; i<N; i++) S[i]= GETC(); | ||
755 | } | ||
756 | } | ||
757 | else if ( (marker & 0xf0) == 0xC0 ) // START OF FRAME SOFn C0..CF (C4, CC, C8 checked before) | ||
758 | { | ||
759 | GETWbi();//Lf | ||
760 | j->P= GETC();//P | ||
761 | j->Y= GETWbi();//Y: Number of lines | ||
762 | j->X= GETWbi();//X: Number of samples per line | ||
763 | j->Nf= GETC();//Nf | ||
764 | |||
765 | printf("SOF%d (%s)\n", marker&15, SOFSTRING[marker&15]); | ||
766 | printf(" P=%d Y=%d X=%d\n", j->P, j->Y, j->X); | ||
767 | printf(" Nf=%d\n", j->Nf); | ||
768 | |||
769 | if (*SOFSTRING[marker&15] == '-') return JPEGENUMERR_UNKNOWN_SOF; | ||
770 | if (j->Nf>4) return JPEGENUMERR_COMP4; | ||
771 | if (!j->Y) return JPEGENUMERR_ZEROY; // I have no idea about this DNL stuff | ||
772 | j->SOF= marker; | ||
773 | |||
774 | if ( (j->SOF&3)==3 ) // LOSSLESS-mode | ||
775 | { | ||
776 | int TotalDU= set_dim(j, 1); // for malloc: in samples as coeff; | ||
777 | |||
778 | if (j->SOF > 0xC8) { // arithmetic: | ||
779 | |||
780 | j->Reset_decoder= Reset_decoder_arith_lossless; | ||
781 | j->decode_lossless= decode_lossless_arith; | ||
782 | j->Byte_in= Byte_in_arith; | ||
783 | |||
784 | // Arithmetic: need a line to store DIFF, where??? | ||
785 | for (i=0; i<j->Nf; i++) | ||
786 | { | ||
787 | struct COMP *C= j->Components + i; | ||
788 | C->du_total += C->du_width; | ||
789 | TotalDU+= C->du_width; | ||
790 | } | ||
791 | } | ||
792 | else { // Huffman | ||
793 | j->Reset_decoder= Reset_decoder_huff_lossless; | ||
794 | j->decode_lossless= decode_lossless_huff; | ||
795 | j->Byte_in= Byte_in_huff; | ||
796 | } | ||
797 | |||
798 | // malloc sample storage | ||
799 | { | ||
800 | TSAMP *samp; | ||
801 | int mallocTotalCoef= sizeof(TSAMP) * TotalDU; | ||
802 | j->jpeg_mem= calloc(mallocTotalCoef, 1); | ||
803 | if ( 0 == j->jpeg_mem ) return JPEGENUMERR_MALLOC; | ||
804 | samp= j->jpeg_mem; | ||
805 | for (i=0; i<j->Nf; i++) | ||
806 | { | ||
807 | struct COMP *C= j->Components + i; | ||
808 | C->samp= samp; | ||
809 | samp+= C->du_total; | ||
810 | C->diffAbove= samp - C->du_width; // 1 line DIFF-BUFFER for Arith | ||
811 | } | ||
812 | } | ||
813 | } | ||
814 | else // DCT-mode | ||
815 | { | ||
816 | int TotalDU= set_dim(j, 8); // for malloc in DU; | ||
817 | |||
818 | printf(" %d MCU (%d x %d)\n", j->mcu_total, j->mcu_width, j->mcu_height); | ||
819 | |||
820 | // malloc DU-s | ||
821 | { | ||
822 | DU *du; | ||
823 | int mallocTotalCoef= sizeof(DU) * TotalDU; | ||
824 | j->jpeg_mem= calloc(mallocTotalCoef, 1); | ||
825 | if ( 0 == j->jpeg_mem ) return JPEGENUMERR_MALLOC; | ||
826 | du= j->jpeg_mem; | ||
827 | for (i=0; i<j->Nf; i++) | ||
828 | { | ||
829 | struct COMP *C= j->Components + i; | ||
830 | C->du= du; | ||
831 | du+= C->du_total; | ||
832 | } | ||
833 | } | ||
834 | |||
835 | printf(" Malloc for %d Data Units (%d bytes)\n\n", TotalDU, sizeof(DU)*TotalDU); | ||
836 | |||
837 | if (j->SOF > 0xC8) { // DCT Arithmetic | ||
838 | j->Reset_decoder= Reset_decoder_arith; | ||
839 | j->Byte_in= Byte_in_arith; | ||
840 | } | ||
841 | else { // DCT Huffman | ||
842 | j->Reset_decoder= Reset_decoder_huff; | ||
843 | j->Byte_in= Byte_in_huff; | ||
844 | } | ||
845 | } | ||
846 | } | ||
847 | /*else if ( (marker & 0xf8) == 0xD0 ) // RSTn D0..D7 | ||
848 | { | ||
849 | printf("RST%d\n", marker&7); | ||
850 | printf("%08X: ....\n", TELL()); | ||
851 | }*/ | ||
852 | else if ( marker == 0xD9 ) // EOI | ||
853 | { | ||
854 | printf("EOI\n"); | ||
855 | return JPEGENUM_OK; | ||
856 | } | ||
857 | else if ( marker == 0xDA ) // SOS | ||
858 | { | ||
859 | int ci; | ||
860 | GETWbi(); //Ls | ||
861 | printf("SOS\n"); | ||
862 | j->Ns= GETC();//Ns | ||
863 | printf(" Ns: %d (%s scan)\n", j->Ns, (j->Ns>1)?"Interleaved":"Single"); | ||
864 | |||
865 | for (ci=0; ci<j->Ns; ci++) | ||
866 | { | ||
867 | struct COMP *sc; | ||
868 | int Cs= GETC(); // Cs -> Cid (Scan component selector) | ||
869 | int T= GETC(); | ||
870 | int Td= T>>4; | ||
871 | int Ta= T&15; | ||
872 | printf(" Cs=%d Td=%d Ta=%d\n", Cs, Td, Ta); | ||
873 | |||
874 | {// safe search | ||
875 | for ( i=0; i<4 && j->Components[i].Ci != Cs; i++ ) ; | ||
876 | if ( 4 == i ) return JPEGENUMERR_COMPNOTFOUND; | ||
877 | j->ScanComponents[ci]= sc= j->Components+i; | ||
878 | } | ||
879 | |||
880 | if (j->SOF > 0xC8) // arithmetic | ||
881 | { | ||
882 | sc->U= j->U[Td]; | ||
883 | sc->L= j->L[Td]; | ||
884 | sc->Kx= j->Kx[Ta]; | ||
885 | |||
886 | if ((j->SOF&3)==3) sc->LLST= j->ACST[Td]; // LOSSLESS: ACST re-used to save storage (lossles stat. area little less than AC, but more than DC) | ||
887 | else { | ||
888 | sc->ACST= j->ACST[Ta]-1; // DCT. Modified for speed: use 'k' to index the 63 increments for S0, SN,SP... | ||
889 | sc->DCST= j->DCST[Td]; | ||
890 | } | ||
891 | } | ||
892 | else { // Huffman | ||
893 | sc->ACB= j->HTB[1][Ta]; | ||
894 | sc->ACS= j->HTS[1][Ta]; | ||
895 | sc->DCB= j->HTB[0][Td]; | ||
896 | sc->DCS= j->HTS[0][Td]; | ||
897 | } | ||
898 | } | ||
899 | |||
900 | j->Ss= GETC();//Ss (DCT) or Px (LL) | ||
901 | j->Se= GETC();//Se | ||
902 | j->Al= GETC();//AhAl | ||
903 | j->Ah= j->Al>>4; | ||
904 | j->Al&= 15; | ||
905 | j->Al2= 1<<j->Al;//pre-computed | ||
906 | |||
907 | printf(" %s: %d\n", ((j->SOF&3)==3)?"Px":"Ss", j->Ss); | ||
908 | printf(" Se: %d\n", j->Se); | ||
909 | printf(" Ah: %d\n", j->Ah); | ||
910 | printf(" %s: %d\n", ((j->SOF&3)==3)?"Pt":"Al", j->Al); | ||
911 | |||
912 | printf("%08X: ECS\n", TELL()); // Entropy-Coded Segment | ||
913 | |||
914 | j->Reset_decoder(j); // arithmetic/huffman/lossless | ||
915 | |||
916 | if ((j->SOF&3)==3) // LOSSLESS | ||
917 | { | ||
918 | if (j->Ns>1) | ||
919 | { | ||
920 | DecodeInterleaved_LL(j); | ||
921 | } | ||
922 | else | ||
923 | { | ||
924 | DecodeSingle_LL(j); | ||
925 | } | ||
926 | } | ||
927 | else { // DCT-type | ||
928 | |||
929 | if (j->SOF > 0xC8) // arithmetic: | ||
930 | { | ||
931 | j->DecodeDataUnit= j->Ss? (j->Ah? ac_succ_arith : ac_decode_arith) : (j->Se? du_sequential_arith : (j->Ah? dc_succ_arith : dc_decode_arith)); | ||
932 | } | ||
933 | else { | ||
934 | j->DecodeDataUnit= j->Ss? (j->Ah? ac_succ_huff : ac_decode_huff) : (j->Se? du_sequential_huff : (j->Ah? dc_succ_huff : dc_decode_huff)); | ||
935 | } | ||
936 | |||
937 | if (j->Ns>1) | ||
938 | { | ||
939 | DecodeInterleaved_DCT(j); | ||
940 | } | ||
941 | else | ||
942 | { | ||
943 | DecodeSingle_DCT(j); | ||
944 | } | ||
945 | } | ||
946 | } | ||
947 | else if ( marker == 0xDB ) // DQT | ||
948 | { | ||
949 | // Just read in (this is a coeff-decoder) | ||
950 | int Pq; | ||
951 | int Lq= GETWbi(); | ||
952 | printf("DQT\n"); | ||
953 | |||
954 | for (Lq-=2; Lq; Lq -= 65 + 64*Pq) | ||
955 | { | ||
956 | int (*get)(); | ||
957 | int T= GETC(); | ||
958 | int Tq= T&3; | ||
959 | int *qt= j->QT[Tq]; | ||
960 | Pq= T>>4; | ||
961 | printf(" Tq=%d Pq=%d (%d-bit)\n", Tq, Pq, Pq?16:8); | ||
962 | get= Pq? GETWbi : GETC; | ||
963 | if (*qt) return JPEGENUMERR_QTREDEF; // re-defined quant table? Can be, not implemented. | ||
964 | for (i=0; i<64; i++) qt[i]= get(); | ||
965 | } | ||
966 | } | ||
967 | else if ( marker == 0xDC ) // DNL | ||
968 | { | ||
969 | printf("DNL\n"); | ||
970 | return JPEGENUMERR_MARKERDNL; | ||
971 | } | ||
972 | else if ( marker == 0xDD ) // DRI | ||
973 | { | ||
974 | GETWbi();//Lr | ||
975 | j->Ri= GETWbi(); | ||
976 | printf("DRI\n"); | ||
977 | printf(" Ri: %d\n", j->Ri); | ||
978 | } | ||
979 | else if ( (marker & 0xf0) == 0xE0 ) // APPn E0..EF | ||
980 | { | ||
981 | int La= GETWbi(); | ||
982 | SEEK(La-2); | ||
983 | printf("APP%d\n", marker&15); | ||
984 | } | ||
985 | else if ( marker == 0xFE ) // COM | ||
986 | { | ||
987 | SEEK(GETWbi()-2); | ||
988 | printf("COM\n"); | ||
989 | } | ||
990 | else | ||
991 | { | ||
992 | printf("???\n"); | ||
993 | } | ||
994 | } | ||
995 | } | ||
diff --git a/apps/plugins/imageviewer/jpegp/jpeg81.h b/apps/plugins/imageviewer/jpegp/jpeg81.h new file mode 100644 index 0000000000..fa71b10113 --- /dev/null +++ b/apps/plugins/imageviewer/jpegp/jpeg81.h | |||
@@ -0,0 +1,147 @@ | |||
1 | /* Copyright (c) 2017 A. Tarpai | ||
2 | * | ||
3 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
4 | * of this software and associated documentation files (the "Software"), to deal | ||
5 | * in the Software without restriction, including without limitation the rights | ||
6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
7 | * copies of the Software, and to permit persons to whom the Software is | ||
8 | * furnished to do so, subject to the following conditions: | ||
9 | * | ||
10 | * The above copyright notice and this permission notice shall be included in all | ||
11 | * copies or substantial portions of the Software. | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
19 | * SOFTWARE. | ||
20 | */ | ||
21 | |||
22 | enum JPEGENUM { | ||
23 | JPEGENUM_OK=1, | ||
24 | JPEGENUMERR_MISSING_SOI = -999, // file doesnt start with SOI | ||
25 | JPEGENUMERR_UNKNOWN_SOF, // differential frame? | ||
26 | JPEGENUMERR_COMP4, // more than 4 components in file | ||
27 | JPEGENUMERR_MALLOC, // malloc failed | ||
28 | JPEGENUMERR_NODHT, // no DHT found | ||
29 | JPEGENUMERR_NODQT, // no DQT found | ||
30 | JPEGENUMERR_QTREDEF, // not implemented (*) | ||
31 | JPEGENUMERR_MARKERC8, // JPG-1 extension? | ||
32 | JPEGENUMERR_MARKERDNL, // DNL marker found (not supported) | ||
33 | JPEGENUMERR_ZEROY, // Y in SOFn is zero (DNL?) | ||
34 | JPEGENUMERR_COMPNOTFOUND, // Scan component selector (Csj) not found among Component identifiers (Ci) | ||
35 | }; | ||
36 | |||
37 | typedef short TCOEF; // 16-bit coefficients | ||
38 | typedef TCOEF DU[64]; // The DATA UNIT | ||
39 | typedef unsigned short TSAMP; // Lossless 'coefficients' are unsigned | ||
40 | |||
41 | struct CABACSTATE { // borrowed from the AVC decoder | ||
42 | int StateIdx; | ||
43 | int valMPS; | ||
44 | }; | ||
45 | |||
46 | struct COMP { // Image Component Info and variables | ||
47 | |||
48 | // from SOF | ||
49 | int Ci; // Component identifier | ||
50 | int Hi; // Horizontal sampling factor | ||
51 | int Vi; // Vertical sampling factor | ||
52 | int Qi; // Quantization table destination selector | ||
53 | |||
54 | // Computed parameters | ||
55 | int du_w, du_h; // width/height in data units for single scans and for idct/conversion | ||
56 | int du_size; // = du_w * du_h | ||
57 | |||
58 | int du_width; // total width in DU (storage and interleaved scans) | ||
59 | int du_total; // -> for malloc | ||
60 | |||
61 | // Component coefficient buffer | ||
62 | union { | ||
63 | DU *du; // DCT: pointer to DU | ||
64 | TSAMP *samp; // LL | ||
65 | }; | ||
66 | |||
67 | // In scans | ||
68 | union { // either/or | ||
69 | int DC; // jpeg's differential encoded DC (per scan-component) | ||
70 | int EOBRUN; // Only in AC-single scan (Huffman) | ||
71 | }; | ||
72 | |||
73 | // Huffman | ||
74 | int *ACB; // AC-'base-values' | ||
75 | unsigned char *ACS; // AC-symbols | ||
76 | int *DCB; | ||
77 | unsigned char *DCS; | ||
78 | |||
79 | // Arithmetic | ||
80 | struct CABACSTATE *DCST; // DC-statistical area | ||
81 | struct CABACSTATE *ACST; // with -1 offset (we use 'k' itself for addressing) | ||
82 | struct CABACSTATE *LLST; | ||
83 | int U, L, Kx; | ||
84 | int DIFF; // diff value for the previous DC | ||
85 | |||
86 | // Lossless | ||
87 | short *diffAbove; // stored DIFF for LOSSLESS (an MCU line - 1?) | ||
88 | int diffLeft[4+1]; // LineNo added (to fast test for zero) | ||
89 | }; | ||
90 | |||
91 | |||
92 | struct JPEGD { // The JPEG DECODER OBJECT | ||
93 | |||
94 | struct COMP Components[4]; | ||
95 | |||
96 | // SOFn: Frame Header | ||
97 | int Nf; | ||
98 | int P; | ||
99 | int Y, X; // "number of samples per line in the component with the maximum number of horizontal samples" and vertical | ||
100 | int SOF; // save marker to make decisions | ||
101 | int QT[4][64]; // Q-tables from stream | ||
102 | |||
103 | void *jpeg_mem; // <-- free me | ||
104 | |||
105 | int Hmax, Vmax; // for conversion | ||
106 | int mcu_width; | ||
107 | int mcu_height; | ||
108 | int mcu_total; // covers the whole image | ||
109 | |||
110 | int HTB[2][4][16]; // Huffman 'base' values | ||
111 | unsigned char HTS[2][4][256]; // Huffman 'symbol' values | ||
112 | |||
113 | |||
114 | int Ri; // Restart interval | ||
115 | |||
116 | void (*Reset_decoder)(struct JPEGD *j); // huffman/arithmetic/lossless | ||
117 | |||
118 | // Actual Scan | ||
119 | int Ns; | ||
120 | struct COMP *ScanComponents[4]; // --> pointer to COMP in order of scan component definition | ||
121 | int Ss, Se, Al, Ah; | ||
122 | int Al2; // =1<<Al | ||
123 | |||
124 | int ScanByte; | ||
125 | int ScanBit; | ||
126 | int (*Byte_in)(struct JPEGD *j); // huffman/arithmetic | ||
127 | void (*DecodeDataUnit)(struct JPEGD *j, struct COMP *sc, TCOEF *coef); // DCT huffman/arithmetic | ||
128 | |||
129 | |||
130 | // LOSSLESS | ||
131 | int LineNo; // Ri clears this | ||
132 | void (*decode_lossless)(struct JPEGD *j, struct COMP *C, int x, int y, TSAMP *coef); // huffman/arithmetic | ||
133 | |||
134 | // Arith | ||
135 | // DAC, ArithmeticConditioning | ||
136 | int U[4], L[4], Kx[4]; | ||
137 | |||
138 | unsigned short C; //CodeRegister; // C <-- from bit stream | ||
139 | unsigned short A; //ProbabilityIntervalRegister; // A <-- | ||
140 | |||
141 | // AVC-style (JPEG 'statictical area') | ||
142 | struct CABACSTATE DCST[4][49]; | ||
143 | struct CABACSTATE ACST[4][245]; | ||
144 | |||
145 | }; | ||
146 | |||
147 | extern int JPEGDecode(struct JPEGD *j); | ||
diff --git a/docs/CREDITS b/docs/CREDITS index a4b23cd412..10ce7e71c9 100644 --- a/docs/CREDITS +++ b/docs/CREDITS | |||
@@ -771,3 +771,4 @@ The microtar team (rxi and others) | |||
771 | The UnifontEX and GNU Unifont teams | 771 | The UnifontEX and GNU Unifont teams |
772 | The xrick team | 772 | The xrick team |
773 | The Terminus Font team | 773 | The Terminus Font team |
774 | Attila Tarpai (The RAINBOW image decoder lib author) | ||