#ifndef _JPEG_H_
#define _JPEG_H_
typedef signed char shortint;
typedef signed short smallint;
typedef signed int longint;
typedef unsigned char byte;
typedef signed int integer;
typedef unsigned short word;
typedef unsigned int dword;
//typedef unsigned int long;
typedef shortint * pshortint;
typedef smallint * psmallint;
typedef longint * plongint;
typedef byte * pbyte;
typedef integer * pint;
typedef integer myint[8][8];
typedef unsigned char * pchar;
typedef unsigned int boolean;
typedef byte * pointer;
#define false 0
#define true 1
#define func_ok 0
#define func_memory_error 1
#define func_file_error 2
#define func_format_error 3
#define m_sof0 0xc0
#define m_dht 0xc4
#define m_eoi 0xd9
#define m_sos 0xda
#define m_dqt 0xdb
#define m_dri 0xdd
#define m_app0 0xe0
#define w1 2841 // 2048*sqrt(2)*cos(1*pi/16)
#define w2 2676 // 2048*sqrt(2)*cos(2*pi/16)
#define w3 2408 // 2048*sqrt(2)*cos(3*pi/16)
#define w5 1609 // 2048*sqrt(2)*cos(5*pi/16)
#define w6 1108 // 2048*sqrt(2)*cos(6*pi/16)
#define w7 565 // 2048*sqrt(2)*cos(7*pi/16)
extern pchar jpeg_source;
extern pointer bmp_dest;
extern dword bmp_size;
boolean jpeg_decode(void);
/*
integer inittag(void);
void inittable(void);
integer decode(void);
integer decodemcublock(void);
integer hufblock(byte dchufindex, byte achufindex);
integer decodeelement(void);
void iqtizzmcucomponent(smallint flag);
void iqtizzblock(psmallint s, pint d, smallint flag);
void getyuv(smallint flag);
void storebuffer(void);
byte readbyte(void);
void initialize_fast_idct(void);
void fast_idct(myint block);
void idctrow(myint block);
void idctcol(myint block);
*/
#endif // _JPEG_H_
#include <jpeg.h>
const byte myand[9] = { 0, 1, 3, 7, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
const byte zig_zag[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 }
};
pchar jpeg_source;
pointer bmp_dest;
dword bmp_size;
dword imgwidth = 0;
dword imgheight = 0;
smallint interval = 0;
boolean intervalflag;
byte comp_index[4];
byte ydcindex, yacindex, uvdcindex, uvacindex, huftabindex;
smallint restart;
smallint comp_num;
smallint samprate_y_h, samprate_y_v, samprate_u_h, samprate_u_v, samprate_v_h,
samprate_v_v;
smallint h_ytou, v_ytou, h_ytov, v_ytov, y_in_mcu, u_in_mcu, v_in_mcu;
smallint bitpos, curbyte, rrun, vvalue;
smallint ycoef, ucoef, vcoef;
dword sizei, sizej;
dword linebytes, numcolors;
smallint qt_table[3][64];
smallint code_pos_table[4][16];
smallint code_len_table[4][16];
smallint blockbuffer[64];
smallint mcubuffer[10 *64];
word code_value_table[4][256];
word huf_max_value[4][16];
word huf_min_value[4][16];
pchar lpimgdata, lp;
psmallint yqttable, uqttable, vqttable;
integer y[4 *64];
integer u[4 *64];
integer v[4 *64];
integer qtzzmcubuffer[10 *64];
longint iclip[1024];
integer inittag(void);
void inittable(void);
integer decode(void);
integer decodemcublock(void);
integer hufblock(byte dchufindex, byte achufindex);
integer decodeelement(void);
void iqtizzmcucomponent(smallint flag);
void iqtizzblock(psmallint s, pint d, smallint flag);
void getyuv(smallint flag);
void storebuffer(void);
byte readbyte(void);
void initialize_fast_idct(void);
void fast_idct(myint block);
void idctrow(myint block);
void idctcol(myint block);
//------------------------------------------------------------------------------
// width = 800
// height = 480
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
boolean jpeg_decode(void)
{
inittable();
if (inittag())
{
if ((samprate_y_h != 0) && (samprate_y_v != 0))
{
numcolors = 0;
if ( ( imgwidth != 800) || ( imgheight != 480 ) ) return 0;
//linebytes = ((imgwidth *24+31) / 32) *4;
linebytes = imgwidth * 2;
bmp_size = linebytes * imgheight;
if (decode() == func_ok)
return 1;
}
}
return 0;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
integer inittag(void)
{
boolean finish;
byte id;
smallint llength;
smallint i, j, k;
smallint huftab1, huftab2;
smallint huftabindex;
byte hf_table_index;
byte qt_table_index;
byte comnum;
pchar lptemp;
smallint ccount;
finish = false;
lp = jpeg_source + 2;
while (!finish)
{
id = lp[1];
lp+=2;
switch (id)
{
case m_app0:
{
llength = (lp[0] << 8) + lp[1];
lp += llength; //skip jfif segment marker
break;
}
case m_dqt:
{
llength = (lp[0] << 8) + lp[1];
qt_table_index = lp[2] & 0x0F;
lptemp = lp + 3;
if (llength < 80)
{
for (i = 0; i < 64; i++)
{
qt_table[qt_table_index] = *lptemp;
lptemp++;
}
}
else
{
for (i = 0; i < 64; i++)
{
qt_table[qt_table_index] = *lptemp;
lptemp++;
}
qt_table_index = (*lptemp) & 0x0F;
lptemp++;
for (i = 0; i < 64; i++)
{
qt_table[qt_table_index] = *lptemp;
lptemp++;
}
}
lp = lp + llength;
break;
}
case m_sof0:
{
llength = (lp[0] << 8) + lp[1];
imgheight = (lp[3] << 8) + lp[4];
imgwidth = (lp[5] << 8) + lp[6];
comp_num = lp[7];
if (((comp_num != 1) && (comp_num != 3)))
return func_format_error;
if (comp_num == 3)
{
comp_index[0] = lp[8];
samprate_y_h = lp[9] >> 4;
samprate_y_v = lp[9] & 0x0f;
yqttable = &qt_table[lp[10]][0];
comp_index[1] = lp[11];
samprate_u_h = lp[12] >> 4;
samprate_u_v = lp[12] & 0x0f;
uqttable = &qt_table[lp[13]][0];
comp_index[2] = lp[14];
samprate_v_h = lp[15] >> 4;
samprate_v_v = lp[15] & 0x0f;
vqttable = &qt_table[lp[16]][0];
}
else
// if (comp_num == 1)
{
comp_index[0] = lp[8];
samprate_y_h = lp[9] >> 4;
samprate_y_v = lp[9] & 0x0f;
yqttable = &qt_table[lp[10]][0];
comp_index[1] = lp[8];
samprate_u_h = 1;
samprate_u_v = 1;
uqttable = &qt_table[lp[10]][0];
comp_index[2] = lp[8];
samprate_v_h = 1;
samprate_v_v = 1;
vqttable = &qt_table[lp[10]][0];
}
lp = lp + llength;
break;
}
case m_dht:
{
llength = (lp[0] << 8) + lp[1];
if (llength < 0xd0)
{
huftab1 = lp[2] >> 4;
huftab2 = lp[2] & 0x0f;
huftabindex = huftab1*2 + huftab2;
lptemp = lp + 3;
for (i = 0; i < 16; i++)
{
code_len_table[huftabindex] = *lptemp;
lptemp++;
}
j = 0;
for (i = 0; i < 16; i++)
{
if (code_len_table[huftabindex] != 0)
{
k = 0;
while (k < code_len_table[huftabindex])
{
code_value_table[huftabindex][k + j] = *lptemp;
lptemp = lptemp + 1;
k = k + 1;
}
j = j + k;
}
}
i = 0;
while (code_len_table[huftabindex] == 0)
i = i + 1;
for (j = 0; j < i; j++)
{
huf_min_value[huftabindex][j] = 0;
huf_max_value[huftabindex][j] = 0;
}
huf_min_value[huftabindex] = 0;
huf_max_value[huftabindex] = code_len_table[huftabindex] - 1;
for (j = i + 1; j < 16; j++)
{
huf_min_value[huftabindex][j] = (huf_max_value[huftabindex][j -
1] + 1) << 1;
huf_max_value[huftabindex][j] = huf_min_value[huftabindex][j] +
code_len_table[huftabindex][j] - 1;
}
code_pos_table[huftabindex][0] = 0;
for (j = 1; j < 16; j++)
code_pos_table[huftabindex][j] = code_len_table[huftabindex][j -
1] + code_pos_table[huftabindex][j - 1];
lp = lp + llength;
}
else
{
hf_table_index = lp[2];
lp = lp + 2;
while (hf_table_index != 0xff)
{
huftab1 = hf_table_index >> 4;
huftab2 = hf_table_index & 0x0F;
huftabindex = huftab1 * 2+huftab2;
lptemp = lp;
lptemp++;
ccount = 0;
for (i = 0; i < 16; i++)
{
code_len_table[huftabindex] = *lptemp;
lptemp++;
ccount = ccount + code_len_table[huftabindex];
}
ccount = ccount + 17;
j = 0;
for (i = 0; i < 16; i++)
{
if (code_len_table[huftabindex] != 0)
{
k = 0;
while (k < code_len_table[huftabindex])
{
code_value_table[huftabindex][k + j] = *lptemp;
lptemp++;
k++;
}
j = j + k;
}
}
i = 0;
while (code_len_table[huftabindex] == 0)
i++;
for (j = 0; j < i; j++)
{
huf_min_value[huftabindex][j] = 0;
huf_max_value[huftabindex][j] = 0;
}
huf_min_value[huftabindex] = 0;
huf_max_value[huftabindex] = code_len_table[huftabindex] - 1;
for (j = i + 1; j < 16; j++)
{
huf_min_value[huftabindex][j] = (huf_max_value[huftabindex][j - 1] + 1) << 1;
huf_max_value[huftabindex][j] = huf_min_value[huftabindex][j] + code_len_table[huftabindex][j] - 1;
}
code_pos_table[huftabindex][0] = 0;
for (j = 1; j < 16; j++)
code_pos_table[huftabindex][j] = code_len_table[huftabindex][j- 1] + code_pos_table[huftabindex][j - 1];
lp = lp + ccount;
hf_table_index = *lp;
}
}
break;
}
case m_dri:
{
llength = (lp[0] << 8) + lp[1];
restart = (lp[2] << 8) + lp[3];
lp = lp + llength;
break;
}
case m_sos:
{
llength = (lp[0] << 8) + lp[1];
comnum = lp[2];
if (comnum != comp_num)
return func_format_error;
lptemp = lp + 3;
for (i = 0; i < comp_num; i++)
{
if (*lptemp == comp_index[0])
{
ydcindex = lptemp[1] >> 4;
yacindex = (lptemp[1] & 0x0f) + 2;
}
else
{
uvdcindex = lptemp[1] >> 4;
uvacindex = (lptemp[1] & 0x0f) + 2;
}
lptemp = lptemp + 2;
}
lp = lp + llength;
finish = true;
break;
}
case m_eoi:
{
return func_format_error;
}
default:
{
if ((id &0xf0) != 0xd0)
{
llength = (lp[0] << 8) + lp[1];
lp = lp + llength;
}
else
{
lp = lp + 2;
}
}
}
}
return 1;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void inittable(void)
{
smallint i, j;
sizei = 0;
sizej = 0;
imgwidth = 0;
imgheight = 0;
interval = 0;
rrun = 0;
vvalue = 0;
bitpos = 0;
curbyte = 0;
intervalflag = false;
restart = 0;
for (i = 0; i < 3; i++)
for (j = 0; j < 64; j++)
qt_table[j] = 0;
comp_num = 0;
huftabindex = 0;
for (i = 0; i < 3; i++)
comp_index = 0;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 16; j++)
{
code_len_table[j] = 0;
code_pos_table[j] = 0;
huf_max_value[j] = 0;
huf_min_value[j] = 0;
}
}
for (i = 0; i < 4; i++)
{
for (j = 0; j < 256; j++)
{
code_value_table[j] = 0;
}
}
for (i = 0; i < 10 *64; i++)
{
mcubuffer = 0;
qtzzmcubuffer = 0;
}
for (i = 0; i < 64; i++)
{
y = 0;
u = 0;
v = 0;
blockbuffer = 0;
}
ycoef = 0;
ucoef = 0;
vcoef = 0;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
integer decode(void)
{
integer funcret;
y_in_mcu = samprate_y_h * samprate_y_v;
u_in_mcu = samprate_u_h * samprate_u_v;
v_in_mcu = samprate_v_h * samprate_v_v;
h_ytou = samprate_y_h / samprate_u_h;
v_ytou = samprate_y_v / samprate_u_v;
h_ytov = samprate_y_h / samprate_v_h;
v_ytov = samprate_y_v / samprate_v_v;
initialize_fast_idct();
funcret = decodemcublock();
while (funcret == func_ok)
{
interval++;
if ((restart != 0) && ((interval % restart) == 0))
intervalflag = true;
else
intervalflag = false;
iqtizzmcucomponent(0);
iqtizzmcucomponent(1);
iqtizzmcucomponent(2);
getyuv(0);
getyuv(1);
getyuv(2);
storebuffer();
sizej = sizej + (dword)(samprate_y_h *8);
if (sizej >= imgwidth)
{
sizej = 0;
sizei = sizei + (dword)(samprate_y_v *8);
}
if ((sizej == 0) && (sizei >= imgheight))
break;
funcret = decodemcublock();
}
return funcret;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void getyuv(smallint flag)
{
smallint h, vv;
integer temp;
smallint i, j, k, hk;
pint buf, tempbuf;
pint pqtzzmcu;
switch (flag)
{
case 0:
{
h = samprate_y_h;
vv = samprate_y_v;
buf = y;
pqtzzmcu = qtzzmcubuffer;
break;
}
case 1:
{
h = samprate_u_h;
vv = samprate_u_v;
buf = u;
pqtzzmcu = qtzzmcubuffer;
pqtzzmcu += (y_in_mcu * 64);
break;
}
case 2:
{
h = samprate_v_h;
vv = samprate_v_v;
buf = v;
pqtzzmcu = qtzzmcubuffer;
pqtzzmcu += ( (y_in_mcu + u_in_mcu) *64 );
break;
}
default:
{
h = 0;
vv = 0;
buf = 0;
pqtzzmcu = 0;
}
}
for (i = 0; i < vv; i++)
for (j = 0; j < h; j++)
for (k = 0; k < 8; k++)
for (hk = 0; hk < 8; hk++)
{
temp = (i *8+k) *samprate_y_h * 8 + j * 8 + hk;
tempbuf = buf;
tempbuf += temp;
*tempbuf = *pqtzzmcu;
pqtzzmcu++;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void storebuffer16(void)
{
smallint i, j;
pchar lpbmp;
byte r, g, b;
integer yy, uu, vv, rr, gg, bb;
for (i = 0; i < samprate_y_v *8; i++)
{
if ((sizei + (dword)(i)) < imgheight)
{
lpbmp = bmp_dest + (dword)((imgheight - sizei - (dword)(i) - 1) *linebytes + sizej * 2); // 2 bytes for RGB565
for (j = 0; j < samprate_y_h *8; j++)
{
if ((sizej + (dword)(j)) < imgwidth)
{
yy = y[i *8 * samprate_y_h + j];
uu = u[(i / v_ytou) *8 * samprate_y_h + j / h_ytou];
vv = v[(i / v_ytov) *8 * samprate_y_h + j / h_ytov];
rr = ((yy << 8) + 18 * uu + 367 * vv);
if (rr < 0)
rr = (rr >> 8) | (0xFFFFFFFF << (32-8));
else
rr = rr >> 8;
gg = ((yy << 8) - 159 * uu - 220 * vv);
if (gg < 0)
gg = (gg >> 8) | (0xFFFFFFFF << (32-8));
else
gg = gg >> 8;
bb = ((yy << 8) + 411 * uu - 29 * vv);
if (bb < 0)
bb = (bb >> 8) | (0xFFFFFFFF << (32-8));
else
bb = bb >> 8;
r = (byte)(rr);
g = (byte)(gg);
b = (byte)(bb);
if ((rr &0xffffff00) != 0)
if (rr > 255)
r = 255;
else if (rr < 0)
r = 0;
if (gg &0xffffff00 != 0)
if (gg > 255)
g = 255;
else if (gg < 0)
g = 0;
if (bb &0xffffff00 != 0)
if (bb > 255)
b = 255;
else if (bb < 0)
b = 0;
// *lpbmp = b;
// lpbmp++;
// *lpbmp = g;
// lpbmp++;
// *lpbmp = r;
// lpbmp++;
*lpbmp = b;
lpbmp++;
*lpbmp = g;
lpbmp++;
*lpbmp = r;
lpbmp++;
}
else
break;
}
}
else
break;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void storebuffer24(void)
{
smallint i, j;
pchar lpbmp;
byte r, g, b;
integer yy, uu, vv, rr, gg, bb;
for (i = 0; i < samprate_y_v *8; i++)
{
if ((sizei + (dword)(i)) < imgheight)
{
lpbmp = bmp_dest + (dword)((imgheight - sizei - (dword)(i) - 1) *linebytes + sizej * 3);
for (j = 0; j < samprate_y_h *8; j++)
{
if ((sizej + (dword)(j)) < imgwidth)
{
yy = y[i *8 * samprate_y_h + j];
uu = u[(i / v_ytou) *8 * samprate_y_h + j / h_ytou];
vv = v[(i / v_ytov) *8 * samprate_y_h + j / h_ytov];
rr = ((yy << 8) + 18 * uu + 367 * vv);
if (rr < 0)
rr = (rr >> 8) | (0xFFFFFFFF << (32-8));
else
rr = rr >> 8;
gg = ((yy << 8) - 159 * uu - 220 * vv);
if (gg < 0)
gg = (gg >> 8) | (0xFFFFFFFF << (32-8));
else
gg = gg >> 8;
bb = ((yy << 8) + 411 * uu - 29 * vv);
if (bb < 0)
bb = (bb >> 8) | (0xFFFFFFFF << (32-8));
else
bb = bb >> 8;
r = (byte)(rr);
g = (byte)(gg);
b = (byte)(bb);
if ((rr &0xffffff00) != 0)
if (rr > 255)
r = 255;
else if (rr < 0)
r = 0;
if (gg &0xffffff00 != 0)
if (gg > 255)
g = 255;
else if (gg < 0)
g = 0;
if (bb &0xffffff00 != 0)
if (bb > 255)
b = 255;
else if (bb < 0)
b = 0;
*lpbmp = b;
lpbmp++;
*lpbmp = g;
lpbmp++;
*lpbmp = r;
lpbmp++;
}
else
break;
}
}
else
break;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void storebuffer(void)
{
smallint i, j;
pchar lpbmp;
byte r, g, b;
word color16;
integer yy, uu, vv, rr, gg, bb;
for (i = 0; i < samprate_y_v *8; i++)
{
if ((sizei + (dword)(i)) < imgheight)
{
//for bmp
lpbmp = bmp_dest + (dword)((imgheight - sizei - (dword)(i) - 1) *linebytes + sizej * 2);
// for LCD
lpbmp = bmp_dest + (dword)((sizei + (dword)(i)) *linebytes + sizej * 2);
for (j = 0; j < samprate_y_h *8; j++)
{
if ((sizej + (dword)(j)) < imgwidth)
{
yy = y[i *8 * samprate_y_h + j];
uu = u[(i / v_ytou) *8 * samprate_y_h + j / h_ytou];
vv = v[(i / v_ytov) *8 * samprate_y_h + j / h_ytov];
rr = ((yy << 8) + 18 * uu + 367 * vv);
gg = ((yy << 8) - 159 * uu - 220 * vv);
bb = ((yy << 8) + 411 * uu - 29 * vv);
if (rr < 0)
rr = (rr >> 8) | (0xFFFFFFFF << (32-8));
else
rr = rr >> 8;
if (gg < 0)
gg = (gg >> 8) | (0xFFFFFFFF << (32-8));
else
gg = gg >> 8;
if (bb < 0)
bb = (bb >> 8) | (0xFFFFFFFF << (32-8));
else
bb = bb >> 8;
r = (byte)(rr);
g = (byte)(gg);
b = (byte)(bb);
if ((rr &0xffffff00) != 0)
if (rr > 255)
r = 255;
else if (rr < 0)
r = 0;
if (gg &0xffffff00 != 0)
if (gg > 255)
g = 255;
else if (gg < 0)
g = 0;
if (bb &0xffffff00 != 0)
if (bb > 255)
b = 255;
else if (bb < 0)
b = 0;
color16 = ( (r>>3) << 11) + ( (g>>2) << 5) + (b>>3);
*lpbmp = color16;
lpbmp++;
*lpbmp = color16>>8;
lpbmp++;
}
else
break;
}
}
else
break;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
integer decodemcublock(void)
{
psmallint lpmcubuffer;
smallint i, j;
integer funcret;
if (intervalflag)
{
lp += 2;
ycoef = 0;
ucoef = 0;
vcoef = 0;
bitpos = 0;
curbyte = 0;
}
switch (comp_num)
{
case 3:
{
lpmcubuffer = mcubuffer;
for (i = 0; i < samprate_y_h *samprate_y_v; i++)
{
funcret = hufblock(ydcindex, yacindex); //????4 * (8*8)
if (funcret != func_ok)
{
return funcret;
}
blockbuffer[0] = blockbuffer[0] + ycoef;
ycoef = blockbuffer[0];
for (j = 0; j < 64; j++)
{
*lpmcubuffer = blockbuffer[j];
lpmcubuffer++;
}
}
for (i = 0; i < samprate_u_h *samprate_u_v; i++)
{
funcret = hufblock(uvdcindex, uvacindex);
if (funcret != func_ok)
{
return funcret;
}
blockbuffer[0] = blockbuffer[0] + ucoef;
ucoef = blockbuffer[0];
for (j = 0; j < 64; j++)
{
*lpmcubuffer = blockbuffer[j];
lpmcubuffer++;
}
}
for (i = 0; i < samprate_v_h *samprate_v_v; i++)
{
funcret = hufblock(uvdcindex, uvacindex);
if (funcret != func_ok)
{
return funcret;
}
blockbuffer[0] = blockbuffer[0] + vcoef;
vcoef = blockbuffer[0];
for (j = 0; j < 64; j++)
{
*lpmcubuffer = blockbuffer[j];
lpmcubuffer++;
}
}
break;
}
case 1:
{
lpmcubuffer = mcubuffer;
funcret = hufblock(ydcindex, yacindex);
if (funcret != func_ok)
{
return funcret;
}
blockbuffer[0] = blockbuffer[0] + ycoef;
ycoef = blockbuffer[0];
for (j = 0; j < 64; j++)
{
*lpmcubuffer = blockbuffer[j];
lpmcubuffer++;
}
for (i = 0; i < 128; i++)
{
*lpmcubuffer = 0;
lpmcubuffer++;
}
break;
}
default:
{
return func_format_error;
}
}
return func_ok;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
integer hufblock(byte dchufindex, byte achufindex)
{
smallint count, i;
integer funcret;
count = 0;
huftabindex = dchufindex;
funcret = decodeelement();
if (funcret != func_ok)
return funcret;
blockbuffer[count] = vvalue;
count++;
//ac
huftabindex = achufindex;
while (count < 64)
{
funcret = decodeelement();
if (funcret != func_ok)
return funcret;
if ((rrun == 0) && (vvalue == 0))
{
for (i = count; i < 64; i++)
blockbuffer = 0;
count = 64;
}
else
{
for (i = 0; i < rrun; i++)
{
blockbuffer[count] = 0;
count++;
}
blockbuffer[count] = vvalue;
count++;
}
}
return func_ok;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
integer decodeelement(void)
{
integer thiscode, tempcode;
word temp, valueex;
smallint codelen;
byte hufexbyte, runsize, tempsize, sign;
byte newbyte, lastbyte;
if (bitpos >= 1)
{
bitpos--;
thiscode = (byte)(curbyte >> bitpos);
curbyte = curbyte & myand[bitpos];
}
else
{
lastbyte = readbyte();
bitpos--;
newbyte = curbyte &myand[bitpos];
thiscode = lastbyte >> 7;
curbyte = newbyte;
}
codelen = 1;
while ((thiscode < huf_min_value[huftabindex][codelen - 1]) ||
(code_len_table[huftabindex][codelen - 1] == 0) ||
(thiscode > huf_max_value[huftabindex][codelen - 1]))
{
if (bitpos >= 1)
{
bitpos--;
tempcode = (byte)(curbyte >> bitpos);
curbyte = curbyte &myand[bitpos];
}
else
{
lastbyte = readbyte();
bitpos--;
newbyte = curbyte &myand[bitpos];
tempcode = (byte)(lastbyte >> 7);
curbyte = newbyte;
}
thiscode = (thiscode << 1) + tempcode;
codelen++;
if (codelen > 16)
return func_format_error;
} //while
temp = thiscode - huf_min_value[huftabindex][codelen - 1] +
code_pos_table[huftabindex][codelen - 1];
hufexbyte = (byte)(code_value_table[huftabindex][temp]);
rrun = (smallint)(hufexbyte >> 4);
runsize = hufexbyte &0x0f;
if (runsize == 0)
{
vvalue = 0;
return func_ok;
}
tempsize = runsize;
if (bitpos >= runsize)
{
bitpos = bitpos - runsize;
valueex = (byte)(curbyte >> bitpos);
curbyte = curbyte &myand[bitpos];
}
else
{
valueex = curbyte;
tempsize = tempsize - bitpos;
while (tempsize > 8)
{
lastbyte = readbyte();
valueex = (valueex << 8) + (byte)(lastbyte);
tempsize = tempsize - 8;
}
lastbyte = readbyte();
bitpos = bitpos - tempsize;
valueex = (valueex << tempsize) + (lastbyte >> bitpos);
curbyte = lastbyte &myand[bitpos];
}
sign = valueex >> (runsize - 1);
if (sign != 0)
vvalue = valueex;
else
{
valueex = valueex ^ 0xffff;
temp = 0xffff << runsize;
vvalue = - ((smallint)(valueex ^ temp));
}
return func_ok;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void iqtizzmcucomponent(smallint flag)
{
smallint h, vv, i, j;
pint pqtzzmcubuffer, tempbuf1;
psmallint pmcubuffer, tempbuf2;
switch (flag)
{
case 0:
{
h = samprate_y_h;
vv = samprate_y_v;
pmcubuffer = (psmallint)(mcubuffer);
pqtzzmcubuffer = qtzzmcubuffer;
break;
}
case 1:
{
h = samprate_u_h;
vv = samprate_u_v;
pmcubuffer = (psmallint)(mcubuffer);
pmcubuffer += y_in_mcu * 64;
pqtzzmcubuffer = qtzzmcubuffer;
pqtzzmcubuffer += y_in_mcu * 64;
break;
}
case 2:
{
h = samprate_v_h;
vv = samprate_v_v;
pmcubuffer = (psmallint)(mcubuffer);
pmcubuffer += (y_in_mcu + u_in_mcu) *64;
pqtzzmcubuffer = qtzzmcubuffer;
pqtzzmcubuffer += (y_in_mcu + u_in_mcu) *64;
break;
}
default:
{
h = 0;
pqtzzmcubuffer = 0;
pmcubuffer = 0;
vv = 0;
break;
}
}
for (i = 0; i < vv; i++)
{
for (j = 0; j < h; j++)
{
tempbuf2 = pmcubuffer;
tempbuf2 += (i *h + j) *64;
tempbuf1 = pqtzzmcubuffer;
tempbuf1 += (i *h + j) *64;
iqtizzblock(tempbuf2, tempbuf1, flag);
}
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void iqtizzblock(psmallint s, pint d, smallint flag)
{
smallint i, j, tag, offset;
psmallint pqt, temp1, temp3;
myint buffer2;
pint temp2;
switch (flag)
{
case 0:
{
pqt = yqttable;
offset = 128;
break;
}
case 1:
{
pqt = uqttable;
offset = 0;
break;
}
case 2:
{
pqt = vqttable;
offset = 0;
break;
}
default:
{
pqt = 0;
offset = 0;
break;
}
}
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
tag = zig_zag[j];
temp1 = s;
temp1 += tag;
temp3 = pqt;
temp3 += tag;
buffer2[j] = (integer)( (*temp1) * (*temp3) );
}
fast_idct(buffer2); //??dct
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
temp2 = d;
temp2 += (i *8+j);
*temp2 = buffer2[j] + offset;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void fast_idct(myint block)
{
idctrow(block);
idctcol(block);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
byte readbyte(void)
{
byte i;
i = *lp;
lp = lp + 1;
if (i == 0xff)
lp = lp + 1;
bitpos = 8;
curbyte = i;
return i;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void initialize_fast_idct(void)
{
smallint i;
for (i = - 512; i < 512; i++)
{
if (i < - 256)
iclip[512+i] = - 256;
if (i > 255)
iclip[512+i] = 255;
if ((i >= - 256) && (i <= 255))
iclip[512+i] = i;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void idctrow(myint blk)
{
integer i, x0, x1, x2, x3, x4, x5, x6, x7, x8;
//intcut
for (i = 0; i < 8; i++)
{
x1 = blk[4] << 11;
x2 = blk[6];
x3 = blk[2];
x4 = blk[1];
x5 = blk[7];
x6 = blk[5];
x7 = blk[3];
if ((x1 | x2 | x3 | x4 | x5 | x6 | x7) == 0)
{
blk[1] = blk[0] << 3;
blk[2] = blk[0] << 3;
blk[3] = blk[0] << 3;
blk[4] = blk[0] << 3;
blk[5] = blk[0] << 3;
blk[6] = blk[0] << 3;
blk[7] = blk[0] << 3;
blk[0] = blk[0] << 3;
continue;
}
x0 = (blk[0] << 11) + 128; // for proper rounding in the fourth stage
//first stage
x8 = w7 *(x4 + x5);
x4 = x8 + (w1 - w7) *x4;
x5 = x8 - (w1 + w7) *x5;
x8 = w3 *(x6 + x7);
x6 = x8 - (w3 - w5) *x6;
x7 = x8 - (w3 + w5) *x7;
//second stage
x8 = x0 + x1;
x0 = x0 - x1;
x1 = w6 *(x3 + x2);
x2 = x1 - (w2 + w6) *x2;
x3 = x1 + (w2 - w6) *x3;
x1 = x4 + x6;
x4 = x4 - x6;
x6 = x5 + x7;
x5 = x5 - x7;
//third stage
x7 = x8 + x3;
x8 = x8 - x3;
x3 = x0 + x2;
x0 = x0 - x2;
if ((181 *(x4 + x5) + 128) < 0)
x2 = ((181 *(x4 + x5) + 128) >> 8) | (((0xFFFFFFFF)) << (32-8));
else
x2 = (181 *(x4 + x5) + 128) >> 8;
if ((181 *(x4 - x5) + 128) < 0)
x4 = ((181 *(x4 - x5) + 128) >> 8) | (((0xFFFFFFFF)) << (32-8));
else
x4 = (181 *(x4 - x5) + 128) >> 8;
//fourth stage
if (x7 + x1 < 0)
blk[0] = ((x7 + x1) >> 8) | (((0xFFFFFFFF)) << (32-8));
else
blk[0] = (x7 + x1) >> 8;
if (x3 + x2 < 0)
blk[1] = ((x3 + x2) >> 8) | (((0xFFFFFFFF)) << (32-8));
else
blk[1] = (x3 + x2) >> 8;
if (x0 + x4 < 0)
blk[2] = ((x0 + x4) >> 8) | (((0xFFFFFFFF)) << (32-8));
else
blk[2] = (x0 + x4) >> 8;
if (x8 + x6 < 0)
blk[3] = ((x8 + x6) >> 8) | (((0xFFFFFFFF)) << (32-8));
else
blk[3] = (x8 + x6) >> 8;
if (x8 - x6 < 0)
blk[4] = ((x8 - x6) >> 8) | (((0xFFFFFFFF)) << (32-8));
else
blk[4] = (x8 - x6) >> 8;
if (x0 - x4 < 0)
blk[5] = ((x0 - x4) >> 8) | (((0xFFFFFFFF)) << (32-8));
else
blk[5] = (x0 - x4) >> 8;
if (x3 - x2 < 0)
blk[6] = ((x3 - x2) >> 8) | (((0xFFFFFFFF)) << (32-8));
else
blk[6] = (x3 - x2) >> 8;
if (x7 - x1 < 0)
blk[7] = ((x7 - x1) >> 8) | (((0xFFFFFFFF)) << (32-8));
else
blk[7] = (x7 - x1) >> 8;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void idctcol(myint blk)
{
integer j, x0, x1, x2, x3, x4, x5, x6, x7, x8;
integer temp;
//intcut
for (j = 0; j < 8; j++)
{
x1 = blk[4][j] << 8;
x2 = blk[6][j];
x3 = blk[2][j];
x4 = blk[1][j];
x5 = blk[7][j];
x6 = blk[5][j];
x7 = blk[3][j];
if ((x1 | x2 | x3 | x4 | x5 | x6 | x7) == 0)
{
if ((blk[0][j] + 32) < 0)
temp = ((blk[0][j] + 32) >> 6) | (0xFFFFFFFF << (32-6));
else
temp = (blk[0][j] + 32) >> 6;
blk[1][j] = iclip[512+temp];
blk[2][j] = iclip[512+temp];
blk[3][j] = iclip[512+temp];
blk[4][j] = iclip[512+temp];
blk[5][j] = iclip[512+temp];
blk[6][j] = iclip[512+temp];
blk[7][j] = iclip[512+temp];
blk[0][j] = iclip[512+temp];
continue;
}
x0 = (blk[0][j] << 8) + 8192;
//first stage
x8 = w7 *(x4 + x5) + 4;
if ((x8 + (w1 - w7) *x4) < 0)
x4 = ((x8 + (w1 - w7) *x4) >> 3) | (0xFFFFFFFF << (32-3));
else
x4 = (x8 + (w1 - w7) *x4) >> 3;
if ((x8 - (w1 + w7) *x5) < 0)
x5 = ((x8 - (w1 + w7) *x5) >> 3) | (0xFFFFFFFF << (32-3));
else
x5 = (x8 - (w1 + w7) *x5) >> 3;
x8 = w3 *(x6 + x7) + 4;
if ((x8 - (w3 - w5) *x6) < 0)
x6 = ((x8 - (w3 - w5) *x6) >> 3) | (0xFFFFFFFF << (32-3));
else
x6 = (x8 - (w3 - w5) *x6) >> 3;
if ((x8 - (w3 + w5) *x7) < 0)
x7 = ((x8 - (w3 + w5) *x7) >> 3) | (0xFFFFFFFF << (32-3));
else
x7 = (x8 - (w3 + w5) *x7) >> 3;
//second stage
x8 = x0 + x1;
x0 = x0 - x1;
x1 = w6 *(x3 + x2) + 4;
if ((x1 - (w2 + w6) *x2) < 0)
x2 = ((x1 - (w2 + w6) *x2) >> 3) | (0xFFFFFFFF << (32-3));
else
x2 = (x1 - (w2 + w6) *x2) >> 3;
if ((x1 + (w2 - w6) *x3) < 0)
x3 = ((x1 + (w2 - w6) *x3) >> 3) | (0xFFFFFFFF << (32-3));
else
x3 = (x1 + (w2 - w6) *x3) >> 3;
x1 = x4 + x6;
x4 = x4 - x6;
x6 = x5 + x7;
x5 = x5 - x7;
//third stage
x7 = x8 + x3;
x8 = x8 - x3;
x3 = x0 + x2;
x0 = x0 - x2;
if ((181 *(x4 + x5) + 128) < 0)
x2 = ((181 *(x4 + x5) + 128) >> 8) | (0xFFFFFFFF << (32-8));
else
x2 = (181 *(x4 + x5) + 128) >> 8;
if ((181 *(x4 - x5) + 128) < 0)
x4 = ((181 *(x4 - x5) + 128) >> 8) | (0xFFFFFFFF << (32-8));
else
x4 = (181 *(x4 - x5) + 128) >> 8;
//fourth stage
if (x7 + x1 < 0)
temp = ((x7 + x1) >> 14) | (0xFFFFFFFF << (32-14));
else
temp = (x7 + x1) >> 14;
blk[0][j] = iclip[512+temp];
if (x3 + x2 < 0)
temp = ((x3 + x2) >> 14) | (0xFFFFFFFF << (32-14));
else
temp = (x3 + x2) >> 14;
blk[1][j] = iclip[512+temp];
if (x0 + x4 < 0)
temp = ((x0 + x4) >> 14) | (0xFFFFFFFF << (32-14));
else
temp = (x0 + x4) >> 14;
blk[2][j] = iclip[512+temp];
if (x8 + x6 < 0)
temp = ((x8 + x6) >> 14) | (0xFFFFFFFF << (32-14));
else
temp = (x8 + x6) >> 14;
blk[3][j] = iclip[512+temp];
if (x8 - x6 < 0)
temp = ((x8 - x6) >> 14) | (0xFFFFFFFF << (32-14));
else
temp = (x8 - x6) >> 14;
blk[4][j] = iclip[512+temp];
if (x0 - x4 < 0)
temp = ((x0 - x4) >> 14) | (0xFFFFFFFF << (32-14));
else
temp = (x0 - x4) >> 14;
blk[5][j] = iclip[512+temp];
if (x3 - x2 < 0)
temp = ((x3 - x2) >> 14) | (0xFFFFFFFF << (32-14));
else
temp = (x3 - x2) >> 14;
blk[6][j] = iclip[512+temp];
if (x7 - x1 < 0)
temp = ((x7 - x1) >> 14) | (0xFFFFFFFF << (32-14));
else
temp = (x7 - x1) >> 14;
blk[7][j] = iclip[512+temp];
}
}
文章评论(0条评论)
登录后参与讨论