From 7ae5e8180b1211be9a9ba3328115990982204a6a Mon Sep 17 00:00:00 2001 From: Pavel Charvat Date: Wed, 26 Jul 2006 22:55:08 +0200 Subject: [PATCH] common parts of all lib*_read_data moved to io-main.h has_palette info moved to io.flags some bugfixes --- images/image-tool.c | 4 +-- images/image-walk.h | 2 ++ images/images.h | 61 +++++++++++++--------------------------- images/io-libjpeg.c | 45 ++++++------------------------ images/io-libmagick.c | 64 ++++++++++++++---------------------------- images/io-libpng.c | 49 +++++++++----------------------- images/io-libungif.c | 65 +++++++++++++------------------------------ images/io-main.c | 1 + 8 files changed, 88 insertions(+), 203 deletions(-) diff --git a/images/image-tool.c b/images/image-tool.c index d9b20adc..7a778b29 100644 --- a/images/image-tool.c +++ b/images/image-tool.c @@ -133,13 +133,13 @@ main(int argc, char **argv) bclose(io.fastbuf); printf("Format: %s\n", image_format_to_extension(io.format) ? : (byte *)"?"); printf("Dimensions: %dx%d\n", io.cols, io.rows); - printf("Colorspace: %s\n", io.has_palette ? (byte *)"Palette" : image_channels_format_to_name(io.flags & IMAGE_CHANNELS_FORMAT)); + printf("Colorspace: %s\n", (io.flags & IMAGE_IO_HAS_PALETTE) ? (byte *)"Palette" : image_channels_format_to_name(io.flags & IMAGE_CHANNELS_FORMAT)); printf("NumColors: %d\n", io.number_of_colors); } else { MSG("%s %dx%d %s", image_format_to_extension(io.format) ? : (byte *)"?", io.cols, io.rows, - io.has_palette ? (byte *)"Palette" : image_channels_format_to_name(io.flags & IMAGE_CHANNELS_FORMAT)); + (io.flags & IMAGE_IO_HAS_PALETTE) ? (byte *)"Palette" : image_channels_format_to_name(io.flags & IMAGE_CHANNELS_FORMAT)); if (cols) if (fit_to_box) { diff --git a/images/image-walk.h b/images/image-walk.h index 821712af..dfc72a19 100644 --- a/images/image-walk.h +++ b/images/image-walk.h @@ -147,11 +147,13 @@ static void P(walk) #undef IMAGE_WALK_UNROLL #undef IMAGE_WALK_DOUBLE #undef IMAGE_WALK_EXTRA_ARGS +#undef IMAGE_WALK_IMAGE #undef IMAGE_WALK_PIXELS #undef IMAGE_WALK_COLS #undef IMAGE_WALK_ROWS #undef IMAGE_WALK_COL_STEP #undef IMAGE_WALK_ROW_STEP +#undef IMAGE_WALK_SEC_IMAGE #undef IMAGE_WALK_SEC_PIXELS #undef IMAGE_WALK_SEC_COLS #undef IMAGE_WALK_SEC_ROWS diff --git a/images/images.h b/images/images.h index 4b864c54..8300c3cc 100644 --- a/images/images.h +++ b/images/images.h @@ -110,22 +110,21 @@ enum image_format { }; struct image_io { - /* R - read_header input */ - /* H - read_header output */ - /* I - read_data input */ - /* O - read_data output */ - /* W - write input */ - - struct image *image; /* [ OW] - image data */ - enum image_format format; /* [R W] - file format (IMAGE_FORMAT_x) */ - struct fastbuf *fastbuf; /* [R W] - source/destination stream */ - struct mempool *pool; /* [ I ] - parameter to image_new */ - u32 cols; /* [ HI ] - number of columns, parameter to image_new */ - u32 rows; /* [ HI ] - number of rows, parameter to image_new */ - u32 flags; /* [ HI ] - parameter to image new, read_header fills IMAGE_CHANNELS_FORMAT */ - u32 jpeg_quality; /* [ W] - JPEG compression quality (1..100) */ - u32 number_of_colors; /* [ H ] - number of image colors */ - u32 has_palette; /* [ H ] - true for image with indexed colors */ + /* R - read_header input */ + /* H - read_header output */ + /* I - read_data input */ + /* O - read_data output */ + /* W - write input */ + + struct image *image; /* [ OW] - image data */ + enum image_format format; /* [R W] - file format (IMAGE_FORMAT_x) */ + struct fastbuf *fastbuf; /* [R W] - source/destination stream */ + struct mempool *pool; /* [ I ] - parameter to image_new */ + u32 cols; /* [ HI ] - number of columns, parameter to image_new */ + u32 rows; /* [ HI ] - number of rows, parameter to image_new */ + u32 flags; /* [ HI ] - see enum image_io_flags */ + u32 jpeg_quality; /* [ W] - JPEG compression quality (1..100) */ + u32 number_of_colors; /* [ H ] - number of image colors */ /* internals */ struct image_thread *thread; @@ -135,6 +134,11 @@ struct image_io { void (*read_cancel)(struct image_io *io); }; +enum image_io_flags { + IMAGE_IO_IMAGE_FLAGS = 0xffff, /* [ HI ] - parameter to image new, read_header fills IMAGE_CHANNELS_FORMAT */ + IMAGE_IO_HAS_PALETTE = 0x10000, /* [ H ] - true for image with indexed colors */ +}; + void 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); @@ -149,29 +153,4 @@ byte *image_format_to_extension(enum image_format format); enum image_format image_extension_to_format(byte *extension); enum image_format image_file_name_to_format(byte *file_name); -/* internals */ - -#ifdef CONFIG_IMAGES_LIBJPEG -int libjpeg_read_header(struct image_io *io); -int libjpeg_read_data(struct image_io *io); -int libjpeg_write(struct image_io *io); -#endif - -#ifdef CONFIG_IMAGES_LIBPNG -int libpng_read_header(struct image_io *io); -int libpng_read_data(struct image_io *io); -int libpng_write(struct image_io *io); -#endif - -#ifdef CONFIG_IMAGES_LIBUNGIF -int libungif_read_header(struct image_io *io); -int libungif_read_data(struct image_io *io); -#endif - -#ifdef CONFIG_IMAGES_LIBMAGICK -int libmagick_read_header(struct image_io *io); -int libmagick_read_data(struct image_io *io); -int libmagick_write(struct image_io *io); -#endif - #endif diff --git a/images/io-libjpeg.c b/images/io-libjpeg.c index b6c6552a..1e1f90b5 100644 --- a/images/io-libjpeg.c +++ b/images/io-libjpeg.c @@ -13,7 +13,7 @@ #include "lib/mempool.h" #include "lib/fastbuf.h" #include "images/images.h" - +#include "images/io-main.h" #include #include #include @@ -257,14 +257,11 @@ libjpeg_read_data(struct image_io *io) return 0; } - /* Allocate the image... FIXME: use libjpeg feature to speed up downscale */ - volatile int need_scale = io->cols != i->cinfo.image_width || io->rows != i->cinfo.image_height; - struct image * volatile img = need_scale ? - image_new(io->thread, i->cinfo.image_width, i->cinfo.image_height, io->flags & IMAGE_PIXEL_FORMAT, NULL) : - image_new(io->thread, i->cinfo.image_width, i->cinfo.image_height, io->flags, io->pool); - if (!img) + /* Prepare the image ... FIXME: use libjpeg feature to speed up downscale */ + struct image_io_read_data_internals rdi; + if (unlikely(!image_io_read_data_prepare(&rdi, io, i->cinfo.image_width, i->cinfo.image_height))) { - image_thread_err(io->thread, IMAGE_ERR_INVALID_PIXEL_FORMAT, "Unsupported color space."); + jpeg_destroy_decompress(&i->cinfo); return 0; } @@ -273,12 +270,12 @@ libjpeg_read_data(struct image_io *io) { DBG("Libjpeg failed to read the image, longjump saved us"); jpeg_destroy_decompress(&i->cinfo); - if (need_scale || !io->pool) - image_destroy(img); + image_io_read_data_break(&rdi, io); return 0; } /* Decompress the image */ + struct image *img = rdi.image; jpeg_start_decompress(&i->cinfo); switch (img->pixel_size) { @@ -331,32 +328,8 @@ libjpeg_read_data(struct image_io *io) jpeg_finish_decompress(&i->cinfo); jpeg_destroy_decompress(&i->cinfo); - /* Scale result if necessary */ - if (need_scale) - { - DBG("Scaling image"); - struct image *dest = image_new(io->thread, io->cols, io->rows, io->flags, io->pool); - if (!dest) - { - image_destroy(img); - return 0; - } - if (!(image_scale(io->thread, dest, img))) - { - image_destroy(img); - if (!io->pool) - image_destroy(dest); - return 0; - } - image_destroy(img); - io->image = dest; - } - else - io->image = img; - io->image_destroy = !io->pool; - - DBG("Image readed"); - return 1; + /* Finish the image */ + return image_io_read_data_finish(&rdi, io); } int diff --git a/images/io-libmagick.c b/images/io-libmagick.c index db5d7398..3319260d 100644 --- a/images/io-libmagick.c +++ b/images/io-libmagick.c @@ -13,6 +13,7 @@ #include "lib/mempool.h" #include "lib/fastbuf.h" #include "images/images.h" +#include "images/io-main.h" #include #include #include @@ -96,15 +97,15 @@ 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 | IMAGE_ALPHA; break; default: - io->flags |= COLOR_SPACE_RGB | IMAGE_ALPHA; + io->flags = COLOR_SPACE_RGB | IMAGE_ALPHA; break; } io->number_of_colors = rd->image->colors; if (rd->image->storage_class == PseudoClass && rd->image->compression != JPEGCompression) - io->has_palette = 1; + io->flags |= IMAGE_IO_HAS_PALETTE; io->read_cancel = libmagick_read_cancel; return 1; @@ -141,30 +142,31 @@ libmagick_read_data(struct image_io *io) break; } - /* Allocate image for conversion */ - int need_scale = io->cols != rd->image->columns || io->rows != rd->image->rows; - int need_destroy = need_scale || !io->pool; - struct image *img = need_scale ? - image_new(io->thread, rd->image->columns, rd->image->rows, io->flags & IMAGE_CHANNELS_FORMAT, NULL) : - image_new(io->thread, io->cols, io->rows, io->flags, io->pool); - if (unlikely(!img)) - goto err; + /* Prepare the image */ + struct image_io_read_data_internals rdi; + if (unlikely(!image_io_read_data_prepare(&rdi, io, rd->image->columns, rd->image->rows))) + { + libmagick_destroy_read_data(rd); + return 0; + } /* Acquire pixels */ PixelPacket *src = (PixelPacket *)AcquireImagePixels(rd->image, 0, 0, rd->image->columns, rd->image->rows, &rd->exception); if (unlikely(!src)) { image_thread_err(io->thread, IMAGE_ERR_READ_FAILED, "Cannot acquire image pixels."); - goto err; + libmagick_destroy_read_data(rd); + image_io_read_data_break(&rdi, io); + return 0; } /* Convert pixels */ - switch (img->pixel_size) + switch (rdi.image->pixel_size) { case 1: # define IMAGE_WALK_PREFIX(x) walk_##x # define IMAGE_WALK_INLINE -# define IMAGE_WALK_IMAGE img +# define IMAGE_WALK_IMAGE (rdi.image) # define IMAGE_WALK_UNROLL 4 # define IMAGE_WALK_COL_STEP 1 # define IMAGE_WALK_DO_STEP do{ \ @@ -176,7 +178,7 @@ libmagick_read_data(struct image_io *io) case 2: # define IMAGE_WALK_PREFIX(x) walk_##x # define IMAGE_WALK_INLINE -# define IMAGE_WALK_IMAGE img +# define IMAGE_WALK_IMAGE (rdi.image) # define IMAGE_WALK_UNROLL 4 # define IMAGE_WALK_COL_STEP 2 # define IMAGE_WALK_DO_STEP do{ \ @@ -189,7 +191,7 @@ libmagick_read_data(struct image_io *io) case 3: # define IMAGE_WALK_PREFIX(x) walk_##x # define IMAGE_WALK_INLINE -# define IMAGE_WALK_IMAGE img +# define IMAGE_WALK_IMAGE (rdi.image) # define IMAGE_WALK_UNROLL 4 # define IMAGE_WALK_COL_STEP 3 # define IMAGE_WALK_DO_STEP do{ \ @@ -203,7 +205,7 @@ libmagick_read_data(struct image_io *io) case 4: # define IMAGE_WALK_PREFIX(x) walk_##x # define IMAGE_WALK_INLINE -# define IMAGE_WALK_IMAGE img +# define IMAGE_WALK_IMAGE (rdi.image) # define IMAGE_WALK_UNROLL 4 # define IMAGE_WALK_COL_STEP 4 # define IMAGE_WALK_DO_STEP do{ \ @@ -222,32 +224,8 @@ libmagick_read_data(struct image_io *io) /* Free GraphicsMagick structures */ libmagick_destroy_read_data(rd); - /* Scale image */ - if (need_scale) - { - struct image *img2 = image_new(io->thread, io->cols, io->rows, io->flags, io->pool); - if (unlikely(!img2)) - goto err2; - int result = image_scale(io->thread, img2, img); - image_destroy(img); - img = img2; - need_destroy = !io->pool; - if (unlikely(!result)) - goto err2; - } - - /* Success */ - io->image = img; - io->image_destroy = need_destroy; - return 1; - - /* Free structures */ -err: - libmagick_destroy_read_data(rd); -err2: - if (need_destroy) - image_destroy(img); - return 0; + /* Finish the image */ + return image_io_read_data_finish(&rdi, io); } int diff --git a/images/io-libpng.c b/images/io-libpng.c index dbf33d51..638427da 100644 --- a/images/io-libpng.c +++ b/images/io-libpng.c @@ -13,6 +13,7 @@ #include "lib/mempool.h" #include "lib/fastbuf.h" #include "images/images.h" +#include "images/io-main.h" #include #include @@ -143,29 +144,28 @@ libpng_read_header(struct image_io *io) switch (rd->color_type) { case PNG_COLOR_TYPE_GRAY: - io->flags |= COLOR_SPACE_GRAYSCALE; + io->flags = COLOR_SPACE_GRAYSCALE; io->number_of_colors = 1 << 8; break; case PNG_COLOR_TYPE_GRAY_ALPHA: - io->flags |= COLOR_SPACE_GRAYSCALE | IMAGE_ALPHA; + io->flags = COLOR_SPACE_GRAYSCALE | IMAGE_ALPHA; io->number_of_colors = 1 << 8; break; case PNG_COLOR_TYPE_RGB: - io->flags |= COLOR_SPACE_RGB; + io->flags = COLOR_SPACE_RGB; io->number_of_colors = 1 << 24; break; case PNG_COLOR_TYPE_RGB_ALPHA: io->number_of_colors = 1 << 24; - io->flags |= COLOR_SPACE_RGB | IMAGE_ALPHA; + io->flags = COLOR_SPACE_RGB | IMAGE_ALPHA; break; case PNG_COLOR_TYPE_PALETTE: - io->flags |= COLOR_SPACE_RGB | IMAGE_ALPHA; + io->flags = COLOR_SPACE_RGB | IMAGE_ALPHA | IMAGE_IO_HAS_PALETTE; int num_palette; if (png_get_PLTE(rd->png_ptr, rd->info_ptr, NULL, &num_palette)) io->number_of_colors = num_palette; else io->number_of_colors = 1 << rd->bit_depth; - io->has_palette = 1; break; default: png_destroy_read_struct(&rd->png_ptr, &rd->info_ptr, &rd->end_ptr); @@ -197,11 +197,9 @@ libpng_read_data(struct image_io *io) return 0; } - volatile int need_scale = io->cols != rd->cols || io->rows != rd->rows; - struct image * volatile img = need_scale ? - image_new(io->thread, rd->cols, rd->rows, io->flags & IMAGE_PIXEL_FORMAT, NULL) : - image_new(io->thread, rd->cols, rd->rows, io->flags, io->pool); - if (!img) + /* Prepare the image */ + struct image_io_read_data_internals rdi; + if (unlikely(!image_io_read_data_prepare(&rdi, io, rd->cols, rd->rows))) { png_destroy_read_struct(&rd->png_ptr, &rd->info_ptr, &rd->end_ptr); return 0; @@ -211,8 +209,7 @@ libpng_read_data(struct image_io *io) { DBG("Libpng failed to read the image, longjump saved us"); png_destroy_read_struct(&rd->png_ptr, &rd->info_ptr, &rd->end_ptr); - if (need_scale || !io->pool) - image_destroy(img); + image_io_read_data_break(&rdi, io); return 0; } @@ -265,6 +262,7 @@ libpng_read_data(struct image_io *io) /* Read image data */ DBG("Reading image data"); + struct image *img = rdi.image; byte *pixels = img->pixels; png_bytep rows[img->rows]; for (uns r = 0; r < img->rows; r++, pixels += img->row_size) @@ -275,29 +273,8 @@ libpng_read_data(struct image_io *io) /* Destroy libpng read structure */ png_destroy_read_struct(&rd->png_ptr, &rd->info_ptr, &rd->end_ptr); - /* Scale and store the resulting image */ - if (need_scale) - { - struct image *dest = image_new(io->thread, io->cols, io->rows, io->flags, io->pool); - if (!dest) - { - image_destroy(img); - return 0; - } - if (!image_scale(io->thread, dest, img)) - { - image_destroy(img); - if (!io->pool) - image_destroy(dest); - return 0; - } - io->image = dest; - } - else - io->image = img; - io->image_destroy = !io->pool; - - return 1; + /* Finish the image */ + return image_io_read_data_finish(&rdi, io); } int diff --git a/images/io-libungif.c b/images/io-libungif.c index 7c9850e4..3a2af11c 100644 --- a/images/io-libungif.c +++ b/images/io-libungif.c @@ -13,6 +13,7 @@ #include "lib/mempool.h" #include "lib/fastbuf.h" #include "images/images.h" +#include "images/io-main.h" #include static int @@ -75,9 +76,8 @@ libungif_read_header(struct image_io *io) } io->cols = image->ImageDesc.Width; io->rows = image->ImageDesc.Height; - io->has_palette = 1; io->number_of_colors = color_map->ColorCount; - io->flags = COLOR_SPACE_RGB; + io->flags = COLOR_SPACE_RGB | IMAGE_IO_HAS_PALETTE; if ((uns)gif->SBackGroundColor < (uns)color_map->ColorCount) io->flags |= IMAGE_ALPHA; @@ -100,31 +100,30 @@ libungif_read_data(struct image_io *io) GifFileType *gif = io->read_data; SavedImage *image = gif->SavedImages; - /* Allocate image */ - int need_scale = io->cols != (uns)image->ImageDesc.Width || io->rows != (uns)image->ImageDesc.Height; - int need_destroy = need_scale || !io->pool; - struct image *img = need_scale ? - image_new(io->thread, image->ImageDesc.Width, image->ImageDesc.Height, io->flags & IMAGE_CHANNELS_FORMAT, NULL) : - image_new(io->thread, io->cols, io->rows, io->flags, io->pool); - if (unlikely(!img)) - goto err; + /* Prepare image */ + struct image_io_read_data_internals rdi; + if (unlikely(!image_io_read_data_prepare(&rdi, io, image->ImageDesc.Width, image->ImageDesc.Height))) + { + DGifCloseFile(gif); + return 0; + } /* Get pixels and palette */ byte *pixels = (byte *)image->RasterBits; ColorMapObject *color_map = image->ImageDesc.ColorMap ? : gif->SColorMap; GifColorType *palette = color_map->Colors; uns background = gif->SBackGroundColor; - byte *img_end = img->pixels + img->image_size; + byte *img_end = rdi.image->pixels + rdi.image->image_size; /* Handle deinterlacing */ uns dein_step, dein_next; if (image->ImageDesc.Interlace) - dein_step = dein_next = img->row_size << 3; + dein_step = dein_next = rdi.image->row_size << 3; else - dein_step = dein_next = img->row_size; + dein_step = dein_next = rdi.image->row_size; /* Convert pixels */ - switch (img->pixel_size) + switch (rdi.image->pixel_size) { case 1: { @@ -136,11 +135,11 @@ libungif_read_data(struct image_io *io) # define DO_ROW_END do{ \ walk_row_start += dein_step; \ if (walk_row_start > img_end) \ - { uns n = dein_next >> 1; walk_row_start = img->pixels + n, dein_step = dein_next; dein_next = n; } \ + { uns n = dein_next >> 1; walk_row_start = rdi.image->pixels + n, dein_step = dein_next; dein_next = n; } \ }while(0) # define IMAGE_WALK_PREFIX(x) walk_##x # define IMAGE_WALK_INLINE -# define IMAGE_WALK_IMAGE img +# define IMAGE_WALK_IMAGE (rdi.image) # define IMAGE_WALK_UNROLL 4 # define IMAGE_WALK_COL_STEP 1 # define IMAGE_WALK_ROW_STEP 0 @@ -163,7 +162,7 @@ libungif_read_data(struct image_io *io) pal[background * 2 + 1] = 0; # define IMAGE_WALK_PREFIX(x) walk_##x # define IMAGE_WALK_INLINE -# define IMAGE_WALK_IMAGE img +# define IMAGE_WALK_IMAGE (rdi.image) # define IMAGE_WALK_UNROLL 4 # define IMAGE_WALK_COL_STEP 2 # define IMAGE_WALK_ROW_STEP 0 @@ -185,7 +184,7 @@ libungif_read_data(struct image_io *io) bzero(pal_pos, pal_end - pal_pos); # define IMAGE_WALK_PREFIX(x) walk_##x # define IMAGE_WALK_INLINE -# define IMAGE_WALK_IMAGE img +# define IMAGE_WALK_IMAGE (rdi.image) # define IMAGE_WALK_UNROLL 4 # define IMAGE_WALK_COL_STEP 3 # define IMAGE_WALK_ROW_STEP 0 @@ -210,7 +209,7 @@ libungif_read_data(struct image_io *io) pal[background * 4 + 3] = 0; # define IMAGE_WALK_PREFIX(x) walk_##x # define IMAGE_WALK_INLINE -# define IMAGE_WALK_IMAGE img +# define IMAGE_WALK_IMAGE (rdi.image) # define IMAGE_WALK_UNROLL 4 # define IMAGE_WALK_COL_STEP 4 # define IMAGE_WALK_ROW_STEP 0 @@ -226,30 +225,6 @@ libungif_read_data(struct image_io *io) /* Destroy libungif structure */ DGifCloseFile(gif); - /* Scale image */ - if (need_scale) - { - struct image *img2 = image_new(io->thread, io->cols, io->rows, io->flags, io->pool); - if (unlikely(!img2)) - goto err2; - int result = image_scale(io->thread, img2, img); - image_destroy(img); - img = img2; - need_destroy = !io->pool; - if (unlikely(!result)) - goto err2; - } - - /* Success */ - io->image = img; - io->image_destroy = need_destroy; - return 1; - - /* Free structures */ -err: - DGifCloseFile(gif); -err2: - if (need_destroy) - image_destroy(img); - return 0; + /* Finish image */ + return image_io_read_data_finish(&rdi, io); } diff --git a/images/io-main.c b/images/io-main.c index ef4bd705..ac3c3c62 100644 --- a/images/io-main.c +++ b/images/io-main.c @@ -11,6 +11,7 @@ #include "lib/lib.h" #include "images/images.h" +#include "images/io-main.h" #include void -- 2.39.2