renamed png functions
[swftools.git] / lib / png.c
index f6edc12..2a31537 100644 (file)
--- a/lib/png.c
+++ b/lib/png.c
@@ -85,8 +85,8 @@ static unsigned int png_get_dword(FILE*fi)
 
 struct png_header
 {
-    int width;
-    int height;
+    unsigned width;
+    unsigned height;
     int bpp;
     int mode;
 };
@@ -167,7 +167,7 @@ static inline byte PaethPredictor (byte a,byte b,byte c)
         else return c;
 }
 
-static void applyfilter1(int mode, unsigned char*src, unsigned char*old, unsigned char*dest, int width)
+static void applyfilter1(int mode, unsigned char*src, unsigned char*old, unsigned char*dest, unsigned width)
 {
     int x;
     unsigned char last=0;
@@ -218,7 +218,7 @@ static void applyfilter1(int mode, unsigned char*src, unsigned char*old, unsigne
 
 }
 
-static void applyfilter2(int mode, unsigned char*src, unsigned char*old, unsigned char*dest, int width)
+static void applyfilter2(int mode, unsigned char*src, unsigned char*old, unsigned char*dest, unsigned width)
 {
     int x;
     unsigned char lasta=0;
@@ -281,7 +281,7 @@ static void applyfilter2(int mode, unsigned char*src, unsigned char*old, unsigne
 
 
 /* also performs 24 bit conversion! */
-static void applyfilter3(int mode, unsigned char*src, unsigned char*old, unsigned char*dest, int width)
+static void applyfilter3(int mode, unsigned char*src, unsigned char*old, unsigned char*dest, unsigned width)
 {
     int x;
     unsigned char lastr=0;
@@ -358,7 +358,7 @@ static void applyfilter3(int mode, unsigned char*src, unsigned char*old, unsigne
     }    
 }
 
-void png_inverse_filter_32(int mode, unsigned char*src, unsigned char*old, unsigned char*dest, int width)
+void png_inverse_filter_32(int mode, unsigned char*src, unsigned char*old, unsigned char*dest, unsigned width)
 {
     int x;
     unsigned char lastr=0;
@@ -441,7 +441,7 @@ void png_inverse_filter_32(int mode, unsigned char*src, unsigned char*old, unsig
     }    
 }
 
-EXPORT int getPNGdimensions(const char*sname, int*destwidth, int*destheight)
+EXPORT int png_getdimensions(const char*sname, unsigned*destwidth, unsigned*destheight)
 {
     FILE*fi;
     struct png_header header;
@@ -455,17 +455,17 @@ EXPORT int getPNGdimensions(const char*sname, int*destwidth, int*destheight)
 
     *destwidth = header.width;
     *destheight = header.height;
+    fclose(fi);
     return 1;
 }
 
-EXPORT int getPNG(const char*sname, int*destwidth, int*destheight, unsigned char**destdata)
+EXPORT int png_load(const char*sname, unsigned*destwidth, unsigned*destheight, unsigned char**destdata)
 {
     char tagid[4];
     int len;
     unsigned char*data;
     unsigned char*imagedata;
     unsigned char*zimagedata=0;
-    unsigned long int imagedatalen;
     unsigned long int zimagedatalen=0;
     unsigned char*palette = 0;
     int palettelen = 0;
@@ -499,7 +499,10 @@ EXPORT int getPNG(const char*sname, int*destwidth, int*destheight, unsigned char
        return 0;
     }
 
-    imagedatalen = bypp * header.width * header.height + 65536;
+    unsigned long long imagedatalen_64 = ((unsigned long long)header.width + 1) * header.height * bypp;
+    if(imagedatalen_64 > 0xffffffff)
+       return 0;
+    unsigned long imagedatalen = (unsigned long)imagedatalen_64;
     imagedata = (unsigned char*)malloc(imagedatalen);
 
     fseek(fi,8,SEEK_SET);
@@ -561,6 +564,7 @@ EXPORT int getPNG(const char*sname, int*destwidth, int*destheight, unsigned char
         }
     }
     
+    fclose(fi);
     if(!zimagedata || uncompress(imagedata, &imagedatalen, zimagedata, zimagedatalen) != Z_OK) {
        printf("Couldn't uncompress %s!\n", sname);
        if(zimagedata)
@@ -568,7 +572,6 @@ EXPORT int getPNG(const char*sname, int*destwidth, int*destheight, unsigned char
        return 0;
     }
     free(zimagedata);
-    fclose(fi);
 
     *destwidth = header.width;
     *destheight = header.height;
@@ -1150,7 +1153,7 @@ static inline u32 color_hash(COL*col)
     return hash;
 }
 
-static int png_get_number_of_palette_entries(COL*img, int width, int height, COL*palette, char*has_alpha)
+static int png_get_number_of_palette_entries(COL*img, unsigned width, unsigned height, COL*palette, char*has_alpha)
 {
     int len = width*height;
     int t;
@@ -1265,11 +1268,11 @@ static void png_map_to_palette(COL*src, unsigned char*dest, int size, COL*palett
     }
 }
 
-static int png_apply_specific_filter_8(int filtermode, unsigned char*dest, unsigned char*src, int width)
+static int png_apply_specific_filter_8(int filtermode, unsigned char*dest, unsigned char*src, unsigned width)
 {
     int pos2 = 0;
     int pos = 0;
-    int srcwidth = width;
+    unsigned srcwidth = width;
     int x;
     if(filtermode == 0) {
        for(x=0;x<width;x++) {
@@ -1308,11 +1311,11 @@ static int png_apply_specific_filter_8(int filtermode, unsigned char*dest, unsig
     return filtermode;
 }
 
-static int png_apply_specific_filter_32(int filtermode, unsigned char*dest, unsigned char*src, int width)
+static int png_apply_specific_filter_32(int filtermode, unsigned char*dest, unsigned char*src, unsigned width)
 {
     int pos2 = 0;
     int pos = 0;
-    int srcwidth = width*4;
+    unsigned srcwidth = width*4;
     int x;
     if(filtermode == 0) {
        for(x=0;x<width;x++) {
@@ -1395,28 +1398,17 @@ static void make_num_bits_table()
     }
 }
 
-static int png_find_best_filter_8(unsigned char*src, int width, int y)
-{
-    /*
-
-       FFFF I X   X    M   M EEEE
-       F    I  X X     MM MM E
-       FFF  I   X      M M M EEE
-       F    I  X X     M   M E
-       F    I X   X    M   M EEEE
-
-    */
-    return 0;
-}
-
-static int png_find_best_filter_32(unsigned char*src, int width, int y)
+static int png_find_best_filter(unsigned char*src, unsigned width, int bpp, int y)
 {
     make_num_bits_table();
     
     int num_filters = y>0?5:2; //don't apply y-direction filter in first line
 
-    int srcwidth = y?width*4:0;
-    int x;
+    int bytes_per_pixel = bpp>>3;
+    int w = width*bytes_per_pixel;
+    int back_x = bytes_per_pixel;
+    int back_y = y?width*bytes_per_pixel:0;
+
     unsigned char*pairs[5];
     pairs[0] = calloc(1, 8192);
     pairs[1] = calloc(1, 8192);
@@ -1425,23 +1417,23 @@ static int png_find_best_filter_32(unsigned char*src, int width, int y)
     pairs[4] = calloc(1, 8192);
     
     unsigned char old[5];
-
-    old[0] = src[3];
-    old[1] = src[3];
-    old[2] = src[3] - src[3-srcwidth];
-    old[3] = src[3] - src[3-srcwidth];
-    old[4] = src[3] - PaethPredictor(0, src[3-srcwidth], 0);
+    int l = bytes_per_pixel - 1;
+    old[0] = src[l];
+    old[1] = src[l];
+    old[2] = src[l] - src[l-back_y];
+    old[3] = src[l] - src[l-back_y];
+    old[4] = src[l] - PaethPredictor(0, src[l-back_y], 0);
 
     int different_pairs[5] = {0,0,0,0,0};
 
-    int w = width*4;
-    for(x=4;x<w;x++) {
+    int x;
+    for(x=bytes_per_pixel;x<w;x++) {
        unsigned char dest[5];
        dest[0] = src[x];
-       dest[1] = src[x] - src[x-4];
-       dest[2] = src[x] - src[x-srcwidth];
-       dest[3] = src[x] - (src[x-4] + src[x-srcwidth])/2;
-       dest[4] = src[x] - PaethPredictor(src[x-4], src[x-srcwidth], src[x-4-srcwidth]);
+       dest[1] = src[x] - src[x-back_x];
+       dest[2] = src[x] - src[x-back_y];
+       dest[3] = src[x] - (src[x-back_x] + src[x-back_y])/2;
+       dest[4] = src[x] - PaethPredictor(src[x-back_x], src[x-back_y], src[x-back_x-back_y]);
 
        int i;
        for(i=0;i<5;i++) {
@@ -1474,13 +1466,12 @@ static int png_find_best_filter_32(unsigned char*src, int width, int y)
 }
     
     
-static int png_apply_filter(unsigned char*dest, unsigned char*src, int width, int y, int bpp)
+static int png_apply_filter(unsigned char*dest, unsigned char*src, unsigned width, int y, int bpp)
 {
-    make_num_bits_table();
-
-    int num_filters = y>0?5:2; //don't apply y-direction filter in first line
     int best_nr = 0;
 #if 0
+    make_num_bits_table();
+    int num_filters = y>0?5:2; //don't apply y-direction filter in first line
     int f;
     int best_energy = INT_MAX;
     int w = width*(bpp/8);
@@ -1514,10 +1505,7 @@ static int png_apply_filter(unsigned char*dest, unsigned char*src, int width, in
     }
     free(pairs);
 #else
-    if(bpp==8)
-       best_nr = png_find_best_filter_8(src, width, y);
-    else
-       best_nr = png_find_best_filter_32(src, width, y);
+    best_nr = png_find_best_filter(src, width, bpp, y);
 #endif
     if(bpp==8)
        png_apply_specific_filter_8(best_nr, dest, src, width);
@@ -1526,16 +1514,16 @@ static int png_apply_filter(unsigned char*dest, unsigned char*src, int width, in
     return best_nr;
 }
 
-int png_apply_filter_8(unsigned char*dest, unsigned char*src, int width, int y)
+int png_apply_filter_8(unsigned char*dest, unsigned char*src, unsigned width, int y)
 {
-    png_apply_filter(dest, src, width, y, 8);
+    return png_apply_filter(dest, src, width, y, 8);
 }
-int png_apply_filter_32(unsigned char*dest, unsigned char*src, int width, int y)
+int png_apply_filter_32(unsigned char*dest, unsigned char*src, unsigned width, int y)
 {
-    png_apply_filter(dest, src, width, y, 32);
+    return png_apply_filter(dest, src, width, y, 32);
 }
 
-EXPORT void savePNG(const char*filename, unsigned char*data, int width, int height, int numcolors)
+EXPORT void png_write_palette_based(const char*filename, unsigned char*data, unsigned width, unsigned height, int numcolors)
 {
     FILE*fi;
     int crc;
@@ -1543,8 +1531,6 @@ EXPORT void savePNG(const char*filename, unsigned char*data, int width, int heig
     unsigned char format;
     unsigned char tmp;
     unsigned char* data2=0;
-    u32 datalen;
-    u32 datalen2;
     unsigned char head[] = {137,80,78,71,13,10,26,10}; // PNG header
     int cols;
     char alpha = 1;
@@ -1561,7 +1547,6 @@ EXPORT void savePNG(const char*filename, unsigned char*data, int width, int heig
 
     if(!numcolors) {
        int num = png_get_number_of_palette_entries((COL*)data, width, height, palette, &has_alpha);
-       num = 256;
        if(num<=255) {
            //printf("image has %d different colors (alpha=%d)\n", num, has_alpha);
            data2 = malloc(width*height);
@@ -1582,8 +1567,6 @@ EXPORT void savePNG(const char*filename, unsigned char*data, int width, int heig
         png_quantize_image(data, width*height, numcolors, &data, palette);
     }
 
-    datalen = (width*height*bpp/8+cols*8);
-    
     fi = fopen(filename, "wb");
     if(!fi) {
        perror("open");
@@ -1645,8 +1628,8 @@ EXPORT void savePNG(const char*filename, unsigned char*data, int width, int heig
     {
        int x,y;
         int bypp = bpp/8;
-       int srcwidth = width * bypp;
-       int linelen = 1 + srcwidth;
+       unsigned srcwidth = width * bypp;
+       unsigned linelen = 1 + srcwidth;
         if(bypp==2) 
             linelen = 1 + ((srcwidth+1)&~1);
         else if(bypp==3) 
@@ -1706,11 +1689,11 @@ EXPORT void savePNG(const char*filename, unsigned char*data, int width, int heig
     fclose(fi);
 }
 
-EXPORT void writePNG(const char*filename, unsigned char*data, int width, int height)
+EXPORT void png_write(const char*filename, unsigned char*data, unsigned width, unsigned height)
 {
-    savePNG(filename, data, width, height, 0);
+    png_write_palette_based(filename, data, width, height, 0);
 }
-EXPORT void writePalettePNG(const char*filename, unsigned char*data, int width, int height)
+EXPORT void png_write_palette_based_2(const char*filename, unsigned char*data, unsigned width, unsigned height)
 {
-    savePNG(filename, data, width, height, 256);
+    png_write_palette_based(filename, data, width, height, 256);
 }