7f324bfef57725792f30447fdf482b084e815427
[colorize.git] / src / ppm.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include "ppm.h"
5
6 #ifdef WITH_MAGICK
7 #include <magick/api.h>
8
9 /* load given PPM image to memory. return memory pointer, witdth and height
10  * if offset is given, no memory is allocated */
11 int load_img(int offset, unsigned char **buffer, int *width, int *height,
12         const char *filename, int index)
13 {
14         int rc = -1;
15         Image *image = NULL;
16         ImageInfo *imageinfo = NULL;
17         ExceptionInfo exception;
18
19 //      MagickCoreGenesis(NULL,MagickFalse);
20         InitializeMagick(NULL);
21         imageinfo = CloneImageInfo(0);
22         GetExceptionInfo(&exception);
23
24         sprintf(imageinfo->filename, filename, index);
25
26         image = ReadImage(imageinfo, &exception);
27         if (!image) {
28 //              printf("failed to read image '%s' via *magick\n", filename);
29                 goto exit;
30         }
31         *width = image->columns;
32         *height = image->rows;
33
34         if (offset < 0) {
35                 *buffer = (unsigned char *)malloc((*width) * (*height) * 3);
36                 if (!*buffer) {
37                         printf("failed to allocate image data\n");
38                         goto exit;
39                 }
40                 offset = 0;
41         }
42 //      ExportImagePixels(image, 0, 0, *width, *height, "RGB", CharPixel, *buffer, NULL);
43         DispatchImage(image, 0, 0, *width, *height, "RGB", CharPixel, *buffer, NULL);
44
45         rc = 0;
46
47 exit:
48         if (image)
49                 DestroyImage(image);
50
51         if (imageinfo)
52                 DestroyImageInfo(imageinfo);
53
54 //      MagickCoreTerminus();
55         DestroyMagick();
56
57         return rc;
58 }
59
60 /* save given image */
61 int save_img(unsigned char *buffer, int width, int height, const char *filename,
62         int index)
63 {
64         int rc = -1;
65         Image *image = NULL;
66         ImageInfo *imageinfo = NULL;
67         ExceptionInfo exception;
68
69 //      MagickCoreGenesis(NULL,MagickFalse);
70         InitializeMagick(NULL);
71         imageinfo = CloneImageInfo(0);
72         GetExceptionInfo(&exception);
73
74         imageinfo->quality = 100;
75
76         image=ConstituteImage(width, height, "RGB", CharPixel, buffer, &exception);
77         if (!image) {
78                 printf("failed to prepare to write image\n");
79                 goto exit;
80         }
81         sprintf(image->filename, filename, index); /* ACHTUNG: nicht imageinfo!!! */
82         if (!WriteImage(imageinfo, image)) {
83                 printf("failed to write image\n");
84                 goto exit;
85         }
86
87         rc = 0;
88
89 exit:
90         if (image)
91                 DestroyImage(image);
92
93         if (imageinfo)
94                 DestroyImageInfo(imageinfo);
95
96 //      MagickCoreTerminus();
97         DestroyMagick();
98
99         return rc;
100 }
101 #else
102
103 /* load given PPM image to memory. return memory pointer, witdth and height
104  * if offset is given, no memory is allocated */
105 int load_img(int offset, unsigned char **buffer, int *width, int *height,
106         const char *filename, int index)
107 {
108         FILE *fp;
109         char line[256];
110         int words, i;
111
112         sprintf(line, filename, index);
113 //      printf("reading image: %s\n", line);
114         fp = fopen(line, "r");
115         if (!fp) {
116 //              printf("failed to read ppm image '%s'\n", filename);
117                 return -1;
118         }
119 again1:
120         if (!fgets(line, sizeof(line), fp)) {
121                 printf("failed to read image depth\n");
122                 fclose(fp);
123                 return -1;
124         }
125         line[sizeof(line)-1] = '\0';
126         if (line[0]) line[strlen(line)-1] = '\0';
127         if (line[0] == '#')
128                 goto again1;
129         if (!!strcmp(line, "P6")) {
130                 printf("expecting image depth 'P6'\n");
131                 fclose(fp);
132                 return -1;
133         }
134 again2:
135         if (!fgets(line, sizeof(line), fp)) {
136                 printf("failed to read image size\n");
137                 fclose(fp);
138                 return -1;
139         }
140         line[sizeof(line)-1] = '\0';
141         if (line[0]) line[strlen(line)-1] = '\0';
142         if (line[0] == '#')
143                 goto again2;
144         sscanf(line, "%d %d", width, height);
145 //      printf("Image size: w=%d h=%d\n", *width, *height);
146 again3:
147         if (!fgets(line, sizeof(line), fp)) {
148                 printf("failed to read line '255' or '65535'\n");
149                 fclose(fp);
150                 return -1;
151         }
152         line[sizeof(line)-1] = '\0';
153         if (line[0]) line[strlen(line)-1] = '\0';
154         if (line[0] == '#')
155                 goto again3;
156         if (!strcmp(line, "255")) {
157                 words = 1;
158         } else
159         if (!strcmp(line, "65535")) {
160                 words = 2;
161         } else {
162                 printf("expecting line '255' or '65535'\n");
163                 fclose(fp);
164                 return -1;
165         }
166         if (offset < 0) {
167                 *buffer = (unsigned char *)malloc((*width) * (*height) * 3 * words);
168                 if (!*buffer) {
169                         printf("failed to allocate image data\n");
170                         fclose(fp);
171                         return -1;
172                 }
173                 offset = 0;
174         }
175         if (fread((*buffer) + offset, (*width) * (*height) * 3 * words, 1, fp) != 1) {
176                 printf("failed to read image data\n");
177                 free(*buffer);
178                 fclose(fp);
179                 return -1;
180         }
181
182         /* convert 16 to 8 bits */
183         if (words == 2) {
184                 for (i = 0; i < (*width) * (*height) * 3; i++)
185                         (*buffer)[offset + i] = (*buffer)[offset + i*2];
186         }
187
188         fclose(fp);
189
190         return 0;
191 }
192
193 /* save given image */
194 int save_img(unsigned char *buffer, int width, int height, const char *filename,
195         int index)
196 {
197         FILE *fp;
198         int rc;
199         char line[256];
200
201         sprintf(line, filename, index);
202 //      printf("writing image: %s\n", line);
203         fp = fopen(line, "w");
204         if (!fp) {
205                 printf("failed to write image\n");
206                 return -1;
207         }
208         fprintf(fp, "P6\n%d %d\n255\n", width, height);
209         rc = fwrite(buffer, width * height * 3, 1, fp);
210         fclose(fp);
211
212         return rc;
213 }
214 #endif
215
216 /* convert an image to a three dimensional array of double
217  * the size is: width, height, 3
218  */
219 void img2array(unsigned char *img, int iw, int ih, double *array, int aw,
220         int ah)
221 {
222         int x, y;
223         int plane = aw * ah;
224         double r, g, b;
225
226         for (y = 0; y < ih; y++) {
227                 for (x = 0; x < iw; x++) {
228                         r = img[(x+iw*y)*3] / 255.0F;
229                         g = img[(x+iw*y)*3+1] / 255.0F;
230                         b = img[(x+iw*y)*3+2] / 255.0F;
231                         array[x+aw*y] = r;
232                         array[x+aw*y+plane] = g;
233                         array[x+aw*y+plane+plane] = b;
234                 }
235         }
236 }
237
238 /* convert a three dimensional array of double to an image
239  * the size is: width, height, 3
240  */
241 void array2img(double *array, int aw, int ah, unsigned char *img, int iw,
242         int ih)
243 {
244         int x, y, c;
245         int plane = aw * ah;
246         double r, g, b;
247
248         for (y = 0; y < ih; y++) {
249                 for (x = 0; x < iw; x++) {
250                         r = array[x+aw*y];
251                         g = array[x+aw*y+plane];
252                         b = array[x+aw*y+plane+plane];
253                         c = (r * 255.0F + 0.5F);
254                         if (c < 0)
255                                 c = 0;
256                         else if (c > 255)
257                                 c = 255;
258                         img[(x+iw*y)*3] = c;
259                         c = (g * 255.0F + 0.5F);
260                         if (c < 0)
261                                 c = 0;
262                         else if (c > 255)
263                                 c = 255;
264                         img[(x+iw*y)*3+1] = c;
265                         c = (b * 255.0F + 0.5F);
266                         if (c < 0)
267                                 c = 0;
268                         else if (c > 255)
269                                 c = 255;
270                         img[(x+iw*y)*3+2] = c;
271                 }
272         }
273 }
274
275