]> mj.ucw.cz Git - libucw.git/blob - images/io-main.c
slow image compression via GraphicsMagick
[libucw.git] / images / io-main.c
1 /*
2  *      Image Library -- Image compression/decompression interface
3  *
4  *      (c) 2006 Pavel Charvat <pchar@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #undef LOCAL_DEBUG
11
12 #include "lib/lib.h"
13 #include "images/images.h"
14 #include <string.h>
15
16 void
17 image_io_init(struct image_thread *it, struct image_io *io)
18 {
19   DBG("image_io_init()");
20   bzero(io, sizeof(*io));
21   io->thread = it;
22   io->internal_pool = mp_new(1024);
23 }
24
25 static inline void
26 image_io_read_cancel(struct image_io *io)
27 {
28   if (io->read_cancel)
29     {
30       io->read_cancel(io);
31       io->read_cancel = NULL;
32     }
33 }
34
35 static inline void
36 image_io_image_destroy(struct image_io *io)
37 {
38   if (io->image_destroy)
39     {
40       image_destroy(io->thread, io->image);
41       io->image_destroy = 0;
42       io->image = NULL;
43     }
44 }
45
46 void
47 image_io_cleanup(struct image_io *io)
48 {
49   DBG("image_io_cleanup()");
50   image_io_read_cancel(io);
51   image_io_image_destroy(io);
52   mp_delete(io->internal_pool);
53 }
54
55 void
56 image_io_reset(struct image_io *io)
57 {
58   DBG("image_io_reset()");
59   image_io_read_cancel(io);
60   image_io_image_destroy(io);
61   struct mempool *pool = io->internal_pool;
62   mp_flush(pool);
63   bzero(io, sizeof(*io));
64   io->internal_pool = pool;
65 }
66
67 int
68 image_io_read_header(struct image_io *io)
69 {
70   DBG("image_io_read_header()");
71   image_io_read_cancel(io);
72   image_io_image_destroy(io);
73   switch (io->format) {
74     case IMAGE_FORMAT_JPEG:
75 #if defined(CONFIG_LIBJPEG)
76       return libjpeg_read_header(io);
77 #elif defined(CONFIG_LIBMAGICK)
78       return libmagick_read_header(io);
79 #endif
80       break;
81
82     case IMAGE_FORMAT_PNG:
83 #if defined(CONFIG_LIBPNG)
84       return libpng_read_header(io);
85 #elif defined(CONFIG_LIBMAGICK)
86       return libmagick_read_header(io);
87 #endif
88       break;
89
90     case IMAGE_FORMAT_GIF:
91 #if defined(CONFIG_LIBUNGIG)
92       return libungif_read_header(io);
93 #elif defined(CONFIG_LIBMAGICK)
94       return libmagick_read_header(io);
95 #endif
96       break;
97
98     case IMAGE_FORMAT_UNDEFINED:
99       // FIXME: auto-detect
100       break;
101
102     default:
103       ASSERT(0);
104   }
105   image_thread_err(io->thread, IMAGE_ERR_INVALID_FILE_FORMAT, "Image format not supported.");
106   return 0;
107 }
108
109 struct image *
110 image_io_read_data(struct image_io *io, int ref)
111 {
112   DBG("image_io_read_data()");
113   ASSERT(io->read_cancel);
114   io->read_cancel = NULL;
115   int result;
116   switch (io->format) {
117     case IMAGE_FORMAT_JPEG:
118 #if defined(CONFIG_LIBJPEG)
119       result = libjpeg_read_data(io);
120 #elif defined(CONFIG_LIBMAGICK)
121       result = libmagick_read_data(io);
122 #else
123       ASSERT(0);
124 #endif
125       break;
126
127     case IMAGE_FORMAT_PNG:
128 #if defined(CONFIG_LIBPNG)
129       result = libpng_read_data(io);
130 #elif defined(CONFIG_LIBMAGICK)
131       result = libmagick_read_data(io);
132 #else
133       ASSERT(0);
134 #endif
135       break;
136
137     case IMAGE_FORMAT_GIF:
138 #if defined(CONFIG_LIBUNGIF)
139       result = libungif_read_data(io);
140 #elif defined(CONFIG_LIBMAGICK)
141       result = libmagick_read_data(io);
142 #else
143       ASSERT(0);
144 #endif
145       break;
146
147     default:
148       ASSERT(0);
149   }
150   if (result)
151     {
152       if (ref)
153         io->image_destroy = 0;
154       return io->image;
155     }
156   else
157     return NULL;
158 }
159
160 struct image *
161 image_io_read(struct image_io *io, int ref)
162 {
163   if (!image_io_read_header(io))
164     return NULL;
165   return image_io_read_data(io, ref);
166 }
167
168 int
169 image_io_write(struct image_io *io)
170 {
171   DBG("image_io_write()");
172   image_io_read_cancel(io);
173   switch (io->format) {
174     case IMAGE_FORMAT_JPEG:
175 #if defined(CONFIG_LIBJPEG)
176       return libjpeg_write(io);
177 #elif defined(CONFIG_LIBMAGICK)
178       return libmagick_write(io);
179 #endif
180       break;
181
182     case IMAGE_FORMAT_PNG:
183 #if defined(CONFIG_LIBMAGICK)
184       return libmagick_write(io);
185 #endif
186       break;
187
188     case IMAGE_FORMAT_GIF:
189 #if defined(CONFIG_LIBMAGICK)
190       return libmagick_write(io);
191 #endif
192       break;
193
194     default:
195       break;
196   }
197   image_thread_err(io->thread, IMAGE_ERR_INVALID_FILE_FORMAT, "Image format not supported.");
198   return 0;
199 }
200
201 byte *
202 image_format_to_extension(enum image_format format)
203 {
204   switch (format)
205     {
206       case IMAGE_FORMAT_JPEG:
207         return "jpg";
208       case IMAGE_FORMAT_PNG:
209         return "png";
210       case IMAGE_FORMAT_GIF:
211         return "gif";
212       default:
213         return NULL;
214     }
215 }
216
217 enum image_format
218 image_extension_to_format(byte *extension)
219 {
220   if (!strcasecmp(extension, "jpg"))
221     return IMAGE_FORMAT_JPEG;
222   if (!strcasecmp(extension, "jpeg"))
223     return IMAGE_FORMAT_JPEG;
224   if (!strcasecmp(extension, "png"))
225     return IMAGE_FORMAT_PNG;
226   if (!strcasecmp(extension, "gif"))
227     return IMAGE_FORMAT_GIF;
228   return IMAGE_FORMAT_UNDEFINED;
229 }
230
231 enum image_format
232 image_file_name_to_format(byte *file_name)
233 {
234   byte *extension = strrchr(file_name, '.');
235   return extension ? image_extension_to_format(extension + 1) : IMAGE_FORMAT_UNDEFINED;
236 }