From ba50f044fa8cb1504465a9795cd7865cba934e60 Mon Sep 17 00:00:00 2001 From: kramm Date: Fri, 29 Oct 2004 14:24:17 +0000 Subject: [PATCH] added swf_ExtractImage() function. --- lib/modules/swfbits.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++- lib/rfxswf.h | 4 + 2 files changed, 235 insertions(+), 3 deletions(-) diff --git a/lib/modules/swfbits.c b/lib/modules/swfbits.c index 73159de..a687ffb 100644 --- a/lib/modules/swfbits.c +++ b/lib/modules/swfbits.c @@ -35,14 +35,14 @@ typedef struct _JPEGDESTMGR // Destination manager callbacks -void RFXSWF_init_destination(j_compress_ptr cinfo) +static void RFXSWF_init_destination(j_compress_ptr cinfo) { JPEGDESTMGR * dmgr = (JPEGDESTMGR *)cinfo->dest; dmgr->buffer = (JOCTET*)malloc(OUTBUFFER_SIZE); dmgr->mgr.next_output_byte = dmgr->buffer; dmgr->mgr.free_in_buffer = OUTBUFFER_SIZE; } -boolean RFXSWF_empty_output_buffer(j_compress_ptr cinfo) +static boolean RFXSWF_empty_output_buffer(j_compress_ptr cinfo) { JPEGDESTMGR * dmgr = (JPEGDESTMGR *)cinfo->dest; swf_SetBlock(dmgr->t,(U8*)dmgr->buffer,OUTBUFFER_SIZE); dmgr->mgr.next_output_byte = dmgr->buffer; @@ -50,7 +50,7 @@ boolean RFXSWF_empty_output_buffer(j_compress_ptr cinfo) return TRUE; } -void RFXSWF_term_destination(j_compress_ptr cinfo) +static void RFXSWF_term_destination(j_compress_ptr cinfo) { JPEGDESTMGR * dmgr = (JPEGDESTMGR *)cinfo->dest; swf_SetBlock(dmgr->t,(U8*)dmgr->buffer,OUTBUFFER_SIZE-dmgr->mgr.free_in_buffer); free(dmgr->buffer); @@ -248,6 +248,108 @@ int swf_SetJPEGBits(TAG * t,char * fname,int quality) return 0; } +/* jpeg_source_mgr functions */ +static void tag_init_source(struct jpeg_decompress_struct *cinfo) +{ + TAG*tag = (TAG*)cinfo->client_data; + swf_SetTagPos(tag, 2); + cinfo->src->bytes_in_buffer = 0; +} +static boolean tag_fill_input_buffer(struct jpeg_decompress_struct *cinfo) +{ + TAG*tag = (TAG*)cinfo->client_data; + if(tag->data[tag->pos+0] == 0xff && + tag->data[tag->pos+1] == 0xd9 && + tag->data[tag->pos+2] == 0xff && + tag->data[tag->pos+3] == 0xd8) { + printf("Skip\n"); + tag->pos += 4; + } + if(tag->pos >= tag->len) { + cinfo->src->next_input_byte = 0; + cinfo->src->bytes_in_buffer = 0; + return 0; + } + cinfo->src->next_input_byte = &tag->data[tag->pos]; + cinfo->src->bytes_in_buffer = 1;//tag->len - tag->pos; + tag->pos += 1; + return 1; +} +static void tag_skip_input_data(struct jpeg_decompress_struct *cinfo, long count) +{ + TAG*tag = (TAG*)cinfo->client_data; + cinfo->src->next_input_byte = 0; + cinfo->src->bytes_in_buffer = 0; + tag->pos += count; +} +static boolean tag_resync_to_restart(struct jpeg_decompress_struct *cinfo, int desired) +{ + return jpeg_resync_to_restart(cinfo, desired); +} +static void tag_term_source(struct jpeg_decompress_struct *cinfo) +{ + TAG*tag = (TAG*)cinfo->client_data; +} +RGBA* swf_JPEG2TagToImage(TAG*tag, int*width, int*height) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + struct jpeg_source_mgr mgr; + RGBA * dest; + *width = 0; + *height = 0; + + if(tag->id == ST_DEFINEBITSJPEG) { + fprintf(stderr, "rfxswf: extracting from definebitsjpeg not yet supported"); + return 0; + } + if(tag->id == ST_DEFINEBITSJPEG3) { + fprintf(stderr, "rfxswf: extracting from definebitsjpeg3 not yet supported"); + return 0; + } + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + + cinfo.client_data = (void*)tag; + cinfo.src = &mgr; + cinfo.src->init_source = tag_init_source; + cinfo.src->fill_input_buffer = tag_fill_input_buffer; + cinfo.src->skip_input_data = tag_skip_input_data; + cinfo.src->resync_to_restart = jpeg_resync_to_restart; + cinfo.src->term_source = tag_term_source; + cinfo.out_color_space = JCS_RGB; + + jpeg_read_header(&cinfo, TRUE); + *width = cinfo.image_width; + *height = cinfo.image_height; + dest = malloc(sizeof(RGBA)*cinfo.image_width*cinfo.image_height); + + jpeg_start_decompress(&cinfo); + int y; + for (y=0;y=0;--x) { + int b = to[x*3+0]; + int g = to[x*3+1]; + int r = to[x*3+2]; + line[x].r = r; + line[x].g = g; + line[x].b = b; + line[x].a = 255; + } + } + + jpeg_finish_decompress(&cinfo); + + jpeg_destroy_decompress(&cinfo); + return dest; +} + + #endif // HAVE_JPEGLIB // Lossless compression texture based on zlib @@ -443,6 +545,106 @@ int swf_SetLosslessBitsGrayscale(TAG * t,U16 width,U16 height,U8 * bitmap) { return swf_SetLosslessBitsIndexed(t,width,height,bitmap,NULL,256); } +RGBA* swf_DefineLosslessBitsTagToImage(TAG*tag, int*dwidth, int*dheight) +{ + int id,format,height, width, pos; + U32 datalen, datalen2; + int error; + int bpp=1; + int cols=0; + int pos2=0; + char alpha = tag->id == ST_DEFINEBITSLOSSLESS2; + int t,x,y; + RGBA*palette; + U8*data,*data2; + RGBA*dest; + if(tag->id != ST_DEFINEBITSLOSSLESS && + tag->id != ST_DEFINEBITSLOSSLESS2) { + fprintf(stderr, "rfxswf: Object %d is not a PNG picture!\n",GET16(tag->data)); + return 0; + } + swf_SetTagPos(tag, 0); + id =swf_GetU16(tag); + format = swf_GetU8(tag); + if(format == 3) bpp = 8; + if(format == 4) bpp = 16; + if(format == 5) bpp = 32; + if(format!=3 && format!=5) { + if(format==4) + fprintf(stderr, "rfxswf: Can't handle 16-bit palette images yet (image %d)\n",id); + else + fprintf(stderr, "rfxswf: Unknown image type %d in image %d\n", format, id); + return 0; + } + *dwidth = width = swf_GetU16(tag); + *dheight = height = swf_GetU16(tag); + + dest = malloc(sizeof(RGBA)*width*height); + + if(format == 3) cols = swf_GetU8(tag) + 1; + else cols = 0; + + data = 0; + datalen = (width*height*bpp/8+cols*8); + do { + if(data) + free(data); + datalen+=4096; + data = malloc(datalen); + error = uncompress (data, &datalen, &tag->data[tag->pos], tag->len-tag->pos); + } while(error == Z_BUF_ERROR); + if(error != Z_OK) { + fprintf(stderr, "rfxswf: Zlib error %d (image %d)\n", error, id); + return 0; + } + pos = 0; + + palette = (RGBA*)malloc(cols*sizeof(RGBA)); + for(t=0;tid == ST_DEFINEBITSJPEG || + tag->id == ST_DEFINEBITSJPEG2 || + tag->id == ST_DEFINEBITSJPEG3) { +#ifdef HAVE_JPEGLIB + return swf_JPEG2TagToImage(tag, dwidth, dheight); +#else + fprintf(stderr, "rfxswf: Error: No JPEG library compiled in"); + return 0; +#endif + } + if(tag->id == ST_DEFINEBITSLOSSLESS || + tag->id == ST_DEFINEBITSLOSSLESS2) { +#ifdef HAVE_ZLIB + return swf_DefineLosslessBitsTagToImage(tag, dwidth, dheight); +#else + fprintf(stderr, "rfxswf: Error: No JPEG library compiled in"); + return 0; +#endif + } + fprintf(stderr, "rfxswf: Error: Invalid tag (%d, %s)", tag->id, swf_TagGetName(tag)); + return 0; +} + #undef OUTBUFFER_SIZE diff --git a/lib/rfxswf.h b/lib/rfxswf.h index 2e8bb43..81863da 100644 --- a/lib/rfxswf.h +++ b/lib/rfxswf.h @@ -693,6 +693,7 @@ void swf_GetJPEGSize(char * fname, int*width, int*height); int swf_SetJPEGBits(TAG * t,char * fname,int quality); void swf_SetJPEGBits2(TAG * t,U16 width,U16 height,RGBA * bitmap,int quality); int swf_SetJPEGBits3(TAG * tag,U16 width,U16 height,RGBA* bitmap, int quality); +RGBA* swf_JPEG2TagToImage(TAG*tag, int*width, int*height); #define BYTES_PER_SCANLINE(width) ((width+3)&0xfffffffc) @@ -703,6 +704,9 @@ int swf_SetJPEGBits3(TAG * tag,U16 width,U16 height,RGBA* bitmap, int quality); int swf_SetLosslessBits(TAG * t,U16 width,U16 height,void * bitmap,U8 bitmap_flags); int swf_SetLosslessBitsIndexed(TAG * t,U16 width,U16 height,U8 * bitmap,RGBA * palette,U16 ncolors); int swf_SetLosslessBitsGrayscale(TAG * t,U16 width,U16 height,U8 * bitmap); +RGBA* swf_DefineLosslessBitsTagToImage(TAG*tag, int*width, int*height); + +RGBA* swf_ExtractImage(TAG*tag, int*dwidth, int*dheight); // swfsound.c void swf_SetSoundStreamHead(TAG*tag, int avgnumsamples); -- 1.7.10.4