unsigned char * swf_tag_jpeg3_output_detail(swf_tag_t *tag, unsigned long *length, struct swf_object_ *swf) { swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL; bitstream_t *bs = NULL; unsigned char *data = NULL, *new_buff = NULL; unsigned long offset_to_alpha; unsigned long compsize, old_size; int result; if (tag == NULL) { fprintf(stderr, "swf_tag_jpeg3_output_detail: tag == NULL\n"); } if (swf == NULL) { fprintf(stderr, "swf_tag_jpeg3_output_detail: swf == NULL\n"); } if (length == NULL) { fprintf(stderr, "swf_tag_jpeg3_output_detail: length == NULL\n"); } swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail; *length = 0; bs = bitstream_open(); bitstream_putbytesLE(bs, swf_tag_jpeg->image_id, 2); bitstream_putbytesLE(bs, swf_tag_jpeg->jpeg_data_len, 4); bitstream_putstring(bs, swf_tag_jpeg->jpeg_data, swf_tag_jpeg->jpeg_data_len); offset_to_alpha = swf_tag_jpeg->jpeg_data_len; old_size = swf_tag_jpeg->alpha_data_len; compsize = old_size * 1.001 + 12; // increasing, rarely situation new_buff = malloc(compsize); // result = compress2(new_buff, &compsize, swf_tag_jpeg->alpha_data, old_size, swf->compress_level); result = compress2(new_buff, &compsize, swf_tag_jpeg->alpha_data, old_size, swf->compress_level); if (result != Z_OK) { if (result == Z_MEM_ERROR) { fprintf(stderr, "swf_tag_jpeg_output_detail: compress Z_MEM_ERROR: can't malloc\n"); } else if (result == Z_BUF_ERROR) { fprintf(stderr, "swf_tag_jpeg_output_detail: compress Z_BUF_ERROR: not enough buff size\n"); } else { fprintf(stderr, "swf_tag_jpeg_output_detail: compress failed by unknown reason\n"); } free(new_buff); bitstream_close(bs); return NULL; // FAILURE } bitstream_putstring(bs, new_buff, compsize); free(new_buff); data = bitstream_steal(bs, length); bitstream_close(bs); return data; }
int swf_tag_jpeg_input_detail(swf_tag_t *tag, struct swf_object_ *swf) { swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL; unsigned char *data = NULL; unsigned long length; bitstream_t *bs = NULL; (void) swf; if (tag == NULL) { fprintf(stderr, "ERROR: swf_tag_jpeg_input_detail: swf_tag_jpeg == NULL\n"); return 1; } swf_tag_jpeg = tag->detail; data = tag->data; length = tag->length; if (swf_tag_jpeg == NULL) { fprintf(stderr, "ERROR: swf_tag_jpeg_input_detail: swf_tag_jpeg == NULL\n"); return 1; } bs = bitstream_open(); bitstream_input(bs, data, length); swf_tag_jpeg->image_id = bitstream_getbytesLE(bs, 2); swf_tag_jpeg->jpeg_data = bitstream_output_sub(bs, 2, length - 2); swf_tag_jpeg->jpeg_data_len = length - 2; swf_tag_jpeg->alpha_data = NULL; swf_tag_jpeg->alpha_data_len = 0; bitstream_close(bs); return 0; }
int swf_tag_action_input_detail(swf_tag_t *tag, struct swf_object_ *swf) { swf_tag_action_detail_t *swf_tag_action = tag->detail; unsigned char *data = tag->data; unsigned long length = tag->length; bitstream_t *bs; (void) swf; if (tag == NULL) { fprintf(stderr, "ERROR: swf_tag_action_input_detail: tag == NULL\n"); return 1; } swf_tag_action = tag->detail; data = tag->data; length = tag->length; if (swf_tag_action == NULL) { fprintf(stderr, "ERROR: swf_tag_action_input_detail: swf_tag_action == NULL\n"); return 1; } bs = bitstream_open(); bitstream_input(bs, data, length); if (tag->code == 59) { // DoInitAction swf_tag_action->action_sprite = bitstream_getbytesLE(bs, 2); } else { // DoAction swf_tag_action->action_sprite = 0; // fail safe } swf_tag_action->action_list = swf_action_list_create(); if (swf_tag_action->action_list == NULL) { fprintf(stderr, "swf_tag_action_input_detail: swf_action_list_create failed\n"); bitstream_close(bs); return 1; } if (swf_action_list_parse(bs, swf_tag_action->action_list)) { fprintf(stderr, "swf_tag_action_input_detail: swf_action_list_parse failed\n"); bitstream_close(bs); return 1; } bitstream_close(bs); return 0; }
unsigned char * swf_tag_action_output_detail(swf_tag_t *tag, unsigned long *length, struct swf_object_ *swf) { swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) tag->detail; bitstream_t *bs; unsigned char *data; *length = 0; (void) swf; bs = bitstream_open(); if (tag->code == 59) { // DoInitAction bitstream_putbytesLE(bs, swf_tag_action->action_sprite, 2); } else { // DoAction ; // nothing } swf_action_list_build(bs,swf_tag_action->action_list); data = bitstream_steal(bs, length); bitstream_close(bs); return data; }
unsigned char * swf_tag_jpeg_output_detail(swf_tag_t *tag, unsigned long *length, struct swf_object_ *swf) { swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL; bitstream_t *bs = NULL; unsigned char *data = NULL; (void) swf; if (tag == NULL) { fprintf(stderr, "swf_tag_jpeg_output_detail: tag == NULL\n"); return NULL; } swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail; *length = 0; bs = bitstream_open(); bitstream_putbytesLE(bs, swf_tag_jpeg->image_id, 2); bitstream_putstring(bs, swf_tag_jpeg->jpeg_data, swf_tag_jpeg->jpeg_data_len); data = bitstream_steal(bs, length); bitstream_close(bs); return data; }
int swf_tag_shape_input_detail(swf_tag_t *tag, struct swf_object_ *swf) { swf_tag_shape_detail_t *swf_tag_shape = tag->detail; unsigned char *data = tag->data; unsigned long length = tag->length; bitstream_t *bs; int ret; (void) swf; if (swf_tag_shape == NULL) { fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape == NULL\n"); return 1; } // parse context swf_tag_shape->_current_x = 0; swf_tag_shape->_current_y = 0; swf_tag_shape->_parse_condition = 0; bs = bitstream_open(); bitstream_input(bs, data, length); swf_tag_shape->shape_id = bitstream_getbytesLE(bs, 2); ret = swf_rect_parse(bs, &(swf_tag_shape->rect)); if (ret) { fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->rect parse failed. shape_id=%d\n", swf_tag_shape->shape_id); bitstream_close(bs); return ret; } // DefineMorphShape, DefineMorphShape2 swf_tag_shape->is_morph = (tag->code == 46) || (tag->code == 84); // DefineShape4, DefineMorphShape2 swf_tag_shape->has_strokes = (tag->code == 83) || (tag->code == 84); if (swf_tag_shape->is_morph) { ret = swf_rect_parse(bs, &(swf_tag_shape->rect_morph)); if (ret) { fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->rect_morph parse failed. shape_id=%d\n", swf_tag_shape->shape_id); bitstream_close(bs); return ret; } } if (swf_tag_shape->has_strokes) { ret = swf_rect_parse(bs, &(swf_tag_shape->stroke_rect)); if (ret) { fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->stroke_rect parse failed. shape_id=%d\n", swf_tag_shape->shape_id); bitstream_close(bs); return ret; } if (swf_tag_shape->is_morph) { ret = swf_rect_parse(bs, &(swf_tag_shape->stroke_rect_morph)); if (ret) { fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->stroke_rect_morph parse failed. shape_id=%d\n", swf_tag_shape->shape_id); bitstream_close(bs); return ret; } } swf_tag_shape->define_shape_reserved = bitstream_getbits(bs, 6); swf_tag_shape->define_shape_non_scaling_strokes = bitstream_getbits(bs, 1); swf_tag_shape->define_shape_scaling_strokes = bitstream_getbits(bs, 1); } if (swf_tag_shape->is_morph) { bitstream_align(bs); swf_tag_shape->offset_morph = bitstream_getbytesLE(bs, 4); ret = swf_morph_shape_with_style_parse(bs, &swf_tag_shape->morph_shape_with_style, tag); if (ret) { fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_shape_with_style_parse swf_tag_shape->morph_shape_with_style failed. shape_id=%d\n", swf_tag_shape->shape_id); bitstream_close(bs); return ret; } } else { ret = swf_shape_with_style_parse(bs, &swf_tag_shape->shape_with_style, tag); if (ret) { fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_shape_with_style_parse swf_tag_shape->shape_with_style failed. shape_id=%d\n", swf_tag_shape->shape_id); bitstream_close(bs); return ret; } } bitstream_close(bs); return 0; }
unsigned char * swf_tag_shape_output_detail(swf_tag_t *tag, unsigned long *length, struct swf_object_ *swf) { swf_tag_shape_detail_t *swf_tag_shape = (swf_tag_shape_detail_t *) tag->detail; bitstream_t *bs; unsigned char *data; int ret; long offset_of_offset_morph = 0; long tmp_offset_byte = 0; long tmp_offset_bit = 0; (void) swf; *length = 0; // build context swf_tag_shape->_current_fill_style_num = 0; swf_tag_shape->_current_line_style_num = 0; swf_tag_shape->_current_x = 0; swf_tag_shape->_current_y = 0; // bs = bitstream_open(); bitstream_putbytesLE(bs, swf_tag_shape->shape_id, 2); swf_rect_build(bs, &(swf_tag_shape->rect)); // DefineMorphShape, DefineMorphShape2 swf_tag_shape->is_morph = (tag->code == 46) || (tag->code == 84); // DefineShape4, DefineMorphShape2 swf_tag_shape->has_strokes = (tag->code == 83) || (tag->code == 84); if (swf_tag_shape->is_morph) { ret = swf_rect_build(bs, &(swf_tag_shape->rect_morph)); if (ret) { fprintf(stderr, "ERROR: swf_tag_shape_output_detail: swf_tag_shape->rect_morph build failed\n"); bitstream_close(bs); return NULL; } } if (swf_tag_shape->has_strokes) { ret = swf_rect_build(bs, &(swf_tag_shape->stroke_rect)); if (ret) { fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->stroke_rect build failed\n"); bitstream_close(bs); return NULL; } if (swf_tag_shape->is_morph) { ret = swf_rect_build(bs, &(swf_tag_shape->stroke_rect_morph)); if (ret) { fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->stroke_rect_morph build failed\n"); bitstream_close(bs); return NULL; } } bitstream_putbits(bs, 6, swf_tag_shape->define_shape_reserved ); bitstream_putbits(bs, 1, swf_tag_shape->define_shape_non_scaling_strokes ); bitstream_putbits(bs, 1, swf_tag_shape->define_shape_scaling_strokes); } if (swf_tag_shape->is_morph) { bitstream_align(bs); // memory offset for overwrite this value after. offset_of_offset_morph = bitstream_getbytepos(bs); bitstream_putbytesLE(bs, swf_tag_shape->offset_morph, 4); swf_morph_shape_with_style_build(bs, &swf_tag_shape->morph_shape_with_style, tag); // rewind to overwrite offset_morph field and overwrite it. // offset distance from offset_morph so -4 operation swf_tag_shape->offset_morph = swf_tag_shape->morph_shape_with_style.offset_of_end_edges - offset_of_offset_morph - 4; tmp_offset_byte = bitstream_getbytepos(bs); // save offset tmp_offset_bit = bitstream_getbitpos(bs); bitstream_setpos(bs, offset_of_offset_morph, 0); bitstream_putbytesLE(bs, swf_tag_shape->offset_morph , 4); bitstream_setpos(bs, tmp_offset_byte, tmp_offset_bit); // restore offset } else { ret = swf_shape_with_style_build(bs, &swf_tag_shape->shape_with_style, tag); if (ret) { fprintf(stderr, "swf_tag_shape_output_detail: swf_shape_with_style_build failed\n"); bitstream_close(bs); return NULL; } } data = bitstream_steal(bs, length); bitstream_close(bs); return data; }
void * pngconv_png2lossless(unsigned char *png_data, unsigned long png_data_len, int *tag_no, int *format, unsigned short *width, unsigned short *height, void **colormap, int *colormap_count, int rgb15) { volatile png_structp png_ptr = NULL; volatile png_infop png_info_ptr = NULL; my_png_buffer png_buff; int bpp, color_type; png_uint_32 png_width = 0, png_height = 0; volatile png_bytepp png_image_data = NULL; register png_uint_32 x, y; void *image_data = NULL; png_color *palette = NULL; int palette_num = 0; png_bytep trans = NULL; int num_trans = 0; png_color_16p trans_values = NULL; if (png_data == NULL) { fprintf(stderr, "pngconv_png2lossless: png_data == NULL\n"); return NULL; } if (png_sig_cmp((png_bytep)png_data, 0, 8)) { // bad signature fprintf(stderr, "pngconv_png2lossless: is not PNG!\n"); return NULL; } png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL,NULL,NULL); if (! png_ptr) { fprintf(stderr, "pngconv_png2lossless: can't create read_struct\n"); return NULL; } if (setjmp(png_jmpbuf(png_ptr))) { fprintf(stderr, "pngconv_png2lossless: libpng error jump occured\n"); png_destroy_read_struct((png_structpp) &png_ptr, (png_infopp) &png_info_ptr, NULL); if (png_image_data) { for (y=0 ; y < png_height ; y++) { free(png_image_data[y]); } free(png_image_data); } return NULL; } png_info_ptr = png_create_info_struct(png_ptr); if (! png_info_ptr) { fprintf(stderr, "pngconv_png2lossless: can't create info_struct\n"); png_destroy_read_struct ((png_structpp)&png_ptr, NULL, NULL); return NULL; } png_buff.data = png_data; png_buff.data_len = png_data_len; png_buff.data_offset = 0; png_data_read(png_ptr, &png_buff); png_read_info(png_ptr, png_info_ptr); png_get_IHDR(png_ptr, png_info_ptr, &png_width, &png_height, &bpp, &color_type, NULL, NULL, NULL); *width = (unsigned short) png_width; *height = (unsigned short) png_height; if ((rgb15 > 0) && (color_type != PNG_COLOR_TYPE_RGB)) { // warning fprintf(stderr, "rgb15 is %d but color_type is not PNG24\n", rgb15); } switch(color_type) { case PNG_COLOR_TYPE_PALETTE: *format = 3; png_get_PLTE(png_ptr, png_info_ptr, &palette, &palette_num); if (png_get_tRNS(png_ptr, png_info_ptr, &trans, &num_trans, &trans_values) && (num_trans > 0)) { *tag_no = 36; // DefineBitsLossless2 } else { *tag_no = 20; // DefineBitsLossless } break; case PNG_COLOR_TYPE_RGB: if (rgb15 > 0) { *format = 4; } else { *format = 5; } *tag_no = 20; /* DefineBitsLossless */ break; case PNG_COLOR_TYPE_RGB_ALPHA: *format = 5; *tag_no = 36; /* DefineBitsLossless2 */ if (png_get_valid(png_ptr, png_info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); break; default: fprintf(stderr, "pngconv_png2lossless: color_type=%d not implemented yet.\n", color_type); png_destroy_read_struct((png_structpp)&png_ptr, (png_infopp)&png_info_ptr, 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_structpp)&png_ptr, (png_infopp)&png_info_ptr, 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_ptr)); } png_read_image(png_ptr, png_image_data); /* * image copy */ if (color_type == PNG_COLOR_TYPE_PALETTE) { register int i; unsigned char *indices_data; *colormap_count = palette_num; if (num_trans == 0) { 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; } *colormap = result_colormap; } else { swf_rgba_t *result_colormap = malloc(sizeof(swf_rgba_t) * palette_num); // Lossless2 for (i=0 ; i < palette_num ; i++) { if (i < num_trans) { int alpha_value = trans[i]; result_colormap[i].red = palette[i].red * alpha_value / 0xff; result_colormap[i].green = palette[i].green * alpha_value / 0xff; result_colormap[i].blue = palette[i].blue * alpha_value / 0xff; result_colormap[i].alpha = alpha_value; } else { result_colormap[i].red = palette[i].red; result_colormap[i].green = palette[i].green; result_colormap[i].blue = palette[i].blue; result_colormap[i].alpha = 0xff; // opaque } } *colormap = result_colormap; } indices_data = malloc(((png_width+ 3) & -4) * png_height); i = 0; for (y=0 ; y < png_height ; y++) { bitstream_t *bs = bitstream_open(); if (bs == NULL) { free(*colormap); *colormap = NULL; free(indices_data); for (y=0 ; y < png_height ; y++) { free(png_image_data[y]); } free(png_image_data); return NULL; } bitstream_input(bs, png_image_data[y], png_width); for (x=0 ; x < png_width ; x++) { indices_data[i] = bitstream_getbits(bs, bpp); i++; } while (i % 4) { i++; } // 4byte alignment bitstream_close(bs); } 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++) { for (x=0 ; x < png_width ; x++) { 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++) { int alpha_value = png_image_data[y][4*x + 3]; argb_list[x+y*png_width].red = png_image_data[y][4*x + 0] * alpha_value / 0xff; argb_list[x+y*png_width].green = png_image_data[y][4*x + 1] * alpha_value / 0xff; argb_list[x+y*png_width].blue = png_image_data[y][4*x + 2] * alpha_value / 0xff; argb_list[x+y*png_width].alpha = alpha_value; } } image_data = argb_list; } for (y=0 ; y < png_height ; y++) { free(png_image_data[y]); } free(png_image_data); /* * destruct */ png_destroy_read_struct((png_structpp) &png_ptr, (png_infopp) &png_info_ptr, NULL); return image_data; }
int swf_tag_place_input_detail(swf_tag_t *tag, struct swf_object_ *swf) { swf_tag_place_detail_t *swf_tag_place = tag->detail; unsigned char *data = tag->data; unsigned long length = tag->length; bitstream_t *bs; int ret; (void) swf; if (swf_tag_place == NULL) { fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place == NULL\n"); return 1; } swf_tag_place->character_id = 0; // undefined bs = bitstream_open(); bitstream_input(bs, data, length); if (tag->code == 4) { // PlaceObject swf_tag_place->character_id = bitstream_getbytesLE(bs, 2); swf_tag_place->depth = bitstream_getbytesLE(bs, 2); ret = swf_matrix_parse(bs, &(swf_tag_place->matrix)); if (ret) { fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place->matrix parse failed. character_id=%d\n", swf_tag_place->character_id); bitstream_close(bs); return ret; } bitstream_align(bs); if (bitstream_getbytepos(bs) < length) { // optional ret = swf_cxform_parse(bs, &(swf_tag_place->color_transform)); if (ret) { fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place->color_transform parse failed. character_id=%d\n", swf_tag_place->character_id); bitstream_close(bs); return ret; } } else { swf_tag_place->color_transform.has_add_terms = 0; swf_tag_place->color_transform.has_mult_terms = 0; swf_tag_place->color_transform.nbits = 0; } } else if (tag->code == 26) { // PlaceObject2 swf_tag_place->flag_has_clip_action = bitstream_getbit(bs); swf_tag_place->flag_has_clip_depth = bitstream_getbit(bs); swf_tag_place->flag_has_name = bitstream_getbit(bs); swf_tag_place->flag_has_ratio = bitstream_getbit(bs); swf_tag_place->flag_has_color_transform = bitstream_getbit(bs); swf_tag_place->flag_has_matrix = bitstream_getbit(bs); swf_tag_place->flag_has_character = bitstream_getbit(bs); swf_tag_place->flag_has_move = bitstream_getbit(bs); swf_tag_place->depth = bitstream_getbytesLE(bs, 2); if (swf_tag_place->flag_has_character) { swf_tag_place->character_id = bitstream_getbytesLE(bs, 2); } else { swf_tag_place->character_id = 0; } if (swf_tag_place->flag_has_matrix) { ret = swf_matrix_parse(bs, &(swf_tag_place->matrix)); if (ret) { fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place->matrix parse failed. character_id=%d\n", swf_tag_place->character_id); bitstream_close(bs); return ret; } } if (swf_tag_place->flag_has_color_transform) { ret = swf_cxformwithalpha_parse(bs, &(swf_tag_place->color_transform_with_alpha)); if (ret) { fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place->color_transform parse failed. character_id=%d\n", swf_tag_place->character_id); bitstream_close(bs); return ret; } } if (swf_tag_place->flag_has_ratio) { swf_tag_place->ratio = bitstream_getbytesLE(bs, 2); } if (swf_tag_place->flag_has_name) { swf_tag_place->name = (char *) bitstream_outputstring(bs); } if (swf_tag_place->flag_has_clip_depth) { swf_tag_place->clip_depth = bitstream_getbytesLE(bs, 2); } // TODO: clip action data for SWF 5 } else { bitstream_close(bs); return 1; // unknown tag; } bitstream_close(bs); return 0; }
unsigned char * swf_tag_place_output_detail(swf_tag_t *tag, unsigned long *length, struct swf_object_ *swf) { swf_tag_place_detail_t *swf_tag_place = (swf_tag_place_detail_t *) tag->detail; bitstream_t *bs; unsigned char *data; int ret; (void) swf; *length = 0; bs = bitstream_open(); if (tag->code == 4) { // PlaceObject bitstream_putbytesLE(bs, swf_tag_place->character_id, 2); bitstream_putbytesLE(bs, swf_tag_place->depth, 2); ret = swf_matrix_build(bs, &(swf_tag_place->matrix)); if (ret) { fprintf(stderr, "ERROR: swf_tag_place_output_detail: swf_tag_place->matrix build failed. character_id=%d\n", swf_tag_place->character_id); bitstream_close(bs); return NULL; } if (swf_tag_place->color_transform.has_add_terms || swf_tag_place->color_transform.has_mult_terms) { // optional ret = swf_cxform_build(bs, &(swf_tag_place->color_transform)); if (ret) { fprintf(stderr, "ERROR: swf_tag_place_output_detail: swf_tag_place->color_transform build failed. character_id=%d\n", swf_tag_place->character_id); bitstream_close(bs); return NULL; } } } else if (tag->code == 26) { // PlaceObject2 bitstream_putbit(bs, swf_tag_place->flag_has_clip_action); bitstream_putbit(bs, swf_tag_place->flag_has_clip_depth); bitstream_putbit(bs, swf_tag_place->flag_has_name); bitstream_putbit(bs, swf_tag_place->flag_has_ratio); bitstream_putbit(bs, swf_tag_place->flag_has_color_transform); bitstream_putbit(bs, swf_tag_place->flag_has_matrix); bitstream_putbit(bs, swf_tag_place->flag_has_character); bitstream_putbit(bs, swf_tag_place->flag_has_move); bitstream_putbytesLE(bs, swf_tag_place->depth, 2); if (swf_tag_place->flag_has_character) { bitstream_putbytesLE(bs, swf_tag_place->character_id, 2); } if (swf_tag_place->flag_has_matrix) { ret = swf_matrix_build(bs, &(swf_tag_place->matrix)); if (ret) { fprintf(stderr, "ERROR: swf_tag_place_output_detail: swf_tag_place->matrix build failed. character_id=%d\n", swf_tag_place->character_id); bitstream_close(bs); return NULL; } } if (swf_tag_place->flag_has_color_transform) { ret = swf_cxformwithalpha_build(bs, &(swf_tag_place->color_transform_with_alpha)); if (ret) { fprintf(stderr, "ERROR: swf_tag_place_output_detail: swf_tag_place->color_transform build failed. character_id=%d\n", swf_tag_place->character_id); bitstream_close(bs); return NULL; } } if (swf_tag_place->flag_has_ratio) { bitstream_putbytesLE(bs, swf_tag_place->ratio, 2); } if (swf_tag_place->flag_has_name) { bitstream_putstring(bs, (unsigned char *) swf_tag_place->name, strlen(swf_tag_place->name) + 1); } if (swf_tag_place->flag_has_clip_depth) { bitstream_putbytesLE(bs, swf_tag_place->clip_depth, 2); } // TODO: clip action data for SWF 5 } else { bitstream_close(bs); return NULL; // unknown tag; } data = bitstream_steal(bs, length); bitstream_close(bs); return data; }
int swf_tag_jpeg3_input_detail(swf_tag_t *tag, struct swf_object_ *swf) { swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL; unsigned char *data = NULL; unsigned long length; unsigned long offset_to_alpha; bitstream_t *bs = NULL; unsigned long offset, alpha_data_len; unsigned char *old_buff_ref = NULL, *new_buff = NULL; unsigned long origsize; int result; (void) swf; if (tag == NULL) { fprintf(stderr, "swf_tag_jpeg3_input_detail: tag == NULL\n"); return 1; } swf_tag_jpeg = tag->detail; data = tag->data; length = tag->length; if (swf_tag_jpeg == NULL) { fprintf(stderr, "ERROR: swf_tag_jpeg3_input_detail: swf_tag_jpeg == NULL\n"); return 1; } bs = bitstream_open(); bitstream_input(bs, data, length); swf_tag_jpeg->image_id = bitstream_getbytesLE(bs, 2); offset_to_alpha = bitstream_getbytesLE(bs, 4); swf_tag_jpeg->offset_to_alpha = offset_to_alpha; swf_tag_jpeg->jpeg_data = bitstream_output_sub(bs, 2 + 4 , offset_to_alpha); if (swf_tag_jpeg->jpeg_data == NULL) { free(swf_tag_jpeg); bitstream_close(bs); fprintf(stderr, "swf_tag_jpeg3_create_detail: swf_tag_jpeg->jpeg_data\n"); return 1; } swf_tag_jpeg->jpeg_data_len = offset_to_alpha; offset = 2 + 4 + offset_to_alpha; alpha_data_len = length - offset; // TODO: analyze jpeg and get width and height origsize = 512 * alpha_data_len; // XXX greater than jpeg1,2 new_buff = malloc(origsize); // enough size? old_buff_ref = bitstream_buffer(bs, offset); result = uncompress(new_buff, &origsize, old_buff_ref, alpha_data_len); if (result == Z_BUF_ERROR) { // XXX origsize *= 2; new_buff = realloc(new_buff, origsize); // enough size? if (new_buff == NULL) { free(swf_tag_jpeg); bitstream_close(bs); fprintf(stderr, "swf_tag_jpeg3_create_detail: realloc(%p, %lu) failed\n", new_buff, origsize); return 1; } result = uncompress(new_buff, &origsize, old_buff_ref, alpha_data_len); } if (result == Z_OK) { swf_tag_jpeg->alpha_data = realloc(new_buff, origsize); swf_tag_jpeg->alpha_data_len = origsize; } else { if (result == Z_MEM_ERROR) { fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: Z_MEM_ERROR: can't malloc\n"); } else if (result == Z_BUF_ERROR) { fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: Z_BUF_ERROR: not enough buff size\n"); } else if (result == Z_DATA_ERROR) { fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: Z_DATA_ERROR: corrupted or imcomplete data\n"); } else { fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: failed by unknown reason (%d)\n", result); } free(new_buff); } bitstream_close(bs); return 0; }
int swf_action_list_replace_strings(swf_action_list_t *action_list, int *modified, y_keyvalue_t *kv) { swf_action_t *action; if (modified) { *modified = 0; } for (action=action_list->head ; action ; action=action->next) { if (action->action_id < 0x80) { continue; // skip (no string) } switch(action->action_id) { int type; unsigned char *token; int token_len; bitstream_t *bs; char *value; int value_len; int count; int m = 0; int i; case 0x83: // Get URL m = 0; bs = bitstream_open(); token = action->action_data; token_len = strlen((char *) token); value = y_keyvalue_get(kv, (char *)token, token_len, &value_len); if (value) { bitstream_putstring(bs, (unsigned char *) value, value_len); bitstream_putbyte(bs, '\0'); m = 1; } else { bitstream_putstring(bs, (unsigned char *) token, token_len); bitstream_putbyte(bs, '\0'); } token += token_len + 1; token_len = strlen((char *) token); value = y_keyvalue_get(kv, (char *)token, token_len, &value_len); if (value) { bitstream_putstring(bs, (unsigned char *)value, value_len); bitstream_putbyte(bs, '\0'); m = 1; } else { bitstream_putstring(bs, (unsigned char *)token, token_len); bitstream_putbyte(bs, '\0'); } if (m) { unsigned long length; free(action->action_data); action->action_data = bitstream_steal(bs, &length); action->action_length = length; if (modified) { *modified = 1; } } bitstream_close(bs); break; case 0x88: // ActionConstantPool m = 0; count = action->action_data[0] + 0x100 * action->action_data[1]; token = action->action_data + 2; bs = bitstream_open(); bitstream_putbytesLE(bs, count, 2); for (i = 0 ; i < count ; i++) { token_len = strlen((char *) token); value = y_keyvalue_get(kv, (char *)token, token_len, &value_len); if (value) { bitstream_putstring(bs, (unsigned char *)value, value_len); bitstream_putbyte(bs, '\0'); m = 1; } else { bitstream_putstring(bs, (unsigned char *)token , token_len); bitstream_putbyte(bs, '\0'); } token += token_len + 1; } if (m) { unsigned long length; free(action->action_data); action->action_data = bitstream_steal(bs, &length); action->action_length = length; if (modified) { *modified = 1; } } bitstream_close(bs); break; case 0x96: // Push Data m = 0; token = action->action_data; bs = bitstream_open(); while (token < action->action_data + action->action_length) { static const int action_value_type_size[] = { -1, // 0: String 4, // 1: Float 0, // 2: NULL 0, // 3: Undefined 1, // 4: Register 1, // 5: Boolean 8, // 6: Double 4, // 7: Integer 1, // 8: Dictionary Lookup 2, // 9: Large Dictionary Lookup }; type = token[0]; bitstream_putbyte(bs, type); token += 1; if (type == 0) { // String token_len = strlen((char *) token); value = y_keyvalue_get(kv, (char *)token, token_len, &value_len); if (value) { bitstream_putstring(bs, (unsigned char *)value, value_len); bitstream_putbyte(bs, '\0'); m = 1; } else { bitstream_putstring(bs, (unsigned char *)token , token_len); bitstream_putbyte(bs, '\0'); } token += token_len + 1; } else if (type < 10) { // else String bitstream_putstring(bs, token, action_value_type_size[type]); token += action_value_type_size[type]; } else { fprintf(stderr, "swf_action_list_replace_strings: illegal type=%d\n", type); bitstream_close(bs); return 1; // FAILURE } } if (m) { unsigned long length; free(action->action_data); action->action_data = bitstream_steal(bs, &length); action->action_length = length; if (modified) { *modified = 1; } } bitstream_close(bs); break; } } return 0; }
int main(int argc, char **argv) { char *png_filename = NULL; struct stat filestat; FILE *fp = NULL; my_png_buffer png_buff; int is_png; png_uint_32 png_width, png_height; int bpp, color_type; png_bytepp image_data; png_uint_32 x, y; png_color *palette = NULL; int palette_num = 0; png_bytep trans = NULL; int num_trans; png_color_16p trans_values = NULL; int palette_dump_unit; if (argc != 2) { char *program_filename = argv[0]; fprintf(stderr, "Usage: %s <png_filename>\n", program_filename); return EXIT_FAILURE; } png_filename = argv[1]; // printf("png_filename=%s\n", png_filename); if(stat(png_filename, &filestat)) { perror("stat pngfile"); return EXIT_FAILURE; } png_buff.data_len = filestat.st_size; png_buff.data_offset = 0; // printf("png_buff.data_len=%lu\n", png_buff.data_len); fp = fopen(png_filename, "rb"); if (! fp) { fprintf(stderr, "Can't open file(%s)\n", png_filename); return EXIT_FAILURE; } png_buff.data = calloc(png_buff.data_len, 1); fread(png_buff.data, 1, png_buff.data_len, fp); fclose(fp); is_png = png_check_sig((png_bytep)png_buff.data, 8); if (! is_png) { fprintf(stderr, "is not PNG!\n"); free(png_buff.data); return EXIT_FAILURE; } png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL,NULL,NULL); if (! png_ptr) { fprintf(stderr, "can't create read_struct\n"); free(png_buff.data); return EXIT_FAILURE; } png_infop png_info_ptr = png_create_info_struct(png_ptr); if (! png_info_ptr) { fprintf(stderr, "can't create info_struct\n"); png_destroy_read_struct (&png_ptr, NULL, NULL); free(png_buff.data); return EXIT_FAILURE; } png_data_read(png_ptr, &png_buff); png_read_info(png_ptr, png_info_ptr); png_get_IHDR(png_ptr, png_info_ptr, &png_width, &png_height, &bpp, &color_type, NULL, NULL, NULL); printf("(width, height)=(%lu,%lu) bpp=%d", png_width, png_height, bpp); printf(" color_type=%d", color_type); switch(color_type) { case PNG_COLOR_TYPE_GRAY: printf("(GRAY)"); if (! png_get_tRNS(png_ptr, png_info_ptr, &trans, &num_trans, &trans_values)) { num_trans = 0; } printf(" num_trans=%d", num_trans); break; case PNG_COLOR_TYPE_GRAY_ALPHA: printf("(GRAY_ALPHA)"); break; case PNG_COLOR_TYPE_RGB: printf("(RGB)"); if (png_get_PLTE(png_ptr, png_info_ptr, &palette, &palette_num)) { printf(" palette_num=%d", palette_num); } if (! png_get_tRNS(png_ptr, png_info_ptr, &trans, &num_trans, &trans_values)) { num_trans = 0; } printf(" num_trans=%d", num_trans); break; case PNG_COLOR_TYPE_RGB_ALPHA: printf("(RGB_ALPHA)"); if (png_get_PLTE(png_ptr, png_info_ptr, &palette, &palette_num)) { printf(" palette_num=%d", palette_num); } // if (png_get_valid(png_ptr, png_info_ptr, PNG_INFO_tRNS)) // png_set_tRNS_to_alpha(png_ptr); break; case PNG_COLOR_TYPE_PALETTE: printf("(PALETTE)"); png_get_PLTE(png_ptr, png_info_ptr, &palette, &palette_num); printf(" palette_num=%d", palette_num); if (! png_get_tRNS(png_ptr, png_info_ptr, &trans, &num_trans, &trans_values)) { num_trans = 0; } printf(" num_trans=%d", num_trans); break; default: printf("color_type(%d) not implement yet.\n", color_type); } printf("\n"); /* image */ 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_ptr)); } png_read_image(png_ptr, image_data); if (num_trans == 0) { palette_dump_unit = 8; } else { palette_dump_unit = 4; } if (color_type == PNG_COLOR_TYPE_PALETTE) { int i, j; for (i = 0 ; i < palette_num ; i+=palette_dump_unit ) { printf("[%03d]", i); for (j = 0 ; (j < palette_dump_unit) && ((i+j) < palette_num) ; j++) { if ((i+j) < num_trans) { printf(" #%02x%02x%02x(%02x)", palette[i+j].red, palette[i+j].green, palette[i+j].blue, trans[i+j] & 0xff); } else { printf(" #%02x%02x%02x", palette[i+j].red, palette[i+j].green, palette[i+j].blue); } } printf("\n"); } for (y=0; y < png_height; y++) { unsigned char *linedata = image_data[y]; bitstream_t *bs = bitstream_open(); bitstream_input(bs, linedata, png_get_rowbytes(png_ptr, png_info_ptr)); printf("y=%lu: ", y); for (x=0; x < png_width; x++) { int colorindex = bitstream_getbits(bs, bpp); printf("%02x ", colorindex); } bitstream_close(bs); printf("\n"); } } else { for (y=0; y < png_height; y++) { printf("y=%lu: ", y); for (x=0; x < png_width; x++) { switch(color_type) { case PNG_COLOR_TYPE_GRAY: printf("%02x ", image_data[y][x]); break; case PNG_COLOR_TYPE_RGB: printf("%02x%02x%02x ", image_data[y][3*x], image_data[y][3*x+1], image_data[y][3*x+2]); break; case PNG_COLOR_TYPE_RGB_ALPHA: printf("%02x%02x%02x(%02x) ", image_data[y][4*x], image_data[y][4*x+1], image_data[y][4*x+2], image_data[y][4*x+3]); break; default: break; } } printf("\n"); } } /* * finish */ for (y=0; y < png_height; y++) { free(image_data[y]); } free(image_data); png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL); free(png_buff.data); return EXIT_SUCCESS; }