[Swfed-svn] swfed-svn [52] replacePNGData の palette 形式 PNG 対応

アーカイブの一覧に戻る

svnno****@sourc***** svnno****@sourc*****
2008年 10月 2日 (木) 17:38:46 JST


Revision: 52
          http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi?root=swfed&view=rev&rev=52
Author:   yoya
Date:     2008-10-02 17:38:46 +0900 (Thu, 02 Oct 2008)

Log Message:
-----------
replacePNGData の palette 形式 PNG 対応

Modified Paths:
--------------
    src/swf_png.c
    src/swf_png.h
    src/swf_tag_lossless.c


-------------- next part --------------
Modified: src/swf_png.c
===================================================================
--- src/swf_png.c	2008-10-01 10:05:17 UTC (rev 51)
+++ src/swf_png.c	2008-10-02 08:38:46 UTC (rev 52)
@@ -8,7 +8,7 @@
 #include <stdlib.h>
 #include <png.h>
 #include "bitstream.h"
-#include "swf_rgb.h" // Lossless  format=3
+#include "swf_rgb.h"  // Lossless  format=3
 #include "swf_rgba.h" // Lossless2 format=3
 #include "swf_xrgb.h" // Lossless  format=5
 #include "swf_argb.h" // Lossless2 format=5
@@ -77,8 +77,9 @@
 
 void *
 pngconv_png2lossless(unsigned char *png_data, unsigned long png_data_len,
-                  int *tag_no, int *format,
-                  unsigned short *width, unsigned short *height) {
+                     int *tag_no, int *format,
+                     unsigned short *width, unsigned short *height,
+                     void **colormap, int *colormap_count) {
     png_structp png_ptr;
     png_infop png_info;
     my_png_buffer png_buff;
@@ -88,7 +89,9 @@
     png_bytepp png_image_data;
     png_uint_32 x, y;
     void *image_data;
-    *format = 5; /* sorry. i ignore pallet color and 5x3bit color */
+    png_color *palette = NULL;
+//    png_color_16p background; // for bKGD ???
+    int palette_num = 0;
 
     is_png = png_check_sig((png_bytep)png_data, 8);
     if (! is_png) {
@@ -118,22 +121,38 @@
                  NULL, NULL, NULL);
     *width = (unsigned short) png_width;
     *height = (unsigned short) png_height;
-    if (bpp != 8) {
-        fprintf(stderr, "pngconv_png2lossless: bpp=%d not implemented yet.\n", bpp);
-        png_destroy_read_struct(&png_ptr, &png_info, NULL);
-        return NULL;
-    }
-    if (color_type == PNG_COLOR_TYPE_RGB) {
+    switch(color_type) {
+    case PNG_COLOR_TYPE_PALETTE:
+        *format = 3;
+/*         if (png_get_bKGD(png_ptr, png_info, &background)) {
+            *tag_no = 36; // DefineBitsLossless2
+        } else {
+            *tag_no = 20; // DefineBitsLossless1
+        }
+*/
         *tag_no = 20; /* DefineBitsLossless */
-    } else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+        png_get_PLTE(png_ptr, png_info, &palette, &palette_num);
+        break;
+    case PNG_COLOR_TYPE_RGB:
+        *format = 5;
+        *tag_no = 20; /* DefineBitsLossless */
+    case PNG_COLOR_TYPE_RGB_ALPHA:
+        *format = 5;
         *tag_no = 36; /* DefineBitsLossless2 */
         if (png_get_valid(png_ptr, png_info, PNG_INFO_tRNS))
             png_set_tRNS_to_alpha(png_ptr);
-    } else {
+        break;
+    default:
         fprintf(stderr, "pngconv_png2lossless: color_type=%d not implemented yet.\n", color_type);
         png_destroy_read_struct(&png_ptr, &png_info, NULL);
         return NULL;
     }
+    if (bpp != 8) {
+        fprintf(stderr, "pngconv_png2lossless: bpp=%d not implemented yet. accept only bpp=8\n", bpp);
+        png_destroy_read_struct(&png_ptr, &png_info, NULL);
+        return NULL;
+    }
+    
     png_image_data = (png_bytepp) malloc(png_height * sizeof(png_bytep));
     for (y=0; y < png_height; y++) {
         png_image_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, png_info));
@@ -142,7 +161,25 @@
     /*
      * image copy
      */
