X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=images%2Fio-main.c;h=c2975842c3e7076b2e4e8162250c865a39c4d660;hb=1cf8ac51f5495ccd5187dc220ffc69e95d6e0cfc;hp=eb04faa9b46a55fc17310b752b77d43830682a70;hpb=6a4b173e7d57907f20a4397e68d277d74a2bc840;p=libucw.git diff --git a/images/io-main.c b/images/io-main.c index eb04faa9..c2975842 100644 --- a/images/io-main.c +++ b/images/io-main.c @@ -9,17 +9,56 @@ #undef LOCAL_DEBUG -#include "lib/lib.h" +#include "ucw/lib.h" +#include "ucw/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 @@ -35,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->thread, io->image); - io->image_destroy = 0; + image_destroy(io->image); + io->flags &= ~IMAGE_IO_NEED_DESTROY; io->image = NULL; } } @@ -49,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); } @@ -59,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 @@ -72,37 +125,39 @@ image_io_read_header(struct image_io *io) image_io_image_destroy(io); switch (io->format) { case IMAGE_FORMAT_JPEG: -#if defined(CONFIG_LIBJPEG) +#if defined(CONFIG_IMAGES_LIBJPEG) return libjpeg_read_header(io); -#elif defined(CONFIG_LIBMAGICK) +#elif defined(CONFIG_IMAGES_LIBMAGICK) return libmagick_read_header(io); #endif break; case IMAGE_FORMAT_PNG: -#if defined(CONFIG_LIBPNG) +#if defined(CONFIG_IMAGES_LIBPNG) return libpng_read_header(io); -#elif defined(CONFIG_LIBMAGICK) +#elif defined(CONFIG_IMAGES_LIBMAGICK) return libmagick_read_header(io); #endif break; case IMAGE_FORMAT_GIF: -#if defined(CONFIG_LIBUNGIG) +#if defined(CONFIG_IMAGES_LIBUNGIF) || defined(CONFIG_IMAGES_LIBGIF) return libungif_read_header(io); -#elif defined(CONFIG_LIBMAGICK) +#elif defined(CONFIG_IMAGES_LIBMAGICK) return libmagick_read_header(io); #endif 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; } @@ -115,9 +170,9 @@ image_io_read_data(struct image_io *io, int ref) int result; switch (io->format) { case IMAGE_FORMAT_JPEG: -#if defined(CONFIG_LIBJPEG) +#if defined(CONFIG_IMAGES_LIBJPEG) result = libjpeg_read_data(io); -#elif defined(CONFIG_LIBMAGICK) +#elif defined(CONFIG_IMAGES_LIBMAGICK) result = libmagick_read_data(io); #else ASSERT(0); @@ -125,9 +180,9 @@ image_io_read_data(struct image_io *io, int ref) break; case IMAGE_FORMAT_PNG: -#if defined(CONFIG_LIBPNG) +#if defined(CONFIG_IMAGES_LIBPNG) result = libpng_read_data(io); -#elif defined(CONFIG_LIBMAGICK) +#elif defined(CONFIG_IMAGES_LIBMAGICK) result = libmagick_read_data(io); #else ASSERT(0); @@ -135,9 +190,17 @@ image_io_read_data(struct image_io *io, int ref) break; case IMAGE_FORMAT_GIF: -#if defined(CONFIG_LIBUNGIF) +#if defined(CONFIG_IMAGES_LIBUNGIF) || defined(CONFIG_IMAGES_LIBGIF) result = libungif_read_data(io); -#elif defined(CONFIG_LIBMAGICK) +#elif defined(CONFIG_IMAGES_LIBMAGICK) + result = libmagick_read_data(io); +#else + ASSERT(0); +#endif + break; + + case IMAGE_FORMAT_UNDEFINED: +#if defined(CONFIG_IMAGES_LIBMAGICK) result = libmagick_read_data(io); #else ASSERT(0); @@ -149,8 +212,10 @@ image_io_read_data(struct image_io *io, int ref) } 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 @@ -172,21 +237,31 @@ image_io_write(struct image_io *io) image_io_read_cancel(io); switch (io->format) { case IMAGE_FORMAT_JPEG: -#if defined(CONFIG_LIBJPEG) +#if defined(CONFIG_IMAGES_LIBJPEG) return libjpeg_write(io); +#elif defined(CONFIG_IMAGES_LIBMAGICK) + return libmagick_write(io); #endif break; case IMAGE_FORMAT_PNG: +#if defined(CONFIG_IMAGES_LIBPNG) + return libpng_write(io); +#elif defined(CONFIG_IMAGES_LIBMAGICK) + return libmagick_write(io); +#endif break; case IMAGE_FORMAT_GIF: +#if defined(CONFIG_IMAGES_LIBMAGICK) + return libmagick_write(io); +#endif break; 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; } @@ -226,3 +301,78 @@ image_file_name_to_format(byte *file_name) byte *extension = strrchr(file_name, '.'); return extension ? image_extension_to_format(extension + 1) : IMAGE_FORMAT_UNDEFINED; } + +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) & IMAGE_NEW_FLAGS)) + return rdi->image = image_new(io->context, cols, rows, flags & IMAGE_IO_IMAGE_FLAGS, NULL); + else + return rdi->image = image_new(io->context, io->cols, io->rows, io->flags & IMAGE_IO_IMAGE_FLAGS, io->pool); +} + +int +image_io_read_data_finish(struct image_io_read_data_internals *rdi, struct image_io *io) +{ + DBG("image_io_read_data_finish()"); + if (rdi->need_transformations) + { + /* Scale the image */ + if (io->cols != rdi->image->cols || io->rows != rdi->image->rows) + { + DBG("Scaling image"); + 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->context, img, rdi->image))) + { + image_destroy(rdi->image); + image_destroy(img); + return 0; + } + image_destroy(rdi->image); + rdi->image = img; + } + + /* Convert pixel format */ + if (io->flags != rdi->image->flags) + { + struct image *img = image_new(io->context, io->cols, io->rows, io->flags, io->pool); + if (unlikely(!img)) + { + image_destroy(rdi->image); + return 0; + } + 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); + image_destroy(img); + return 0; + } + image_destroy(rdi->image); + rdi->image = img; + } + } + + /* Success */ + io->image = rdi->image; + return 1; +} + +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->image) + image_destroy(rdi->image); +}