From: Pavel Charvat Date: Mon, 31 Jul 2006 05:58:08 +0000 (+0200) Subject: apply background color to transparent pictures X-Git-Tag: holmes-import~624 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=422234aee83909200561bcce45f6bc1ed84f4789;p=libucw.git apply background color to transparent pictures support for libgif (same as libungif) some small fixes --- diff --git a/images/Makefile b/images/Makefile index 4147a200..f7d6873e 100644 --- a/images/Makefile +++ b/images/Makefile @@ -4,7 +4,7 @@ DIRS+=images PROGS+=$(addprefix $(o)/images/,image-tool) -LIBIMAGES_MODS=image scale io-main +LIBIMAGES_MODS=image scale color alpha io-main LIBIMAGES=$(o)/images/libimages.$(LS) LIBIMAGES_LIBS= @@ -21,6 +21,11 @@ endif ifdef CONFIG_IMAGES_LIBUNGIF LIBIMAGES_MODS+=io-libungif LIBIMAGES_LIBS+=-lungif +else +ifdef CONFIG_IMAGES_LIBGIF +LIBIMAGES_MODS+=io-libungif +LIBIMAGES_LIBS+=-lgif +endif endif ifdef CONFIG_IMAGES_LIBMAGICK @@ -41,15 +46,16 @@ TESTS+=$(o)/images/hilbert-test.test $(o)/images/hilbert-test: LIBS+=-lm $(LIBSH) $(o)/images/hilbert-test.test: $(o)/images/hilbert-test +TESTS+=$(o)/images/color.test +$(o)/images/color-t: LIBS+=-lm +$(o)/images/color.test: $(o)/images/color-t + #$(o)/images/image-test: $(o)/images/image-test.o $(LIBIMAGES) $(LIBUCW) #$(o)/images/image-test: LIBS+=$(LIBIMAGES_LIBS) #$(o)/images/image-idx: $(o)/images/image-idx.o $(o)/images/image-obj.o $(o)/images/dup-cmp.o $(o)/indexer/iconfig.o $(o)/images/image-sig.o $(o)/images/kd-tree.o $(o)/images/color.o $(o)/images/image-io.o $(LIBSH) $(LIBLANG) $(LIBCHARSET) #$(o)/images/image-idx: LIBS+=-lGraphicsMagick -ljpeg -lpng -#$(o)/images/color-t: LIBS+=-lm -#$(o)/images/color.test: $(o)/images/color-t - # By :;DF #PROGS+=$(addprefix $(o)/images/,decomp) # diff --git a/images/alpha.c b/images/alpha.c new file mode 100644 index 00000000..f3a85c35 --- /dev/null +++ b/images/alpha.c @@ -0,0 +1,72 @@ +/* + * Image Library -- Alpha channels + * + * (c) 2006 Pavel Charvat + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#define LOCAL_DEBUG + +#include "lib/lib.h" +#include "images/images.h" +#include "images/color.h" + +static inline uns +merge_func(uns value, uns alpha, uns acoef, uns bcoef) +{ + return ((uns)(acoef + (int)alpha * (int)(value - bcoef)) * (0xffffffffU / 255 / 255)) >> 24; +} + +int +image_apply_background(struct image_thread *thread UNUSED, struct image *dest, struct image *src, struct color *background) +{ + DBG("image_apply_background()"); + + /* Grayscale */ + if (src->pixel_size == 2) + { + ASSERT(dest->pixel_size == 1); + byte bg; + color_put_grayscale(&bg, background); + uns a = 255 * bg, b = bg; +# define IMAGE_WALK_PREFIX(x) walk_##x +# define IMAGE_WALK_INLINE +# define IMAGE_WALK_DOUBLE +# define IMAGE_WALK_UNROLL 4 +# define IMAGE_WALK_IMAGE dest +# define IMAGE_WALK_SEC_IMAGE src +# define IMAGE_WALK_COL_STEP 1 +# define IMAGE_WALK_SEC_COL_STEP 2 +# define IMAGE_WALK_DO_STEP do{ walk_pos[0] = merge_func(walk_sec_pos[0], walk_sec_pos[1], a, b); }while(0) +# include "images/image-walk.h" + } + + /* RGBA to RGB or aligned RGB */ + else if (src->pixel_size == 4) + { + ASSERT((src->flags & IMAGE_ALPHA) && dest->pixel_size >= 3 && !(dest->flags & IMAGE_ALPHA)); + byte bg[3]; + color_put_rgb(bg, background); + uns a0 = 255 * bg[0], b0 = bg[0]; + uns a1 = 255 * bg[1], b1 = bg[1]; + uns a2 = 255 * bg[2], b2 = bg[2]; +# define IMAGE_WALK_PREFIX(x) walk_##x +# define IMAGE_WALK_INLINE +# define IMAGE_WALK_DOUBLE +# define IMAGE_WALK_UNROLL 2 +# define IMAGE_WALK_IMAGE dest +# define IMAGE_WALK_SEC_IMAGE src +# define IMAGE_WALK_SEC_COL_STEP 4 +# define IMAGE_WALK_DO_STEP do{ \ + walk_pos[0] = merge_func(walk_sec_pos[0], walk_sec_pos[3], a0, b0); \ + walk_pos[1] = merge_func(walk_sec_pos[1], walk_sec_pos[3], a1, b1); \ + walk_pos[2] = merge_func(walk_sec_pos[2], walk_sec_pos[3], a2, b2); \ + }while(0) +# include "images/image-walk.h" + } + else + ASSERT(0); + return 1; +} diff --git a/images/color.c b/images/color.c index e6846605..5f41e935 100644 --- a/images/color.c +++ b/images/color.c @@ -11,8 +11,61 @@ #include "sherlock/sherlock.h" #include "lib/math.h" +#include "images/images.h" #include "images/color.h" +struct color color_black = { .color_space = COLOR_SPACE_GRAYSCALE }; +struct color color_white = { .c = { 255 }, .color_space = COLOR_SPACE_GRAYSCALE }; + +inline void +color_put_grayscale(byte *dest, struct color *color) +{ + switch (color->color_space) + { + case COLOR_SPACE_GRAYSCALE: + dest[0] = color->c[0]; + break; + case COLOR_SPACE_RGB: + dest[0] = rgb_to_gray_func(color->c[0], color->c[1], color->c[2]); + break; + default: + ASSERT(0); + } +} + +inline void +color_put_rgb(byte *dest, struct color *color) +{ + switch (color->color_space) + { + case COLOR_SPACE_GRAYSCALE: + dest[0] = dest[1] = dest[2] = color->c[0]; + break; + case COLOR_SPACE_RGB: + dest[0] = color->c[0]; + dest[1] = color->c[1]; + dest[2] = color->c[2]; + break; + default: + ASSERT(0); + } +} + +void +color_put_color_space(byte *dest, struct color *color, enum color_space color_space) +{ + switch (color_space) + { + case COLOR_SPACE_GRAYSCALE: + color_put_grayscale(dest, color); + break; + case COLOR_SPACE_RGB: + color_put_rgb(dest, color); + break; + default: + ASSERT(0); + } +} /********************* EXACT CONVERSION ROUTINES **********************/ diff --git a/images/color.h b/images/color.h index ec3cd4af..8ec18e92 100644 --- a/images/color.h +++ b/images/color.h @@ -23,6 +23,36 @@ #ifndef _IMAGES_COLOR_H #define _IMAGES_COLOR_H +#include "images/images.h" + +static inline uns +rgb_to_gray_func(uns r, uns g, uns b) +{ + return (r * 19660 + g * 38666 + b * 7210) >> 16; +} + +extern struct color color_black, color_white; + +static inline void +color_make_gray(struct color *color, uns gray) +{ + color->c[0] = gray; + color->color_space = COLOR_SPACE_GRAYSCALE; +} + +static inline void +color_make_rgb(struct color *color, uns r, uns g, uns b) +{ + color->c[0] = r; + color->c[1] = g; + color->c[2] = b; + color->color_space = COLOR_SPACE_RGB; +} + +void color_put_color_space(byte *dest, struct color *color, enum color_space color_space); +void color_put_grayscale(byte *dest, struct color *color); +void color_put_rgb(byte *dest, struct color *color); + /* Exact slow conversion routines */ void srgb_to_xyz_slow(double dest[3], double src[3]); void xyz_to_luv_slow(double dest[3], double src[3]); diff --git a/images/image.c b/images/image.c index 378b8922..13576d8c 100644 --- a/images/image.c +++ b/images/image.c @@ -157,7 +157,7 @@ void image_destroy(struct image *img) { DBG("image_destroy(img=%p)", img); - xfree((byte *)img); + xfree(img); } void diff --git a/images/images.h b/images/images.h index 8300c3cc..d421dfc4 100644 --- a/images/images.h +++ b/images/images.h @@ -94,11 +94,20 @@ byte *color_space_to_name(enum color_space cs); byte *image_channels_format_to_name(uns format); uns image_name_to_channels_format(byte *name); +struct color { + byte c[3]; + byte color_space; +} PACKED; + /* scale.c */ int image_scale(struct image_thread *thread, struct image *dest, struct image *src); void image_dimensions_fit_to_box(u32 *cols, u32 *rows, u32 max_cols, u32 max_rows, uns upsample); +/* alpha.c */ + +int image_apply_background(struct image_thread *thread, struct image *dest, struct image *src, struct color *background); + /* image-io.c */ enum image_format { @@ -125,6 +134,7 @@ struct image_io { 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 */ + struct color background_color; /* [ HI ] - background color, zero if undefined */ /* internals */ struct image_thread *thread; @@ -135,8 +145,10 @@ struct image_io { }; enum image_io_flags { - IMAGE_IO_IMAGE_FLAGS = 0xffff, /* [ HI ] - parameter to image new, read_header fills IMAGE_CHANNELS_FORMAT */ + IMAGE_IO_IMAGE_FLAGS = 0xffff, /* [ HI ] - mask of parameters to image new, read_header fills IMAGE_CHANNELS_FORMAT */ IMAGE_IO_HAS_PALETTE = 0x10000, /* [ H ] - true for image with indexed colors */ + IMAGE_IO_HAS_BACKGROUND = 0x20000, /* [ H ] - picture contains background info */ + IMAGE_IO_USE_BACKGROUND = 0x40000, /* [ I ] - merge transparent pixels with background_color */ }; void image_io_init(struct image_thread *it, struct image_io *io); diff --git a/images/io-libjpeg.c b/images/io-libjpeg.c index 1e1f90b5..f7458124 100644 --- a/images/io-libjpeg.c +++ b/images/io-libjpeg.c @@ -259,7 +259,7 @@ libjpeg_read_data(struct image_io *io) /* 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))) + if (unlikely(!image_io_read_data_prepare(&rdi, io, i->cinfo.image_width, i->cinfo.image_height, io->flags))) { jpeg_destroy_decompress(&i->cinfo); return 0; @@ -291,7 +291,7 @@ libjpeg_read_data(struct image_io *io) } } break; - /* garscale with alpha */ + /* grayscale with alpha */ case 2: { byte buf[img->cols], *src; diff --git a/images/io-libmagick.c b/images/io-libmagick.c index 3319260d..e4bca9c3 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/color.h" #include "images/io-main.h" #include #include @@ -118,7 +119,7 @@ err: static inline byte libmagick_pixel_to_gray(PixelPacket *pixel) { - return ((uns)pixel->red * 19660 + (uns)pixel->green * 38666 + (uns)pixel->blue * 7210) >> (16 + QUANTUM_SCALE); + return rgb_to_gray_func(pixel->red, pixel->green, pixel->blue) >> QUANTUM_SCALE; } int @@ -144,7 +145,10 @@ libmagick_read_data(struct image_io *io) /* 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))) + uns read_flags = io->flags; + if ((read_flags & IMAGE_IO_USE_BACKGROUND) && !(read_flags & IMAGE_ALPHA)) + read_flags |= IMAGE_ALPHA; + if (unlikely(!image_io_read_data_prepare(&rdi, io, rd->image->columns, rd->image->rows, read_flags))) { libmagick_destroy_read_data(rd); return 0; diff --git a/images/io-libpng.c b/images/io-libpng.c index 638427da..1e1704f8 100644 --- a/images/io-libpng.c +++ b/images/io-libpng.c @@ -197,22 +197,20 @@ libpng_read_data(struct image_io *io) return 0; } - /* 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; - } + rdi.image = NULL; if (setjmp(png_jmpbuf(rd->png_ptr))) { DBG("Libpng failed to read the image, longjump saved us"); png_destroy_read_struct(&rd->png_ptr, &rd->info_ptr, &rd->end_ptr); - image_io_read_data_break(&rdi, io); + if (rdi.image) + image_io_read_data_break(&rdi, io); return 0; } + uns read_flags = io->flags; + /* Apply transformations */ if (rd->bit_depth == 16) png_set_strip_16(rd->png_ptr); @@ -241,7 +239,12 @@ libpng_read_data(struct image_io *io) if ((io->flags & IMAGE_COLOR_SPACE) == COLOR_SPACE_RGB) png_set_gray_to_rgb(rd->png_ptr); if (!(io->flags & IMAGE_ALPHA)) - png_set_strip_alpha(rd->png_ptr); + { + if (io->flags & IMAGE_IO_USE_BACKGROUND) + read_flags |= IMAGE_ALPHA; + else + png_set_strip_alpha(rd->png_ptr); + } break; case PNG_COLOR_TYPE_RGB: if ((io->flags & IMAGE_COLOR_SPACE) == COLOR_SPACE_GRAYSCALE) @@ -253,13 +256,24 @@ libpng_read_data(struct image_io *io) if ((io->flags & IMAGE_COLOR_SPACE) == COLOR_SPACE_GRAYSCALE) png_set_rgb_to_gray_fixed(rd->png_ptr, 1, 21267, 71514); if (!(io->flags & IMAGE_ALPHA) && (io->flags & IMAGE_PIXEL_FORMAT) != (COLOR_SPACE_RGB | IMAGE_PIXELS_ALIGNED)) - png_set_strip_alpha(rd->png_ptr); + { + if (io->flags & IMAGE_IO_USE_BACKGROUND) + read_flags |= IMAGE_ALPHA; + else + png_set_strip_alpha(rd->png_ptr); + } break; default: ASSERT(0); } png_read_update_info(rd->png_ptr, rd->info_ptr); + /* Prepare the image */ + if (unlikely(!image_io_read_data_prepare(&rdi, io, rd->cols, rd->rows, read_flags))) + { + png_destroy_read_struct(&rd->png_ptr, &rd->info_ptr, &rd->end_ptr); + return 0; + } /* Read image data */ DBG("Reading image data"); struct image *img = rdi.image; diff --git a/images/io-libungif.c b/images/io-libungif.c index 3a2af11c..a35b6d83 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/color.h" #include "images/io-main.h" #include @@ -76,22 +77,25 @@ libungif_read_header(struct image_io *io) } io->cols = image->ImageDesc.Width; io->rows = image->ImageDesc.Height; - io->number_of_colors = color_map->ColorCount; + if (unlikely((io->number_of_colors = color_map->ColorCount) > 256)) + { + image_thread_err(io->thread, IMAGE_ERR_READ_FAILED, "Too many gif colors."); + DGifCloseFile(gif); + return 0; + } io->flags = COLOR_SPACE_RGB | IMAGE_IO_HAS_PALETTE; if ((uns)gif->SBackGroundColor < (uns)color_map->ColorCount) - io->flags |= IMAGE_ALPHA; + { + io->flags |= IMAGE_ALPHA | IMAGE_IO_HAS_BACKGROUND; + GifColorType *background = color_map->Colors + gif->SBackGroundColor; + color_make_rgb(&io->background_color, background->Red, background->Green, background->Blue); + } /* Success */ io->read_cancel = libungif_read_cancel; return 1; } -static inline byte -libungif_pixel_to_gray(GifColorType *pixel) -{ - return ((uns)pixel->Red * 19660 + (uns)pixel->Green * 38666 + (uns)pixel->Blue * 7210) >> 16; -} - int libungif_read_data(struct image_io *io) { @@ -102,7 +106,7 @@ libungif_read_data(struct image_io *io) /* Prepare image */ struct image_io_read_data_internals rdi; - if (unlikely(!image_io_read_data_prepare(&rdi, io, image->ImageDesc.Width, image->ImageDesc.Height))) + if (unlikely(!image_io_read_data_prepare(&rdi, io, image->ImageDesc.Width, image->ImageDesc.Height, io->flags))) { DGifCloseFile(gif); return 0; @@ -129,9 +133,11 @@ libungif_read_data(struct image_io *io) { byte pal[256], *pal_pos = pal, *pal_end = pal + 256; for (uns i = 0; i < (uns)color_map->ColorCount; i++, pal_pos++, palette++) - *pal_pos = libungif_pixel_to_gray(palette); + *pal_pos = rgb_to_gray_func(palette->Red, palette->Green, palette->Blue); if (pal_pos != pal_end) bzero(pal_pos, pal_end - pal_pos); + if (io->flags & IMAGE_IO_USE_BACKGROUND) + color_put_grayscale(pal + background, &io->background_color); # define DO_ROW_END do{ \ walk_row_start += dein_step; \ if (walk_row_start > img_end) \ @@ -153,7 +159,7 @@ libungif_read_data(struct image_io *io) byte pal[256 * 2], *pal_pos = pal, *pal_end = pal + 256 * 2; for (uns i = 0; i < (uns)color_map->ColorCount; i++, pal_pos += 2, palette++) { - pal_pos[0] = libungif_pixel_to_gray(palette); + pal_pos[0] = rgb_to_gray_func(palette->Red, palette->Green, palette->Blue); pal_pos[1] = 255; } if (pal_pos != pal_end) @@ -182,6 +188,8 @@ libungif_read_data(struct image_io *io) } if (pal_pos != pal_end) bzero(pal_pos, pal_end - pal_pos); + if (io->flags & IMAGE_IO_USE_BACKGROUND) + color_put_rgb(pal + background, &io->background_color); # define IMAGE_WALK_PREFIX(x) walk_##x # define IMAGE_WALK_INLINE # define IMAGE_WALK_IMAGE (rdi.image) diff --git a/images/io-main.c b/images/io-main.c index ac3c3c62..9442c7e0 100644 --- a/images/io-main.c +++ b/images/io-main.c @@ -7,7 +7,7 @@ * of the GNU Lesser General Public License. */ -#undef LOCAL_DEBUG +#define LOCAL_DEBUG #include "lib/lib.h" #include "images/images.h" @@ -89,7 +89,7 @@ image_io_read_header(struct image_io *io) break; case IMAGE_FORMAT_GIF: -#if defined(CONFIG_IMAGES_LIBUNGIF) +#if defined(CONFIG_IMAGES_LIBUNGIF) || defined(CONFIG_IMAGES_LIBGIF) return libungif_read_header(io); #elif defined(CONFIG_IMAGES_LIBMAGICK) return libmagick_read_header(io); @@ -136,7 +136,7 @@ image_io_read_data(struct image_io *io, int ref) break; case IMAGE_FORMAT_GIF: -#if defined(CONFIG_IMAGES_LIBUNGIF) +#if defined(CONFIG_IMAGES_LIBUNGIF) || defined(CONFIG_IMAGES_LIBGIF) result = libungif_read_data(io); #elif defined(CONFIG_IMAGES_LIBMAGICK) result = libmagick_read_data(io); @@ -237,3 +237,86 @@ 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) + { + rdi->need_destroy = 1; + return rdi->image = image_new(io->thread, 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); + } +} + +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"); + 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); + if (unlikely(!img)) + { + image_destroy(rdi->image); + return 0; + } + if (unlikely(!image_scale(io->thread, img, rdi->image))) + { + image_destroy(rdi->image); + if (rdi->need_destroy) + image_destroy(img); + return 0; + } + rdi->image = img; + } + + /* Merge with background */ + if ((io->flags ^ rdi->image->flags) & IMAGE_ALPHA) + { + 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); + if (unlikely(!img)) + { + image_destroy(rdi->image); + return 0; + } + if (unlikely(!image_apply_background(io->thread, img, rdi->image, &io->background_color))) + { + image_destroy(rdi->image); + if (rdi->need_destroy) + image_destroy(img); + return 0; + } + rdi->image = img; + } + + ASSERT(!rdi->need_transformations); + } + + /* Success */ + io->image = rdi->image; + io->image_destroy = rdi->need_destroy; + 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->need_destroy) + image_destroy(rdi->image); +} diff --git a/images/io-main.h b/images/io-main.h index ed4f8537..c7cfffcc 100644 --- a/images/io-main.h +++ b/images/io-main.h @@ -18,55 +18,12 @@ int libmagick_write(struct image_io *io); struct image_io_read_data_internals { struct image *image; - int need_scale; + int need_transformations; int need_destroy; }; -static inline struct image * -image_io_read_data_prepare(struct image_io_read_data_internals *rdi, struct image_io *io, uns cols, uns rows) -{ - rdi->need_scale = io->cols != cols | io->rows != rows; - rdi->need_destroy = rdi->need_scale || !io->pool; - return rdi->image = rdi->need_scale ? - image_new(io->thread, cols, rows, io->flags & IMAGE_CHANNELS_FORMAT, NULL) : - image_new(io->thread, io->cols, io->rows, io->flags & IMAGE_IO_IMAGE_FLAGS, io->pool); -} - -static inline int -image_io_read_data_finish(struct image_io_read_data_internals *rdi, struct image_io *io) -{ - if (rdi->need_scale) - { - struct image *img = image_new(io->thread, io->cols, io->rows, io->flags & IMAGE_IO_IMAGE_FLAGS, io->pool); - if (unlikely(!img)) - { - if (rdi->need_destroy) - image_destroy(rdi->image); - return 0; - } - if (unlikely(!image_scale(io->thread, img, rdi->image))) - { - image_destroy(rdi->image); - if (!io->pool) - image_destroy(img); - return 0; - } - io->image = img; - io->image_destroy = !io->pool; - } - else - { - io->image = rdi->image; - io->image_destroy = rdi->need_destroy; - } - return 1; -} - -static inline void -image_io_read_data_break(struct image_io_read_data_internals *rdi, struct image_io *io UNUSED) -{ - if (rdi->need_destroy) - image_destroy(rdi->image); -} +struct image *image_io_read_data_prepare(struct image_io_read_data_internals *rdi, struct image_io *io, uns cols, uns rows, uns flags); +int image_io_read_data_finish(struct image_io_read_data_internals *rdi, struct image_io *io); +void image_io_read_data_break(struct image_io_read_data_internals *rdi, struct image_io *io); #endif diff --git a/images/scale.c b/images/scale.c index 4eceac67..2c351cbd 100644 --- a/images/scale.c +++ b/images/scale.c @@ -74,7 +74,7 @@ image_dimensions_fit_to_box(u32 *cols, u32 *rows, u32 max_cols, u32 max_rows, un { if (!upsample) return; - if (max_cols / *cols > max_rows / *rows) + if (max_cols * *rows > max_rows * *cols) { *cols = *cols * max_rows / *rows; *cols = MIN(*cols, max_cols); @@ -100,5 +100,4 @@ down_rows: *rows = *rows * max_cols / *cols; *rows = MAX(*rows, 1); *cols = max_cols; - return; }