X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfbits.c;h=da8be390f22423292615b059b883a3b693e0cf74;hb=6b6dbbd49f51d7ca661a4ee8eba96426f288b177;hp=5106df5faad8135637b16a43ad4d9a8b64ebba23;hpb=387eb848e7ef7a878ced45d4193529787628dff0;p=swftools.git diff --git a/lib/modules/swfbits.c b/lib/modules/swfbits.c index 5106df5..da8be39 100644 --- a/lib/modules/swfbits.c +++ b/lib/modules/swfbits.c @@ -11,12 +11,13 @@ */ -#ifdef _JPEGLIB_INCLUDED_ #define OUTBUFFER_SIZE 0x8000 +#ifdef _JPEGLIB_INCLUDED_ + typedef struct _JPEGDESTMGR { struct jpeg_destination_mgr mgr; - LPTAG t; + TAG * t; JOCTET * buffer; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; @@ -25,14 +26,14 @@ typedef struct _JPEGDESTMGR // Destination manager callbacks void swf_init_destination(j_compress_ptr cinfo) -{ LPJPEGDESTMGR dmgr = (LPJPEGDESTMGR)cinfo->dest; +{ 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 swf_empty_output_buffer(j_compress_ptr cinfo) -{ LPJPEGDESTMGR dmgr = (LPJPEGDESTMGR)cinfo->dest; +{ JPEGDESTMGR * dmgr = (JPEGDESTMGR *)cinfo->dest; SetBlock(dmgr->t,(U8*)dmgr->buffer,OUTBUFFER_SIZE); dmgr->mgr.next_output_byte = dmgr->buffer; dmgr->mgr.free_in_buffer = OUTBUFFER_SIZE; @@ -40,19 +41,19 @@ boolean swf_empty_output_buffer(j_compress_ptr cinfo) } void swf_term_destination(j_compress_ptr cinfo) -{ LPJPEGDESTMGR dmgr = (LPJPEGDESTMGR)cinfo->dest; +{ JPEGDESTMGR * dmgr = (JPEGDESTMGR *)cinfo->dest; SetBlock(dmgr->t,(U8*)dmgr->buffer,OUTBUFFER_SIZE-dmgr->mgr.free_in_buffer); free(dmgr->buffer); dmgr->mgr.free_in_buffer = 0; } -LPJPEGBITS SetJPEGBitsStart(LPTAG t,int width,int height,int quality) +JPEGBITS * SetJPEGBitsStart(TAG * t,int width,int height,int quality) { - LPJPEGDESTMGR jpeg; + JPEGDESTMGR * jpeg; // redirect compression lib output to local SWF Tag structure - jpeg = (LPJPEGDESTMGR)malloc(sizeof(JPEGDESTMGR)); + jpeg = (JPEGDESTMGR *)malloc(sizeof(JPEGDESTMGR)); if (!jpeg) return NULL; memset(jpeg,0x00,sizeof(JPEGDESTMGR)); @@ -87,32 +88,32 @@ LPJPEGBITS SetJPEGBitsStart(LPTAG t,int width,int height,int quality) jpeg_suppress_tables(&jpeg->cinfo, TRUE); jpeg_start_compress(&jpeg->cinfo, FALSE); - return (LPJPEGBITS)jpeg; + return (JPEGBITS *)jpeg; } -int SetJPEGBitsLines(LPJPEGBITS jpegbits,U8 ** data,int n) -{ LPJPEGDESTMGR jpeg = (LPJPEGDESTMGR)jpegbits; +int SetJPEGBitsLines(JPEGBITS * jpegbits,U8 ** data,int n) +{ JPEGDESTMGR * jpeg = (JPEGDESTMGR *)jpegbits; if (!jpeg) return -1; jpeg_write_scanlines(&jpeg->cinfo,data,n); return 0; } -int SetJPEGBitsLine(LPJPEGBITS jpegbits,U8 * data) +int SetJPEGBitsLine(JPEGBITS * jpegbits,U8 * data) { return SetJPEGBitsLines(jpegbits,&data,1); } -int SetJPEGBitsFinish(LPJPEGBITS jpegbits) -{ LPJPEGDESTMGR jpeg = (LPJPEGDESTMGR)jpegbits; +int SetJPEGBitsFinish(JPEGBITS * jpegbits) +{ JPEGDESTMGR * jpeg = (JPEGDESTMGR *)jpegbits; if (!jpeg) return -1; jpeg_finish_compress(&jpeg->cinfo); free(jpeg); return 0; } -int SetJPEGBits(LPTAG t,char * fname,int quality) +int SetJPEGBits(TAG * t,char * fname,int quality) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; - LPJPEGBITS out; + JPEGBITS * out; FILE * f; U8 * scanline; @@ -145,7 +146,185 @@ int SetJPEGBits(LPTAG t,char * fname,int quality) return 0; } -#undef OUTBUFFER_SIZE +#endif // _JPEGLIB_INCLUDED_ + +// Lossless compression texture based on zlib + +#ifdef _ZLIB_INCLUDED_ + +int swf_deflate_wraper(TAG * t,z_stream * zs,U8 * data,boolean finish) +{ while (1) + { int status = deflate(zs,Z_SYNC_FLUSH); + + if (zs->avail_out == 0) + { SetBlock(t,data,zs->next_out-data); + zs->next_out = data; + zs->avail_out = OUTBUFFER_SIZE; + } + + if (zs->avail_in==0) + { if (finish) deflate(zs,Z_FINISH); + break; + } + + if (status!=Z_OK) + { +#ifdef DEBUG_RFXSWF + fprintf(stderr,"rfxswf: zlib compression error (%i)\n",status); #endif + return status; + } + + } + return 0; +} + +int SetLosslessBits(TAG * t,U16 width,U16 height,void * bitmap,U8 bitmap_flags) +{ int res = 0; + int bps; + U8 * data; + + switch (bitmap_flags) + { case BMF_8BIT: + return SetLosslessBitsIndexed(t,width,height,bitmap,NULL,256); + case BMF_16BIT: + bps = BYTES_PER_SCANLINE(sizeof(U16)*width); + break; + case BMF_32BIT: + bps = width*4; + break; + default: + return -1; + } + + SetU8(t,bitmap_flags); + SetU16(t,width); + SetU16(t,height); + + if (data=malloc(OUTBUFFER_SIZE)) + { z_stream zs; + + memset(&zs,0x00,sizeof(z_stream)); + zs.zalloc = Z_NULL; + zs.zfree = Z_NULL; + + if (deflateInit(&zs,Z_DEFAULT_COMPRESSION)==Z_OK) + { zs.avail_in = bps*height; + zs.next_in = bitmap; + zs.next_out = data; + zs.avail_out = OUTBUFFER_SIZE; + + if (swf_deflate_wraper(t,&zs,data,TRUE)<0) res = -3; + if (zs.next_out>data) SetBlock(t,data,zs.next_out-data); + + deflateEnd(&zs); + + + } else res = -3; // zlib error + free(data); + } else res = -2; // memory error + + return res; +} + +int SetLosslessBitsIndexed(TAG * t,U16 width,U16 height,U8 * bitmap,RGBA * palette,U16 ncolors) +{ RGBA * pal = palette; + int bps = BYTES_PER_SCANLINE(width); + U8 * data; + int res = 0; + + if (!pal) // create default palette for grayscale images + { int i; + pal = malloc(256*sizeof(RGBA)); + for (i=0;i<256;i++) { pal[i].r = pal[i].g = pal[i].b = i; pal[i].a = 0xff;} + ncolors = 256; + } + + if ((ncolors<2)||(ncolors>256)||(!t)) return -1; // parameter error + + SetU8(t,BMF_8BIT); + SetU16(t,width); + SetU16(t,height); + SetU8(t,ncolors-1); // number of pal entries + + if (data=malloc(OUTBUFFER_SIZE)) + { z_stream zs; + + memset(&zs,0x00,sizeof(z_stream)); + zs.zalloc = Z_NULL; + zs.zfree = Z_NULL; + + if (deflateInit(&zs,Z_DEFAULT_COMPRESSION)==Z_OK) + { U8 * zpal; // compress palette + if (zpal = malloc(ncolors*4)) + { U8 * pp = zpal; + int i; + + /* be careful with ST_DEFINEBITSLOSSLESS2, because + the Flash player produces great bugs if you use too many + alpha colors in your palette. The only sensible result that + can be archeived is setting one color to r=0,b=0,g=0,a=0 to + make transparent parts in sprites. That's the cause why alpha + handling is implemented in lossless routines of rfxswf. + + Indeed: I haven't understood yet how flash player handles + alpha values different from 0 and 0xff in lossless bitmaps... + */ + + if (GetTagID(t)==ST_DEFINEBITSLOSSLESS2) // have alpha channel? + { for (i=0;idata) SetBlock(t,data,zs.next_out-data); + + free(zpal); + } else res = -2; // memory error + } else res = -3; // zlib error + free(data); + } else res = -2; + + if (!palette) free(pal); + + return res; +} + +int SetLosslessBitsGrayscale(TAG * t,U16 width,U16 height,U8 * bitmap) +{ return SetLosslessBitsIndexed(t,width,height,bitmap,NULL,256); +} + + +#endif // _ZLIB_INCLUDED_ + +#undef OUTBUFFER_SIZE + -// insert zlib/PNG functions here