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

📄 jpeg.c

📁 Flush解码源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -