📄 jpeg.c
字号:
dc_node = dec->huffman_node + (dc << 8); ac_node = dec->huffman_node + (ac << 8) + 512; /* First step: huffman-decode 1 DC coefficient */ data = huffman_decode(dec, dc_node); *old_dc += get_bits(dec, data & 0xf); dat[0] = *old_dc; coef = 1; do { /* Second step: huffman-decode 63 AC coefficients */ data = huffman_decode(dec, ac_node); if (data == -2) data = 0; else if (data == -1) { /* Bad block */ for (i=0; i<64; i++) dat[i] = 0; for (i=0; i<8; i++) dat[(i<<3)|i] = 255; for (i=0; i<8; i++) dat[(i<<3)|(7-i)] = 255; return 1; } num_zeros = data >> 4; num_bits = data & 0xf; val = get_bits(dec, num_bits); /* Third step: run length decoding */ if ((num_zeros == 0) && (num_bits == 0)) { /* end of block */ for (i=coef; i<64; i++) dat[i] = 0; break; } else if ((num_zeros == 15) && (num_bits == 0)) { /* 16 zeros RLE */ for (i=0; i<16; i++) dat[coef + i] = 0; coef += 16; } else { /* normal zero run length */ for (i=0; i<num_zeros && coef<64; i++) dat[coef++] = 0; if (coef >= 64) break; dat[coef++] = val; } } while (coef < 64); /* Fourth step: zig-zag reordering */ zigzag_reorder(dat); /* Fifth step: dequantization and inverse discrete cosine transform */ do_idct(dat, dec->dequant + (qt << 6)); return 0;}// CHANGED - copied from include/allegro/internal/alconfig.h//#define AL_INLINE(type, name, args, code) extern inline type name args code// CHANGED - copied from src/inline.c// #define AL_INLINE(type, name, args, code) type name args code// CHANGED - copied from include/allegro/inline/color.inl#define _rgb_r_shift_24 16#define _rgb_g_shift_24 8#define _rgb_b_shift_24 0int makecol24(int r, int g, int b) { return ((r << _rgb_r_shift_24) | (g << _rgb_g_shift_24) | (b << _rgb_b_shift_24));}/* putpixel_lc: * Draws a pixel onto a 24bit bitmap, given its luminance and chrominance. */static void putpixel_lc(BITMAP *bmp, int xx, int yy, int y, int cb, int cr){ int r, g, b; r = (int)((double)y + 1.402 * ((double)cr - 128.0)); g = (int)((double)y - 0.34414 * ((double)cb - 128.0) - 0.71414 * ((double)cr - 128.0)); b = (int)((double)y + 1.772 * ((double)cb - 128.0)); r = MID(0, r, 255); g = MID(0, g, 255); b = MID(0, b, 255); putpixel(bmp, xx, yy, makecol24(r, g, b));}DECODER_DATA dec;/* load_memory_jpg: * Decodes a jpg image from a memory chunk. */BITMAP *load_memory_jpg(void *data, RGB *pal){ BITMAP *bmp; PALETTE tmppal; int y1[64], y2[64], y3[64], y4[64], cb[64], cr[64]; int dc_y, dc_cb, dc_cr; int i, j, x, y, dest_depth, hue; memset(&dec, 0, sizeof(dec)); if (!pal) pal = tmppal; dec.data_start = (unsigned char *)data; dec.data = dec.data_start; /* * Scans the jpg data for markers, until the SOS marker is found. */ do { if (*dec.data++ == 0xff) { switch (*dec.data) { case SOF0: case SOF1: dec.flags |= SOF0_DEFINED; if (read_sof0(&dec)) return NULL; break; case DHT: dec.flags |= DHT_DEFINED; read_dht(&dec); break; case SOI: dec.flags |= SOI_DEFINED; dec.data++; break; case SOS: dec.flags |= SOS_DEFINED; if (read_sos(&dec)) return NULL; break; case DQT: dec.flags |= DQT_DEFINED; if (read_dqt(&dec)) return NULL; break; case DRI: dec.flags |= DRI_DEFINED; dec.data += 5; break; case APP0: dec.flags |= APP0_DEFINED; if (read_app0(&dec)) return NULL; break; case COM: dec.data++; i = NEXTWORD(&dec); dec.data += i; break; default: return NULL; } } /* * Continue scanning for 10000 bytes (more than enough for a header eh?) * or until all the proper markers have been found. */ } while ((dec.data <= dec.data_start + 10000) && !(dec.flags & SOS_DEFINED)); /* * Checks if the SOF0, DHT, SOI, SOS, DQT and APP0 markers are all there. */ if ((dec.flags & JFIF_OK) != JFIF_OK) return NULL; // TODO - check this - src/graphics.c dest_depth = 32; // FIXIT // dest_depth = _color_load_depth(24, FALSE); // TODO - straightforward - src/graphics.c // bmp = (BITMAP*) 0xf80000; // FIXIT bmp = create_bitmap_ex(dest_depth, dec.width, dec.height); if (!bmp) return NULL; x = y = 0; dc_y = dc_cb = dc_cr = 0; dec.bits = 8; dec.byte = *dec.data;#ifndef NATIVE_COMPILE print("Decoding ");#endif switch(dec.components) { case 3: /* * Image has three components (1 for luminance and 2 for chrominance); * this means it's a colored image. */ switch(dec.samples_y) { case 4: do {#ifndef NATIVE_COMPILE print (".");#endif /* 1st case: * chrominance is taken every two pixels (horizontally and * vertically), and luminance for every pixel. */ decode_block(&dec, y1, dec.dc_y, dec.ac_y, dec.quant_y, &dc_y); decode_block(&dec, y2, dec.dc_y, dec.ac_y, dec.quant_y, &dc_y); decode_block(&dec, y3, dec.dc_y, dec.ac_y, dec.quant_y, &dc_y); decode_block(&dec, y4, dec.dc_y, dec.ac_y, dec.quant_y, &dc_y); decode_block(&dec, cb, dec.dc_cbcr, dec.ac_cbcr, dec.quant_cbcr, &dc_cb); decode_block(&dec, cr, dec.dc_cbcr, dec.ac_cbcr, dec.quant_cbcr, &dc_cr); for (i=0; i<8; i++) for (j=0; j<8; j++) putpixel_lc(bmp, x + j, y + i, y1[(i << 3) | j], cb[((i >> 1) << 3) | (j >> 1)], cr[((i >> 1) << 3) | (j >> 1)]); for (i=0; i<8; i++) for (j=0; j<8; j++) putpixel_lc(bmp, x + 8 + j, y + i, y2[(i << 3) | j], cb[((i >> 1) << 3) | ((j >> 1) + 4)], cr[((i >> 1) << 3) | ((j >> 1) + 4)]); for (i=0; i<8; i++) for (j=0; j<8; j++) putpixel_lc(bmp, x + j, y + 8 + i, y3[(i << 3) | j], cb[(((i >> 1) + 4) << 3) | (j >> 1)], cr[(((i >> 1) + 4) << 3) | (j >> 1)]); for (i=0; i<8; i++) for (j=0; j<8; j++) putpixel_lc(bmp, x + 8 + j, y + 8 + i, y4[(i << 3) | j], cb[(((i >> 1) + 4) << 3) | ((j >> 1) + 4)], cr[(((i >> 1) + 4) << 3) | ((j >> 1) + 4)]); x += 16; if (x >= dec.width) { x = 0; y += 16; if (dec.flags & DRI_DEFINED) { dc_y = dc_cb = dc_cr = 0; dec.data += 2; dec.bits = 0; } } } while (y < dec.height); break; case 2: do { /* 2nd case: * chrominance is taken every two pixels (only horizontally) * and luminance every pixel. */ decode_block(&dec, y1, dec.dc_y, dec.ac_y, dec.quant_y, &dc_y); decode_block(&dec, y2, dec.dc_y, dec.ac_y, dec.quant_y, &dc_y); decode_block(&dec, cb, dec.dc_cbcr, dec.ac_cbcr, dec.quant_cbcr, &dc_cb); decode_block(&dec, cr, dec.dc_cbcr, dec.ac_cbcr, dec.quant_cbcr, &dc_cr); for (i=0; i<8; i++) for (j=0; j<8; j++) putpixel_lc(bmp, x + j, y + i, y1[(i << 3) | j], cb[(i << 3) | (j >> 1)], cr[(i << 3) | (j >> 1)]); for (i=0; i<8; i++) for (j=0; j<8; j++) putpixel_lc(bmp, x + 8 + j, y + i, y2[(i << 3) | j], cb[(i << 3) | ((j >> 1) + 4)], cr[(i << 3) | ((j >> 1) + 4)]); x += 16; if (x >= dec.width) { x = 0; y += 8; if (dec.flags & DRI_DEFINED) { dc_y = dc_cb = dc_cr = 0; dec.data += 2; dec.bits = 0; } } } while (y < dec.height); break; case 1: do { /* 3rd case: * chrominance and luminance are taken every pixel. */ decode_block(&dec, y1, dec.dc_y, dec.ac_y, dec.quant_y, &dc_y); decode_block(&dec, cb, dec.dc_cbcr, dec.ac_cbcr, dec.quant_cbcr, &dc_cb); decode_block(&dec, cr, dec.dc_cbcr, dec.ac_cbcr, dec.quant_cbcr, &dc_cr); for (i=0; i<8; i++) for (j=0; j<8; j++) putpixel_lc(bmp, x + j, y + i, y1[(i << 3) | j], cb[(i << 3) | j], cr[(i << 3) | j]); x += 8; if (x >= dec.width) { x = 0; y += 8; if (dec.flags & DRI_DEFINED) { dc_y = dc_cb = dc_cr = 0; dec.data += 2; dec.bits = 0; } } } while (y < dec.height); break; } break; // CHANGED case 1: /* * Image has just one component (luminance) taken every pixel; we * have a grayscaled picture. */ do { decode_block(&dec, y1, dec.dc_y, dec.ac_y, dec.quant_y, &dc_y); for (i=0; i<8; i++) for (j=0; j<8; j++) { hue = MID(0, y1[(i << 3) | j], 255); putpixel(bmp, x + j, y + i, makecol24(hue, hue, hue)); } x += 8; if (x >= dec.width) { x = 0; y += 8; if (dec.flags & DRI_DEFINED) { dc_y = 0; dec.data += 2; dec.bits = 0; } } } while (y < dec.height); break; } // TODO #ifdef NATIVE_COMPILE /* generate_332_palette(pal); if (dest_depth != 24) bmp = _fixup_loaded_bitmap(bmp, pal, dest_depth); */ #endif // NATIVE_COMPILE return bmp;}/* load_jpg: * Loads a jpg image file (duh!). */#ifdef FULL_VERSIONBITMAP *load_jpg(char *filename, RGB *pal){ PACKFILE *f; BITMAP *bmp; long size; unsigned char *data; size = file_size(filename); if (!size) return NULL; /* * Loads the whole file in memory. */ data = (unsigned char *)_al_malloc(size); if (!data) return NULL; if (!(f = pack_fopen(filename, F_READ))) { _al_free(data); return NULL; } pack_fread(data, size, f); pack_fclose(f); /* * Decodes it. */ bmp = load_memory_jpg(data, pal); _al_free(data); return bmp;}#endif // FULL_VERSION
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -