summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Artiukhin <bahusdrive@gmail.com>2024-10-09 17:31:17 +0300
committerSolomon Peachy <pizza@shaftnet.org>2024-10-14 09:19:34 -0400
commit64ad7354b6bbc61782935f64873afdf2c0a18bc1 (patch)
tree8a63030501dbb910a88cacfeae150bd068fb6c2a
parent772eff8ca6268fc613637d25cb7056419af48442 (diff)
downloadrockbox-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.h56
-rw-r--r--apps/plugins/imageviewer/jpegp/idct.c134
-rw-r--r--apps/plugins/imageviewer/jpegp/idct.h6
-rw-r--r--apps/plugins/imageviewer/jpegp/jpeg81.c995
-rw-r--r--apps/plugins/imageviewer/jpegp/jpeg81.h147
-rw-r--r--docs/CREDITS1
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
40extern int GETC();
41
42// Multibyte helpers
43extern int GETWbi(); // read word (16-bit) big-endian
44extern int GETWli(); // little-endian
45extern int GETDbi(); // read double word (32-bit) big-endian
46extern int GETDli(); // little-endian
47
48// positioning
49extern void SEEK(int); // move relative to current
50extern void POS(int); // move absolute position (TIFF)
51extern int TELL(); // read actual position
52
53
54// For RAINBOW clients to implement outside of Rainbow Library
55extern void *OPEN(char*);
56extern 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
39int 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
50static 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};
55unsigned 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
60static 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
95extern 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
112int 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
123extern 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 @@
1extern void idct_sq(short *coef, int *q); // <-- scaled integer idct WITH de-quantization
2extern void idct_s(int *t, short *y); // <-- scaled integer idct
3
4extern int zigzag[64];
5extern int SCALEM[64];
6extern 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/************************************************************************
2jpeg81.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
51static int P1(struct COMP *C, TSAMP *samp) // Px = Ra
52{
53 return samp[-1];
54}
55
56static int P2(struct COMP *C, TSAMP *samp) // Px = Rb
57{
58 return samp[-C->du_width];
59}
60
61static int P3(struct COMP *C, TSAMP *samp) // Px = Rc
62{
63 return samp[-C->du_width-1];
64}
65
66static 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
71static 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
76static 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
81static int P7(struct COMP *C, TSAMP *samp) // Px = (Ra + Rb)/2
82{
83 return (samp[-1] + samp[-C->du_width]) >> 1;
84}
85
86static int (*PN[])(struct COMP *C, TSAMP *samp) = {
87 0, P1, P2, P3, P4, P5, P6, P7
88};
89
90static 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
107static 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
123static 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
130static 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
137static 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
144static 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
151static void dc_succ_huff(struct JPEGD *j, struct COMP *sc, TCOEF *coef)
152{
153 *coef |= GetBit(j) << j->Al;
154}
155
156static 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
163static 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
185static 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
191static 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
214static 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
226static 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
234static 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
241static 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
252static 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
267static void ResetStat(struct CABACSTATE *st, int n) // Initialize statistics areas
268{
269 while (--n >= 0) st[n].valMPS= st[n].StateIdx=0;
270}
271
272static 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
280static 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
297static 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
306static 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
310static void Renorm(struct JPEGD *j)
311{
312 do j->C= 2*j->C | GetBit(j);
313 while ( (short)(j->A*=2) >= 0);
314}
315
316static 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
323static 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
332static 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
346static 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
361static 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
374static 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
387static 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
398static 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
406static 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
421static 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
427static void ac_decode_arith(struct JPEGD *j, struct COMP *sc, TCOEF *coef)
428{
429 ac_band(j, sc, coef, j->Ss);
430}
431
432static void dc_succ_arith(struct JPEGD *j, struct COMP *sc, TCOEF *coef)
433{
434 *coef |= DecodeFIX(j) << j->Al;
435}
436
437static 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
463static 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
478static 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
487static 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
505static 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
526static 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
540static 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
557static 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
589static 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
613static int div_up(int a, int b) // ~ciel([a/b])
614{
615 return (a + b - 1) / b;
616}
617
618static 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
677extern 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
22enum 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
37typedef short TCOEF; // 16-bit coefficients
38typedef TCOEF DU[64]; // The DATA UNIT
39typedef unsigned short TSAMP; // Lossless 'coefficients' are unsigned
40
41struct CABACSTATE { // borrowed from the AVC decoder
42 int StateIdx;
43 int valMPS;
44};
45
46struct 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
92struct 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
147extern 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)
771The UnifontEX and GNU Unifont teams 771The UnifontEX and GNU Unifont teams
772The xrick team 772The xrick team
773The Terminus Font team 773The Terminus Font team
774Attila Tarpai (The RAINBOW image decoder lib author)