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 io->internal_pool = mp_new(1024);
27 image_io_read_cancel(struct image_io *io)
32 io->read_cancel = NULL;
37 image_io_image_destroy(struct image_io *io)
39 if (io->image && (io->flags & IMAGE_IO_NEED_DESTROY))
41 image_destroy(io->image);
42 io->flags &= ~IMAGE_IO_NEED_DESTROY;
48 image_io_cleanup(struct image_io *io)
50 DBG("image_io_cleanup()");
51 image_io_read_cancel(io);
52 image_io_image_destroy(io);
53 mp_delete(io->internal_pool);
57 image_io_reset(struct image_io *io)
59 DBG("image_io_reset()");
60 image_io_read_cancel(io);
61 image_io_image_destroy(io);
62 struct mempool *pool = io->internal_pool;
63 struct image_thread *thread = io->thread;
65 bzero(io, sizeof(*io));
66 io->internal_pool = pool;
71 image_io_read_header(struct image_io *io)
73 DBG("image_io_read_header()");
74 image_io_read_cancel(io);
75 image_io_image_destroy(io);
77 case IMAGE_FORMAT_JPEG:
78 #if defined(CONFIG_IMAGES_LIBJPEG)
79 return libjpeg_read_header(io);
80 #elif defined(CONFIG_IMAGES_LIBMAGICK)
81 return libmagick_read_header(io);
85 case IMAGE_FORMAT_PNG:
86 #if defined(CONFIG_IMAGES_LIBPNG)
87 return libpng_read_header(io);
88 #elif defined(CONFIG_IMAGES_LIBMAGICK)
89 return libmagick_read_header(io);
93 case IMAGE_FORMAT_GIF:
94 #if defined(CONFIG_IMAGES_LIBUNGIF) || defined(CONFIG_IMAGES_LIBGIF)
95 return libungif_read_header(io);
96 #elif defined(CONFIG_IMAGES_LIBMAGICK)
97 return libmagick_read_header(io);
101 case IMAGE_FORMAT_UNDEFINED:
102 #if defined (CONFIG_IMAGES_LIBMAGICK)
103 return libmagick_read_header(io);
110 image_thread_err(io->thread, IMAGE_ERR_INVALID_FILE_FORMAT, "Image format not supported.");
115 image_io_read_data(struct image_io *io, int ref)
117 DBG("image_io_read_data()");
118 ASSERT(io->read_cancel);
119 io->read_cancel = NULL;
121 switch (io->format) {
122 case IMAGE_FORMAT_JPEG:
123 #if defined(CONFIG_IMAGES_LIBJPEG)
124 result = libjpeg_read_data(io);
125 #elif defined(CONFIG_IMAGES_LIBMAGICK)
126 result = libmagick_read_data(io);
132 case IMAGE_FORMAT_PNG:
133 #if defined(CONFIG_IMAGES_LIBPNG)
134 result = libpng_read_data(io);
135 #elif defined(CONFIG_IMAGES_LIBMAGICK)
136 result = libmagick_read_data(io);
142 case IMAGE_FORMAT_GIF:
143 #if defined(CONFIG_IMAGES_LIBUNGIF) || defined(CONFIG_IMAGES_LIBGIF)
144 result = libungif_read_data(io);
145 #elif defined(CONFIG_IMAGES_LIBMAGICK)
146 result = libmagick_read_data(io);
152 case IMAGE_FORMAT_UNDEFINED:
153 #if defined(CONFIG_IMAGES_LIBMAGICK)
154 result = libmagick_read_data(io);
166 io->flags |= IMAGE_IO_NEED_DESTROY;
168 io->flags &= ~IMAGE_IO_NEED_DESTROY;
176 image_io_read(struct image_io *io, int ref)
178 if (!image_io_read_header(io))
180 return image_io_read_data(io, ref);
184 image_io_write(struct image_io *io)
186 DBG("image_io_write()");
187 image_io_read_cancel(io);
188 switch (io->format) {
189 case IMAGE_FORMAT_JPEG:
190 #if defined(CONFIG_IMAGES_LIBJPEG)
191 return libjpeg_write(io);
192 #elif defined(CONFIG_IMAGES_LIBMAGICK)
193 return libmagick_write(io);
197 case IMAGE_FORMAT_PNG:
198 #if defined(CONFIG_IMAGES_LIBPNG)
199 return libpng_write(io);
200 #elif defined(CONFIG_IMAGES_LIBMAGICK)
201 return libmagick_write(io);
205 case IMAGE_FORMAT_GIF:
206 #if defined(CONFIG_IMAGES_LIBMAGICK)
207 return libmagick_write(io);
214 image_thread_err(io->thread, IMAGE_ERR_INVALID_FILE_FORMAT, "Output format not supported.");
219 image_format_to_extension(enum image_format format)
223 case IMAGE_FORMAT_JPEG:
225 case IMAGE_FORMAT_PNG:
227 case IMAGE_FORMAT_GIF:
235 image_extension_to_format(byte *extension)
237 if (!strcasecmp(extension, "jpg"))
238 return IMAGE_FORMAT_JPEG;
239 if (!strcasecmp(extension, "jpeg"))
240 return IMAGE_FORMAT_JPEG;
241 if (!strcasecmp(extension, "png"))
242 return IMAGE_FORMAT_PNG;
243 if (!strcasecmp(extension, "gif"))
244 return IMAGE_FORMAT_GIF;
245 return IMAGE_FORMAT_UNDEFINED;
249 image_file_name_to_format(byte *file_name)
251 byte *extension = strrchr(file_name, '.');
252 return extension ? image_extension_to_format(extension + 1) : IMAGE_FORMAT_UNDEFINED;
256 image_io_read_data_prepare(struct image_io_read_data_internals *rdi, struct image_io *io, uns cols, uns rows, uns flags)
258 DBG("image_io_read_data_prepare()");
259 if (rdi->need_transformations = io->cols != cols || io->rows != rows ||
260 ((io->flags ^ flags) & IMAGE_NEW_FLAGS))
261 return rdi->image = image_new(io->thread, cols, rows, flags & IMAGE_IO_IMAGE_FLAGS, NULL);
263 return rdi->image = image_new(io->thread, io->cols, io->rows, io->flags & IMAGE_IO_IMAGE_FLAGS, io->pool);
267 image_io_read_data_finish(struct image_io_read_data_internals *rdi, struct image_io *io)
269 DBG("image_io_read_data_finish()");
270 if (rdi->need_transformations)
272 /* Scale the image */
273 if (io->cols != rdi->image->cols || io->rows != rdi->image->rows)
275 DBG("Scaling image");
276 uns flags = rdi->image->flags;
277 if (!(rdi->need_transformations = ((io->flags ^ rdi->image->flags) & (IMAGE_NEW_FLAGS & ~IMAGE_PIXELS_ALIGNED))))
279 struct image *img = image_new(io->thread, io->cols, io->rows, flags, rdi->need_transformations ? NULL : io->pool);
282 image_destroy(rdi->image);
285 if (unlikely(!image_scale(io->thread, img, rdi->image)))
287 image_destroy(rdi->image);
291 image_destroy(rdi->image);
295 /* Merge with background */
296 if ((io->flags ^ rdi->image->flags) & IMAGE_ALPHA)
298 DBG("Aplying background");
299 uns flags = rdi->image->flags & ~IMAGE_ALPHA;
300 if (!(rdi->need_transformations = (flags ^ io->flags) & (IMAGE_NEW_FLAGS & ~IMAGE_PIXELS_ALIGNED)))
302 struct image *img = image_new(io->thread, io->cols, io->rows, flags, rdi->need_transformations ? NULL : io->pool);
305 image_destroy(rdi->image);
308 if (unlikely(!image_apply_background(io->thread, img, rdi->image, &io->background_color)))
310 image_destroy(rdi->image);
314 image_destroy(rdi->image);
318 // FIXME: support for various color spaces
320 ASSERT(!rdi->need_transformations);
324 io->image = rdi->image;
329 image_io_read_data_break(struct image_io_read_data_internals *rdi, struct image_io *io UNUSED)
331 DBG("image_io_read_data_break()");
333 image_destroy(rdi->image);