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;