gcc 2.95.x fixes
[swftools.git] / lib / modules / swfbits.c
index 57350da..f238503 100644 (file)
@@ -36,37 +36,114 @@ int swf_ImageHasAlpha(RGBA*img, int width, int height)
     }
     return hasalpha;
 }
-   
-int swf_ImageGetNumberOfPaletteEntries(RGBA*img, int width, int height, RGBA*palette)
+
+/*int swf_ImageGetNumberOfPaletteEntries(RGBA*img, int width, int height, RGBA*palette)
 {
     int len = width*height;
     int t;
     int palsize = 0;
-    RGBA pal[256];
+    RGBA pal[512];
+    U32*pal32=(U32*)pal;
     int palette_overflow = 0;
-    for(t=0;t<len;t++) {
+    U32 lastcol32 = 0;
+
+    if(sizeof(RGBA)!=sizeof(U32))
+       fprintf(stderr, "rfxswf: sizeof(RGBA)!=sizeof(U32))");
+
+    lastcol32 = pal32[palsize++] = *(U32*)&img[0];
+
+    for(t=1;t<len;t++) {
        RGBA col = img[t];
        U32 col32 = *(U32*)&img[t];
-       int i=0;
+       int i;
+       if(col32==lastcol32)
+           continue;
        for(i=0;i<palsize;i++) {
-           if(col32 == *(U32*)&pal[i])
+           if(col32 == pal32[i])
                break;
        }
        if(i==palsize) {
-           if(palsize==256) {
+           if(palsize==512) {
                palette_overflow = 1;
                break;
            }
-           pal[palsize++] = col;
+           pal32[palsize++] = col32;
        }
+       lastcol32 = col32;
     }
     if(palette_overflow)
        return width*height;
     if(palette)
        memcpy(palette, pal, palsize*sizeof(RGBA));
     return palsize;
+}*/
+
+int swf_ImageGetNumberOfPaletteEntries(RGBA*img, int width, int height, RGBA*palette)
+{
+    int len = width*height;
+    int t;
+    int palsize = 0;
+    U32* pal;
+    int size[256];
+    int palette_overflow = 0;
+    U32 lastcol32 = 0;
+
+    pal = malloc(65536*sizeof(U32));
+
+    memset(size, 0, sizeof(size));
+
+    if(sizeof(RGBA)!=sizeof(U32))
+       fprintf(stderr, "rfxswf: sizeof(RGBA)!=sizeof(U32))");
+
+    lastcol32 = (*(U32*)&img[0])^0xffffffff; // don't match
+
+    for(t=0;t<len;t++) {
+       RGBA col = img[t];
+       U32 col32 = *(U32*)&img[t];
+       int i;
+       int csize;
+       U32 hash;
+       U32* cpal;
+       if(col32 == lastcol32)
+           continue;
+       hash = (col32 >> 17) ^ col32;
+       hash ^= ((hash>>8) + 1) ^ hash;
+       hash &= 255;
+
+       csize = size[hash];
+       cpal = &pal[hash*256];
+       for(i=0;i<csize;i++) {
+           if(col32 == cpal[i])
+               break;
+       }
+       if(i==csize) {
+           if(palsize==256) {
+               palette_overflow = 1;
+               break;
+           }
+           cpal[size[hash]++] = col32;
+           palsize++;
+       }
+       lastcol32 = col32;
+    }
+    if(palette_overflow)
+       return width*height;
+    if(palette) {
+       int i = 0;
+       for(t=0;t<256;t++) {
+           int s;
+           int csize = size[t];
+           U32* cpal = &pal[t*256];
+           for(s=0;s<csize;s++)
+               palette[i++] = *(RGBA*)(&cpal[s]);
+       }
+    }
+    free(pal);
+    return palsize;
 }
 
