* optimized swf_GetNumberOfPaletteEntries()
[swftools.git] / lib / modules / swfbits.c
index 57350da..66b61f4 100644 (file)
@@ -36,37 +36,112 @@ 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;
+       U32 hash;
+       if(col32 == lastcol32)
+           continue;
+       hash = (col32 >> 17) ^ col32;
+       hash ^= ((hash>>8) + 1) ^ hash;
+       hash &= 255;
+
+       int csize = size[hash];
+       U32* 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 {
@@ -938,8 +1013,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;