mbed port of "TJpgDec - Tiny JPEG Decompressor" http://elm-chan.org/fsw/tjpgd/00index.html

Dependents:   Nucleo_Pic_Viewer GSDPlayer b2b

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TinyJpgDec.cpp Source File

TinyJpgDec.cpp

00001 // see also http://elm-chan.org/fsw/tjpgd/00index.html
00002 
00003 /*----------------------------------------------------------------------------/
00004 / TJpgDec - Tiny JPEG Decompressor R0.01b                     (C)ChaN, 2012
00005 /-----------------------------------------------------------------------------/
00006 / The TJpgDec is a generic JPEG decompressor module for tiny embedded systems.
00007 / This is a free software that opened for education, research and commercial
00008 /  developments under license policy of following terms.
00009 /
00010 /  Copyright (C) 2012, ChaN, all right reserved.
00011 /
00012 / * The TJpgDec module is a free software and there is NO WARRANTY.
00013 / * No restriction on use. You can use, modify and redistribute it for
00014 /   personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
00015 / * Redistributions of source code must retain the above copyright notice.
00016 /
00017 /-----------------------------------------------------------------------------/
00018 / Oct 04,'11 R0.01  First release.
00019 / Feb 19,'12 R0.01a Fixed decompression fails when scan starts with an escape seq.
00020 / Sep 03,'12 R0.01b Added JD_TBLCLIP option.
00021 /----------------------------------------------------------------------------*/
00022 
00023 #include "TinyJpgDec.h"
00024 #include "mbed.h" //evillive
00025 
00026 /*-----------------------------------------------*/
00027 /* Zigzag-order to raster-order conversion table */
00028 /*-----------------------------------------------*/
00029 
00030 #define ZIG(n)  Zig[n]
00031 
00032 static
00033 const BYTE Zig[64] = {  /* Zigzag-order to raster-order conversion table */
00034     0,  1,  8, 16,  9,  2,  3, 10, 17, 24, 32, 25, 18, 11,  4,  5,
00035     12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13,  6,  7, 14, 21, 28,
00036     35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
00037     58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
00038 };
00039 
00040 
00041 
00042 /*-------------------------------------------------*/
00043 /* Input scale factor of Arai algorithm            */
00044 /* (scaled up 16 bits for fixed point operations)  */
00045 /*-------------------------------------------------*/
00046 
00047 #define IPSF(n) Ipsf[n]
00048 
00049 static
00050 const WORD Ipsf[64] = { /* See also aa_idct.png */
00051     (WORD)(1.00000*8192), (WORD)(1.38704*8192), (WORD)(1.30656*8192), (WORD)(1.17588*8192), (WORD)(1.00000*8192), (WORD)(0.78570*8192), (WORD)(0.54120*8192), (WORD)(0.27590*8192),
00052     (WORD)(1.38704*8192), (WORD)(1.92388*8192), (WORD)(1.81226*8192), (WORD)(1.63099*8192), (WORD)(1.38704*8192), (WORD)(1.08979*8192), (WORD)(0.75066*8192), (WORD)(0.38268*8192),
00053     (WORD)(1.30656*8192), (WORD)(1.81226*8192), (WORD)(1.70711*8192), (WORD)(1.53636*8192), (WORD)(1.30656*8192), (WORD)(1.02656*8192), (WORD)(0.70711*8192), (WORD)(0.36048*8192),
00054     (WORD)(1.17588*8192), (WORD)(1.63099*8192), (WORD)(1.53636*8192), (WORD)(1.38268*8192), (WORD)(1.17588*8192), (WORD)(0.92388*8192), (WORD)(0.63638*8192), (WORD)(0.32442*8192),
00055     (WORD)(1.00000*8192), (WORD)(1.38704*8192), (WORD)(1.30656*8192), (WORD)(1.17588*8192), (WORD)(1.00000*8192), (WORD)(0.78570*8192), (WORD)(0.54120*8192), (WORD)(0.27590*8192),
00056     (WORD)(0.78570*8192), (WORD)(1.08979*8192), (WORD)(1.02656*8192), (WORD)(0.92388*8192), (WORD)(0.78570*8192), (WORD)(0.61732*8192), (WORD)(0.42522*8192), (WORD)(0.21677*8192),
00057     (WORD)(0.54120*8192), (WORD)(0.75066*8192), (WORD)(0.70711*8192), (WORD)(0.63638*8192), (WORD)(0.54120*8192), (WORD)(0.42522*8192), (WORD)(0.29290*8192), (WORD)(0.14932*8192),
00058     (WORD)(0.27590*8192), (WORD)(0.38268*8192), (WORD)(0.36048*8192), (WORD)(0.32442*8192), (WORD)(0.27590*8192), (WORD)(0.21678*8192), (WORD)(0.14932*8192), (WORD)(0.07612*8192)
00059 };
00060 
00061 
00062 
00063 /*---------------------------------------------*/
00064 /* Conversion table for fast clipping process  */
00065 /*---------------------------------------------*/
00066 
00067 #if JD_TBLCLIP
00068 
00069 #define BYTECLIP(v) Clip8[(UINT)(v) & 0x3FF]
00070 
00071 static
00072 const BYTE Clip8[1024] = {
00073     /* 0..255 */
00074     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,
00075     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,
00076     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,
00077     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,
00078     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,
00079     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,
00080     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,
00081     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,
00082     /* 256..511 */
00083     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00084     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00085     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00086     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00087     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00088     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00089     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00090     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00091     /* -512..-257 */
00092     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00093     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00094     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00095     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00096     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00097     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00098     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00099     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00100     /* -256..-1 */
00101     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00102     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00103     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00104     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00105     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00106     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00107     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00108     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00109 };
00110 
00111 #else   /* JD_TBLCLIP */
00112 
00113 inline
00114 BYTE BYTECLIP (
00115     INT val
00116 )
00117 {
00118     if (val < 0) val = 0;
00119     if (val > 255) val = 255;
00120 
00121     return (BYTE)val;
00122 }
00123 
00124 #endif
00125 
00126 
00127 
00128 /*-----------------------------------------------------------------------*/
00129 /* Allocate a memory block from memory pool                              */
00130 /*-----------------------------------------------------------------------*/
00131 
00132 static
00133 void* alloc_pool (  /* Pointer to allocated memory block (NULL:no memory available) */
00134     JDEC* jd,       /* Pointer to the decompressor object */
00135     UINT nd         /* Number of bytes to allocate */
00136 )
00137 {
00138     char *rp = 0;
00139 
00140 
00141     nd = (nd + 3) & ~3;         /* Align block size to the word boundary */
00142 
00143     if (jd->sz_pool >= nd) {
00144         jd->sz_pool -= nd;
00145         rp = (char*)jd->pool;           /* Get start of available memory pool */
00146         jd->pool = (void*)(rp + nd);    /* Allocate requierd bytes */
00147     }
00148 
00149     return (void*)rp;   /* Return allocated memory block (NULL:no memory to allocate) */
00150 }
00151 
00152 
00153 
00154 
00155 /*-----------------------------------------------------------------------*/
00156 /* Create de-quantization and prescaling tables with a DQT segment       */
00157 /*-----------------------------------------------------------------------*/
00158 
00159 static
00160 JRESULT // UINT evillive
00161 create_qt_tbl (    /* 0:OK, !0:Failed */
00162     JDEC* jd,           /* Pointer to the decompressor object */
00163     const BYTE* data,   /* Pointer to the quantizer tables */
00164     UINT ndata          /* Size of input data */
00165 )
00166 {
00167     UINT i;
00168     BYTE d, z;
00169     LONG *pb;
00170 
00171 
00172     while (ndata) { /* Process all tables in the segment */
00173         if (ndata < 65) return JDR_FMT1;    /* Err: table size is unaligned */
00174         ndata -= 65;
00175         d = *data++;                            /* Get table property */
00176         if (d & 0xF0) return JDR_FMT1;          /* Err: not 8-bit resolution */
00177         i = d & 3;                              /* Get table ID */
00178         pb = (LONG*)alloc_pool(jd, 64 * sizeof (LONG));/* Allocate a memory block for the table */
00179         if (!pb) return JDR_MEM1;               /* Err: not enough memory */
00180         jd->qttbl[i] = pb;                      /* Register the table */
00181         for (i = 0; i < 64; i++) {              /* Load the table */
00182             z = ZIG(i);                         /* Zigzag-order to raster-order conversion */
00183             pb[z] = (LONG)((DWORD)*data++ * IPSF(z));   /* Apply scale factor of Arai algorithm to the de-quantizers */
00184         }
00185     }
00186 
00187     return JDR_OK;
00188 }
00189 
00190 
00191 
00192 
00193 /*-----------------------------------------------------------------------*/
00194 /* Create huffman code tables with a DHT segment                         */
00195 /*-----------------------------------------------------------------------*/
00196 
00197 static
00198 JRESULT //UINT  evillive
00199 create_huffman_tbl (   /* 0:OK, !0:Failed */
00200     JDEC* jd,               /* Pointer to the decompressor object */
00201     const BYTE* data,       /* Pointer to the packed huffman tables */
00202     UINT ndata              /* Size of input data */
00203 )
00204 {
00205     UINT i, j, b, np, cls, num;
00206     BYTE d, *pb, *pd;
00207     WORD hc, *ph;
00208 
00209 
00210     while (ndata) { /* Process all tables in the segment */
00211         if (ndata < 17) return JDR_FMT1;    /* Err: wrong data size */
00212         ndata -= 17;
00213         d = *data++;                        /* Get table number and class */
00214         cls = (d >> 4);
00215         num = d & 0x0F;     /* class = dc(0)/ac(1), table number = 0/1 */
00216         if (d & 0xEE) return JDR_FMT1;      /* Err: invalid class/number */
00217         pb = (BYTE*)alloc_pool(jd, 16);            /* Allocate a memory block for the bit distribution table */
00218         if (!pb) return JDR_MEM1;           /* Err: not enough memory */
00219         jd->huffbits[num][cls] = pb;
00220         for (np = i = 0; i < 16; i++) {     /* Load number of patterns for 1 to 16-bit code */
00221             pb[i] = b = *data++;
00222             np += b;    /* Get sum of code words for each code */
00223         }
00224 
00225         ph = (WORD*)alloc_pool(jd, np * sizeof (WORD));/* Allocate a memory block for the code word table */
00226         if (!ph) return JDR_MEM1;           /* Err: not enough memory */
00227         jd->huffcode[num][cls] = ph;
00228         hc = 0;
00229         for (j = i = 0; i < 16; i++) {      /* Re-build huffman code word table */
00230             b = pb[i];
00231             while (b--) ph[j++] = hc++;
00232             hc <<= 1;
00233         }
00234 
00235         if (ndata < np) return JDR_FMT1;    /* Err: wrong data size */
00236         ndata -= np;
00237         pd = (BYTE*)alloc_pool(jd, np);            /* Allocate a memory block for the decoded data */
00238         if (!pd) return JDR_MEM1;           /* Err: not enough memory */
00239         jd->huffdata[num][cls] = pd;
00240         for (i = 0; i < np; i++) {          /* Load decoded data corresponds to each code ward */
00241             d = *data++;
00242             if (!cls && d > 11) return JDR_FMT1;
00243             *pd++ = d;
00244         }
00245     }
00246 
00247     return JDR_OK;
00248 }
00249 
00250 
00251 
00252 
00253 /*-----------------------------------------------------------------------*/
00254 /* Extract N bits from input stream                                      */
00255 /*-----------------------------------------------------------------------*/
00256 
00257 static
00258 INT bitext (    /* >=0: extracted data, <0: error code */
00259     JDEC* jd,   /* Pointer to the decompressor object */
00260     UINT nbit   /* Number of bits to extract (1 to 11) */
00261 )
00262 {
00263     BYTE msk, s, *dp;
00264     UINT dc, v, f;
00265 
00266 
00267     msk = jd->dmsk;
00268     dc = jd->dctr;
00269     dp = jd->dptr;   /* Bit mask, number of data available, read ptr */
00270     s = *dp;
00271     v = f = 0;
00272     do {
00273         if (!msk) {             /* Next byte? */
00274             if (!dc) {          /* No input data is available, re-fill input buffer */
00275                 dp = jd->inbuf; /* Top of input buffer */
00276                 dc = jd->infunc(jd, dp, JD_SZBUF);
00277                 if (!dc) return 0 - (INT)JDR_INP;   /* Err: read error or wrong stream termination */
00278             } else {
00279                 dp++;           /* Next data ptr */
00280             }
00281             dc--;               /* Decrement number of available bytes */
00282             if (f) {            /* In flag sequence? */
00283                 f = 0;          /* Exit flag sequence */
00284                 if (*dp != 0) return 0 - (INT)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */
00285                 *dp = s = 0xFF;         /* The flag is a data 0xFF */
00286             } else {
00287                 s = *dp;                /* Get next data byte */
00288                 if (s == 0xFF) {        /* Is start of flag sequence? */
00289                     f = 1;
00290                     continue;    /* Enter flag sequence */
00291                 }
00292             }
00293             msk = 0x80;     /* Read from MSB */
00294         }
00295         v <<= 1;    /* Get a bit */
00296         if (s & msk) v++;
00297         msk >>= 1;
00298         nbit--;
00299     } while (nbit);
00300     jd->dmsk = msk;
00301     jd->dctr = dc;
00302     jd->dptr = dp;
00303 
00304     return (INT)v;
00305 }
00306 
00307 
00308 
00309 
00310 /*-----------------------------------------------------------------------*/
00311 /* Extract a huffman decoded data from input stream                      */
00312 /*-----------------------------------------------------------------------*/
00313 
00314 static
00315 INT huffext (           /* >=0: decoded data, <0: error code */
00316     JDEC* jd,           /* Pointer to the decompressor object */
00317     const BYTE* hbits,  /* Pointer to the bit distribution table */
00318     const WORD* hcode,  /* Pointer to the code word table */
00319     const BYTE* hdata   /* Pointer to the data table */
00320 )
00321 {
00322     BYTE msk, s, *dp;
00323     UINT dc, v, f, bl, nd;
00324 
00325 
00326     msk = jd->dmsk;
00327     dc = jd->dctr;
00328     dp = jd->dptr;   /* Bit mask, number of data available, read ptr */
00329     s = *dp;
00330     v = f = 0;
00331     bl = 16;    /* Max code length */
00332     do {
00333         if (!msk) {     /* Next byte? */
00334             if (!dc) {  /* No input data is available, re-fill input buffer */
00335                 dp = jd->inbuf; /* Top of input buffer */
00336                 dc = jd->infunc(jd, dp, JD_SZBUF);
00337                 if (!dc) {printf("huffext KO 1\n");return 0 - (INT)JDR_INP;}   /* Err: read error or wrong stream termination */
00338             } else {
00339                 dp++;   /* Next data ptr */
00340             }
00341             dc--;       /* Decrement number of available bytes */
00342             if (f) {        /* In flag sequence? */
00343                 f = 0;      /* Exit flag sequence */
00344                 if (*dp != 0)
00345                     {printf("huffext KO 2\n");return 0 - (INT)JDR_FMT1;}   /* Err: unexpected flag is detected (may be collapted data) */
00346                 *dp = s = 0xFF;         /* The flag is a data 0xFF */
00347             } else {
00348                 s = *dp;                /* Get next data byte */
00349                 if (s == 0xFF) {        /* Is start of flag sequence? */
00350                     f = 1;
00351                     continue;    /* Enter flag sequence, get trailing byte */
00352                 }
00353             }
00354             msk = 0x80;     /* Read from MSB */
00355         }
00356         v <<= 1;    /* Get a bit */
00357         if (s & msk) v++;
00358         msk >>= 1;
00359 
00360         for (nd = *hbits++; nd; nd--) { /* Search the code word in this bit length */
00361             if (v == *hcode++) {        /* Matched? */
00362                 jd->dmsk = msk;
00363                 jd->dctr = dc;
00364                 jd->dptr = dp;
00365                 //printf("huffext OK\n");
00366                 return *hdata;          /* Return the decoded data */
00367             }
00368             hdata++;
00369         }
00370         bl--;
00371     } while (bl);
00372     printf("huffext KO 3\n");
00373     return 0 - (INT)JDR_FMT1;   /* Err: code not found (may be collapted data) */
00374 }
00375 
00376 
00377 
00378 
00379 /*-----------------------------------------------------------------------*/
00380 /* Apply Inverse-DCT in Arai Algorithm (see also aa_idct.png)            */
00381 /*-----------------------------------------------------------------------*/
00382 
00383 static
00384 void block_idct (
00385     LONG* src,  /* Input block data (de-quantized and pre-scaled for Arai Algorithm) */
00386     BYTE* dst   /* Pointer to the destination to store the block as byte array */
00387 )
00388 {
00389     const LONG M13 = (LONG)(1.41421*4096), M2 = (LONG)(1.08239*4096), M4 = (LONG)(2.61313*4096), M5 = (LONG)(1.84776*4096);
00390     LONG v0, v1, v2, v3, v4, v5, v6, v7;
00391     LONG t10, t11, t12, t13;
00392     UINT i;
00393 
00394     /* Process columns */
00395     for (i = 0; i < 8; i++) {
00396         v0 = src[8 * 0];    /* Get even elements */
00397         v1 = src[8 * 2];
00398         v2 = src[8 * 4];
00399         v3 = src[8 * 6];
00400 
00401         t10 = v0 + v2;      /* Process the even elements */
00402         t12 = v0 - v2;
00403         t11 = (v1 - v3) * M13 >> 12;
00404         v3 += v1;
00405         t11 -= v3;
00406         v0 = t10 + v3;
00407         v3 = t10 - v3;
00408         v1 = t11 + t12;
00409         v2 = t12 - t11;
00410 
00411         v4 = src[8 * 7];    /* Get odd elements */
00412         v5 = src[8 * 1];
00413         v6 = src[8 * 5];
00414         v7 = src[8 * 3];
00415 
00416         t10 = v5 - v4;      /* Process the odd elements */
00417         t11 = v5 + v4;
00418         t12 = v6 - v7;
00419         v7 += v6;
00420         v5 = (t11 - v7) * M13 >> 12;
00421         v7 += t11;
00422         t13 = (t10 + t12) * M5 >> 12;
00423         v4 = t13 - (t10 * M2 >> 12);
00424         v6 = t13 - (t12 * M4 >> 12) - v7;
00425         v5 -= v6;
00426         v4 -= v5;
00427 
00428         src[8 * 0] = v0 + v7;   /* Write-back transformed values */
00429         src[8 * 7] = v0 - v7;
00430         src[8 * 1] = v1 + v6;
00431         src[8 * 6] = v1 - v6;
00432         src[8 * 2] = v2 + v5;
00433         src[8 * 5] = v2 - v5;
00434         src[8 * 3] = v3 + v4;
00435         src[8 * 4] = v3 - v4;
00436 
00437         src++;  /* Next column */
00438     }
00439 
00440     /* Process rows */
00441     src -= 8;
00442     for (i = 0; i < 8; i++) {
00443         v0 = src[0] + (128L << 8);  /* Get even elements (remove DC offset (-128) here) */
00444         v1 = src[2];
00445         v2 = src[4];
00446         v3 = src[6];
00447 
00448         t10 = v0 + v2;              /* Process the even elements */
00449         t12 = v0 - v2;
00450         t11 = (v1 - v3) * M13 >> 12;
00451         v3 += v1;
00452         t11 -= v3;
00453         v0 = t10 + v3;
00454         v3 = t10 - v3;
00455         v1 = t11 + t12;
00456         v2 = t12 - t11;
00457 
00458         v4 = src[7];                /* Get odd elements */
00459         v5 = src[1];
00460         v6 = src[5];
00461         v7 = src[3];
00462 
00463         t10 = v5 - v4;              /* Process the odd elements */
00464         t11 = v5 + v4;
00465         t12 = v6 - v7;
00466         v7 += v6;
00467         v5 = (t11 - v7) * M13 >> 12;
00468         v7 += t11;
00469         t13 = (t10 + t12) * M5 >> 12;
00470         v4 = t13 - (t10 * M2 >> 12);
00471         v6 = t13 - (t12 * M4 >> 12) - v7;
00472         v5 -= v6;
00473         v4 -= v5;
00474 
00475         dst[0] = BYTECLIP((v0 + v7) >> 8);  /* Descale the transformed values 8 bits and output */
00476         dst[7] = BYTECLIP((v0 - v7) >> 8);
00477         dst[1] = BYTECLIP((v1 + v6) >> 8);
00478         dst[6] = BYTECLIP((v1 - v6) >> 8);
00479         dst[2] = BYTECLIP((v2 + v5) >> 8);
00480         dst[5] = BYTECLIP((v2 - v5) >> 8);
00481         dst[3] = BYTECLIP((v3 + v4) >> 8);
00482         dst[4] = BYTECLIP((v3 - v4) >> 8);
00483         dst += 8;
00484 
00485         src += 8;   /* Next row */
00486     }
00487 }
00488 
00489 
00490 
00491 
00492 /*-----------------------------------------------------------------------*/
00493 /* Load all blocks in the MCU into working buffer                        */
00494 /*-----------------------------------------------------------------------*/
00495 
00496 static
00497 JRESULT 
00498 //INT evillive
00499 mcu_load (
00500     JDEC* jd        /* Pointer to the decompressor object */
00501 )
00502 {
00503     LONG *tmp = (LONG*)jd->workbuf; /* Block working buffer for de-quantize and IDCT */
00504     UINT blk, nby, nbc, i, z, id, cmp;
00505     INT b, d, e;
00506     BYTE *bp;
00507     const BYTE *hb, *hd;
00508     const WORD *hc;
00509     const LONG *dqf;
00510 
00511 
00512     nby = jd->msx * jd->msy;    /* Number of Y blocks (1, 2 or 4) */
00513     nbc = 2;                    /* Number of C blocks (2) */
00514     bp = jd->mcubuf;            /* Pointer to the first block */
00515 
00516     for (blk = 0; blk < nby + nbc; blk++) {
00517         cmp = (blk < nby) ? 0 : blk - nby + 1;  /* Component number 0:Y, 1:Cb, 2:Cr */
00518         id = cmp ? 1 : 0;                       /* Huffman table ID of the component */
00519 
00520         /* Extract a DC element from input stream */
00521         hb = jd->huffbits[id][0];               /* Huffman table for the DC element */
00522         hc = jd->huffcode[id][0];
00523         hd = jd->huffdata[id][0];
00524         b = huffext(jd, hb, hc, hd);            /* Extract a huffman coded data (bit length) */
00525         //if (b < 0) return 0 - b;                /* Err: invalid code or input */
00526         if (b < 0) {printf("mcu_load KO 1\n");return (JRESULT)(-b);} // evillive                /* Err: invalid code or input */
00527         d = jd->dcv[cmp];                       /* DC value of previous block */
00528         if (b) {                                /* If there is any difference from previous block */
00529             e = bitext(jd, b);                  /* Extract data bits */
00530             //if (e < 0) return 0 - e;            /* Err: input */
00531             if (e < 0) {printf("mcu_load KO 2\n");return (JRESULT)(-e); }//evillive
00532             b = 1 << (b - 1);                   /* MSB position */
00533             if (!(e & b)) e -= (b << 1) - 1;    /* Restore sign if needed */
00534             d += e;                             /* Get current value */
00535             jd->dcv[cmp] = (SHORT)d;            /* Save current DC value for next block */
00536         }
00537         dqf = jd->qttbl[jd->qtid[cmp]];         /* De-quantizer table ID for this component */
00538         tmp[0] = d * dqf[0] >> 8;               /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */
00539 
00540         /* Extract following 63 AC elements from input stream */
00541         for (i = 1; i < 64; i++) tmp[i] = 0;    /* Clear rest of elements */
00542         hb = jd->huffbits[id][1];               /* Huffman table for the AC elements */
00543         hc = jd->huffcode[id][1];
00544         hd = jd->huffdata[id][1];
00545         i = 1;                  /* Top of the AC elements */
00546         do {
00547             b = huffext(jd, hb, hc, hd);        /* Extract a huffman coded value (zero runs and bit length) */
00548             if (b == 0) break;                  /* EOB? */
00549             //if (b < 0) return 0 - b;            /* Err: invalid code or input error */
00550             if (b < 0) {printf("mcu_load KO 3\n");return (JRESULT)(-b);}//evillive
00551             z = (UINT)b >> 4;                   /* Number of leading zero elements */
00552             if (z) {
00553                 i += z;                         /* Skip zero elements */
00554                 if (i >= 64) {printf("mcu_load KO 4\n");return JDR_FMT1;}   /* Too long zero run */
00555             }
00556             if (b &= 0x0F) {                    /* Bit length */
00557                 d = bitext(jd, b);              /* Extract data bits */
00558                 //if (d < 0) return 0 - d;        /* Err: input device */
00559                 if (d < 0) {printf("mcu_load KO 5\n");return (JRESULT)(-d); }// evillive
00560                 b = 1 << (b - 1);               /* MSB position */
00561                 if (!(d & b)) d -= (b << 1) - 1;/* Restore negative value if needed */
00562                 z = ZIG(i);                     /* Zigzag-order to raster-order converted index */
00563                 tmp[z] = d * dqf[z] >> 8;       /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */
00564             }
00565         } while (++i < 64);     /* Next AC element */
00566 
00567         if (JD_USE_SCALE && jd->scale == 3)
00568             *bp = (*tmp / 256) + 128;   /* If scale ratio is 1/8, IDCT can be ommited and only DC element is used */
00569         else
00570             block_idct(tmp, bp);        /* Apply IDCT and store the block to the MCU buffer */
00571 
00572         bp += 64;               /* Next block */
00573     }
00574 
00575     return JDR_OK;  /* All blocks have been loaded successfully */
00576 }
00577 
00578 
00579 
00580 
00581 /*-----------------------------------------------------------------------*/
00582 /* Output an MCU: Convert YCrCb to RGB and output it in RGB form         */
00583 /*-----------------------------------------------------------------------*/
00584 
00585 static
00586 JRESULT mcu_output (
00587     JDEC* jd,   /* Pointer to the decompressor object */
00588     UINT (*outfunc)(JDEC*, void*, JRECT*),  /* RGB output function */
00589     UINT x,     /* MCU position in the image (left of the MCU) */
00590     UINT y      /* MCU position in the image (top of the MCU) */
00591 )
00592 {
00593     const INT CVACC = (sizeof (INT) > 2) ? 1024 : 128;
00594     UINT ix, iy, mx, my, rx, ry;
00595     INT yy, cb, cr;
00596     BYTE *py, *pc, *rgb24;
00597     JRECT rect;
00598 
00599 
00600     mx = jd->msx * 8;
00601     my = jd->msy * 8;                 /* MCU size (pixel) */
00602     rx = (x + mx <= jd->width) ? mx : jd->width - x;    /* Output rectangular size (it may be clipped at right/bottom end) */
00603     ry = (y + my <= jd->height) ? my : jd->height - y;
00604     if (JD_USE_SCALE) {
00605         rx >>= jd->scale;
00606         ry >>= jd->scale;
00607         if (!rx || !ry) return JDR_OK;                  /* Skip this MCU if all pixel is to be rounded off */
00608         x >>= jd->scale;
00609         y >>= jd->scale;
00610     }
00611     rect.left = x;
00612     rect.right = x + rx - 1;             /* Rectangular area in the frame buffer */
00613     rect.top = y;
00614     rect.bottom = y + ry - 1;
00615 
00616 
00617     if (!JD_USE_SCALE || jd->scale != 3) {  /* Not for 1/8 scaling */
00618 
00619         /* Build an RGB MCU from discrete comopnents */
00620         rgb24 = (BYTE*)jd->workbuf;
00621         for (iy = 0; iy < my; iy++) {
00622             pc = jd->mcubuf;
00623             py = pc + iy * 8;
00624             if (my == 16) {     /* Double block height? */
00625                 pc += 64 * 4 + (iy >> 1) * 8;
00626                 if (iy >= 8) py += 64;
00627             } else {            /* Single block height */
00628                 pc += mx * 8 + iy * 8;
00629             }
00630             for (ix = 0; ix < mx; ix++) {
00631                 cb = pc[0] - 128;   /* Get Cb/Cr component and restore right level */
00632                 cr = pc[64] - 128;
00633                 if (mx == 16) {                 /* Double block width? */
00634                     if (ix == 8) py += 64 - 8;  /* Jump to next block if double block heigt */
00635                     pc += ix & 1;               /* Increase chroma pointer every two pixels */
00636                 } else {                        /* Single block width */
00637                     pc++;                       /* Increase chroma pointer every pixel */
00638                 }
00639                 yy = *py++;         /* Get Y component */
00640 
00641                 /* Convert YCbCr to RGB */
00642                 *rgb24++ = /* R */ BYTECLIP(yy + ((INT)(1.402 * CVACC) * cr) / CVACC);
00643                 *rgb24++ = /* G */ BYTECLIP(yy - ((INT)(0.344 * CVACC) * cb + (INT)(0.714 * CVACC) * cr) / CVACC);
00644                 *rgb24++ = /* B */ BYTECLIP(yy + ((INT)(1.772 * CVACC) * cb) / CVACC);
00645             }
00646         }
00647 
00648         /* Descale the MCU rectangular if needed */
00649         if (JD_USE_SCALE && jd->scale) {
00650             UINT x, y, r, g, b, s, w, a;
00651             BYTE *op;
00652 
00653             /* Get averaged RGB value of each square correcponds to a pixel */
00654             s = jd->scale * 2;  /* Bumber of shifts for averaging */
00655             w = 1 << jd->scale; /* Width of square */
00656             a = (mx - w) * 3;   /* Bytes to skip for next line in the square */
00657             op = (BYTE*)jd->workbuf;
00658             for (iy = 0; iy < my; iy += w) {
00659                 for (ix = 0; ix < mx; ix += w) {
00660                     rgb24 = (BYTE*)jd->workbuf + (iy * mx + ix) * 3;
00661                     r = g = b = 0;
00662                     for (y = 0; y < w; y++) {   /* Accumulate RGB value in the square */
00663                         for (x = 0; x < w; x++) {
00664                             r += *rgb24++;
00665                             g += *rgb24++;
00666                             b += *rgb24++;
00667                         }
00668                         rgb24 += a;
00669                     }                           /* Put the averaged RGB value as a pixel */
00670                     *op++ = (BYTE)(r >> s);
00671                     *op++ = (BYTE)(g >> s);
00672                     *op++ = (BYTE)(b >> s);
00673                 }
00674             }
00675         }
00676 
00677     } else {    /* For only 1/8 scaling (left-top pixel in each block are the DC value of the block) */
00678 
00679         /* Build a 1/8 descaled RGB MCU from discrete comopnents */
00680         rgb24 = (BYTE*)jd->workbuf;
00681         pc = jd->mcubuf + mx * my;
00682         cb = pc[0] - 128;       /* Get Cb/Cr component and restore right level */
00683         cr = pc[64] - 128;
00684         for (iy = 0; iy < my; iy += 8) {
00685             py = jd->mcubuf;
00686             if (iy == 8) py += 64 * 2;
00687             for (ix = 0; ix < mx; ix += 8) {
00688                 yy = *py;   /* Get Y component */
00689                 py += 64;
00690 
00691                 /* Convert YCbCr to RGB */
00692                 *rgb24++ = /* R */ BYTECLIP(yy + ((INT)(1.402 * CVACC) * cr / CVACC));
00693                 *rgb24++ = /* G */ BYTECLIP(yy - ((INT)(0.344 * CVACC) * cb + (INT)(0.714 * CVACC) * cr) / CVACC);
00694                 *rgb24++ = /* B */ BYTECLIP(yy + ((INT)(1.772 * CVACC) * cb / CVACC));
00695             }
00696         }
00697     }
00698 
00699     /* Squeeze up pixel table if a part of MCU is to be truncated */
00700     mx >>= jd->scale;
00701     if (rx < mx) {
00702         BYTE *s, *d;
00703         UINT x, y;
00704 
00705         s = d = (BYTE*)jd->workbuf;
00706         for (y = 0; y < ry; y++) {
00707             for (x = 0; x < rx; x++) {  /* Copy effective pixels */
00708                 *d++ = *s++;
00709                 *d++ = *s++;
00710                 *d++ = *s++;
00711             }
00712             s += (mx - rx) * 3; /* Skip truncated pixels */
00713         }
00714     }
00715 
00716     /* Convert RGB888 to RGB565 if needed */
00717     if (JD_FORMAT == 1) {
00718         BYTE *s = (BYTE*)jd->workbuf;
00719         WORD w, *d = (WORD*)s;
00720         UINT n = rx * ry;
00721 
00722         do {
00723             w = (*s++ & 0xF8) << 8;     /* RRRRR----------- */
00724             w |= (*s++ & 0xFC) << 3;    /* -----GGGGGG----- */
00725             w |= *s++ >> 3;             /* -----------BBBBB */
00726             *d++ = w;
00727         } while (--n);
00728     }
00729 
00730     /* Output the RGB rectangular */
00731     return outfunc(jd, jd->workbuf, &rect) ? JDR_OK : JDR_INTR;
00732 }
00733 
00734 
00735 
00736 
00737 /*-----------------------------------------------------------------------*/
00738 /* Process restart interval                                              */
00739 /*-----------------------------------------------------------------------*/
00740 
00741 static
00742 JRESULT restart (
00743     JDEC* jd,   /* Pointer to the decompressor object */
00744     WORD rstn   /* Expected restert sequense number */
00745 )
00746 {
00747     UINT i, dc;
00748     WORD d;
00749     BYTE *dp;
00750 
00751 
00752     /* Discard padding bits and get two bytes from the input stream */
00753     dp = jd->dptr;
00754     dc = jd->dctr;
00755     d = 0;
00756     for (i = 0; i < 2; i++) {
00757         if (!dc) {  /* No input data is available, re-fill input buffer */
00758             dp = jd->inbuf;
00759             dc = jd->infunc(jd, dp, JD_SZBUF);
00760             if (!dc) return JDR_INP;
00761         } else {
00762             dp++;
00763         }
00764         dc--;
00765         d = (d << 8) | *dp; /* Get a byte */
00766     }
00767     jd->dptr = dp;
00768     jd->dctr = dc;
00769     jd->dmsk = 0;
00770 
00771     /* Check the marker */
00772     if ((d & 0xFFD8) != 0xFFD0 || (d & 7) != (rstn & 7))
00773         return JDR_FMT1;    /* Err: expected RSTn marker is not detected (may be collapted data) */
00774 
00775     /* Reset DC offset */
00776     jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0;
00777 
00778     return JDR_OK;
00779 }
00780 
00781 
00782 
00783 
00784 /*-----------------------------------------------------------------------*/
00785 /* Analyze the JPEG image and Initialize decompressor object             */
00786 /*-----------------------------------------------------------------------*/
00787 
00788 #define LDB_WORD(ptr)       (WORD)(((WORD)*((BYTE*)(ptr))<<8)|(WORD)*(BYTE*)((ptr)+1))
00789 
00790 
00791 JRESULT
00792 //INT
00793  jd_prepare (
00794     JDEC* jd,           /* Blank decompressor object */
00795     UINT (*infunc)(JDEC*, BYTE*, UINT), /* JPEG strem input function */
00796     void* pool,         /* Working buffer for the decompression session */
00797     UINT sz_pool,       /* Size of working buffer */
00798     void* dev           /* I/O device identifier for the session */
00799 )
00800 {
00801     BYTE *seg, b;
00802     WORD marker;
00803     DWORD ofs;
00804     UINT n, i, j, len;
00805     JRESULT rc;
00806 
00807 
00808     if (!pool) return JDR_PAR;
00809 
00810     jd->pool = pool;        /* Work memroy */
00811     jd->sz_pool = sz_pool;  /* Size of given work memory */
00812     jd->infunc = infunc;    /* Stream input function */
00813     jd->device = dev;       /* I/O device identifier */
00814     jd->nrst = 0;           /* No restart interval (default) */
00815 
00816     for (i = 0; i < 2; i++) {   /* Nulls pointers */
00817         for (j = 0; j < 2; j++) {
00818             jd->huffbits[i][j] = 0;
00819             jd->huffcode[i][j] = 0;
00820             jd->huffdata[i][j] = 0;
00821         }
00822     }
00823     for (i = 0; i < 4; i++) jd->qttbl[i] = 0;
00824 
00825     jd->inbuf = seg = (BYTE*)alloc_pool(jd, JD_SZBUF);     /* Allocate stream input buffer */
00826     if (!seg) return JDR_MEM1;
00827 
00828     if (jd->infunc(jd, seg, 2) != 2) return JDR_INP;/* Check SOI marker */
00829     if (LDB_WORD(seg) != 0xFFD8) return JDR_FMT1;   /* Err: SOI is not detected */
00830     ofs = 2;
00831 
00832     for (;;) {
00833         /* Get a JPEG marker */
00834         if (jd->infunc(jd, seg, 4) != 4) return JDR_INP;
00835         marker = LDB_WORD(seg);     /* Marker */
00836         len = LDB_WORD(seg + 2);    /* Length field */
00837         if (len <= 2 || (marker >> 8) != 0xFF) return JDR_FMT1;
00838         len -= 2;       /* Content size excluding length field */
00839         ofs += 4 + len; /* Number of bytes loaded */
00840 
00841         switch (marker & 0xFF) {
00842             case 0xC0:  /* SOF0 (baseline JPEG) */
00843                 /* Load segment data */
00844                 if (len > JD_SZBUF) return JDR_MEM2;
00845                 if (jd->infunc(jd, seg, len) != len) return JDR_INP;
00846 
00847                 jd->width = LDB_WORD(seg+3);        /* Image width in unit of pixel */
00848                 jd->height = LDB_WORD(seg+1);       /* Image height in unit of pixel */
00849                 if (seg[5] != 3) return JDR_FMT3;   /* Err: Supports only Y/Cb/Cr format */
00850 
00851                 /* Check three image components */
00852                 for (i = 0; i < 3; i++) {
00853                     b = seg[7 + 3 * i];                         /* Get sampling factor */
00854                     if (!i) {   /* Y component */
00855                         if (b != 0x11 && b != 0x22 && b != 0x21)/* Check sampling factor */
00856                             return JDR_FMT3;                    /* Err: Supports only 4:4:4, 4:2:0 or 4:2:2 */
00857                         jd->msx = b >> 4;
00858                         jd->msy = b & 15;     /* Size of MCU [blocks] */
00859                     } else {    /* Cb/Cr component */
00860                         if (b != 0x11) return JDR_FMT3;         /* Err: Sampling factor of Cr/Cb must be 1 */
00861                     }
00862                     b = seg[8 + 3 * i];                         /* Get dequantizer table ID for this component */
00863                     if (b > 3) return JDR_FMT3;                 /* Err: Invalid ID */
00864                     jd->qtid[i] = b;
00865                 }
00866                 break;
00867 
00868             case 0xDD:  /* DRI */
00869                 /* Load segment data */
00870                 if (len > JD_SZBUF) return JDR_MEM2;
00871                 if (jd->infunc(jd, seg, len) != len) return JDR_INP;
00872 
00873                 /* Get restart interval (MCUs) */
00874                 jd->nrst = LDB_WORD(seg);
00875                 break;
00876 
00877             case 0xC4:  /* DHT */
00878                 /* Load segment data */
00879                 if (len > JD_SZBUF) return JDR_MEM2;
00880                 if (jd->infunc(jd, seg, len) != len) return JDR_INP;
00881 
00882                 /* Create huffman tables */
00883                 rc = create_huffman_tbl(jd, seg, len);
00884                 if (rc) return rc;
00885                 break;
00886 
00887             case 0xDB:  /* DQT */
00888                 /* Load segment data */
00889                 if (len > JD_SZBUF) return JDR_MEM2;
00890                 if (jd->infunc(jd, seg, len) != len) return JDR_INP;
00891 
00892                 /* Create de-quantizer tables */
00893                 rc = create_qt_tbl(jd, seg, len);
00894                 if (rc) return rc;
00895                 break;
00896 
00897             case 0xDA:  /* SOS */
00898                 /* Load segment data */
00899                 if (len > JD_SZBUF) return JDR_MEM2;
00900                 if (jd->infunc(jd, seg, len) != len) return JDR_INP;
00901 
00902                 if (!jd->width || !jd->height) return JDR_FMT1; /* Err: Invalid image size */
00903 
00904                 if (seg[0] != 3) return JDR_FMT3;               /* Err: Supports only three color components format */
00905 
00906                 /* Check if all tables corresponding to each components have been loaded */
00907                 for (i = 0; i < 3; i++) {
00908                     b = seg[2 + 2 * i]; /* Get huffman table ID */
00909                     if (b != 0x00 && b != 0x11) return JDR_FMT3;    /* Err: Different table number for DC/AC element */
00910                     b = i ? 1 : 0;
00911                     if (!jd->huffbits[b][0] || !jd->huffbits[b][1]) /* Check huffman table for this component */
00912                         return JDR_FMT1;                            /* Err: Huffman table not loaded */
00913                     if (!jd->qttbl[jd->qtid[i]]) return JDR_FMT1;   /* Err: Dequantizer table not loaded */
00914                 }
00915 
00916                 /* Allocate working buffer for MCU and RGB */
00917                 n = jd->msy * jd->msx;                      /* Number of Y blocks in the MCU */
00918                 if (!n) return JDR_FMT1;                    /* Err: SOF0 has not been loaded */
00919                 len = n * 64 * 2 + 64;                      /* Allocate buffer for IDCT and RGB output */
00920                 if (len < 256) len = 256;                   /* but at least 256 byte is required for IDCT */
00921                 jd->workbuf = alloc_pool(jd, len);          /* and it may occupy a part of following MCU working buffer for RGB output */
00922                 if (!jd->workbuf) return JDR_MEM1;          /* Err: not enough memory */
00923                 jd->mcubuf = (BYTE*)alloc_pool(jd, (n + 2) * 64);  /* Allocate MCU working buffer */
00924                 if (!jd->mcubuf) return JDR_MEM1;           /* Err: not enough memory */
00925 
00926                 /* Pre-load the JPEG data to extract it from the bit stream */
00927                 jd->dptr = seg;
00928                 jd->dctr = 0;
00929                 jd->dmsk = 0; /* Prepare to read bit stream */
00930                 if (ofs %= JD_SZBUF) {                      /* Align read offset to JD_SZBUF */
00931                     jd->dctr = jd->infunc(jd, seg + ofs, JD_SZBUF - (UINT)ofs);
00932                     jd->dptr = seg + ofs - 1;
00933                 }
00934 
00935                 return JDR_OK;      /* Initialization succeeded. Ready to decompress the JPEG image. */
00936 
00937             case 0xC1:  /* SOF1 */
00938             case 0xC2:  /* SOF2 */
00939             case 0xC3:  /* SOF3 */
00940             case 0xC5:  /* SOF5 */
00941             case 0xC6:  /* SOF6 */
00942             case 0xC7:  /* SOF7 */
00943             case 0xC9:  /* SOF9 */
00944             case 0xCA:  /* SOF10 */
00945             case 0xCB:  /* SOF11 */
00946             case 0xCD:  /* SOF13 */
00947             case 0xCE:  /* SOF14 */
00948             case 0xCF:  /* SOF15 */
00949             case 0xD9:  /* EOI */
00950                 return JDR_FMT3;    /* Unsuppoted JPEG standard (may be progressive JPEG) */
00951 
00952             default:    /* Unknown segment (comment, exif or etc..) */
00953                 /* Skip segment data */
00954                 if (jd->infunc(jd, 0, len) != len)  /* Null pointer specifies to skip bytes of stream */
00955                     return JDR_INP;
00956         }
00957     }
00958 }
00959 
00960 
00961 
00962 
00963 /*-----------------------------------------------------------------------*/
00964 /* Start to decompress the JPEG picture                                  */
00965 /*-----------------------------------------------------------------------*/
00966 
00967 JRESULT jd_decomp (
00968     JDEC* jd,                               /* Initialized decompression object */
00969     UINT (*outfunc)(JDEC*, void*, JRECT*),  /* RGB output function */
00970     BYTE scale                              /* Output de-scaling factor (0 to 3) */
00971 )
00972 {
00973     UINT x, y, mx, my;
00974     WORD rst, rsc;
00975     JRESULT rc;
00976 
00977 
00978     if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR;
00979     jd->scale = scale;
00980 
00981     mx = jd->msx * 8;
00982     my = jd->msy * 8;         /* Size of the MCU (pixel) */
00983 
00984     jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0;   /* Initialize DC values */
00985     rst = rsc = 0;
00986 
00987     rc = JDR_OK;
00988     for (y = 0; y < jd->height; y += my) {      /* Vertical loop of MCUs */
00989         for (x = 0; x < jd->width; x += mx) {   /* Horizontal loop of MCUs */
00990             if (jd->nrst && rst++ == jd->nrst) {    /* Process restart interval if enabled */
00991                 rc = restart(jd, rsc++);
00992                 if (rc != JDR_OK) {printf("jd_decomp KO 1\n");return rc;}
00993                 rst = 1;
00994             }
00995             rc = mcu_load(jd);                  /* Load an MCU (decompress huffman coded stream and apply IDCT) */
00996             if (rc != JDR_OK) {printf("jd_decomp KO 2\n");return rc;}
00997             rc = mcu_output(jd, outfunc, x, y); /* Output the MCU (color space conversion, scaling and output) */
00998             if (rc != JDR_OK) {printf("jd_decomp KO 3\n");return rc;}
00999         }
01000     }
01001 
01002     return rc;
01003 }
01004 
01005 
01006