📄 swfdec_image.c
字号:
/* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> * 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <zlib.h>#include <string.h>#include "jpeg.h"#include "swfdec_image.h"#include "swfdec_cache.h"#include "swfdec_debug.h"#include "swfdec_swf_decoder.h"static void merge_alpha (SwfdecImage * image, unsigned char *image_data, unsigned char *alpha);static void swfdec_image_colormap_decode (SwfdecImage * image, unsigned char *dest, unsigned char *src, unsigned char *colormap, int colormap_len);G_DEFINE_TYPE (SwfdecImage, swfdec_image, SWFDEC_TYPE_CACHED)static voidswfdec_image_unload (SwfdecCached *cached){ SwfdecImage *image = SWFDEC_IMAGE (cached); if (image->surface) { cairo_surface_destroy (image->surface); image->surface = NULL; } else if (image->data) { g_free (image->data); } image->data = NULL;}static voidswfdec_image_dispose (GObject *object){ SwfdecImage * image = SWFDEC_IMAGE (object); if (image->jpegtables) { swfdec_buffer_unref (image->jpegtables); image->jpegtables = NULL; } if (image->raw_data) { swfdec_buffer_unref (image->raw_data); image->raw_data = NULL; } G_OBJECT_CLASS (swfdec_image_parent_class)->dispose (object);}static voidswfdec_image_class_init (SwfdecImageClass * g_class){ GObjectClass *object_class = G_OBJECT_CLASS (g_class); SwfdecCachedClass *cached_class = SWFDEC_CACHED_CLASS (g_class); object_class->dispose = swfdec_image_dispose; cached_class->unload = swfdec_image_unload;}static voidswfdec_image_init (SwfdecImage * image){}intswfdec_image_jpegtables (SwfdecSwfDecoder * s){ SwfdecBits *bits = &s->b; SWFDEC_DEBUG ("swfdec_image_jpegtables"); s->jpegtables = swfdec_buffer_ref (bits->buffer); bits->ptr += bits->buffer->length; return SWFDEC_STATUS_OK;}inttag_func_define_bits_jpeg (SwfdecSwfDecoder * s){ SwfdecBits *bits = &s->b; int id; SwfdecImage *image; SWFDEC_LOG ("tag_func_define_bits_jpeg"); id = swfdec_bits_get_u16 (bits); SWFDEC_LOG (" id = %d", id); image = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_IMAGE); if (!image) return SWFDEC_STATUS_OK; image->type = SWFDEC_IMAGE_TYPE_JPEG; if (!s->jpegtables) { SWFDEC_ERROR("No global JPEG tables available"); } else { image->jpegtables = swfdec_buffer_ref (s->jpegtables); } image->raw_data = swfdec_buffer_ref (bits->buffer); bits->ptr += bits->buffer->length - 2; return SWFDEC_STATUS_OK;}static voidswfdec_image_jpeg_load (SwfdecImage *image){ JpegDecoder *dec; dec = jpeg_decoder_new (); if (image->jpegtables) { if (image->jpegtables->data[0] != 0xff || image->jpegtables->data[1] != 0xd8) { SWFDEC_ERROR("not jpeg %02x %02x", image->jpegtables->data[0], image->jpegtables->data[1]); jpeg_decoder_free (dec); return; } jpeg_decoder_addbits (dec, image->jpegtables->data, image->jpegtables->length); } if (image->raw_data->data[2] != 0xff || image->raw_data->data[3] != 0xd8) { SWFDEC_ERROR("not jpeg %02x %02x", image->raw_data->data[2], image->raw_data->data[3]); jpeg_decoder_free (dec); return; } jpeg_decoder_addbits (dec, image->raw_data->data + 2, image->raw_data->length - 2); jpeg_decoder_parse (dec); jpeg_decoder_get_image_size (dec, &image->width, &image->height); if (image->width == 0 || image->height == 0) { jpeg_decoder_free (dec); return; } swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height); image->data = jpeg_decoder_get_argb_image (dec); image->rowstride = image->width * 4; jpeg_decoder_free (dec); SWFDEC_LOG (" width = %d", image->width); SWFDEC_LOG (" height = %d", image->height);}inttag_func_define_bits_jpeg_2 (SwfdecSwfDecoder * s){ SwfdecBits *bits = &s->b; int id; SwfdecImage *image; id = swfdec_bits_get_u16 (bits); SWFDEC_LOG (" id = %d", id); image = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_IMAGE); if (!image) return SWFDEC_STATUS_OK; image->type = SWFDEC_IMAGE_TYPE_JPEG2; image->raw_data = swfdec_buffer_ref (bits->buffer); bits->ptr += bits->buffer->length - 2; return SWFDEC_STATUS_OK;}static voidswfdec_image_jpeg2_load (SwfdecImage *image){ JpegDecoder *dec; dec = jpeg_decoder_new (); if (image->raw_data->data[2] != 0xff || image->raw_data->data[3] != 0xd8) { SWFDEC_ERROR("not jpeg %02x %02x", image->raw_data->data[2], image->raw_data->data[3]); jpeg_decoder_free (dec); return; } jpeg_decoder_addbits (dec, image->raw_data->data + 2, image->raw_data->length - 2); jpeg_decoder_parse (dec); jpeg_decoder_get_image_size (dec, &image->width, &image->height); if (image->width == 0 || image->height == 0) { jpeg_decoder_free (dec); return; } swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height); image->data = jpeg_decoder_get_argb_image (dec); image->rowstride = image->width * 4; jpeg_decoder_free (dec); SWFDEC_LOG (" width = %d", image->width); SWFDEC_LOG (" height = %d", image->height);}inttag_func_define_bits_jpeg_3 (SwfdecSwfDecoder * s){ SwfdecBits *bits = &s->b; guint id; SwfdecImage *image; id = swfdec_bits_get_u16 (bits); SWFDEC_LOG (" id = %d", id); image = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_IMAGE); if (!image) return SWFDEC_STATUS_OK; image->type = SWFDEC_IMAGE_TYPE_JPEG3; image->raw_data = swfdec_bits_get_buffer (bits, -1); return SWFDEC_STATUS_OK;}static voidswfdec_image_jpeg3_load (SwfdecImage *image){ JpegDecoder *dec; SwfdecBits bits; SwfdecBuffer *buffer; int jpeg_length; swfdec_bits_init (&bits, image->raw_data); jpeg_length = swfdec_bits_get_u32 (&bits); buffer = swfdec_bits_get_buffer (&bits, jpeg_length); if (buffer == NULL) return; dec = jpeg_decoder_new (); if (buffer->data[0] != 0xff || buffer->data[1] != 0xd8) { SWFDEC_ERROR("not jpeg %02x %02x", buffer->data[0], buffer->data[1]); jpeg_decoder_free (dec); return; } jpeg_decoder_addbits (dec, buffer->data, buffer->length); swfdec_buffer_unref (buffer); jpeg_decoder_parse (dec); jpeg_decoder_get_image_size (dec, &image->width, &image->height); if (image->width == 0 || image->height == 0) { jpeg_decoder_free (dec); return; } swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height); image->data = jpeg_decoder_get_argb_image (dec); image->rowstride = image->width * 4; jpeg_decoder_free (dec); buffer = swfdec_bits_decompress (&bits, -1, image->width * image->height); if (buffer) { merge_alpha (image, image->data, buffer->data); swfdec_buffer_unref (buffer); } else { SWFDEC_WARNING ("cannot set alpha channel information, decompression failed"); } SWFDEC_LOG (" width = %d", image->width); SWFDEC_LOG (" height = %d", image->height);}static voidmerge_alpha (SwfdecImage * image, unsigned char *image_data, unsigned char *alpha){ int x, y; unsigned char *p; for (y = 0; y < image->height; y++) { p = image_data + y * image->rowstride; for (x = 0; x < image->width; x++) { p[SWFDEC_COLOR_INDEX_ALPHA] = *alpha; p += 4; alpha++; } }}static voidswfdec_image_lossless_load (SwfdecImage *image){ int format; guint color_table_size; unsigned char *ptr; SwfdecBits bits; int have_alpha = (image->type == SWFDEC_IMAGE_TYPE_LOSSLESS2); swfdec_bits_init (&bits, image->raw_data); format = swfdec_bits_get_u8 (&bits); SWFDEC_LOG (" format = %d", format); image->width = swfdec_bits_get_u16 (&bits); SWFDEC_LOG (" width = %d", image->width); image->height = swfdec_bits_get_u16 (&bits); SWFDEC_LOG (" height = %d", image->height);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -