⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpegls.cpp

📁 MONA是为数不多的C++语言编写的一个很小的操作系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -