Fixed the DCinema filesize allocation. It now includes the SOT marker size
[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 #include "convert.h"
38
39 /*
40  * Get logarithm of an integer and round downwards.
41  *
42  * log2(a)
43  */
44 static int int_floorlog2(int a) {
45         int l;
46         for (l = 0; a > 1; l++) {
47                 a >>= 1;
48         }
49         return l;
50 }
51
52 /*
53  * Divide an integer by a power of 2 and round upwards.
54  *
55  * a divided by 2^b
56  */
57 static int int_ceildivpow2(int a, int b) {
58         return (a + (1 << b) - 1) >> b;
59 }
60
61 /*
62  * Divide an integer and round upwards.
63  *
64  * a divided by b
65  */
66 static int int_ceildiv(int a, int b) {
67         return (a + b - 1) / b;
68 }
69
70 /* -->> -->> -->> -->>
71
72   BMP IMAGE FORMAT
73
74  <<-- <<-- <<-- <<-- */
75
76 /* WORD defines a two byte word */
77 typedef unsigned short int WORD;
78
79 /* DWORD defines a four byte word */
80 typedef unsigned long int DWORD;
81
82 typedef struct {
83   WORD bfType;                  /* 'BM' for Bitmap (19776) */
84   DWORD bfSize;                 /* Size of the file        */
85   WORD bfReserved1;             /* Reserved : 0            */
86   WORD bfReserved2;             /* Reserved : 0            */
87   DWORD bfOffBits;              /* Offset                  */
88 } BITMAPFILEHEADER_t;
89
90 typedef struct {
91   DWORD biSize;                 /* Size of the structure in bytes */
92   DWORD biWidth;                /* Width of the image in pixels */
93   DWORD biHeight;               /* Heigth of the image in pixels */
94   WORD biPlanes;                /* 1 */
95   WORD biBitCount;              /* Number of color bits by pixels */
96   DWORD biCompression;          /* Type of encoding 0: none 1: RLE8 2: RLE4 */
97   DWORD biSizeImage;            /* Size of the image in bytes */
98   DWORD biXpelsPerMeter;        /* Horizontal (X) resolution in pixels/meter */
99   DWORD biYpelsPerMeter;        /* Vertical (Y) resolution in pixels/meter */
100   DWORD biClrUsed;              /* Number of color used in the image (0: ALL) */
101   DWORD biClrImportant;         /* Number of important color (0: ALL) */
102 } BITMAPINFOHEADER_t;
103
104 opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
105         int subsampling_dx = parameters->subsampling_dx;
106         int subsampling_dy = parameters->subsampling_dy;
107
108         int i, numcomps, w, h;
109         OPJ_COLOR_SPACE color_space;
110         opj_image_cmptparm_t cmptparm[3];       /* maximum of 3 components */
111         opj_image_t * image = NULL;
112
113         FILE *IN;
114         BITMAPFILEHEADER_t File_h;
115         BITMAPINFOHEADER_t Info_h;
116         unsigned char *RGB;
117         unsigned char *table_R, *table_G, *table_B;
118         unsigned int j, PAD = 0;
119
120         int x, y, index;
121         int gray_scale = 1, not_end_file = 1; 
122
123         unsigned int line = 0, col = 0;
124         unsigned char v, v2;
125         DWORD W, H;
126   
127         IN = fopen(filename, "rb");
128         if (!IN) {
129                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
130                 return 0;
131         }
132         
133         File_h.bfType = getc(IN);
134         File_h.bfType = (getc(IN) << 8) + File_h.bfType;
135         
136         if (File_h.bfType != 19778) {
137                 fprintf(stderr,"Error, not a BMP file!\n");
138                 return 0;
139         } else {
140                 /* FILE HEADER */
141                 /* ------------- */
142                 File_h.bfSize = getc(IN);
143                 File_h.bfSize = (getc(IN) << 8) + File_h.bfSize;
144                 File_h.bfSize = (getc(IN) << 16) + File_h.bfSize;
145                 File_h.bfSize = (getc(IN) << 24) + File_h.bfSize;
146
147                 File_h.bfReserved1 = getc(IN);
148                 File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1;
149
150                 File_h.bfReserved2 = getc(IN);
151                 File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2;
152
153                 File_h.bfOffBits = getc(IN);
154                 File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits;
155                 File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits;
156                 File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits;
157
158                 /* INFO HEADER */
159                 /* ------------- */
160
161                 Info_h.biSize = getc(IN);
162                 Info_h.biSize = (getc(IN) << 8) + Info_h.biSize;
163                 Info_h.biSize = (getc(IN) << 16) + Info_h.biSize;
164                 Info_h.biSize = (getc(IN) << 24) + Info_h.biSize;
165
166                 Info_h.biWidth = getc(IN);
167                 Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth;
168                 Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth;
169                 Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth;
170                 w = Info_h.biWidth;
171
172                 Info_h.biHeight = getc(IN);
173                 Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight;
174                 Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight;
175                 Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight;
176                 h = Info_h.biHeight;
177
178                 Info_h.biPlanes = getc(IN);
179                 Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes;
180
181                 Info_h.biBitCount = getc(IN);
182                 Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount;
183
184                 Info_h.biCompression = getc(IN);
185                 Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression;
186                 Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression;
187                 Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression;
188
189                 Info_h.biSizeImage = getc(IN);
190                 Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage;
191                 Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage;
192                 Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage;
193
194                 Info_h.biXpelsPerMeter = getc(IN);
195                 Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter;
196                 Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter;
197                 Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter;
198
199                 Info_h.biYpelsPerMeter = getc(IN);
200                 Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter;
201                 Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter;
202                 Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter;
203
204                 Info_h.biClrUsed = getc(IN);
205                 Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed;
206                 Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed;
207                 Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed;
208
209                 Info_h.biClrImportant = getc(IN);
210                 Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant;
211                 Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant;
212                 Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant;
213
214                 /* Read the data and store them in the OUT file */
215     
216                 if (Info_h.biBitCount == 24) {
217                         numcomps = 3;
218                         color_space = CLRSPC_SRGB;
219                         /* initialize image components */
220                         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
221                         for(i = 0; i < numcomps; i++) {
222                                 cmptparm[i].prec = 8;
223                                 cmptparm[i].bpp = 8;
224                                 cmptparm[i].sgnd = 0;
225                                 cmptparm[i].dx = subsampling_dx;
226                                 cmptparm[i].dy = subsampling_dy;
227                                 cmptparm[i].w = w;
228                                 cmptparm[i].h = h;
229                         }
230                         /* create the image */
231                         image = opj_image_create(numcomps, &cmptparm[0], color_space);
232                         if(!image) {
233                                 fclose(IN);
234                                 return NULL;
235                         }
236
237                         /* set image offset and reference grid */
238                         image->x0 = parameters->image_offset_x0;
239                         image->y0 = parameters->image_offset_y0;
240                         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
241                         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
242
243                         /* set image data */
244
245                         /* Place the cursor at the beginning of the image information */
246                         fseek(IN, 0, SEEK_SET);
247                         fseek(IN, File_h.bfOffBits, SEEK_SET);
248                         
249                         W = Info_h.biWidth;
250                         H = Info_h.biHeight;
251
252                         /* PAD = 4 - (3 * W) % 4; */
253                         /* PAD = (PAD == 4) ? 0 : PAD; */
254                         PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0;
255                         
256                         RGB = (unsigned char *) malloc((3 * W + PAD) * H * sizeof(unsigned char));
257                         
258                         fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN);
259                         
260                         index = 0;
261
262                         for(y = 0; y < (int)H; y++) {
263                                 unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y);
264                                 for(x = 0; x < (int)W; x++) {
265                                         unsigned char *pixel = &scanline[3 * x];
266                                         image->comps[0].data[index] = pixel[2]; /* R */
267                                         image->comps[1].data[index] = pixel[1]; /* G */
268                                         image->comps[2].data[index] = pixel[0]; /* B */
269                                         index++;
270                                 }
271                         }
272
273                         free(RGB);
274
275                 } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) {
276                         table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
277                         table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
278                         table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
279                         
280                         for (j = 0; j < Info_h.biClrUsed; j++) {
281                                 table_B[j] = getc(IN);
282                                 table_G[j] = getc(IN);
283                                 table_R[j] = getc(IN);
284                                 getc(IN);
285                                 if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j])
286                                         gray_scale = 0;
287                         }
288                         
289                         /* Place the cursor at the beginning of the image information */
290                         fseek(IN, 0, SEEK_SET);
291                         fseek(IN, File_h.bfOffBits, SEEK_SET);
292                         
293                         W = Info_h.biWidth;
294                         H = Info_h.biHeight;
295                         if (Info_h.biWidth % 2)
296                                 W++;
297                         
298                         numcomps = gray_scale ? 1 : 3;
299                         color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;
300                         /* initialize image components */
301                         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
302                         for(i = 0; i < numcomps; i++) {
303                                 cmptparm[i].prec = 8;
304                                 cmptparm[i].bpp = 8;
305                                 cmptparm[i].sgnd = 0;
306                                 cmptparm[i].dx = subsampling_dx;
307                                 cmptparm[i].dy = subsampling_dy;
308                                 cmptparm[i].w = w;
309                                 cmptparm[i].h = h;
310                         }
311                         /* create the image */
312                         image = opj_image_create(numcomps, &cmptparm[0], color_space);
313                         if(!image) {
314                                 fclose(IN);
315                                 return NULL;
316                         }
317
318                         /* set image offset and reference grid */
319                         image->x0 = parameters->image_offset_x0;
320                         image->y0 = parameters->image_offset_y0;
321                         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
322                         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
323
324                         /* set image data */
325
326                         RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char));
327                         
328                         fread(RGB, sizeof(unsigned char), W * H, IN);
329                         if (gray_scale) {
330                                 index = 0;
331                                 for (j = 0; j < W * H; j++) {
332                                         if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) {
333                                                 image->comps[0].data[index] = table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]];
334                                                 index++;
335                                         }
336                                 }
337
338                         } else {                
339                                 index = 0;
340                                 for (j = 0; j < W * H; j++) {
341                                         if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) {
342                                                 unsigned char pixel_index = RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)];
343                                                 image->comps[0].data[index] = table_R[pixel_index];
344                                                 image->comps[1].data[index] = table_G[pixel_index];
345                                                 image->comps[2].data[index] = table_B[pixel_index];
346                                                 index++;
347                                         }
348                                 }
349                         }
350                         free(RGB);
351       free(table_R);
352       free(table_G);
353       free(table_B);
354                 } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) {                               
355                         table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
356                         table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
357                         table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
358                         
359                         for (j = 0; j < Info_h.biClrUsed; j++) {
360                                 table_B[j] = getc(IN);
361                                 table_G[j] = getc(IN);
362                                 table_R[j] = getc(IN);
363                                 getc(IN);
364                                 if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j])
365                                         gray_scale = 0;
366                         }
367
368                         numcomps = gray_scale ? 1 : 3;
369                         color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;
370                         /* initialize image components */
371                         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
372                         for(i = 0; i < numcomps; i++) {
373                                 cmptparm[i].prec = 8;
374                                 cmptparm[i].bpp = 8;
375                                 cmptparm[i].sgnd = 0;
376                                 cmptparm[i].dx = subsampling_dx;
377                                 cmptparm[i].dy = subsampling_dy;
378                                 cmptparm[i].w = w;
379                                 cmptparm[i].h = h;
380                         }
381                         /* create the image */
382                         image = opj_image_create(numcomps, &cmptparm[0], color_space);
383                         if(!image) {
384                                 fclose(IN);
385                                 return NULL;
386                         }
387
388                         /* set image offset and reference grid */
389                         image->x0 = parameters->image_offset_x0;
390                         image->y0 = parameters->image_offset_y0;
391                         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
392                         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
393
394                         /* set image data */
395                         
396                         /* Place the cursor at the beginning of the image information */
397                         fseek(IN, 0, SEEK_SET);
398                         fseek(IN, File_h.bfOffBits, SEEK_SET);
399                         
400                         RGB = (unsigned char *) malloc(Info_h.biWidth * Info_h.biHeight * sizeof(unsigned char));
401             
402                         while (not_end_file) {
403                                 v = getc(IN);
404                                 if (v) {
405                                         v2 = getc(IN);
406                                         for (i = 0; i < (int) v; i++) {
407                                                 RGB[line * Info_h.biWidth + col] = v2;
408                                                 col++;
409                                         }
410                                 } else {
411                                         v = getc(IN);
412                                         switch (v) {
413                                                 case 0:
414                                                         col = 0;
415                                                         line++;
416                                                         break;
417                                                 case 1:
418                                                         line++;
419                                                         not_end_file = 0;
420                                                         break;
421                                                 case 2:
422                                                         fprintf(stderr,"No Delta supported\n");
423                                                         opj_image_destroy(image);
424                                                         fclose(IN);
425                                                         return NULL;
426                                                 default:
427                                                         for (i = 0; i < v; i++) {
428                                                                 v2 = getc(IN);
429                                                                 RGB[line * Info_h.biWidth + col] = v2;
430                                                                 col++;
431                                                         }
432                                                         if (v % 2)
433                                                                 v2 = getc(IN);
434                                                         break;
435                                         }
436                                 }
437                         }
438                         if (gray_scale) {
439                                 index = 0;
440                                 for (line = 0; line < Info_h.biHeight; line++) {
441                                         for (col = 0; col < Info_h.biWidth; col++) {
442                                                 image->comps[0].data[index] = table_R[(int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]];
443                                                 index++;
444                                         }
445                                 }
446                         } else {
447                                 index = 0;
448                                 for (line = 0; line < Info_h.biHeight; line++) {
449                                         for (col = 0; col < Info_h.biWidth; col++) {
450                                                 unsigned char pixel_index = (int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col];
451                                                 image->comps[0].data[index] = table_R[pixel_index];
452                                                 image->comps[1].data[index] = table_G[pixel_index];
453                                                 image->comps[2].data[index] = table_B[pixel_index];
454                                                 index++;
455                                         }
456                                 }
457                         }
458                         free(RGB);
459       free(table_R);
460       free(table_G);
461       free(table_B);
462         } else {
463                 fprintf(stderr, 
464                         "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount);
465         }
466         fclose(IN);
467  }
468  
469  return image;
470 }
471
472 int imagetobmp(opj_image_t * image, const char *outfile) {
473         int w, wr, h, hr;
474         int i, pad;
475         FILE *fdest = NULL;
476         int adjustR, adjustG, adjustB;
477
478         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
479                 && image->comps[1].dx == image->comps[2].dx
480                 && image->comps[0].dy == image->comps[1].dy
481                 && image->comps[1].dy == image->comps[2].dy
482                 && image->comps[0].prec == image->comps[1].prec
483                 && image->comps[1].prec == image->comps[2].prec) {
484                 
485                 /* -->> -->> -->> -->>    
486                 24 bits color       
487                 <<-- <<-- <<-- <<-- */
488             
489                 fdest = fopen(outfile, "wb");
490                 if (!fdest) {
491                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
492                         return 1;
493                 }
494             
495                 w = image->comps[0].w;
496                 wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
497             
498                 h = image->comps[0].h;
499                 hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
500             
501                 fprintf(fdest, "BM");
502             
503                 /* FILE HEADER */
504                 /* ------------- */
505                 fprintf(fdest, "%c%c%c%c",
506                         (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) + 54) & 0xff,
507                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 8) & 0xff,
508                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 16) & 0xff,
509                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 24) & 0xff);
510                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
511                 fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
512             
513                 /* INFO HEADER   */
514                 /* ------------- */
515                 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
516                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff),
517                         (unsigned char) ((wr) >> 8) & 0xff,
518                         (unsigned char) ((wr) >> 16) & 0xff,
519                         (unsigned char) ((wr) >> 24) & 0xff);
520                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff),
521                         (unsigned char) ((hr) >> 8) & 0xff,
522                         (unsigned char) ((hr) >> 16) & 0xff,
523                         (unsigned char) ((hr) >> 24) & 0xff);
524                 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
525                 fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
526                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
527                 fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * hr * wr + 3 * hr * (wr % 2)) & 0xff,
528                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 8) & 0xff,
529                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 16) & 0xff,
530                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 24) & 0xff);
531                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 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", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
534                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
535             
536                 if (image->comps[0].prec > 8) {
537                         adjustR = image->comps[0].prec - 8;
538                         printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
539                 }
540                 else 
541                         adjustR = 0;
542                 if (image->comps[1].prec > 8) {
543                         adjustG = image->comps[1].prec - 8;
544                         printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
545                 }
546                 else 
547                         adjustG = 0;
548                 if (image->comps[2].prec > 8) {
549                         adjustB = image->comps[2].prec - 8;
550                         printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
551                 }
552                 else 
553                         adjustB = 0;
554
555                 for (i = 0; i < wr * hr; i++) {
556                         unsigned char rc, gc, bc;
557                         int r, g, b;
558                                                         
559                         r = image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
560                         r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
561                         rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2));
562                         g = image->comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
563                         g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
564                         gc = (unsigned char) ((g >> adjustG)+((g >> (adjustG-1))%2));
565                         b = image->comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
566                         b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
567                         bc = (unsigned char) ((b >> adjustB)+((b >> (adjustB-1))%2));
568
569                         fprintf(fdest, "%c%c%c", bc, gc, rc);
570                         
571                         if ((i + 1) % wr == 0) {
572                                 for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--) /* ADD */
573                                         fprintf(fdest, "%c", 0);
574                         }
575                 }
576                 fclose(fdest);
577         } else {                        /* Gray-scale */
578
579                 /* -->> -->> -->> -->>
580                 8 bits non code (Gray scale)
581                 <<-- <<-- <<-- <<-- */
582
583                 fdest = fopen(outfile, "wb");
584                 w = image->comps[0].w;
585                 wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
586             
587                 h = image->comps[0].h;
588                 hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
589             
590                 fprintf(fdest, "BM");
591             
592                 /* FILE HEADER */
593                 /* ------------- */
594                 fprintf(fdest, "%c%c%c%c", (unsigned char) (hr * wr + 54 + 1024 + hr * (wr % 2)) & 0xff,
595                         (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) >> 8) & 0xff,
596                         (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) >> 16) & 0xff,
597                         (unsigned char) ((hr * wr + 54 + 1024 + wr * (wr % 2)) >> 24) & 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", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff, 
600                         ((54 + 1024) >> 16) & 0xff,
601                         ((54 + 1024) >> 24) & 0xff);
602             
603                 /* INFO HEADER */
604                 /* ------------- */
605                 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
606                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff),
607                         (unsigned char) ((wr) >> 8) & 0xff,
608                         (unsigned char) ((wr) >> 16) & 0xff,
609                         (unsigned char) ((wr) >> 24) & 0xff);
610                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff),
611                         (unsigned char) ((hr) >> 8) & 0xff,
612                         (unsigned char) ((hr) >> 16) & 0xff,
613                         (unsigned char) ((hr) >> 24) & 0xff);
614                 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
615                 fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
616                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
617                 fprintf(fdest, "%c%c%c%c", (unsigned char) (hr * wr + hr * (wr % 2)) & 0xff,
618                         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 8) &      0xff,
619                         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 16) &     0xff,
620                         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 24) & 0xff);
621                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
622                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
623                 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
624                 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
625
626                 if (image->comps[0].prec > 8) {
627                         adjustR = image->comps[0].prec - 8;
628                         printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
629                 }
630
631                 for (i = 0; i < 256; i++) {
632                         fprintf(fdest, "%c%c%c%c", i, i, i, 0);
633                 }
634
635                 for (i = 0; i < wr * hr; i++) {
636                         unsigned char rc;
637                         int r;
638                         
639                         r = image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
640                         r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
641                         rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2));
642                         
643                         fprintf(fdest, "%c", rc);
644
645                         if ((i + 1) % wr == 0) {
646                                 for (pad = wr % 4 ? 4 - wr % 4 : 0; pad > 0; pad--)     /* ADD */
647                                         fprintf(fdest, "%c", 0);
648                         }
649                 }
650                 fclose(fdest);
651         }
652
653         return 0;
654 }
655
656 /* -->> -->> -->> -->>
657
658 PGX IMAGE FORMAT
659
660 <<-- <<-- <<-- <<-- */
661
662
663 unsigned char readuchar(FILE * f)
664 {
665   unsigned char c1;
666   fread(&c1, 1, 1, f);
667   return c1;
668 }
669
670 unsigned short readushort(FILE * f, int bigendian)
671 {
672   unsigned char c1, c2;
673   fread(&c1, 1, 1, f);
674   fread(&c2, 1, 1, f);
675   if (bigendian)
676     return (c1 << 8) + c2;
677   else
678     return (c2 << 8) + c1;
679 }
680
681 unsigned int readuint(FILE * f, int bigendian)
682 {
683   unsigned char c1, c2, c3, c4;
684   fread(&c1, 1, 1, f);
685   fread(&c2, 1, 1, f);
686   fread(&c3, 1, 1, f);
687   fread(&c4, 1, 1, f);
688   if (bigendian)
689     return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
690   else
691     return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1;
692 }
693
694 opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) {
695         FILE *f = NULL;
696         int w, h, prec;
697         int i, numcomps, max;
698         OPJ_COLOR_SPACE color_space;
699         opj_image_cmptparm_t cmptparm;  /* maximum of 1 component  */
700         opj_image_t * image = NULL;
701
702         char endian1,endian2,sign;
703         char signtmp[32];
704
705         char temp[32];
706         int bigendian;
707         opj_image_comp_t *comp = NULL;
708
709         numcomps = 1;
710         color_space = CLRSPC_GRAY;
711
712         memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t));
713
714         max = 0;
715
716         f = fopen(filename, "rb");
717         if (!f) {
718           fprintf(stderr, "Failed to open %s for reading !\n", filename);
719           return NULL;
720         }
721
722         fseek(f, 0, SEEK_SET);
723         fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h);
724         
725         i=0;
726         sign='+';               
727         while (signtmp[i]!='\0') {
728                 if (signtmp[i]=='-') sign='-';
729                 i++;
730         }
731         
732         fgetc(f);
733         if (endian1=='M' && endian2=='L') {
734                 bigendian = 1;
735         } else if (endian2=='M' && endian1=='L') {
736                 bigendian = 0;
737         } else {
738                 fprintf(stderr, "Bad pgx header, please check input file\n");
739                 return NULL;
740         }
741
742         /* initialize image component */
743
744         cmptparm.x0 = parameters->image_offset_x0;
745         cmptparm.y0 = parameters->image_offset_y0;
746         cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1;
747         cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1;
748         
749         if (sign == '-') {
750                 cmptparm.sgnd = 1;
751         } else {
752                 cmptparm.sgnd = 0;
753         }
754         cmptparm.prec = prec;
755         cmptparm.bpp = prec;
756         cmptparm.dx = parameters->subsampling_dx;
757         cmptparm.dy = parameters->subsampling_dy;
758         
759         /* create the image */
760         image = opj_image_create(numcomps, &cmptparm, color_space);
761         if(!image) {
762                 fclose(f);
763                 return NULL;
764         }
765         /* set image offset and reference grid */
766         image->x0 = cmptparm.x0;
767         image->y0 = cmptparm.x0;
768         image->x1 = cmptparm.w;
769         image->y1 = cmptparm.h;
770
771         /* set image data */
772
773         comp = &image->comps[0];
774
775         for (i = 0; i < w * h; i++) {
776                 int v;
777                 if (comp->prec <= 8) {
778                         if (!comp->sgnd) {
779                                 v = readuchar(f);
780                         } else {
781                                 v = (char) readuchar(f);
782                         }
783                 } else if (comp->prec <= 16) {
784                         if (!comp->sgnd) {
785                                 v = readushort(f, bigendian);
786                         } else {
787                                 v = (short) readushort(f, bigendian);
788                         }
789                 } else {
790                         if (!comp->sgnd) {
791                                 v = readuint(f, bigendian);
792                         } else {
793                                 v = (int) readuint(f, bigendian);
794                         }
795                 }
796                 if (v > max)
797                         max = v;
798                 comp->data[i] = v;
799         }
800         fclose(f);
801         comp->bpp = int_floorlog2(max) + 1;
802
803         return image;
804 }
805
806 int imagetopgx(opj_image_t * image, const char *outfile) {
807         int w, wr, h, hr;
808         int i, j, compno;
809         FILE *fdest = NULL;
810
811         for (compno = 0; compno < image->numcomps; compno++) {
812                 opj_image_comp_t *comp = &image->comps[compno];
813                 char bname[256]; /* buffer for name */
814     char *name = bname; /* pointer */
815     int nbytes = 0;
816     const size_t olen = strlen(outfile);
817     const size_t dotpos = olen - 4;
818     const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */
819     if( outfile[dotpos] != '.' ) {
820       /* `pgx` was recognized but there is no dot at expected position */
821       fprintf(stderr, "ERROR -> Impossible happen." );
822       return 1;
823       }
824     if( total > 256 ) {
825       name = (char*)malloc(total+1);
826       }
827     strncpy(name, outfile, dotpos);
828                 if (image->numcomps > 1) {
829                         sprintf(name+dotpos, "-%d.pgx", compno);
830                 } else {
831                         strcpy(name+dotpos, ".pgx");
832                 }
833                 fdest = fopen(name, "wb");
834                 if (!fdest) {
835                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
836                         return 1;
837                 }
838     /* dont need name anymore */
839     if( total > 256 ) {
840       free(name);
841       }
842
843                 w = image->comps[compno].w;
844                 wr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);
845             
846                 h = image->comps[compno].h;
847                 hr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);
848             
849                 fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, wr, hr);
850                 if (comp->prec <= 8) {
851                         nbytes = 1;
852                 } else if (comp->prec <= 16) {
853                         nbytes = 2;
854                 } else {
855                         nbytes = 4;
856                 }
857                 for (i = 0; i < wr * hr; i++) {
858                         int v = image->comps[compno].data[i / wr * w + i % wr];
859                         for (j = nbytes - 1; j >= 0; j--) {
860                                 char byte = (char) (v >> (j * 8));
861                                 fwrite(&byte, 1, 1, fdest);
862                         }
863                 }
864                 fclose(fdest);
865         }
866
867         return 0;
868 }
869
870 /* -->> -->> -->> -->>
871
872 PNM IMAGE FORMAT
873
874 <<-- <<-- <<-- <<-- */
875
876 opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) {
877         int subsampling_dx = parameters->subsampling_dx;
878         int subsampling_dy = parameters->subsampling_dy;
879
880         FILE *f = NULL;
881         int i, compno, numcomps, w, h;
882         OPJ_COLOR_SPACE color_space;
883         opj_image_cmptparm_t cmptparm[3];       /* maximum of 3 components */
884         opj_image_t * image = NULL;
885         char value;
886         
887         f = fopen(filename, "rb");
888         if (!f) {
889                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
890                 return 0;
891         }
892
893         if (fgetc(f) != 'P')
894                 return 0;
895         value = fgetc(f);
896
897                 switch(value) {
898                         case '2':       /* greyscale image type */
899                         case '5':
900                                 numcomps = 1;
901                                 color_space = CLRSPC_GRAY;
902                                 break;
903                                 
904                         case '3':       /* RGB image type */
905                         case '6':
906                                 numcomps = 3;
907                                 color_space = CLRSPC_SRGB;
908                                 break;
909                                 
910                         default:
911                                 fclose(f);
912                                 return NULL;
913                 }
914                 
915                 fgetc(f);
916                 
917                 /* skip comments */
918                 while(fgetc(f) == '#') while(fgetc(f) != '\n');
919                 
920                 fseek(f, -1, SEEK_CUR);
921                 fscanf(f, "%d %d\n255", &w, &h);                        
922                 fgetc(f);       /* <cr><lf> */
923                 
924         /* initialize image components */
925         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
926         for(i = 0; i < numcomps; i++) {
927                 cmptparm[i].prec = 8;
928                 cmptparm[i].bpp = 8;
929                 cmptparm[i].sgnd = 0;
930                 cmptparm[i].dx = subsampling_dx;
931                 cmptparm[i].dy = subsampling_dy;
932                 cmptparm[i].w = w;
933                 cmptparm[i].h = h;
934         }
935         /* create the image */
936         image = opj_image_create(numcomps, &cmptparm[0], color_space);
937         if(!image) {
938                 fclose(f);
939                 return NULL;
940         }
941
942         /* set image offset and reference grid */
943         image->x0 = parameters->image_offset_x0;
944         image->y0 = parameters->image_offset_y0;
945         image->x1 = parameters->image_offset_x0 + (w - 1) *     subsampling_dx + 1;
946         image->y1 = parameters->image_offset_y0 + (h - 1) *     subsampling_dy + 1;
947
948         /* set image data */
949
950         if ((value == '2') || (value == '3')) { /* ASCII */
951                 for (i = 0; i < w * h; i++) {
952                         for(compno = 0; compno < numcomps; compno++) {
953                                 unsigned int index = 0;
954                                 fscanf(f, "%u", &index);
955                                 /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
956                                 image->comps[compno].data[i] = index;
957                         }
958                 }
959         } else if ((value == '5') || (value == '6')) {  /* BINARY */
960                 for (i = 0; i < w * h; i++) {
961                         for(compno = 0; compno < numcomps; compno++) {
962                                 unsigned char index = 0;
963                                 fread(&index, 1, 1, f);
964                                 /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
965                                 image->comps[compno].data[i] = index;
966                         }
967                 }
968         }
969
970         fclose(f);
971
972         return image;
973 }
974
975 int imagetopnm(opj_image_t * image, const char *outfile) {
976         int w, wr, wrr, h, hr, hrr, max;
977         int i, compno;
978         int adjustR, adjustG, adjustB, adjustX;
979         FILE *fdest = NULL;
980         char S2;
981         const char *tmp = outfile;
982
983         while (*tmp) {
984                 tmp++;
985         }
986         tmp--;
987         tmp--;
988         S2 = *tmp;
989
990         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
991                 && image->comps[1].dx == image->comps[2].dx
992                 && image->comps[0].dy == image->comps[1].dy
993                 && image->comps[1].dy == image->comps[2].dy
994                 && image->comps[0].prec == image->comps[1].prec
995                 && image->comps[1].prec == image->comps[2].prec
996                 && S2 !='g' && S2 !='G') {
997
998                 fdest = fopen(outfile, "wb");
999                 if (!fdest) {
1000                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1001                         return 1;
1002                 }
1003
1004                 w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
1005                 wr = image->comps[0].w;
1006                 wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
1007         
1008                 h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
1009                 hr = image->comps[0].h;
1010                 hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
1011             
1012                 max = image->comps[0].prec > 8 ? 255 : (1 << image->comps[0].prec) - 1;
1013             
1014                 image->comps[0].x0 = int_ceildivpow2(image->comps[0].x0 - int_ceildiv(image->x0, image->comps[0].dx), image->comps[0].factor);
1015                 image->comps[0].y0 = int_ceildivpow2(image->comps[0].y0 -       int_ceildiv(image->y0, image->comps[0].dy), image->comps[0].factor);
1016
1017                 fprintf(fdest, "P6\n%d %d\n%d\n", wrr, hrr, max);
1018
1019                 if (image->comps[0].prec > 8) {
1020                         adjustR = image->comps[0].prec - 8;
1021                         printf("PNM CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
1022                 }
1023                 else 
1024                         adjustR = 0;
1025                 if (image->comps[1].prec > 8) {
1026                         adjustG = image->comps[1].prec - 8;
1027                         printf("PNM CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
1028                 }
1029                 else 
1030                         adjustG = 0;
1031                 if (image->comps[2].prec > 8) {
1032                         adjustB = image->comps[2].prec - 8;
1033                         printf("PNM CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
1034                 }
1035                 else 
1036                         adjustB = 0;
1037
1038
1039                 for (i = 0; i < wrr * hrr; i++) {
1040                         int r, g, b;
1041                         unsigned char rc,gc,bc;
1042                         r = image->comps[0].data[i / wrr * wr + i % wrr];
1043                         r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
1044                         rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2));
1045
1046                         g = image->comps[1].data[i / wrr * wr + i % wrr];
1047                         g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
1048                         gc = (unsigned char) ((g >> adjustG)+((g >> (adjustG-1))%2));
1049                         
1050                         b = image->comps[2].data[i / wrr * wr + i % wrr];
1051                         b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
1052                         bc = (unsigned char) ((b >> adjustB)+((b >> (adjustB-1))%2));
1053                         
1054                         fprintf(fdest, "%c%c%c", rc, gc, bc);
1055                 }
1056                 fclose(fdest);
1057
1058         } else {
1059                 int ncomp=(S2=='g' || S2=='G')?1:image->numcomps;
1060                 if (image->numcomps > ncomp) {
1061                         fprintf(stderr,"WARNING -> [PGM files] Only the first component\n");
1062                         fprintf(stderr,"           is written to the file\n");
1063                 }
1064                 for (compno = 0; compno < ncomp; compno++) {
1065                         char name[256];
1066                         if (ncomp > 1) {
1067                                 sprintf(name, "%d.%s", compno, outfile);
1068                         } else {
1069                                 sprintf(name, "%s", outfile);
1070                         }
1071                         
1072                         fdest = fopen(name, "wb");
1073                         if (!fdest) {
1074                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
1075                                 return 1;
1076                         }
1077             
1078                         w = int_ceildiv(image->x1 - image->x0, image->comps[compno].dx);
1079                         wr = image->comps[compno].w;
1080                         wrr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);
1081                         
1082                         h = int_ceildiv(image->y1 - image->y0, image->comps[compno].dy);
1083                         hr = image->comps[compno].h;
1084                         hrr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);
1085                         
1086                         max = image->comps[compno].prec > 8 ? 255 : (1 << image->comps[compno].prec) - 1;
1087                         
1088                         image->comps[compno].x0 = int_ceildivpow2(image->comps[compno].x0 - int_ceildiv(image->x0, image->comps[compno].dx), image->comps[compno].factor);
1089                         image->comps[compno].y0 = int_ceildivpow2(image->comps[compno].y0 - int_ceildiv(image->y0, image->comps[compno].dy), image->comps[compno].factor);
1090                         
1091                         fprintf(fdest, "P5\n%d %d\n%d\n", wrr, hrr, max);
1092                         
1093                         if (image->comps[compno].prec > 8) {
1094                                 adjustX = image->comps[0].prec - 8;
1095                                 printf("PNM CONVERSION: Truncating component %d from %d bits to 8 bits\n",compno, image->comps[compno].prec);
1096                         }
1097                         else 
1098                                 adjustX = 0;
1099                         
1100                         for (i = 0; i < wrr * hrr; i++) {
1101                                 int l;
1102                                 unsigned char lc;
1103                                 l = image->comps[compno].data[i / wrr * wr + i % wrr];
1104                                 l += (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0);
1105                                 lc = (unsigned char) ((l >> adjustX)+((l >> (adjustX-1))%2));
1106                                 fprintf(fdest, "%c", lc);
1107                         }
1108                         fclose(fdest);
1109                 }
1110         }
1111
1112         return 0;
1113 }
1114
1115 /* -->> -->> -->> -->>
1116
1117         TIFF IMAGE FORMAT
1118
1119  <<-- <<-- <<-- <<-- */
1120
1121 typedef struct tiff_infoheader{
1122         DWORD tiWidth;  // Width of Image in pixel
1123         DWORD tiHeight; // Height of Image in pixel
1124         DWORD tiPhoto;  // Photometric
1125         WORD  tiBps;    // Bits per sample
1126         WORD  tiSf;             // Sample Format
1127         WORD  tiSpp;    // Sample per pixel 1-bilevel,gray scale , 2- RGB
1128         WORD  tiPC;     // Planar config (1-Interleaved, 2-Planarcomp)
1129 }tiff_infoheader_t;
1130
1131 int imagetotif(opj_image_t * image, const char *outfile) {
1132         int width, height;
1133         int bps,index;
1134         TIFF *tif;
1135         tdata_t buf;
1136         tstrip_t strip;
1137         tsize_t strip_size;
1138
1139         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
1140                 && image->comps[1].dx == image->comps[2].dx
1141                 && image->comps[0].dy == image->comps[1].dy
1142                 && image->comps[1].dy == image->comps[2].dy
1143                 && image->comps[0].prec == image->comps[1].prec
1144                 && image->comps[1].prec == image->comps[2].prec) {
1145
1146                         /* -->> -->> -->>    
1147                         RGB color           
1148                         <<-- <<-- <<-- */
1149
1150                         tif = TIFFOpen(outfile, "wb"); 
1151                         if (!tif) {
1152                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1153                                 return 1;
1154                         }
1155
1156                         width   = image->comps[0].w;
1157                         height= image->comps[0].h;
1158                         bps             = image->comps[0].prec;
1159                         /* Set tags */
1160                         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
1161                         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
1162                         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
1163                         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
1164                         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
1165                         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1166                         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
1167                         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
1168
1169                         /* Get a buffer for the data */
1170                         buf = _TIFFmalloc(TIFFStripSize(tif));
1171                         index=0;
1172                         strip_size=0;
1173                         strip_size=TIFFStripSize(tif);
1174                         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1175                                 unsigned char *dat8;
1176                                 int i;
1177                                 dat8 = buf;
1178                                 if (image->comps[0].prec == 8){
1179                                         for (i=0; i<TIFFStripSize(tif); i+=3) { // 8 bits per pixel 
1180                                                 dat8[i+0] = image->comps[0].data[index] ;       // R 
1181                                                 dat8[i+1] = image->comps[1].data[index] ;       // G 
1182                                                 dat8[i+2] = image->comps[2].data[index] ;       // B 
1183                                                 index++;
1184                                         }
1185                                 }else if (image->comps[0].prec == 12){
1186                                         for (i=0; i<TIFFStripSize(tif); i+=9) { // 12 bits per pixel 
1187                                                 dat8[i+0] = (image->comps[0].data[index]>>8)<<4 | (image->comps[0].data[index]>>4);
1188                                                 dat8[i+1] = (image->comps[0].data[index]<<4)|((image->comps[1].data[index]>>8)& 0x0f);
1189                                                 dat8[i+2] = (image->comps[1].data[index]);
1190                                                 dat8[i+3] = (image->comps[2].data[index]>>8)<<4 | (image->comps[2].data[index]>>4);
1191                                                 dat8[i+4] = (image->comps[2].data[index]<<4)|((image->comps[0].data[index+1]>>8)& 0x0f);
1192                                                 dat8[i+5] = (image->comps[0].data[index+1]);
1193                                                 dat8[i+6] = (image->comps[1].data[index+1]>>8)<<4 | (image->comps[1].data[index+1]>>4);
1194                                                 dat8[i+7] = (image->comps[1].data[index+1]<<4)|((image->comps[2].data[index+1]>>8)& 0x0f);
1195                                                 dat8[i+8] = (image->comps[2].data[index+1]);
1196                                                 index+=2;
1197                                         }
1198                                 }else if (image->comps[0].prec == 16){
1199                                         for (i=0; i<TIFFStripSize(tif); i+=6) { // 16 bits per pixel 
1200                                                 dat8[i+0] =  image->comps[0].data[index];//LSB
1201                                                 dat8[i+1] = (image->comps[0].data[index]>> 8);//MSB      
1202                                                 dat8[i+2] =  image->comps[1].data[index]; 
1203                                                 dat8[i+3] = (image->comps[1].data[index]>> 8);  
1204                                                 dat8[i+4] =  image->comps[2].data[index];        
1205                                                 dat8[i+5] = (image->comps[2].data[index]>> 8); 
1206                                                 index++;
1207                                         }
1208                                 }else{
1209                                         fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec);
1210                                         fprintf(stderr,"Aborting\n");
1211                                         return 1;
1212                                 }
1213                                 TIFFWriteEncodedStrip(tif, strip, buf, strip_size);
1214                         }
1215                         _TIFFfree(buf);
1216                         TIFFClose(tif);
1217                 }else if (image->numcomps == 1){
1218                         /* -->> -->> -->>    
1219                         Black and White     
1220                         <<-- <<-- <<-- */
1221
1222                         tif = TIFFOpen(outfile, "wb"); 
1223                         if (!tif) {
1224                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1225                                 return 1;
1226                         }
1227
1228                         width   = image->comps[0].w;
1229                         height= image->comps[0].h;
1230                         bps             = image->comps[0].prec;
1231
1232                         /* Set tags */
1233                         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
1234                         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
1235                         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
1236                         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
1237                         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
1238                         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1239                         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
1240                         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
1241
1242                         /* Get a buffer for the data */
1243                         buf = _TIFFmalloc(TIFFStripSize(tif));
1244                         index = 0;
1245                         strip_size = 0;
1246                         strip_size = TIFFStripSize(tif);
1247                         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1248                                 unsigned char *dat8;
1249                                 int i;
1250                                 dat8 = buf;
1251                                 if (image->comps[0].prec == 8){
1252                                         for (i=0; i<TIFFStripSize(tif); i+=1) { // 8 bits per pixel 
1253                                                 dat8[i+0] = image->comps[0].data[index] ;
1254                                                 index++;
1255                                         }
1256                                 }else if (image->comps[0].prec == 12){
1257                                         for (i = 0; i<TIFFStripSize(tif); i+=3) {       // 12 bits per pixel 
1258                                                 dat8[i+0] = (image->comps[0].data[index]>>8)<<4 | (image->comps[0].data[index]>>4);
1259                                                 dat8[i+1] = (image->comps[0].data[index]<<4)|((image->comps[0].data[index+1]>>8)& 0x0f);
1260                                                 dat8[i+2] = (image->comps[0].data[index+1]);
1261                                                 index+=2;
1262                                         }
1263                                 }else if (image->comps[0].prec == 16){
1264                                         for (i=0; i<TIFFStripSize(tif); i+=2) { // 16 bits per pixel 
1265                                                 dat8[i+0] =  image->comps[0].data[index];
1266                                                 dat8[i+1] = (image->comps[0].data[index]>> 8);
1267                                                 index++;
1268                                         }
1269                                 }else{
1270                                         fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec);
1271                                         fprintf(stderr,"Aborting\n");
1272                                         return 1;
1273                                 }
1274                                 TIFFWriteEncodedStrip(tif, strip, buf, strip_size);
1275                         }
1276                         _TIFFfree(buf);
1277                         TIFFClose(tif);
1278                 }else{
1279                         fprintf(stderr,"False color format. Only RGB & Grayscale has been implemented\n");
1280                         fprintf(stderr,"Aborting\n");
1281                         return 1;
1282                 }
1283                 return 0;
1284 }
1285
1286 opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
1287 {
1288         int subsampling_dx = parameters->subsampling_dx;
1289         int subsampling_dy = parameters->subsampling_dy;
1290         TIFF *tif;
1291         tiff_infoheader_t Info;
1292         tdata_t buf;
1293         tstrip_t strip;
1294         tsize_t strip_size;
1295         int j, numcomps, w, h,index;
1296         OPJ_COLOR_SPACE color_space;
1297         opj_image_cmptparm_t cmptparm[3];
1298         opj_image_t * image = NULL;
1299
1300         tif = TIFFOpen(filename, "r");
1301
1302         if (!tif) {
1303                 fprintf(stderr, "Failed to open %s for reading\n", filename);
1304                 return 0;
1305         }
1306
1307         TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &Info.tiWidth);
1308         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &Info.tiHeight);
1309         TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &Info.tiBps);
1310         TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &Info.tiSf);
1311         TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &Info.tiSpp);
1312         Info.tiPhoto = 0;
1313         TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &Info.tiPhoto);
1314         TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &Info.tiPC);
1315         w= Info.tiWidth;
1316         h= Info.tiHeight;
1317         
1318         if (Info.tiPhoto == 2) { 
1319                 /* -->> -->> -->>    
1320                 RGB color           
1321                 <<-- <<-- <<-- */
1322
1323                 numcomps = 3;
1324                 color_space = CLRSPC_SRGB;
1325                 /* initialize image components*/ 
1326                 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
1327                 for(j = 0; j < numcomps; j++) {
1328                         if (parameters->cp_cinema) {
1329                                 cmptparm[j].prec = 12;
1330                                 cmptparm[j].bpp = 12;
1331                         }else{
1332                                 cmptparm[j].prec = Info.tiBps;
1333                                 cmptparm[j].bpp = Info.tiBps;
1334                         }
1335                         cmptparm[j].sgnd = 0;
1336                         cmptparm[j].dx = subsampling_dx;
1337                         cmptparm[j].dy = subsampling_dy;
1338                         cmptparm[j].w = w;
1339                         cmptparm[j].h = h;
1340                 }
1341                 /* create the image*/ 
1342                 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1343                 if(!image) {
1344                         TIFFClose(tif);
1345                         return NULL;
1346                 }
1347
1348                 /* set image offset and reference grid */
1349                 image->x0 = parameters->image_offset_x0;
1350                 image->y0 = parameters->image_offset_y0;
1351                 image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
1352                 image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
1353
1354                 buf = _TIFFmalloc(TIFFStripSize(tif));
1355                 strip_size=0;
1356                 strip_size=TIFFStripSize(tif);
1357                 index = 0;
1358                 /* Read the Image components*/
1359                 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1360                         unsigned char *dat8;
1361                         int i, ssize;
1362                         ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
1363                         dat8 = buf;
1364
1365                         if (Info.tiBps==12){
1366                                 for (i=0; i<ssize; i+=9) {      /*12 bits per pixel*/
1367                                         image->comps[0].data[index]   = ( dat8[i+0]<<4 )                |(dat8[i+1]>>4);
1368                                         image->comps[1].data[index]   = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2];
1369                                         image->comps[2].data[index]   = ( dat8[i+3]<<4)                 |(dat8[i+4]>>4);
1370                                         image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5];
1371                                         image->comps[1].data[index+1] = ( dat8[i+6] <<4)                |(dat8[i+7]>>4);
1372                                         image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8];
1373                                         index+=2;
1374                                 }
1375                         }
1376                         else if( Info.tiBps==16){
1377                                 for (i=0; i<ssize; i+=6) {      /* 16 bits per pixel */
1378                                         image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0];   // R 
1379                                         image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2];   // G 
1380                                         image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4];   // B 
1381                                         if(parameters->cp_cinema){/* Rounding to 12 bits*/
1382                                                 image->comps[0].data[index] = (image->comps[0].data[index] + 0x08) >> 4 ;
1383                                                 image->comps[1].data[index] = (image->comps[1].data[index] + 0x08) >> 4 ;
1384                                                 image->comps[2].data[index] = (image->comps[2].data[index] + 0x08) >> 4 ;
1385                                         }
1386                                         index++;
1387                                 }
1388                         }
1389                         else if ( Info.tiBps==8){
1390                                 for (i=0; i<ssize; i+=3) {      /* 8 bits per pixel */
1391                                         image->comps[0].data[index] = dat8[i+0];        // R 
1392                                         image->comps[1].data[index] = dat8[i+1];        // G 
1393                                         image->comps[2].data[index] = dat8[i+2];        // B 
1394                                         if(parameters->cp_cinema){/* Rounding to 12 bits*/
1395                                                 image->comps[0].data[index] = image->comps[0].data[index] << 4 ;
1396                                                 image->comps[1].data[index] = image->comps[1].data[index] << 4 ;
1397                                                 image->comps[2].data[index] = image->comps[2].data[index] << 4 ;
1398                                         }
1399                                         index++;
1400                                 }
1401                         }
1402                         else{
1403                                 fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps);
1404                                 fprintf(stderr,"Aborting\n");
1405                                 return NULL;
1406                         }
1407                 }
1408
1409                 _TIFFfree(buf);
1410                 TIFFClose(tif);
1411         }else if(Info.tiPhoto == 1) { 
1412                 /* -->> -->> -->>    
1413                 Black and White
1414                 <<-- <<-- <<-- */
1415
1416                 numcomps = 1;
1417                 color_space = CLRSPC_GRAY;
1418                 /* initialize image components*/ 
1419                 memset(&cmptparm[0], 0, sizeof(opj_image_cmptparm_t));
1420                 cmptparm[0].prec = Info.tiBps;
1421                 cmptparm[0].bpp = Info.tiBps;
1422                 cmptparm[0].sgnd = 0;
1423                 cmptparm[0].dx = subsampling_dx;
1424                 cmptparm[0].dy = subsampling_dy;
1425                 cmptparm[0].w = w;
1426                 cmptparm[0].h = h;
1427
1428                 /* create the image*/ 
1429                 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1430                 if(!image) {
1431                         TIFFClose(tif);
1432                         return NULL;
1433                 }
1434                 /* set image offset and reference grid */
1435                 image->x0 = parameters->image_offset_x0;
1436                 image->y0 = parameters->image_offset_y0;
1437                 image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
1438                 image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
1439
1440                 buf = _TIFFmalloc(TIFFStripSize(tif));
1441                 strip_size = 0;
1442                 strip_size = TIFFStripSize(tif);
1443                 index = 0;
1444                 /* Read the Image components*/
1445                 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1446                         unsigned char *dat8;
1447                         int i, ssize;
1448                         ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
1449                         dat8 = buf;
1450
1451                         if (Info.tiBps==12){
1452                                 for (i=0; i<ssize; i+=3) {      /* 12 bits per pixel*/
1453                                         image->comps[0].data[index] = ( dat8[i+0]<<4 )                          |(dat8[i+1]>>4) ;
1454                                         image->comps[0].data[index] = ((dat8[i+1]& 0x0f)<< 8)   | dat8[i+2];
1455                                         index+=2;
1456                                 }
1457                         }
1458                         else if( Info.tiBps==16){
1459                                 for (i=0; i<ssize; i+=2) {      /* 16 bits per pixel */
1460                                         image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0];
1461                                         index++;
1462                                 }
1463                         }
1464                         else if ( Info.tiBps==8){
1465                                 for (i=0; i<ssize; i+=1) {      /* 8 bits per pixel */
1466                                         image->comps[0].data[index] = dat8[i+0];
1467                                         index++;
1468                                 }
1469                         }
1470                         else{
1471                                 fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps);
1472                                 fprintf(stderr,"Aborting\n");
1473                                 return NULL;
1474                         }
1475                 }
1476
1477                 _TIFFfree(buf);
1478                 TIFFClose(tif);
1479         }else{
1480                 fprintf(stderr,"False color format. Only RGB & Grayscale has been implemented\n");
1481                 fprintf(stderr,"Aborting\n");
1482                 return NULL;
1483         }
1484         return image;
1485 }
1486
1487 /* -->> -->> -->> -->>
1488
1489         RAW IMAGE FORMAT
1490
1491  <<-- <<-- <<-- <<-- */
1492
1493 opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) {
1494         int subsampling_dx = parameters->subsampling_dx;
1495         int subsampling_dy = parameters->subsampling_dy;
1496
1497         FILE *f = NULL;
1498         int i, compno, numcomps, w, h;
1499         OPJ_COLOR_SPACE color_space;
1500         opj_image_cmptparm_t *cmptparm; 
1501         opj_image_t * image = NULL;
1502         unsigned short ch;
1503         
1504         if((raw_cp->rawWidth * raw_cp->rawHeight * raw_cp->rawComp * raw_cp->rawBitDepth) == 0)
1505         {
1506                 fprintf(stderr,"\nError: invalid raw image parameters\n");
1507                 fprintf(stderr,"Please use the Format option -F:\n");
1508                 fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
1509                 fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n");
1510                 fprintf(stderr,"Aborting\n");
1511                 return NULL;
1512         }
1513
1514         f = fopen(filename, "rb");
1515         if (!f) {
1516                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
1517                 fprintf(stderr,"Aborting\n");
1518                 return NULL;
1519         }
1520         numcomps = raw_cp->rawComp;
1521         color_space = CLRSPC_SRGB;
1522         w = raw_cp->rawWidth;
1523         h = raw_cp->rawHeight;
1524         cmptparm = (opj_image_cmptparm_t*) malloc(numcomps * sizeof(opj_image_cmptparm_t));
1525         
1526         /* initialize image components */       
1527         memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
1528         for(i = 0; i < numcomps; i++) {         
1529                 cmptparm[i].prec = raw_cp->rawBitDepth;
1530                 cmptparm[i].bpp = raw_cp->rawBitDepth;
1531                 cmptparm[i].sgnd = raw_cp->rawSigned;
1532                 cmptparm[i].dx = subsampling_dx;
1533                 cmptparm[i].dy = subsampling_dy;
1534                 cmptparm[i].w = w;
1535                 cmptparm[i].h = h;
1536         }
1537         /* create the image */
1538         image = opj_image_create(numcomps, &cmptparm[0], color_space);
1539         if(!image) {
1540                 fclose(f);
1541                 return NULL;
1542         }
1543
1544         /* set image offset and reference grid */
1545         image->x0 = parameters->image_offset_x0;
1546         image->y0 = parameters->image_offset_y0;
1547         image->x1 = parameters->image_offset_x0 + (w - 1) *     subsampling_dx + 1;
1548         image->y1 = parameters->image_offset_y0 + (h - 1) *     subsampling_dy + 1;
1549
1550         if(raw_cp->rawBitDepth <= 8)
1551         {
1552                 unsigned char value = 0;
1553                 for(compno = 0; compno < numcomps; compno++) {
1554                         for (i = 0; i < w * h; i++) {
1555                                 if (!fread(&value, 1, 1, f)) {
1556                                         fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
1557                                         return NULL;
1558                                 }
1559                                 image->comps[compno].data[i] = raw_cp->rawSigned?(char)value:value;
1560                         }
1561                 }
1562         }
1563         else
1564         {
1565                 unsigned short value = 0;
1566                 for(compno = 0; compno < numcomps; compno++) {
1567                         for (i = 0; i < w * h; i++) {
1568                                 if (!fread(&value, 2, 1, f)) {
1569                                         fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
1570                                         return NULL;
1571                                 }
1572                                 image->comps[compno].data[i] = raw_cp->rawSigned?(short)value:value;
1573                         }
1574                 }
1575         }
1576
1577         if (fread(&ch, 1, 1, f)) {
1578                 fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n");
1579         }
1580
1581         fclose(f);
1582
1583         return image;
1584 }
1585
1586 int imagetoraw(opj_image_t * image, const char *outfile)
1587 {
1588         FILE *rawFile = NULL;
1589         int compno, pixelsToWrite, offset, cont;
1590
1591         if((image->numcomps * image->x1 * image->y1) == 0)
1592         {
1593                 fprintf(stderr,"\nError: invalid raw image parameters\n");
1594                 return 1;
1595         }
1596
1597         rawFile = fopen(outfile, "wb");
1598         if (!rawFile) {
1599                 fprintf(stderr, "Failed to open %s for writing !!\n", outfile);
1600                 return 1;
1601         }
1602
1603         fprintf(stdout,"Raw image characteristics: %d components\n", image->numcomps);
1604
1605         for(compno = 0; compno < image->numcomps; compno++)
1606         {
1607                 fprintf(stdout,"Component %d characteristics: %dx%dx%d %s\n", compno, image->comps[compno].w,
1608                         image->comps[compno].h, image->comps[compno].prec, image->comps[compno].sgnd==1 ? "signed": "unsigned");
1609
1610                 pixelsToWrite = image->comps[compno].w * image->comps[compno].h;
1611                 offset = 0;
1612
1613                 if(image->comps[compno].prec <= 8)
1614                 {
1615                         if(image->comps[compno].sgnd == 1)
1616                         {
1617                                 signed char curr;
1618                                 int mask = (1 << image->comps[compno].prec) - 1;
1619                                 for(cont = 0; cont < pixelsToWrite; cont++)
1620                                 {                               
1621                                         curr = (signed char) (image->comps[compno].data[cont] & mask);
1622                                         fwrite(&curr, sizeof(signed char), 1, rawFile);
1623                                 }
1624                         }
1625                         else if(image->comps[compno].sgnd == 0)
1626                         {
1627                                 unsigned char curr;
1628                                 int mask = (1 << image->comps[compno].prec) - 1;
1629                                 for(cont = 0; cont < pixelsToWrite; cont++)
1630                                 {                               
1631                                         curr = (unsigned char) (image->comps[compno].data[cont] & mask);
1632                                         fwrite(&curr, sizeof(unsigned char), 1, rawFile);
1633                                 }
1634                         }
1635                 }
1636                 else if(image->comps[compno].prec <= 16)
1637                 {
1638                         if(image->comps[compno].sgnd == 1)
1639                         {
1640                                 signed short int curr;
1641                                 int mask = (1 << image->comps[compno].prec) - 1;
1642                                 for(cont = 0; cont < pixelsToWrite; cont++)
1643                                 {                               
1644                                         curr = (signed short int) (image->comps[compno].data[cont] & mask);
1645                                         fwrite(&curr, sizeof(signed short int), 1, rawFile);
1646                                 }
1647                         }
1648                         else if(image->comps[compno].sgnd == 0)
1649                         {
1650                                 unsigned short int curr;
1651                                 int mask = (1 << image->comps[compno].prec) - 1;
1652                                 for(cont = 0; cont < pixelsToWrite; cont++)
1653                                 {                               
1654                                         curr = (unsigned short int) (image->comps[compno].data[cont] & mask);
1655                                         fwrite(&curr, sizeof(unsigned short int), 1, rawFile);
1656                                 }
1657                         }
1658                 }
1659                 else if (image->comps[compno].prec <= 32)
1660                 {
1661
1662
1663                 }
1664                 else
1665                 {
1666                         fprintf(stderr,"\nError: invalid precision\n");
1667                         return 1;
1668                 }
1669         }
1670         fclose(rawFile);
1671         return 0;
1672 }