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

📄 jpegls.cpp

📁 MONA是为数不多的C++语言编写的一个很小的操作系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    while( size < 16 ) {
        size++;
        v = get_bits(1);
        code = (code << 1) | v;

        while(h->size[k] == size){
            if(h->code[k] == code){
                return h->value[k];
            }
            k++;
        }
    }

    //晞崋僄儔乕
    return -1;
}

// 媡DCT乮僷僋
// 晜摦彮悢偮偐偭偪傖偭偰傞傫偱丄偳偆偵偐偟偨偄.

#ifdef USE_CHENDCT

#include "chendct.c"
void JPEG::idct_init(void)
{

}

void JPEG::idct(int *block,int *dest)
{
    ChenIDct(block,dest);
}
#else

const int C1_16 = 4017;					// cos( pi/16) x4096 (2^12)
const int C2_16 = 3784;					// cos(2pi/16) x4096 (2^12)
const int C3_16 = 3406;					// cos(3pi/16) x4096 (2^12)
const int C4_16 = 2896;					// cos(4pi/16) x4096 (2^12)
const int C5_16 = 2276;					// cos(5pi/16) x4096 (2^12)
const int C6_16 = 1567;					// cos(6pi/16) x4096 (2^12)
const int C7_16 = 799;					// cos(7pi/16) x4096 (2^12)

//  original code from Yui's code

void CJPEGLS::idct(int *src,int *dst){

    int		w;
    int		s0, s1, s2, s3, s4, s5, s6, s7;
    int		t0, t1, t2, t3, t4, t5, t6, t7;


    for (w = 0; w < 8; w++) {
        s4 = (src[1] * C7_16) - (src[7] * C1_16);
        s5 = (src[5] * C3_16) - (src[3] * C5_16);
        s6 = (src[3] * C3_16) + (src[5] * C5_16);
        s7 = (src[7] * C7_16) + (src[1] * C1_16);

        t0 = (src[0] + src[4]) * C4_16;
        t1 = (src[0] - src[4]) * C4_16;
        t2 = (src[2] * C6_16) - (src[6] * C2_16);
        t3 = (src[2] * C2_16) + (src[6] * C6_16);
        t4 = s4 + s5;
        t5 = s4 - s5;
        t6 = s7 - s6;
        t7 = s6 + s7;

        s0 = t0 + t3;
        s1 = t1 + t2;
        s2 = t1 - t2;
        s3 = t0 - t3;
        s5 = (t6 - t5) * 41 / 58;			// 1/sqrt(2)  12/17
        s6 = (t5 + t6) * 41 / 58;			// 1/sqrt(2)

        *src++ = (s0 + t7) >> 11;
        *src++ = (s1 + s6) >> 11;
        *src++ = (s2 + s5) >> 11;
        *src++ = (s3 + t4) >> 11;
        *src++ = (s3 - t4) >> 11;
        *src++ = (s2 - s5) >> 11;
        *src++ = (s1 - s6) >> 11;
        *src++ = (s0 - t7) >> 11;
    }

    src -= 64;

    for (w = 0; w < 8; w++) {

        t0 = (src[ 0] + src[32]) * C4_16;
        t1 = (src[ 0] - src[32]) * C4_16;
        t2 = src[16] * C6_16 - src[48] * C2_16;
        t3 = src[16] * C2_16 + src[48] * C6_16;
        s0 = t0 + t3;
        s1 = t1 + t2;
        s2 = t1 - t2;
        s3 = t0 - t3;

        s4 = src[ 8] * C7_16 - src[56] * C1_16;
        s5 = src[40] * C3_16 - src[24] * C5_16;
        s6 = src[24] * C3_16 + src[40] * C5_16;
        s7 = src[56] * C7_16 + src[ 8] * C1_16;
        t4 = s4 + s5;
        t5 = s4 - s5;
        t6 = s7 - s6;
        t7 = s6 + s7;

        s5 = (t6 - t5) * 41 / 58;			// 1/sqrt(2)
        s6 = (t5 + t6) * 41 / 58;			// 1/sqrt(2)

        dst[ 0] = ((s0 + t7) >> 15);		// 寢壥偼 1/2 偵側偭偰傞両
        dst[ 8] = ((s1 + s6) >> 15);		// signed 傪 unsigned偵僉儍僗僩
        dst[16] = ((s2 + s5) >> 15);		// 偟偰傞偺傪拲堄偡傞帠丅
        dst[24] = ((s3 + t4) >> 15);
        dst[32] = ((s3 - t4) >> 15);
        dst[40] = ((s2 - s5) >> 15);
        dst[48] = ((s1 - s6) >> 15);
        dst[56] = ((s0 - t7) >> 15);

        src++;
        dst++;
    }
}

