X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfbits.c;h=84a3b5065d5314687c5131db55b96d54f4f8f8ef;hb=879d0eec420fe0fd5ddcd56c8fe62b82a6744edd;hp=4510c48e4998d17c6871038d5d4e19863424e9c7;hpb=644837a3d0f18ac76d55c9ba438246cb5a2927d6;p=swftools.git diff --git a/lib/modules/swfbits.c b/lib/modules/swfbits.c index 4510c48..84a3b50 100644 --- a/lib/modules/swfbits.c +++ b/lib/modules/swfbits.c @@ -61,30 +61,6 @@ int swf_ImageHasAlpha(RGBA*img, int width, int height) return hasalpha; } -int swf_ImageGetNumberOfPaletteEntries2(RGBA*_img, int width, int height) -{ - int len = width*height; - int t; - U32* img = (U32*)_img; - U32 color1 = img[0]; - U32 color2 = 0; - for(t=1;tclient_data; - if (tag->data[tag->pos + 0] == 0xff && + if (tag->pos + 4 <= tag->len && + tag->data[tag->pos + 0] == 0xff && tag->data[tag->pos + 1] == 0xd9 && tag->data[tag->pos + 2] == 0xff && tag->data[tag->pos + 3] == 0xd8) { @@ -903,6 +887,7 @@ void swf_SetLosslessImage(TAG*tag, RGBA*data, int width, int height) tag->id = ST_DEFINEBITSLOSSLESS; } else { tag->id = ST_DEFINEBITSLOSSLESS2; + /* FIXME: we're destroying the callers data here */ swf_PreMultiplyAlpha(data, width, height); } num = swf_ImageGetNumberOfPaletteEntries(data, width, height, 0); @@ -1158,6 +1143,16 @@ int swf_SetJPEGBits3(TAG * tag, U16 width, U16 height, RGBA * bitmap, int qualit return 0; } +#else +int swf_SetJPEGBits3(TAG * tag, U16 width, U16 height, RGBA * bitmap, int quality) +{ + fprintf(stderr, "Error: swftools compiled without jpeglib\n"); + return -1; +} +#endif + + +#define NO_LOSSLESS /* expects mem to be non-premultiplied */ TAG* swf_AddImage(TAG*tag, int bitid, RGBA*mem, int width, int height, int quality) { @@ -1165,11 +1160,19 @@ TAG* swf_AddImage(TAG*tag, int bitid, RGBA*mem, int width, int height, int quali int has_alpha = swf_ImageHasAlpha(mem,width,height); /* try lossless image */ + +#ifdef NO_LOSSLESS + tag1 = swf_InsertTag(0, /*ST_DEFINEBITSLOSSLESS1/2*/0); + tag1->len = 0x7fffffff; +#else tag1 = swf_InsertTag(0, /*ST_DEFINEBITSLOSSLESS1/2*/0); swf_SetU16(tag1, bitid); swf_SetLosslessImage(tag1, mem, width, height); +#endif - /* try jpeg image */ +#if defined(HAVE_JPEGLIB) + /* try jpeg image. Notice that if (and only if) we tried the lossless compression + above, the data will now be premultiplied with alpha. */ if(has_alpha) { tag2 = swf_InsertTag(0, ST_DEFINEBITSJPEG3); swf_SetU16(tag2, bitid); @@ -1179,25 +1182,24 @@ TAG* swf_AddImage(TAG*tag, int bitid, RGBA*mem, int width, int height, int quali swf_SetU16(tag2, bitid); swf_SetJPEGBits2(tag2, width, height, mem, quality); } +#endif - if(quality>100 || (tag1 && tag1->len < tag2->len)) { + if(quality>100 || !tag2 || (tag1 && tag1->len < tag2->len)) { /* use the zlib version- it's smaller */ tag1->prev = tag; if(tag) tag->next = tag1; tag = tag1; - swf_DeleteTag(tag2); + swf_DeleteTag(0, tag2); } else { /* use the jpeg version- it's smaller */ tag2->prev = tag; if(tag) tag->next = tag2; tag = tag2; - swf_DeleteTag(tag1); + swf_DeleteTag(0, tag1); } return tag; } -#endif - RGBA *swf_ExtractImage(TAG * tag, int *dwidth, int *dheight) { RGBA *img; @@ -1260,190 +1262,6 @@ void swf_RemoveJPEGTables(SWF * swf) } if (swf->firstTag == tables_tag) swf->firstTag = tables_tag->next; - swf_DeleteTag(tables_tag); + swf_DeleteTag(swf, tables_tag); } -typedef struct scale_lookup { - int pos; - unsigned int weight; -} scale_lookup_t; - -typedef struct rgba_int { - unsigned int r,g,b,a; -} rgba_int_t; - -static int bicubic = 0; - -static scale_lookup_t**make_scale_lookup(int width, int newwidth) -{ - scale_lookup_t*lookupx = (scale_lookup_t*)malloc((width>newwidth?width:newwidth)*2*sizeof(scale_lookup_t)); - scale_lookup_t**lblockx = (scale_lookup_t**)malloc((newwidth+1)*sizeof(scale_lookup_t**)); - double fx = ((double)width)/((double)newwidth); - double px = 0; - int x; - scale_lookup_t*p_x = lookupx; - - if(newwidth<=width) { - for(x=0;x=width) tox = width-1; - for(xx=fromx;xx<=tox;xx++) { - if(xx==fromx && xx==tox) p_x->weight = 256; - else if(xx==fromx) p_x->weight = xweight; - else if(xx==tox) p_x->weight = 256-w; - else p_x->weight = i; - w+=p_x->weight; - p_x->pos = xx; - p_x++; - } - px = ex; - } - } else { - for(x=0;x=width) ix2=width-1; - lblockx[x] = p_x; - if(bicubic) - r = -2*r*r*r+3*r*r; - p_x[0].weight = (int)(256*(1-r)); - p_x[0].pos = ix1; - p_x[1].weight = 256-p_x[0].weight; - p_x[1].pos = ix2; - p_x+=2; - px += fx; - } - } - lblockx[newwidth] = p_x; - return lblockx; -} - -static void encodeMonochromeImage(RGBA*data, int width, int height, RGBA*colors) -{ - int t; - int len = width*height; - - U32* img = (U32*)data; - U32 color1 = img[0]; - U32 color2 = 0; - for(t=1;t> 8; - data[t].g = (colors[0].g * (255-m) + colors[1].g * m) >> 8; - data[t].b = (colors[0].b * (255-m) + colors[1].b * m) >> 8; - data[t].a = (colors[0].a * (255-m) + colors[1].a * m) >> 8; - } -} - -RGBA* swf_ImageScale(RGBA*data, int width, int height, int newwidth, int newheight) -{ - int x,y; - RGBA* newdata; - scale_lookup_t *p, **lblockx,**lblocky; - rgba_int_t*tmpline; - int monochrome = 0; - RGBA monochrome_colors[2]; - - if(newwidth<1 || newheight<1) - return 0; - - if(swf_ImageGetNumberOfPaletteEntries2(data, width, height) == 2) { - monochrome=1; - encodeMonochromeImage(data, width, height, monochrome_colors); - } - - tmpline = (rgba_int_t*)malloc(width*sizeof(rgba_int_t)); - newdata = (RGBA*)malloc(newwidth*newheight*sizeof(RGBA)); - - lblockx = make_scale_lookup(width, newwidth); - lblocky = make_scale_lookup(height, newheight); - - for(p=lblocky[0];ppos*=width; - - for(y=0;ypos]; - scale_lookup_t*p_x; - int weight = p_y->weight; - for(x=0;xpos]; - unsigned int weight = p_x->weight; - r += col->r*weight; - g += col->g*weight; - b += col->b*weight; - a += col->a*weight; - p_x++; - } while (p_xr = r >> 16; - destline->g = g >> 16; - destline->b = b >> 16; - destline->a = a >> 16; - - destline++; - } - } - - if(monochrome) - decodeMonochromeImage(newdata, newwidth, newheight, monochrome_colors); - - free(tmpline); - free(*lblockx); - free(lblockx); - free(*lblocky); - free(lblocky); - return newdata; -} - -