2 * Image Library -- Image compression/decompression interface
4 * (c) 2006 Pavel Charvat <pchar@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
13 #include <ucw/mempool.h>
14 #include <images/images.h>
15 #include <images/error.h>
16 #include <images/io-main.h>
17 #include <images/color.h>
22 image_io_init(struct image_context *ctx, struct image_io *io)
24 DBG("image_io_init()");
25 bzero(io, sizeof(*io));
27 #ifdef CONFIG_IMAGES_LIBJPEG
28 if (!libjpeg_init(io))
31 #ifdef CONFIG_IMAGES_LIBPNG
35 #ifdef CONFIG_IMAGES_LIBUNGIF
36 if (!libungif_init(io))
39 #ifdef CONFIG_IMAGES_LIBMAGICK
40 if (!libmagick_init(io))
41 goto libmagick_failed;
43 io->internal_pool = mp_new(1024);
45 #ifdef CONFIG_IMAGES_LIBMAGICK
46 libmagick_cleanup(io);
49 #ifdef CONFIG_IMAGES_LIBUNGIF
53 #ifdef CONFIG_IMAGES_LIBPNG
57 #ifdef CONFIG_IMAGES_LIBJPEG
65 image_io_read_cancel(struct image_io *io)
70 io->read_cancel = NULL;
75 image_io_image_destroy(struct image_io *io)
77 if (io->image && (io->flags & IMAGE_IO_NEED_DESTROY))
79 image_destroy(io->image);
80 io->flags &= ~IMAGE_IO_NEED_DESTROY;
86 image_io_cleanup(struct image_io *io)
88 DBG("image_io_cleanup()");
89 image_io_read_cancel(io);
90 image_io_image_destroy(io);
91 #ifdef CONFIG_IMAGES_LIBMAGICK
92 libmagick_cleanup(io);
94 #ifdef CONFIG_IMAGES_LIBUNGIF
97 #ifdef CONFIG_IMAGES_LIBPNG
100 #ifdef CONFIG_IMAGES_LIBJPEG
103 mp_delete(io->internal_pool);
107 image_io_reset(struct image_io *io)
109 DBG("image_io_reset()");
110 image_io_read_cancel(io);
111 image_io_image_destroy(io);
112 struct mempool *pool = io->internal_pool;
113 struct image_context *ctx = io->context;
115 bzero(io, sizeof(*io));
116 io->internal_pool = pool;
121 image_io_read_header(struct image_io *io)
123 DBG("image_io_read_header()");
124 image_io_read_cancel(io);
125 image_io_image_destroy(io);
126 switch (io->format) {
127 case IMAGE_FORMAT_JPEG:
128 #if defined(CONFIG_IMAGES_LIBJPEG)
129 return libjpeg_read_header(io);
130 #elif defined(CONFIG_IMAGES_LIBMAGICK)
131 return libmagick_read_header(io);
135 case IMAGE_FORMAT_PNG:
136 #if defined(CONFIG_IMAGES_LIBPNG)
137 return libpng_read_header(io);
138 #elif defined(CONFIG_IMAGES_LIBMAGICK)
139 return libmagick_read_header(io);
143 case IMAGE_FORMAT_GIF:
144 #if defined(CONFIG_IMAGES_LIBUNGIF) || defined(CONFIG_IMAGES_LIBGIF)
145 return libungif_read_header(io);
146 #elif defined(CONFIG_IMAGES_LIBMAGICK)
147 return libmagick_read_header(io);
151 case IMAGE_FORMAT_UNDEFINED:
152 #if defined (CONFIG_IMAGES_LIBMAGICK)
153 return libmagick_read_header(io);
160 IMAGE_ERROR(io->context, IMAGE_ERROR_INVALID_FILE_FORMAT, "Image format not supported.");
165 image_io_read_data(struct image_io *io, int ref)
167 DBG("image_io_read_data()");
168 ASSERT(io->read_cancel);
169 io->read_cancel = NULL;
171 switch (io->format) {
172 case IMAGE_FORMAT_JPEG:
173 #if defined(CONFIG_IMAGES_LIBJPEG)
174 result = libjpeg_read_data(io);
175 #elif defined(CONFIG_IMAGES_LIBMAGICK)
176 result = libmagick_read_data(io);
182 case IMAGE_FORMAT_PNG:
183 #if defined(CONFIG_IMAGES_LIBPNG)
184 result = libpng_read_data(io);
185 #elif defined(CONFIG_IMAGES_LIBMAGICK)
186 result = libmagick_read_data(io);
192 case IMAGE_FORMAT_GIF:
193 #if defined(CONFIG_IMAGES_LIBUNGIF) || defined(CONFIG_IMAGES_LIBGIF)
194 result = libungif_read_data(io);
195 #elif defined(CONFIG_IMAGES_LIBMAGICK)
196 result = libmagick_read_data(io);
202 case IMAGE_FORMAT_UNDEFINED:
203 #if defined(CONFIG_IMAGES_LIBMAGICK)
204 result = libmagick_read_data(io);
216 io->flags |= IMAGE_IO_NEED_DESTROY;
218 io->flags &= ~IMAGE_IO_NEED_DESTROY;
226 image_io_read(struct image_io *io, int ref)
228 if (!image_io_read_header(io))
230 return image_io_read_data(io, ref);
234 image_io_write(struct image_io *io)
236 DBG("image_io_write()");
237 image_io_read_cancel(io);
238 switch (io->format) {
239 case IMAGE_FORMAT_JPEG:
240 #if defined(CONFIG_IMAGES_LIBJPEG)
241 return libjpeg_write(io);
242 #elif defined(CONFIG_IMAGES_LIBMAGICK)
243 return libmagick_write(io);
247 case IMAGE_FORMAT_PNG:
248 #if defined(CONFIG_IMAGES_LIBPNG)
249 return libpng_write(io);
250 #elif defined(CONFIG_IMAGES_LIBMAGICK)
251 return libmagick_write(io);
255 case IMAGE_FORMAT_GIF:
256 #if defined(CONFIG_IMAGES_LIBMAGICK)
257 return libmagick_write(io);
264 IMAGE_ERROR(io->context, IMAGE_ERROR_INVALID_FILE_FORMAT, "Output format not supported.");
269 image_format_to_extension(enum image_format format)
273 case IMAGE_FORMAT_JPEG:
275 case IMAGE_FORMAT_PNG:
277 case IMAGE_FORMAT_GIF:
285 image_extension_to_format(byte *extension)
287 if (!strcasecmp(extension, "jpg"))
288 return IMAGE_FORMAT_JPEG;
289 if (!strcasecmp(extension, "jpeg"))
290 return IMAGE_FORMAT_JPEG;
291 if (!strcasecmp(extension, "png"))
292 return IMAGE_FORMAT_PNG;
293 if (!strcasecmp(extension, "gif"))
294 return IMAGE_FORMAT_GIF;
295 return IMAGE_FORMAT_UNDEFINED;
299 image_file_name_to_format(byte *file_name)
301 byte *extension = strrchr(file_name, '.');
302 return extension ? image_extension_to_format(extension + 1) : IMAGE_FORMAT_UNDEFINED;
306 image_io_read_data_prepare(struct image_io_read_data_internals *rdi, struct image_io *io, uint cols, uint rows, uint flags)
308 DBG("image_io_read_data_prepare()");
309 if (rdi->need_transformations = io->cols != cols || io->rows != rows ||
310 ((io->flags ^ flags) & IMAGE_NEW_FLAGS))
311 return rdi->image = image_new(io->context, cols, rows, flags & IMAGE_IO_IMAGE_FLAGS, NULL);
313 return rdi->image = image_new(io->context, io->cols, io->rows, io->flags & IMAGE_IO_IMAGE_FLAGS, io->pool);
317 image_io_read_data_finish(struct image_io_read_data_internals *rdi, struct image_io *io)
319 DBG("image_io_read_data_finish()");
320 if (rdi->need_transformations)
322 /* Scale the image */
323 if (io->cols != rdi->image->cols || io->rows != rdi->image->rows)
325 DBG("Scaling image");
326 uint flags = rdi->image->flags;
327 if (!(rdi->need_transformations = ((io->flags ^ rdi->image->flags) & (IMAGE_NEW_FLAGS & ~IMAGE_PIXELS_ALIGNED))))
329 struct image *img = image_new(io->context, io->cols, io->rows, flags, rdi->need_transformations ? NULL : io->pool);
332 image_destroy(rdi->image);
335 if (unlikely(!image_scale(io->context, img, rdi->image)))
337 image_destroy(rdi->image);
341 image_destroy(rdi->image);
345 /* Convert pixel format */
346 if (io->flags != rdi->image->flags)
348 struct image *img = image_new(io->context, io->cols, io->rows, io->flags, io->pool);
351 image_destroy(rdi->image);
354 struct image_conv_options opt = image_conv_defaults;
355 opt.background = io->background_color;
356 if (unlikely(!image_conv(io->context, img, rdi->image, &opt)))
358 image_destroy(rdi->image);
362 image_destroy(rdi->image);
368 io->image = rdi->image;
373 image_io_read_data_break(struct image_io_read_data_internals *rdi, struct image_io *io UNUSED)
375 DBG("image_io_read_data_break()");
377 image_destroy(rdi->image);