📄 jpeg.c
字号:
int quant_index; component_id = get_u8(bits); dc_table = getbits(bits,4); ac_table = getbits(bits,4); index = jpeg_decoder_find_component_by_id(dec, component_id); h_subsample = dec->components[index].h_oversample; v_subsample = dec->components[index].v_oversample; quant_index = dec->components[index].quant_table; for(y=0;y<v_subsample;y++){ for(x=0;x<h_subsample;x++){ dec->scan_list[n].component_index = index; dec->scan_list[n].dc_table = dc_table; dec->scan_list[n].ac_table = ac_table; dec->scan_list[n].quant_table = quant_index; dec->scan_list[n].x = x; dec->scan_list[n].y = y; dec->scan_list[n].offset = y*8*dec->components[index].rowstride + x*8; n++; }} dec->scan_h_subsample = MAX(dec->scan_h_subsample,h_subsample); dec->scan_v_subsample = MAX(dec->scan_v_subsample,v_subsample); syncbits(bits); JPEG_DEBUG(0,"component %d: index=%d dc_table=%d ac_table=%d n=%d\n", component_id, index, dc_table, ac_table, n); } dec->scan_list_length = n; spectral_start = get_u8(bits); spectral_end = get_u8(bits); JPEG_DEBUG(0,"spectral range [%d,%d]\n",spectral_start,spectral_end); approx_high = getbits(bits,4); approx_low = getbits(bits,4); JPEG_DEBUG(0,"approx range [%d,%d]\n",approx_low, approx_high); syncbits(bits); dec->x = 0; dec->y = 0; dec->dc[0] = dec->dc[1] = dec->dc[2] = dec->dc[3] = 128*8; if(bits->end != bits->ptr)JPEG_DEBUG(0,"endptr != bits\n"); return length;}int jpeg_decoder_application0(JpegDecoder *dec, bits_t *bits){ int length; JPEG_DEBUG(0,"app0\n"); length = get_be_u16(bits); JPEG_DEBUG(0,"length=%d\n",length); if(strncmp(bits->ptr,"JFIF",4)==0 && bits->ptr[4]==0){ int version; int units; int x_density; int y_density; int x_thumbnail; int y_thumbnail; JPEG_DEBUG(0,"JFIF\n"); bits->ptr += 5; version = get_be_u16(bits); units = get_u8(bits); x_density = get_be_u16(bits); y_density = get_be_u16(bits); x_thumbnail = get_u8(bits); y_thumbnail = get_u8(bits); JPEG_DEBUG(0,"version = %04x\n",version); JPEG_DEBUG(0,"units = %d\n",units); JPEG_DEBUG(0,"x_density = %d\n",x_density); JPEG_DEBUG(0,"y_density = %d\n",y_density); JPEG_DEBUG(0,"x_thumbnail = %d\n",x_thumbnail); JPEG_DEBUG(0,"y_thumbnail = %d\n",y_thumbnail); } if(strncmp(bits->ptr,"JFXX",4)==0 && bits->ptr[4]==0){ JPEG_DEBUG(0,"JFIF extension (not handled)\n"); bits->ptr += length - 2; } return length;}int jpeg_decoder_application_misc(JpegDecoder *dec, bits_t *bits){ int length; JPEG_DEBUG(0,"appX\n"); length = get_be_u16(bits); JPEG_DEBUG(0,"length=%d\n",length); JPEG_DEBUG(0,"JPEG application tag X ignored\n"); dumpbits(bits); bits->ptr += length - 2; return length;}int jpeg_decoder_comment(JpegDecoder *dec, bits_t *bits){ int length; JPEG_DEBUG(0,"comment\n"); length = get_be_u16(bits); JPEG_DEBUG(0,"length=%d\n",length); dumpbits(bits); bits->ptr += length - 2; return length;}int jpeg_decoder_restart_interval(JpegDecoder *dec, bits_t *bits){ int length; JPEG_DEBUG(0,"comment\n"); length = get_be_u16(bits); JPEG_DEBUG(0,"length=%d\n",length); dec->restart_interval = get_be_u16(bits); JPEG_DEBUG(0,"restart_interval=%d\n",dec->restart_interval); return length;}int jpeg_decoder_restart(JpegDecoder *dec, bits_t *bits){ JPEG_DEBUG(0,"restart\n"); return 0;}void jpeg_decoder_decode_entropy_segment(JpegDecoder *dec, bits_t *bits){ bits_t b2, *bits2 = &b2; short block[64]; short block2[64]; unsigned char *newptr; int len; int j; int i; int go; int x,y; int n; int ret; len = 0; j = 0; while(1){ if(bits->ptr[len]==0xff && bits->ptr[len+1]!=0x00){ break; } len++; } JPEG_DEBUG(0,"entropy length = %d\n", len); /* we allocate extra space, since the getbits() code can * potentially read past the end of the buffer */ newptr = g_malloc(len+2); for(i=0;i<len;i++){ newptr[j] = bits->ptr[i]; j++; if(bits->ptr[i]==0xff) i++; } bits->ptr += len; bits2->ptr = newptr; bits2->idx = 0; bits2->end = newptr + j; newptr[j] = 0; newptr[j+1] = 0; dec->dc[0] = dec->dc[1] = dec->dc[2] = dec->dc[3] = 128*8; go = 1; x = dec->x; y = dec->y; n = dec->restart_interval; if(n==0)n=G_MAXINT; while(n-->0){ for(i=0;i<dec->scan_list_length;i++){ int dc_table_index; int ac_table_index; int quant_index; unsigned char *ptr; int component_index; JPEG_DEBUG(3,"%d,%d: component=%d dc_table=%d ac_table=%d\n", x,y, dec->scan_list[i].component_index, dec->scan_list[i].dc_table, dec->scan_list[i].ac_table); component_index = dec->scan_list[i].component_index; dc_table_index = dec->scan_list[i].dc_table; ac_table_index = dec->scan_list[i].ac_table; quant_index = dec->scan_list[i].quant_table; ret = huffman_table_decode_macroblock(block, dec->dc_huff_table[dc_table_index], dec->ac_huff_table[ac_table_index], bits2); if(ret<0){ JPEG_DEBUG(0,"%d,%d: component=%d dc_table=%d ac_table=%d\n", x,y, dec->scan_list[i].component_index, dec->scan_list[i].dc_table, dec->scan_list[i].ac_table); n = 0; break; } JPEG_DEBUG(3,"using quant table %d\n", quant_index); dequant8x8_s16(block2, block, dec->quant_table[quant_index]); dec->dc[component_index] += block2[0]; block2[0] = dec->dc[component_index]; unzigzag8x8_s16(block, block2); idct8x8_s16(block2, block, sizeof(short)*8, sizeof(short)*8); dump_block8x8_s16(block2); ptr = dec->components[component_index].image + x*dec->components[component_index].h_oversample + dec->scan_list[i].offset + dec->components[component_index].rowstride * y * dec->components[component_index].v_oversample; clipconv8x8_u8_s16(ptr, dec->components[component_index].rowstride, block2); } x += 8; if(x*dec->scan_h_subsample >= dec->width){ x = 0; y += 8; } if(y*dec->scan_v_subsample >= dec->height){ go = 0; } } dec->x = x; dec->y = y; g_free(newptr);}JpegDecoder *jpeg_decoder_new(void){ JpegDecoder *dec; dec = g_new0(JpegDecoder,1); huffman_table_load_std_jpeg(dec); return dec;}void jpeg_decoder_free(JpegDecoder *dec){ int i; huffman_table_free(dec->dc_huff_table[0]); huffman_table_free(dec->ac_huff_table[0]); huffman_table_free(dec->dc_huff_table[1]); huffman_table_free(dec->ac_huff_table[1]); for(i=0;i<JPEG_N_COMPONENTS;i++){ if(dec->components[i].image)g_free(dec->components[i].image); } if(dec->data) g_free(dec->data); g_free(dec);}int jpeg_decoder_addbits(JpegDecoder *dec, unsigned char *data, unsigned int len){ unsigned int offset; offset = dec->bits.ptr - dec->data; dec->data = realloc(dec->data, dec->data_len + len); memcpy(dec->data + dec->data_len, data, len); dec->data_len += len; dec->bits.ptr = dec->data + offset; dec->bits.end = dec->data + dec->data_len; return 0;}int jpeg_decoder_get_image_size(JpegDecoder *dec, int *width, int *height){ if(width) *width = dec->width; if(height) *height = dec->height; return 0;}int jpeg_decoder_get_component_ptr(JpegDecoder *dec, int id, unsigned char **image, int *rowstride){ int i; i = jpeg_decoder_find_component_by_id(dec,id); if(image)*image = dec->components[i].image; if(rowstride)*rowstride = dec->components[i].rowstride; return 0;}int jpeg_decoder_get_component_size(JpegDecoder *dec, int id, int *width, int *height){ int i; /* subsampling sizes are rounded up */ i = jpeg_decoder_find_component_by_id(dec,id); if(width) *width = (dec->width-1) / dec->components[i].h_subsample + 1; if(height) *height = (dec->height-1) / dec->components[i].v_subsample + 1; return 0;}int jpeg_decoder_get_component_subsampling(JpegDecoder *dec, int id, int *h_subsample, int *v_subsample){ int i; i = jpeg_decoder_find_component_by_id(dec,id); if(h_subsample) *h_subsample = dec->components[i].h_subsample; if(v_subsample) *v_subsample = dec->components[i].v_subsample; return 0;}int jpeg_decoder_parse(JpegDecoder *dec){ bits_t *bits = &dec->bits; bits_t b2; unsigned int x; unsigned int tag; int i; while(bits->ptr < bits->end){ x = get_u8(bits); if(x != 0xff){ int n = 0; while(x != 0xff){ x = get_u8(bits); n++; } JPEG_DEBUG(0,"lost sync, skipped %d bytes\n",n); } while(x == 0xff){ x = get_u8(bits); } tag = x; JPEG_DEBUG(0,"tag %02x\n",tag); b2 = *bits; for(i=0;i<n_jpeg_markers - 1;i++){ if(tag==jpeg_markers[i].tag){ break; } } JPEG_DEBUG(0,"tag: %s\n",jpeg_markers[i].name); if(jpeg_markers[i].func){ jpeg_markers[i].func(dec,&b2); }else{ JPEG_DEBUG(0,"unhandled or illegal JPEG marker (0x%02x)\n",tag); dumpbits(&b2); } if(jpeg_markers[i].flags & JPEG_ENTROPY_SEGMENT){ jpeg_decoder_decode_entropy_segment(dec,&b2); } syncbits(&b2); bits->ptr = b2.ptr; } return 0;}int jpeg_decoder_verbose_level = -1;void jpeg_debug(int n, const char *format, ... ){ va_list args; if(n>jpeg_decoder_verbose_level)return; fflush(stdout); fprintf(stderr,"JPEG_DEBUG: "); va_start(args, format); vfprintf(stderr,format, args); va_end(args);}/* misc helper functins */static char *sprintbits(char *str, unsigned int bits, int n){ int i; int bit = 1<<(n-1); for(i=0;i<n;i++){ str[i] = (bits&bit) ? '1' : '0'; bit>>=1; } str[i] = 0; return str;}static void dump_block8x8_s16(short *q){ int i; for(i=0;i<8;i++){ JPEG_DEBUG(3,"%3d %3d %3d %3d %3d %3d %3d %3d\n", q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7]); q+=8; }}static void dequant8x8_s16(short *dest, short *src, short *mult){ int i; for(i=0;i<64;i++){ dest[i] = src[i] * mult[i]; }}static void clipconv8x8_u8_s16(unsigned char *dest, int stride, short *src){ int i,j; int x; for(i=0;i<8;i++){ for(j=0;j<8;j++){ x = *src++; if(x<0)x=0; if(x>255)x=255; dest[j] = x; } dest += stride; }}static void huffman_table_load_std_jpeg(JpegDecoder *dec){ bits_t b, *bits = &b; bits->ptr = std_tables; bits->idx = 0; bits->end = std_tables + sizeof(std_tables); dec->dc_huff_table[0] = huffman_table_new_jpeg(bits); dec->ac_huff_table[0] = huffman_table_new_jpeg(bits); dec->dc_huff_table[1] = huffman_table_new_jpeg(bits); dec->ac_huff_table[1] = huffman_table_new_jpeg(bits);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -