X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=images%2Fio-main.c;h=f69b8b6c4a4bf926706f365c36cbbd5f2d6f3dc1;hb=3d7098f19d62bb9000048d1f36a2091e0fc263b0;hp=9442c7e0170084a7cb106d4b67352e65b00f2c92;hpb=422234aee83909200561bcce45f6bc1ed84f4789;p=libucw.git diff --git a/images/io-main.c b/images/io-main.c index 9442c7e0..f69b8b6c 100644 --- a/images/io-main.c +++ b/images/io-main.c @@ -7,20 +7,58 @@ * of the GNU Lesser General Public License. */ -#define LOCAL_DEBUG +#undef LOCAL_DEBUG #include "lib/lib.h" +#include "lib/mempool.h" #include "images/images.h" +#include "images/error.h" #include "images/io-main.h" +#include "images/color.h" + #include -void -image_io_init(struct image_thread *it, struct image_io *io) +int +image_io_init(struct image_context *ctx, struct image_io *io) { DBG("image_io_init()"); bzero(io, sizeof(*io)); - io->thread = it; + io->context = ctx; +#ifdef CONFIG_IMAGES_LIBJPEG + if (!libjpeg_init(io)) + goto libjpeg_failed; +#endif +#ifdef CONFIG_IMAGES_LIBPNG + if (!libpng_init(io)) + goto libpng_failed; +#endif +#ifdef CONFIG_IMAGES_LIBUNGIF + if (!libungif_init(io)) + goto libungif_failed; +#endif +#ifdef CONFIG_IMAGES_LIBMAGICK + if (!libmagick_init(io)) + goto libmagick_failed; +#endif io->internal_pool = mp_new(1024); + return 1; +#ifdef CONFIG_IMAGES_LIBMAGICK + libmagick_cleanup(io); +libmagick_failed: +#endif +#ifdef CONFIG_IMAGES_LIBUNGIF + libungif_cleanup(io); +libungif_failed: +#endif +#ifdef CONFIG_IMAGES_LIBPNG + libpng_cleanup(io); +libpng_failed: +#endif +#ifdef CONFIG_IMAGES_LIBJPEG + libjpeg_cleanup(io); +libjpeg_failed: +#endif + return 0; } static inline void @@ -36,10 +74,10 @@ image_io_read_cancel(struct image_io *io) static inline void image_io_image_destroy(struct image_io *io) { - if (io->image_destroy) + if (io->image && (io->flags & IMAGE_IO_NEED_DESTROY)) { image_destroy(io->image); - io->image_destroy = 0; + io->flags &= ~IMAGE_IO_NEED_DESTROY; io->image = NULL; } } @@ -50,6 +88,18 @@ image_io_cleanup(struct image_io *io) DBG("image_io_cleanup()"); image_io_read_cancel(io); image_io_image_destroy(io); +#ifdef CONFIG_IMAGES_LIBMAGICK + libmagick_cleanup(io); +#endif +#ifdef CONFIG_IMAGES_LIBUNGIF + libungif_cleanup(io); +#endif +#ifdef CONFIG_IMAGES_LIBPNG + libpng_cleanup(io); +#endif +#ifdef CONFIG_IMAGES_LIBJPEG + libjpeg_cleanup(io); +#endif mp_delete(io->internal_pool); } @@ -60,9 +110,11 @@ image_io_reset(struct image_io *io) image_io_read_cancel(io); image_io_image_destroy(io); struct mempool *pool = io->internal_pool; + struct image_context *ctx = io->context; mp_flush(pool); bzero(io, sizeof(*io)); io->internal_pool = pool; + io->context = ctx; } int @@ -97,13 +149,15 @@ image_io_read_header(struct image_io *io) break; case IMAGE_FORMAT_UNDEFINED: - // FIXME: auto-detect +#if defined (CONFIG_IMAGES_LIBMAGICK) + return libmagick_read_header(io); +#endif break; default: ASSERT(0); } - image_thread_err(io->thread, IMAGE_ERR_INVALID_FILE_FORMAT, "Image format not supported."); + IMAGE_ERROR(io->context, IMAGE_ERROR_INVALID_FILE_FORMAT, "Image format not supported."); return 0; } @@ -145,13 +199,23 @@ image_io_read_data(struct image_io *io, int ref) #endif break; + case IMAGE_FORMAT_UNDEFINED: +#if defined(CONFIG_IMAGES_LIBMAGICK) + result = libmagick_read_data(io); +#else + ASSERT(0); +#endif + break; + default: ASSERT(0); } if (result) { - if (ref) - io->image_destroy = 0; + if (!ref) + io->flags |= IMAGE_IO_NEED_DESTROY; + else + io->flags &= ~IMAGE_IO_NEED_DESTROY; return io->image; } else @@ -197,7 +261,7 @@ image_io_write(struct image_io *io) default: break; } - image_thread_err(io->thread, IMAGE_ERR_INVALID_FILE_FORMAT, "Image format not supported."); + IMAGE_ERROR(io->context, IMAGE_ERROR_INVALID_FILE_FORMAT, "Output format not supported."); return 0; } @@ -242,16 +306,11 @@ struct image * image_io_read_data_prepare(struct image_io_read_data_internals *rdi, struct image_io *io, uns cols, uns rows, uns flags) { DBG("image_io_read_data_prepare()"); - if (rdi->need_transformations = io->cols != cols || io->rows != rows || io->flags != flags) - { - rdi->need_destroy = 1; - return rdi->image = image_new(io->thread, cols, rows, flags & IMAGE_IO_IMAGE_FLAGS, NULL); - } + if (rdi->need_transformations = io->cols != cols || io->rows != rows || + ((io->flags ^ flags) & IMAGE_NEW_FLAGS)) + return rdi->image = image_new(io->context, cols, rows, flags & IMAGE_IO_IMAGE_FLAGS, NULL); else - { - rdi->need_destroy = !io->pool; - return rdi->image = image_new(io->thread, io->cols, io->rows, io->flags & IMAGE_IO_IMAGE_FLAGS, io->pool); - } + return rdi->image = image_new(io->context, io->cols, io->rows, io->flags & IMAGE_IO_IMAGE_FLAGS, io->pool); } int @@ -264,52 +323,49 @@ image_io_read_data_finish(struct image_io_read_data_internals *rdi, struct image if (io->cols != rdi->image->cols || io->rows != rdi->image->rows) { DBG("Scaling image"); - rdi->need_transformations = io->flags != rdi->image->flags; - rdi->need_destroy = rdi->need_transformations || !io->pool; - struct image *img = image_new(io->thread, io->cols, io->rows, rdi->image->flags, rdi->need_transformations ? NULL : io->pool); + uns flags = rdi->image->flags; + if (!(rdi->need_transformations = ((io->flags ^ rdi->image->flags) & (IMAGE_NEW_FLAGS & ~IMAGE_PIXELS_ALIGNED)))) + flags = io->flags; + struct image *img = image_new(io->context, io->cols, io->rows, flags, rdi->need_transformations ? NULL : io->pool); if (unlikely(!img)) { image_destroy(rdi->image); return 0; } - if (unlikely(!image_scale(io->thread, img, rdi->image))) + if (unlikely(!image_scale(io->context, img, rdi->image))) { image_destroy(rdi->image); - if (rdi->need_destroy) - image_destroy(img); + image_destroy(img); return 0; } + image_destroy(rdi->image); rdi->image = img; } - /* Merge with background */ - if ((io->flags ^ rdi->image->flags) & IMAGE_ALPHA) + /* Convert pixel format */ + if (io->flags != rdi->image->flags) { - DBG("Aplying background"); - rdi->need_transformations = 0; - rdi->need_destroy = rdi->need_transformations || !io->pool; - struct image *img = image_new(io->thread, io->cols, io->rows, io->flags, rdi->need_transformations ? NULL : io->pool); + struct image *img = image_new(io->context, io->cols, io->rows, io->flags, io->pool); if (unlikely(!img)) { image_destroy(rdi->image); return 0; } - if (unlikely(!image_apply_background(io->thread, img, rdi->image, &io->background_color))) + struct image_conv_options opt = image_conv_defaults; + opt.background = io->background_color; + if (unlikely(!image_conv(io->context, img, rdi->image, &opt))) { image_destroy(rdi->image); - if (rdi->need_destroy) - image_destroy(img); + image_destroy(img); return 0; } + image_destroy(rdi->image); rdi->image = img; } - - ASSERT(!rdi->need_transformations); } /* Success */ io->image = rdi->image; - io->image_destroy = rdi->need_destroy; return 1; } @@ -317,6 +373,6 @@ void image_io_read_data_break(struct image_io_read_data_internals *rdi, struct image_io *io UNUSED) { DBG("image_io_read_data_break()"); - if (rdi->need_destroy) + if (rdi->image) image_destroy(rdi->image); }