[Swfed-svn] swfed-svn [15] format=3 ( index 形式 ) の画像抽出対応

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2008年 8月 8日 (金) 05:59:11 JST


Revision: 15
          http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi?root=swfed&view=rev&rev=15
Author:   yoya
Date:     2008-08-08 05:59:11 +0900 (Fri, 08 Aug 2008)

Log Message:
-----------
format=3 (index 形式)の画像抽出対応

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-08-07 20:58:41 UTC (rev 14)
+++ src/swf_png.c	2008-08-07 20:59:11 UTC (rev 15)
@@ -8,6 +8,8 @@
 #include <stdlib.h>
 #include <png.h>
 #include "bitstream.h"
+#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
 #include "swf_png.h"
@@ -83,11 +85,9 @@
     int is_png;
     int bpp, color_type;
     png_uint_32 png_width, png_height;
-    png_bytepp image_data;
+    png_bytepp png_image_data;
     png_uint_32 x, y;
-    swf_xrgb_t *xrgb_list;
-    swf_argb_t *argb_list;
-
+    void *image_data;
     *format = 5; /* sorry. i ignore pallet color and 5x3bit color */
 
     is_png = png_check_sig((png_bytep)png_data, 8);
@@ -134,63 +134,64 @@
         png_destroy_read_struct(&png_ptr, &png_info, NULL);
         return NULL;
     }
-    image_data = (png_bytepp) malloc(png_height * sizeof(png_bytep));
+    png_image_data = (png_bytepp) malloc(png_height * sizeof(png_bytep));
     for (y=0; y < png_height; y++) {
-        image_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, png_info));
+        png_image_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, png_info));
     }
-    png_read_image(png_ptr, image_data);
+    png_read_image(png_ptr, png_image_data);
     /*
      * image copy
      */
     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++) {
             for (x=0; x < png_width; x++) {
-                xrgb_list[x+y*png_width].red   = image_data[y][3*x + 0];
-                xrgb_list[x+y*png_width].green = image_data[y][3*x + 1];
-                xrgb_list[x+y*png_width].blue  = image_data[y][3*x + 2];
+                xrgb_list[x+y*png_width].red   = png_image_data[y][3*x + 0];
+                xrgb_list[x+y*png_width].green = png_image_data[y][3*x + 1];
+                xrgb_list[x+y*png_width].blue  = png_image_data[y][3*x + 2];
             }
         }
+        image_data = xrgb_list;
     } else { // PNG_COLOR_TYPE_RGB_ALPHA
+        swf_argb_t *argb_list;
         argb_list = malloc(sizeof(swf_argb_t) * png_width * png_height);
         for (y=0; y < png_height; y++) {
             for (x=0; x < png_width; x++) {
-                argb_list[x+y*png_width].red   = image_data[y][4*x + 0];
-                argb_list[x+y*png_width].green = image_data[y][4*x + 1];
-                argb_list[x+y*png_width].blue  = image_data[y][4*x + 2];
-                argb_list[x+y*png_width].alpha = image_data[y][4*x + 3];
+                argb_list[x+y*png_width].red   = png_image_data[y][4*x + 0];
+                argb_list[x+y*png_width].green = png_image_data[y][4*x + 1];
+                argb_list[x+y*png_width].blue  = png_image_data[y][4*x + 2];
+                argb_list[x+y*png_width].alpha = png_image_data[y][4*x + 3];
             }
         }
+        image_data = argb_list;
     }
     for (y=0; y < png_height; y++) {
-        free(image_data[y]);
+        free(png_image_data[y]);
     }
-    free(image_data);
+    free(png_image_data);
     /*
      * destruct
      */
     png_destroy_read_struct (&png_ptr, &png_info, NULL);
