📄 jpegls.cpp
字号:
/*
* JPEG decoding engine for DCT-baseline
*
* copyrights 2003 by nikq | nikq::club.
*/
#include <jpegls.h>
//僕僌僓僌僥乕僽儖
static int zigzag_table[]={
0, 1, 8, 16,9, 2, 3,10,
17,24,32,25,18,11, 4, 5,
12,19,26,33,40,48,41,34,
27,20,13, 6, 7,14,21,28,
35,42,49,56,57,50,43,36,
29,22,15,23,30,37,44,51,
58,59,52,45,38,31,39,46,
53,60,61,54,47,55,62,63,
0
};
// 僐儞僗僩儔僋僞
CJPEGLS::CJPEGLS()
{
init();
decode_init();
}
CJPEGLS::~CJPEGLS()
{
//摿偵側偟
}
int CJPEGLS::Open( unsigned char *data,int size )
{
this->data= data;
data_size = size;
data_index= 0;
//僿僢僟偺僷乕僗
return header();
}
void CJPEGLS::GetInfo( int* _width, int* _height )
{
*_width = width;
*_height = height;
}
void CJPEGLS::Decode( unsigned char * dest )
{
decode(dest);
}
// -------------------------- I/O ----------------------------
// 價僢僌僄儞僨傿傾儞偭傐偄
unsigned char CJPEGLS::get_byte(void)
{
unsigned char c;
// EOF
if(data_index >= data_size)
return 0;
c = data[ data_index++ ];
return c;
}
unsigned short CJPEGLS::get_word(void)
{
unsigned char h,l;
h = get_byte();
l = get_byte();
return (h<<8)|l;
}
unsigned short CJPEGLS::get_bits(int bit)
{
unsigned char c;
unsigned short ret;
while( bit_remain <= 16 ){
c = get_byte();
if(c == 0xFF)
get_byte();
bit_buff = (bit_buff << 8) | c;
bit_remain += 8;
}
ret = (bit_buff>>(bit_remain - bit))&((1<<bit)-1);
bit_remain -= bit;
return ret;
}
// ------------------------ JPEG 僙僌儊儞僩幚憰 -----------------
// 枹懳墳側偺偼偡偭旘偽偡
void CJPEGLS::skip(void)
{
unsigned w;
w = get_word() - 2;
data_index += w;
}
// start of frame
void CJPEGLS::sof(void)
{
unsigned char c,n;
int i,h,v;
//printf("--- SOF ---\n");
c = get_word();
c = get_byte(); // bpp
height = get_word();
width = get_word();
n = get_byte(); // Num of compo
compo_count = n; // nf
for(i=0;i<n;i++) {
compo_id[i] = get_byte();
c = get_byte();
//printf("%02x\n",c);
compo_sample[i] = c;
h = (c>>4) & 0x0F;
v = c & 0x0F;
compo_h[i] = h;
compo_v[i] = v;
if(max_h < h)
max_h = h;
if(max_v < v)
max_v = v;
compo_qt[i] = get_byte();
}
}
// data restart interval
void CJPEGLS::dri(void)
{
get_word();
//printf("--- DRI ---\n");
interval = get_word();
}
// define quantize table
void CJPEGLS::dqt(void)
{
unsigned char c;
int i,j,size;
size = get_word() - 2;
//printf("--- DQT ---\n");
while(size>0) {
c = get_byte();
size--;
j = c & 7;
if(j > n_qt)
n_qt = j;
if((c>>3)){
// 16 bit DQT
for(i=0;i<64;i++){
size-=2;
qt[j][ i ] = (get_word()>>8);
}
}
else{
// 8 bit DQT
for(i=0;i<64;i++){
size--;
qt[j][ i ] = get_byte();
}
}
}
}
// define huffman table
void CJPEGLS::dht(void)
{
unsigned tc,th;
unsigned code = 0;
unsigned char val;
int i,j,k,num,Li[17];
int len;
HUFF *table;
len = get_word() - 2;
//printf("--- DHT ---\n");
while(len > 0)
{
val = get_byte();
tc = (val>>4) & 0x0F; // 僥乕僽儖僋儔僗(DC/AC惉暘僙儗僋僞)
th = val & 0x0F; // 僥乕僽儖僿僢僟(壗枃栚偺僾儗乕儞偐)
table = (HUFF*)&(huff[tc][th]);
num = 0;
for (i = 1; i <= 16; i++) {
Li[i] = get_byte();
num += Li[i];
}
table->elem = num;
// 晞崋惗惉
k=0;
for(i=1;i<=16;i++) {
for(j=0;j<Li[i];j++) {
table->size[k++] = i;
}
}
k=0;
code=0;
i = table->size[0];
while(k<num) {
while(table->size[k] == i){
table->code[k++] = code++;
}
if(k>=num)
break;
do{
code = code << 1;
i++;
}while(table->size[k] != i);
}
for(k=0;k<num;k++)
table->value[k] = get_byte();
len = len - 18 - num;
}
}
// start of scan
void CJPEGLS::sos(void)
{
int i;
unsigned char c;
get_word();
//printf("-------SOS----\n");
scan_count = get_byte();
for(i=0;i<scan_count;i++) {
scan_id[i] = get_byte();
c = get_byte();
scan_dc[i] = c >> 4; // DC Huffman Table
scan_ac[i] = c & 0x0F; // AC Huffman Table
}
//3 bytes skip
get_byte();
get_byte();
get_byte();
}
void CJPEGLS::init(void)
{
int i;
//printf("-------init----\n");
for(i=0;i<3;i++)
mcu_preDC[i]=0;
n_qt = 0;
max_h = 0;
max_v = 0;
bit_remain = 0;
bit_buff = 0;
// DRI儕僙僢僩柍偟
interval = 0;
}
int CJPEGLS::header(void)
{
unsigned char c;
int end = 0;
while(!end)
{
c = get_byte();
if(data_index >= data_size)
return -1;
c = get_byte();
switch(c)
{
case 0xD8: break;
case 0xD9: end = 1;break;
case 0xC0: sof(); break;
case 0xC4: dht(); break;
case 0xDB: dqt(); break;
case 0xDD: dri(); break;
case 0xDA: sos(); end = 1; break;
default:
skip();
}
}
return 0;
}
// ------------------------------------ MCU decode --------------------------
// 僨僐乕僪
int CJPEGLS::decode_init(void)
{
int i,j;
for(i=0;i< scan_count;i++) {
// i:scan
for(j=0;j< compo_count;j++) {
// j:frame
if( scan_id[i] == compo_id[j]){
scan_h[i] = compo_h[j];
scan_v[i] = compo_v[j];
scan_qt[i]= compo_qt[j];
break;
}
}
if(j >= compo_count){
// 僾儘僌儗僢僔僽JPEG偩偲偙傟偑弌傑偡
return 1;
}
}
mcu_width = max_h * 8;
mcu_height = max_v * 8;
for(i=0;i<32*32*4;i++){
mcu_buf[i] = 0x80;
}
for(i=0;i<scan_count;i++){
mcu_yuv[i] = mcu_buf + i*32*32;
}
return 0;
}
// 僴僼儅儞 1僔儞儃儖暅崋
int CJPEGLS::get_huff(int tc,int th)
{
HUFF *h = &(huff[tc][th]);
int code,size,k,v;
code = 0;
size = 0;
k = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -