]> Creatis software - gdcm.git/blob - src/gdcmopenjpeg/codec/convert.c
06b460aeca8721974fc8edfa161b8cdfb675e8eb
[gdcm.git] / src / gdcmopenjpeg / codec / convert.c
1 /*\r
2  * Copyright (c) 2001-2003, David Janssens\r
3  * Copyright (c) 2002-2003, Yannick Verschueren\r
4  * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe\r
5  * Copyright (c) 2005, HervĂ© Drolon, FreeImage Team\r
6  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium\r
7  * All rights reserved.\r
8  *\r
9  * Redistribution and use in source and binary forms, with or without\r
10  * modification, are permitted provided that the following conditions\r
11  * are met:\r
12  * 1. Redistributions of source code must retain the above copyright\r
13  *    notice, this list of conditions and the following disclaimer.\r
14  * 2. Redistributions in binary form must reproduce the above copyright\r
15  *    notice, this list of conditions and the following disclaimer in the\r
16  *    documentation and/or other materials provided with the distribution.\r
17  *\r
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
28  * POSSIBILITY OF SUCH DAMAGE.\r
29  */\r
30 #include <stdio.h>\r
31 #include <stdlib.h>\r
32 #include <string.h>\r
33 #include "openjpeg.h"\r
34 \r
35 /*\r
36  * Get logarithm of an integer and round downwards.\r
37  *\r
38  * log2(a)\r
39  */\r
40 static int int_floorlog2(int a) {\r
41   int l;\r
42   for (l = 0; a > 1; l++) {\r
43     a >>= 1;\r
44   }\r
45   return l;\r
46 }\r
47 \r
48 /*\r
49  * Divide an integer by a power of 2 and round upwards.\r
50  *\r
51  * a divided by 2^b\r
52  */\r
53 static int int_ceildivpow2(int a, int b) {\r
54   return (a + (1 << b) - 1) >> b;\r
55 }\r
56 \r
57 /*\r
58  * Divide an integer and round upwards.\r
59  *\r
60  * a divided by b\r
61  */\r
62 static int int_ceildiv(int a, int b) {\r
63   return (a + b - 1) / b;\r
64 }\r
65 \r
66 /* -->> -->> -->> -->>\r
67 \r
68   BMP IMAGE FORMAT\r
69 \r
70  <<-- <<-- <<-- <<-- */\r
71 \r
72 /* WORD defines a two byte word */\r
73 typedef unsigned short int WORD;\r
74 \r
75 /* DWORD defines a four byte word */\r
76 typedef unsigned long int DWORD;\r
77 \r
78 typedef struct {\r
79   WORD bfType;      /* 'BM' for Bitmap (19776) */\r
80   DWORD bfSize;      /* Size of the file        */\r
81   WORD bfReserved1;    /* Reserved : 0            */\r
82   WORD bfReserved2;    /* Reserved : 0            */\r
83   DWORD bfOffBits;    /* Offset                  */\r
84 } BITMAPFILEHEADER_t;\r
85 \r
86 typedef struct {\r
87   DWORD biSize;      /* Size of the structure in bytes */\r
88   DWORD biWidth;    /* Width of the image in pixels */\r
89   DWORD biHeight;    /* Heigth of the image in pixels */\r
90   WORD biPlanes;    /* 1 */\r
91   WORD biBitCount;    /* Number of color bits by pixels */\r
92   DWORD biCompression;    /* Type of encoding 0: none 1: RLE8 2: RLE4 */\r
93   DWORD biSizeImage;    /* Size of the image in bytes */\r
94   DWORD biXpelsPerMeter;  /* Horizontal (X) resolution in pixels/meter */\r
95   DWORD biYpelsPerMeter;  /* Vertical (Y) resolution in pixels/meter */\r
96   DWORD biClrUsed;    /* Number of color used in the image (0: ALL) */\r
97   DWORD biClrImportant;    /* Number of important color (0: ALL) */\r
98 } BITMAPINFOHEADER_t;\r
99 \r
100 opj_image_t* bmptoimage(char *filename, opj_cparameters_t *parameters) {\r
101   int subsampling_dx = parameters->subsampling_dx;\r
102   int subsampling_dy = parameters->subsampling_dy;\r
103 \r
104   int i, numcomps, w, h;\r
105   OPJ_COLOR_SPACE color_space;\r
106   opj_image_cmptparm_t cmptparm[3];  /* maximum of 3 components */\r
107   opj_image_t * image = NULL;\r
108 \r
109   FILE *IN;\r
110   BITMAPFILEHEADER_t File_h;\r
111   BITMAPINFOHEADER_t Info_h;\r
112   unsigned char *RGB;\r
113   unsigned char *table_R, *table_G, *table_B;\r
114   unsigned int j, PAD = 0;\r
115 \r
116   int x, y, index;\r
117   int gray_scale = 1, not_end_file = 1; \r
118 \r
119   unsigned int line = 0, col = 0;\r
120   unsigned char v, v2;\r
121   DWORD W, H;\r
122   \r
123   IN = fopen(filename, "rb");\r
124   if (!IN) {\r
125     fprintf(stderr, "\033[0;33mFailed to open %s for reading !!\033[0;39m\n", filename);\r
126     return 0;\r
127   }\r
128   \r
129   File_h.bfType = getc(IN);\r
130   File_h.bfType = (getc(IN) << 8) + File_h.bfType;\r
131   \r
132   if (File_h.bfType != 19778) {\r
133     fprintf(stderr,"Error, not a BMP file!\n");\r
134     return 0;\r
135   } else {\r
136     /* FILE HEADER */\r
137     /* ------------- */\r
138     File_h.bfSize = getc(IN);\r
139     File_h.bfSize = (getc(IN) << 8) + File_h.bfSize;\r
140     File_h.bfSize = (getc(IN) << 16) + File_h.bfSize;\r
141     File_h.bfSize = (getc(IN) << 24) + File_h.bfSize;\r
142 \r
143     File_h.bfReserved1 = getc(IN);\r
144     File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1;\r
145 \r
146     File_h.bfReserved2 = getc(IN);\r
147     File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2;\r
148 \r
149     File_h.bfOffBits = getc(IN);\r
150     File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits;\r
151     File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits;\r
152     File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits;\r
153 \r
154     /* INFO HEADER */\r
155     /* ------------- */\r
156 \r
157     Info_h.biSize = getc(IN);\r
158     Info_h.biSize = (getc(IN) << 8) + Info_h.biSize;\r
159     Info_h.biSize = (getc(IN) << 16) + Info_h.biSize;\r
160     Info_h.biSize = (getc(IN) << 24) + Info_h.biSize;\r
161 \r
162     Info_h.biWidth = getc(IN);\r
163     Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth;\r
164     Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth;\r
165     Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth;\r
166     w = Info_h.biWidth;\r
167 \r
168     Info_h.biHeight = getc(IN);\r
169     Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight;\r
170     Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight;\r
171     Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight;\r
172     h = Info_h.biHeight;\r
173 \r
174     Info_h.biPlanes = getc(IN);\r
175     Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes;\r
176 \r
177     Info_h.biBitCount = getc(IN);\r
178     Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount;\r
179 \r
180     Info_h.biCompression = getc(IN);\r
181     Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression;\r
182     Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression;\r
183     Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression;\r
184 \r
185     Info_h.biSizeImage = getc(IN);\r
186     Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage;\r
187     Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage;\r
188     Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage;\r
189 \r
190     Info_h.biXpelsPerMeter = getc(IN);\r
191     Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter;\r
192     Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter;\r
193     Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter;\r
194 \r
195     Info_h.biYpelsPerMeter = getc(IN);\r
196     Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter;\r
197     Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter;\r
198     Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter;\r
199 \r
200     Info_h.biClrUsed = getc(IN);\r
201     Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed;\r
202     Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed;\r
203     Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed;\r
204 \r
205     Info_h.biClrImportant = getc(IN);\r
206     Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant;\r
207     Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant;\r
208     Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant;\r
209 \r
210     /* Read the data and store them in the OUT file */\r
211     \r
212     if (Info_h.biBitCount == 24) {\r
213       numcomps = 3;\r
214       color_space = CLRSPC_SRGB;\r
215       /* initialize image components */\r
216       memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));\r
217       for(i = 0; i < numcomps; i++) {\r
218         cmptparm[i].prec = 8;\r
219         cmptparm[i].bpp = 8;\r
220         cmptparm[i].sgnd = 0;\r
221         cmptparm[i].dx = subsampling_dx;\r
222         cmptparm[i].dy = subsampling_dy;\r
223         cmptparm[i].w = w;\r
224         cmptparm[i].h = h;\r
225       }\r
226       /* create the image */\r
227       image = opj_image_create(numcomps, &cmptparm[0], color_space);\r
228       if(!image) {\r
229         fclose(IN);\r
230         return NULL;\r
231       }\r
232 \r
233       /* set image offset and reference grid */\r
234       image->x0 = parameters->image_offset_x0;\r
235       image->y0 = parameters->image_offset_y0;\r
236       image->x1 =  !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;\r
237       image->y1 =  !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;\r
238 \r
239       /* set image data */\r
240 \r
241       /* Place the cursor at the beginning of the image information */\r
242       fseek(IN, 0, SEEK_SET);\r
243       fseek(IN, File_h.bfOffBits, SEEK_SET);\r
244       \r
245       W = Info_h.biWidth;\r
246       H = Info_h.biHeight;\r
247 \r
248       /* PAD = 4 - (3 * W) % 4; */\r
249       /* PAD = (PAD == 4) ? 0 : PAD; */\r
250       PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0;\r
251       \r
252       RGB = (unsigned char *) malloc((3 * W + PAD) * H * sizeof(unsigned char));\r
253       \r
254       fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN);\r
255       \r
256       index = 0;\r
257 \r
258       for(y = 0; y < (int)H; y++) {\r
259         unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y);\r
260         for(x = 0; x < (int)W; x++) {\r
261           unsigned char *pixel = &scanline[3 * x];\r
262           image->comps[0].data[index] = pixel[2];  /* R */\r
263           image->comps[1].data[index] = pixel[1];  /* G */\r
264           image->comps[2].data[index] = pixel[0];  /* B */\r
265           index++;\r
266         }\r
267       }\r
268 \r
269       free(RGB);\r
270 \r
271     } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) {\r
272       table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));\r
273       table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));\r
274       table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));\r
275       \r
276       for (j = 0; j < Info_h.biClrUsed; j++) {\r
277         table_B[j] = getc(IN);\r
278         table_G[j] = getc(IN);\r
279         table_R[j] = getc(IN);\r
280         getc(IN);\r
281         if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j])\r
282           gray_scale = 0;\r
283       }\r
284       \r
285       /* Place the cursor at the beginning of the image information */\r
286       fseek(IN, 0, SEEK_SET);\r
287       fseek(IN, File_h.bfOffBits, SEEK_SET);\r
288       \r
289       W = Info_h.biWidth;\r
290       H = Info_h.biHeight;\r
291       if (Info_h.biWidth % 2)\r
292         W++;\r
293       \r
294       numcomps = gray_scale ? 1 : 3;\r
295       color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;\r
296       /* initialize image components */\r
297       memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));\r
298       for(i = 0; i < numcomps; i++) {\r
299         cmptparm[i].prec = 8;\r
300         cmptparm[i].bpp = 8;\r
301         cmptparm[i].sgnd = 0;\r
302         cmptparm[i].dx = subsampling_dx;\r
303         cmptparm[i].dy = subsampling_dy;\r
304         cmptparm[i].w = w;\r
305         cmptparm[i].h = h;\r
306       }\r
307       /* create the image */\r
308       image = opj_image_create(numcomps, &cmptparm[0], color_space);\r
309       if(!image) {\r
310         fclose(IN);\r
311         return NULL;\r
312       }\r
313 \r
314       /* set image offset and reference grid */\r
315       image->x0 = parameters->image_offset_x0;\r
316       image->y0 = parameters->image_offset_y0;\r
317       image->x1 =  !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;\r
318       image->y1 =  !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;\r
319 \r
320       /* set image data */\r
321 \r
322       RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char));\r
323       \r
324       fread(RGB, sizeof(unsigned char), W * H, IN);\r
325       if (gray_scale) {\r
326         index = 0;\r
327         for (j = 0; j < W * H; j++) {\r
328           if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) {\r
329             image->comps[0].data[index] = table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]];\r
330             index++;\r
331           }\r
332         }\r
333 \r
334       } else {    \r
335         index = 0;\r
336         for (j = 0; j < W * H; j++) {\r
337           if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) {\r
338             unsigned char pixel_index = RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)];\r
339             image->comps[0].data[index] = table_R[pixel_index];\r
340             image->comps[1].data[index] = table_G[pixel_index];\r
341             image->comps[2].data[index] = table_B[pixel_index];\r
342             index++;\r
343           }\r
344         }\r
345       }\r
346       free(RGB);\r
347             \r
348     } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) {        \r
349       table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));\r
350       table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));\r
351       table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));\r
352       \r
353       for (j = 0; j < Info_h.biClrUsed; j++) {\r
354         table_B[j] = getc(IN);\r
355         table_G[j] = getc(IN);\r
356         table_R[j] = getc(IN);\r
357         getc(IN);\r
358         if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j])\r
359           gray_scale = 0;\r
360       }\r
361 \r
362       numcomps = gray_scale ? 1 : 3;\r
363       color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;\r
364       /* initialize image components */\r
365       memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));\r
366       for(i = 0; i < numcomps; i++) {\r
367         cmptparm[i].prec = 8;\r
368         cmptparm[i].bpp = 8;\r
369         cmptparm[i].sgnd = 0;\r
370         cmptparm[i].dx = subsampling_dx;\r
371         cmptparm[i].dy = subsampling_dy;\r
372         cmptparm[i].w = w;\r
373         cmptparm[i].h = h;\r
374       }\r
375       /* create the image */\r
376       image = opj_image_create(numcomps, &cmptparm[0], color_space);\r
377       if(!image) {\r
378         fclose(IN);\r
379         return NULL;\r
380       }\r
381 \r
382       /* set image offset and reference grid */\r
383       image->x0 = parameters->image_offset_x0;\r
384       image->y0 = parameters->image_offset_y0;\r
385       image->x1 =  !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;\r
386       image->y1 =  !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;\r
387 \r
388       /* set image data */\r
389       \r
390       /* Place the cursor at the beginning of the image information */\r
391       fseek(IN, 0, SEEK_SET);\r
392       fseek(IN, File_h.bfOffBits, SEEK_SET);\r
393       \r
394       RGB = (unsigned char *) malloc(Info_h.biWidth * Info_h.biHeight * sizeof(unsigned char));\r
395             \r
396       while (not_end_file) {\r
397         v = getc(IN);\r
398         if (v) {\r
399           v2 = getc(IN);\r
400           for (i = 0; i < (int) v; i++) {\r
401             RGB[line * Info_h.biWidth + col] = v2;\r
402             col++;\r
403           }\r
404         } else {\r
405           v = getc(IN);\r
406           switch (v) {\r
407             case 0:\r
408               col = 0;\r
409               line++;\r
410               break;\r
411             case 1:\r
412               line++;\r
413               not_end_file = 0;\r
414               break;\r
415             case 2:\r
416               fprintf(stderr,"No Delta supported\n");\r
417               opj_image_destroy(image);\r
418               fclose(IN);\r
419               return NULL;\r
420               break;\r
421             default:\r
422               for (i = 0; i < v; i++) {\r
423                 v2 = getc(IN);\r
424                 RGB[line * Info_h.biWidth + col] = v2;\r
425                 col++;\r
426               }\r
427               if (v % 2)\r
428                 v2 = getc(IN);\r
429               break;\r
430           }\r
431         }\r
432       }\r
433       if (gray_scale) {\r
434         index = 0;\r
435         for (line = 0; line < Info_h.biHeight; line++) {\r
436           for (col = 0; col < Info_h.biWidth; col++) {\r
437             image->comps[0].data[index] = table_R[(int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]];\r
438             index++;\r
439           }\r
440         }\r
441       } else {\r
442         index = 0;\r
443         for (line = 0; line < Info_h.biHeight; line++) {\r
444           for (col = 0; col < Info_h.biWidth; col++) {\r
445             unsigned char pixel_index = (int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col];\r
446             image->comps[0].data[index] = table_R[pixel_index];\r
447             image->comps[1].data[index] = table_G[pixel_index];\r
448             image->comps[2].data[index] = table_B[pixel_index];\r
449             index++;\r
450           }\r
451         }\r
452       }\r
453       free(RGB);\r
454   } else {\r
455     fprintf(stderr, \r
456       "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount);\r
457   }\r
458   fclose(IN);\r
459  }\r
460  \r
461  return image;\r
462 }\r
463 \r
464 int imagetobmp(opj_image_t * image, char *outfile) {\r
465   int w, wr, h, hr;\r
466   int i, pad;\r
467   FILE *fdest = NULL;\r
468 \r
469   if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx\r
470     && image->comps[1].dx == image->comps[2].dx\r
471     && image->comps[0].dy == image->comps[1].dy\r
472     && image->comps[1].dy == image->comps[2].dy\r
473     && image->comps[0].prec == image->comps[1].prec\r
474     && image->comps[1].prec == image->comps[2].prec) {\r
475     \r
476     /* -->> -->> -->> -->>    \r
477     24 bits color      \r
478     <<-- <<-- <<-- <<-- */\r
479       \r
480     fdest = fopen(outfile, "wb");\r
481     if (!fdest) {\r
482       fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);\r
483       return 1;\r
484     }\r
485       \r
486     /* w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); */\r
487     /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), image->comps[0].dx); */\r
488     w = image->comps[0].w;\r
489     wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);\r
490       \r
491     /* h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); */\r
492     /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */\r
493     h = image->comps[0].h;\r
494     hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);\r
495       \r
496     fprintf(fdest, "BM");\r
497       \r
498     /* FILE HEADER */\r
499     /* ------------- */\r
500     fprintf(fdest, "%c%c%c%c",\r
501       (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) + 54) & 0xff,\r
502       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54)  >> 8) & 0xff,\r
503       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54)  >> 16) & 0xff,\r
504       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54)  >> 24) & 0xff);\r
505     fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);\r
506     fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);\r
507       \r
508     /* INFO HEADER   */\r
509     /* ------------- */\r
510     fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,  ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);\r
511     fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff),\r
512       (unsigned char) ((wr) >> 8) & 0xff,\r
513       (unsigned char) ((wr) >> 16) & 0xff,\r
514       (unsigned char) ((wr) >> 24) & 0xff);\r
515     fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff),\r
516       (unsigned char) ((hr) >> 8) & 0xff,\r
517       (unsigned char) ((hr) >> 16) & 0xff,\r
518       (unsigned char) ((hr) >> 24) & 0xff);\r
519     fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);\r
520     fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);\r
521     fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);\r
522     fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * hr * wr + 3 * hr * (wr % 2)) & 0xff,\r
523       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 8) & 0xff,\r
524       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 16) & 0xff,\r
525       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 24) & 0xff);\r
526     fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);\r
527     fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,  ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);\r
528     fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);\r
529     fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);\r
530       \r
531     for (i = 0; i < wr * hr; i++) {\r
532       unsigned char R, G, B;\r
533       /* a modifier */\r
534       /* R = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */\r
535       R = image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];\r
536       /* G = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */\r
537       G = image->comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];\r
538       /* B = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */\r
539       B = image->comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];\r
540       fprintf(fdest, "%c%c%c", B, G, R);\r
541       \r
542       if ((i + 1) % wr == 0) {\r
543         for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--)  /* ADD */\r
544           fprintf(fdest, "%c", 0);\r
545       }\r
546     }\r
547     fclose(fdest);\r
548   } else {      /* Gray-scale */\r
549 \r
550     /* -->> -->> -->> -->>\r
551     8 bits non code (Gray scale)\r
552     <<-- <<-- <<-- <<-- */\r
553 \r
554     fdest = fopen(outfile, "wb");\r
555     /* w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); */\r
556     /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), image->comps[0].dx); */\r
557     w = image->comps[0].w;\r
558     wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);\r
559       \r
560     /* h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); */\r
561     /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */\r
562     h = image->comps[0].h;\r
563     hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);\r
564       \r
565     fprintf(fdest, "BM");\r
566       \r
567     /* FILE HEADER */\r
568     /* ------------- */\r
569     fprintf(fdest, "%c%c%c%c", (unsigned char) (hr * wr + 54 + 1024 + hr * (wr % 2)) & 0xff,\r
570       (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) >> 8) & 0xff,\r
571       (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) >> 16) & 0xff,\r
572       (unsigned char) ((hr * wr + 54 + 1024 + wr * (wr % 2)) >> 24) & 0xff);\r
573     fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);\r
574     fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff, \r
575       ((54 + 1024) >> 16) & 0xff,\r
576       ((54 + 1024) >> 24) & 0xff);\r
577       \r
578     /* INFO HEADER */\r
579     /* ------------- */\r
580     fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,  ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);\r
581     fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff),\r
582       (unsigned char) ((wr) >> 8) & 0xff,\r
583       (unsigned char) ((wr) >> 16) & 0xff,\r
584       (unsigned char) ((wr) >> 24) & 0xff);\r
585     fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff),\r
586       (unsigned char) ((hr) >> 8) & 0xff,\r
587       (unsigned char) ((hr) >> 16) & 0xff,\r
588       (unsigned char) ((hr) >> 24) & 0xff);\r
589     fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);\r
590     fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);\r
591     fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);\r
592     fprintf(fdest, "%c%c%c%c", (unsigned char) (hr * wr + hr * (wr % 2)) & 0xff,\r
593       (unsigned char) ((hr * wr + hr * (wr % 2)) >> 8) &  0xff,\r
594       (unsigned char) ((hr * wr + hr * (wr % 2)) >> 16) &  0xff,\r
595       (unsigned char) ((hr * wr + hr * (wr % 2)) >> 24) & 0xff);\r
596     fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,  ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);\r
597     fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,  ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);\r
598     fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);\r
599     fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);\r
600   }\r
601 \r
602   for (i = 0; i < 256; i++) {\r
603     fprintf(fdest, "%c%c%c%c", i, i, i, 0);\r
604   }\r
605 \r
606   for (i = 0; i < wr * hr; i++) {\r
607     /* a modifier !! */\r
608     /* fprintf(fdest, "%c", image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]); */\r
609     fprintf(fdest, "%c", image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]);\r
610     /*if (((i + 1) % w == 0 && w % 2))\r
611     fprintf(fdest, "%c", 0); */\r
612     if ((i + 1) % wr == 0) {\r
613       for (pad = wr % 4 ? 4 - wr % 4 : 0; pad > 0; pad--)  /* ADD */\r
614         fprintf(fdest, "%c", 0);\r
615     }\r
616   }\r
617   fclose(fdest);\r
618 \r
619   return 0;\r
620 }\r
621 \r
622 /* -->> -->> -->> -->>\r
623 \r
624 PGX IMAGE FORMAT\r
625 \r
626 <<-- <<-- <<-- <<-- */\r
627 \r
628 \r
629 unsigned char readuchar(FILE * f)\r
630 {\r
631   unsigned char c1;\r
632   fread(&c1, 1, 1, f);\r
633   return c1;\r
634 }\r
635 \r
636 unsigned short readushort(FILE * f, int bigendian)\r
637 {\r
638   unsigned char c1, c2;\r
639   fread(&c1, 1, 1, f);\r
640   fread(&c2, 1, 1, f);\r
641   if (bigendian)\r
642     return (c1 << 8) + c2;\r
643   else\r
644     return (c2 << 8) + c1;\r
645 }\r
646 \r
647 unsigned int readuint(FILE * f, int bigendian)\r
648 {\r
649   unsigned char c1, c2, c3, c4;\r
650   fread(&c1, 1, 1, f);\r
651   fread(&c2, 1, 1, f);\r
652   fread(&c3, 1, 1, f);\r
653   fread(&c4, 1, 1, f);\r
654   if (bigendian)\r
655     return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;\r
656   else\r
657     return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1;\r
658 }\r
659 \r
660 opj_image_t* pgxtoimage(char *filename, opj_cparameters_t *parameters) {\r
661   FILE *f = NULL;\r
662   int w, h, prec;\r
663   int i, numcomps, max;\r
664   OPJ_COLOR_SPACE color_space;\r
665   opj_image_cmptparm_t cmptparm;  /* maximum of 1 component  */\r
666   opj_image_t * image = NULL;\r
667 \r
668   char endian1,endian2,sign;\r
669   char signtmp[32];\r
670 \r
671   char temp[32];\r
672   int bigendian;\r
673   opj_image_comp_t *comp = NULL;\r
674 \r
675   numcomps = 1;\r
676   color_space = CLRSPC_GRAY;\r
677 \r
678   memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t));\r
679 \r
680   max = 0;\r
681 \r
682   f = fopen(filename, "rb");\r
683   if (!f) {\r
684     fprintf(stderr, "Failed to open %s for reading !\n", filename);\r
685     return NULL;\r
686   }\r
687 \r
688   fseek(f, 0, SEEK_SET);\r
689   fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h);\r
690   \r
691   i=0;\r
692   sign='+';    \r
693   while (signtmp[i]!='\0') {\r
694     if (signtmp[i]=='-') sign='-';\r
695     i++;\r
696   }\r
697   \r
698   fgetc(f);\r
699   if (endian1=='M' && endian2=='L') {\r
700     bigendian = 1;\r
701   } else if (endian2=='M' && endian1=='L') {\r
702     bigendian = 0;\r
703   } else {\r
704     fprintf(stderr, "Bad pgx header, please check input file\n");\r
705     return NULL;\r
706   }\r
707 \r
708   /* initialize image component */\r
709 \r
710   cmptparm.x0 = parameters->image_offset_x0;\r
711   cmptparm.y0 = parameters->image_offset_y0;\r
712   cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1;\r
713   cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1;\r
714   \r
715   if (sign == '-') {\r
716     cmptparm.sgnd = 1;\r
717   } else {\r
718     cmptparm.sgnd = 0;\r
719   }\r
720   cmptparm.prec = prec;\r
721   cmptparm.bpp = prec;\r
722   cmptparm.dx = parameters->subsampling_dx;\r
723   cmptparm.dy = parameters->subsampling_dy;\r
724   \r
725   /* create the image */\r
726   image = opj_image_create(numcomps, &cmptparm, color_space);\r
727   if(!image) {\r
728     fclose(f);\r
729     return NULL;\r
730   }\r
731   /* set image offset and reference grid */\r
732   image->x0 = cmptparm.x0;\r
733   image->y0 = cmptparm.x0;\r
734   image->x1 = cmptparm.w;\r
735   image->y1 = cmptparm.h;\r
736 \r
737   /* set image data */\r
738 \r
739   comp = &image->comps[0];\r
740 \r
741   for (i = 0; i < w * h; i++) {\r
742     int v;\r
743     if (comp->prec <= 8) {\r
744       if (!comp->sgnd) {\r
745         v = readuchar(f);\r
746       } else {\r
747         v = (char) readuchar(f);\r
748       }\r
749     } else if (comp->prec <= 16) {\r
750       if (!comp->sgnd) {\r
751         v = readushort(f, bigendian);\r
752       } else {\r
753         v = (short) readushort(f, bigendian);\r
754       }\r
755     } else {\r
756       if (!comp->sgnd) {\r
757         v = readuint(f, bigendian);\r
758       } else {\r
759         v = (int) readuint(f, bigendian);\r
760       }\r
761     }\r
762     if (v > max)\r
763       max = v;\r
764     comp->data[i] = v;\r
765   }\r
766   fclose(f);\r
767   comp->bpp = int_floorlog2(max) + 1;\r
768 \r
769   return image;\r
770 }\r
771 \r
772 int imagetopgx(opj_image_t * image, char *outfile) {\r
773   int w, wr, h, hr;\r
774   int i, j, compno;\r
775   FILE *fdest = NULL;\r
776 \r
777   for (compno = 0; compno < image->numcomps; compno++) {\r
778     opj_image_comp_t *comp = &image->comps[compno];\r
779     char name[256];\r
780     int nbytes = 0;\r
781     char *tmp = outfile;\r
782     while (*tmp) {\r
783       tmp++;\r
784     }\r
785     while (*tmp!='.') {\r
786       tmp--;\r
787     }\r
788     *tmp='\0';\r
789 \r
790     if (image->numcomps > 1) {\r
791       sprintf(name, "%s-%d.pgx", outfile, compno);\r
792     } else {\r
793       sprintf(name, "%s.pgx", outfile);\r
794     }\r
795     fdest = fopen(name, "wb");\r
796     if (!fdest) {\r
797       fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);\r
798       return 1;\r
799     }\r
800     /* w = int_ceildiv(image->x1 - image->x0, comp->dx); */\r
801     /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), comp->dx); */\r
802     w = image->comps[compno].w;\r
803     wr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);\r
804       \r
805     /* h = int_ceildiv(image->y1 - image->y0, comp->dy); */\r
806     /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), comp->dy); */\r
807     h = image->comps[compno].h;\r
808     hr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);\r
809       \r
810     fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, wr, hr);\r
811     if (comp->prec <= 8) {\r
812       nbytes = 1;\r
813     } else if (comp->prec <= 16) {\r
814       nbytes = 2;\r
815     } else {\r
816       nbytes = 4;\r
817     }\r
818     for (i = 0; i < wr * hr; i++) {\r
819       int v = image->comps[compno].data[i / wr * w + i % wr];\r
820       for (j = nbytes - 1; j >= 0; j--) {\r
821         char byte = (char) (v >> (j * 8));\r
822         fwrite(&byte, 1, 1, fdest);\r
823       }\r
824     }\r
825     fclose(fdest);\r
826   }\r
827 \r
828   return 0;\r
829 }\r
830 \r
831 /* -->> -->> -->> -->>\r
832 \r
833 PNM IMAGE FORMAT\r
834 \r
835 <<-- <<-- <<-- <<-- */\r
836 \r
837 opj_image_t* pnmtoimage(char *filename, opj_cparameters_t *parameters) {\r
838   int subsampling_dx = parameters->subsampling_dx;\r
839   int subsampling_dy = parameters->subsampling_dy;\r
840 \r
841   FILE *f = NULL;\r
842   int i, compno, numcomps, w, h;\r
843   OPJ_COLOR_SPACE color_space;\r
844   opj_image_cmptparm_t cmptparm[3];  /* maximum of 3 components */\r
845   opj_image_t * image = NULL;\r
846   char value;\r
847   char comment[256];\r
848 \r
849   f = fopen(filename, "rb");\r
850   if (!f) {\r
851     fprintf(stderr, "\033[0;33mFailed to open %s for reading !!\033[0;39m\n", filename);\r
852     return 0;\r
853   }\r
854 \r
855   if (fgetc(f) != 'P')\r
856     return 0;\r
857   value = fgetc(f);\r
858 \r
859   switch(value) {\r
860     case '2':  /* greyscale image type */\r
861     case '5':\r
862     {\r
863       numcomps = 1;\r
864       color_space = CLRSPC_GRAY;\r
865 \r
866       fgetc(f);\r
867 \r
868       if (fgetc(f) == '#') {\r
869         /* skip comments */\r
870         fseek(f, 0, SEEK_SET);\r
871         if (value == '2') {\r
872           fscanf(f, "P2\n");\r
873         } else if (value == '5') {\r
874           fscanf(f, "P5\n");\r
875         }\r
876         fgets(comment, 256, f);\r
877         fscanf(f, "%d %d\n255", &w, &h);\r
878       } else {\r
879         fseek(f, 0, SEEK_SET);\r
880         if (value == '2') {\r
881           fscanf(f, "P2\n%d %d\n255", &w, &h);\r
882         } else if (value == '5') {\r
883           fscanf(f, "P5\n%d %d\n255", &w, &h);\r
884         }\r
885       }\r
886       \r
887       fgetc(f);  /* <cr><lf> */\r
888     }\r
889     break;\r
890 \r
891     case '3':  /* RGB image type */\r
892     case '6':\r
893     {\r
894       numcomps = 3;\r
895       color_space = CLRSPC_SRGB;\r
896 \r
897       fgetc(f);\r
898 \r
899       if (fgetc(f) == '#') {\r
900         /* skip comments */\r
901         fseek(f, 0, SEEK_SET);\r
902         if (value == '3') {\r
903           fscanf(f, "P3\n");\r
904         } else if (value == '6') {\r
905           fscanf(f, "P6\n");\r
906         }\r
907         fgets(comment, 256, f);\r
908         fscanf(f, "%d %d\n255", &w, &h);\r
909       } else {\r
910         fseek(f, 0, SEEK_SET);\r
911         if (value == '3') {\r
912           fscanf(f, "P3\n%d %d\n255", &w, &h);\r
913         } else if (value == '6') {\r
914           fscanf(f, "P6\n%d %d\n255", &w, &h);\r
915         }\r
916       }\r
917       \r
918       fgetc(f);  /* <cr><lf> */\r
919     }\r
920     break;\r
921 \r
922     default:\r
923       fclose(f);\r
924       return NULL;\r
925   }\r
926 \r
927   /* initialize image components */\r
928   memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));\r
929   for(i = 0; i < numcomps; i++) {\r
930     cmptparm[i].prec = 8;\r
931     cmptparm[i].bpp = 8;\r
932     cmptparm[i].sgnd = 0;\r
933     cmptparm[i].dx = subsampling_dx;\r
934     cmptparm[i].dy = subsampling_dy;\r
935     cmptparm[i].w = w;\r
936     cmptparm[i].h = h;\r
937   }\r
938   /* create the image */\r
939   image = opj_image_create(numcomps, &cmptparm[0], color_space);\r
940   if(!image) {\r
941     fclose(f);\r
942     return NULL;\r
943   }\r
944 \r
945   /* set image offset and reference grid */\r
946   image->x0 = parameters->image_offset_x0;\r
947   image->y0 = parameters->image_offset_y0;\r
948   image->x1 = parameters->image_offset_x0 + (w - 1) *  subsampling_dx + 1;\r
949   image->y1 = parameters->image_offset_y0 + (h - 1) *  subsampling_dy + 1;\r
950 \r
951   /* set image data */\r
952 \r
953   if ((value == '2') || (value == '3')) {  /* ASCII */\r
954     for (i = 0; i < w * h; i++) {\r
955       for(compno = 0; compno < numcomps; compno++) {\r
956         unsigned int index = 0;\r
957         fscanf(f, "%u", &index);\r
958         /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */\r
959         image->comps[compno].data[i] = index;\r
960       }\r
961     }\r
962   } else if ((value == '5') || (value == '6')) {  /* BINARY */\r
963     for (i = 0; i < w * h; i++) {\r
964       for(compno = 0; compno < numcomps; compno++) {\r
965         unsigned char index = 0;\r
966         fread(&index, 1, 1, f);\r
967         /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */\r
968         image->comps[compno].data[i] = index;\r
969       }\r
970     }\r
971   }\r
972 \r
973   fclose(f);\r
974 \r
975   return image;\r
976 }\r
977 \r
978 int imagetopnm(opj_image_t * image, char *outfile) {\r
979   int w, wr, wrr, h, hr, hrr, max;\r
980   int i, compno;\r
981   int adjust;\r
982   FILE *fdest = NULL;\r
983   char S2;\r
984   char *tmp = outfile;\r
985 \r
986   while (*tmp) {\r
987     tmp++;\r
988   }\r
989   tmp--;\r
990   tmp--;\r
991   S2 = *tmp;\r
992 \r
993   if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx\r
994     && image->comps[1].dx == image->comps[2].dx\r
995     && image->comps[0].dy == image->comps[1].dy\r
996     && image->comps[1].dy == image->comps[2].dy\r
997     && image->comps[0].prec == image->comps[1].prec\r
998     && image->comps[1].prec == image->comps[2].prec\r
999     && S2 !='g' && S2 !='G') {\r
1000 \r
1001     fdest = fopen(outfile, "wb");\r
1002     if (!fdest) {\r
1003       fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);\r
1004       return 1;\r
1005     }\r
1006 \r
1007     w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);\r
1008     /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor),image->comps[0].dx); */\r
1009     wr = image->comps[0].w;\r
1010     wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);\r
1011         \r
1012     h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);\r
1013     /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */\r
1014     hr = image->comps[0].h;\r
1015     hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);\r
1016       \r
1017     max = image->comps[0].prec > 8 ? 255 : (1 << image->comps[0].prec) - 1;\r
1018       \r
1019     image->comps[0].x0 = int_ceildivpow2(image->comps[0].x0 - int_ceildiv(image->x0, image->comps[0].dx), image->comps[0].factor);\r
1020     image->comps[0].y0 = int_ceildivpow2(image->comps[0].y0 -  int_ceildiv(image->y0, image->comps[0].dy), image->comps[0].factor);\r
1021 \r
1022     fprintf(fdest, "P6\n%d %d\n%d\n", wrr, hrr, max);\r
1023     adjust = image->comps[0].prec > 8 ? image->comps[0].prec - 8 : 0;\r
1024     for (i = 0; i < wrr * hrr; i++) {\r
1025       int r, g, b;\r
1026       unsigned char rc,gc,bc;\r
1027       r = image->comps[0].data[i / wrr * wr + i % wrr];\r
1028       r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);\r
1029       rc = (unsigned char) ((r >> adjust)+((r >> (adjust-1))%2));\r
1030 \r
1031       g = image->comps[1].data[i / wrr * wr + i % wrr];\r
1032       g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);\r
1033       gc = (unsigned char) ((g >> adjust)+((g >> (adjust-1))%2));\r
1034       \r
1035       b = image->comps[2].data[i / wrr * wr + i % wrr];\r
1036       b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);\r
1037       bc = (unsigned char) ((b >> adjust)+((b >> (adjust-1))%2));\r
1038       \r
1039       fprintf(fdest, "%c%c%c", rc, gc, bc);\r
1040     }\r
1041     fclose(fdest);\r
1042   } else {\r
1043     int ncomp=(S2=='g' || S2=='G')?1:image->numcomps;\r
1044     if (image->numcomps>ncomp) {\r
1045       fprintf(stderr,"WARNING -> [PGM files] Only the first component\n");\r
1046       fprintf(stderr,"           is written to the file\n");\r
1047     }\r
1048     for (compno = 0; compno < ncomp; compno++) {\r
1049       char name[256];\r
1050       if (ncomp > 1) {\r
1051         sprintf(name, "%d.%s", compno, outfile);\r
1052       } else {\r
1053         sprintf(name, "%s", outfile);\r
1054       }\r
1055       \r
1056       fdest = fopen(name, "wb");\r
1057       if (!fdest) {\r
1058         fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);\r
1059         return 1;\r
1060       }\r
1061             \r
1062       w = int_ceildiv(image->x1 - image->x0, image->comps[compno].dx);\r
1063       /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor),image->comps[compno].dx); */\r
1064       wr = image->comps[compno].w;\r
1065       wrr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);\r
1066       \r
1067       h = int_ceildiv(image->y1 - image->y0, image->comps[compno].dy);\r
1068       /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[compno].dy); */\r
1069       hr = image->comps[compno].h;\r
1070       hrr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);\r
1071       \r
1072       max = image->comps[compno].prec > 8 ? 255 : (1 << image->comps[compno].prec) - 1;\r
1073       \r
1074       image->comps[compno].x0 = int_ceildivpow2(image->comps[compno].x0 - int_ceildiv(image->x0, image->comps[compno].dx), image->comps[compno].factor);\r
1075       image->comps[compno].y0 = int_ceildivpow2(image->comps[compno].y0 - int_ceildiv(image->y0, image->comps[compno].dy), image->comps[compno].factor);\r
1076       \r
1077       fprintf(fdest, "P5\n%d %d\n%d\n", wrr, hrr, max);\r
1078       adjust = image->comps[compno].prec > 8 ? image->comps[compno].prec - 8 : 0;\r
1079 \r
1080       for (i = 0; i < wrr * hrr; i++) {\r
1081         int l;\r
1082         unsigned char lc;\r
1083         l = image->comps[compno].data[i / wrr * wr + i % wrr];\r
1084         l += (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0);\r
1085         lc = (unsigned char) ((l >> adjust)+((l >> (adjust-1))%2));\r
1086         fprintf(fdest, "%c", lc);\r
1087       }\r
1088       fclose(fdest);\r
1089     }\r
1090   }\r
1091 \r
1092   return 0;\r
1093 }\r