-    if (color_type == PNG_COLOR_TYPE_RGB) {
-        return (void *) xrgb_list;
-    } else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-        return (void *) argb_list;
-    }
-    return NULL;
+    return image_data;
 }
 
 unsigned char *
 pngconv_lossless2png(void *image_data,
                       unsigned short width, unsigned short height,
-                      int tag_no, int format,
+                     void *index_data,
+                     unsigned short index_data_count,
+                     int tag_no, int format,
                       unsigned long *length) {
     png_structp png_ptr;
     png_infop info_ptr;
     my_png_buffer png_buff;
     png_uint_32 png_width, png_height;
     int bpp, color_type;
-    png_bytepp png_data;
+    png_bytepp png_image_data;
     png_uint_32 x, y;
-    if (format != 5) {
+    if ((format != 3) && (format != 5)) {
         fprintf(stderr, "jpegconv_lossless2png: format=%d not implemented yes.\n", format);
         return NULL;
     }
@@ -209,7 +210,9 @@
     png_width = width;
     png_height = height;
     bpp = 8;
-    if (tag_no == 20) { /* DefineBitsLossless */
+    if (format == 3) {
+        color_type =  PNG_COLOR_TYPE_PALETTE;
+    } else if (tag_no == 20) { /* DefineBitsLossless */
         color_type = PNG_COLOR_TYPE_RGB;
     } else if (tag_no == 36) { /* DefineBitsLossless2 */
         color_type = PNG_COLOR_TYPE_RGB_ALPHA;
@@ -220,33 +223,70 @@
         return NULL;
     }
     png_set_filter(png_ptr, 0, PNG_ALL_FILTERS);
-    png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
     png_set_IHDR(png_ptr, info_ptr,
                  png_width, png_height, bpp, color_type,
                  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
                  PNG_FILTER_TYPE_DEFAULT);
+    if (format == 3) {
+        int i;
+        png_colorp png_palette;
+        if (index_data_count == 0) {
+            fprintf(stderr, "jpegconv_lossless2png: index_data_count == 0 at line(%d)\n", __LINE__);
+            png_destroy_write_struct (&png_ptr, &info_ptr);
+            return NULL;
+        }
+        png_palette = (png_colorp) malloc(sizeof(png_color)*index_data_count);
+        png_set_packing(png_ptr);
+        if (tag_no == 20) {
+            swf_rgb_t *rgb_list  = index_data;
+            for (i=0; i<index_data_count; i++) {
+                png_palette[i].red   = rgb_list[i].red;
+                png_palette[i].green = rgb_list[i].green;
+                png_palette[i].blue  = rgb_list[i].blue;
+            }
+        } else {
+            swf_rgba_t *rgba_list  = index_data;
+            for (i=0; i<index_data_count; i++) {
+                png_palette[i].red   = rgba_list[i].red;
+                png_palette[i].green = rgba_list[i].green;
+                png_palette[i].blue  = rgba_list[i].blue;
+//                png_palette[i].alpha = rgba_list[i].alpha;
+            }
+        }
+        png_set_PLTE( png_ptr, info_ptr, png_palette, index_data_count);
+//        free(png_palette);
+    }
     png_set_gAMA(png_ptr, info_ptr, 1.0);
-    png_data = (png_bytepp) malloc(png_height * sizeof(png_bytep));
-    if (color_type == PNG_COLOR_TYPE_RGB) {
+    png_image_data = (png_bytepp) malloc(png_height * sizeof(png_bytep));
+    if (color_type == PNG_COLOR_TYPE_PALETTE) {
+        for (y=0; y < png_height; y++) {
+            png_image_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, info_ptr));
+            for (x=0; x < png_width; x++) {
+                unsigned char *data = image_data;
+                png_image_data[y][x] = data[x + y*((png_width +3) & -4)];
+            }
+        }
+        
+    } else if (color_type == PNG_COLOR_TYPE_RGB) {
         swf_xrgb_t *xrgb_list = image_data;
         for (y=0; y < png_height; y++) {
-            png_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, info_ptr)) \
+            png_image_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, info_ptr)) \
                 ;
             for (x=0; x < png_width; x++) {
-                png_data[y][3*x]   =  xrgb_list[x+y*png_width].red;
-                png_data[y][3*x+1] =  xrgb_list[x+y*png_width].green;
-                png_data[y][3*x+2] =  xrgb_list[x+y*png_width].blue;
+                png_image_data[y][3*x]   =  xrgb_list[x+y*png_width].red;
+                png_image_data[y][3*x+1] =  xrgb_list[x+y*png_width].green;
+                png_image_data[y][3*x+2] =  xrgb_list[x+y*png_width].blue;
             }
         }
     } else {
         swf_argb_t *argb_list = image_data;
         for (y=0; y < png_height; y++) {
-            png_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, info_ptr));
+            png_image_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, info_ptr));
             for (x=0; x < png_width; x++) {
-                png_data[y][4*x]   = argb_list[x+y*png_width].red;
-                png_data[y][4*x+1] = argb_list[x+y*png_width].green;
-                png_data[y][4*x+2] = argb_list[x+y*png_width].blue;
-                png_data[y][4*x+3] = argb_list[x+y*png_width].alpha;
+                png_image_data[y][4*x]   = argb_list[x+y*png_width].red;
+                png_image_data[y][4*x+1] = argb_list[x+y*png_width].green;
+                png_image_data[y][4*x+2] = argb_list[x+y*png_width].blue;
+                png_image_data[y][4*x+3] = argb_list[x+y*png_width].alpha;
             }
         }
         