-    if (color_type == PNG_COLOR_TYPE_RGB) {
+    if (color_type == PNG_COLOR_TYPE_PALETTE) {
+        int i;
+        *colormap_count = palette_num;
+        swf_rgb_t *result_colormap = malloc(sizeof(swf_rgb_t) * palette_num);   // Lossless
+        for (i = 0 ; i < palette_num ; i++) {
+            result_colormap[i].red   = palette[i].red;
+            result_colormap[i].green = palette[i].green;
+            result_colormap[i].blue  = palette[i].blue;
+        }
+        unsigned char *indices_data =
+            malloc(((png_width+ 3) & -4) * png_height);
+        for (y=0; y < png_height; y++) {
+            for (x=0; x < png_width; x++) {
+                indices_data[x+y*((png_width + 3) & -4)] = png_image_data[y][x]; // XXX
+            }
+        }
+        *colormap = result_colormap;
+        image_data = indices_data;
+    } else if (color_type == PNG_COLOR_TYPE_RGB) {
         swf_xrgb_t *xrgb_list;
         xrgb_list = malloc(sizeof(swf_xrgb_t) * png_width * png_height);
         for (y=0; y < png_height; y++) {
@@ -217,7 +254,7 @@
     } else if (tag_no == 36) { /* DefineBitsLossless2 */
         color_type = PNG_COLOR_TYPE_RGB_ALPHA;
     } else {
-        fprintf(stderr, "jpegconv_lossless2png: tag_no=%d not implemented.\n",
+        fprintf(stderr, "jpegconv_lossless2png: format!=3 and tag_no=%d not implemented.\n",
                 tag_no);
         png_destroy_write_struct (&png_ptr, &info_ptr);
         return NULL;

Modified: src/swf_png.h
===================================================================
--- src/swf_png.h	2008-10-01 10:05:17 UTC (rev 51)
+++ src/swf_png.h	2008-10-02 08:38:46 UTC (rev 52)
@@ -7,7 +7,8 @@
 extern void *
 pngconv_png2lossless(unsigned char *png_data, unsigned long png_data_len,
                      int *tag, int *format,
-                     unsigned short *width, unsigned short *height);
+                     unsigned short *width, unsigned short *height,
+                     void **colormap, int *colormap_count);
 
 extern unsigned char *
 pngconv_lossless2png(void *image_data,

Modified: src/swf_tag_lossless.c
===================================================================
--- src/swf_tag_lossless.c	2008-10-01 10:05:17 UTC (rev 51)
+++ src/swf_tag_lossless.c	2008-10-02 08:38:46 UTC (rev 52)
@@ -39,7 +39,7 @@
     
     swf_tag_lossless = calloc(sizeof(*swf_tag_lossless), 1);
     if (swf_tag_lossless == NULL) {
-        fprintf(stderr, "ERROR: swf_tag_lossless_create_detail: can't calloc\n");
+        fprintf(stderr, "swf_tag_lossless_create_detail: can't calloc swf_tag_lossless\n");
         return NULL;
     }
     bs = bitstream_open();
@@ -64,13 +64,6 @@
         old_buff_ref = bitstream_buffer(bs, offset);
         old_size = bitstream_length(bs) - offset;
         result = uncompress(tmp_buff, &origsize, old_buff_ref, old_size);
-        if (indices_len != origsize - bytes_per_color * swf_tag_lossless->colormap_count) {
-            fprintf(stderr, "swf_tag_lossless_create_detail: indices_len != origsize - %d * swf_tag_lossless->colormap_count at line(%d)\n",
-                    bytes_per_color, __LINE__);
-            free(tmp_buff);
-            bitstream_close(bs);
-            return NULL;
-        }
         if (result != Z_OK) {
             if (result == Z_MEM_ERROR) {
                 fprintf(stderr, "swf_tag_lossless_create_detail: uncompress: Z_MEM_ERROR: can't malloc at line(%d)\n", __LINE__);
@@ -85,11 +78,19 @@
             bitstream_close(bs);
             return NULL;
         }
+        if (indices_len != origsize - bytes_per_color * swf_tag_lossless->colormap_count) {
+            fprintf(stderr, "swf_tag_lossless_create_detail: indices_len(%lu) != origsize(%lu) - %d * swf_tag_lossless->colormap_count(%d) at line(%d)\n",
+                    indices_len, origsize, bytes_per_color,
+                    swf_tag_lossless->colormap_count, __LINE__);
+            free(tmp_buff);
+            bitstream_close(bs);
+            return NULL;
+        }
         bs2 = bitstream_open();
         bitstream_input(bs2, tmp_buff, origsize);
         if (tag->tag == 20) { // Lossless
             swf_tag_lossless->colormap = malloc(sizeof(swf_rgb_t) * swf_tag_lossless->colormap_count);
-            for (i=0; i<swf_tag_lossless->colormap_count; i++) {
+            for (i=0 ; i < swf_tag_lossless->colormap_count ; i++) {
                 swf_rgb_t *rgb = swf_tag_lossless->colormap + i;
                 swf_rgb_parse(bs2, rgb);
             }
@@ -195,16 +196,18 @@
         bs2 = bitstream_open();
         if (tag->tag == 20) { // Lossless
             for (i=0; i<swf_tag_lossless->colormap_count; i++) {
-                swf_rgb_t *rgb = swf_tag_lossless->colormap + sizeof(swf_rgb_t)*i;
+                swf_rgb_t *rgb = swf_tag_lossless->colormap + i;
                 swf_rgb_build(bs2, rgb);
             }
         } else { // tag == 36 (Lossless2)
             for (i=0; i<swf_tag_lossless->colormap_count; i++) {
-                swf_rgba_t *rgba = swf_tag_lossless->colormap2 + sizeof(swf_rgba_t)*i;
+                swf_rgba_t *rgba = swf_tag_lossless->colormap2 + i;
                 swf_rgba_build(bs2, rgba);
             }
         }
         indices_len = ((swf_tag_lossless->width + 3) & -4) * swf_tag_lossless->height;
+        bitstream_putstring(bs2, swf_tag_lossless->indices,
+                            indices_len);
         old_buff_ref = bitstream_buffer(bs2, 0);
         old_size = bitstream_length(bs2);
         tmp_buff = malloc(old_size); // too enough size
@@ -349,6 +352,8 @@
     int tag_no, format;
     unsigned short width, height;
     unsigned char *result_data;
+    void *colormap = NULL;
+    int colormap_count = 0;
     swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) detail;
     if (detail == NULL) {
         fprintf(stderr, "swf_tag_lossless_replace_lossless_data: detail == NULL at line(%d)\n", __LINE__);
@@ -358,7 +363,9 @@
         return 1;
     }
     result_data = pngconv_png2lossless(png_data, png_data_len,
-                                       &tag_no, &format, &width, &height);
+                                       &tag_no, &format,
+                                       &width, &height,
+                                       &colormap, &colormap_count);
 
     if (result_data == NULL) {
         fprintf(stderr, "swf_tag_lossless_replace_lossless_data: pngconv_png2lossless failed at line(%d)\n", __LINE__);
@@ -368,12 +375,36 @@
     swf_tag_lossless->format = format;
     swf_tag_lossless->width  = width;
     swf_tag_lossless->height = height;
-    if (format == 5) {
+    if (format == 3) {
+        free(swf_tag_lossless->colormap);
+        free(swf_tag_lossless->colormap2);
+        free(swf_tag_lossless->indices);
         free(swf_tag_lossless->bitmap);
         free(swf_tag_lossless->bitmap2);
+        swf_tag_lossless->colormap = NULL;
+        swf_tag_lossless->colormap2 = NULL;
+        swf_tag_lossless->indices = NULL;
         swf_tag_lossless->bitmap = NULL;
         swf_tag_lossless->bitmap2 = NULL;
         if (tag_no == 20) {
+            swf_tag_lossless->colormap = (swf_rgb_t*) colormap;
+        } else if (tag_no == 36) {
+            swf_tag_lossless->colormap2 = (swf_rgba_t*) colormap;
+        }
+        swf_tag_lossless->colormap_count = colormap_count;
+        swf_tag_lossless->indices = (unsigned char *) result_data;
+    } else if (format == 5) {
+        free(swf_tag_lossless->colormap);
+        free(swf_tag_lossless->colormap2);
+        free(swf_tag_lossless->indices);
+        free(swf_tag_lossless->bitmap);
+        free(swf_tag_lossless->bitmap2);
+        swf_tag_lossless->colormap = NULL;
+        swf_tag_lossless->colormap2 = NULL;
+        swf_tag_lossless->indices = NULL;
+        swf_tag_lossless->bitmap = NULL;
+        swf_tag_lossless->bitmap2 = NULL;
+        if (tag_no == 20) {
             swf_tag_lossless->bitmap = (swf_xrgb_t*) result_data;
         } else if (tag_no == 36) {
             swf_tag_lossless->bitmap2 = (swf_argb_t*) result_data;


Swfed-svn メーリングリストの案内
アーカイブの一覧に戻る