• JPEG解码实现


      这几天接了个任务,把JPEG转为BMP。我在网上搜了很多代码,最后决定自己来写,写到后面已经变成大段借用其他人的代码了。

      下面来说说这里面的几个难点,文后会附上代码。

       1 IDCT, 反离散余弦变换,这个找了很多现成的代码,最后使用了stb_image的代码拷过来改了下。

       2 resample,网上流行很广的文章里一笔带过,据那篇文章弄出来发现锯齿严重,和原图有差别,最后拷stb_image的代码来改的。

       3 图片转为RGB和色调有点差别,后来交换了下Cr,Cb就正常了,我也不知道咋搞的。

    我觉得这点代码还是挺有意思的,huffman, RLE, 字节流的处理等等.

    另贴一个参考的文章 http://www.cnblogs.com/leaven/archive/2010/04/06/1705846.html

     不可以用附件九直接写下面了。

    #include "stdio.h"
    #include "string.h"
    #include "assert.h"
    #include "stdlib.h"
    
    #define jpeg_printf
    
    #define getbit(k, i) (((k)>>(i))&1)
    #define high(k)      ((k)>>4)
    #define low(k)       ((k)&0xf)
    
    #ifndef _DEBUG
    #undef  assert
    #define assert(x) if (!(x)){ return 0; }
    #endif
    
    typedef unsigned char uint8;
    
    typedef struct color_t
    {
        uint8 y;
        uint8 cr;
        uint8 cb;
    }color;
    
    typedef struct _huffman_node {
        struct _huffman_node* l;
        struct _huffman_node* r;
        int w;
    }huffman_node;
    
    static huffman_node*
    huffman_node_create() {
        huffman_node* p;
    
        p = (huffman_node*)malloc(sizeof(huffman_node));
        p->l = 0;
        p->r = 0;
        p->w = -1;
        return p;
    }
    
    static void
    huffman_node_visit(huffman_node* p, int c, int l) {
        int i;
        if (p == 0) {
            return;
        }
    
        if (p->l == 0 && p->r == 0) {
            for (i = l - 1; i >= 0; i--) {
                if (getbit(c, i)) {
                    printf("1");
                }
                else {
                    printf("0");
                }
            }
            printf(" 0x%02x
    ", p->w);
        }
        else {
            huffman_node_visit(p->l, c<<1, l + 1);
            huffman_node_visit(p->r, (c<<1) + 1, l + 1);
        }
    }
    
    static void
    huffman_node_release(huffman_node* node) {
        if (node != 0) {
            huffman_node_release(node->l);
            huffman_node_release(node->r);
            free(node);
        }
    }
    
    typedef struct _huffman {
        huffman_node* r;
        huffman_node* p;
    
        int l;
        int c;
    }huffman;
    
    #define huffman_reset(h) h->p = h->r
    
    static huffman*
    huffman_create() {
        huffman* h;
        
        h = (huffman*)malloc(sizeof(huffman));
        h->r = huffman_node_create();
        h->l = -1;
        return h;
    }
    
    static int
    huffman_match(huffman* h, int x) {
        if (x) {
            h->p = h->p->r;
        }
        else {
            h->p = h->p->l;
        }
    
        if (h->p == 0) {
            return -1;
        }
        return h->p->l == 0 && h->p->r == 0; 
    }
    
    static void
    huffman_insert(huffman* h, int l, int v) {
        int i;
        huffman_node* p;
    
        if (h->l == -1) {
            h->c = 0;
            h->l = l;
        }
        else {
            h->c = (h->c + 1)<<(l - h->l);
            h->l = l;
        }
    
        p = h->r;
        for (i = l - 1; i >= 0; i--) {
            if (getbit(h->c, i)) {
                if (p->r == 0) {
                    p->r = huffman_node_create();
                }
                p = p->r;
            }
            else {
                if (p->l == 0) {
                    p->l = huffman_node_create();
                }
                p = p->l;
            }
        }
        p->w = v;
    }
    
    static void
    huffman_print(huffman* h) {
        huffman_node_visit(h->r, 0, 0);
    }
    
    static void
    huffman_release(huffman* h) {
        if (h != 0) {
            huffman_node_release(h->r);
            free(h);
        }
    }
    
    typedef struct _color_comp {
        int qi;
        int di;
        int ai;
        int df;
    }color_comp;
    
    typedef struct _jpeg {
        int width;
        int height;
    
        uint8 qt[4][64];
    
        huffman* dh[4];
        huffman* ah[4];
    
        color_comp cc[4];
    
        color* pixels;
    
        uint8* data;
        int    size;
    
        int ei;
        int di;
        int rr;
    }jpeg;
    
    static int
    jpeg_decode_huffman(jpeg* jpg, uint8* p) {
        huffman* h;
        uint8* q;
        int i, j, l, k, f, d;
        int t[16];
    
        q = jpg->data + jpg->size;
        assert(p + 2 <= q);
        l = (p[0]<<8) + p[1];
        assert(p + l <= q);
        for (k = 2; k < l;) {
            d = low(p[k]);
            f = high(p[k]);
            assert(d <= 3 && f <= 1);
    
            if (f) {
                h = jpg->ah[d];
            }
            else {
                h = jpg->dh[d];
            }
    
            k++;
            assert(p + k + 16 <= q && k + 16 <= l);
            for (i = 0; i < 16; i++) {
                t[i] = p[k++];
            }
    
            for (i = 0; i < 16; i++) {
                assert(p + k + t[i] <= q && k + t[i] <= l);
                for (j = 0; j < t[i]; j++) {
                    huffman_insert(h, i + 1, p[k++]);
                }
            }
        }
        return 1;
    }
    
    static int
    jpeg_prepare(jpeg* jpg) {
        int i, j, l, p, id, qi, tp, s;
        uint8* data;
        
        data = jpg->data;
        if (data[0] != 0xff || data[1] != 0xd8) {
            return 0;
        }
    
        s = jpg->size;
        for (i = 2; i < s;) {
            if (data[i++] == 0xff) {
                assert(i + 3 <= s);
    
                switch (data[i++]) {
                case 0xdb: {
                        l = (data[i]<<8) + data[i + 1];
                        assert(i + l <= s);
                        for (p = i + 2; p < i + l;) {
                            id = low(data[p]);
                            assert(id <= 3 && high(data[p]) == 0);
                            p++;
                            assert(p + 64 <= s && p + 64 <= i + l);
                            for (j = 0; j < 64; j++) {
                                jpg->qt[id][j] = data[p++];
                            }
                        }
                    }
                    break;
                case 0xc0: {
                        l = (data[i]<<8) + data[i + 1];
                        assert(l == 17 && i + 17 <= s && data[i + 2] == 8);
    
                        p = i + 3;
                        jpg->height = (data[p]<<8) + data[p + 1];
                        p += 2;
                        jpg->width = (data[p]<<8) + data[p + 1];
                        p += 2;
                        assert(low(jpg->height) == 0 && low(jpg->width) == 0 && data[p] == 3);
                        p++;
                        
                        id = data[p];
                        qi = data[p + 2];
                        assert(id == 1 && data[p + 1] == 0x22 && qi <= 3);
                        jpg->cc[id].qi = qi;
                        p += 3;
    
                        id = data[p];
                        qi = data[p + 2];
                        assert(id == 2 && data[p + 1] == 0x11 && qi <= 3);
                        jpg->cc[id].qi = qi;
                        p += 3;
    
                        id = data[p];
                        qi = data[p + 2];
                        assert(id == 3 && data[p + 1] == 0x11 && qi <= 3);
                        jpg->cc[id].qi = qi;
                    }
                    break;
                case 0xc4:
                    if (!jpeg_decode_huffman(jpg, data + i)) {
                        return 0;
                    }
                    break;
                case 0xdd: {
                        assert(0);
                    }
                case 0xda: {
                        l = (data[i]<<8) + data[i + 1];
                        assert(l == 12 && i + l <= s);
                        
                        p = i + 2;
                        assert(data[p] == 3);
                        p++;
    
                        id = data[p];
                        tp = data[p + 1];
                        assert(id == 1 && low(tp) <= 3 &&high(tp) <= 3);
                        jpg->cc[id].ai = low(tp);
                        jpg->cc[id].di = high(tp);
                        p += 2;
    
                        id = data[p];
                        tp = data[p + 1];
                        assert(id == 2 && low(tp) <= 3 &&high(tp) <= 3);
                        jpg->cc[id].ai = low(tp);
                        jpg->cc[id].di = high(tp);
                        p += 2;
    
                        id = data[p];
                        tp = data[p + 1];
                        assert(id == 3 && low(tp) <= 3 &&high(tp) <= 3);
                        jpg->cc[id].ai = low(tp);
                        jpg->cc[id].di = high(tp);
    
                        jpg->ei = i + l;
                        return 1;
                    }
                    break;
                default:
                    break;
                }
                i += (data[i]<<8) + data[i + 1];
            }
        }
        return 0;
    }
    
    void* 
    jpeg_load(const char* file) {
        FILE* fd;
        jpeg* jpg;
        int i;
    
        jpg = (jpeg*)malloc(sizeof(jpeg));
        memset(jpg, 0, sizeof(jpeg));
    
        for (i = 0; i < 4; i++) {
            jpg->dh[i] = huffman_create();
            jpg->ah[i] = huffman_create();
        }
    
        fd = fopen(file, "rb");
        if (fd == 0) {
            jpeg_free(jpg);
            return 0;
        }
    
        //文件读写
        fseek(fd, 0 ,SEEK_END);
        jpg->size = ftell(fd);
        jpg->data = (uint8*)malloc(jpg->size * sizeof(uint8));
        
        fseek(fd, 0, SEEK_SET);
        fread(jpg->data, jpg->size, 1, fd);
        fclose(fd);
    
        if (!jpeg_prepare(jpg)) {
            jpeg_free(jpg);
            return 0;
        }
        return jpg;
    }
    
    void
    jpeg_free(void* ctx) {
        int i;
        jpeg* jpg = (jpeg*)ctx;
        if (jpg->pixels != 0) {
            free(jpg->pixels);
        }
        if (jpg->data != 0) {
            free(jpg->data);
        }
    
        for (i = 0; i < 4; i++) {
            huffman_release(jpg->dh[i]);
            huffman_release(jpg->ah[i]);
        }
        free(jpg);
    }
    
    int
    jpeg_query(void* ctx, int* width, int* height) {
        jpeg* jpg = (jpeg*)ctx;
        *width  = jpg->width;
        *height = jpg->height;
        return 1;
    }
    
    //-1 结束
    //-2 错误
    static
    int jpeg_nextbyte(jpeg* jpg) {
        int x;
        if (jpg->ei >= jpg->size) {
            return -1;
        }
    
        x = jpg->data[jpg->ei];
        if (x != 0xff) {
            jpg->ei++;
            return x;
        }
        else {
            jpg->ei++;
            if (jpg->ei >= jpg->size) {
                return -1;
            }
    
            x = jpg->data[jpg->ei];
            if (x == 0) {
                jpg->ei++;
                return 0xff;
            }
            else if (x == 0xff)
            {
                return jpeg_nextbyte(jpg);
            }
            else if (x < 0xd0 || x > 0xd9) {
                jpg->ei++;
                return x;
            }
            else {
                return -2;
            }
        }
        return -2;
    }
    
    static int
    jpeg_nextbit(jpeg* jpg) {
        int x;
        if (jpg->di == 0 && (jpg->rr = jpeg_nextbyte(jpg)) < 0) {
            return -1;
        }
        x = getbit(jpg->rr, 7 - jpg->di);
        jpg->di = (jpg->di + 1) % 8;
        return x;
    }
    
    static int
    jpeg_decode_byte(jpeg* jpg, huffman* h) {
        int x, m;
        huffman_reset(h);
    
        while ((x = jpeg_nextbit(jpg)) >= 0) {
            m = huffman_match(h, x);
            if (m == -1) {
                return -1;
            }
            else if (m) {
                jpeg_printf("x%x ", h->p->w);
                return h->p->w;
            }
        }
        return -1;
    }
    
    static int
    jpeg_read(jpeg* jpg, int len, int* x) {
        int i, v, s, b;
    
        if ((s = jpeg_nextbit(jpg)) < 0) {
            return 0;
        }
    
        v = 0;
        for (i = 1; i < len; i++) {
            if ((b = jpeg_nextbit(jpg)) < 0) {
                return 0;
            }
            v = (v<<1) + b;
        }
        if (s == 0) {
            *x = -(1<<len) + 1 + v;
        }
        else {
            *x =  (1<<(len - 1)) + v;
        }
        jpeg_printf("r%d ", *x);
        return 1;
    }
    
    //region copy from stb_image.cpp
    #pragma region idct
    
    uint8 clamp(int x)
    {
        if ((unsigned int) x > 255) {
            if (x < 0) return 0;
            if (x > 255) return 255;
        }
        return (uint8) x;
    }
    
    #define f2f(x)  (int) (((x) * 4096 + 0.5))
    #define fsh(x)  ((x) << 12)
    
    #define IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7)        
        int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; 
        p2 = s2;                                    
        p3 = s6;                                    
        p1 = (p2+p3) * f2f(0.5411961f);             
        t2 = p1 + p3*f2f(-1.847759065f);            
        t3 = p1 + p2*f2f( 0.765366865f);            
        p2 = s0;                                    
        p3 = s4;                                    
        t0 = fsh(p2+p3);                            
        t1 = fsh(p2-p3);                            
        x0 = t0+t3;                                 
        x3 = t0-t3;                                 
        x1 = t1+t2;                                 
        x2 = t1-t2;                                 
        t0 = s7;                                    
        t1 = s5;                                    
        t2 = s3;                                    
        t3 = s1;                                    
        p3 = t0+t2;                                 
        p4 = t1+t3;                                 
        p1 = t0+t3;                                 
        p2 = t1+t2;                                 
        p5 = (p3+p4)*f2f( 1.175875602f);            
        t0 = t0*f2f( 0.298631336f);                 
        t1 = t1*f2f( 2.053119869f);                 
        t2 = t2*f2f( 3.072711026f);                 
        t3 = t3*f2f( 1.501321110f);                 
        p1 = p5 + p1*f2f(-0.899976223f);            
        p2 = p5 + p2*f2f(-2.562915447f);            
        p3 = p3*f2f(-1.961570560f);                 
        p4 = p4*f2f(-0.390180644f);                 
        t3 += p1+p4;                                
        t2 += p2+p3;                                
        t1 += p2+p4;                                
        t0 += p1+p3;
    
    static void idct_block(uint8 *out, int data[64])
    {
        int i,val[64],*v=val;
        uint8 *o;
        int *d = data;
    
        for (i=0; i < 8; ++i,++d, ++v) {
            if (d[8]==0 && d[16]==0 && d[24]==0 && d[32]==0
                && d[40]==0 && d[48]==0 && d[56]==0) {
                    int dcterm = d[0]<< 2;
                    v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm;
            } else {
                IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56])
                x0 += 512; x1 += 512; x2 += 512; x3 += 512;
                v[ 0] = (x0+t3) >> 10;
                v[56] = (x0-t3) >> 10;
                v[ 8] = (x1+t2) >> 10;
                v[48] = (x1-t2) >> 10;
                v[16] = (x2+t1) >> 10;
                v[40] = (x2-t1) >> 10;
                v[24] = (x3+t0) >> 10;
                v[32] = (x3-t0) >> 10;
            }
        }
    
        for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=8) {
            IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7])
            x0 += 65536 + (128<<17);
            x1 += 65536 + (128<<17);
            x2 += 65536 + (128<<17);
            x3 += 65536 + (128<<17);
    
            o[0] = clamp((x0+t3) >> 17);
            o[7] = clamp((x0-t3) >> 17);
            o[1] = clamp((x1+t2) >> 17);
            o[6] = clamp((x1-t2) >> 17);
            o[2] = clamp((x2+t1) >> 17);
            o[5] = clamp((x2-t1) >> 17);
            o[3] = clamp((x3+t0) >> 17);
            o[4] = clamp((x3-t0) >> 17);
        }
    }
    
    #pragma endregion
    
    static
    int invZ[64] = {
            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};
    
    static int
    jpeg_decode_block(jpeg* jpg, uint8* block, int ci) {
        int cc[64];
        int aa[64];
        huffman *dh, *ah;
        uint8* qt;
        int i, t, r, v;
    
        dh = jpg->dh[jpg->cc[ci].di];
        ah = jpg->ah[jpg->cc[ci].ai];
        qt = jpg->qt[jpg->cc[ci].qi];
        memset(cc, 0, 64 * sizeof(cc[0]));
    
        //直流分量
        jpeg_printf("
    d:%d
    ", jpg->cc[ci].di);
        if ((t = jpeg_decode_byte(jpg, dh)) < 0) {
            return 0;
        }
        if (t > 0) {
            assert(jpeg_read(jpg, t, &r));
            cc[0] = r;
        }
    
        cc[0] += jpg->cc[ci].df;
        jpg->cc[ci].df = cc[0];
        cc[0] = (short)cc[0];
    
        //交流分量
        jpeg_printf("
    a:%d
    ", jpg->cc[ci].ai);
        for (i = 1; i < 64;) {
            if ((r = jpeg_decode_byte(jpg, ah)) < 0) {
                return 0;
            }
    
            if (low(r) == 0) {
                if (r != 0xf0) {
                    break;
                }
                i += 16;
            }
            else {
                i += high(r);
                assert(jpeg_read(jpg, low(r), &v));
                if (i < 64) {
                    cc[i++] = v;
                }
            }
        }
    
        //反量化
        for (i = 0; i < 64; i++) {
            cc[i] *= qt[i];
        }
    
        //反Zig
        for (i = 0; i < 64; i++) {
            aa[invZ[i]] = cc[i];
        }
    
        //反离散余弦变换
        idct_block(block, aa);
        return 1;
    }
    
    #define div16(x) ((uint8) ((x) >> 4))
    #define div4(x) ((uint8) ((x) >> 2))
    
    color* jpeg_data(void* ctx) {
        jpeg* jpg = (jpeg*)ctx;
        return jpg->pixels;
    }
    
    static int
    jpeg_process_mcu(jpeg* jpg, int l, int t, 
                uint8* py, uint8* pcr, uint8* pcb) {
        int i, w;
        uint8 c[64];
    
        w = jpg->width;
        assert(jpeg_decode_block(jpg, c, 1));
        for (i = 0; i < 64; i++) {
            py[(t + i / 8) * w + l + i % 8] = c[i];
        }
        assert(jpeg_decode_block(jpg, c, 1));
        for (i = 0; i < 64; i++) {
            py[(t + i / 8) * w + l + 8 + i % 8] = c[i];
        }
        assert(jpeg_decode_block(jpg, c, 1));
        for (i = 0; i < 64; i++) {
            py[(t + 8 + i / 8) * w + l + i % 8] = c[i];
        }
        assert(jpeg_decode_block(jpg, c, 1));
        for (i = 0; i < 64; i++) {
            py[(t + 8 + i / 8) * w + l + 8 + i % 8] = c[i];
        }
        assert(jpeg_decode_block(jpg, c, 2));
        for (i = 0; i < 64; i++) {
            pcr[(t /2 + i / 8) * w / 2 + l / 2 + i % 8] = c[i];
        }
        assert(jpeg_decode_block(jpg, c, 3));
        for (i = 0; i < 64; i++) {
            pcb[(t / 2 + i / 8) * w / 2  + l / 2 + i % 8] = c[i];
        }
        return 1;
    
    }
    
    //resample copy from stbi_image.cpp
    #pragma region resample
    
    typedef struct {
        uint8 *line0,*line1;
        int hs,vs;   // expansion factor in each axis
        int w_lores; // horizontal pixels pre-expansion 
        int ystep;   // how far through vertical expansion we are
        int ypos;    // which pre-expansion row we're on
    } resample;
    
    static void
    resampleCr(color* colors, uint8* in_near, uint8* in_far, int w) {
        int i, t0, t1;
    
        t1 = 3 * in_near[0] + in_far[0];
        colors[0].cr = div4(t1 + 2);
        for (i=1; i < w; ++i) {
            t0 = t1;
            t1 = 3 * in_near[i] + in_far[i];
            colors[i * 2-1].cr = div16(3*t0 + t1 + 8);
            colors[i * 2].cr   = div16(3*t1 + t0 + 8);
        }
        colors[w * 2 - 1].cr = div4(t1+2);
    }
    
    static void
    resampleCb(color* colors, uint8* in_near, uint8* in_far, int w) {
        int i, t0, t1;
    
        t1 = 3 * in_near[0] + in_far[0];
        colors[0].cb = div4(t1 + 2);
        for (i=1; i < w; ++i) {
            t0 = t1;
            t1 = 3 * in_near[i] + in_far[i];
            colors[i * 2-1].cb = div16(3*t0 + t1 + 8);
            colors[i * 2].cb   = div16(3*t1 + t0 + 8);
        }
        colors[w * 2 - 1].cb = div4(t1+2);
    }
    #pragma endregion
    
    int
    jpeg_decode(void* ctx) {
        uint8 *py, *pcr, *pcb;
        int w, h, i, j;
        jpeg* p;
        color* px;
        resample sample;
    
        p   = (jpeg*)ctx;
        w   = p->width;
        h   = p->height;
        py  = (uint8*)malloc(w * h * sizeof(uint8));
        pcr = (uint8*)malloc(w * h * sizeof(uint8) / 4);
        pcb = (uint8*)malloc(w * h * sizeof(uint8) / 4);
    
        for (i = 0; i < h; i += 16) {
            for (j = 0; j < w; j += 16) {
                if (!jpeg_process_mcu(p, j,
                          i, py, pcr, pcb)) {
                    free(py); free(pcr); free(pcb);
                    return 0;
                }
            }
        }
    
        px = (color*)malloc(w * h * sizeof(color));
        for (i = w * h - 1; i >= 0; i--) {
            px[i].y = py[i];
        }
    
        sample.hs = sample.vs = 2;
        sample.w_lores = w / 2;
        sample.ystep = 1;
        sample.line0 = pcr;
        sample.line1 = pcr;
        sample.ypos  = 0;
    
        for (i = 0; i < h; i++) {
            color* out = px + i * w;
            int y_bot = sample.ystep >= (sample.vs >> 1);
            resampleCr(out, 
                 y_bot ? sample.line1 : sample.line0,
                 y_bot ? sample.line0 : sample.line1,
                 sample.w_lores);
    
            if (++sample.ystep >= sample.vs) {
                sample.ystep = 0;
                sample.line0 = sample.line1;
                if (++sample.ypos < h / 2)
                    sample.line1 += sample.w_lores;
            }
        }
    
        sample.ystep = 1;
        sample.line0 = pcb;
        sample.line1 = pcb;
        sample.ypos  = 0;
    
        for (i = 0; i < h; i++) {
            color* out = px + i * w;
            int y_bot = sample.ystep >= (sample.vs >> 1);
            resampleCb(out, 
                y_bot ? sample.line1 : sample.line0,
                y_bot ? sample.line0 : sample.line1,
                sample.w_lores);
    
            if (++sample.ystep >= sample.vs) {
                sample.ystep = 0;
                sample.line0 = sample.line1;
                if (++sample.ypos < h / 2)
                    sample.line1 += sample.w_lores;
            }
        }
        free(py); free(pcr); free(pcb);
        p->pixels = px;
        return 1;
    }
    
    void jpeg_save(const char* file,int desW, int desH, color* colors)
    {
        int desBufSize = ((desW * BITCOUNT + 31) / 32) * 4 * desH;
        int desLineSize = ((desW * BITCOUNT + 31) / 32) * 4;    
        BYTE *desBuf = new BYTE[desBufSize];
    
        for (int i = 0; i < desH; i++)
        {
            int x = i * desLineSize;
            for (int j = 0; j < desW; j++)
            {
                int y_fixed = (colors->y << 16) + 32768; // rounding
                int r,g,b;
                int cr = colors->cr - 128;
                int cb = colors->cb - 128;
                r = y_fixed + cb*float2fixed(1.40200f);
                g = y_fixed - cb*float2fixed(0.71414f) - cr*float2fixed(0.34414f);
                b = y_fixed                            + cr*float2fixed(1.77200f);
                r >>= 16;
                g >>= 16;
                b >>= 16;
                if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
                if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
                if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
    
                desBuf[x++] = b;
                desBuf[x++] = g;
                desBuf[x++] = r;
    
                colors++;
            }
        }
    
        HFILE hfile = _lcreat(file.c_str,0);
        BITMAPFILEHEADER nbmfHeader = { 0 };    
        nbmfHeader.bfType = 0x4D42;
        nbmfHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + desBufSize;
        nbmfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
        BITMAPINFOHEADER bmi = { 0 };
        bmi.biSize=sizeof(BITMAPINFOHEADER); 
        bmi.biWidth = desW; 
        bmi.biHeight= -desH; 
        bmi.biPlanes=1;
        bmi.biBitCount=BITCOUNT;
    
        _lwrite(hfile,(LPCSTR)&nbmfHeader,sizeof(BITMAPFILEHEADER));
        _lwrite(hfile,(LPCSTR)&bmi,sizeof(BITMAPINFOHEADER));
        _lwrite(hfile,(LPCSTR)desBuf,desBufSize);
        _lclose(hfile);
    }
  • 相关阅读:
    Java基础之IO框架
    Java基础之RTTI 运行时类型识别
    Java进阶之多线程
    Java进阶之内存管理与垃圾回收
    Java进阶之网络编程
    springcloud的Hystrix turbine断路器聚合监控实现(基于springboot2.02版本)
    springmvc,controller层在接收浏览器url传来的参数带中文乱码问题。
    Cannot read lifecycle mapping metadata for artifact org.apache.maven.plugins:mav问题
    springboot2.x自定义拦截把static静态文件给拦截的坑
    Eclipse启动发生的错误:An internal error occurred during: "Initializing Java Tooling".
  • 原文地址:https://www.cnblogs.com/cmzbjl/p/3167620.html
Copyright © 2020-2023  润新知