@@ -257,7 +297,7 @@
     png_data_write(png_ptr, &png_buff);
 
     png_write_info(png_ptr, info_ptr);
-    png_write_image(png_ptr, png_data);
+    png_write_image(png_ptr, png_image_data);
     png_write_end(png_ptr, info_ptr);
     //
     png_destroy_write_struct(&png_ptr, &info_ptr);

Modified: src/swf_png.h
===================================================================
--- src/swf_png.h	2008-08-07 20:58:41 UTC (rev 14)
+++ src/swf_png.h	2008-08-07 20:59:11 UTC (rev 15)
@@ -12,5 +12,7 @@
 extern unsigned char *
 pngconv_lossless2png(void *image_data,
                       unsigned short width, unsigned short height,
+                     void *index_data,
+                     unsigned short index_data_count,
                       int tag, int format,
                       unsigned long *length);

Modified: src/swf_tag_lossless.c
===================================================================
--- src/swf_tag_lossless.c	2008-08-07 20:58:41 UTC (rev 14)
+++ src/swf_tag_lossless.c	2008-08-07 20:59:11 UTC (rev 15)
@@ -289,7 +289,8 @@
     swf_tag_lossless_detail_t *swf_tag_lossless;
     unsigned char *data;
     *length = 0;
-    void *image_data;
+    void *index_data = NULL;
+    void *image_data = NULL;
     if (detail == NULL) {
         fprintf(stderr, "swf_tag_lossless_get_lossless_data: detail == NULL at line(%d)\n", __LINE__);
     }
@@ -297,15 +298,25 @@
     if (swf_tag_lossless->image_id != image_id) {
         return NULL;
     }
-    if (swf_tag_lossless->format != 5) {
+    if ((swf_tag_lossless->format != 3) && (swf_tag_lossless->format != 5)) {
         fprintf(stderr, "swf_tag_lossless_get_lossless_data: format=%d not implement yet\n",
                 swf_tag_lossless->format);
         return NULL;
     }
     if (tag->tag == 20) {
-        image_data = (void *) swf_tag_lossless->bitmap;
-    } else {
-        image_data = (void *) swf_tag_lossless->bitmap2;
+        if (swf_tag_lossless->format == 3) {
+            index_data = (void *) swf_tag_lossless->colormap;
+            image_data = (void *) swf_tag_lossless->indices;
+        } else {
+            image_data = (void *) swf_tag_lossless->bitmap;
+        }
+    } else { // 36
+        if (swf_tag_lossless->format == 3) {
+            index_data = (void *) swf_tag_lossless->colormap2;
+            image_data = (void *) swf_tag_lossless->indices;
+        } else {
+            image_data = (void *) swf_tag_lossless->bitmap2;
+        }
     }
     if (image_data == NULL) {
         fprintf(stderr, "swf_tag_lossless_get_lossless_data: image_data == NULL at line(%d)\n", __LINE__);
@@ -314,6 +325,8 @@
     data = pngconv_lossless2png(image_data,
                                 swf_tag_lossless->width,
                                 swf_tag_lossless->height,
+                                index_data,
+                                swf_tag_lossless->colormap_count,
                                 tag->tag, swf_tag_lossless->format,
                                 length);
     return data;


Swfed-svn メーリングリストの案内
Back to archive index