+
+
 #ifdef HAVE_JPEGLIB
 
 typedef struct _JPEGDESTMGR {
@@ -609,21 +686,22 @@ int swf_SetLosslessBitsGrayscale(TAG * t, U16 width, U16 height, U8 * bitmap)
 void swf_SetLosslessImage(TAG*tag, RGBA*data, int width, int height)
 {
     int hasalpha = swf_ImageHasAlpha(data, width, height);
+    int num;
     if(!hasalpha) {
        tag->id = ST_DEFINEBITSLOSSLESS;
     } else {
        tag->id = ST_DEFINEBITSLOSSLESS2;
        /* TODO: premultiply alpha? */
     }
-    int num = swf_ImageGetNumberOfPaletteEntries(data, width, height, 0);
+    num = swf_ImageGetNumberOfPaletteEntries(data, width, height, 0);
     if(num>1 && num<=256) {
        RGBA*palette = (RGBA*)malloc(sizeof(RGBA)*num);
-       swf_ImageGetNumberOfPaletteEntries(data, width, height, palette);
        int width2 = BYTES_PER_SCANLINE(width);
        U8*data2 = (U8*)malloc(width2*height);
        int len = width*height;
        int x,y;
        int r;
+       swf_ImageGetNumberOfPaletteEntries(data, width, height, palette);
        for(y=0;y<height;y++) {
            RGBA*src = &data[width*y];
            U8*dest = &data2[width2*y];
@@ -938,8 +1016,9 @@ void swf_RemoveJPEGTables(SWF * swf)
            void *data = rfx_alloc(tag->len);
            swf_GetBlock(tag, data, tag->len);
            swf_ResetTag(tag, ST_DEFINEBITSJPEG2);
+           swf_SetBlock(tag, &((U8*)data)[0], 2); //id
            swf_SetBlock(tag, tables_tag->data, tables_tag->len);
-           swf_SetBlock(tag, data, tag->len);
+           swf_SetBlock(tag, &((U8*)data)[2], tag->len-2);
            free(data);
        }
        tag = tag->next;
@@ -971,7 +1050,6 @@ static scale_lookup_t**make_scale_lookup(int width, int newwidth)
 
     if(newwidth<=width) {
        for(x=0;x<newwidth;x++) {
-           lblockx[x] = p_x;
            double ex = px + fx;
            int fromx = (int)px;
            int tox = (int)ex;
@@ -980,6 +1058,7 @@ static scale_lookup_t**make_scale_lookup(int width, int newwidth)
            int xweight = (int)(rem*256/fx);
            int xx;
            int w = 0;
+           lblockx[x] = p_x;
            if(tox>=width) tox = width-1;
            for(xx=fromx;xx<=tox;xx++) {
                if(xx==fromx && xx==tox) p_x->weight = 256;
@@ -994,11 +1073,11 @@ static scale_lookup_t**make_scale_lookup(int width, int newwidth)
        }
     } else {
        for(x=0;x<newwidth;x++) {
-           lblockx[x] = p_x;
            int ix1 = (int)px;
            int ix2 = ((int)px)+1;
-           if(ix2>=width) ix2=width-1;
            double r = px-ix1;
+           if(ix2>=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));
@@ -1015,12 +1094,16 @@ static scale_lookup_t**make_scale_lookup(int width, int newwidth)
 
 RGBA* swf_ImageScale(RGBA*data, int width, int height, int newwidth, int newheight)
 {
-    if(newwidth<1 || newheight<1)
-       return 0;
     int x,y;
-    RGBA* newdata= (RGBA*)malloc(newwidth*newheight*sizeof(RGBA));
+    RGBA* newdata; 
     scale_lookup_t *p, **lblockx,**lblocky;
-    rgba_int_t*tmpline = (rgba_int_t*)malloc(width*sizeof(rgba_int_t));
+    rgba_int_t*tmpline;
+    
+    if(newwidth<1 || newheight<1)
+       return 0;
+
+    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);
@@ -1033,7 +1116,7 @@ RGBA* swf_ImageScale(RGBA*data, int width, int height, int newwidth, int newheig
        
        /* create lookup table for y */
        rgba_int_t*l = tmpline;
-       scale_lookup_t*p_y;
+       scale_lookup_t*p_y,*p_x;
        memset(tmpline, 0, width*sizeof(rgba_int_t));
        for(p_y=lblocky[y];p_y<lblocky[y+1];p_y++) {
            RGBA*line = &data[p_y->pos];
@@ -1048,7 +1131,7 @@ RGBA* swf_ImageScale(RGBA*data, int width, int height, int newwidth, int newheig
        }
 
        /* process x direction */
-       scale_lookup_t*p_x = lblockx[0];
+       p_x = lblockx[0];
        for(x=0;x<newwidth;x++) {
            unsigned int r=0,g=0,b=0,a=0;
            scale_lookup_t*p_x_to = lblockx[x+1];