#endif

// 晞崋壔偝傟偨悢抣傪尦偵栠偡

int CJPEGLS::get_value(int size) {
    int val = 0;
    if(size == 0)
        val = 0;
    else
    {
        val = get_bits(size);
        if (!(val & (1<<(size-1))))
            val = val - (1 << size) + 1;
    }
    return val;
}

// ---- 僽儘僢僋偺僨僐乕僪 ---
// 僴僼儅儞僨僐乕僪亄媡検巕壔亄媡僕僌僓僌
int CJPEGLS::decode_huff(int scan,int *block)
{
    int size, val, run, index;
    int *pQt = (int *)(qt[scan_qt[scan]]);

    // DC
    size = get_huff(0,scan_dc[scan]);
    if(size < 0)
        return 0;

    val = get_value(size);
    mcu_preDC[scan] += val;
    block[0] = mcu_preDC[scan] * pQt[0];

    //AC暅崋
    index = 1;
    while(index<64)
    {
        size = get_huff(1,scan_ac[scan]);
        if(size < 0)
            break;
        // EOB
        if(size == 0)
            break;

        // RLE
        run  = (size>>4)&0xF;
        size = size & 0x0F;

        val = get_value(size);

        // ZRL
        while (run-- > 0)
            block[ zigzag_table[index++] ] = 0;

        block[ zigzag_table[index] ] = val * pQt[index];
        index++;
    }
    while(index<64)
        block[zigzag_table[index++]]=0;
    return 0;
}

// 僽儘僢僋 (曗娫偐偗傞偵偼丄偙偙偱)
// 儕僒儞僾儕儞僌
#define INDEX(X,Y) (((Y)*8)+(X))
void CJPEGLS::mcu_bitblt(int *src,int *dest,int width,
                       int x0,int y0,int x1,int y1)
{
    int w,h,t;
    int x,y,x2,y2;
    int dx,dy;
    int c1,c2,c3,c4;
    int vx1,vx2;
    w = x1 - x0;
    h = y1 - y0;

    for(y=y0;y<y1;y++) {
        t = (y-y0) * 8;
        y2 = t / h;
        dy = t % h;
        for(x=x0;x<x1;x++) {
            t = (x-x0) * 8;
            x2 = t / w;
            dx = t % w;
            if(x2+1 > 7){
                c1 = src[INDEX(x2,y2)];
                c2 = c1;
                if(y2+1 > 7){
                    c3 = c1;
                    c4 = c1;
                } else {
                    c3 = src[INDEX(x2,y2+1)];
                    c4 = c3;
                }
            }
            else{
                c1 = src[INDEX(x2  ,y2)];
                c2 = src[INDEX(x2+1,y2)];
                if(y2+1 > 7){
                    c3 = c1;
                    c4 = c2;
                } else {
                    c3 = src[INDEX(x2  ,y2+1)];
                    c4 = src[INDEX(x2+1,y2+1)];
                }
            }
            vx1 = (c1 * (w-dx) + c2 * dx) / w;
            vx2 = (c3 * (w-dx) + c4 * dx) / w;
            dest[(y*width) + x] = (vx1 *(h-dy) + vx2 * dy) / h;
        }
    }
}
#undef INDEX
// MCU堦屄曄姺
void CJPEGLS::decode_mcu(void)
{
    int scan,val;
    int h,v;
    int *p,hh,vv;
    int block[64],dest[64];

    // mcu_width x mcu_height僒僀僘偺僽儘僢僋傪揥奐
    for(scan=0;scan<scan_count;scan++)
    {
        hh = scan_h[scan];
        vv = scan_v[scan];
        //printf("scan %d (%dx%d)\n",scan,hh,vv);
        for(v=0;v<vv;v++){
            for(h=0;h<hh;h++){

                // 僽儘僢僋(8x8)偺僨僐乕僪
                val = decode_huff(scan , block);

                // 媡DCT
                idct(block,dest);

                // 彂偒崬傒僶僢僼傽
                p = mcu_buf + (scan * 32 * 32);

                // 奼戝揮憲
                mcu_bitblt(dest , p ,
                                mcu_width,
                                mcu_width * h / hh,
                                mcu_height* v / vv,
                                mcu_width * (h+1) / hh,
                                mcu_height* (v+1) / vv);
            }
        }
    }
}

