Fixed raw option to encode raw images with more than three components.
[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
477         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
478                 && image->comps[1].dx == image->comps[2].dx
479                 && image->comps[0].dy == image->comps[1].dy
480                 && image->comps[1].dy == image->comps[2].dy
481                 && image->comps[0].prec == image->comps[1].prec
482                 && image->comps[1].prec == image->comps[2].prec) {
483                 
484                 /* -->> -->> -->> -->>    
485                 24 bits color       
486                 <<-- <<-- <<-- <<-- */
487             
488                 fdest = fopen(outfile, "wb");
489                 if (!fdest) {
490                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
491                         return 1;
492                 }
493             
494                 /* w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); */
495                 /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), image->comps[0].dx); */
496                 w = image->comps[0].w;
497                 wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
498             
499                 /* h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); */
500                 /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */
501                 h = image->comps[0].h;
502                 hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
503             
504                 fprintf(fdest, "BM");
505             
506                 /* FILE HEADER */
507                 /* ------------- */
508                 fprintf(fdest, "%c%c%c%c",
509                         (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) + 54) & 0xff,
510                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 8) & 0xff,
511                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 16) & 0xff,
512                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 24) & 0xff);
513                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
514                 fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
515             
516                 /* INFO HEADER   */
517                 /* ------------- */
518                 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
519                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff),
520                         (unsigned char) ((wr) >> 8) & 0xff,
521                         (unsigned char) ((wr) >> 16) & 0xff,
522                         (unsigned char) ((wr) >> 24) & 0xff);
523                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff),
524                         (unsigned char) ((hr) >> 8) & 0xff,
525                         (unsigned char) ((hr) >> 16) & 0xff,
526                         (unsigned char) ((hr) >> 24) & 0xff);
527                 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
528                 fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
529                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
530                 fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * hr * wr + 3 * hr * (wr % 2)) & 0xff,
531                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 8) & 0xff,
532                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 16) & 0xff,
533                         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 24) & 0xff);
534                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
535                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
536                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
537                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
538             
539                 for (i = 0; i < wr * hr; i++) {
540                         unsigned char R, G, B;
541                         /* a modifier */
542                         /* R = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */
543                         R = image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
544                         /* G = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */
545                         G = image->comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
546                         /* B = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */
547                         B = image->comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
548                         fprintf(fdest, "%c%c%c", B, G, R);
549                         
550                         if ((i + 1) % wr == 0) {
551                                 for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--) /* ADD */
552                                         fprintf(fdest, "%c", 0);
553                         }
554                 }
555                 fclose(fdest);
556         } else {                        /* Gray-scale */
557
558                 /* -->> -->> -->> -->>
559                 8 bits non code (Gray scale)
560                 <<-- <<-- <<-- <<-- */
561
562                 fdest = fopen(outfile, "wb");
563                 /* w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); */
564                 /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), image->comps[0].dx); */
565                 w = image->comps[0].w;
566                 wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
567             
568                 /* h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); */
569                 /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */
570                 h = image->comps[0].h;
571                 hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
572             
573                 fprintf(fdest, "BM");
574             
575                 /* FILE HEADER */
576                 /* ------------- */
577                 fprintf(fdest, "%c%c%c%c", (unsigned char) (hr * wr + 54 + 1024 + hr * (wr % 2)) & 0xff,
578                         (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) >> 8) & 0xff,
579                         (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) >> 16) & 0xff,
580                         (unsigned char) ((hr * wr + 54 + 1024 + wr * (wr % 2)) >> 24) & 0xff);
581                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
582                 fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff, 
583                         ((54 + 1024) >> 16) & 0xff,
584                         ((54 + 1024) >> 24) & 0xff);
585             
586                 /* INFO HEADER */
587                 /* ------------- */
588                 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
589                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff),
590                         (unsigned char) ((wr) >> 8) & 0xff,
591                         (unsigned char) ((wr) >> 16) & 0xff,
592                         (unsigned char) ((wr) >> 24) & 0xff);
593                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff),
594                         (unsigned char) ((hr) >> 8) & 0xff,
595                         (unsigned char) ((hr) >> 16) & 0xff,
596                         (unsigned char) ((hr) >> 24) & 0xff);
597                 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
598                 fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
599                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
600                 fprintf(fdest, "%c%c%c%c", (unsigned char) (hr * wr + hr * (wr % 2)) & 0xff,
601                         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 8) &      0xff,
602                         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 16) &     0xff,
603                         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 24) & 0xff);
604                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
605                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
606                 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
607                 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
608
609                 for (i = 0; i < 256; i++) {
610                         fprintf(fdest, "%c%c%c%c", i, i, i, 0);
611                 }
612
613                 for (i = 0; i < wr * hr; i++) {
614                         /* a modifier !! */
615                         /* fprintf(fdest, "%c", image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]); */
616                         fprintf(fdest, "%c", image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]);
617                         /*if (((i + 1) % w == 0 && w % 2))
618                         fprintf(fdest, "%c", 0); */
619                         if ((i + 1) % wr == 0) {
620                                 for (pad = wr % 4 ? 4 - wr % 4 : 0; pad > 0; pad--)     /* ADD */
621                                         fprintf(fdest, "%c", 0);
622                         }
623                 }
624                 fclose(fdest);
625         }
626
627         return 0;
628 }
629
630 /* -->> -->> -->> -->>
631
632 PGX IMAGE FORMAT
633
634 <<-- <<-- <<-- <<-- */
635
636
637 unsigned char readuchar(FILE * f)
638 {
639   unsigned char c1;
640   fread(&c1, 1, 1, f);
641   return c1;
642 }
643
644 unsigned short readushort(FILE * f, int bigendian)
645 {
646   unsigned char c1, c2;
647   fread(&c1, 1, 1, f);
648   fread(&c2, 1, 1, f);
649   if (bigendian)
650     return (c1 << 8) + c2;
651   else
652     return (c2 << 8) + c1;
653 }
654
655 unsigned int readuint(FILE * f, int bigendian)
656 {
657   unsigned char c1, c2, c3, c4;
658   fread(&c1, 1, 1, f);
659   fread(&c2, 1, 1, f);
660   fread(&c3, 1, 1, f);
661   fread(&c4, 1, 1, f);
662   if (bigendian)
663     return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
664   else
665     return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1;
666 }
667
668 opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) {
669         FILE *f = NULL;
670         int w, h, prec;
671         int i, numcomps, max;
672         OPJ_COLOR_SPACE color_space;
673         opj_image_cmptparm_t cmptparm;  /* maximum of 1 component  */
674         opj_image_t * image = NULL;
675
676         char endian1,endian2,sign;
677         char signtmp[32];
678
679         char temp[32];
680         int bigendian;
681         opj_image_comp_t *comp = NULL;
682
683         numcomps = 1;
684         color_space = CLRSPC_GRAY;
685
686         memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t));
687
688         max = 0;
689
690         f = fopen(filename, "rb");
691         if (!f) {
692           fprintf(stderr, "Failed to open %s for reading !\n", filename);
693           return NULL;
694         }
695
696         fseek(f, 0, SEEK_SET);
697         fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h);
698         
699         i=0;
700         sign='+';               
701         while (signtmp[i]!='\0') {
702                 if (signtmp[i]=='-') sign='-';
703                 i++;
704         }
705         
706         fgetc(f);
707         if (endian1=='M' && endian2=='L') {
708                 bigendian = 1;
709         } else if (endian2=='M' && endian1=='L') {
710                 bigendian = 0;
711         } else {
712                 fprintf(stderr, "Bad pgx header, please check input file\n");
713                 return NULL;
714         }
715
716         /* initialize image component */
717
718         cmptparm.x0 = parameters->image_offset_x0;
719         cmptparm.y0 = parameters->image_offset_y0;
720         cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1;
721         cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1;
722         
723         if (sign == '-') {
724                 cmptparm.sgnd = 1;
725         } else {
726                 cmptparm.sgnd = 0;
727         }
728         cmptparm.prec = prec;
729         cmptparm.bpp = prec;
730         cmptparm.dx = parameters->subsampling_dx;
731         cmptparm.dy = parameters->subsampling_dy;
732         
733         /* create the image */
734         image = opj_image_create(numcomps, &cmptparm, color_space);
735         if(!image) {
736                 fclose(f);
737                 return NULL;
738         }
739         /* set image offset and reference grid */
740         image->x0 = cmptparm.x0;
741         image->y0 = cmptparm.x0;
742         image->x1 = cmptparm.w;
743         image->y1 = cmptparm.h;
744
745         /* set image data */
746
747         comp = &image->comps[0];
748
749         for (i = 0; i < w * h; i++) {
750                 int v;
751                 if (comp->prec <= 8) {
752                         if (!comp->sgnd) {
753                                 v = readuchar(f);
754                         } else {
755                                 v = (char) readuchar(f);
756                         }
757                 } else if (comp->prec <= 16) {
758                         if (!comp->sgnd) {
759                                 v = readushort(f, bigendian);
760                         } else {
761                                 v = (short) readushort(f, bigendian);
762                         }
763                 } else {
764                         if (!comp->sgnd) {
765                                 v = readuint(f, bigendian);
766                         } else {
767                                 v = (int) readuint(f, bigendian);
768                         }
769                 }
770                 if (v > max)
771                         max = v;
772                 comp->data[i] = v;
773         }
774         fclose(f);
775         comp->bpp = int_floorlog2(max) + 1;
776
777         return image;
778 }
779
780 int imagetopgx(opj_image_t * image, const char *outfile) {
781         int w, wr, h, hr;
782         int i, j, compno;
783         FILE *fdest = NULL;
784
785         for (compno = 0; compno < image->numcomps; compno++) {
786                 opj_image_comp_t *comp = &image->comps[compno];
787                 char bname[256]; /* buffer for name */
788     char *name = bname; /* pointer */
789     int nbytes = 0;
790     const size_t olen = strlen(outfile);
791     const size_t dotpos = olen - 4;
792     const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */
793     if( outfile[dotpos] != '.' ) {
794       /* `pgx` was recognized but there is no dot at expected position */
795       fprintf(stderr, "ERROR -> Impossible happen." );
796       return 1;
797       }
798     if( total > 256 ) {
799       name = (char*)malloc(total+1);
800       }
801     strncpy(name, outfile, dotpos);
802                 if (image->numcomps > 1) {
803                         sprintf(name+dotpos, "-%d.pgx", compno);
804                 } else {
805                         strcpy(name+dotpos, ".pgx");
806                 }
807                 fdest = fopen(name, "wb");
808                 if (!fdest) {
809                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
810                         return 1;
811                 }
812     /* dont need name anymore */
813     if( total > 256 ) {
814       free(name);
815       }
816                 /* w = int_ceildiv(image->x1 - image->x0, comp->dx); */
817                 /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), comp->dx); */
818                 w = image->comps[compno].w;
819                 wr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);
820             
821                 /* h = int_ceildiv(image->y1 - image->y0, comp->dy); */
822                 /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), comp->dy); */
823                 h = image->comps[compno].h;
824                 hr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);
825             
826                 fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, wr, hr);
827                 if (comp->prec <= 8) {
828                         nbytes = 1;
829                 } else if (comp->prec <= 16) {
830                         nbytes = 2;
831                 } else {
832                         nbytes = 4;
833                 }
834                 for (i = 0; i < wr * hr; i++) {
835                         int v = image->comps[compno].data[i / wr * w + i % wr];
836                         for (j = nbytes - 1; j >= 0; j--) {
837                                 char byte = (char) (v >> (j * 8));
838                                 fwrite(&byte, 1, 1, fdest);
839                         }
840                 }
841                 fclose(fdest);
842         }
843
844         return 0;
845 }
846
847 /* -->> -->> -->> -->>
848
849 PNM IMAGE FORMAT
850
851 <<-- <<-- <<-- <<-- */
852
853 opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) {
854         int subsampling_dx = parameters->subsampling_dx;
855         int subsampling_dy = parameters->subsampling_dy;
856
857         FILE *f = NULL;
858         int i, compno, numcomps, w, h;
859         OPJ_COLOR_SPACE color_space;
860         opj_image_cmptparm_t cmptparm[3];       /* maximum of 3 components */
861         opj_image_t * image = NULL;
862         char value;
863         
864         f = fopen(filename, "rb");
865         if (!f) {
866                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
867                 return 0;
868         }
869
870         if (fgetc(f) != 'P')
871                 return 0;
872         value = fgetc(f);
873
874                 switch(value) {
875                         case '2':       /* greyscale image type */
876                         case '5':
877                                 numcomps = 1;
878                                 color_space = CLRSPC_GRAY;
879                                 break;
880                                 
881                         case '3':       /* RGB image type */
882                         case '6':
883                                 numcomps = 3;
884                                 color_space = CLRSPC_SRGB;
885                                 break;
886                                 
887                         default:
888                                 fclose(f);
889                                 return NULL;
890                 }
891                 
892                 fgetc(f);
893                 
894                 /* skip comments */
895                 while(fgetc(f) == '#') while(fgetc(f) != '\n');
896                 
897                 fseek(f, -1, SEEK_CUR);
898                 fscanf(f, "%d %d\n255", &w, &h);                        
899                 fgetc(f);       /* <cr><lf> */
900                 
901         /* initialize image components */
902         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
903         for(i = 0; i < numcomps; i++) {
904                 cmptparm[i].prec = 8;
905                 cmptparm[i].bpp = 8;
906                 cmptparm[i].sgnd = 0;
907                 cmptparm[i].dx = subsampling_dx;
908                 cmptparm[i].dy = subsampling_dy;
909                 cmptparm[i].w = w;
910                 cmptparm[i].h = h;
911         }
912         /* create the image */
913         image = opj_image_create(numcomps, &cmptparm[0], color_space);
914         if(!image) {
915                 fclose(f);
916                 return NULL;
917         }
918
919         /* set image offset and reference grid */
920         image->x0 = parameters->image_offset_x0;
921         image->y0 = parameters->image_offset_y0;
922         image->x1 = parameters->image_offset_x0 + (w - 1) *     subsampling_dx + 1;
923         image->y1 = parameters->image_offset_y0 + (h - 1) *     subsampling_dy + 1;
924
925         /* set image data */
926
927         if ((value == '2') || (value == '3')) { /* ASCII */
928                 for (i = 0; i < w * h; i++) {
929                         for(compno = 0; compno < numcomps; compno++) {
930                                 unsigned int index = 0;
931                                 fscanf(f, "%u", &index);
932                                 /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
933                                 image->comps[compno].data[i] = index;
934                         }
935                 }
936         } else if ((value == '5') || (value == '6')) {  /* BINARY */
937                 for (i = 0; i < w * h; i++) {
938                         for(compno = 0; compno < numcomps; compno++) {
939                                 unsigned char index = 0;
940                                 fread(&index, 1, 1, f);
941                                 /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
942                                 image->comps[compno].data[i] = index;
943                         }
944                 }
945         }
946
947         fclose(f);
948
949         return image;
950 }
951
952 int imagetopnm(opj_image_t * image, const char *outfile) {
953         int w, wr, wrr, h, hr, hrr, max;
954         int i, compno;
955         int adjust;
956         FILE *fdest = NULL;
957         char S2;
958         const char *tmp = outfile;
959
960         while (*tmp) {
961                 tmp++;
962         }
963         tmp--;
964         tmp--;
965         S2 = *tmp;
966
967         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
968                 && image->comps[1].dx == image->comps[2].dx
969                 && image->comps[0].dy == image->comps[1].dy
970                 && image->comps[1].dy == image->comps[2].dy
971                 && image->comps[0].prec == image->comps[1].prec
972                 && image->comps[1].prec == image->comps[2].prec
973                 && S2 !='g' && S2 !='G') {
974
975                 fdest = fopen(outfile, "wb");
976                 if (!fdest) {
977                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
978                         return 1;
979                 }
980
981                 w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
982                 /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor),image->comps[0].dx); */
983                 wr = image->comps[0].w;
984                 wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
985         
986                 h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
987                 /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */
988                 hr = image->comps[0].h;
989                 hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
990             
991                 max = image->comps[0].prec > 8 ? 255 : (1 << image->comps[0].prec) - 1;
992             
993                 image->comps[0].x0 = int_ceildivpow2(image->comps[0].x0 - int_ceildiv(image->x0, image->comps[0].dx), image->comps[0].factor);
994                 image->comps[0].y0 = int_ceildivpow2(image->comps[0].y0 -       int_ceildiv(image->y0, image->comps[0].dy), image->comps[0].factor);
995
996                 fprintf(fdest, "P6\n%d %d\n%d\n", wrr, hrr, max);
997                 adjust = image->comps[0].prec > 8 ? image->comps[0].prec - 8 : 0;
998                 for (i = 0; i < wrr * hrr; i++) {
999                         int r, g, b;
1000                         unsigned char rc,gc,bc;
1001                         r = image->comps[0].data[i / wrr * wr + i % wrr];
1002                         r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
1003                         rc = (unsigned char) ((r >> adjust)+((r >> (adjust-1))%2));
1004
1005                         g = image->comps[1].data[i / wrr * wr + i % wrr];
1006                         g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
1007                         gc = (unsigned char) ((g >> adjust)+((g >> (adjust-1))%2));
1008                         
1009                         b = image->comps[2].data[i / wrr * wr + i % wrr];
1010                         b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
1011                         bc = (unsigned char) ((b >> adjust)+((b >> (adjust-1))%2));
1012                         
1013                         fprintf(fdest, "%c%c%c", rc, gc, bc);
1014                 }
1015                 fclose(fdest);
1016         } else {
1017                 int ncomp=(S2=='g' || S2=='G')?1:image->numcomps;
1018                 if (image->numcomps>ncomp) {
1019                         fprintf(stderr,"WARNING -> [PGM files] Only the first component\n");
1020                         fprintf(stderr,"           is written to the file\n");
1021                 }
1022                 for (compno = 0; compno < ncomp; compno++) {
1023                         char name[256];
1024                         if (ncomp > 1) {
1025                                 sprintf(name, "%d.%s", compno, outfile);
1026                         } else {
1027                                 sprintf(name, "%s", outfile);
1028                         }
1029                         
1030                         fdest = fopen(name, "wb");
1031                         if (!fdest) {
1032                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
1033                                 return 1;
1034                         }
1035             
1036                         w = int_ceildiv(image->x1 - image->x0, image->comps[compno].dx);
1037                         /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor),image->comps[compno].dx); */
1038                         wr = image->comps[compno].w;
1039                         wrr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);
1040                         
1041                         h = int_ceildiv(image->y1 - image->y0, image->comps[compno].dy);
1042                         /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[compno].dy); */
1043                         hr = image->comps[compno].h;
1044                         hrr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);
1045                         
1046                         max = image->comps[compno].prec > 8 ? 255 : (1 << image->comps[compno].prec) - 1;
1047                         
1048                         image->comps[compno].x0 = int_ceildivpow2(image->comps[compno].x0 - int_ceildiv(image->x0, image->comps[compno].dx), image->comps[compno].factor);
1049                         image->comps[compno].y0 = int_ceildivpow2(image->comps[compno].y0 - int_ceildiv(image->y0, image->comps[compno].dy), image->comps[compno].factor);
1050                         
1051                         fprintf(fdest, "P5\n%d %d\n%d\n", wrr, hrr, max);
1052                         adjust = image->comps[compno].prec > 8 ? image->comps[compno].prec - 8 : 0;
1053
1054                         for (i = 0; i < wrr * hrr; i++) {
1055                                 int l;
1056                                 unsigned char lc;
1057                                 l = image->comps[compno].data[i / wrr * wr + i % wrr];
1058                                 l += (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0);
1059                                 lc = (unsigned char) ((l >> adjust)+((l >> (adjust-1))%2));
1060                                 fprintf(fdest, "%c", lc);
1061                         }
1062                         fclose(fdest);
1063                 }
1064         }
1065
1066         return 0;
1067 }
1068
1069 /* -->> -->> -->> -->>
1070
1071         TIFF IMAGE FORMAT
1072
1073  <<-- <<-- <<-- <<-- */
1074
1075 typedef struct tiff_infoheader{
1076         DWORD tiWidth;  // Width of Image in pixel
1077         DWORD tiHeight; // Height of Image in pixel
1078         DWORD tiPhoto;  // Photometric
1079         WORD  tiBps;    // Bits per sample
1080         WORD  tiSf;             // Sample Format
1081         WORD  tiSpp;    // Sample per pixel 1-bilevel,gray scale , 2- RGB
1082         WORD  tiPC;     // Planar config (1-Interleaved, 2-Planarcomp)
1083 }tiff_infoheader_t;
1084
1085 int imagetotif(opj_image_t * image, const char *outfile) {
1086         int width, height;
1087         int bps,index;
1088         TIFF *tif;
1089         tdata_t buf;
1090         tstrip_t strip;
1091         tsize_t strip_size;
1092
1093         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
1094                 && image->comps[1].dx == image->comps[2].dx
1095                 && image->comps[0].dy == image->comps[1].dy
1096                 && image->comps[1].dy == image->comps[2].dy
1097                 && image->comps[0].prec == image->comps[1].prec
1098                 && image->comps[1].prec == image->comps[2].prec) {
1099
1100                         /* -->> -->> -->>    
1101                         RGB color           
1102                         <<-- <<-- <<-- */
1103
1104                         tif = TIFFOpen(outfile, "wb"); 
1105                         if (!tif) {
1106                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1107                                 return 1;
1108                         }
1109
1110                         width   = image->comps[0].w;
1111                         height= image->comps[0].h;
1112                         bps             = image->comps[0].prec;
1113                         /* Set tags */
1114                         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
1115                         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
1116                         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
1117                         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
1118                         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
1119                         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1120                         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
1121                         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
1122
1123                         /* Get a buffer for the data */
1124                         buf = _TIFFmalloc(TIFFStripSize(tif));
1125                         index=0;
1126                         strip_size=0;
1127                         strip_size=TIFFStripSize(tif);
1128                         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1129                                 unsigned char *dat8;
1130                                 int i;
1131                                 dat8 = buf;
1132                                 if (image->comps[0].prec == 8){
1133                                         for (i=0; i<TIFFStripSize(tif); i+=3) { // 8 bits per pixel 
1134                                                 dat8[i+0] = image->comps[0].data[index] ;       // R 
1135                                                 dat8[i+1] = image->comps[1].data[index] ;       // G 
1136                                                 dat8[i+2] = image->comps[2].data[index] ;       // B 
1137                                                 index++;
1138                                         }
1139                                 }else if (image->comps[0].prec == 12){
1140                                         for (i=0; i<TIFFStripSize(tif); i+=9) { // 12 bits per pixel 
1141                                                 dat8[i+0] = (image->comps[0].data[index]>>8)<<4 | (image->comps[0].data[index]>>4);
1142                                                 dat8[i+1] = (image->comps[0].data[index]<<4)|((image->comps[1].data[index]>>8)& 0x0f);
1143                                                 dat8[i+2] = (image->comps[1].data[index]);
1144                                                 dat8[i+3] = (image->comps[2].data[index]>>8)<<4 | (image->comps[2].data[index]>>4);
1145                                                 dat8[i+4] = (image->comps[2].data[index]<<4)|((image->comps[1].data[index+1]>>8)& 0x0f);
1146                                                 dat8[i+5] = (image->comps[0].data[index+1]);
1147                                                 dat8[i+6] = (image->comps[1].data[index+1]>>8)<<4 | (image->comps[1].data[index+1]>>4);
1148                                                 dat8[i+7] = (image->comps[1].data[index+1]<<4)|((image->comps[2].data[index+1]>>8)& 0x0f);
1149                                                 dat8[i+8] = (image->comps[2].data[index+1]);
1150                                                 index+=2;
1151                                         }
1152                                 }else if (image->comps[0].prec == 16){
1153                                         for (i=0; i<TIFFStripSize(tif); i+=6) { // 16 bits per pixel 
1154                                                 dat8[i+0] =  image->comps[0].data[index];//LSB
1155                                                 dat8[i+1] = (image->comps[0].data[index]>> 8);//MSB      
1156                                                 dat8[i+2] =  image->comps[1].data[index]; 
1157                                                 dat8[i+3] = (image->comps[1].data[index]>> 8);  
1158                                                 dat8[i+4] =  image->comps[2].data[index];        
1159                                                 dat8[i+5] = (image->comps[2].data[index]>> 8); 
1160                                                 index++;
1161                                         }
1162                                 }else{
1163                                         fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec);
1164                                         fprintf(stderr,"Aborting\n");
1165                                         return 1;
1166                                 }
1167                                 TIFFWriteEncodedStrip(tif, strip, buf, strip_size);
1168                         }
1169                         _TIFFfree(buf);
1170                         TIFFClose(tif);
1171                 }else if (image->numcomps == 1){
1172                         /* -->> -->> -->>    
1173                         Black and White     
1174                         <<-- <<-- <<-- */
1175
1176                         tif = TIFFOpen(outfile, "wb"); 
1177                         if (!tif) {
1178                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1179                                 return 1;
1180                         }
1181
1182                         width   = image->comps[0].w;
1183                         height= image->comps[0].h;
1184                         bps             = image->comps[0].prec;
1185
1186                         /* Set tags */
1187                         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
1188                         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
1189                         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
1190                         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
1191                         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
1192                         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1193                         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
1194                         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
1195
1196                         /* Get a buffer for the data */
1197                         buf = _TIFFmalloc(TIFFStripSize(tif));
1198                         index = 0;
1199                         strip_size = 0;
1200                         strip_size = TIFFStripSize(tif);
1201                         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1202                                 unsigned char *dat8;
1203                                 int i;
1204                                 dat8 = buf;
1205                                 if (image->comps[0].prec == 8){
1206                                         for (i=0; i<TIFFStripSize(tif); i+=1) { // 8 bits per pixel 
1207                                                 dat8[i+0] = image->comps[0].data[index] ;
1208                                                 index++;
1209                                         }
1210                                 }else if (image->comps[0].prec == 12){
1211                                         for (i = 0; i<TIFFStripSize(tif); i+=3) {       // 12 bits per pixel 
1212                                                 dat8[i+0] = (image->comps[0].data[index]>>8)<<4 | (image->comps[0].data[index]>>4);
1213                                                 dat8[i+1] = (image->comps[0].data[index]<<4)|((image->comps[0].data[index+1]>>8)& 0x0f);
1214                                                 dat8[i+2] = (image->comps[0].data[index+1]);
1215                                                 index+=2;
1216                                         }
1217                                 }else if (image->comps[0].prec == 16){
1218                                         for (i=0; i<TIFFStripSize(tif); i+=2) { // 16 bits per pixel 
1219                                                 dat8[i+0] =  image->comps[0].data[index];
1220                                                 dat8[i+1] = (image->comps[0].data[index]>> 8);
1221                                                 index++;
1222                                         }
1223                                 }else{
1224                                         fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec);
1225                                         fprintf(stderr,"Aborting\n");
1226                                         return 1;
1227                                 }
1228                                 TIFFWriteEncodedStrip(tif, strip, buf, strip_size);
1229                         }
1230                         _TIFFfree(buf);
1231                         TIFFClose(tif);
1232                 }else{
1233                         fprintf(stderr,"False color format. Only RGB & Grayscale has been implemented\n");
1234                         fprintf(stderr,"Aborting\n");
1235                         return 1;
1236                 }
1237                 return 0;
1238 }
1239
1240 opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
1241 {
1242         int subsampling_dx = parameters->subsampling_dx;
1243         int subsampling_dy = parameters->subsampling_dy;
1244         TIFF *tif;
1245         tiff_infoheader_t Info;
1246         tdata_t buf;
1247         tstrip_t strip;
1248         tsize_t strip_size;
1249         int j, numcomps, w, h,index;
1250         OPJ_COLOR_SPACE color_space;
1251         opj_image_cmptparm_t cmptparm[3];
1252         opj_image_t * image = NULL;
1253
1254         tif = TIFFOpen(filename, "r");
1255
1256         if (!tif) {
1257                 fprintf(stderr, "Failed to open %s for reading\n", filename);
1258                 return 0;
1259         }
1260
1261         TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &Info.tiWidth);
1262         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &Info.tiHeight);
1263         TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &Info.tiBps);
1264         TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &Info.tiSf);
1265         TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &Info.tiSpp);
1266         Info.tiPhoto = 0;
1267         TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &Info.tiPhoto);
1268         TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &Info.tiPC);
1269         w= Info.tiWidth;
1270         h= Info.tiHeight;
1271         
1272         if (Info.tiPhoto == 2) { 
1273                 /* -->> -->> -->>    
1274                 RGB color           
1275                 <<-- <<-- <<-- */
1276
1277                 numcomps = 3;
1278                 color_space = CLRSPC_SRGB;
1279                 /* initialize image components*/ 
1280                 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
1281                 for(j = 0; j < numcomps; j++) {
1282                         if (parameters->cp_cinema) {
1283                                 cmptparm[j].prec = 12;
1284                                 cmptparm[j].bpp = 12;
1285                         }else{
1286                                 cmptparm[j].prec = Info.tiBps;
1287                                 cmptparm[j].bpp = Info.tiBps;
1288                         }
1289                         cmptparm[j].sgnd = 0;
1290                         cmptparm[j].dx = subsampling_dx;
1291                         cmptparm[j].dy = subsampling_dy;
1292                         cmptparm[j].w = w;
1293                         cmptparm[j].h = h;
1294                 }
1295                 /* create the image*/ 
1296                 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1297                 if(!image) {
1298                         TIFFClose(tif);
1299                         return NULL;
1300                 }
1301
1302                 /* set image offset and reference grid */
1303                 image->x0 = parameters->image_offset_x0;
1304                 image->y0 = parameters->image_offset_y0;
1305                 image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
1306                 image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
1307
1308                 buf = _TIFFmalloc(TIFFStripSize(tif));
1309                 strip_size=0;
1310                 strip_size=TIFFStripSize(tif);
1311                 index = 0;
1312                 /* Read the Image components*/
1313                 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1314                         unsigned char *dat8;
1315                         int i, ssize;
1316                         ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
1317                         dat8 = buf;
1318
1319                         if (Info.tiBps==12){
1320                                 for (i=0; i<ssize; i+=9) {      /*12 bits per pixel*/
1321                                         image->comps[0].data[index]   = ( dat8[i+0]<<4 )                |(dat8[i+1]>>4);
1322                                         image->comps[1].data[index]   = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2];
1323                                         image->comps[2].data[index]   = ( dat8[i+3]<<4)                 |(dat8[i+4]>>4);
1324                                         image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5];
1325                                         image->comps[1].data[index+1] = ( dat8[i+6] <<4)                |(dat8[i+7]>>4);
1326                                         image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8];
1327                                         index+=2;
1328                                 }
1329                         }
1330                         else if( Info.tiBps==16){
1331                                 for (i=0; i<ssize; i+=6) {      /* 16 bits per pixel */
1332                                         image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0];   // R 
1333                                         image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2];   // G 
1334                                         image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4];   // B 
1335                                         if(parameters->cp_cinema){/* Rounding to 12 bits*/
1336                                                 image->comps[0].data[index] = (image->comps[0].data[index] + 0x08) >> 4 ;
1337                                                 image->comps[1].data[index] = (image->comps[1].data[index] + 0x08) >> 4 ;
1338                                                 image->comps[2].data[index] = (image->comps[2].data[index] + 0x08) >> 4 ;
1339                                         }
1340                                         index++;
1341                                 }
1342                         }
1343                         else if ( Info.tiBps==8){
1344                                 for (i=0; i<ssize; i+=3) {      /* 8 bits per pixel */
1345                                         image->comps[0].data[index] = dat8[i+0];        // R 
1346                                         image->comps[1].data[index] = dat8[i+1];        // G 
1347                                         image->comps[2].data[index] = dat8[i+2];        // B 
1348                                         if(parameters->cp_cinema){/* Rounding to 12 bits*/
1349                                                 image->comps[0].data[index] = image->comps[0].data[index] << 4 ;
1350                                                 image->comps[1].data[index] = image->comps[1].data[index] << 4 ;
1351                                                 image->comps[2].data[index] = image->comps[2].data[index] << 4 ;
1352                                         }
1353                                         index++;
1354                                 }
1355                         }
1356                         else{
1357                                 fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps);
1358                                 fprintf(stderr,"Aborting\n");
1359                                 return NULL;
1360                         }
1361                 }
1362
1363                 _TIFFfree(buf);
1364                 TIFFClose(tif);
1365         }else if(Info.tiPhoto == 1) { 
1366                 /* -->> -->> -->>    
1367                 Black and White
1368                 <<-- <<-- <<-- */
1369
1370                 numcomps = 1;
1371                 color_space = CLRSPC_GRAY;
1372                 /* initialize image components*/ 
1373                 memset(&cmptparm[0], 0, sizeof(opj_image_cmptparm_t));
1374                 cmptparm[0].prec = Info.tiBps;
1375                 cmptparm[0].bpp = Info.tiBps;
1376                 cmptparm[0].sgnd = 0;
1377                 cmptparm[0].dx = subsampling_dx;
1378                 cmptparm[0].dy = subsampling_dy;
1379                 cmptparm[0].w = w;
1380                 cmptparm[0].h = h;
1381
1382                 /* create the image*/ 
1383                 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1384                 if(!image) {
1385                         TIFFClose(tif);
1386                         return NULL;
1387                 }
1388                 /* set image offset and reference grid */
1389                 image->x0 = parameters->image_offset_x0;
1390                 image->y0 = parameters->image_offset_y0;
1391                 image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
1392                 image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
1393
1394                 buf = _TIFFmalloc(TIFFStripSize(tif));
1395                 strip_size = 0;
1396                 strip_size = TIFFStripSize(tif);
1397                 index = 0;
1398                 /* Read the Image components*/
1399                 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1400                         unsigned char *dat8;
1401                         int i, ssize;
1402                         ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
1403                         dat8 = buf;
1404
1405                         if (Info.tiBps==12){
1406                                 for (i=0; i<ssize; i+=3) {      /* 12 bits per pixel*/
1407                                         image->comps[0].data[index] = ( dat8[i+0]<<4 )                          |(dat8[i+1]>>4) ;
1408                                         image->comps[0].data[index] = ((dat8[i+1]& 0x0f)<< 8)   | dat8[i+2];
1409                                         index+=2;
1410                                 }
1411                         }
1412                         else if( Info.tiBps==16){
1413                                 for (i=0; i<ssize; i+=2) {      /* 16 bits per pixel */
1414                                         image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0];
1415                                         index++;
1416                                 }
1417                         }
1418                         else if ( Info.tiBps==8){
1419                                 for (i=0; i<ssize; i+=1) {      /* 8 bits per pixel */
1420                                         image->comps[0].data[index] = dat8[i+0];
1421                                         index++;
1422                                 }
1423                         }
1424                         else{
1425                                 fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps);
1426                                 fprintf(stderr,"Aborting\n");
1427                                 return NULL;
1428                         }
1429                 }
1430
1431                 _TIFFfree(buf);
1432                 TIFFClose(tif);
1433         }else{
1434                 fprintf(stderr,"False color format. Only RGB & Grayscale has been implemented\n");
1435                 fprintf(stderr,"Aborting\n");
1436                 return NULL;
1437         }
1438         return image;
1439 }
1440
1441 /* -->> -->> -->> -->>
1442
1443         RAW IMAGE FORMAT
1444
1445  <<-- <<-- <<-- <<-- */
1446
1447 opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) {
1448         int subsampling_dx = parameters->subsampling_dx;
1449         int subsampling_dy = parameters->subsampling_dy;
1450
1451         FILE *f = NULL;
1452         int i, compno, numcomps, w, h;
1453         OPJ_COLOR_SPACE color_space;
1454         opj_image_cmptparm_t *cmptparm; 
1455         opj_image_t * image = NULL;
1456         unsigned short ch;
1457         
1458         if((raw_cp->rawWidth * raw_cp->rawHeight * raw_cp->rawComp * raw_cp->rawBitDepth) == 0)
1459         {
1460                 fprintf(stderr,"\nError: invalid raw image parameters\n");
1461                 fprintf(stderr,"Please use the Format option -F:\n");
1462                 fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
1463                 fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n");
1464                 fprintf(stderr,"Aborting\n");
1465                 return NULL;
1466         }
1467
1468         f = fopen(filename, "rb");
1469         if (!f) {
1470                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
1471                 fprintf(stderr,"Aborting\n");
1472                 return NULL;
1473         }
1474         numcomps = raw_cp->rawComp;
1475         color_space = CLRSPC_SRGB;
1476         w = raw_cp->rawWidth;
1477         h = raw_cp->rawHeight;
1478         cmptparm = (opj_image_cmptparm_t*) malloc(numcomps * sizeof(opj_image_cmptparm_t));
1479         
1480         /* initialize image components */       
1481         memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
1482         for(i = 0; i < numcomps; i++) {         
1483                 cmptparm[i].prec = raw_cp->rawBitDepth;
1484                 cmptparm[i].bpp = raw_cp->rawBitDepth;
1485                 cmptparm[i].sgnd = raw_cp->rawSigned;
1486                 cmptparm[i].dx = subsampling_dx;
1487                 cmptparm[i].dy = subsampling_dy;
1488                 cmptparm[i].w = w;
1489                 cmptparm[i].h = h;
1490         }
1491         /* create the image */
1492         image = opj_image_create(numcomps, &cmptparm[0], color_space);
1493         if(!image) {
1494                 fclose(f);
1495                 return NULL;
1496         }
1497
1498         /* set image offset and reference grid */
1499         image->x0 = parameters->image_offset_x0;
1500         image->y0 = parameters->image_offset_y0;
1501         image->x1 = parameters->image_offset_x0 + (w - 1) *     subsampling_dx + 1;
1502         image->y1 = parameters->image_offset_y0 + (h - 1) *     subsampling_dy + 1;
1503
1504         if(raw_cp->rawBitDepth <= 8)
1505         {
1506                 unsigned char value = 0;
1507                 for(compno = 0; compno < numcomps; compno++) {
1508                         for (i = 0; i < w * h; i++) {
1509                                 if (!fread(&value, 1, 1, f)) {
1510                                         fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
1511                                         return NULL;
1512                                 }
1513                                 image->comps[compno].data[i] = raw_cp->rawSigned?(char)value:value;
1514                         }
1515                 }
1516         }
1517         else
1518         {
1519                 unsigned short value = 0;
1520                 for(compno = 0; compno < numcomps; compno++) {
1521                         for (i = 0; i < w * h; i++) {
1522                                 if (!fread(&value, 2, 1, f)) {
1523                                         fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
1524                                         return NULL;
1525                                 }
1526                                 image->comps[compno].data[i] = raw_cp->rawSigned?(short)value:value;
1527                         }
1528                 }
1529         }
1530
1531         if (fread(&ch, 1, 1, f)) {
1532                 fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n");
1533         }
1534
1535         fclose(f);
1536
1537         return image;
1538 }
1539
1540 int imagetoraw(opj_image_t * image, const char *outfile)
1541 {
1542         FILE *rawFile = NULL;
1543         int compno, pixelsToWrite, offset, cont;
1544
1545         if((image->numcomps * image->x1 * image->y1) == 0)
1546         {
1547                 fprintf(stderr,"\nError: invalid raw image parameters\n");
1548                 return 1;
1549         }
1550
1551         rawFile = fopen(outfile, "wb");
1552         if (!rawFile) {
1553                 fprintf(stderr, "Failed to open %s for writing !!\n", outfile);
1554                 return 1;
1555         }
1556
1557         fprintf(stdout,"Raw image characteristics: %d components\n", image->numcomps);
1558
1559         for(compno = 0; compno < image->numcomps; compno++)
1560         {
1561                 fprintf(stdout,"Component %d characteristics: %dx%dx%d %s\n", compno, image->comps[compno].w,
1562                         image->comps[compno].h, image->comps[compno].prec, image->comps[compno].sgnd==1 ? "signed": "unsigned");
1563
1564                 pixelsToWrite = image->comps[compno].w * image->comps[compno].h;
1565                 offset = 0;
1566
1567                 if(image->comps[compno].prec <= 8)
1568                 {
1569                         if(image->comps[compno].sgnd == 1)
1570                         {
1571                                 signed char curr;
1572                                 int mask = (1 << image->comps[compno].prec) - 1;
1573                                 for(cont = 0; cont < pixelsToWrite; cont++)
1574                                 {                               
1575                                         curr = (signed char) (image->comps[compno].data[cont] & mask);
1576                                         fwrite(&curr, sizeof(signed char), 1, rawFile);
1577                                 }
1578                         }
1579                         else if(image->comps[compno].sgnd == 0)
1580                         {
1581                                 unsigned char curr;
1582                                 int mask = (1 << image->comps[compno].prec) - 1;
1583                                 for(cont = 0; cont < pixelsToWrite; cont++)
1584                                 {                               
1585                                         curr = (unsigned char) (image->comps[compno].data[cont] & mask);
1586                                         fwrite(&curr, sizeof(unsigned char), 1, rawFile);
1587                                 }
1588                         }
1589                 }
1590                 else if(image->comps[compno].prec <= 16)
1591                 {
1592                         if(image->comps[compno].sgnd == 1)
1593                         {
1594                                 signed short int curr;
1595                                 int mask = (1 << image->comps[compno].prec) - 1;
1596                                 for(cont = 0; cont < pixelsToWrite; cont++)
1597                                 {                               
1598                                         curr = (signed short int) (image->comps[compno].data[cont] & mask);
1599                                         fwrite(&curr, sizeof(signed short int), 1, rawFile);
1600                                 }
1601                         }
1602                         else if(image->comps[compno].sgnd == 0)
1603                         {
1604                                 unsigned short int curr;
1605                                 int mask = (1 << image->comps[compno].prec) - 1;
1606                                 for(cont = 0; cont < pixelsToWrite; cont++)
1607                                 {                               
1608                                         curr = (unsigned short int) (image->comps[compno].data[cont] & mask);
1609                                         fwrite(&curr, sizeof(unsigned short int), 1, rawFile);
1610                                 }
1611                         }
1612                 }
1613                 else if (image->comps[compno].prec <= 32)
1614                 {
1615
1616
1617                 }
1618                 else
1619                 {
1620                         fprintf(stderr,"\nError: invalid precision\n");
1621                         return 1;
1622                 }
1623         }
1624         fclose(rawFile);
1625         return 0;
1626 }