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