📄 jpeg.c
字号:
int index; int h_subsample; int v_subsample; 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); OIL_DEBUG ("component %d: index=%d dc_table=%d ac_table=%d n=%d", component_id, index, dc_table, ac_table, n); } dec->scan_list_length = n; spectral_start = get_u8 (bits); spectral_end = get_u8 (bits); OIL_DEBUG ("spectral range [%d,%d]", spectral_start, spectral_end); approx_high = getbits (bits, 4); approx_low = getbits (bits, 4); OIL_DEBUG ("approx range [%d,%d]", 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) OIL_DEBUG ("endptr != bits"); return length;}intjpeg_decoder_application0 (JpegDecoder * dec, bits_t * bits){ int length; OIL_DEBUG ("app0"); length = get_be_u16 (bits); OIL_DEBUG ("length=%d", length); if (memcmp (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; OIL_DEBUG ("JFIF"); 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); OIL_DEBUG ("version = %04x", version); OIL_DEBUG ("units = %d", units); OIL_DEBUG ("x_density = %d", x_density); OIL_DEBUG ("y_density = %d", y_density); OIL_DEBUG ("x_thumbnail = %d", x_thumbnail); OIL_DEBUG ("y_thumbnail = %d", y_thumbnail); } if (memcmp (bits->ptr, "JFXX", 4) == 0 && bits->ptr[4] == 0) { OIL_DEBUG ("JFIF extension (not handled)"); bits->ptr += length - 2; } return length;}intjpeg_decoder_application_misc (JpegDecoder * dec, bits_t * bits){ int length; OIL_DEBUG ("appX"); length = get_be_u16 (bits); OIL_DEBUG ("length=%d", length); OIL_DEBUG ("JPEG application tag X ignored"); dumpbits (bits); bits->ptr += length - 2; return length;}intjpeg_decoder_comment (JpegDecoder * dec, bits_t * bits){ int length; OIL_DEBUG ("comment"); length = get_be_u16 (bits); OIL_DEBUG ("length=%d", length); dumpbits (bits); bits->ptr += length - 2; return length;}intjpeg_decoder_restart_interval (JpegDecoder * dec, bits_t * bits){ int length; OIL_DEBUG ("comment"); length = get_be_u16 (bits); OIL_DEBUG ("length=%d", length); dec->restart_interval = get_be_u16 (bits); OIL_DEBUG ("restart_interval=%d", dec->restart_interval); return length;}intjpeg_decoder_restart (JpegDecoder * dec, bits_t * bits){ OIL_DEBUG ("restart"); return 0;}voidjpeg_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++; } OIL_DEBUG ("entropy length = %d", len); /* we allocate extra space, since the getbits() code can * potentially read past the end of the buffer */ newptr = 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 = INT_MAX; 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; OIL_DEBUG ("%d,%d: component=%d dc_table=%d ac_table=%d", 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) { OIL_DEBUG ("%d,%d: component=%d dc_table=%d ac_table=%d", x, y, dec->scan_list[i].component_index, dec->scan_list[i].dc_table, dec->scan_list[i].ac_table); n = 0; break; } OIL_DEBUG ("using quant table %d", quant_index); oil_mult8x8_s16 (block2, block, dec->quant_table[quant_index], sizeof (short) * 8, sizeof(short) * 8, sizeof (short) * 8); dec->dc[component_index] += block2[0]; block2[0] = dec->dc[component_index]; oil_unzigzag8x8_s16 (block, sizeof (short) * 8, block2, sizeof (short) * 8); oil_idct8x8_s16 (block2, sizeof (short) * 8, block, sizeof (short) * 8); oil_trans8x8_s16 (block, sizeof (short) * 8, block2, sizeof (short) * 8); 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; oil_clipconv8x8_u8_s16 (ptr, dec->components[component_index].rowstride, block, sizeof (short) * 8); } 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; free (newptr);}JpegDecoder *jpeg_decoder_new (void){ JpegDecoder *dec; oil_init (); dec = malloc (sizeof(JpegDecoder)); memset (dec, 0, sizeof(JpegDecoder)); huffman_table_load_std_jpeg (dec); return dec;}voidjpeg_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) free (dec->components[i].image); } if (dec->data) free (dec->data); free (dec);}intjpeg_decoder_addbits (JpegDecoder * dec, unsigned char *data, unsigned int len){ unsigned int offset;#if 0 { static int index = 0; FILE *file; char s[100]; sprintf(s, "image-%d.jpg", index++); file = fopen(s, "w"); fwrite (data, len, 1, file); fclose(file); }#endif 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;}intjpeg_decoder_get_image_size (JpegDecoder * dec, int *width, int *height){ if (width) *width = dec->width; if (height) *height = dec->height; return 0;}intjpeg_decoder_get_component_ptr (JpegDecoder * dec, int id, const 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;}intjpeg_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;}intjpeg_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;}intjpeg_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++; } OIL_DEBUG ("lost sync, skipped %d bytes", n); } while (x == 0xff) { x = get_u8 (bits); } tag = x; OIL_DEBUG ("tag %02x", tag); b2 = *bits; for (i = 0; i < n_jpeg_markers - 1; i++) { if (tag == jpeg_markers[i].tag) { break; } } OIL_DEBUG ("tag: %s", jpeg_markers[i].name); if (jpeg_markers[i].func) { jpeg_markers[i].func (dec, &b2); } else { OIL_DEBUG ("unhandled or illegal JPEG marker (0x%02x)", 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;}/* misc helper functins */static voidhuffman_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 + -