// YCrCb=>RGB

void CJPEGLS::decode_yuv(int h,int v,unsigned char *rgb)
{
    int x0,y0,x,y,x1,y1;
    int *py,*pu,*pv;
    int Y,U,V,k;
    int R,G,B;
    int mw,mh,w;

    mw = mcu_width;
    mh = mcu_height;
    w = width;

    x0 = h * max_h * 8;
    y0 = v * max_v * 8;

    x1 = width - x0;
    if(x1 > mw)
        x1 = mw;
    y1 = height - y0;
    if(y1 > mh)
        y1 = mh;

    py = mcu_buf;
    pu = mcu_buf + 1024;
    pv = mcu_buf + 2048;


    for(y=0;y<y1;y++){
        for(x=0;x<x1;x++){
            k = y*mw+x;

            Y = py[ k ];
            U = pu[ k ];
            V = pv[ k ];

            R = 128 + ((Y*0x1000 + V*0x166E) / 4096);
            R = (R & 0xffffff00) ? (R >> 24) ^ 0xff : R;

            G = 128 + ((Y*0x1000 - V*0x0B6C) / 4096);
            G = (G & 0xffffff00) ? (G >> 24) ^ 0xff : G;

            B = 128 + ((Y*0x1000 - V*4 + U*0x1C59) / 4096);
            B = (B & 0xffffff00) ? (B >> 24) ^ 0xff : B;

            rgb[((y0+y)*w + (x0+x))*3  ] = R;
            rgb[((y0+y)*w + (x0+x))*3+1] = G;
            rgb[((y0+y)*w + (x0+x))*3+2] = B;
        }
    }
}

void CJPEGLS::decode(unsigned char *rgb)
{
    int h_unit,v_unit;
    int mcu_count,h,v;

    // MCU僒僀僘寁嶼
    decode_init();

    h_unit = width / mcu_width;
    v_unit = height/ mcu_height;
    if((width  % mcu_width) > 0){
        h_unit++;
    }
    if((height % mcu_height) > 0){
        v_unit++;
    }

    // 1僽儘僢僋揥奐偡傞偐傕偟傟側偄
    mcu_count = 0;
    for(v=0;v<v_unit;v++){
        for(h=0;h<h_unit;h++){
            mcu_count++;

            decode_mcu();
            decode_yuv(h,v,rgb);

            if(interval > 0 && mcu_count >= interval){

                // RSTm儅乕僇傪偡偭旘偽偡(FF hoge)
                // hoge偼撉傒旘偽偟偰傞偺偱丄FF傕旘偽偡

                bit_remain -= (bit_remain & 7);
                bit_remain -= 8;

                //printf("remain:%d\n",bit_remain);
                mcu_preDC[0] = 0;
                mcu_preDC[1] = 0;
                mcu_preDC[2] = 0;
                mcu_count = 0;
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -