#include
#include
typedef unsigned long U32;
typedef unsigned short U16;
typedef unsigned char U8;
typedef signed short S16;
typedef signed long S32;
typedef struct
{
U16 x;
U16 y;
}
PegPoint;
typedef struct
{
U8 uFlags; // combination of flags above
U8 uBitsPix; // 1, 2, 4, or 8
U16 wWidth; // in pixels
U16 wHeight; // in pixels
U16 dTransColor; // transparent color for > 8bpp bitmaps
U8 *pStart; // bitmap data pointer
U32 uBmpSize;
}PegBitmap;
void
DEBUG_Message (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
printf (fmt, ap);
va_end (ap);
printf ("\n");
}
#define DISPLAY_HEIGHT 220
#define DISPLAY_WIDTH 176
#define MAX_MALLOC_LEN 0xF0000
U16 display[DISPLAY_HEIGHT][DISPLAY_WIDTH];
/*
JPEG ENCODE OUT FORMAT
BMP_RGB24,//save as 24bits bitmap file
DAT_RGB16//save as 16bits pixel
*/
#define M_SOF0 0xC0 /* Start Of Frame N */
#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */
#define M_DHT 0xC4
#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) */
#define M_EOI 0xD9 /* End Of Image (end of datastream) */
#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */
#define M_DQT 0xDB
#define M_DRI 0xDD
#define M_APP0 0xE0 /* Application-specific marker, type N */
#define M_APP12 0xEC /* (we don't bother to list all 16 APPn's) */
#define M_APP14 0xEE
#define M_COM 0xFE /* COMment */
#ifndef PEG_RGB16
#undef COLORBITS
#define COLORBITS (24)
#define widthbytes(i) ((i + 31) / 32 * 4)
//extern U8 display[DISPLAY_HEIGHT * widthbytes (COLORBITS * DISPLAY_WIDTH) + 0x36];
#endif
typedef enum
{
DECODE_ERROR_FROMAT = -1, //Error decode file format!
DECODE_ERROR_SUPPORT = -2, //No surpport decode file format !
DECODE_ERROR_MAX
}
T_DECODE_ERROR_ID;
typedef struct tagJPEGDECODE
{
//U8 compressindex[3];
U8 YDCindex;
U8 YACindex;
U8 UVDCindex;
U8 UVACindex;
U8 HufTabindex;
S16 sampleYH;
S16 sampleYV;
S16 sampleUH;
S16 sampleUV;
S16 sampleVH;
S16 sampleVV;
S16 HYtoU;
S16 VYtoU;
S16 HYtoV;
S16 VYtoV;
S16 YinMCU;
S16 UinMCU;
S16 VinMCU;
S16 compressnum;
S16 *YQt;
S16 *UQt;
S16 *VQt;
S16 bitpos;
S16 curbyte;
S16 run;
S16 value;
S16 ycoef;
S16 ucoef;
S16 vcoef;
S16 intervalflag;
S16 interval;
S16 restart;
S16 Qt[3][64];
S16 codepos[4][16];
S16 codelen[4][16];
S16 MCUbuffer[10 * 64];
S16 blockbuffer[64];
U16 codevalue[4][256];
U16 hufmax[4][16];
U16 hufmin[4][16];
S32 Y[4 * 64];
S32 U[4 * 64];
S32 V[4 * 64];
S32 QtZMCUbuffer[10 * 64];
//U32 linebytes;
U32 imgwidth;
U32 imgheight;
U32 width;
U32 height;
U32 LiHeight; //limit image output height
U32 LiWidth; //limit image output width
U16 OffsetHeight;
U16 OffsetWidth;
U32 lSrc;
U8 *pSrc; //the source jpeg encoded buffer
U32 lDst;
U8 *pDst; //the destination rgb16 or rgb24 buffer
}
JPEGDECODE;
static JPEGDECODE *jpg;
const U8 JPEGAnd[9] = { 0x00, 0x01, 0x03, 0x07, 0xf, 0x1f, 0x3f, 0x7f, 0xff };
const S16 JPEGZ[8][8] = {
{0, 1, 5, 6, 14, 15, 27, 28},
{2, 4, 7, 13, 16, 26, 29, 42},
{3, 8, 12, 17, 25, 30, 41, 43},
{9, 11, 18, 24, 31, 40, 44, 53},
{10, 19, 23, 32, 39, 45, 52, 54},
{20, 22, 33, 38, 46, 51, 55, 60},
{21, 34, 37, 47, 50, 56, 59, 61},
{35, 36, 48, 49, 57, 58, 62, 63}
};
S32
JE_Initialize (U8 * buff, U32 len)
{
U8 *p, *q, hfindex, qtindex, number;
S16 i, j, k, finish = 0, huftab1, huftab2, huftabindex, count;
U16 length;
U8 flag;
U8 compressindex[3];
DEBUG_Message ("........initialize........");
jpg->pSrc = (U8 *) buff;
jpg->lSrc = len;
if (!(*jpg->pSrc == 0xFF) && (*(jpg->pSrc + 1) == M_SOI))
{
DEBUG_Message ("1. Error Jpg File format!");
return DECODE_ERROR_FROMAT;
}
#if 1
if (!(*(jpg->pSrc + jpg->lSrc - 2) == 0xFF)
&& (*(jpg->pSrc + jpg->lSrc - 1) == M_EOI))
{
DEBUG_Message ("1. Error Jpg File format!");
return DECODE_ERROR_FROMAT;
}
#endif
jpg->pSrc += 2;
while (!finish)
{
if (0xFF != (*jpg->pSrc))
{
return DECODE_ERROR_FROMAT;
}
flag = *(jpg->pSrc + 1);
length = (((U16) (*(jpg->pSrc + 2))) <<>pSrc + 3)) - 2;
jpg->pSrc += 4;
switch (flag)
{
case M_COM:
jpg->pSrc += length + 2;
break;
case M_APP0:
case M_APP14:
case M_APP12:
jpg->pSrc += length;
break;
case M_DQT:
p = jpg->pSrc;
qtindex = (*p) & 0x0f;
q = p + 1;
if (length + 2 < 80)
for (i = 0; i < 64; i++)
jpg->Qt[qtindex][i] = (S16) (0x00ff & (*(q++)));
else
{
for (i = 0; i < 64; i++)
jpg->Qt[qtindex][i] = (S16) (0x00ff & (*(q++)));
qtindex = *(q++) & 0x0f;
for (i = 0; i < 64; i++)
jpg->Qt[qtindex][i] = (S16)(0x00ff & (*(q++)));
}
p = NULL;
jpg->pSrc += length;
break;
case M_SOF2:
{
DEBUG_Message ("No surpport Jpg File format!");
return DECODE_ERROR_SUPPORT;
}
case M_SOF0:
p = jpg->pSrc;
jpg->imgheight = (((U32) (*(p + 1))) << 8) + (*(p + 2));
jpg->imgwidth = (((U32) (*(p + 3))) << 8) + (*(p + 4));
jpg->compressnum = (*(p + 5)) & 0x00ff;
if ((1 != jpg->compressnum) && (3 != jpg->compressnum))
{
DEBUG_Message ("2. Error Jpg File format!");
return DECODE_ERROR_FROMAT;
}
if (3 == jpg->compressnum)
{
compressindex[0] = *(p + 6);
jpg->sampleYH = (*(p + 7)) >> 4;
jpg->sampleYV = (*(p + 7)) & 0x0f;
jpg->YQt = (S16 *) jpg->Qt[*(p + 8)];
compressindex[1] = *(p + 9);
jpg->sampleUH = (*(p + 10)) >> 4;
jpg->sampleUV = (*(p + 10)) & 0x0f;
jpg->UQt = (S16 *) jpg->Qt[*(p + 11)];
compressindex[2] = *(p + 12);
jpg->sampleVH = (*(p + 13)) >> 4;
jpg->sampleVV = (*(p + 13)) & 0x0f;
jpg->VQt = (S16 *) jpg->Qt[*(p + 14)];
}
else
{
compressindex[0] = *(p + 6);
jpg->sampleYH = (*(p + 7)) >> 4;
jpg->sampleYV = (*(p + 7)) & 0x0f;
jpg->YQt = (S16 *) jpg->Qt[*(p + 8)];
compressindex[1] = *(p + 6);
jpg->sampleUH = 1;
jpg->sampleUV = 1;
jpg->UQt = (S16 *) jpg->Qt[*(p + 8)];
compressindex[2] = *(p + 6);
jpg->sampleVH = 1;
jpg->sampleVV = 1;
jpg->VQt = (S16 *) jpg->Qt[*(p + 8)];
}
p = NULL;
jpg->pSrc += length;
break;
case M_DHT:
p = jpg->pSrc;
hfindex = *p;
while (0xff != hfindex)
{
huftab1 = (S16) hfindex >> 4;
huftab2 = (S16) hfindex & 0x0f;
huftabindex = huftab1 * 2 + huftab2;
q = p + 1;
count = 0;
for (i = 0; i < 16; i++)
{
jpg->codelen[huftabindex][i] = (S16) (0x00ff & (*(q++)));
count += jpg->codelen[huftabindex][i];
}
count += 17;
j = 0;
for (i = 0; i < 16; i++)
if (jpg->codelen[huftabindex][i] != 0)
{
k = 0;
while (k <>codelen[huftabindex][i])
{
jpg->codevalue[huftabindex][k + j] = (S16) (*(q++));
k++;
}
j += k;
}
i = 0;
while (jpg->codelen[huftabindex][i] == 0)
i++;
for (j = 0; j < i; j++)
{
jpg->hufmin[huftabindex][j] = 0;
jpg->hufmax[huftabindex][j] = 0;
}
jpg->hufmin[huftabindex][i] = 0;
jpg->hufmax[huftabindex][i] = jpg->codelen[huftabindex][i] - 1;
for (j = i + 1; j < 16; j++)
{
jpg->hufmin[huftabindex][j] =
(jpg->hufmax[huftabindex][j - 1] + 1) << 1;
jpg->hufmax[huftabindex][j] =
jpg->hufmin[huftabindex][j] +
jpg->codelen[huftabindex][j] - 1;
}
jpg->codepos[huftabindex][0] = 0;
for (j = 1; j < 16; j++)
jpg->codepos[huftabindex][j] =
jpg->codelen[huftabindex][j - 1] +
jpg->codepos[huftabindex][j - 1];
p += count;
hfindex = *p;
}
p -= length;
p = NULL;
jpg->pSrc += length;
break;
case M_DRI:
p = jpg->pSrc;
jpg->restart = ((*p) << 8) | (*(p + 1));
p = NULL;
jpg->pSrc += length;
break;
case M_SOS:
p = jpg->pSrc;
number = *p;
if (number != (U8) jpg->compressnum)
{
DEBUG_Message ("3. Error Jpg File format!");
return DECODE_ERROR_FROMAT;
}
q = p + 1;
for (i = 0; i <>compressnum; i++)
{
if (*q == compressindex[0])
{
jpg->YDCindex = (*(q + 1)) >> 4;
jpg->YACindex = ((*(q + 1)) & 0x0f) + 2;
}
else
{
jpg->UVDCindex = (*(q + 1)) >> 4;
jpg->UVACindex = ((*(q + 1)) & 0x0f) + 2;
}
q += 2;
}
finish = 1;
p = NULL;
jpg->pSrc += length;
break;
case M_EOI:
{
DEBUG_Message ("4. Error Jpg File format!");
return DECODE_ERROR_FROMAT;
}
//break;
default:
if ((flag & 0xF0) != 0xD0)
jpg->pSrc += length;
break;
}
}
jpg->LiWidth =
jpg->imgwidth <>imgwidth : DISPLAY_WIDTH;
jpg->LiHeight =
jpg->imgheight <>imgheight : DISPLAY_HEIGHT;
#ifdef BMP_RGB24
//jpg->linebytes = widthbytes (COLORBITS * imgwidth);
jpg->lDst =
(U32) DISPLAY_HEIGHT *widthbytes (COLORBITS * DISPLAY_WIDTH) + 0x36;
#else
jpg->lDst = DISPLAY_HEIGHT * DISPLAY_WIDTH * 2;
#endif
return (U32) jpg->lDst;
}
void
JPEGSavebmp (void)
{
S16 i, j;
U8 r, g, b;
S32 y, u, v, rr, gg, bb;
#ifdef BMP_RGB24
U8 *rgb = NULL;
#else
U16 *rgb = NULL;
#endif
U32 lheight; //offset height
U32 lwidth; //offset width
for (i = 0; i <>sampleYV * 8; i++)
{
lheight = jpg->height + i + jpg->OffsetHeight;
lwidth = jpg->width + jpg->OffsetWidth;
if (lheight <>LiHeight)
{
#ifdef BMP_RGB24
#if 1
rgb =
jpg->pDst + (DISPLAY_HEIGHT - lheight -
1) * widthbytes (COLORBITS * DISPLAY_WIDTH) +
3 * lwidth + 0x36;
#else //FLIPVERTICAL
rgb =
jpg->pDst + jpg->lDst -
((DISPLAY_HEIGHT -
lheight) * widthbytes (COLORBITS * DISPLAY_WIDTH)) + 3 * lwidth;
#endif
#else
rgb = (U16 *) (jpg->pDst +
(U32) (jpg->lDst - (DISPLAY_HEIGHT - lheight - 1) *2* DISPLAY_WIDTH +
((lwidth)*2)));
#endif
#ifdef BMP_RGB24
for (j = 0; j <>sampleYH * 8; j++)
#else
for (j = 0; j <>sampleYH * 8; j++,rgb++)
#endif
{
if ((lwidth + j) <>LiWidth)
{
y = jpg->Y[(i <<>sampleYH + j];
u = jpg->U[(i / jpg->VYtoU) * 8 * jpg->sampleYH + j / jpg->HYtoU];
v = jpg->V[(i / jpg->VYtoV) * 8 * jpg->sampleYH + j / jpg->HYtoV];
rr = (((y + 20) <<>> 8;
gg = (((y + 20) <<>> 8;
bb = (((y + 20) <<>> 8;
r = (U8) rr;
g = (U8) gg;
b = (U8) bb;
if (rr & 0xffffff00)
{
if (rr > 255)
r = 255;
else if (rr < 0)
r = 0;
}
if (gg & 0xffffff00)
{
if (gg > 255)
g = 255;
else if (gg < 0)
g = 0;
}
if (bb & 0xffffff00)
{
if (bb > 255)
b = 255;
else if (bb < 0)
b = 0;
}
#ifdef BMP_RGB24
*rgb++ = b;
*rgb++ = g;
*rgb++ = r;
#else
*rgb =(U16) ((r >> 3) <<>> 2) <<>> 3);
#endif
}
else
break;
}
}
else
break;
}
//view peg picture//yacht:20030822
}
U8
JPEGReadbyte (void)
{
U8 c;
c = (*jpg->pSrc) & 0xff;
jpg->pSrc++;
if (c == 0xff)
jpg->pSrc++;
jpg->bitpos = 8;
jpg->curbyte = c;
return c;
}
S16
JPEGDecodeElement (void)
{
S16 codelength;
S32 thiscode, tempcode;
U16 temp, new;
U8 hufbyte, runsize, tempsize, sign;
U8 newbyte, lastbyte;
if (jpg->bitpos >= 1)
{
jpg->bitpos--;
thiscode = (U8) jpg->curbyte >> jpg->bitpos;
jpg->curbyte = jpg->curbyte & JPEGAnd[jpg->bitpos];
}
else
{
lastbyte = JPEGReadbyte ();
jpg->bitpos--;
newbyte = jpg->curbyte & JPEGAnd[jpg->bitpos];
thiscode = lastbyte >> 7;
jpg->curbyte = newbyte;
}
codelength = 1;
while ((thiscode <>hufmin[jpg->HufTabindex][codelength - 1])
|| (jpg->codelen[jpg->HufTabindex][codelength - 1] == 0)
|| (thiscode > jpg->hufmax[jpg->HufTabindex][codelength - 1]))
{
if (jpg->bitpos >= 1)
{
jpg->bitpos--;
tempcode = (U8) jpg->curbyte >> jpg->bitpos;
jpg->curbyte = jpg->curbyte & JPEGAnd[jpg->bitpos];
}
else
{
lastbyte = JPEGReadbyte ();
jpg->bitpos--;
newbyte = jpg->curbyte & JPEGAnd[jpg->bitpos];
tempcode = (U8) lastbyte >> 7;
jpg->curbyte = newbyte;
}
thiscode = (thiscode << 1) + tempcode;
codelength++;
if (codelength > 16)
{
DEBUG_Message ("5. Error Jpg File format!");
return 0;
}
}
temp =
(U16) (thiscode - jpg->hufmin[jpg->HufTabindex][codelength - 1] +
jpg->codepos[jpg->HufTabindex][codelength - 1]);
hufbyte = (U8) jpg->codevalue[jpg->HufTabindex][temp];
jpg->run = (S16) (hufbyte >> 4);
runsize = hufbyte & 0x0f;
if (runsize == 0)
{
jpg->value = 0;
return 1;
}
tempsize = runsize;
if (jpg->bitpos >= runsize)
{
jpg->bitpos -= runsize;
new = (U8) jpg->curbyte >> jpg->bitpos;
jpg->curbyte = jpg->curbyte & JPEGAnd[jpg->bitpos];
}
else
{
new = jpg->curbyte;
tempsize -= jpg->bitpos;
while (tempsize > 8)
{
lastbyte = JPEGReadbyte ();
new = (new << 8) + (U8) lastbyte;
tempsize -= 8;
}
lastbyte = JPEGReadbyte ();
jpg->bitpos -= tempsize;
new = (new <<>> jpg->bitpos);
jpg->curbyte = lastbyte & JPEGAnd[jpg->bitpos];
}
sign = new >> (runsize - 1);
if (sign)
jpg->value = new;
else
{
new = new ^ 0xffff;
temp = 0xffff << runsize;
jpg->value = -(S16) (new ^ temp);
}
return 1;
}
S16
JPEGHufBlock (U8 dchufindex, U8 achufindex)
{
S16 i, count = 0;
jpg->HufTabindex = dchufindex;
if (JPEGDecodeElement () != 1)
return 0;
jpg->blockbuffer[count++] = jpg->value;
jpg->HufTabindex = achufindex;
while (count < 64)
{
if (JPEGDecodeElement () != 1)
return 0;
if ((jpg->run == 0) && (jpg->value == 0))
{
for (i = count; i < 64; i++)
jpg->blockbuffer[i] = 0;
count = 64;
}
else
{
for (i = 0; i <>run; i++)
jpg->blockbuffer[count++] = 0;
jpg->blockbuffer[count++] = jpg->value;
}
}
return 1;
}
S16
JPEGDecodeMCUBlock (void)
{
S16 i, j, *pMCUBuffer;
if (jpg->intervalflag)
{
jpg->pSrc += 2;
jpg->ycoef = jpg->ucoef = jpg->vcoef = 0;
jpg->bitpos = 0;
jpg->curbyte = 0;
}
switch (jpg->compressnum)
{
case 3:
pMCUBuffer = jpg->MCUbuffer;
for (i = 0; i <>sampleYH * jpg->sampleYV; i++)
{
if (JPEGHufBlock (jpg->YDCindex, jpg->YACindex) != 1)
return 0;
jpg->blockbuffer[0] = jpg->blockbuffer[0] + jpg->ycoef;
jpg->ycoef = jpg->blockbuffer[0];
for (j = 0; j < 64; j++)
*pMCUBuffer++ = jpg->blockbuffer[j];
}
for (i = 0; i <>sampleUH * jpg->sampleUV; i++)
{
if (JPEGHufBlock (jpg->UVDCindex, jpg->UVACindex) != 1)
return 0;
jpg->blockbuffer[0] = jpg->blockbuffer[0] + jpg->ucoef;
jpg->ucoef = jpg->blockbuffer[0];
for (j = 0; j < 64; j++)
*pMCUBuffer++ = jpg->blockbuffer[j];
}
for (i = 0; i <>sampleVH * jpg->sampleVV; i++)
{
if (JPEGHufBlock (jpg->UVDCindex, jpg->UVACindex) != 1)
return 0;
jpg->blockbuffer[0] = jpg->blockbuffer[0] + jpg->vcoef;
jpg->vcoef = jpg->blockbuffer[0];
for (j = 0; j < 64; j++)
*pMCUBuffer++ = jpg->blockbuffer[j];
}
break;
case 1:
pMCUBuffer = jpg->MCUbuffer;
if (JPEGHufBlock (jpg->YDCindex, jpg->YACindex) != 1)
return 0;
jpg->blockbuffer[0] = jpg->blockbuffer[0] + jpg->ycoef;
jpg->ycoef = jpg->blockbuffer[0];
for (j = 0; j < 64; j++)
*pMCUBuffer++ = jpg->blockbuffer[j];
for (i = 0; i < 128; i++)
*pMCUBuffer++ = 0;
break;
default:
{
DEBUG_Message ("6. Error Jpg File format!");
return 0;
}
}
return (1);
}
void
JPEGIDCT (S32 * p, S16 * k)
{
register long x;
register long x0;
register long x1;
register long x2;
register long x3;
register long x4;
register long x5;
register long x6;
register long x7;
x1 = p[*(k + 4)] << 11;
x2 = p[*(k + 6)];
x3 = p[*(k + 2)];
x4 = p[*(k + 1)];
x5 = p[*(k + 7)];
x6 = p[*(k + 5)];
x7 = p[*(k + 3)];
x0 = (p[*(k + 0)] << 11) + 1024;
x = 565 * (x4 + x5);
x4 = x + 2276 * x4;
x5 = x - 3406 * x5;
x = 2408 * (x6 + x7);
x6 = x - 799 * x6;
x7 = x - 4017 * x7;
x = 1108 * (x3 + x2);
x2 = x - 3784 * x2;
x3 = x + 1568 * x3;
x = x6;
x6 = x5 + x7;
x5 -= x7;
x7 = x0 + x1;
x0 -= x1;
x1 = x + x4;
x4 -= x;
x = x5;
x5 = x7 - x3;
x7 += x3;
x3 = x0 + x2;
x0 -= x2;
x2 = (181 * (x4 + x) + 128) >> 8;
x4 = (181 * (x4 - x) + 128) >> 8;
p[*(k + 0)] = (x7 + x1) >> 11;
p[*(k + 1)] = (x3 + x2) >> 11;
p[*(k + 2)] = (x0 + x4) >> 11;
p[*(k + 3)] = (x5 + x6) >> 11;
p[*(k + 4)] = (x5 - x6) >> 11;
p[*(k + 5)] = (x0 - x4) >> 11;
p[*(k + 6)] = (x3 - x2) >> 11;
p[*(k + 7)] = (x7 - x1) >> 11;
}
void
JPEGIDCTint (S32 * metrix)
{
short i;
short k[2][8]={{ 0, 1, 2, 3, 4, 5, 6, 7},
{ 0, 8,16,24,32,40,48,56}};
for (i = 0; i < 8; i++)
JPEGIDCT (metrix + (i << 3), k[0]);
for (i = 0; i < 8; i++)
JPEGIDCT (metrix + i, k[1]);
}
void
JPEGIQtZBlock (S16 * s, S32 * d, S16 * pQt, S16 correct)
{
S16 i, j;
S32 *pbuffer, buffer[8][8];
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
//tag = Z[i][j];
buffer[i][j] = (S32) s[JPEGZ[i][j]] * (S32) pQt[JPEGZ[i][j]];
}
pbuffer = (S32 *) buffer;
JPEGIDCTint (pbuffer);
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
d[(i <<>> 3) + correct;
}
void
JPEGIQtZMCU (S16 xx, S16 yy, S16 offset, S16 * pQt, S16 correct)
{
S16 i, j, *pMCUBuffer;
S32 *pQtZMCUBuffer;
pMCUBuffer = jpg->MCUbuffer + offset;
pQtZMCUBuffer = jpg->QtZMCUbuffer + offset;
for (i = 0; i < yy; i++)
for (j = 0; j < xx; j++)
JPEGIQtZBlock (pMCUBuffer + (i * xx + j) * 64,
pQtZMCUBuffer + (i * xx + j) * 64, pQt, correct);
}
void
JPEGGetYUV (S16 xx, S16 yy, S32 * buf, S16 offset)
{
S16 i, j, k, n;
S32 *pQtZMCU;
pQtZMCU = jpg->QtZMCUbuffer + offset;
for (i = 0; i < yy; i++)
for (j = 0; j < xx; j++)
for (k = 0; k < 8; k++)
for (n = 0; n < 8; n++)
buf[((((i <<>sampleYH) << 3) + (j << 3) + n] = *pQtZMCU++;
}
void
JE_Decode (PegPoint Where)
{
S16 Yinbuf, Uinbuf, Vinbuf;
#ifdef BMP_RGB24
U8 bfType[2];
BITMAPFILEHEADEREX hdr;
BITMAPINFOHEADER bi;
bfType[0] = 0x42; /* BM */
bfType[1] = 0x4D;
hdr.bfReserved = 0L;
hdr.bfOffBits = 0x36;
hdr.bfSize = jpg->lDst;
bi.biSize = 0x28;
bi.biWidth = (S32) DISPLAY_WIDTH; //jpg->LiWidth;
bi.biHeight = (S32) DISPLAY_HEIGHT; //jpg->LiHeight;
bi.biPlanes = 1;
bi.biBitCount = (S16) COLORBITS;
bi.biCompression = 0;
bi.biSizeImage = hdr.bfSize - 0x36;
bi.biXPelsPerMeter = 0xEce;
bi.biYPelsPerMeter = 0xEc4;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
memcpy (jpg->pDst, bfType, (S32) 2 * sizeof (U8));
memcpy (jpg->pDst + 2 * sizeof (U8), &hdr,
(S32) sizeof (BITMAPFILEHEADEREX));
memcpy (jpg->pDst + sizeof (BITMAPFILEHEADEREX) + 2 * sizeof (U8), &bi,
(S32) sizeof (BITMAPINFOHEADER));
#endif
jpg->OffsetWidth = Where.x;
jpg->OffsetHeight = Where.y;
if ((jpg->OffsetWidth >= (U16) DISPLAY_WIDTH) || (jpg->OffsetHeight >= (U16) DISPLAY_HEIGHT)) //||(jpg->OffsetWidth < (U16)0)||(jpg->OffsetHeight < (U16)0))
return; // no need decode
jpg->YinMCU = jpg->sampleYH * jpg->sampleYV;
jpg->UinMCU = jpg->sampleUH * jpg->sampleUV;
jpg->VinMCU = jpg->sampleVH * jpg->sampleVV;
jpg->HYtoU = jpg->sampleYH / jpg->sampleUH;
jpg->VYtoU = jpg->sampleYV / jpg->sampleUV;
jpg->HYtoV = jpg->sampleYH / jpg->sampleVH;
jpg->VYtoV = jpg->sampleYV / jpg->sampleVV;
Yinbuf = 0;
Uinbuf = jpg->YinMCU << 6;
Vinbuf = (jpg->YinMCU + jpg->UinMCU) << 6;
while (JPEGDecodeMCUBlock ())
{
jpg->interval++;
if ((jpg->restart) && (jpg->interval % jpg->restart == 0))
jpg->intervalflag = 1;
else
jpg->intervalflag = 0;
JPEGIQtZMCU (jpg->sampleYH, jpg->sampleYV, Yinbuf, jpg->YQt, 128);
JPEGIQtZMCU (jpg->sampleUH, jpg->sampleUV, Uinbuf, jpg->UQt, 0);
JPEGIQtZMCU (jpg->sampleVH, jpg->sampleVV, Vinbuf, jpg->VQt, 0);
JPEGGetYUV (jpg->sampleYH, jpg->sampleYV, jpg->Y, Yinbuf);
JPEGGetYUV (jpg->sampleUH, jpg->sampleUV, jpg->U, Uinbuf);
JPEGGetYUV (jpg->sampleVH, jpg->sampleVV, jpg->V, Vinbuf);
JPEGSavebmp ();
jpg->width += (jpg->sampleYH << 3);
if (jpg->width >= jpg->imgwidth)
{
jpg->width = 0;
jpg->height += (jpg->sampleYV << 3);
}
if ((jpg->width == 0) && (jpg->height >= jpg->imgheight))
break;
}
}
static JPEGDECODE jpegdecode;
U16
JE_MemInit (void)
{
if (jpg != NULL)
{
jpg = NULL;
}
jpg = (JPEGDECODE *) & jpegdecode;
DEBUG_Message ("JE_MemInit!");
memset (jpg, 0x00, sizeof (JPEGDECODE));
return sizeof (JPEGDECODE);
}
U16
JE_MemAlloc (void)
{
jpg->pDst = (U8 *) & display;
//#ifdef _SUPPORT_FILE
memset (jpg->pDst, 0xFF, jpg->lDst);
//#endif
return (U16) (jpg->lDst);
}
void
JE_MemRelease (void)
{
jpg->pDst = NULL;
jpg = NULL;
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
int
JPEGDecodeMain (PegPoint Where, U8 * fp_jpg_buffer, U32 jpg_total_size)
{
S32 dstlen = 0;
#ifdef _SUPPORT_FILE
FILE *fpTar;
#endif
DEBUG_Message ("........test........");
//DEBUG_Message ("........%d........", sizeof (JPEGDECODE));
JE_MemInit (); //////////////////////////////////////////////////////////
dstlen = JE_Initialize (fp_jpg_buffer, jpg_total_size);
if ((dstlen <> MAX_MALLOC_LEN))
{
DEBUG_Message ("........overflow........");
return -1;
}
JE_MemAlloc (); //////////////////////////////////////////////////////////
JE_Decode (Where);
DEBUG_Message ("........test over........");
#ifdef _SUPPORT_FILE
if ((fpTar = fopen ("test001.bmp", "wb")) == NULL)
{
DEBUG_Message ("Can not create output File!");
return -1;
}
fwrite (jpg->pDst, jpg->lDst, 1, fpTar);
fclose (fpTar);
#endif
JE_MemRelease (); //////////////////////////////////////////////////////////
return 0;
}
#define ROMDATA const
#define UCHAR unsigned char
#include "Resource1.h"
int main(void)
{
PegPoint Where = { 10, 28 };
for(;;)
{
JPEGDecodeMain (Where, gbtestBitmap.pStart, gbtestBitmap.uBmpSize);
TargetLabel:
DEBUG_Message("test continue!");
}
return 0;
}