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;