From 5fad380fbef965c12e904e79d0e8071c44c53ef4 Mon Sep 17 00:00:00 2001 From: boehme Date: Sun, 28 Oct 2001 18:57:31 +0000 Subject: [PATCH] new lossless image functions (alpha channel still buggy, but I suspect the flash player to cause these problems ...) --- lib/modules/swfbits.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 182 insertions(+), 3 deletions(-) diff --git a/lib/modules/swfbits.c b/lib/modules/swfbits.c index 2ecc39d..da8be39 100644 --- a/lib/modules/swfbits.c +++ b/lib/modules/swfbits.c @@ -11,9 +11,10 @@ */ -#ifdef _JPEGLIB_INCLUDED_ #define OUTBUFFER_SIZE 0x8000 +#ifdef _JPEGLIB_INCLUDED_ + typedef struct _JPEGDESTMGR { struct jpeg_destination_mgr mgr; TAG * t; @@ -145,7 +146,185 @@ int SetJPEGBits(TAG * 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 -- 1.7.10.4