📄 jpeg.c
字号:
/* * JPGalleg: JPEG image decoding routines for * * ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * game programming library. * * Version 1.1, by Angelo Mottola, May/June 2000 * * See README file for instructions on using this package in your own * programs. *///#include <allegro.h>//#include <allegro/aintern.h>#include "my_lib.h"//#include <math.h>#define FIX_0_298631336 ((long) 2446)#define FIX_0_390180644 ((long) 3196)#define FIX_0_541196100 ((long) 4433)#define FIX_0_765366865 ((long) 6270)#define FIX_0_899976223 ((long) 7373)#define FIX_1_175875602 ((long) 9633)#define FIX_1_501321110 ((long) 12299)#define FIX_1_847759065 ((long) 15137)#define FIX_1_961570560 ((long) 16069)#define FIX_2_053119869 ((long) 16819)#define FIX_2_562915447 ((long) 20995)#define FIX_3_072711026 ((long) 25172)#define NEXTWORD(x) ((*(x)->data << 8) | (*((x)->data + 1)))#define DESCALE(x,n) (((x) + ((long)1 << ((n) - 1))) >> n)#define SOF0 0xc0#define SOF1 0xc1#define DHT 0xc4#define SOI 0xd8#define EOI 0xd9#define SOS 0xda#define DQT 0xdb#define DRI 0xdd#define APP0 0xe0#define COM 0xfe#define SOF0_DEFINED 0x01#define DHT_DEFINED 0x02#define SOI_DEFINED 0x04#define SOS_DEFINED 0x08#define DQT_DEFINED 0x10#define APP0_DEFINED 0x20#define DRI_DEFINED 0x40#define JFIF_OK 0x3Fextern void do_idct(int *, int *);typedef struct HUFFMAN_NODE{ long index; int code, length;} HUFFMAN_NODE;typedef struct DECODER_DATA{ unsigned char *data_start; /* buffered JPG data block */ unsigned char *data; /* pointer to actual data */ int bits; /* number of bits available to be read */ int byte; /* current byte read */ int width, height; /* size of the image */ int components; /* number of image pixel components */ HUFFMAN_NODE huffman_node[1024]; /* huffman decoding entries */ int dequant[128]; /* dequantization tables */ int huffman_y, huffman_cbcr; /* for tables handling */ int samples_y; /* y sampling factor */ int quant_y, quant_cbcr; /* quantization table indexes */ int ac_y, ac_cbcr; /* AC y/cbcr table indexes */ int dc_y, dc_cbcr; /* DC y/cbcr table indexes */ int flags; /* Various decoding flags */} DECODER_DATA;/* next_bit: * Returns next bit from decoding data stream. */static unsigned long next_bit(DECODER_DATA *dec){ long seg_len; dec->bits--; if (dec->bits < 0) { dec->bits = 7; dec->byte = *(++dec->data); if (dec->byte == 0xff) { dec->data++; } } return (long)((dec->byte & (1 << dec->bits)) ? 1 : 0);}/* get_bits: * Reads a sequence of bits from the buffered data stream. Used to get the * representation of a number, given its category (by JPEG standard). */static int get_bits(DECODER_DATA *dec, int category){ unsigned int i; int result = 0; for (i=0; i<category; i++) result = (result << 1) | next_bit(dec); /* adjust sign of the value by category */ if (result >= (1 << (category - 1))) return result; else return result - ((1 << category) - 1);}/* huffman_decode: * Decodes a huffman encoded value from JPG file. */static int huffman_decode(DECODER_DATA *dec, HUFFMAN_NODE *node){ int i, j, found = -1; long val; if (*dec->data == 0xff) if (*(dec->data + 1) >= 0xd0 && *(dec->data + 1) <= 0xd7) { val = (1 << dec->bits) - 1; if ((dec->byte & val) == val) return -2; } val = 0; for (i=1; i<=16; i++) { val = (val << 1) | next_bit(dec); for (j=0; j<256; j++) { if (node[j].length > i) break; if ((node[j].length == i) && (node[j].index == val)) { found = j; break; } } if (found > -1) break; } if (found == -1) return -1; return node[found].code;}/* zigzag_reorder: * Reorders coefficients following the zigzag scan path. */static void zigzag_reorder(int *coefs){ int i, temp[64], scan[64] = { 0, 1, 5, 6,14,15,27,28, 2, 4, 7,13,16,26,29,42, 3, 8,12,17,25,30,41,43, 9,11,18,24,31,40,44,53, 10,19,23,32,39,45,52,54, 20,22,33,38,46,51,55,60, 21,34,37,47,50,56,59,61, 35,36,48,49,57,58,62,63 }; for (i=0; i<64; i++) temp[i] = coefs[scan[i]]; for (i=0; i<64; i++) coefs[i] = temp[i];}/* read_dht: * Reads AC/DC huffman table(s) from jpeg data. */static int read_dht(DECODER_DATA *dec){ int bit_len[16]; int table_class, table_id, i, j; unsigned int seg_len, count, val, table, index; dec->data++; seg_len = NEXTWORD(dec); dec->data += 2; count = 2; do { table_id = *dec->data & 0x1; table_class = (*dec->data & 0x10) >> 4; table = (table_class << 9) | (table_id << 8); dec->data++; count++; for (i=0; i<16; i++, count++) bit_len[i] = *dec->data++; val = 0; index = -1; for (i=0; i<16; i++) { for (j=0; j<bit_len[i]; j++) { index++; count++; dec->huffman_node[table | index].code = *dec->data++; dec->huffman_node[table | index].index = val; dec->huffman_node[table | index].length = i + 1; val++; } val <<= 1; } } while (count < seg_len); return 0;}/* read_sof0: * Basically reads more image informations. */static int read_sof0(DECODER_DATA *dec){ unsigned char comps; int i; dec->data += 3; if (*dec->data != 8) /* Only 8 bits/sample supported */ return 2; dec->data++; dec->height = NEXTWORD(dec); dec->data += 2; dec->width = NEXTWORD(dec); dec->data += 2; comps = *dec->data++; for (i=0; i<comps; i++) { switch (*dec->data) { case 1: dec->data++; dec->samples_y = (*dec->data & 0xf) * (*dec->data >> 4); dec->data++; dec->quant_y = *dec->data++; break; case 2: case 3: /* Skips cbcr samples (we don't care) */ dec->data += 2; dec->quant_cbcr = *dec->data++; break; } } return 0;}/* read_dqt: * Reads dequantization table(s). */static int read_dqt(DECODER_DATA *dec){ unsigned int seg_len, count; int i, qt_num; dec->data++; seg_len = NEXTWORD(dec); dec->data += 2; count = 2; do { if ((qt_num = (*dec->data & 0xf)) > 1) /* Illegal dequantization table number */ return 1; if (*dec->data & 0xf0) /* Only 8 bit dequantization table precision supported */ return 1; dec->data++; count++; for (i=0; i<64; i++, count++) dec->dequant[(qt_num << 6) | i] = *dec->data++; zigzag_reorder(dec->dequant + (qt_num << 6)); } while (count < seg_len); return 0;} /* read_sos: * Reads final image informations before decoding. */static int read_sos(DECODER_DATA *dec){ int i; dec->data += 3; dec->components = *dec->data++; if ((dec->components != 1) && (dec->components != 3)) /* Only 1 or 3 components supported */ return 2; for (i=0; i<dec->components; i++) { switch (*dec->data) { case 1: dec->data++; dec->ac_y = *dec->data & 0xf; dec->dc_y = *dec->data >> 4; dec->data++; break; case 2: case 3: dec->data++; dec->ac_cbcr = *dec->data & 0xf; dec->dc_cbcr = *dec->data >> 4; dec->data++; break; default: return 3; } } /* Skip next 3 bytes */ dec->data += 3; return 0;}/* read_app0: * Reads JFIF format data segment. */static int read_app0(DECODER_DATA *dec){ int skip; dec->data++; if (NEXTWORD(dec) < 16) /* Segment length too short */ return 1; dec->data += 2; if (strcmp(dec->data, "JFIF")) /* Invalid JFIF id */ return 1; dec->data += 5; if (*dec->data != 1) /* Only JFIF version 1.x supported */ return 1; dec->data += 7; /* Skips thumbnail */ skip = (*dec->data) * (*(dec->data + 1)); dec->data += 2 + (skip * 3); return 0;}/* decode_block: * Decodes a 8x8 block of pixel components; core algorithm. */static int decode_block(DECODER_DATA *dec, int *dat, int dc, int ac, int qt, int *old_dc){ int temp[64]; int data, num_zeros, num_bits; int i, val, coef; HUFFMAN_NODE *dc_node, *ac_node;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -