Bugs corrected in decoding of command line (getopt.c), in the handling of 16 bit...
[openjpeg.git] / codec / convert.c
1 /*
2  * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3  * Copyright (c) 2002-2007, Professor Benoit Macq
4  * Copyright (c) 2001-2003, David Janssens
5  * Copyright (c) 2002-2003, Yannick Verschueren
6  * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
7  * Copyright (c) 2005, Herve Drolon, FreeImage Team
8  * Copyright (c) 2006-2007, Parvatha Elangovan
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include "openjpeg.h"
36 #include "../libs/libtiff/tiffio.h"
37
38 /*
39  * Get logarithm of an integer and round downwards.
40  *
41  * log2(a)
42  */
43 static int int_floorlog2(int a) {
44         int l;
45         for (l = 0; a > 1; l++) {
46                 a >>= 1;
47         }
48         return l;
49 }
50
51 /*
52  * Divide an integer by a power of 2 and round upwards.
53  *
54  * a divided by 2^b
55  */
56 static int int_ceildivpow2(int a, int b) {
57         return (a + (1 << b) - 1) >> b;
58 }
59
60 /*
61  * Divide an integer and round upwards.
62  *
63  * a divided by b
64  */
65 static int int_ceildiv(int a, int b) {
66         return (a + b - 1) / b;
67 }
68
69 /* -->> -->> -->> -->>
70
71   BMP IMAGE FORMAT
72
73  <<-- <<-- <<-- <<-- */
74
75 /* WORD defines a two byte word */
76 typedef unsigned short int WORD;
77
78 /* DWORD defines a four byte word */
79 typedef unsigned long int DWORD;
80
81 typedef struct {
82   WORD bfType;                  /* 'BM' for Bitmap (19776) */
83   DWORD bfSize;                 /* Size of the file        */
84   WORD bfReserved1;             /* Reserved : 0            */
85   WORD bfReserved2;             /* Reserved : 0            */
86   DWORD bfOffBits;              /* Offset                  */
87 } BITMAPFILEHEADER_t;
88
89 typedef struct {
90   DWORD biSize;                 /* Size of the structure in bytes */
91   DWORD biWidth;                /* Width of the image in pixels */
92   DWORD biHeight;               /* Heigth of the image in pixels */
93   WORD biPlanes;                /* 1 */
94   WORD biBitCount;              /* Number of color bits by pixels */
95   DWORD biCompression;          /* Type of encoding 0: none 1: RLE8 2: RLE4 */
96   DWORD biSizeImage;            /* Size of the image in bytes */
97   DWORD biXpelsPerMeter;        /* Horizontal (X) resolution in pixels/meter */
98   DWORD biYpelsPerMeter;        /* Vertical (Y) resolution in pixels/meter */
99   DWORD biClrUsed;              /* Number of color used in the image (0: ALL) */
100   DWORD biClrImportant;         /* Number of important color (0: ALL) */
101 } BITMAPINFOHEADER_t;
102
103 opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
104         int subsampling_dx = parameters->subsampling_dx;
105         int subsampling_dy = parameters->subsampling_dy;
106
107         int i, numcomps, w, h;
108         OPJ_COLOR_SPACE color_space;
109         opj_image_cmptparm_t cmptparm[3];       /* maximum of 3 components */
110         opj_image_t * image = NULL;
111
112         FILE *IN;
113         BITMAPFILEHEADER_t File_h;
114         BITMAPINFOHEADER_t Info_h;
115         unsigned char *RGB;
116         unsigned char *table_R, *table_G, *table_B;
117         unsigned int j, PAD = 0;
118
119         int x, y, index;
120         int gray_scale = 1, not_end_file = 1; 
121
122         unsigned int line = 0, col = 0;
123         unsigned char v, v2;
124         DWORD W, H;
125   
126         IN = fopen(filename, "rb");
127         if (!IN) {
128                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
129                 return 0;
130         }
131         
132         File_h.bfType = getc(IN);
133         File_h.bfType = (getc(IN) << 8) + File_h.bfType;
134         
135         if (File_h.bfType != 19778) {
136                 fprintf(stderr,"Error, not a BMP file!\n");
137                 return 0;
138         } else {
139                 /* FILE HEADER */
140                 /* ------------- */
141                 File_h.bfSize = getc(IN);
142                 File_h.bfSize = (getc(IN) << 8) + File_h.bfSize;
143                 File_h.bfSize = (getc(IN) << 16) + File_h.bfSize;
144                 File_h.bfSize = (getc(IN) << 24) + File_h.bfSize;
145
146                 File_h.bfReserved1 = getc(IN);
147                 File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1;
148
149                 File_h.bfReserved2 = getc(IN);
150                 File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2;
151
152                 File_h.bfOffBits = getc(IN);
153                 File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits;
154                 File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits;
155                 File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits;
156
157                 /* INFO HEADER */
158                 /* ------------- */
159
160                 Info_h.biSize = getc(IN);
161                 Info_h.biSize = (getc(IN) << 8) + Info_h.biSize;
162                 Info_h.biSize = (getc(IN) << 16) + Info_h.biSize;
163                 Info_h.biSize = (getc(IN) << 24) + Info_h.biSize;
164
165                 Info_h.biWidth = getc(IN);
166                 Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth;
167                 Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth;
168                 Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth;
169                 w = Info_h.biWidth;
170
171                 Info_h.biHeight = getc(IN);
172                 Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight;
173                 Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight;
174                 Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight;
175                 h = Info_h.biHeight;
176
177                 Info_h.biPlanes = getc(IN);
178                 Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes;
179
180                 Info_h.biBitCount = getc(IN);
181                 Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount;
182
183                 Info_h.biCompression = getc(IN);
184                 Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression;
185                 Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression;
186                 Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression;
187
188                 Info_h.biSizeImage = getc(IN);
189                 Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage;
190                 Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage;
191                 Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage;
192
193                 Info_h.biXpelsPerMeter = getc(IN);
194                 Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter;
195                 Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter;
196                 Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter;
197
198                 Info_h.biYpelsPerMeter = getc(IN);
199                 Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter;
200                 Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter;
201                 Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter;
202
203                 Info_h.biClrUsed = getc(IN);
204                 Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed;
205                 Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed;
206                 Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed;
207
208                 Info_h.biClrImportant = getc(IN);
209                 Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant;
210                 Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant;
211                 Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant;
212
213                 /* Read the data and store them in the OUT file */
214     
215                 if (Info_h.biBitCount == 24) {
216                         numcomps = 3;
217                         color_space = CLRSPC_SRGB;
218                         /* initialize image components */
219                         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
220                         for(i = 0; i < numcomps; i++) {
221                                 cmptparm[i].prec = 8;
222                                 cmptparm[i].bpp = 8;
223                                 cmptparm[i].sgnd = 0;
224                                 cmptparm[i].dx = subsampling_dx;
225                                 cmptparm[i].dy = subsampling_dy;
226                                 cmptparm[i].w = w;
227                                 cmptparm[i].h = h;
228                         }
229                         /* create the image */
230                         image = opj_image_create(numcomps, &cmptparm[0], color_space);
231                         if(!image) {
232                                 fclose(IN);
233                                 return NULL;
234                         }
235
236                         /* set image offset and reference grid */
237                         image->x0 = parameters->image_offset_x0;
238                         image->y0 = parameters->image_offset_y0;
239                         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
240                         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
241
242                         /* set image data */
243
244                         /* Place the cursor at the beginning of the image information */
245                         fseek(IN, 0, SEEK_SET);
246                         fseek(IN, File_h.bfOffBits, SEEK_SET);
247                         
248                         W = Info_h.biWidth;
249                         H = Info_h.biHeight;
250
251                         /* PAD = 4 - (3 * W) % 4; */
252                         /* PAD = (PAD == 4) ? 0 : PAD; */
253                         PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0;
254                         
255                         RGB = (unsigned char *) malloc((3 * W + PAD) * H * sizeof(unsigned char));
256                         
257                         fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN);
258                         
259                         index = 0;
260
261                         for(y = 0; y < (int)H; y++) {
262                                 unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y);
263                                 for(x = 0; x < (int)W; x++) {
264                                         unsigned char *pixel = &scanline[3 * x];
265                                         image->comps[0].data[index] = pixel[2]; /* R */
266                                         image->comps[1].data[index] = pixel[1]; /* G */
267                                         image->comps[2].data[index] = pixel[0]; /* B */
268                                         index++;
269                                 }
270                         }
271
272                         free(RGB);
273
274                 } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) {
275                         table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
276                         table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
277                         table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
278                         
279                         for (j = 0; j < Info_h.biClrUsed; j++) {
280                                 table_B[j] = getc(IN);
281                                 table_G[j] = getc(IN);
282                                 table_R[j] = getc(IN);
283                                 getc(IN);
284                                 if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j])
285                                         gray_scale = 0;
286                         }
287                         
288                         /* Place the cursor at the beginning of the image information */
289                         fseek(IN, 0, SEEK_SET);
290                         fseek(IN, File_h.bfOffBits, SEEK_SET);
291                         
292                         W = Info_h.biWidth;
293                         H = Info_h.biHeight;
294                         if (Info_h.biWidth % 2)
295                                 W++;
296                         
297                         numcomps = gray_scale ? 1 : 3;
298                         color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;
299                         /* initialize image components */
300                         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
301                         for(i = 0; i < numcomps; i++) {
302                                 cmptparm[i].prec = 8;
303                                 cmptparm[i].bpp = 8;
304                                 cmptparm[i].sgnd = 0;
305                                 cmptparm[i].dx = subsampling_dx;
306                                 cmptparm[i].dy = subsampling_dy;
307                                 cmptparm[i].w = w;
308                                 cmptparm[i].h = h;
309                         }
310                         /* create the image */
311                         image = opj_image_create(numcomps, &cmptparm[0], color_space);
312                         if(!image) {
313                                 fclose(IN);
314                                 return NULL;
315                         }
316
317                         /* set image offset and reference grid */
318                         image->x0 = parameters->image_offset_x0;
319                         image->y0 = parameters->image_offset_y0;
320                         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
321                         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
322
323                         /* set image data */
324
325                         RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char));
326                         
327                         fread(RGB, sizeof(unsigned char), W * H, IN);
328                         if (gray_scale) {
329                                 index = 0;
330                                 for (j = 0; j < W * H; j++) {
331                                         if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) {
332                                                 image->comps[0].data[index] = table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]];
333                                                 index++;
334                                         }
335                                 }
336
337                         } else {                
338                                 index = 0;
339                                 for (j = 0; j < W * H; j++) {
340                                         if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) {
341                                                 unsigned char pixel_index = RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)];
342                                                 image->comps[0].data[index] = table_R[pixel_index];
343                                                 image->comps[1].data[index] = table_G[pixel_index];
344                                                 image->comps[2].data[index] = table_B[pixel_index];
345                                                 index++;
346                                         }
347                                 }
348                         }
349                         free(RGB);
350       free(table_R);
351       free(table_G);
352       free(table_B);
353                 } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) {                               
354                         table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
355                         table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
356                         table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
357                         
358                         for (j = 0; j < Info_h.biClrUsed; j++) {
359                                 table_B[j] = getc(IN);
360                                 table_G[j] = getc(IN);
361                                 table_R[j] = getc(IN);
362                                 getc(IN);
363                                 if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j])
364                                         gray_scale = 0;
365                         }
366
367                         numcomps = gray_scale ? 1 : 3;
368                         color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;
369                         /* initialize image components */
370                         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
371                         for(i = 0; i < numcomps; i++) {
372                                 cmptparm[i].prec = 8;
373                                 cmptparm[i].bpp = 8;
374                                 cmptparm[i].sgnd = 0;
375                                 cmptparm[i].dx = subsampling_dx;
376                                 cmptparm[i].dy = subsampling_dy;
377                                 cmptparm[i].w = w;
378                                 cmptparm[i].h = h;
379                         }
380                         /* create the image */
381                         image = opj_image_create(numcomps, &cmptparm[0], color_space);
382                         if(!image) {
383                                 fclose(IN);
384                                 return NULL;
385                         }
386
387                         /* set image offset and reference grid */
388                         image->x0 = parameters->image_offset_x0;
389                         image->y0 = parameters->image_offset_y0;
390                         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
391                         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
392
393                         /* set image data */
394                         
395                         /* Place the cursor at the beginning of the image information */
396                         fseek(IN, 0, SEEK_SET);
397                         fseek(IN, File_h.bfOffBits, SEEK_SET);
398                         
399                         RGB = (unsigned char *) malloc(Info_h.biWidth * Info_h.biHeight * sizeof(unsigned char));
400             
401                         while (not_end_file) {
402                                 v = getc(IN);
403                                 if (v) {
404                                         v2 = getc(IN);
405                                         for (i = 0; i < (int) v; i++) {
406                                                 RGB[line * Info_h.biWidth + col] = v2;
407                                                 col++;
408                                         }
409                                 } else {
410                                         v = getc(IN);
411                                         switch (v) {
412                                                 case 0:
413                                                         col = 0;
414                                                         line++;
415                                                         break;
416                                                 case 1:
417                                                         line++;
418                                                         not_end_file = 0;
419                                                         break;
420                                                 case 2:
421                                                         fprintf(stderr,"No Delta supported\n");
422                                                         opj_image_destroy(image);
423                                                         fclose(IN);
424                                                         return NULL;
425                                                 default:
426                                                         for (i = 0; i < v; i++) {
427                                                                 v2 = getc(IN);
428                                                                 RGB[line * Info_h.biWidth + col] = v2;
429                                                                 col++;
430                                                         }
431                                                         if (v % 2)
432                                                                 v2 = getc(IN);
433                                                         break;
434                                         }
435                                 }
436                         }
437                         if (gray_scale) {
438                                 index = 0;
439                                 for (line = 0; line < Info_h.biHeight; line++) {
440                                         for (col = 0; col < Info_h.biWidth; col++) {
441                                                 image->comps[0].data[index] = table_R[(int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]];
442                                                 index++;
443                                         }
444                                 }
445                         } else {
446                                 index = 0;
447                                 for (line = 0; line < Info_h.biHeight; line++) {
448                                         for (col = 0; col < Info_h.biWidth; col++) {
449                                                 unsigned char pixel_index = (int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col];
450                                                 image->comps[0].data[index] = table_R[pixel_index];
451                                                 image->comps[1].data[index] = table_G[pixel_index];
452                                                 image->comps[2].data[index] = table_B[pixel_index];
453                                                 index++;
454                                         }
455                                 }
456                         }
457                         free(RGB);
458       free(table_R);
459       free(table_G);
460       free(table_B);
461         } else {
462                 fprintf(stderr, 
463                         "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount);
464         }
465         fclose(IN);
466  }
467  
468  return image;
469 }
470
471 int imagetobmp(opj_image_t * image, const char *outfile) {
472         int w, wr, h, hr;
473         int i, pad;
474         FILE *fdest = NULL;
475
476         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
477                 && image->comps[1].dx == image->comps[2].dx
478                 && image->comps[0].dy == image->comps[1].dy
479                 && image->comps[1].dy == image->comps[2].dy
480                 && image->comps[0].prec == image->comps[1].prec
481                 && image->comps[1].prec == image->comps[2].prec) {
482                 
483                 /* -->> -->> -->> -->>    
484                 24 bits color       
485                 <<-- <<-- <<-- <<-- */
486             
487                 fdest = fopen(outfile, "wb");
488                 if (!fdest) {
489                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
490                         return 1;
491                 }
492             
493                 /* w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); */
494                 /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), image->comps[0].dx); */
495                 w = image->comps[0].w;
496                 wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
497             
498                 /* h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); */
499                 /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */
500                 h = image->comps[0].h;
501                 hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
502             
503                 fprintf(fdest, "BM");
504             
505                 /* FILE HEADER */
506                 /* ------------- */
507                 fprintf(fdest, "%c%c%c%c",
508                         (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) + 54) & 0xff,
509                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 8) & 0xff,
510                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 16) & 0xff,
511                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 24) & 0xff);
512                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
513                 fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
514             
515                 /* INFO HEADER   */
516                 /* ------------- */
517                 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
518                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff),
519                         (unsigned char) ((wr) >> 8) & 0xff,
520                         (unsigned char) ((wr) >> 16) & 0xff,
521                         (unsigned char) ((wr) >> 24) & 0xff);
522                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff),
523                         (unsigned char) ((hr) >> 8) & 0xff,
524                         (unsigned char) ((hr) >> 16) & 0xff,
525                         (unsigned char) ((hr) >> 24) & 0xff);
526                 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
527                 fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
528                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
529                 fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * hr * wr + 3 * hr * (wr % 2)) & 0xff,
530                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 8) & 0xff,
531                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 16) & 0xff,
532                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 24) & 0xff);
533                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
534                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
535                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
536                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
537             
538                 for (i = 0; i < wr * hr; i++) {
539                         unsigned char R, G, B;
540                         /* a modifier */
541                         /* R = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */
542                         R = image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
543                         /* G = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */
544                         G = image->comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
545                         /* B = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */
546                         B = image->comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
547                         fprintf(fdest, "%c%c%c", B, G, R);
548                         
549                         if ((i + 1) % wr == 0) {
550                                 for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--) /* ADD */
551                                         fprintf(fdest, "%c", 0);
552                         }
553                 }
554                 fclose(fdest);
555         } else {                        /* Gray-scale */
556
557                 /* -->> -->> -->> -->>
558                 8 bits non code (Gray scale)
559                 <<-- <<-- <<-- <<-- */
560
561                 fdest = fopen(outfile, "wb");
562                 /* w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); */
563                 /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), image->comps[0].dx); */
564                 w = image->comps[0].w;
565                 wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
566             
567                 /* h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); */
568                 /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */
569                 h = image->comps[0].h;
570                 hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
571             
572                 fprintf(fdest, "BM");
573             
574                 /* FILE HEADER */
575                 /* ------------- */
576                 fprintf(fdest, "%c%c%c%c", (unsigned char) (hr * wr + 54 + 1024 + hr * (wr % 2)) & 0xff,
577                         (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) >> 8) & 0xff,
578                         (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) >> 16) & 0xff,
579                         (unsigned char) ((hr * wr + 54 + 1024 + wr * (wr % 2)) >> 24) & 0xff);
580                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
581                 fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff, 
582                         ((54 + 1024) >> 16) & 0xff,
583                         ((54 + 1024) >> 24) & 0xff);
584             
585                 /* INFO HEADER */
586                 /* ------------- */
587                 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
588                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff),
589                         (unsigned char) ((wr) >> 8) & 0xff,
590                         (unsigned char) ((wr) >> 16) & 0xff,
591                         (unsigned char) ((wr) >> 24) & 0xff);
592                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff),
593                         (unsigned char) ((hr) >> 8) & 0xff,
594                         (unsigned char) ((hr) >> 16) & 0xff,
595                         (unsigned char) ((hr) >> 24) & 0xff);
596                 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
597                 fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
598                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
599                 fprintf(fdest, "%c%c%c%c", (unsigned char) (hr * wr + hr * (wr % 2)) & 0xff,
600                         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 8) &      0xff,
601                         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 16) &     0xff,
602                         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 24) & 0xff);
603                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
604                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
605                 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
606                 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
607
608                 for (i = 0; i < 256; i++) {
609                         fprintf(fdest, "%c%c%c%c", i, i, i, 0);
610                 }
611
612                 for (i = 0; i < wr * hr; i++) {
613                         /* a modifier !! */
614                         /* fprintf(fdest, "%c", image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]); */
615                         fprintf(fdest, "%c", image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]);
616                         /*if (((i + 1) % w == 0 && w % 2))
617                         fprintf(fdest, "%c", 0); */
618                         if ((i + 1) % wr == 0) {
619                                 for (pad = wr % 4 ? 4 - wr % 4 : 0; pad > 0; pad--)     /* ADD */
620                                         fprintf(fdest, "%c", 0);
621                         }
622                 }
623                 fclose(fdest);
624         }
625
626         return 0;
627 }
628
629 /* -->> -->> -->> -->>
630
631 PGX IMAGE FORMAT
632
633 <<-- <<-- <<-- <<-- */
634
635
636 unsigned char readuchar(FILE * f)
637 {
638   unsigned char c1;
639   fread(&c1, 1, 1, f);
640   return c1;
641 }
642
643 unsigned short readushort(FILE * f, int bigendian)
644 {
645   unsigned char c1, c2;
646   fread(&c1, 1, 1, f);
647   fread(&c2, 1, 1, f);
648   if (bigendian)
649     return (c1 << 8) + c2;
650   else
651     return (c2 << 8) + c1;
652 }
653
654 unsigned int readuint(FILE * f, int bigendian)
655 {
656   unsigned char c1, c2, c3, c4;
657   fread(&c1, 1, 1, f);
658   fread(&c2, 1, 1, f);
659   fread(&c3, 1, 1, f);
660   fread(&c4, 1, 1, f);
661   if (bigendian)
662     return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
663   else
664     return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1;
665 }
666
667 opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) {
668         FILE *f = NULL;
669         int w, h, prec;
670         int i, numcomps, max;
671         OPJ_COLOR_SPACE color_space;
672         opj_image_cmptparm_t cmptparm;  /* maximum of 1 component  */
673         opj_image_t * image = NULL;
674
675         char endian1,endian2,sign;
676         char signtmp[32];
677
678         char temp[32];
679         int bigendian;
680         opj_image_comp_t *comp = NULL;
681
682         numcomps = 1;
683         color_space = CLRSPC_GRAY;
684
685         memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t));
686
687         max = 0;
688
689         f = fopen(filename, "rb");
690         if (!f) {
691           fprintf(stderr, "Failed to open %s for reading !\n", filename);
692           return NULL;
693         }
694
695         fseek(f, 0, SEEK_SET);
696         fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h);
697         
698         i=0;
699         sign='+';               
700         while (signtmp[i]!='\0') {
701                 if (signtmp[i]=='-') sign='-';
702                 i++;
703         }
704         
705         fgetc(f);
706         if (endian1=='M' && endian2=='L') {
707                 bigendian = 1;
708         } else if (endian2=='M' && endian1=='L') {
709                 bigendian = 0;
710         } else {
711                 fprintf(stderr, "Bad pgx header, please check input file\n");
712                 return NULL;
713         }
714
715         /* initialize image component */
716
717         cmptparm.x0 = parameters->image_offset_x0;
718         cmptparm.y0 = parameters->image_offset_y0;
719         cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1;
720         cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1;
721         
722         if (sign == '-') {
723                 cmptparm.sgnd = 1;
724         } else {
725                 cmptparm.sgnd = 0;
726         }
727         cmptparm.prec = prec;
728         cmptparm.bpp = prec;
729         cmptparm.dx = parameters->subsampling_dx;
730         cmptparm.dy = parameters->subsampling_dy;
731         
732         /* create the image */
733         image = opj_image_create(numcomps, &cmptparm, color_space);
734         if(!image) {
735                 fclose(f);
736                 return NULL;
737         }
738         /* set image offset and reference grid */
739         image->x0 = cmptparm.x0;
740         image->y0 = cmptparm.x0;
741         image->x1 = cmptparm.w;
742         image->y1 = cmptparm.h;
743
744         /* set image data */
745
746         comp = &image->comps[0];
747
748         for (i = 0; i < w * h; i++) {
749                 int v;
750                 if (comp->prec <= 8) {
751                         if (!comp->sgnd) {
752                                 v = readuchar(f);
753                         } else {
754                                 v = (char) readuchar(f);
755                         }
756                 } else if (comp->prec <= 16) {
757                         if (!comp->sgnd) {
758                                 v = readushort(f, bigendian);
759                         } else {
760                                 v = (short) readushort(f, bigendian);
761                         }
762                 } else {
763                         if (!comp->sgnd) {
764                                 v = readuint(f, bigendian);
765                         } else {
766                                 v = (int) readuint(f, bigendian);
767                         }
768                 }
769                 if (v > max)
770                         max = v;
771                 comp->data[i] = v;
772         }
773         fclose(f);
774         comp->bpp = int_floorlog2(max) + 1;
775
776         return image;
777 }
778
779 int imagetopgx(opj_image_t * image, const char *outfile) {
780         int w, wr, h, hr;
781         int i, j, compno;
782         FILE *fdest = NULL;
783
784         for (compno = 0; compno < image->numcomps; compno++) {
785                 opj_image_comp_t *comp = &image->comps[compno];
786                 char bname[256]; /* buffer for name */
787     char *name = bname; /* pointer */
788     int nbytes = 0;
789     const size_t olen = strlen(outfile);
790     const size_t dotpos = olen - 4;
791     const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */
792     if( outfile[dotpos] != '.' ) {
793       /* `pgx` was recognized but there is no dot at expected position */
794       fprintf(stderr, "ERROR -> Impossible happen." );
795       return 1;
796       }
797     if( total > 256 ) {
798       name = (char*)malloc(total+1);
799       }
800     strncpy(name, outfile, dotpos);
801                 if (image->numcomps > 1) {
802                         sprintf(name+dotpos, "-%d.pgx", compno);
803                 } else {
804                         strcpy(name+dotpos, ".pgx");
805                 }
806                 fdest = fopen(name, "wb");
807                 if (!fdest) {
808                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
809                         return 1;
810                 }
811     /* dont need name anymore */
812     if( total > 256 ) {
813       free(name);
814       }
815                 /* w = int_ceildiv(image->x1 - image->x0, comp->dx); */
816                 /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), comp->dx); */
817                 w = image->comps[compno].w;
818                 wr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);
819             
820                 /* h = int_ceildiv(image->y1 - image->y0, comp->dy); */
821                 /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), comp->dy); */
822                 h = image->comps[compno].h;
823                 hr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);
824             
825                 fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, wr, hr);
826                 if (comp->prec <= 8) {
827                         nbytes = 1;
828                 } else if (comp->prec <= 16) {
829                         nbytes = 2;
830                 } else {
831                         nbytes = 4;
832                 }
833                 for (i = 0; i < wr * hr; i++) {
834                         int v = image->comps[compno].data[i / wr * w + i % wr];
835                         for (j = nbytes - 1; j >= 0; j--) {
836                                 char byte = (char) (v >> (j * 8));
837                                 fwrite(&byte, 1, 1, fdest);
838                         }
839                 }
840                 fclose(fdest);
841         }
842
843         return 0;
844 }
845
846 /* -->> -->> -->> -->>
847
848 PNM IMAGE FORMAT
849
850 <<-- <<-- <<-- <<-- */
851
852 opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) {
853         int subsampling_dx = parameters->subsampling_dx;
854         int subsampling_dy = parameters->subsampling_dy;
855
856         FILE *f = NULL;
857         int i, compno, numcomps, w, h;
858         OPJ_COLOR_SPACE color_space;
859         opj_image_cmptparm_t cmptparm[3];       /* maximum of 3 components */
860         opj_image_t * image = NULL;
861         char value;
862         
863         f = fopen(filename, "rb");
864         if (!f) {
865                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
866                 return 0;
867         }
868
869         if (fgetc(f) != 'P')
870                 return 0;
871         value = fgetc(f);
872
873                 switch(value) {
874                         case '2':       /* greyscale image type */
875                         case '5':
876                                 numcomps = 1;
877                                 color_space = CLRSPC_GRAY;
878                                 break;
879                                 
880                         case '3':       /* RGB image type */
881                         case '6':
882                                 numcomps = 3;
883                                 color_space = CLRSPC_SRGB;
884                                 break;
885                                 
886                         default:
887                                 fclose(f);
888                                 return NULL;
889                 }
890                 
891                 fgetc(f);
892                 
893                 /* skip comments */
894                 while(fgetc(f) == '#') while(fgetc(f) != '\n');
895                 
896                 fseek(f, -1, SEEK_CUR);
897                 fscanf(f, "%d %d\n255", &w, &h);                        
898                 fgetc(f);       /* <cr><lf> */
899                 
900         /* initialize image components */
901         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
902         for(i = 0; i < numcomps; i++) {
903                 cmptparm[i].prec = 8;
904                 cmptparm[i].bpp = 8;
905                 cmptparm[i].sgnd = 0;
906                 cmptparm[i].dx = subsampling_dx;
907                 cmptparm[i].dy = subsampling_dy;
908                 cmptparm[i].w = w;
909                 cmptparm[i].h = h;
910         }
911         /* create the image */
912         image = opj_image_create(numcomps, &cmptparm[0], color_space);
913         if(!image) {
914                 fclose(f);
915                 return NULL;
916         }
917
918         /* set image offset and reference grid */
919         image->x0 = parameters->image_offset_x0;
920         image->y0 = parameters->image_offset_y0;
921         image->x1 = parameters->image_offset_x0 + (w - 1) *     subsampling_dx + 1;
922         image->y1 = parameters->image_offset_y0 + (h - 1) *     subsampling_dy + 1;
923
924         /* set image data */
925
926         if ((value == '2') || (value == '3')) { /* ASCII */
927                 for (i = 0; i < w * h; i++) {
928                         for(compno = 0; compno < numcomps; compno++) {
929                                 unsigned int index = 0;
930                                 fscanf(f, "%u", &index);
931                                 /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
932                                 image->comps[compno].data[i] = index;
933                         }
934                 }
935         } else if ((value == '5') || (value == '6')) {  /* BINARY */
936                 for (i = 0; i < w * h; i++) {
937                         for(compno = 0; compno < numcomps; compno++) {
938                                 unsigned char index = 0;
939                                 fread(&index, 1, 1, f);
940                                 /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
941                                 image->comps[compno].data[i] = index;
942                         }
943                 }
944         }
945
946         fclose(f);
947
948         return image;
949 }
950
951 int imagetopnm(opj_image_t * image, const char *outfile) {
952         int w, wr, wrr, h, hr, hrr, max;
953         int i, compno;
954         int adjust;
955         FILE *fdest = NULL;
956         char S2;
957         const char *tmp = outfile;
958
959         while (*tmp) {
960                 tmp++;
961         }
962         tmp--;
963         tmp--;
964         S2 = *tmp;
965
966         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
967                 && image->comps[1].dx == image->comps[2].dx
968                 && image->comps[0].dy == image->comps[1].dy
969                 && image->comps[1].dy == image->comps[2].dy
970                 && image->comps[0].prec == image->comps[1].prec
971                 && image->comps[1].prec == image->comps[2].prec
972                 && S2 !='g' && S2 !='G') {
973
974                 fdest = fopen(outfile, "wb");
975                 if (!fdest) {
976                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
977                         return 1;
978                 }
979
980                 w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
981                 /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor),image->comps[0].dx); */
982                 wr = image->comps[0].w;
983                 wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
984         
985                 h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
986                 /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */
987                 hr = image->comps[0].h;
988                 hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
989             
990                 max = image->comps[0].prec > 8 ? 255 : (1 << image->comps[0].prec) - 1;
991             
992                 image->comps[0].x0 = int_ceildivpow2(image->comps[0].x0 - int_ceildiv(image->x0, image->comps[0].dx), image->comps[0].factor);
993                 image->comps[0].y0 = int_ceildivpow2(image->comps[0].y0 -       int_ceildiv(image->y0, image->comps[0].dy), image->comps[0].factor);
994
995                 fprintf(fdest, "P6\n%d %d\n%d\n", wrr, hrr, max);
996                 adjust = image->comps[0].prec > 8 ? image->comps[0].prec - 8 : 0;
997                 for (i = 0; i < wrr * hrr; i++) {
998                         int r, g, b;
999                         unsigned char rc,gc,bc;
1000                         r = image->comps[0].data[i / wrr * wr + i % wrr];
1001                         r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
1002                         rc = (unsigned char) ((r >> adjust)+((r >> (adjust-1))%2));
1003
1004                         g = image->comps[1].data[i / wrr * wr + i % wrr];
1005                         g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
1006                         gc = (unsigned char) ((g >> adjust)+((g >> (adjust-1))%2));
1007                         
1008                         b = image->comps[2].data[i / wrr * wr + i % wrr];
1009                         b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
1010                         bc = (unsigned char) ((b >> adjust)+((b >> (adjust-1))%2));
1011                         
1012                         fprintf(fdest, "%c%c%c", rc, gc, bc);
1013                 }
1014                 fclose(fdest);
1015         } else {
1016                 int ncomp=(S2=='g' || S2=='G')?1:image->numcomps;
1017                 if (image->numcomps>ncomp) {
1018                         fprintf(stderr,"WARNING -> [PGM files] Only the first component\n");
1019                         fprintf(stderr,"           is written to the file\n");
1020                 }
1021                 for (compno = 0; compno < ncomp; compno++) {
1022                         char name[256];
1023                         if (ncomp > 1) {
1024                                 sprintf(name, "%d.%s", compno, outfile);
1025                         } else {
1026                                 sprintf(name, "%s", outfile);
1027                         }
1028                         
1029                         fdest = fopen(name, "wb");
1030                         if (!fdest) {
1031                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
1032                                 return 1;
1033                         }
1034             
1035                         w = int_ceildiv(image->x1 - image->x0, image->comps[compno].dx);
1036                         /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor),image->comps[compno].dx); */
1037                         wr = image->comps[compno].w;
1038                         wrr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);
1039                         
1040                         h = int_ceildiv(image->y1 - image->y0, image->comps[compno].dy);
1041                         /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[compno].dy); */
1042                         hr = image->comps[compno].h;
1043                         hrr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);
1044                         
1045                         max = image->comps[compno].prec > 8 ? 255 : (1 << image->comps[compno].prec) - 1;
1046                         
1047                         image->comps[compno].x0 = int_ceildivpow2(image->comps[compno].x0 - int_ceildiv(image->x0, image->comps[compno].dx), image->comps[compno].factor);
1048                         image->comps[compno].y0 = int_ceildivpow2(image->comps[compno].y0 - int_ceildiv(image->y0, image->comps[compno].dy), image->comps[compno].factor);
1049                         
1050                         fprintf(fdest, "P5\n%d %d\n%d\n", wrr, hrr, max);
1051                         adjust = image->comps[compno].prec > 8 ? image->comps[compno].prec - 8 : 0;
1052
1053                         for (i = 0; i < wrr * hrr; i++) {
1054                                 int l;
1055                                 unsigned char lc;
1056                                 l = image->comps[compno].data[i / wrr * wr + i % wrr];
1057                                 l += (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0);
1058                                 lc = (unsigned char) ((l >> adjust)+((l >> (adjust-1))%2));
1059                                 fprintf(fdest, "%c", lc);
1060                         }
1061                         fclose(fdest);
1062                 }
1063         }
1064
1065         return 0;
1066 }
1067
1068 /* -->> -->> -->> -->>
1069
1070         TIFF IMAGE FORMAT
1071
1072  <<-- <<-- <<-- <<-- */
1073
1074 typedef struct tiff_infoheader{
1075         DWORD tiWidth;  // Width of Image in pixel
1076         DWORD tiHeight; // Height of Image in pixel
1077         DWORD tiPhoto;  // Photometric
1078         WORD  tiBps;    // Bits per sample
1079         WORD  tiSf;             // Sample Format
1080         WORD  tiSpp;    // Sample per pixel 1-bilevel,gray scale , 2- RGB
1081         WORD  tiPC;     // Planar config (1-Interleaved, 2-Planarcomp)
1082 }tiff_infoheader_t;
1083
1084 int imagetotif(opj_image_t * image, const char *outfile) {
1085         int width, height;
1086         int bps,index;
1087         TIFF *tif;
1088         tdata_t buf;
1089         tstrip_t strip;
1090         tsize_t strip_size;
1091
1092         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
1093                 && image->comps[1].dx == image->comps[2].dx
1094                 && image->comps[0].dy == image->comps[1].dy
1095                 && image->comps[1].dy == image->comps[2].dy
1096                 && image->comps[0].prec == image->comps[1].prec
1097                 && image->comps[1].prec == image->comps[2].prec) {
1098
1099                         /* -->> -->> -->>    
1100                         RGB color           
1101                         <<-- <<-- <<-- */
1102
1103                         tif = TIFFOpen(outfile, "wb"); 
1104                         if (!tif) {
1105                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1106                                 return 1;
1107                         }
1108
1109                         width   = image->comps[0].w;
1110                         height= image->comps[0].h;
1111                         bps             = image->comps[0].prec;
1112                         /* Set tags */
1113                         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
1114                         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
1115                         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
1116                         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
1117                         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
1118                         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1119                         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
1120                         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
1121
1122                         /* Get a buffer for the data */
1123                         buf = _TIFFmalloc(TIFFStripSize(tif));
1124                         index=0;
1125                         strip_size=0;
1126                         strip_size=TIFFStripSize(tif);
1127                         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1128                                 unsigned char *dat8;
1129                                 int i;
1130                                 dat8 = buf;
1131                                 if (image->comps[0].prec == 8){
1132                                         for (i=0; i<TIFFStripSize(tif); i+=3) { // 8 bits per pixel 
1133                                                 dat8[i+0] = image->comps[0].data[index] ;       // R 
1134                                                 dat8[i+1] = image->comps[1].data[index] ;       // G 
1135                                                 dat8[i+2] = image->comps[2].data[index] ;       // B 
1136                                                 index++;
1137                                         }
1138                                 }else if (image->comps[0].prec == 12){
1139                                         for (i=0; i<TIFFStripSize(tif); i+=9) { // 12 bits per pixel 
1140                                                 dat8[i+0] = (image->comps[0].data[index]>>8)<<4 | (image->comps[0].data[index]>>4);
1141                                                 dat8[i+1] = (image->comps[0].data[index]<<4)|((image->comps[1].data[index]>>8)& 0x0f);
1142                                                 dat8[i+2] = (image->comps[1].data[index]);
1143                                                 dat8[i+3] = (image->comps[2].data[index]>>8)<<4 | (image->comps[2].data[index]>>4);
1144                                                 dat8[i+4] = (image->comps[2].data[index]<<4)|((image->comps[1].data[index+1]>>8)& 0x0f);
1145                                                 dat8[i+5] = (image->comps[0].data[index+1]);
1146                                                 dat8[i+6] = (image->comps[1].data[index+1]>>8)<<4 | (image->comps[1].data[index+1]>>4);
1147                                                 dat8[i+7] = (image->comps[1].data[index+1]<<4)|((image->comps[2].data[index+1]>>8)& 0x0f);
1148                                                 dat8[i+8] = (image->comps[2].data[index+1]);
1149                                                 index+=2;
1150                                         }
1151                                 }else if (image->comps[0].prec == 16){
1152                                         for (i=0; i<TIFFStripSize(tif); i+=6) { // 16 bits per pixel 
1153                                                 dat8[i+0] =  image->comps[0].data[index];//LSB
1154                                                 dat8[i+1] = (image->comps[0].data[index]>> 8);//MSB      
1155                                                 dat8[i+2] =  image->comps[1].data[index]; 
1156                                                 dat8[i+3] = (image->comps[1].data[index]>> 8);  
1157                                                 dat8[i+4] =  image->comps[2].data[index];        
1158                                                 dat8[i+5] = (image->comps[2].data[index]>> 8); 
1159                                                 index++;
1160                                         }
1161                                 }else{
1162                                         fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec);
1163                                         fprintf(stderr,"Aborting\n");
1164                                         return 1;
1165                                 }
1166                                 TIFFWriteEncodedStrip(tif, strip, buf, strip_size);
1167                         }
1168                         _TIFFfree(buf);
1169                         TIFFClose(tif);
1170                 }else if (image->numcomps == 1){
1171                         /* -->> -->> -->>    
1172                         Black and White     
1173                         <<-- <<-- <<-- */
1174
1175                         tif = TIFFOpen(outfile, "wb"); 
1176                         if (!tif) {
1177                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1178                                 return 1;
1179                         }
1180
1181                         width   = image->comps[0].w;
1182                         height= image->comps[0].h;
1183                         bps             = image->comps[0].prec;
1184
1185                         /* Set tags */
1186                         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
1187                         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
1188                         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
1189                         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
1190                         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
1191                         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1192                         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
1193                         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
1194
1195                         /* Get a buffer for the data */
1196                         buf = _TIFFmalloc(TIFFStripSize(tif));
1197                         index = 0;
1198                         strip_size = 0;
1199                         strip_size = TIFFStripSize(tif);
1200                         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1201                                 unsigned char *dat8;
1202                                 int i;
1203                                 dat8 = buf;
1204                                 if (image->comps[0].prec == 8){
1205                                         for (i=0; i<TIFFStripSize(tif); i+=1) { // 8 bits per pixel 
1206                                                 dat8[i+0] = image->comps[0].data[index] ;
1207                                                 index++;
1208                                         }
1209                                 }else if (image->comps[0].prec == 12){
1210                                         for (i = 0; i<TIFFStripSize(tif); i+=3) {       // 12 bits per pixel 
1211                                                 dat8[i+0] = (image->comps[0].data[index]>>8)<<4 | (image->comps[0].data[index]>>4);
1212                                                 dat8[i+1] = (image->comps[0].data[index]<<4)|((image->comps[0].data[index+1]>>8)& 0x0f);
1213                                                 dat8[i+2] = (image->comps[0].data[index+1]);
1214                                                 index+=2;
1215                                         }
1216                                 }else if (image->comps[0].prec == 16){
1217                                         for (i=0; i<TIFFStripSize(tif); i+=2) { // 16 bits per pixel 
1218                                                 dat8[i+0] =  image->comps[0].data[index];
1219                                                 dat8[i+1] = (image->comps[0].data[index]>> 8);
1220                                                 index++;
1221                                         }
1222                                 }else{
1223                                         fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec);
1224                                         fprintf(stderr,"Aborting\n");
1225                                         return 1;
1226                                 }
1227                                 TIFFWriteEncodedStrip(tif, strip, buf, strip_size);
1228                         }
1229                         _TIFFfree(buf);
1230                         TIFFClose(tif);
1231                 }else{
1232                         fprintf(stderr,"False color format. Only RGB & Grayscale has been implemented\n");
1233                         fprintf(stderr,"Aborting\n");
1234                         return 1;
1235                 }
1236                 return 0;
1237 }
1238
1239 opj_image_t* tiftoimage(char *filename, opj_cparameters_t *parameters)
1240 {
1241         int subsampling_dx = parameters->subsampling_dx;
1242         int subsampling_dy = parameters->subsampling_dy;
1243         TIFF *tif;
1244         tiff_infoheader_t Info;
1245         tdata_t buf;
1246         tstrip_t strip;
1247         tsize_t strip_size;
1248         int j, numcomps, w, h,index;
1249         OPJ_COLOR_SPACE color_space;
1250         opj_image_cmptparm_t cmptparm[3];
1251         opj_image_t * image = NULL;
1252
1253         tif = TIFFOpen(filename, "r");
1254
1255         if (!tif) {
1256                 fprintf(stderr, "Failed to open %s for reading\n", filename);
1257                 return 0;
1258         }
1259
1260         TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &Info.tiWidth);
1261         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &Info.tiHeight);
1262         TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &Info.tiBps);
1263         TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &Info.tiSf);
1264         TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &Info.tiSpp);
1265         Info.tiPhoto = 0;
1266         TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &Info.tiPhoto);
1267         TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &Info.tiPC);
1268         w= Info.tiWidth;
1269         h= Info.tiHeight;
1270         
1271         if (Info.tiPhoto == 2) { 
1272                 /* -->> -->> -->>    
1273                 RGB color           
1274                 <<-- <<-- <<-- */
1275
1276                 numcomps = 3;
1277                 color_space = CLRSPC_SRGB;
1278                 /* initialize image components*/ 
1279                 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
1280                 for(j = 0; j < numcomps; j++) {
1281                         if (parameters->cp_cinema) {
1282                                 cmptparm[j].prec = 12;
1283                                 cmptparm[j].bpp = 12;
1284                         }else{
1285                                 cmptparm[j].prec = Info.tiBps;
1286                                 cmptparm[j].bpp = Info.tiBps;
1287                         }
1288                         cmptparm[j].sgnd = 0;
1289                         cmptparm[j].dx = subsampling_dx;
1290                         cmptparm[j].dy = subsampling_dy;
1291                         cmptparm[j].w = w;
1292                         cmptparm[j].h = h;
1293                 }
1294                 /* create the image*/ 
1295                 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1296                 if(!image) {
1297                         TIFFClose(tif);
1298                         return NULL;
1299                 }
1300
1301                 /* set image offset and reference grid */
1302                 image->x0 = parameters->image_offset_x0;
1303                 image->y0 = parameters->image_offset_y0;
1304                 image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
1305                 image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
1306
1307                 buf = _TIFFmalloc(TIFFStripSize(tif));
1308                 strip_size=0;
1309                 strip_size=TIFFStripSize(tif);
1310                 index = 0;
1311                 /* Read the Image components*/
1312                 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1313                         unsigned char *dat8;
1314                         int i, ssize;
1315                         ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
1316                         dat8 = buf;
1317
1318                         if (Info.tiBps==12){
1319                                 for (i=0; i<ssize; i+=9) {      /*12 bits per pixel*/
1320                                         image->comps[0].data[index]   = ( dat8[i+0]<<4 )                |(dat8[i+1]>>4);
1321                                         image->comps[1].data[index]   = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2];
1322                                         image->comps[2].data[index]   = ( dat8[i+3]<<4)                 |(dat8[i+4]>>4);
1323                                         image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5];
1324                                         image->comps[1].data[index+1] = ( dat8[i+6] <<4)                |(dat8[i+7]>>4);
1325                                         image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8];
1326                                         index+=2;
1327                                 }
1328                         }
1329                         else if( Info.tiBps==16){
1330                                 for (i=0; i<ssize; i+=6) {      /* 16 bits per pixel */
1331                                         image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0];   // R 
1332                                         image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2];   // G 
1333                                         image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4];   // B 
1334                                         if(parameters->cp_cinema){/* Rounding to 12 bits*/
1335                                                 image->comps[0].data[index] = (image->comps[0].data[index] + 0x08) >> 4 ;
1336                                                 image->comps[1].data[index] = (image->comps[1].data[index] + 0x08) >> 4 ;
1337                                                 image->comps[2].data[index] = (image->comps[2].data[index] + 0x08) >> 4 ;
1338                                         }
1339                                         index++;
1340                                 }
1341                         }
1342                         else if ( Info.tiBps==8){
1343                                 for (i=0; i<ssize; i+=3) {      /* 8 bits per pixel */
1344                                         image->comps[0].data[index] = dat8[i+0];        // R 
1345                                         image->comps[1].data[index] = dat8[i+1];        // G 
1346                                         image->comps[2].data[index] = dat8[i+2];        // B 
1347                                         if(parameters->cp_cinema){/* Rounding to 12 bits*/
1348                                                 image->comps[0].data[index] = image->comps[0].data[index] << 4 ;
1349                                                 image->comps[1].data[index] = image->comps[1].data[index] << 4 ;
1350                                                 image->comps[2].data[index] = image->comps[2].data[index] << 4 ;
1351                                         }
1352                                         index++;
1353                                 }
1354                         }
1355                         else{
1356                                 fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps);
1357                                 fprintf(stderr,"Aborting\n");
1358                                 return NULL;
1359                         }
1360                 }
1361
1362                 _TIFFfree(buf);
1363                 TIFFClose(tif);
1364         }else if(Info.tiPhoto == 1) { 
1365                 /* -->> -->> -->>    
1366                 Black and White
1367                 <<-- <<-- <<-- */
1368
1369                 numcomps = 1;
1370                 color_space = CLRSPC_GRAY;
1371                 /* initialize image components*/ 
1372                 memset(&cmptparm[0], 0, sizeof(opj_image_cmptparm_t));
1373                 cmptparm[0].prec = Info.tiBps;
1374                 cmptparm[0].bpp = Info.tiBps;
1375                 cmptparm[0].sgnd = 0;
1376                 cmptparm[0].dx = subsampling_dx;
1377                 cmptparm[0].dy = subsampling_dy;
1378                 cmptparm[0].w = w;
1379                 cmptparm[0].h = h;
1380
1381                 /* create the image*/ 
1382                 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1383                 if(!image) {
1384                         TIFFClose(tif);
1385                         return NULL;
1386                 }
1387                 /* set image offset and reference grid */
1388                 image->x0 = parameters->image_offset_x0;
1389                 image->y0 = parameters->image_offset_y0;
1390                 image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
1391                 image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
1392
1393                 buf = _TIFFmalloc(TIFFStripSize(tif));
1394                 strip_size = 0;
1395                 strip_size = TIFFStripSize(tif);
1396                 index = 0;
1397                 /* Read the Image components*/
1398                 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1399                         unsigned char *dat8;
1400                         int i, ssize;
1401                         ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
1402                         dat8 = buf;
1403
1404                         if (Info.tiBps==12){
1405                                 for (i=0; i<ssize; i+=3) {      /* 12 bits per pixel*/
1406                                         image->comps[0].data[index] = ( dat8[i+0]<<4 )                          |(dat8[i+1]>>4) ;
1407                                         image->comps[0].data[index] = ((dat8[i+1]& 0x0f)<< 8)   | dat8[i+2];
1408                                         index+=2;
1409                                 }
1410                         }
1411                         else if( Info.tiBps==16){
1412                                 for (i=0; i<ssize; i+=2) {      /* 16 bits per pixel */
1413                                         image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0];
1414                                         index++;
1415                                 }
1416                         }
1417                         else if ( Info.tiBps==8){
1418                                 for (i=0; i<ssize; i+=1) {      /* 8 bits per pixel */
1419                                         image->comps[0].data[index] = dat8[i+0];
1420                                         index++;
1421                                 }
1422                         }
1423                         else{
1424                                 fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps);
1425                                 fprintf(stderr,"Aborting\n");
1426                                 return NULL;
1427                         }
1428                 }
1429
1430                 _TIFFfree(buf);
1431                 TIFFClose(tif);
1432         }else{
1433                 fprintf(stderr,"False color format. Only RGB & Grayscale has been implemented\n");
1434                 fprintf(stderr,"Aborting\n");
1435                 return NULL;
1436         }
1437         return image;
1438 }