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 "images/images.h"
14 #include "images/io-main.h"
18 image_io_init(struct image_thread *it, struct image_io *io)
20 DBG("image_io_init()");
21 bzero(io, sizeof(*io));
23 #ifdef CONFIG_IMAGES_LIBJPEG
24 if (!libjpeg_init(io))
27 #ifdef CONFIG_IMAGES_LIBPNG
31 #ifdef CONFIG_IMAGES_LIBUNGIF
32 if (!libungif_init(io))
35 #ifdef CONFIG_IMAGES_LIBMAGICK
36 if (!libmagick_init(io))
37 goto libmagick_failed;
39 io->internal_pool = mp_new(1024);
41 #ifdef CONFIG_IMAGES_LIBMAGICK
42 libmagick_cleanup(io);
45 #ifdef CONFIG_IMAGES_LIBUNGIF
49 #ifdef CONFIG_IMAGES_LIBPNG
53 #ifdef CONFIG_IMAGES_LIBJPEG
61 image_io_read_cancel(struct image_io *io)
66 io->read_cancel = NULL;
71 image_io_image_destroy(struct image_io *io)
73 if (io->image && (io->flags & IMAGE_IO_NEED_DESTROY))
75 image_destroy(io->image);
76 io->flags &= ~IMAGE_IO_NEED_DESTROY;
82 image_io_cleanup(struct image_io *io)
84 DBG("image_io_cleanup()");
85 image_io_read_cancel(io);
86 image_io_image_destroy(io);
87 #ifdef CONFIG_IMAGES_LIBMAGICK
88 libmagick_cleanup(io);
90 #ifdef CONFIG_IMAGES_LIBUNGIF
93 #ifdef CONFIG_IMAGES_LIBPNG
96 #ifdef CONFIG_IMAGES_LIBJPEG
99 mp_delete(io->internal_pool);
103 image_io_reset(struct image_io *io)
105 DBG("image_io_reset()");
106 image_io_read_cancel(io);
107 image_io_image_destroy(io);
108 struct mempool *pool = io->internal_pool;
109 struct image_thread *thread = io->thread;
111 bzero(io, sizeof(*io));
112 io->internal_pool = pool;
117 image_io_read_header(struct image_io *io)
119 DBG("image_io_read_header()");
120 image_io_read_cancel(io);
121 image_io_image_destroy(io);
122 switch (io->format) {
123 case IMAGE_FORMAT_JPEG:
124 #if defined(CONFIG_IMAGES_LIBJPEG)
125 return libjpeg_read_header(io);
126 #elif defined(CONFIG_IMAGES_LIBMAGICK)
127 return libmagick_read_header(io);
131 case IMAGE_FORMAT_PNG:
132 #if defined(CONFIG_IMAGES_LIBPNG)
133 return libpng_read_header(io);
134 #elif defined(CONFIG_IMAGES_LIBMAGICK)
135 return libmagick_read_header(io);
139 case IMAGE_FORMAT_GIF:
140 #if defined(CONFIG_IMAGES_LIBUNGIF) || defined(CONFIG_IMAGES_LIBGIF)
141 return libungif_read_header(io);
142 #elif defined(CONFIG_IMAGES_LIBMAGICK)
143 return libmagick_read_header(io);
147 case IMAGE_FORMAT_UNDEFINED:
148 #if defined (CONFIG_IMAGES_LIBMAGICK)
149 return libmagick_read_header(io);
156 image_thread_err(io->thread, IMAGE_ERR_INVALID_FILE_FORMAT, "Image format not supported.");
161 image_io_read_data(struct image_io *io, int ref)
163 DBG("image_io_read_data()");
164 ASSERT(io->read_cancel);
165 io->read_cancel = NULL;
167 switch (io->format) {
168 case IMAGE_FORMAT_JPEG:
169 #if defined(CONFIG_IMAGES_LIBJPEG)
170 result = libjpeg_read_data(io);
171 #elif defined(CONFIG_IMAGES_LIBMAGICK)
172 result = libmagick_read_data(io);
178 case IMAGE_FORMAT_PNG:
179 #if defined(CONFIG_IMAGES_LIBPNG)
180 result = libpng_read_data(io);
181 #elif defined(CONFIG_IMAGES_LIBMAGICK)
182 result = libmagick_read_data(io);
188 case IMAGE_FORMAT_GIF:
189 #if defined(CONFIG_IMAGES_LIBUNGIF) || defined(CONFIG_IMAGES_LIBGIF)
190 result = libungif_read_data(io);
191 #elif defined(CONFIG_IMAGES_LIBMAGICK)
192 result = libmagick_read_data(io);
198 case IMAGE_FORMAT_UNDEFINED:
199 #if defined(CONFIG_IMAGES_LIBMAGICK)
200 result = libmagick_read_data(io);
212 io->flags |= IMAGE_IO_NEED_DESTROY;
214 io->flags &= ~IMAGE_IO_NEED_DESTROY;
222 image_io_read(struct image_io *io, int ref)
224 if (!image_io_read_header(io))
226 return image_io_read_data(io, ref);
230 image_io_write(struct image_io *io)
232 DBG("image_io_write()");
233 image_io_read_cancel(io);
234 switch (io->format) {
235 case IMAGE_FORMAT_JPEG:
236 #if defined(CONFIG_IMAGES_LIBJPEG)
237 return libjpeg_write(io);
238 #elif defined(CONFIG_IMAGES_LIBMAGICK)
239 return libmagick_write(io);
243 case IMAGE_FORMAT_PNG:
244 #if defined(CONFIG_IMAGES_LIBPNG)
245 return libpng_write(io);
246 #elif defined(CONFIG_IMAGES_LIBMAGICK)
247 return libmagick_write(io);
251 case IMAGE_FORMAT_GIF:
252 #if defined(CONFIG_IMAGES_LIBMAGICK)
253 return libmagick_write(io);
260 image_thread_err(io->thread, IMAGE_ERR_INVALID_FILE_FORMAT, "Output format not supported.");
265 image_format_to_extension(enum image_format format)
269 case IMAGE_FORMAT_JPEG:
271 case IMAGE_FORMAT_PNG:
273 case IMAGE_FORMAT_GIF:
281 image_extension_to_format(byte *extension)
283 if (!strcasecmp(extension, "jpg"))
284 return IMAGE_FORMAT_JPEG;
285 if (!strcasecmp(extension, "jpeg"))
286 return IMAGE_FORMAT_JPEG;
287 if (!strcasecmp(extension, "png"))
288 return IMAGE_FORMAT_PNG;
289 if (!strcasecmp(extension, "gif"))
290 return IMAGE_FORMAT_GIF;
291 return IMAGE_FORMAT_UNDEFINED;
295 image_file_name_to_format(byte *file_name)
297 byte *extension = strrchr(file_name, '.');
298 return extension ? image_extension_to_format(extension + 1) : IMAGE_FORMAT_UNDEFINED;
302 image_io_read_data_prepare(struct image_io_read_data_internals *rdi, struct image_io *io, uns cols, uns rows, uns flags)
304 DBG("image_io_read_data_prepare()");
305 if (rdi->need_transformations = io->cols != cols || io->rows != rows ||
306 ((io->flags ^ flags) & IMAGE_NEW_FLAGS))
307 return rdi->image = image_new(io->thread, cols, rows, flags & IMAGE_IO_IMAGE_FLAGS, NULL);
309 return rdi->image = image_new(io->thread, io->cols, io->rows, io->flags & IMAGE_IO_IMAGE_FLAGS, io->pool);
313 image_io_read_data_finish(struct image_io_read_data_internals *rdi, struct image_io *io)
315 DBG("image_io_read_data_finish()");
316 if (rdi->need_transformations)
318 /* Scale the image */
319 if (io->cols != rdi->image->cols || io->rows != rdi->image->rows)
321 DBG("Scaling image");
322 uns flags = rdi->image->flags;
323 if (!(rdi->need_transformations = ((io->flags ^ rdi->image->flags) & (IMAGE_NEW_FLAGS & ~IMAGE_PIXELS_ALIGNED))))
325 struct image *img = image_new(io->thread, io->cols, io->rows, flags, rdi->need_transformations ? NULL : io->pool);
328 image_destroy(rdi->image);
331 if (unlikely(!image_scale(io->thread, img, rdi->image)))
333 image_destroy(rdi->image);
337 image_destroy(rdi->image);
341 /* Merge with background */
342 if ((io->flags ^ rdi->image->flags) & IMAGE_ALPHA)
344 DBG("Aplying background");
345 uns flags = rdi->image->flags & ~IMAGE_ALPHA;
346 if (!(rdi->need_transformations = (flags ^ io->flags) & (IMAGE_NEW_FLAGS & ~IMAGE_PIXELS_ALIGNED)))
348 struct image *img = image_new(io->thread, io->cols, io->rows, flags, rdi->need_transformations ? NULL : io->pool);
351 image_destroy(rdi->image);
354 if (unlikely(!image_apply_background(io->thread, img, rdi->image, &io->background_color)))
356 image_destroy(rdi->image);
360 image_destroy(rdi->image);
364 // FIXME: support for various color spaces
366 ASSERT(!rdi->need_transformations);
370 io->image = rdi->image;
375 image_io_read_data_break(struct image_io_read_data_internals *rdi, struct image_io *io UNUSED)
377 DBG("image_io_read_data_break()");
379 image_destroy(rdi->image);