From: Pavel Charvat Date: Thu, 10 Aug 2006 07:45:59 +0000 (+0200) Subject: - bugfixes X-Git-Tag: holmes-import~600 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=cc158370cbaee83cafb5965f20dc2df848a4faef;p=libucw.git - bugfixes - new parameters to image-tool - io-libmagick can read info about image transparency --- diff --git a/images/image-dup-test.c b/images/image-dup-test.c index 0d18ece0..ecfa5500 100644 --- a/images/image-dup-test.c +++ b/images/image-dup-test.c @@ -114,7 +114,8 @@ main(int argc, char **argv) struct image *img1, *img2; - image_io_init(&it, &io); + if (!image_io_init(&it, &io)) + die("Cannot initialize image I/O (%s)", it.err_msg); MSG("Reading %s", file_name_1); io.fastbuf = bopen(file_name_1, O_RDONLY, 1 << 18); io.format = format_1 ? : image_file_name_to_format(file_name_1); diff --git a/images/image-sim-test.c b/images/image-sim-test.c index a9be56e9..27a63ee1 100644 --- a/images/image-sim-test.c +++ b/images/image-sim-test.c @@ -118,7 +118,8 @@ main(int argc, char **argv) struct image *img1, *img2; - image_io_init(&it, &io); + if (!image_io_init(&it, &io)) + die("Cannot initialize image I/O (%s)", it.err_msg); MSG("Reading %s", file_name_1); io.fastbuf = bopen(file_name_1, O_RDONLY, 1 << 18); io.format = format_1 ? : image_file_name_to_format(file_name_1); diff --git a/images/image-tool.c b/images/image-tool.c index f2170038..831c6577 100644 --- a/images/image-tool.c +++ b/images/image-tool.c @@ -24,30 +24,34 @@ usage(void) fputs("\ Usage: image-tool [options] infile [outfile]\n\ \n\ --q --quiet no progress messages\n\ --f --input-format input image format (jpeg, gif, png)\n\ --F --output-format output image format\n\ --s --size force output dimensions (100x200)\n\ --b --fit-to-box scale to fit the box (100x200)\n\ --c --colorspace force output colorspace (Gray, GrayAlpha, RGB, RGBAlpha)\n\ --Q --jpeg-quality JPEG quality (1..100)\n\ --g --background background color (hexadecimal RRGGBB)\n\ +-q --quiet no progress messages\n\ +-f --input-format input image format (jpeg, gif, png)\n\ +-F --output-format output image format\n\ +-s --size force output dimensions (100x200)\n\ +-b --fit-to-box scale to fit the box (100x200)\n\ +-c --colorspace force output colorspace (Gray, GrayAlpha, RGB, RGBAlpha)\n\ +-Q --jpeg-quality JPEG quality (1..100)\n\ +-g --background background color (hexadecimal RRGGBB)\n\ +-G --default-background background applied only if the image contains no background info (RRGGBB, default=FFFFFF)\n\ +-a --remove-alpha remove alpha channel\n\ ", stderr); exit(1); } -static char *shortopts = "qf:F:s:b:c:Q:g:"; +static char *shortopts = "qf:F:s:b:c:Q:g:G:a"; static struct option longopts[] = { - { "quiet", 0, 0, 'q' }, - { "input-format", 0, 0, 'f' }, - { "output-format", 0, 0, 'F' }, - { "size", 0, 0, 's' }, - { "fit-to-box", 0, 0, 'b' }, - { "colorspace", 0, 0, 'c' }, - { "jpeg-quality", 0, 0, 'Q' }, - { "background", 0, 0, 'g' }, - { NULL, 0, 0, 0 } + { "quiet", 0, 0, 'q' }, + { "input-format", 0, 0, 'f' }, + { "output-format", 0, 0, 'F' }, + { "size", 0, 0, 's' }, + { "fit-to-box", 0, 0, 'b' }, + { "colorspace", 0, 0, 'c' }, + { "jpeg-quality", 0, 0, 'Q' }, + { "background", 0, 0, 'g' }, + { "default-background", 0, 0, 'G' }, + { "remove-alpha", 0, 0, 'a' }, + { NULL, 0, 0, 0 } }; static uns verbose = 1; @@ -61,6 +65,21 @@ static uns fit_to_box; static uns channels_format; static uns jpeg_quality; static struct color background_color; +static struct color default_background_color; +static uns remove_alpha; + +static void +parse_color(struct color *color, byte *s) +{ + if (strlen(s) != 6) + usage(); + s = 0; + char *end; + long int v = strtol(s, &end, 16); + if (errno || *end || v < 0) + usage(); + color_make_rgb(color, (v >> 16) & 255, (v >> 8) & 255, v & 255); +} #define MSG(x...) do{ if (verbose) log(L_INFO, ##x); }while(0) @@ -69,6 +88,7 @@ main(int argc, char **argv) { log_init(argv[0]); int opt; + default_background_color = color_white; while ((opt = getopt_long(argc, argv, shortopts, longopts, NULL)) >= 0) switch (opt) { @@ -114,16 +134,13 @@ main(int argc, char **argv) usage(); break; case 'g': - { - if (strlen(optarg) != 6) - usage(); - errno = 0; - char *end; - long int v = strtol(optarg, &end, 16); - if (errno || *end || v < 0) - usage(); - color_make_rgb(&background_color, (v >> 16) & 255, (v >> 8) & 255, v & 255); - } + parse_color(&background_color, optarg); + break; + case 'G': + parse_color(&default_background_color, optarg); + break; + case 'a': + remove_alpha++; break; default: usage(); @@ -140,7 +157,8 @@ main(int argc, char **argv) struct image_thread it; struct image_io io; image_thread_init(&it); - image_io_init(&it, &io); + if (!image_io_init(&it, &io)) + die("Cannot initialize image I/O (%s)", it.err_msg); MSG("Reading %s", input_file_name); io.fastbuf = bopen(input_file_name, O_RDONLY, 1 << 18); @@ -177,7 +195,9 @@ main(int argc, char **argv) if (background_color.color_space) io.background_color = background_color; else if (!io.background_color.color_space) - io.background_color = color_white; + io.background_color = default_background_color; + if (remove_alpha) + io.flags &= ~IMAGE_ALPHA; if (channels_format) io.flags = io.flags & ~IMAGE_PIXEL_FORMAT | channels_format; if (!(io.flags & IMAGE_ALPHA)) diff --git a/images/images.h b/images/images.h index f0072941..236b0446 100644 --- a/images/images.h +++ b/images/images.h @@ -162,7 +162,7 @@ enum image_io_flags { IMAGE_IO_USE_BACKGROUND = 0x40000, /* [ I ] - merge transparent pixels with background_color */ }; -void image_io_init(struct image_thread *it, struct image_io *io); +int image_io_init(struct image_thread *it, struct image_io *io); void image_io_cleanup(struct image_io *io); void image_io_reset(struct image_io *io); diff --git a/images/io-libmagick.c b/images/io-libmagick.c index bd503e79..d75f0a89 100644 --- a/images/io-libmagick.c +++ b/images/io-libmagick.c @@ -26,20 +26,38 @@ #define BYTE_TO_QUANTUM(x) ((uns)(x) << QUANTUM_SCALE) #define OPACITY_MAX ((1 << QuantumDepth) - 1) +static uns libmagick_counter; + struct magick_read_data { ExceptionInfo exception; ImageInfo *info; Image *image; }; -static inline void +int +libmagick_init(struct image_io *io UNUSED) +{ + // FIXME: lock + if (!libmagick_counter++) + InitializeMagick(NULL); + return 1; +} + +void +libmagick_cleanup(struct image_io *io UNUSED) +{ + // FIXME: lock + if (!--libmagick_counter) + DestroyMagick(); +} + +static void libmagick_destroy_read_data(struct magick_read_data *rd) { if (rd->image) DestroyImage(rd->image); DestroyImageInfo(rd->info); DestroyExceptionInfo(&rd->exception); - DestroyMagick(); } static void @@ -48,8 +66,6 @@ libmagick_read_cancel(struct image_io *io) DBG("libmagick_read_cancel()"); struct magick_read_data *rd = io->read_data; - - DestroyImage(rd->image); libmagick_destroy_read_data(rd); } @@ -70,10 +86,9 @@ libmagick_read_header(struct image_io *io) breadb(io->fastbuf, buf, buf_size); /* Allocate read structure */ - struct magick_read_data *rd = io->read_data = mp_alloc(io->internal_pool, sizeof(*rd)); + struct magick_read_data *rd = io->read_data = mp_alloc_zero(io->internal_pool, sizeof(*rd)); /* Initialize GraphicsMagick */ - InitializeMagick(NULL); GetExceptionInfo(&rd->exception); rd->info = CloneImageInfo(NULL); rd->info->subrange = 1; @@ -98,12 +113,14 @@ libmagick_read_header(struct image_io *io) switch (rd->image->colorspace) { case GRAYColorspace: - io->flags = COLOR_SPACE_GRAYSCALE | IMAGE_ALPHA; + io->flags = COLOR_SPACE_GRAYSCALE; break; default: - io->flags = COLOR_SPACE_RGB | IMAGE_ALPHA; + io->flags = COLOR_SPACE_RGB; break; } + if (rd->image->matte) + io->flags |= IMAGE_ALPHA; io->number_of_colors = rd->image->colors; if (rd->image->storage_class == PseudoClass && rd->image->compression != JPEGCompression) io->flags |= IMAGE_IO_HAS_PALETTE; @@ -241,7 +258,6 @@ libmagick_write(struct image_io *io) int result = 0; ExceptionInfo exception; ImageInfo *info; - InitializeMagick(NULL); GetExceptionInfo(&exception); info = CloneImageInfo(NULL); @@ -390,6 +406,5 @@ err2: err: DestroyImageInfo(info); DestroyExceptionInfo(&exception); - DestroyMagick(); return result; } diff --git a/images/io-libungif.c b/images/io-libungif.c index 5eb7aece..45940ede 100644 --- a/images/io-libungif.c +++ b/images/io-libungif.c @@ -34,7 +34,8 @@ libungif_read_cancel(struct image_io *io) { DBG("libungif_read_cancel()"); - DGifCloseFile(io->read_data); + struct libungif_read_data *rd = io->read_data; + DGifCloseFile(rd->gif); } int diff --git a/images/io-main.c b/images/io-main.c index c4e8fc86..aca3a8ae 100644 --- a/images/io-main.c +++ b/images/io-main.c @@ -14,13 +14,47 @@ #include "images/io-main.h" #include -void +int image_io_init(struct image_thread *it, struct image_io *io) { DBG("image_io_init()"); bzero(io, sizeof(*io)); io->thread = it; +#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 @@ -50,6 +84,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); } diff --git a/images/io-main.h b/images/io-main.h index 3088faf9..477c5dd2 100644 --- a/images/io-main.h +++ b/images/io-main.h @@ -1,17 +1,25 @@ #ifndef _IMAGES_IO_MAIN_H #define _IMAGES_IO_MAIN_H +static inline int libjpeg_init(struct image_io *io UNUSED) { return 1; } +static inline void libjpeg_cleanup(struct image_io *io UNUSED) {} int libjpeg_read_header(struct image_io *io); int libjpeg_read_data(struct image_io *io); int libjpeg_write(struct image_io *io); +static inline int libpng_init(struct image_io *io UNUSED) { return 1; } +static inline void libpng_cleanup(struct image_io *io UNUSED) {} int libpng_read_header(struct image_io *io); int libpng_read_data(struct image_io *io); int libpng_write(struct image_io *io); +static inline int libungif_init(struct image_io *io UNUSED) { return 1; } +static inline void libungif_cleanup(struct image_io *io UNUSED) {} int libungif_read_header(struct image_io *io); int libungif_read_data(struct image_io *io); +int libmagick_init(struct image_io *io); +void libmagick_cleanup(struct image_io *io); int libmagick_read_header(struct image_io *io); int libmagick_read_data(struct image_io *io); int libmagick_write(struct image_io *io);