📄 fad.jpeg.c
字号:
/** * libFAD - Flash Animation Decode library * Copyright (C) 2005-2006 VGSystem Technologies, Inc. * * libFAD is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: fad.jpeg.c,v 1.23 2006/03/08 07:39:12 wrxzzj Exp $ */#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include "fad.jpeg.h"#include "fad.tags.h"#include "fad.bits.h"/**include jpeglib header*/#include "jpeg/jpeglib.h"/**include zlib header*/#include "zlib/zlib.h"typedef struct { fad_object_t base; u8_t *image; u32_t width, height;} jpeg_bits_t;typedef struct { struct jpeg_source_mgr pub; u8_t *img_buf, *jt_buf; u32_t img_size, jt_size;} jb_source_mgr;typedef jb_source_mgr* jb_src_ptr;#ifdef LIBFAD_JPEG_DEBUGstatic int idx = 0;static int fd = -1;#endifstatic void _jb_init_source(j_decompress_ptr cinfo) { /**do nothing*/}static void _jb_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { jb_src_ptr src = (jb_src_ptr)cinfo->src; if(num_bytes > 0) { src->pub.next_input_byte += num_bytes; src->pub.bytes_in_buffer -= num_bytes; }}static void _jb_term_source(j_decompress_ptr cinfo) { jb_src_ptr src = (jb_src_ptr)cinfo->src; /**no work necessary here*/}static boolean _jb_fill_input_buffer(j_decompress_ptr cinfo) { jb_src_ptr src = (jb_src_ptr)cinfo->src;#ifdef LIBFAD_JPEG_DEBUG char imgfile[32]; if(fd < 0) { memset(imgfile, 0, 32); sprintf(imgfile, "jpeg-0%d.jpeg", idx++); fd = open(imgfile, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); if(fd < 0) FAD_ERROR("[*]LIBFAD_JPEG_DEBUG: create %s failure.\n", imgfile); }#endif if(src->jt_buf) { FAD_DEBUG("fill jpeg table, jt_buf = %x, jt_size = %d\n", src->jt_buf, src->jt_size); src->pub.next_input_byte = src->jt_buf; src->pub.bytes_in_buffer = src->jt_size;#ifdef LIBFAD_JPEG_DEBUG if(fd > 0) write(fd, src->jt_buf, src->jt_size);#endif src->jt_buf = NULL; } else if(src->img_buf) { FAD_DEBUG("fill jpeg image, img_buf = %x, img_size = %d\n", src->img_buf, src->img_size); src->pub.next_input_byte = src->img_buf; src->pub.bytes_in_buffer = src->img_size;#ifdef LIBFAD_JPEG_DEBUG if(fd > 0) { write(fd, src->img_buf, src->img_size); close(fd); fd = -1; }#endif src->img_buf = NULL; } return TRUE;}static void _jpeg_bits_src(j_decompress_ptr cinfo, u8_t* img_buf, u8_t* jt_buf, u32_t img_size, u32_t jt_size) { jb_src_ptr src = NULL; if(cinfo->src == NULL) cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(jb_source_mgr)); src = (jb_src_ptr)cinfo->src; src->pub.init_source = _jb_init_source; src->pub.skip_input_data = _jb_skip_input_data; src->pub.resync_to_restart = jpeg_resync_to_restart; src->pub.term_source = _jb_term_source; src->pub.fill_input_buffer = _jb_fill_input_buffer; src->pub.bytes_in_buffer = 0; src->pub.next_input_byte = NULL; src->img_buf = img_buf; src->img_size = img_size; src->jt_buf = jt_buf; src->jt_size = jt_size;}static void _jpeg_bits_v3_decode(jpeg_bits_t* jb, u8_t* img_buf, u8_t* jt_buf, u32_t img_size, u32_t jt_size, u32_t alpha_size) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; s32_t row_stride, size, pos; JSAMPARRAY buffer; u8_t *alpha = NULL, *src = NULL, *dest = NULL; cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); _jpeg_bits_src(&cinfo, img_buf, jt_buf, img_size, jt_size); jpeg_read_header(&cinfo, TRUE); jb->width = cinfo.image_width; jb->height = cinfo.image_height; jpeg_start_decompress(&cinfo); row_stride = cinfo.output_width * cinfo.output_components; jb->image = calloc(cinfo.output_height*cinfo.output_width, 4); if(jb->image == NULL) goto error; alpha = jb->image+cinfo.output_height*row_stride; size = cinfo.output_height*cinfo.output_width; uncompress(alpha, (unsigned long *)&size, img_buf+img_size, alpha_size); //printf("output_width = %d, output_height = %d, size = %d\n", cinfo.output_width, cinfo.output_height, size); buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); dest = jb->image; while(cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, (JSAMPARRAY)buffer, 1); for(pos = 0, src = buffer[0]; pos < cinfo.output_width; pos++, dest+=4, src+=3) { dest[0] = (src[2]*alpha[0])>>8; dest[1] = (src[1]*alpha[0])>>8; dest[2] = (src[0]*alpha[0])>>8; dest[3] = *alpha++; } }error: jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);}static void _jpeg_bits_v1_decode (jpeg_bits_t* jb, u8_t* img_buf, u8_t* jt_buf, u32_t img_size, u32_t jt_size) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; s32_t row_stride; JSAMPARRAY buffer; u8_t *dest = NULL, *src = NULL; u8_t npad = 0; u16_t idx; cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); _jpeg_bits_src(&cinfo, img_buf, jt_buf, img_size, jt_size); jpeg_read_header(&cinfo, TRUE); jb->width = cinfo.image_width; jb->height = cinfo.image_height; jpeg_start_decompress(&cinfo); row_stride = cinfo.output_width * cinfo.output_components; npad = 4 - (row_stride&0x03); jb->image = calloc(cinfo.output_height*cinfo.output_width, 4); if(jb->image == NULL) return; buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); dest = jb->image; while(cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, (JSAMPARRAY)buffer, 1); src = buffer[0]; for(idx=0; idx<cinfo.output_width; idx++, dest+=4, src+=3) { *(dest+0) = *(src+2); *(dest+1) = *(src+1); *(dest+2) = *(src+0); *(dest+3) = 0xff; } }error: jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);}static void _jpeg_bits_do_free(fad_object_t* fo) { jpeg_bits_t* jb = (jpeg_bits_t* )fo; if(jb->image) free(jb->image);}static u8_t _jpeg_bits_do_render(fad_object_t* fo, fad_render_t* render, dl_node_t *node) { jpeg_bits_t* jb = (jpeg_bits_t* )fo; FAD_ERROR("render jpeg image unimplement.\n"); return FAD_TRUE;}static void* _jpeg_bits_get_image(fad_object_t* fo, u32_t* w, u32_t* h) { jpeg_bits_t* jb = (jpeg_bits_t* )fo; if(jb->image) { *w = jb->width; *h = jb->height; } return jb->image;}s32_t jpeg_tables_decode(fad_frame_t* frame, fad_stream_t* s) { frame->jt_buf = (u8_t* )bits_tell(&s->bits); frame->jt_size = s->tag_len-2; return 0;}s32_t jpeg_bits_decode(fad_frame_t* frame, fad_stream_t* s) { jpeg_bits_t* jb; u16_t id; u8_t *ptr, *end = NULL; u8_t *img_buf = NULL, *jt_buf = NULL; u32_t img_size = 0, jt_size = 0, alpha_size = 0; jb = calloc(1, sizeof(jpeg_bits_t)); if(jb == NULL) goto error; jb->base.do_free = _jpeg_bits_do_free; jb->base.do_render = _jpeg_bits_do_render; jb->base.get_image = _jpeg_bits_get_image; jb->base.type = FO_TYPE_JPEG; id = bits_get_u16(&s->bits); if(s->tag_id == TAG_DEFINEBITS) { if(frame->jt_buf == NULL) goto error; img_size = s->tag_len - 4; img_buf = (u8_t* )bits_tell(&s->bits)+2; jt_buf = frame->jt_buf; jt_size = frame->jt_size; } else { if(s->tag_id == TAG_DEFINEBITSJPEG2) { img_size = s->tag_len - 2; img_buf = (u8_t* )bits_tell(&s->bits); } else { img_size = bits_get_u32(&s->bits); img_buf = (u8_t* )bits_tell(&s->bits); alpha_size = s->tag_len - 6 - img_size; FAD_DEBUG("alpha size = %d, img_size = %d\n", alpha_size, img_size); } ptr = img_buf; end = ptr + img_size; while(ptr != end) { if(*ptr == 0xff && *(ptr+1) == 0xd9 && *(ptr+2) == 0xff && *(ptr+3) == 0xd8) { if(ptr == img_buf) { img_buf += 4; img_size -= 4; ptr += 4; continue; } jt_buf = img_buf; jt_size = ptr-img_buf; img_buf = ptr + 4; img_size = img_size - jt_size - 4; FAD_DEBUG("jt_buf = %x, jt_size = %d, img_buf = %x, img_size = %d\n", jt_buf, jt_size, img_buf, img_size); break; } ptr++; } /**while(...)*/ } if(s->tag_id == TAG_DEFINEBITSJPEG3) _jpeg_bits_v3_decode(jb, img_buf, jt_buf, img_size, jt_size, alpha_size); else _jpeg_bits_v1_decode(jb, img_buf, jt_buf, img_size, jt_size); s->dict->put(s->dict, jb, id); FAD_ERROR("append JPEG image to dictionary, id = %d, fo = %x, width = %d, height = %d\n", id, jb, jb->width, jb->height); return 0;error: s->err = FAD_ERROR_MEM; if(jb != NULL) free(jb); return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -