47c299316b6659d89fd8b085e54e67e17e27f214
[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 "opj_config.h"
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #ifdef _WIN32
39 #define BYTE_ORDER LITTLE_ENDIAN
40 #elif __APPLE__
41 #include <machine/endian.h>
42 #else
43 #include <endian.h>
44 #endif
45
46 #ifdef HAVE_LIBTIFF
47 #include <tiffio.h>
48 #endif /* HAVE_LIBTIFF */
49
50 #ifdef HAVE_LIBPNG
51 #include <zlib.h>
52 #include <png.h>
53 #endif /* HAVE_LIBPNG */
54
55 #include "../libopenjpeg/openjpeg.h"
56 #include "convert.h"
57
58 /*
59  * Get logarithm of an integer and round downwards.
60  *
61  * log2(a)
62  */
63 static int int_floorlog2(int a) {
64         int l;
65         for (l = 0; a > 1; l++) {
66                 a >>= 1;
67         }
68         return l;
69 }
70
71 /* -->> -->> -->> -->>
72
73   TGA IMAGE FORMAT
74
75  <<-- <<-- <<-- <<-- */
76
77 // TGA header definition.
78 #pragma pack(push,1) // Pack structure byte aligned
79 typedef struct tga_header
80 {                           
81     unsigned char   id_length;              /* Image id field length    */
82     unsigned char   colour_map_type;        /* Colour map type          */
83     unsigned char   image_type;             /* Image type               */
84     /*
85     ** Colour map specification
86     */
87     unsigned short  colour_map_index;       /* First entry index        */
88     unsigned short  colour_map_length;      /* Colour map length        */
89     unsigned char   colour_map_entry_size;  /* Colour map entry size    */
90     /*
91     ** Image specification
92     */
93     unsigned short  x_origin;               /* x origin of image        */
94     unsigned short  y_origin;               /* u origin of image        */
95     unsigned short  image_width;            /* Image width              */
96     unsigned short  image_height;           /* Image height             */
97     unsigned char   pixel_depth;            /* Pixel depth              */
98     unsigned char   image_desc;             /* Image descriptor         */
99 } tga_header;
100 #pragma pack(pop) // Return to normal structure packing alignment.
101
102 int tga_readheader(FILE *fp, unsigned int *bits_per_pixel, 
103         unsigned int *width, unsigned int *height, int *flip_image)
104 {
105         int palette_size;
106         tga_header tga ;
107
108         if (!bits_per_pixel || !width || !height || !flip_image)
109                 return 0;
110         
111         // Read TGA header
112         fread((unsigned char*)&tga, sizeof(tga_header), 1, fp);
113
114         *bits_per_pixel = tga.pixel_depth;
115         
116         *width  = tga.image_width;
117         *height = tga.image_height ;
118
119         // Ignore tga identifier, if present ...
120         if (tga.id_length)
121         {
122                 unsigned char *id = (unsigned char *) malloc(tga.id_length);
123                 fread(id, tga.id_length, 1, fp);
124                 free(id);  
125         }
126
127         // Test for compressed formats ... not yet supported ...
128         // Note :-  9 - RLE encoded palettized.
129         //                 10 - RLE encoded RGB.
130         if (tga.image_type > 8)
131         {
132                 fprintf(stderr, "Sorry, compressed tga files are not currently supported.\n");
133                 return 0 ;
134         }
135
136         *flip_image = !(tga.image_desc & 32);
137
138         // Palettized formats are not yet supported, skip over the palette, if present ... 
139         palette_size = tga.colour_map_length * (tga.colour_map_entry_size/8);
140         
141         if (palette_size>0)
142         {
143                 fprintf(stderr, "File contains a palette - not yet supported.");
144                 fseek(fp, palette_size, SEEK_CUR);
145         }
146         return 1;
147 }
148
149 int tga_writeheader(FILE *fp, int bits_per_pixel, int width, int height, 
150         bool flip_image)
151 {
152         tga_header tga;
153
154         if (!bits_per_pixel || !width || !height)
155                 return 0;
156
157         memset(&tga, 0, sizeof(tga_header));
158
159         tga.pixel_depth = bits_per_pixel;
160         tga.image_width  = width;
161         tga.image_height = height;
162         tga.image_type = 2; // Uncompressed.
163         tga.image_desc = 8; // 8 bits per component.
164
165         if (flip_image)
166                 tga.image_desc |= 32;
167
168         // Write TGA header
169         fwrite((unsigned char*)&tga, sizeof(tga_header), 1, fp);
170
171         return 1;
172 }
173
174 opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) {
175         FILE *f;
176         opj_image_t *image;
177         unsigned int image_width, image_height, pixel_bit_depth;
178         unsigned int x, y;
179         int flip_image=0;
180         opj_image_cmptparm_t cmptparm[4];       /* maximum 4 components */
181         int numcomps;
182         OPJ_COLOR_SPACE color_space;
183         bool mono ;
184         bool save_alpha;
185         int subsampling_dx, subsampling_dy;
186         int i;  
187
188         f = fopen(filename, "rb");
189         if (!f) {
190                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
191                 return 0;
192         }
193
194         if (!tga_readheader(f, &pixel_bit_depth, &image_width, &image_height, &flip_image))
195                 return NULL;
196
197         // We currently only support 24 & 32 bit tga's ...
198         if (!((pixel_bit_depth == 24) || (pixel_bit_depth == 32)))
199                 return NULL;
200
201         /* initialize image components */   
202         memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
203
204         mono = (pixel_bit_depth == 8) || (pixel_bit_depth == 16);  // Mono with & without alpha.
205         save_alpha = (pixel_bit_depth == 16) || (pixel_bit_depth == 32); // Mono with alpha, or RGB with alpha
206
207         if (mono) {
208                 color_space = CLRSPC_GRAY;
209                 numcomps = save_alpha ? 2 : 1;
210         }       
211         else {
212                 numcomps = save_alpha ? 4 : 3;
213                 color_space = CLRSPC_SRGB;
214         }
215
216         subsampling_dx = parameters->subsampling_dx;
217         subsampling_dy = parameters->subsampling_dy;
218
219         for (i = 0; i < numcomps; i++) {
220                 cmptparm[i].prec = 8;
221                 cmptparm[i].bpp = 8;
222                 cmptparm[i].sgnd = 0;
223                 cmptparm[i].dx = subsampling_dx;
224                 cmptparm[i].dy = subsampling_dy;
225                 cmptparm[i].w = image_width;
226                 cmptparm[i].h = image_height;
227         }
228
229         /* create the image */
230         image = opj_image_create(numcomps, &cmptparm[0], color_space);
231
232         if (!image)
233                 return NULL;
234
235         /* set image offset and reference grid */
236         image->x0 = parameters->image_offset_x0;
237         image->y0 = parameters->image_offset_y0;
238         image->x1 =     !image->x0 ? (image_width - 1) * subsampling_dx + 1 : image->x0 + (image_width - 1) * subsampling_dx + 1;
239         image->y1 =     !image->y0 ? (image_height - 1) * subsampling_dy + 1 : image->y0 + (image_height - 1) * subsampling_dy + 1;
240
241         /* set image data */
242         for (y=0; y < image_height; y++) 
243         {
244                 int index;
245
246                 if (flip_image)
247                         index = (image_height-y-1)*image_width;
248                 else
249                         index = y*image_width;
250
251                 if (numcomps==3)
252                 {
253                         for (x=0;x<image_width;x++) 
254                         {
255                                 unsigned char r,g,b;
256                                 fread(&b, 1, 1, f);
257                                 fread(&g, 1, 1, f);
258                                 fread(&r, 1, 1, f);
259
260                                 image->comps[0].data[index]=r;
261                                 image->comps[1].data[index]=g;
262                                 image->comps[2].data[index]=b;
263                                 index++;
264                         }
265                 }
266                 else if (numcomps==4)
267                 {
268                         for (x=0;x<image_width;x++) 
269                         {
270                                 unsigned char r,g,b,a;
271                                 fread(&b, 1, 1, f);
272                                 fread(&g, 1, 1, f);
273                                 fread(&r, 1, 1, f);
274                                 fread(&a, 1, 1, f);
275
276                                 image->comps[0].data[index]=r;
277                                 image->comps[1].data[index]=g;
278                                 image->comps[2].data[index]=b;
279                                 image->comps[3].data[index]=a;
280                                 index++;
281                         }
282                 }
283                 else {
284                         fprintf(stderr, "Currently unsupported bit depth : %s\n", filename);
285                 }
286         }       
287         return image;
288 }
289
290 int imagetotga(opj_image_t * image, const char *outfile) {
291         int width, height, bpp, x, y;
292         bool write_alpha;
293         int i;
294         unsigned int alpha_channel;
295         float r,g,b,a;
296         unsigned char value;
297         float scale;
298         FILE *fdest;
299
300         fdest = fopen(outfile, "wb");
301         if (!fdest) {
302                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
303                 return 1;
304         }
305
306         for (i = 0; i < image->numcomps-1; i++) {
307                 if ((image->comps[0].dx != image->comps[i+1].dx) 
308                         ||(image->comps[0].dy != image->comps[i+1].dy) 
309                         ||(image->comps[0].prec != image->comps[i+1].prec))     {
310       fprintf(stderr, "Unable to create a tga file with such J2K image charateristics.");
311       return 1;
312    }
313         }
314
315         width = image->comps[0].w;
316         height = image->comps[0].h; 
317
318         // Mono with alpha, or RGB with alpha.
319         write_alpha = (image->numcomps==2) || (image->numcomps==4);   
320
321         // Write TGA header 
322         bpp = write_alpha ? 32 : 24;
323         if (!tga_writeheader(fdest, bpp, width , height, true))
324                 return 1;
325
326         alpha_channel = image->numcomps-1; 
327
328         scale = 255.0f / (float)((1<<image->comps[0].prec)-1);
329
330         for (y=0; y < height; y++) {
331                 unsigned int index=y*width;
332
333                 for (x=0; x < width; x++, index++)      {
334                         r = (float)(image->comps[0].data[index]);
335
336                         if (image->numcomps>2) {
337                                 g = (float)(image->comps[1].data[index]);
338                                 b = (float)(image->comps[2].data[index]);
339                         }
340                         else  {// Greyscale ...
341                                 g = r;
342                                 b = r;
343                         }
344
345                         // TGA format writes BGR ...
346                         value = (unsigned char)(b*scale);
347                         fwrite(&value,1,1,fdest);
348
349                         value = (unsigned char)(g*scale);
350                         fwrite(&value,1,1,fdest);
351
352                         value = (unsigned char)(r*scale);
353                         fwrite(&value,1,1,fdest);
354
355                         if (write_alpha) {
356                                 a = (float)(image->comps[alpha_channel].data[index]);
357                                 value = (unsigned char)(a*scale);
358                                 fwrite(&value,1,1,fdest);
359                         }
360                 }
361         }
362
363         return 0;
364 }
365
366 /* -->> -->> -->> -->>
367
368   BMP IMAGE FORMAT
369
370  <<-- <<-- <<-- <<-- */
371
372 /* WORD defines a two byte word */
373 typedef unsigned short int WORD;
374
375 /* DWORD defines a four byte word */
376 typedef unsigned long int DWORD;
377
378 typedef struct {
379   WORD bfType;                  /* 'BM' for Bitmap (19776) */
380   DWORD bfSize;                 /* Size of the file        */
381   WORD bfReserved1;             /* Reserved : 0            */
382   WORD bfReserved2;             /* Reserved : 0            */
383   DWORD bfOffBits;              /* Offset                  */
384 } BITMAPFILEHEADER_t;
385
386 typedef struct {
387   DWORD biSize;                 /* Size of the structure in bytes */
388   DWORD biWidth;                /* Width of the image in pixels */
389   DWORD biHeight;               /* Heigth of the image in pixels */
390   WORD biPlanes;                /* 1 */
391   WORD biBitCount;              /* Number of color bits by pixels */
392   DWORD biCompression;          /* Type of encoding 0: none 1: RLE8 2: RLE4 */
393   DWORD biSizeImage;            /* Size of the image in bytes */
394   DWORD biXpelsPerMeter;        /* Horizontal (X) resolution in pixels/meter */
395   DWORD biYpelsPerMeter;        /* Vertical (Y) resolution in pixels/meter */
396   DWORD biClrUsed;              /* Number of color used in the image (0: ALL) */
397   DWORD biClrImportant;         /* Number of important color (0: ALL) */
398 } BITMAPINFOHEADER_t;
399
400 opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
401         int subsampling_dx = parameters->subsampling_dx;
402         int subsampling_dy = parameters->subsampling_dy;
403
404         int i, numcomps, w, h;
405         OPJ_COLOR_SPACE color_space;
406         opj_image_cmptparm_t cmptparm[3];       /* maximum of 3 components */
407         opj_image_t * image = NULL;
408
409         FILE *IN;
410         BITMAPFILEHEADER_t File_h;
411         BITMAPINFOHEADER_t Info_h;
412         unsigned char *RGB;
413         unsigned char *table_R, *table_G, *table_B;
414         unsigned int j, PAD = 0;
415
416         int x, y, index;
417         int gray_scale = 1, not_end_file = 1; 
418
419         unsigned int line = 0, col = 0;
420         unsigned char v, v2;
421         DWORD W, H;
422   
423         IN = fopen(filename, "rb");
424         if (!IN) {
425                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
426                 return 0;
427         }
428         
429         File_h.bfType = getc(IN);
430         File_h.bfType = (getc(IN) << 8) + File_h.bfType;
431         
432         if (File_h.bfType != 19778) {
433                 fprintf(stderr,"Error, not a BMP file!\n");
434                 return 0;
435         } else {
436                 /* FILE HEADER */
437                 /* ------------- */
438                 File_h.bfSize = getc(IN);
439                 File_h.bfSize = (getc(IN) << 8) + File_h.bfSize;
440                 File_h.bfSize = (getc(IN) << 16) + File_h.bfSize;
441                 File_h.bfSize = (getc(IN) << 24) + File_h.bfSize;
442
443                 File_h.bfReserved1 = getc(IN);
444                 File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1;
445
446                 File_h.bfReserved2 = getc(IN);
447                 File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2;
448
449                 File_h.bfOffBits = getc(IN);
450                 File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits;
451                 File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits;
452                 File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits;
453
454                 /* INFO HEADER */
455                 /* ------------- */
456
457                 Info_h.biSize = getc(IN);
458                 Info_h.biSize = (getc(IN) << 8) + Info_h.biSize;
459                 Info_h.biSize = (getc(IN) << 16) + Info_h.biSize;
460                 Info_h.biSize = (getc(IN) << 24) + Info_h.biSize;
461
462                 Info_h.biWidth = getc(IN);
463                 Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth;
464                 Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth;
465                 Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth;
466                 w = Info_h.biWidth;
467
468                 Info_h.biHeight = getc(IN);
469                 Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight;
470                 Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight;
471                 Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight;
472                 h = Info_h.biHeight;
473
474                 Info_h.biPlanes = getc(IN);
475                 Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes;
476
477                 Info_h.biBitCount = getc(IN);
478                 Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount;
479
480                 Info_h.biCompression = getc(IN);
481                 Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression;
482                 Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression;
483                 Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression;
484
485                 Info_h.biSizeImage = getc(IN);
486                 Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage;
487                 Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage;
488                 Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage;
489
490                 Info_h.biXpelsPerMeter = getc(IN);
491                 Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter;
492                 Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter;
493                 Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter;
494
495                 Info_h.biYpelsPerMeter = getc(IN);
496                 Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter;
497                 Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter;
498                 Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter;
499
500                 Info_h.biClrUsed = getc(IN);
501                 Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed;
502                 Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed;
503                 Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed;
504
505                 Info_h.biClrImportant = getc(IN);
506                 Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant;
507                 Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant;
508                 Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant;
509
510                 /* Read the data and store them in the OUT file */
511     
512                 if (Info_h.biBitCount == 24) {
513                         numcomps = 3;
514                         color_space = CLRSPC_SRGB;
515                         /* initialize image components */
516                         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
517                         for(i = 0; i < numcomps; i++) {
518                                 cmptparm[i].prec = 8;
519                                 cmptparm[i].bpp = 8;
520                                 cmptparm[i].sgnd = 0;
521                                 cmptparm[i].dx = subsampling_dx;
522                                 cmptparm[i].dy = subsampling_dy;
523                                 cmptparm[i].w = w;
524                                 cmptparm[i].h = h;
525                         }
526                         /* create the image */
527                         image = opj_image_create(numcomps, &cmptparm[0], color_space);
528                         if(!image) {
529                                 fclose(IN);
530                                 return NULL;
531                         }
532
533                         /* set image offset and reference grid */
534                         image->x0 = parameters->image_offset_x0;
535                         image->y0 = parameters->image_offset_y0;
536                         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
537                         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
538
539                         /* set image data */
540
541                         /* Place the cursor at the beginning of the image information */
542                         fseek(IN, 0, SEEK_SET);
543                         fseek(IN, File_h.bfOffBits, SEEK_SET);
544                         
545                         W = Info_h.biWidth;
546                         H = Info_h.biHeight;
547
548                         /* PAD = 4 - (3 * W) % 4; */
549                         /* PAD = (PAD == 4) ? 0 : PAD; */
550                         PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0;
551                         
552                         RGB = (unsigned char *) malloc((3 * W + PAD) * H * sizeof(unsigned char));
553                         
554                         fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN);
555                         
556                         index = 0;
557
558                         for(y = 0; y < (int)H; y++) {
559                                 unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y);
560                                 for(x = 0; x < (int)W; x++) {
561                                         unsigned char *pixel = &scanline[3 * x];
562                                         image->comps[0].data[index] = pixel[2]; /* R */
563                                         image->comps[1].data[index] = pixel[1]; /* G */
564                                         image->comps[2].data[index] = pixel[0]; /* B */
565                                         index++;
566                                 }
567                         }
568
569                         free(RGB);
570
571                 } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) {
572                         table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
573                         table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
574                         table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
575                         
576                         for (j = 0; j < Info_h.biClrUsed; j++) {
577                                 table_B[j] = getc(IN);
578                                 table_G[j] = getc(IN);
579                                 table_R[j] = getc(IN);
580                                 getc(IN);
581                                 if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j])
582                                         gray_scale = 0;
583                         }
584                         
585                         /* Place the cursor at the beginning of the image information */
586                         fseek(IN, 0, SEEK_SET);
587                         fseek(IN, File_h.bfOffBits, SEEK_SET);
588                         
589                         W = Info_h.biWidth;
590                         H = Info_h.biHeight;
591                         if (Info_h.biWidth % 2)
592                                 W++;
593                         
594                         numcomps = gray_scale ? 1 : 3;
595                         color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;
596                         /* initialize image components */
597                         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
598                         for(i = 0; i < numcomps; i++) {
599                                 cmptparm[i].prec = 8;
600                                 cmptparm[i].bpp = 8;
601                                 cmptparm[i].sgnd = 0;
602                                 cmptparm[i].dx = subsampling_dx;
603                                 cmptparm[i].dy = subsampling_dy;
604                                 cmptparm[i].w = w;
605                                 cmptparm[i].h = h;
606                         }
607                         /* create the image */
608                         image = opj_image_create(numcomps, &cmptparm[0], color_space);
609                         if(!image) {
610                                 fclose(IN);
611                                 return NULL;
612                         }
613
614                         /* set image offset and reference grid */
615                         image->x0 = parameters->image_offset_x0;
616                         image->y0 = parameters->image_offset_y0;
617                         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
618                         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
619
620                         /* set image data */
621
622                         RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char));
623                         
624                         fread(RGB, sizeof(unsigned char), W * H, IN);
625                         if (gray_scale) {
626                                 index = 0;
627                                 for (j = 0; j < W * H; j++) {
628                                         if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) {
629                                                 image->comps[0].data[index] = table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]];
630                                                 index++;
631                                         }
632                                 }
633
634                         } else {                
635                                 index = 0;
636                                 for (j = 0; j < W * H; j++) {
637                                         if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) {
638                                                 unsigned char pixel_index = RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)];
639                                                 image->comps[0].data[index] = table_R[pixel_index];
640                                                 image->comps[1].data[index] = table_G[pixel_index];
641                                                 image->comps[2].data[index] = table_B[pixel_index];
642                                                 index++;
643                                         }
644                                 }
645                         }
646                         free(RGB);
647       free(table_R);
648       free(table_G);
649       free(table_B);
650                 } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) {                               
651                         table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
652                         table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
653                         table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
654                         
655                         for (j = 0; j < Info_h.biClrUsed; j++) {
656                                 table_B[j] = getc(IN);
657                                 table_G[j] = getc(IN);
658                                 table_R[j] = getc(IN);
659                                 getc(IN);
660                                 if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j])
661                                         gray_scale = 0;
662                         }
663
664                         numcomps = gray_scale ? 1 : 3;
665                         color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;
666                         /* initialize image components */
667                         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
668                         for(i = 0; i < numcomps; i++) {
669                                 cmptparm[i].prec = 8;
670                                 cmptparm[i].bpp = 8;
671                                 cmptparm[i].sgnd = 0;
672                                 cmptparm[i].dx = subsampling_dx;
673                                 cmptparm[i].dy = subsampling_dy;
674                                 cmptparm[i].w = w;
675                                 cmptparm[i].h = h;
676                         }
677                         /* create the image */
678                         image = opj_image_create(numcomps, &cmptparm[0], color_space);
679                         if(!image) {
680                                 fclose(IN);
681                                 return NULL;
682                         }
683
684                         /* set image offset and reference grid */
685                         image->x0 = parameters->image_offset_x0;
686                         image->y0 = parameters->image_offset_y0;
687                         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
688                         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
689
690                         /* set image data */
691                         
692                         /* Place the cursor at the beginning of the image information */
693                         fseek(IN, 0, SEEK_SET);
694                         fseek(IN, File_h.bfOffBits, SEEK_SET);
695                         
696                         RGB = (unsigned char *) malloc(Info_h.biWidth * Info_h.biHeight * sizeof(unsigned char));
697             
698                         while (not_end_file) {
699                                 v = getc(IN);
700                                 if (v) {
701                                         v2 = getc(IN);
702                                         for (i = 0; i < (int) v; i++) {
703                                                 RGB[line * Info_h.biWidth + col] = v2;
704                                                 col++;
705                                         }
706                                 } else {
707                                         v = getc(IN);
708                                         switch (v) {
709                                                 case 0:
710                                                         col = 0;
711                                                         line++;
712                                                         break;
713                                                 case 1:
714                                                         line++;
715                                                         not_end_file = 0;
716                                                         break;
717                                                 case 2:
718                                                         fprintf(stderr,"No Delta supported\n");
719                                                         opj_image_destroy(image);
720                                                         fclose(IN);
721                                                         return NULL;
722                                                 default:
723                                                         for (i = 0; i < v; i++) {
724                                                                 v2 = getc(IN);
725                                                                 RGB[line * Info_h.biWidth + col] = v2;
726                                                                 col++;
727                                                         }
728                                                         if (v % 2)
729                                                                 v2 = getc(IN);
730                                                         break;
731                                         }
732                                 }
733                         }
734                         if (gray_scale) {
735                                 index = 0;
736                                 for (line = 0; line < Info_h.biHeight; line++) {
737                                         for (col = 0; col < Info_h.biWidth; col++) {
738                                                 image->comps[0].data[index] = table_R[(int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]];
739                                                 index++;
740                                         }
741                                 }
742                         } else {
743                                 index = 0;
744                                 for (line = 0; line < Info_h.biHeight; line++) {
745                                         for (col = 0; col < Info_h.biWidth; col++) {
746                                                 unsigned char pixel_index = (int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col];
747                                                 image->comps[0].data[index] = table_R[pixel_index];
748                                                 image->comps[1].data[index] = table_G[pixel_index];
749                                                 image->comps[2].data[index] = table_B[pixel_index];
750                                                 index++;
751                                         }
752                                 }
753                         }
754                         free(RGB);
755       free(table_R);
756       free(table_G);
757       free(table_B);
758         } else {
759                 fprintf(stderr, 
760                         "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount);
761         }
762         fclose(IN);
763  }
764  
765  return image;
766 }
767
768 int imagetobmp(opj_image_t * image, const char *outfile) {
769         int w, h;
770         int i, pad;
771         FILE *fdest = NULL;
772         int adjustR, adjustG, adjustB;
773
774         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
775                 && image->comps[1].dx == image->comps[2].dx
776                 && image->comps[0].dy == image->comps[1].dy
777                 && image->comps[1].dy == image->comps[2].dy
778                 && image->comps[0].prec == image->comps[1].prec
779                 && image->comps[1].prec == image->comps[2].prec) {
780                 
781                 /* -->> -->> -->> -->>    
782                 24 bits color       
783                 <<-- <<-- <<-- <<-- */
784             
785                 fdest = fopen(outfile, "wb");
786                 if (!fdest) {
787                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
788                         return 1;
789                 }
790             
791                 w = image->comps[0].w;      
792                 h = image->comps[0].h;
793             
794                 fprintf(fdest, "BM");
795             
796                 /* FILE HEADER */
797                 /* ------------- */
798                 fprintf(fdest, "%c%c%c%c",
799                         (unsigned char) (h * w * 3 + 3 * h * (w % 2) + 54) & 0xff,
800                         (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54)     >> 8) & 0xff,
801                         (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54)     >> 16) & 0xff,
802                         (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54)     >> 24) & 0xff);
803                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
804                 fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
805             
806                 /* INFO HEADER   */
807                 /* ------------- */
808                 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
809                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff),
810                         (unsigned char) ((w) >> 8) & 0xff,
811                         (unsigned char) ((w) >> 16) & 0xff,
812                         (unsigned char) ((w) >> 24) & 0xff);
813                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff),
814                         (unsigned char) ((h) >> 8) & 0xff,
815                         (unsigned char) ((h) >> 16) & 0xff,
816                         (unsigned char) ((h) >> 24) & 0xff);
817                 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
818                 fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
819                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
820                 fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * h * w + 3 * h * (w % 2)) & 0xff,
821                         (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 8) & 0xff,
822                         (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 16) & 0xff,
823                         (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 24) & 0xff);
824                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
825                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
826                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
827                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
828             
829                 if (image->comps[0].prec > 8) {
830                         adjustR = image->comps[0].prec - 8;
831                         printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
832                 }
833                 else 
834                         adjustR = 0;
835                 if (image->comps[1].prec > 8) {
836                         adjustG = image->comps[1].prec - 8;
837                         printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
838                 }
839                 else 
840                         adjustG = 0;
841                 if (image->comps[2].prec > 8) {
842                         adjustB = image->comps[2].prec - 8;
843                         printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
844                 }
845                 else 
846                         adjustB = 0;
847
848                 for (i = 0; i < w * h; i++) {
849                         unsigned char rc, gc, bc;
850                         int r, g, b;
851                                                         
852                         r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
853                         r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
854                         rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2));
855                         g = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
856                         g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
857                         gc = (unsigned char) ((g >> adjustG)+((g >> (adjustG-1))%2));
858                         b = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
859                         b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
860                         bc = (unsigned char) ((b >> adjustB)+((b >> (adjustB-1))%2));
861
862                         fprintf(fdest, "%c%c%c", bc, gc, rc);
863                         
864                         if ((i + 1) % w == 0) {
865                                 for (pad = (3 * w) % 4 ? 4 - (3 * w) % 4 : 0; pad > 0; pad--)   /* ADD */
866                                         fprintf(fdest, "%c", 0);
867                         }
868                 }
869                 fclose(fdest);
870         } else {                        /* Gray-scale */
871
872                 /* -->> -->> -->> -->>
873                 8 bits non code (Gray scale)
874                 <<-- <<-- <<-- <<-- */
875
876                 fdest = fopen(outfile, "wb");
877                 w = image->comps[0].w;      
878                 h = image->comps[0].h;
879             
880                 fprintf(fdest, "BM");
881             
882                 /* FILE HEADER */
883                 /* ------------- */
884                 fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + 54 + 1024 + h * (w % 2)) & 0xff,
885                         (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 8) & 0xff,
886                         (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 16) & 0xff,
887                         (unsigned char) ((h * w + 54 + 1024 + w * (w % 2)) >> 24) & 0xff);
888                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
889                 fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff, 
890                         ((54 + 1024) >> 16) & 0xff,
891                         ((54 + 1024) >> 24) & 0xff);
892             
893                 /* INFO HEADER */
894                 /* ------------- */
895                 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
896                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff),
897                         (unsigned char) ((w) >> 8) & 0xff,
898                         (unsigned char) ((w) >> 16) & 0xff,
899                         (unsigned char) ((w) >> 24) & 0xff);
900                 fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff),
901                         (unsigned char) ((h) >> 8) & 0xff,
902                         (unsigned char) ((h) >> 16) & 0xff,
903                         (unsigned char) ((h) >> 24) & 0xff);
904                 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
905                 fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
906                 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
907                 fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + h * (w % 2)) & 0xff,
908                         (unsigned char) ((h * w + h * (w % 2)) >> 8) &  0xff,
909                         (unsigned char) ((h * w + h * (w % 2)) >> 16) & 0xff,
910                         (unsigned char) ((h * w + h * (w % 2)) >> 24) & 0xff);
911                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
912                 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
913                 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
914                 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
915
916                 if (image->comps[0].prec > 8) {
917                         adjustR = image->comps[0].prec - 8;
918                         printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
919                 }else 
920                         adjustR = 0;
921
922                 for (i = 0; i < 256; i++) {
923                         fprintf(fdest, "%c%c%c%c", i, i, i, 0);
924                 }
925
926                 for (i = 0; i < w * h; i++) {
927                         unsigned char rc;
928                         int r;
929                         
930                         r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
931                         r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
932                         rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2));
933                         
934                         fprintf(fdest, "%c", rc);
935
936                         if ((i + 1) % w == 0) {
937                                 for (pad = w % 4 ? 4 - w % 4 : 0; pad > 0; pad--)       /* ADD */
938                                         fprintf(fdest, "%c", 0);
939                         }
940                 }
941                 fclose(fdest);
942         }
943
944         return 0;
945 }
946
947 /* -->> -->> -->> -->>
948
949 PGX IMAGE FORMAT
950
951 <<-- <<-- <<-- <<-- */
952
953
954 unsigned char readuchar(FILE * f)
955 {
956   unsigned char c1;
957   fread(&c1, 1, 1, f);
958   return c1;
959 }
960
961 unsigned short readushort(FILE * f, int bigendian)
962 {
963   unsigned char c1, c2;
964   fread(&c1, 1, 1, f);
965   fread(&c2, 1, 1, f);
966   if (bigendian)
967     return (c1 << 8) + c2;
968   else
969     return (c2 << 8) + c1;
970 }
971
972 unsigned int readuint(FILE * f, int bigendian)
973 {
974   unsigned char c1, c2, c3, c4;
975   fread(&c1, 1, 1, f);
976   fread(&c2, 1, 1, f);
977   fread(&c3, 1, 1, f);
978   fread(&c4, 1, 1, f);
979   if (bigendian)
980     return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
981   else
982     return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1;
983 }
984
985 opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) {
986         FILE *f = NULL;
987         int w, h, prec;
988         int i, numcomps, max;
989         OPJ_COLOR_SPACE color_space;
990         opj_image_cmptparm_t cmptparm;  /* maximum of 1 component  */
991         opj_image_t * image = NULL;
992
993         char endian1,endian2,sign;
994         char signtmp[32];
995
996         char temp[32];
997         int bigendian;
998         opj_image_comp_t *comp = NULL;
999
1000         numcomps = 1;
1001         color_space = CLRSPC_GRAY;
1002
1003         memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t));
1004
1005         max = 0;
1006
1007         f = fopen(filename, "rb");
1008         if (!f) {
1009           fprintf(stderr, "Failed to open %s for reading !\n", filename);
1010           return NULL;
1011         }
1012
1013         fseek(f, 0, SEEK_SET);
1014         fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h);
1015         
1016         i=0;
1017         sign='+';               
1018         while (signtmp[i]!='\0') {
1019                 if (signtmp[i]=='-') sign='-';
1020                 i++;
1021         }
1022         
1023         fgetc(f);
1024         if (endian1=='M' && endian2=='L') {
1025                 bigendian = 1;
1026         } else if (endian2=='M' && endian1=='L') {
1027                 bigendian = 0;
1028         } else {
1029                 fprintf(stderr, "Bad pgx header, please check input file\n");
1030                 return NULL;
1031         }
1032
1033         /* initialize image component */
1034
1035         cmptparm.x0 = parameters->image_offset_x0;
1036         cmptparm.y0 = parameters->image_offset_y0;
1037         cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1;
1038         cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1;
1039         
1040         if (sign == '-') {
1041                 cmptparm.sgnd = 1;
1042         } else {
1043                 cmptparm.sgnd = 0;
1044         }
1045         cmptparm.prec = prec;
1046         cmptparm.bpp = prec;
1047         cmptparm.dx = parameters->subsampling_dx;
1048         cmptparm.dy = parameters->subsampling_dy;
1049         
1050         /* create the image */
1051         image = opj_image_create(numcomps, &cmptparm, color_space);
1052         if(!image) {
1053                 fclose(f);
1054                 return NULL;
1055         }
1056         /* set image offset and reference grid */
1057         image->x0 = cmptparm.x0;
1058         image->y0 = cmptparm.x0;
1059         image->x1 = cmptparm.w;
1060         image->y1 = cmptparm.h;
1061
1062         /* set image data */
1063
1064         comp = &image->comps[0];
1065
1066         for (i = 0; i < w * h; i++) {
1067                 int v;
1068                 if (comp->prec <= 8) {
1069                         if (!comp->sgnd) {
1070                                 v = readuchar(f);
1071                         } else {
1072                                 v = (char) readuchar(f);
1073                         }
1074                 } else if (comp->prec <= 16) {
1075                         if (!comp->sgnd) {
1076                                 v = readushort(f, bigendian);
1077                         } else {
1078                                 v = (short) readushort(f, bigendian);
1079                         }
1080                 } else {
1081                         if (!comp->sgnd) {
1082                                 v = readuint(f, bigendian);
1083                         } else {
1084                                 v = (int) readuint(f, bigendian);
1085                         }
1086                 }
1087                 if (v > max)
1088                         max = v;
1089                 comp->data[i] = v;
1090         }
1091         fclose(f);
1092         comp->bpp = int_floorlog2(max) + 1;
1093
1094         return image;
1095 }
1096
1097 int imagetopgx(opj_image_t * image, const char *outfile) {
1098         int w, h;
1099         int i, j, compno;
1100         FILE *fdest = NULL;
1101
1102         for (compno = 0; compno < image->numcomps; compno++) {
1103                 opj_image_comp_t *comp = &image->comps[compno];
1104                 char bname[256]; /* buffer for name */
1105     char *name = bname; /* pointer */
1106     int nbytes = 0;
1107     const size_t olen = strlen(outfile);
1108     const size_t dotpos = olen - 4;
1109     const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */
1110     if( outfile[dotpos] != '.' ) {
1111       /* `pgx` was recognized but there is no dot at expected position */
1112       fprintf(stderr, "ERROR -> Impossible happen." );
1113       return 1;
1114       }
1115     if( total > 256 ) {
1116       name = (char*)malloc(total+1);
1117       }
1118     strncpy(name, outfile, dotpos);
1119                 if (image->numcomps > 1) {
1120                         sprintf(name+dotpos, "-%d.pgx", compno);
1121                 } else {
1122                         strcpy(name+dotpos, ".pgx");
1123                 }
1124                 fdest = fopen(name, "wb");
1125                 if (!fdest) {
1126                         fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
1127                         return 1;
1128                 }
1129     /* dont need name anymore */
1130     if( total > 256 ) {
1131       free(name);
1132       }
1133
1134                 w = image->comps[compno].w;
1135                 h = image->comps[compno].h;
1136             
1137                 fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, w, h);
1138                 if (comp->prec <= 8) {
1139                         nbytes = 1;
1140                 } else if (comp->prec <= 16) {
1141                         nbytes = 2;
1142                 } else {
1143                         nbytes = 4;
1144                 }
1145                 for (i = 0; i < w * h; i++) {
1146                         int v = image->comps[compno].data[i];
1147                         for (j = nbytes - 1; j >= 0; j--) {
1148                                 char byte = (char) (v >> (j * 8));
1149                                 fwrite(&byte, 1, 1, fdest);
1150                         }
1151                 }
1152                 fclose(fdest);
1153         }
1154
1155         return 0;
1156 }
1157
1158 /* -->> -->> -->> -->>
1159
1160 PNM IMAGE FORMAT
1161
1162 <<-- <<-- <<-- <<-- */
1163
1164 opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) {
1165         int subsampling_dx = parameters->subsampling_dx;
1166         int subsampling_dy = parameters->subsampling_dy;
1167
1168         FILE *f = NULL;
1169         int i, compno, numcomps, w, h;
1170         OPJ_COLOR_SPACE color_space;
1171         opj_image_cmptparm_t cmptparm[3];       /* maximum of 3 components */
1172         opj_image_t * image = NULL;
1173         char value;
1174         
1175         f = fopen(filename, "rb");
1176         if (!f) {
1177                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
1178                 return 0;
1179         }
1180
1181         if (fgetc(f) != 'P')
1182                 return 0;
1183         value = fgetc(f);
1184
1185                 switch(value) {
1186                         case '2':       /* greyscale image type */
1187                         case '5':
1188                                 numcomps = 1;
1189                                 color_space = CLRSPC_GRAY;
1190                                 break;
1191                                 
1192                         case '3':       /* RGB image type */
1193                         case '6':
1194                                 numcomps = 3;
1195                                 color_space = CLRSPC_SRGB;
1196                                 break;
1197                                 
1198                         default:
1199                                 fclose(f);
1200                                 return NULL;
1201                 }
1202                 
1203                 fgetc(f);
1204                 
1205                 /* skip comments */
1206                 while(fgetc(f) == '#') while(fgetc(f) != '\n');
1207                 
1208                 fseek(f, -1, SEEK_CUR);
1209                 fscanf(f, "%d %d\n255", &w, &h);                        
1210                 fgetc(f);       /* <cr><lf> */
1211                 
1212         /* initialize image components */
1213         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
1214         for(i = 0; i < numcomps; i++) {
1215                 cmptparm[i].prec = 8;
1216                 cmptparm[i].bpp = 8;
1217                 cmptparm[i].sgnd = 0;
1218                 cmptparm[i].dx = subsampling_dx;
1219                 cmptparm[i].dy = subsampling_dy;
1220                 cmptparm[i].w = w;
1221                 cmptparm[i].h = h;
1222         }
1223         /* create the image */
1224         image = opj_image_create(numcomps, &cmptparm[0], color_space);
1225         if(!image) {
1226                 fclose(f);
1227                 return NULL;
1228         }
1229
1230         /* set image offset and reference grid */
1231         image->x0 = parameters->image_offset_x0;
1232         image->y0 = parameters->image_offset_y0;
1233         image->x1 = parameters->image_offset_x0 + (w - 1) *     subsampling_dx + 1;
1234         image->y1 = parameters->image_offset_y0 + (h - 1) *     subsampling_dy + 1;
1235
1236         /* set image data */
1237
1238         if ((value == '2') || (value == '3')) { /* ASCII */
1239                 for (i = 0; i < w * h; i++) {
1240                         for(compno = 0; compno < numcomps; compno++) {
1241                                 unsigned int index = 0;
1242                                 fscanf(f, "%u", &index);
1243                                 /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
1244                                 image->comps[compno].data[i] = index;
1245                         }
1246                 }
1247         } else if ((value == '5') || (value == '6')) {  /* BINARY */
1248                 for (i = 0; i < w * h; i++) {
1249                         for(compno = 0; compno < numcomps; compno++) {
1250                                 unsigned char index = 0;
1251                                 fread(&index, 1, 1, f);
1252                                 /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
1253                                 image->comps[compno].data[i] = index;
1254                         }
1255                 }
1256         }
1257
1258         fclose(f);
1259
1260         return image;
1261 }
1262
1263 int imagetopnm(opj_image_t * image, const char *outfile) 
1264 {
1265         int *red, *green, *blue, *alpha;
1266         int wr, hr, max;
1267         int i, compno, ncomp;
1268         int adjustR, adjustG, adjustB;
1269         int fails, is16, force16, want_gray, has_alpha;
1270         int prec, opj_prec, ushift, dshift, v;
1271         FILE *fdest = NULL;
1272         const char *tmp = outfile;
1273         char *destname;
1274
1275     if((opj_prec = image->comps[0].prec) > 16)
1276    {
1277         fprintf(stderr,"%s:%d:imagetopnm\n\tprecision %d is larger than 16"
1278         "\n\t: refused.\n",__FILE__,__LINE__,opj_prec);
1279         return 1;
1280    }
1281         prec = opj_prec;
1282     is16 = force16 = ushift = dshift = has_alpha = 0; fails = 1;
1283
1284     if(prec > 8 && prec < 16)
1285    {
1286      prec = 16; force16 = 1;
1287    }
1288         
1289         while (*tmp) ++tmp; tmp -= 2; 
1290         want_gray = (*tmp == 'g' || *tmp == 'G'); 
1291         ncomp = image->numcomps;
1292
1293         if (ncomp > 2 
1294         && image->comps[0].dx == image->comps[1].dx
1295         && image->comps[1].dx == image->comps[2].dx
1296         && image->comps[0].dy == image->comps[1].dy
1297         && image->comps[1].dy == image->comps[2].dy
1298         && image->comps[0].prec == image->comps[1].prec
1299         && image->comps[1].prec == image->comps[2].prec
1300         && !want_gray
1301            )
1302    {
1303         fdest = fopen(outfile, "wb");
1304
1305         if (!fdest) 
1306   {
1307         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1308         return fails;
1309   }
1310         wr = image->comps[0].w; hr = image->comps[0].h;
1311             
1312         max = (1<<prec) - 1; has_alpha = (ncomp == 4);
1313
1314         is16 = (prec == 16);
1315
1316     red = image->comps[0].data;
1317     green = image->comps[1].data;
1318     blue = image->comps[2].data;
1319         
1320         if(has_alpha)
1321   {
1322          fprintf(fdest, "P7\n# OpenJPEG-%s\nWIDTH %d\nHEIGHT %d\nDEPTH 4\n"
1323                 "MAXVAL %d\nTUPLTYPE RGB_ALPHA\nENDHDR\n", opj_version(),
1324                 wr, hr, max);
1325         alpha = image->comps[3].data;
1326   }
1327         else
1328   {
1329          fprintf(fdest, "P6\n# OpenJPEG-%s\n%d %d\n%d\n", 
1330                 opj_version(), wr, hr, max);
1331         alpha = NULL;
1332   }
1333     if(force16)
1334   {
1335     ushift = 16 - opj_prec; dshift = opj_prec - ushift;
1336   }
1337     adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
1338     adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
1339     adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
1340
1341     for(i = 0; i < wr * hr; ++i)
1342   {
1343         if(is16)
1344  {
1345 /* MSB first: 'man ppm' */
1346
1347         v = *red + adjustR; ++red;
1348
1349         if(force16) { v = (v<<ushift) + (v>>dshift); }
1350
1351 #if BYTE_ORDER == LITTLE_ENDIAN
1352         fprintf(fdest, "%c%c",(unsigned char)v, (unsigned char)(v/256));
1353 #else
1354                 fprintf(fdest, "%c%c",(unsigned char)(v/256), (unsigned char)v);
1355 #endif
1356         v = *green + adjustG; ++green;
1357
1358         if(force16) { v = (v<<ushift) + (v>>dshift); }
1359
1360 #if BYTE_ORDER == LITTLE_ENDIAN
1361         fprintf(fdest, "%c%c",(unsigned char)v, (unsigned char)(v/256));
1362 #else
1363                 fprintf(fdest, "%c%c",(unsigned char)(v/256), (unsigned char)v);
1364 #endif
1365
1366         v =  *blue + adjustB; ++blue;
1367
1368         if(force16) { v = (v<<ushift) + (v>>dshift); }
1369
1370 #if BYTE_ORDER == LITTLE_ENDIAN
1371         fprintf(fdest, "%c%c",(unsigned char)v, (unsigned char)(v/256));
1372 #else
1373                 fprintf(fdest, "%c%c",(unsigned char)(v/256), (unsigned char)v);
1374 #endif
1375
1376         if(has_alpha)
1377        {
1378         v = *alpha++;
1379
1380         if(force16) { v = (v<<ushift) + (v>>dshift); }
1381
1382 #if BYTE_ORDER == LITTLE_ENDIAN
1383         fprintf(fdest, "%c%c",(unsigned char)v, (unsigned char)(v/256));
1384 #else
1385                 fprintf(fdest, "%c%c",(unsigned char)(v/256), (unsigned char)v);
1386 #endif
1387        }
1388         continue;
1389
1390  }
1391 /* prec <= 8: */
1392
1393         fprintf(fdest, "%c%c%c",(unsigned char)*red++, (unsigned char)*green++,
1394                 (unsigned char)*blue++);
1395
1396         if(has_alpha)
1397          fprintf(fdest, "%c", (unsigned char)*alpha++);
1398
1399   }     /* for(i */
1400
1401         fclose(fdest); return 0;
1402    }
1403
1404     if(force16)
1405    {
1406     ushift = 16 - opj_prec; dshift = opj_prec - ushift;
1407    }
1408 /* YUV or MONO: */
1409         if(want_gray) ncomp = 1;
1410 //FIXME: with[out] alpha ?
1411         has_alpha = 0; alpha = NULL;
1412
1413         if (image->numcomps > ncomp) 
1414    {
1415         fprintf(stderr,"WARNING -> [PGM file] Only the first component\n");
1416         fprintf(stderr,"           is written to the file\n");
1417    }
1418         destname = (char*)malloc(strlen(outfile) + 8);
1419
1420         for (compno = 0; compno < ncomp; compno++) 
1421    {
1422         if (ncomp > 1) 
1423          sprintf(destname, "%d.%s", compno, outfile);
1424         else
1425          sprintf(destname, "%s", outfile);
1426
1427         fdest = fopen(destname, "wb");
1428         if (!fdest) 
1429   {
1430         fprintf(stderr, "ERROR -> failed to open %s for writing\n", destname);
1431         free(destname);
1432         return 1;
1433   }
1434         wr = image->comps[compno].w; hr = image->comps[compno].h;
1435
1436         max = (1<<prec) - 1;
1437
1438         fprintf(fdest, "P5\n#OpenJPEG-%s\n%d %d\n%d\n", 
1439                 opj_version(), wr, hr, max);
1440
1441         red = image->comps[compno].data;
1442         adjustR = 
1443         (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0);
1444
1445     if(prec > 8)
1446   {
1447 /* MSB first: 'man ppm' */
1448
1449         for (i = 0; i < wr * hr; i++) 
1450  {
1451
1452         v = *red + adjustR; ++red;
1453
1454         if(force16) { v = (v<<ushift) + (v>>dshift); }
1455
1456 #if BYTE_ORDER == LITTLE_ENDIAN
1457         fprintf(fdest, "%c%c",(unsigned char)v, (unsigned char)(v/256));
1458 #else
1459                 fprintf(fdest, "%c%c",(unsigned char)(v/256), (unsigned char)v);
1460 #endif
1461
1462         if(has_alpha)
1463       {
1464         v = *alpha++;
1465
1466         if(force16) { v = (v<<ushift) + (v>>dshift); }
1467
1468 #if BYTE_ORDER == LITTLE_ENDIAN
1469         fprintf(fdest, "%c%c",(unsigned char)v, (unsigned char)(v/256));
1470 #else
1471                 fprintf(fdest, "%c%c",(unsigned char)(v/256), (unsigned char)v);
1472 #endif
1473       }
1474
1475  }/* for(i */
1476   }
1477         else /* prec <= 8 */
1478   {
1479         for(i = 0; i < wr * hr; ++i)
1480  {
1481          fprintf(fdest, "%c", (unsigned char)(*red + adjustR)); ++red;
1482  }
1483   }
1484         fclose(fdest);
1485    } /* for (compno */
1486         free(destname);
1487
1488         return 0;
1489 }/* imagetopnm() */
1490
1491 #ifdef HAVE_LIBTIFF
1492 /* -->> -->> -->> -->>
1493
1494         TIFF IMAGE FORMAT
1495
1496  <<-- <<-- <<-- <<-- */
1497
1498 typedef struct tiff_infoheader{
1499         DWORD tiWidth;  // Width of Image in pixel
1500         DWORD tiHeight; // Height of Image in pixel
1501         DWORD tiPhoto;  // Photometric
1502         WORD  tiBps;    // Bits per sample
1503         WORD  tiSf;             // Sample Format
1504         WORD  tiSpp;    // Sample per pixel 1-bilevel,gray scale , 2- RGB
1505         WORD  tiPC;     // Planar config (1-Interleaved, 2-Planarcomp)
1506 }tiff_infoheader_t;
1507
1508 int imagetotif(opj_image_t * image, const char *outfile) {
1509         int width, height, imgsize;
1510         int bps,index,adjust = 0;
1511         unsigned int last_i=0;
1512         TIFF *tif;
1513         tdata_t buf;
1514         tstrip_t strip;
1515         tsize_t strip_size;
1516
1517         if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
1518                 && image->comps[1].dx == image->comps[2].dx
1519                 && image->comps[0].dy == image->comps[1].dy
1520                 && image->comps[1].dy == image->comps[2].dy
1521                 && image->comps[0].prec == image->comps[1].prec
1522                 && image->comps[1].prec == image->comps[2].prec) {
1523
1524                         /* -->> -->> -->>    
1525                         RGB color           
1526                         <<-- <<-- <<-- */
1527
1528                         tif = TIFFOpen(outfile, "wb"); 
1529                         if (!tif) {
1530                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1531                                 return 1;
1532                         }
1533
1534                         width   = image->comps[0].w;
1535                         height  = image->comps[0].h;
1536                         imgsize = width * height ;
1537                         bps             = image->comps[0].prec;
1538                         /* Set tags */
1539                         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
1540                         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
1541                         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
1542                         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
1543                         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
1544                         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1545                         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
1546                         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
1547
1548                         /* Get a buffer for the data */
1549                         strip_size=TIFFStripSize(tif);
1550                         buf = _TIFFmalloc(strip_size);
1551                         index=0;                
1552                         adjust = image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0;
1553                         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1554                                 unsigned char *dat8;
1555                                 tsize_t i, ssize;
1556                                 ssize = TIFFStripSize(tif);
1557                                 dat8 = (unsigned char*)buf;
1558                                 if (image->comps[0].prec == 8){
1559                                         for (i=0; i<ssize-2; i+=3) {    // 8 bits per pixel 
1560                                                 int r = 0,g = 0,b = 0;
1561                                                 if(index < imgsize){
1562                                                         r = image->comps[0].data[index];
1563                                                         g = image->comps[1].data[index];
1564                                                         b = image->comps[2].data[index];
1565                                                         if (image->comps[0].sgnd){                      
1566                                                                 r += adjust;
1567                                                                 g += adjust;
1568                                                                 b += adjust;
1569                                                         }
1570                                                         dat8[i+0] = r ; // R 
1571                                                         dat8[i+1] = g ; // G 
1572                                                         dat8[i+2] = b ; // B 
1573                                                         index++;
1574                                                         last_i = i+3;
1575                                                 }else
1576                                                         break;
1577                                         }
1578                                         if(last_i < ssize){
1579                                                 for (i=last_i; i<ssize; i+=3) { // 8 bits per pixel 
1580                                                         int r = 0,g = 0,b = 0;
1581                                                         if(index < imgsize){
1582                                                                 r = image->comps[0].data[index];
1583                                                                 g = image->comps[1].data[index];
1584                                                                 b = image->comps[2].data[index];
1585                                                                 if (image->comps[0].sgnd){                      
1586                                                                         r += adjust;
1587                                                                         g += adjust;
1588                                                                         b += adjust;
1589                                                                 }
1590                                                                 dat8[i+0] = r ; // R 
1591                                                                 if(i+1 <ssize) dat8[i+1] = g ;  else break;// G 
1592                                                                 if(i+2 <ssize) dat8[i+2] = b ;  else break;// B 
1593                                                                 index++;
1594                                                         }else
1595                                                                 break;
1596                                                 }
1597                                         }
1598                                 }else if (image->comps[0].prec == 12){
1599                                         for (i=0; i<ssize-8; i+=9) {    // 12 bits per pixel 
1600                                                 int r = 0,g = 0,b = 0;
1601                                                 int r1 = 0,g1 = 0,b1 = 0;
1602                                                 if((index < imgsize)&(index+1 < imgsize)){
1603                                                         r  = image->comps[0].data[index];
1604                                                         g  = image->comps[1].data[index];
1605                                                         b  = image->comps[2].data[index];
1606                                                         r1 = image->comps[0].data[index+1];
1607                                                         g1 = image->comps[1].data[index+1];
1608                                                         b1 = image->comps[2].data[index+1];
1609                                                         if (image->comps[0].sgnd){                                                                                                              
1610                                                                 r  += adjust;
1611                                                                 g  += adjust;
1612                                                                 b  += adjust;
1613                                                                 r1 += adjust;
1614                                                                 g1 += adjust;
1615                                                                 b1 += adjust;
1616                                                         }
1617                                                         dat8[i+0] = (r >> 4);
1618                                                         dat8[i+1] = ((r & 0x0f) << 4 )|((g >> 8)& 0x0f);
1619                                                         dat8[i+2] = g ;         
1620                                                         dat8[i+3] = (b >> 4);
1621                                                         dat8[i+4] = ((b & 0x0f) << 4 )|((r1 >> 8)& 0x0f);
1622                                                         dat8[i+5] = r1;         
1623                                                         dat8[i+6] = (g1 >> 4);
1624                                                         dat8[i+7] = ((g1 & 0x0f)<< 4 )|((b1 >> 8)& 0x0f);
1625                                                         dat8[i+8] = b1;
1626                                                         index+=2;
1627                                                         last_i = i+9;
1628                                                 }else
1629                                                         break;
1630                                         }
1631                                         if(last_i < ssize){
1632                                                 for (i= last_i; i<ssize; i+=9) {        // 12 bits per pixel 
1633                                                         int r = 0,g = 0,b = 0;
1634                                                         int r1 = 0,g1 = 0,b1 = 0;
1635                                                         if((index < imgsize)&(index+1 < imgsize)){
1636                                                                 r  = image->comps[0].data[index];
1637                                                                 g  = image->comps[1].data[index];
1638                                                                 b  = image->comps[2].data[index];
1639                                                                 r1 = image->comps[0].data[index+1];
1640                                                                 g1 = image->comps[1].data[index+1];
1641                                                                 b1 = image->comps[2].data[index+1];
1642                                                                 if (image->comps[0].sgnd){                                                                                                              
1643                                                                         r  += adjust;
1644                                                                         g  += adjust;
1645                                                                         b  += adjust;
1646                                                                         r1 += adjust;
1647                                                                         g1 += adjust;
1648                                                                         b1 += adjust;
1649                                                                 }
1650                                                                 dat8[i+0] = (r >> 4);
1651                                                                 if(i+1 <ssize) dat8[i+1] = ((r & 0x0f) << 4 )|((g >> 8)& 0x0f); else break;
1652                                                                 if(i+2 <ssize) dat8[i+2] = g ;                  else break;
1653                                                                 if(i+3 <ssize) dat8[i+3] = (b >> 4);    else break;
1654                                                                 if(i+4 <ssize) dat8[i+4] = ((b & 0x0f) << 4 )|((r1 >> 8)& 0x0f);else break;
1655                                                                 if(i+5 <ssize) dat8[i+5] = r1;                  else break;
1656                                                                 if(i+6 <ssize) dat8[i+6] = (g1 >> 4);   else break;
1657                                                                 if(i+7 <ssize) dat8[i+7] = ((g1 & 0x0f)<< 4 )|((b1 >> 8)& 0x0f);else break;
1658                                                                 if(i+8 <ssize) dat8[i+8] = b1;                  else break;
1659                                                                 index+=2;
1660                                                         }else
1661                                                                 break;
1662                                                 }
1663                                         }
1664                                 }else if (image->comps[0].prec == 16){
1665                                         for (i=0 ; i<ssize-5 ; i+=6) {  // 16 bits per pixel 
1666                                                 int r = 0,g = 0,b = 0;
1667                                                 if(index < imgsize){
1668                                                         r = image->comps[0].data[index];
1669                                                         g = image->comps[1].data[index];
1670                                                         b = image->comps[2].data[index];
1671                                                         if (image->comps[0].sgnd){
1672                                                         r += adjust;
1673                                                         g += adjust;
1674                                                         b += adjust;
1675                                                         }
1676                                                         dat8[i+0] =  r;//LSB
1677                                                         dat8[i+1] = (r >> 8);//MSB       
1678                                                         dat8[i+2] =  g;         
1679                                                         dat8[i+3] = (g >> 8);
1680                                                         dat8[i+4] =  b; 
1681                                                         dat8[i+5] = (b >> 8);
1682                                                         index++;
1683                                                         last_i = i+6;
1684                                                 }else
1685                                                         break; 
1686                                         }
1687                                         if(last_i < ssize){
1688                                                 for (i=0 ; i<ssize ; i+=6) {    // 16 bits per pixel 
1689                                                         int r = 0,g = 0,b = 0;
1690                                                         if(index < imgsize){
1691                                                                 r = image->comps[0].data[index];
1692                                                                 g = image->comps[1].data[index];
1693                                                                 b = image->comps[2].data[index];
1694                                                                 if (image->comps[0].sgnd){
1695                                                                         r += adjust;
1696                                                                         g += adjust;
1697                                                                         b += adjust;
1698                                                                 }
1699                                                                 dat8[i+0] =  r;//LSB
1700                                                                 if(i+1 <ssize) dat8[i+1] = (r >> 8);else break;//MSB     
1701                                                                 if(i+2 <ssize) dat8[i+2] =  g;          else break;
1702                                                                 if(i+3 <ssize) dat8[i+3] = (g >> 8);else break;
1703                                                                 if(i+4 <ssize) dat8[i+4] =  b;          else break;
1704                                                                 if(i+5 <ssize) dat8[i+5] = (b >> 8);else break;
1705                                                                 index++;
1706                                                         }else
1707                                                                 break; 
1708                                                 }                                               
1709                                         }
1710                                 }else{
1711                                         fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec);
1712                                         fprintf(stderr,"Aborting\n");
1713                                         return 1;
1714                                 }
1715                                 (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size);
1716                         }
1717                         _TIFFfree((void*)buf);
1718                         TIFFClose(tif);
1719                 }else if (image->numcomps == 1){
1720                         /* -->> -->> -->>    
1721                         Black and White     
1722                         <<-- <<-- <<-- */
1723
1724                         tif = TIFFOpen(outfile, "wb"); 
1725                         if (!tif) {
1726                                 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1727                                 return 1;
1728                         }
1729
1730                         width   = image->comps[0].w;
1731                         height  = image->comps[0].h;
1732                         imgsize = width * height;
1733                         bps             = image->comps[0].prec;
1734
1735                         /* Set tags */
1736                         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
1737                         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
1738                         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
1739                         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
1740                         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
1741                         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1742                         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
1743                         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
1744
1745                         /* Get a buffer for the data */
1746                         strip_size = TIFFStripSize(tif);
1747                         buf = _TIFFmalloc(strip_size);
1748                         index = 0;                      
1749                         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1750                                 unsigned char *dat8;
1751                                 tsize_t i;
1752                                 dat8 = (unsigned char*)buf;
1753                                 if (image->comps[0].prec == 8){
1754                                         for (i=0; i<TIFFStripSize(tif); i+=1) { // 8 bits per pixel 
1755                                                 if(index < imgsize){
1756                                                         int r = 0;
1757                                                         r = image->comps[0].data[index];
1758                                                         if (image->comps[0].sgnd){
1759                                                                 r  += adjust;
1760                                                         }
1761                                                         dat8[i+0] = r;
1762                                                         index++;
1763                                                 }else
1764                                                         break; 
1765                                         }
1766                                 }else if (image->comps[0].prec == 12){
1767                                         for (i = 0; i<TIFFStripSize(tif); i+=3) {       // 12 bits per pixel 
1768                                                 if(index < imgsize){
1769                                                         int r = 0, r1 = 0;
1770                                                         r  = image->comps[0].data[index];
1771                                                         r1 = image->comps[0].data[index+1];
1772                                                         if (image->comps[0].sgnd){
1773                                                                 r  += adjust;
1774                                                                 r1 += adjust;
1775                                                         }
1776                                                         dat8[i+0] = (r >> 4);
1777                                                         dat8[i+1] = ((r & 0x0f) << 4 )|((r1 >> 8)& 0x0f);
1778                                                         dat8[i+2] = r1 ;
1779                                                         index+=2;
1780                                                 }else
1781                                                         break; 
1782                                         }
1783                                 }else if (image->comps[0].prec == 16){
1784                                         for (i=0; i<TIFFStripSize(tif); i+=2) { // 16 bits per pixel 
1785                                                 if(index < imgsize){
1786                                                         int r = 0;
1787                                                         r = image->comps[0].data[index];
1788                                                         if (image->comps[0].sgnd){
1789                                                                 r  += adjust;
1790                                                         }
1791                                                         dat8[i+0] = r;
1792                                                         dat8[i+1] = r >> 8;
1793                                                         index++;
1794                                                 }else
1795                                                         break; 
1796                                         }
1797                                 }else{
1798                                         fprintf(stderr,"TIFF file creation. Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec);
1799                                         fprintf(stderr,"Aborting\n");
1800                                         return 1;
1801                                 }
1802                                 (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size);
1803                         }
1804                         _TIFFfree(buf);
1805                         TIFFClose(tif);
1806                 }else{
1807                         fprintf(stderr,"TIFF file creation. Bad color format. Only RGB & Grayscale has been implemented\n");
1808                         fprintf(stderr,"Aborting\n");
1809                         return 1;
1810                 }
1811                 return 0;
1812 }
1813
1814 opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
1815 {
1816         int subsampling_dx = parameters->subsampling_dx;
1817         int subsampling_dy = parameters->subsampling_dy;
1818         TIFF *tif;
1819         tiff_infoheader_t Info;
1820         tdata_t buf;
1821         tstrip_t strip;
1822         tsize_t strip_size;
1823         int j, numcomps, w, h,index;
1824         OPJ_COLOR_SPACE color_space;
1825         opj_image_cmptparm_t cmptparm[3];
1826         opj_image_t * image = NULL;
1827         int imgsize = 0;
1828
1829         tif = TIFFOpen(filename, "r");
1830
1831         if (!tif) {
1832                 fprintf(stderr, "Failed to open %s for reading\n", filename);
1833                 return 0;
1834         }
1835
1836         TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &Info.tiWidth);
1837         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &Info.tiHeight);
1838         TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &Info.tiBps);
1839         TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &Info.tiSf);
1840         TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &Info.tiSpp);
1841         Info.tiPhoto = 0;
1842         TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &Info.tiPhoto);
1843         TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &Info.tiPC);
1844         w= Info.tiWidth;
1845         h= Info.tiHeight;
1846         
1847         if (Info.tiPhoto == 2) { 
1848                 /* -->> -->> -->>    
1849                 RGB color           
1850                 <<-- <<-- <<-- */
1851
1852                 numcomps = 3;
1853                 color_space = CLRSPC_SRGB;
1854                 /* initialize image components*/ 
1855                 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
1856                 for(j = 0; j < numcomps; j++) {
1857                         if (parameters->cp_cinema) {
1858                                 cmptparm[j].prec = 12;
1859                                 cmptparm[j].bpp = 12;
1860                         }else{
1861                                 cmptparm[j].prec = Info.tiBps;
1862                                 cmptparm[j].bpp = Info.tiBps;
1863                         }
1864                         cmptparm[j].sgnd = 0;
1865                         cmptparm[j].dx = subsampling_dx;
1866                         cmptparm[j].dy = subsampling_dy;
1867                         cmptparm[j].w = w;
1868                         cmptparm[j].h = h;
1869                 }
1870                 /* create the image*/ 
1871                 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1872                 if(!image) {
1873                         TIFFClose(tif);
1874                         return NULL;
1875                 }
1876
1877                 /* set image offset and reference grid */
1878                 image->x0 = parameters->image_offset_x0;
1879                 image->y0 = parameters->image_offset_y0;
1880                 image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
1881                 image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
1882
1883                 buf = _TIFFmalloc(TIFFStripSize(tif));
1884                 strip_size=0;
1885                 strip_size=TIFFStripSize(tif);
1886                 index = 0;
1887                 imgsize = image->comps[0].w * image->comps[0].h ;
1888                 /* Read the Image components*/
1889                 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1890                         unsigned char *dat8;
1891                         int i, ssize;
1892                         ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
1893                         dat8 = (unsigned char*)buf;
1894
1895                         if (Info.tiBps==12){
1896                                 for (i=0; i<ssize; i+=9) {      /*12 bits per pixel*/
1897                                         if((index < imgsize)&(index+1 < imgsize)){
1898                                                 image->comps[0].data[index]   = ( dat8[i+0]<<4 )                |(dat8[i+1]>>4);
1899                                                 image->comps[1].data[index]   = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2];
1900                                                 image->comps[2].data[index]   = ( dat8[i+3]<<4)                 |(dat8[i+4]>>4);
1901                                                 image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5];
1902                                                 image->comps[1].data[index+1] = ( dat8[i+6] <<4)                |(dat8[i+7]>>4);
1903                                                 image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8];
1904                                                 index+=2;
1905                                         }else
1906                                                 break;
1907                                 }
1908                         }
1909                         else if( Info.tiBps==16){
1910                                 for (i=0; i<ssize; i+=6) {      /* 16 bits per pixel */
1911                                         if(index < imgsize){
1912                                                 image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; // R 
1913                                                 image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; // G 
1914                                                 image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4]; // B 
1915                                                 if(parameters->cp_cinema){/* Rounding to 12 bits*/
1916                                                         image->comps[0].data[index] = (image->comps[0].data[index] + 0x08) >> 4 ;
1917                                                         image->comps[1].data[index] = (image->comps[1].data[index] + 0x08) >> 4 ;
1918                                                         image->comps[2].data[index] = (image->comps[2].data[index] + 0x08) >> 4 ;
1919                                                 }
1920                                                 index++;
1921                                         }else
1922                                                 break;
1923                                 }
1924                         }
1925                         else if ( Info.tiBps==8){
1926                                 for (i=0; i<ssize; i+=3) {      /* 8 bits per pixel */
1927                                         if(index < imgsize){
1928                                                 image->comps[0].data[index] = dat8[i+0];// R 
1929                                                 image->comps[1].data[index] = dat8[i+1];// G 
1930                                                 image->comps[2].data[index] = dat8[i+2];// B 
1931                                                 if(parameters->cp_cinema){/* Rounding to 12 bits*/
1932                                                         image->comps[0].data[index] = image->comps[0].data[index] << 4 ;
1933                                                         image->comps[1].data[index] = image->comps[1].data[index] << 4 ;
1934                                                         image->comps[2].data[index] = image->comps[2].data[index] << 4 ;
1935                                                 }
1936                                                 index++;
1937                                         }else
1938                                                 break;
1939                                 }
1940                         }
1941                         else{
1942                                 fprintf(stderr,"TIFF file creation. Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps);
1943                                 fprintf(stderr,"Aborting\n");
1944                                 return NULL;
1945                         }
1946                 }
1947
1948                 _TIFFfree(buf);
1949                 TIFFClose(tif);
1950         }else if(Info.tiPhoto == 1) { 
1951                 /* -->> -->> -->>    
1952                 Black and White
1953                 <<-- <<-- <<-- */
1954
1955                 numcomps = 1;
1956                 color_space = CLRSPC_GRAY;
1957                 /* initialize image components*/ 
1958                 memset(&cmptparm[0], 0, sizeof(opj_image_cmptparm_t));
1959                 cmptparm[0].prec = Info.tiBps;
1960                 cmptparm[0].bpp = Info.tiBps;
1961                 cmptparm[0].sgnd = 0;
1962                 cmptparm[0].dx = subsampling_dx;
1963                 cmptparm[0].dy = subsampling_dy;
1964                 cmptparm[0].w = w;
1965                 cmptparm[0].h = h;
1966
1967                 /* create the image*/ 
1968                 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1969                 if(!image) {
1970                         TIFFClose(tif);
1971                         return NULL;
1972                 }
1973                 /* set image offset and reference grid */
1974                 image->x0 = parameters->image_offset_x0;
1975                 image->y0 = parameters->image_offset_y0;
1976                 image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
1977                 image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
1978
1979                 buf = _TIFFmalloc(TIFFStripSize(tif));
1980                 strip_size = 0;
1981                 strip_size = TIFFStripSize(tif);
1982                 index = 0;
1983                 imgsize = image->comps[0].w * image->comps[0].h ;
1984                 /* Read the Image components*/
1985                 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1986                         unsigned char *dat8;
1987                         int i, ssize;
1988                         ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
1989                         dat8 = (unsigned char*)buf;
1990
1991                         if (Info.tiBps==12){
1992                                 for (i=0; i<ssize; i+=3) {      /* 12 bits per pixel*/
1993                                         if(index < imgsize){
1994                                                 image->comps[0].data[index]   = ( dat8[i+0]<<4 )                |(dat8[i+1]>>4) ;
1995                                                 image->comps[0].data[index+1] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2];
1996                                                 index+=2;
1997                                         }else
1998                                                 break;
1999                                 }
2000                         }
2001                         else if( Info.tiBps==16){
2002                                 for (i=0; i<ssize; i+=2) {      /* 16 bits per pixel */
2003                                         if(index < imgsize){
2004                                                 image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0];
2005                                                 index++;
2006                                         }else
2007                                                 break;
2008                                 }
2009                         }
2010                         else if ( Info.tiBps==8){
2011                                 for (i=0; i<ssize; i+=1) {      /* 8 bits per pixel */
2012                                         if(index < imgsize){
2013                                                 image->comps[0].data[index] = dat8[i+0];
2014                                                 index++;
2015                                         }else
2016                                                 break;
2017                                 }
2018                         }
2019                         else{
2020                                 fprintf(stderr,"TIFF file creation. Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps);
2021                                 fprintf(stderr,"Aborting\n");
2022                                 return NULL;
2023                         }
2024                 }
2025
2026                 _TIFFfree(buf);
2027                 TIFFClose(tif);
2028         }else{
2029                 fprintf(stderr,"TIFF file creation. Bad color format. Only RGB & Grayscale has been implemented\n");
2030                 fprintf(stderr,"Aborting\n");
2031                 return NULL;
2032         }
2033         return image;
2034 }
2035
2036 #endif /* HAVE_LIBTIFF */
2037
2038 /* -->> -->> -->> -->>
2039
2040         RAW IMAGE FORMAT
2041
2042  <<-- <<-- <<-- <<-- */
2043
2044 opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) {
2045         int subsampling_dx = parameters->subsampling_dx;
2046         int subsampling_dy = parameters->subsampling_dy;
2047
2048         FILE *f = NULL;
2049         int i, compno, numcomps, w, h;
2050         OPJ_COLOR_SPACE color_space;
2051         opj_image_cmptparm_t *cmptparm; 
2052         opj_image_t * image = NULL;
2053         unsigned short ch;
2054         
2055         if((! (raw_cp->rawWidth & raw_cp->rawHeight & raw_cp->rawComp & raw_cp->rawBitDepth)) == 0)
2056         {
2057                 fprintf(stderr,"\nError: invalid raw image parameters\n");
2058                 fprintf(stderr,"Please use the Format option -F:\n");
2059                 fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
2060                 fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n");
2061                 fprintf(stderr,"Aborting\n");
2062                 return NULL;
2063         }
2064
2065         f = fopen(filename, "rb");
2066         if (!f) {
2067                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
2068                 fprintf(stderr,"Aborting\n");
2069                 return NULL;
2070         }
2071         numcomps = raw_cp->rawComp;
2072         color_space = CLRSPC_SRGB;
2073         w = raw_cp->rawWidth;
2074         h = raw_cp->rawHeight;
2075         cmptparm = (opj_image_cmptparm_t*) malloc(numcomps * sizeof(opj_image_cmptparm_t));
2076         
2077         /* initialize image components */       
2078         memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
2079         for(i = 0; i < numcomps; i++) {         
2080                 cmptparm[i].prec = raw_cp->rawBitDepth;
2081                 cmptparm[i].bpp = raw_cp->rawBitDepth;
2082                 cmptparm[i].sgnd = raw_cp->rawSigned;
2083                 cmptparm[i].dx = subsampling_dx;
2084                 cmptparm[i].dy = subsampling_dy;
2085                 cmptparm[i].w = w;
2086                 cmptparm[i].h = h;
2087         }
2088         /* create the image */
2089         image = opj_image_create(numcomps, &cmptparm[0], color_space);
2090         if(!image) {
2091                 fclose(f);
2092                 return NULL;
2093         }
2094         /* set image offset and reference grid */
2095         image->x0 = parameters->image_offset_x0;
2096         image->y0 = parameters->image_offset_y0;
2097         image->x1 = parameters->image_offset_x0 + (w - 1) *     subsampling_dx + 1;
2098         image->y1 = parameters->image_offset_y0 + (h - 1) *     subsampling_dy + 1;
2099
2100         if(raw_cp->rawBitDepth <= 8)
2101         {
2102                 unsigned char value = 0;
2103                 for(compno = 0; compno < numcomps; compno++) {
2104                         for (i = 0; i < w * h; i++) {
2105                                 if (!fread(&value, 1, 1, f)) {
2106                                         fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
2107                                         return NULL;
2108                                 }
2109                                 image->comps[compno].data[i] = raw_cp->rawSigned?(char)value:value;
2110                         }
2111                 }
2112         }
2113         else if(raw_cp->rawBitDepth <= 16)
2114         {
2115                 unsigned short value;
2116                 for(compno = 0; compno < numcomps; compno++) {
2117                         for (i = 0; i < w * h; i++) {
2118                                 unsigned char temp;
2119                                 if (!fread(&temp, 1, 1, f)) {
2120                                         fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
2121                                         return NULL;
2122                                 }
2123                                 value = temp << 8;
2124                                 if (!fread(&temp, 1, 1, f)) {
2125                                         fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
2126                                         return NULL;
2127                                 }
2128                                 value += temp;
2129                                 image->comps[compno].data[i] = raw_cp->rawSigned?(short)value:value;
2130                         }
2131                 }
2132         }
2133         else {
2134                 fprintf(stderr,"OpenJPEG cannot encode raw components with bit depth higher than 16 bits.\n");
2135                 return NULL;
2136         }
2137
2138         if (fread(&ch, 1, 1, f)) {
2139                 fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n");
2140         }
2141         fclose(f);
2142
2143         return image;
2144 }
2145
2146 int imagetoraw(opj_image_t * image, const char *outfile)
2147 {
2148         FILE *rawFile = NULL;
2149         int compno;
2150         int w, h;
2151         int line, row;
2152         int *ptr;
2153
2154         if((image->numcomps * image->x1 * image->y1) == 0)
2155         {
2156                 fprintf(stderr,"\nError: invalid raw image parameters\n");
2157                 return 1;
2158         }
2159
2160         rawFile = fopen(outfile, "wb");
2161         if (!rawFile) {
2162                 fprintf(stderr, "Failed to open %s for writing !!\n", outfile);
2163                 return 1;
2164         }
2165
2166         fprintf(stdout,"Raw image characteristics: %d components\n", image->numcomps);
2167
2168         for(compno = 0; compno < image->numcomps; compno++)
2169         {
2170                 fprintf(stdout,"Component %d characteristics: %dx%dx%d %s\n", compno, image->comps[compno].w,
2171                         image->comps[compno].h, image->comps[compno].prec, image->comps[compno].sgnd==1 ? "signed": "unsigned");
2172
2173                 w = image->comps[compno].w;
2174                 h = image->comps[compno].h;
2175
2176                 if(image->comps[compno].prec <= 8)
2177                 {
2178                         if(image->comps[compno].sgnd == 1)
2179                         {
2180                                 signed char curr;
2181                                 int mask = (1 << image->comps[compno].prec) - 1;
2182                                 ptr = image->comps[compno].data;
2183                                 for (line = 0; line < h; line++) {
2184                                         for(row = 0; row < w; row++)    {                               
2185                                                 curr = (signed char) (*ptr & mask);
2186                                                 fwrite(&curr, sizeof(signed char), 1, rawFile);
2187                                                 ptr++;
2188                                         }
2189                                 }
2190                         }
2191                         else if(image->comps[compno].sgnd == 0)
2192                         {
2193                                 unsigned char curr;
2194                                 int mask = (1 << image->comps[compno].prec) - 1;
2195                                 ptr = image->comps[compno].data;
2196                                 for (line = 0; line < h; line++) {
2197                                         for(row = 0; row < w; row++)    {       
2198                                                 curr = (unsigned char) (*ptr & mask);
2199                                                 fwrite(&curr, sizeof(unsigned char), 1, rawFile);
2200                                                 ptr++;
2201                                         }
2202                                 }
2203                         }
2204                 }
2205                 else if(image->comps[compno].prec <= 16)
2206                 {
2207                         if(image->comps[compno].sgnd == 1)
2208                         {
2209                                 signed short int curr;
2210                                 int mask = (1 << image->comps[compno].prec) - 1;
2211                                 ptr = image->comps[compno].data;
2212                                 for (line = 0; line < h; line++) {
2213                                         for(row = 0; row < w; row++)    {                                       
2214                                                 unsigned char temp;
2215                                                 curr = (signed short int) (*ptr & mask);
2216                                                 temp = (unsigned char) (curr >> 8);
2217                                                 fwrite(&temp, 1, 1, rawFile);
2218                                                 temp = (unsigned char) curr;
2219                                                 fwrite(&temp, 1, 1, rawFile);
2220                                                 ptr++;
2221                                         }
2222                                 }
2223                         }
2224                         else if(image->comps[compno].sgnd == 0)
2225                         {
2226                                 unsigned short int curr;
2227                                 int mask = (1 << image->comps[compno].prec) - 1;
2228                                 ptr = image->comps[compno].data;
2229                                 for (line = 0; line < h; line++) {
2230                                         for(row = 0; row < w; row++)    {                               
2231                                                 unsigned char temp;
2232                                                 curr = (unsigned short int) (*ptr & mask);
2233                                                 temp = (unsigned char) (curr >> 8);
2234                                                 fwrite(&temp, 1, 1, rawFile);
2235                                                 temp = (unsigned char) curr;
2236                                                 fwrite(&temp, 1, 1, rawFile);
2237                                                 ptr++;
2238                                         }
2239                                 }
2240                         }
2241                 }
2242                 else if (image->comps[compno].prec <= 32)
2243                 {
2244                         fprintf(stderr,"More than 16 bits per component no handled yet\n");
2245                         return 1;
2246                 }
2247                 else
2248                 {
2249                         fprintf(stderr,"Error: invalid precision: %d\n", image->comps[compno].prec);
2250                         return 1;
2251                 }
2252         }
2253         fclose(rawFile);
2254         return 0;
2255 }
2256
2257 #ifdef HAVE_LIBPNG
2258
2259 #define PNG_MAGIC "\x89PNG\x0d\x0a\x1a\x0a"
2260 #define MAGIC_SIZE 8
2261 /* PNG allows bits per sample: 1, 2, 4, 8, 16 */
2262
2263 opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
2264 {
2265         png_structp  png;
2266         png_infop    info;
2267         double gamma, display_exponent;
2268         int bit_depth, interlace_type,compression_type, filter_type;
2269         int unit;
2270         png_uint_32 resx, resy;
2271         unsigned int i, j;
2272         png_uint_32  width, height;
2273         int color_type, has_alpha, is16;
2274         unsigned char *s;
2275         FILE *reader;
2276         unsigned char **rows;
2277 /* j2k: */
2278         opj_image_t *image;
2279         opj_image_cmptparm_t cmptparm[4];
2280         int sub_dx, sub_dy;
2281         unsigned int nr_comp;
2282         int *r, *g, *b, *a;
2283         unsigned char sigbuf[8];
2284
2285         if((reader = fopen(read_idf, "rb")) == NULL)
2286    {
2287         fprintf(stderr,"pngtoimage: can not open %s\n",read_idf);
2288         return NULL;
2289    }
2290         image = NULL; png = NULL; rows = NULL;
2291
2292         if(fread(sigbuf, 1, MAGIC_SIZE, reader) != MAGIC_SIZE
2293         || memcmp(sigbuf, PNG_MAGIC, MAGIC_SIZE) != 0)
2294    {
2295         fprintf(stderr,"pngtoimage: %s is no valid PNG file\n",read_idf);
2296         goto fin;
2297    }
2298 /* libpng-VERSION/example.c: 
2299  * PC : screen_gamma = 2.2;
2300  * Mac: screen_gamma = 1.7 or 1.0;
2301 */
2302         display_exponent = 2.2;
2303
2304         if((png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
2305                                     NULL, NULL, NULL)) == NULL)
2306           goto fin;
2307         if((info = png_create_info_struct(png)) == NULL)
2308           goto fin;
2309
2310         if(setjmp(png_jmpbuf(png)))
2311           goto fin;
2312
2313         png_init_io(png, reader);
2314         png_set_sig_bytes(png, MAGIC_SIZE);
2315
2316         png_read_info(png, info);
2317
2318         if(png_get_IHDR(png, info, &width, &height,
2319                 &bit_depth, &color_type, &interlace_type, 
2320                 &compression_type, &filter_type) == 0)
2321          goto fin;
2322
2323 /* png_set_expand():
2324  * expand paletted images to RGB, expand grayscale images of
2325  * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
2326  * to alpha channels.
2327 */
2328         if(color_type == PNG_COLOR_TYPE_PALETTE)
2329           png_set_expand(png);
2330         else
2331         if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
2332           png_set_expand(png);
2333
2334         if(png_get_valid(png, info, PNG_INFO_tRNS))
2335           png_set_expand(png);
2336
2337         is16 = (bit_depth == 16);
2338
2339 /* GRAY => RGB; GRAY_ALPHA => RGBA
2340 */
2341         if(color_type == PNG_COLOR_TYPE_GRAY
2342         || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2343    {
2344         png_set_gray_to_rgb(png);
2345         color_type = 
2346          (color_type == PNG_COLOR_TYPE_GRAY? PNG_COLOR_TYPE_RGB:
2347                 PNG_COLOR_TYPE_RGB_ALPHA);
2348    }
2349         if( !png_get_gAMA(png, info, &gamma))
2350           gamma = 0.45455;
2351
2352         png_set_gamma(png, display_exponent, gamma);
2353
2354         png_read_update_info(png, info);
2355
2356         png_get_pHYs(png, info, &resx, &resy, &unit);
2357
2358         color_type = png_get_color_type(png, info);
2359
2360         has_alpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA);
2361
2362         nr_comp = 3 + has_alpha;
2363
2364         bit_depth = png_get_bit_depth(png, info);
2365
2366         rows = (unsigned char**)calloc(height+1, sizeof(unsigned char*));
2367         for(i = 0; i < height; ++i)
2368          rows[i] = (unsigned char*)malloc(png_get_rowbytes(png,info));
2369
2370         png_read_image(png, rows);
2371
2372         memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t));
2373
2374         sub_dx = params->subsampling_dx; sub_dy = params->subsampling_dy;
2375
2376         for(i = 0; i < nr_comp; ++i)
2377    {
2378         cmptparm[i].prec = bit_depth;
2379 /* bits_per_pixel: 8 or 16 */
2380         cmptparm[i].bpp = bit_depth;
2381         cmptparm[i].sgnd = 0;
2382         cmptparm[i].dx = sub_dx;
2383         cmptparm[i].dy = sub_dy;
2384         cmptparm[i].w = width;
2385         cmptparm[i].h = height;
2386    }
2387
2388         image = opj_image_create(nr_comp, &cmptparm[0], CLRSPC_SRGB);
2389
2390         if(image == NULL) goto fin;
2391
2392     image->x0 = params->image_offset_x0;
2393     image->y0 = params->image_offset_y0;
2394     image->x1 = image->x0 + (width  - 1) * sub_dx + 1 + image->x0;
2395     image->y1 = image->y0 + (height - 1) * sub_dy + 1 + image->y0;
2396
2397         r = image->comps[0].data;
2398         g = image->comps[1].data;
2399         b = image->comps[2].data;
2400         a = image->comps[3].data;
2401
2402         for(i = 0; i < height; ++i)
2403    {
2404         s = rows[i];
2405
2406         for(j = 0; j < width; ++j)
2407   {
2408         if(is16)
2409  {
2410         *r++ = s[0]<<8|s[1]; s += 2;
2411
2412         *g++ = s[0]<<8|s[1]; s += 2;
2413         
2414         *b++ = s[0]<<8|s[1]; s += 2;
2415         
2416         if(has_alpha) { *a++ = s[0]<<8|s[1]; s += 2; }
2417
2418         continue;
2419  }
2420         *r++ = *s++; *g++ = *s++; *b++ = *s++;
2421
2422         if(has_alpha) *a++ = *s++;
2423   }
2424    }
2425 fin:
2426         if(rows)
2427    {
2428         for(i = 0; i < height; ++i)
2429          free(rows[i]);
2430         free(rows);
2431    }
2432         if(png)
2433           png_destroy_read_struct(&png, &info, NULL);
2434
2435         fclose(reader);
2436
2437         return image;
2438
2439 }/* pngtoimage() */
2440
2441 int imagetopng(opj_image_t * image, const char *write_idf)
2442 {
2443         FILE *writer;
2444         png_structp png;
2445         png_infop info;
2446         int *red, *green, *blue, *alpha;
2447         unsigned char *row_buf, *d;
2448         int has_alpha, width, height, nr_comp, color_type;
2449         int adjustR, adjustG, adjustB, x, y, fails, is16, force16;
2450   int opj_prec, prec, ushift, dshift;
2451         unsigned short mask = 0xffff;
2452         png_color_8 sig_bit;
2453
2454         is16 = force16 = ushift = dshift = 0; fails = 1;
2455         prec = opj_prec = image->comps[0].prec;
2456
2457         if(prec > 8 && prec < 16)
2458    {
2459          prec = 16; force16 = 1;
2460    }
2461         if(prec != 1 && prec != 2 && prec != 4 && prec != 8 && prec != 16)
2462    {
2463         fprintf(stderr,"imagetopng: can not create %s"
2464          "\n\twrong bit_depth %d\n", write_idf, prec);
2465         return fails;
2466    }
2467         writer = fopen(write_idf, "wb");
2468
2469         if(writer == NULL) return fails;
2470
2471         info = NULL; has_alpha = 0;
2472
2473 /* Create and initialize the png_struct with the desired error handler
2474  * functions.  If you want to use the default stderr and longjump method,
2475  * you can supply NULL for the last three parameters.  We also check that
2476  * the library version is compatible with the one used at compile time,
2477  * in case we are using dynamically linked libraries.  REQUIRED.
2478 */
2479         png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
2480                 NULL, NULL, NULL);
2481 /*png_voidp user_error_ptr, user_error_fn, user_warning_fn); */
2482
2483         if(png == NULL) goto fin;
2484
2485 /* Allocate/initialize the image information data.  REQUIRED 
2486 */
2487         info = png_create_info_struct(png);
2488
2489         if(info == NULL) goto fin;
2490
2491 /* Set error handling.  REQUIRED if you are not supplying your own
2492  * error handling functions in the png_create_write_struct() call.
2493 */
2494         if(setjmp(png_jmpbuf(png))) goto fin;
2495
2496 /* I/O initialization functions is REQUIRED 
2497 */
2498         png_init_io(png, writer);
2499
2500 /* Set the image information here.  Width and height are up to 2^31,
2501  * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
2502  * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
2503  * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
2504  * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
2505  * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
2506  * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. 
2507  * REQUIRED
2508 */
2509         png_set_compression_level(png, Z_BEST_COMPRESSION);
2510
2511         if(prec == 16) mask = 0xffff;
2512         else
2513         if(prec == 8) mask = 0x00ff;
2514         else
2515         if(prec == 4) mask = 0x000f;
2516         else
2517         if(prec == 2) mask = 0x0003;
2518         else
2519         if(prec == 1) mask = 0x0001;
2520
2521         nr_comp = image->numcomps;
2522
2523         if(nr_comp >= 3
2524     && image->comps[0].dx == image->comps[1].dx
2525     && image->comps[1].dx == image->comps[2].dx
2526     && image->comps[0].dy == image->comps[1].dy
2527     && image->comps[1].dy == image->comps[2].dy
2528     && image->comps[0].prec == image->comps[1].prec
2529     && image->comps[1].prec == image->comps[2].prec)
2530    {
2531         int v;
2532
2533     has_alpha = (nr_comp > 3); 
2534
2535         is16 = (prec == 16);
2536         
2537     width = image->comps[0].w;
2538     height = image->comps[0].h;
2539
2540         red = image->comps[0].data;
2541         green = image->comps[1].data;
2542         blue = image->comps[2].data;
2543
2544     sig_bit.red = sig_bit.green = sig_bit.blue = prec;
2545
2546         if(has_alpha) 
2547   {
2548         sig_bit.alpha = prec;
2549         alpha = image->comps[3].data; 
2550         color_type = PNG_COLOR_TYPE_RGB_ALPHA;
2551   }
2552         else 
2553   {
2554         sig_bit.alpha = 0; alpha = NULL;
2555         color_type = PNG_COLOR_TYPE_RGB;
2556   }
2557         png_set_sBIT(png, info, &sig_bit);
2558
2559         png_set_IHDR(png, info, width, height, prec, 
2560          color_type,
2561          PNG_INTERLACE_NONE,
2562          PNG_COMPRESSION_TYPE_BASE,  PNG_FILTER_TYPE_BASE);
2563
2564 /*=============================*/
2565         png_write_info(png, info);
2566 /*=============================*/
2567         if(opj_prec < 8)
2568   {
2569         png_set_packing(png);
2570   }
2571         if(force16)
2572   {
2573         ushift = 16 - opj_prec; dshift = opj_prec - ushift;     
2574   }
2575     adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
2576     adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
2577     adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
2578
2579         row_buf = (unsigned char*)malloc(width * nr_comp * 2);
2580
2581         for(y = 0; y < height; ++y)
2582   {
2583         d = row_buf;
2584
2585         for(x = 0; x < width; ++x)
2586  {
2587                 if(is16)
2588            {
2589 /* Network byte order */
2590                 v = *red + adjustR; ++red;
2591                 
2592                 if(force16) { v = (v<<ushift) + (v>>dshift); }
2593
2594 #if BYTE_ORDER == LITTLE_ENDIAN
2595             *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
2596 #else
2597                  *d++ = (unsigned char)(v>>24);  *d++ = (unsigned char)(v>>16);
2598 #endif
2599                 v = *green + adjustG; ++green;
2600                 
2601                 if(force16) { v = (v<<ushift) + (v>>dshift); }
2602
2603 #if BYTE_ORDER == LITTLE_ENDIAN
2604             *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
2605 #else
2606                  *d++ = (unsigned char)(v>>24);  *d++ = (unsigned char)(v>>16);
2607 #endif
2608
2609                 v =  *blue + adjustB; ++blue;
2610                 
2611                 if(force16) { v = (v<<ushift) + (v>>dshift); }
2612
2613 #if BYTE_ORDER == LITTLE_ENDIAN
2614             *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
2615 #else
2616                  *d++ = (unsigned char)(v>>24);  *d++ = (unsigned char)(v>>16);
2617 #endif
2618
2619                 if(has_alpha)
2620           {
2621                 v = *alpha++;
2622                 
2623                 if(force16) { v = (v<<ushift) + (v>>dshift); }
2624
2625 #if BYTE_ORDER == LITTLE_ENDIAN
2626             *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
2627 #else
2628                  *d++ = (unsigned char)(v>>24);  *d++ = (unsigned char)(v>>16);
2629 #endif
2630           }
2631                 continue;
2632            }
2633                 *d++ = (unsigned char)((*red + adjustR) & mask); ++red;
2634                 *d++ = (unsigned char)((*green + adjustG) & mask); ++green;
2635                 *d++ = (unsigned char)((*blue + adjustB) & mask); ++blue;
2636
2637                 if(has_alpha)
2638            {
2639                 *d++ = (unsigned char)(*alpha & mask); ++alpha;
2640            }
2641  }      /* for(x) */
2642
2643         png_write_row(png, row_buf);
2644
2645   }     /* for(y) */
2646         free(row_buf);
2647
2648    }/* nr_comp >= 3 */
2649         else
2650         if(nr_comp == 1 /* GRAY */
2651         || (   nr_comp == 2 /* GRAY_ALPHA */
2652                 && image->comps[0].dx == image->comps[1].dx
2653                 && image->comps[0].dy == image->comps[1].dy
2654                 && image->comps[0].prec == image->comps[1].prec))
2655    {
2656         int v;
2657
2658         red = image->comps[0].data;
2659
2660     if(force16)
2661   {
2662     ushift = 16 - opj_prec; dshift = opj_prec - ushift;
2663   }
2664
2665     sig_bit.gray = prec;
2666     sig_bit.red = sig_bit.green = sig_bit.blue = sig_bit.alpha = 0;
2667         alpha = NULL;
2668         color_type = PNG_COLOR_TYPE_GRAY;
2669
2670     if(nr_comp == 2) 
2671   { 
2672         has_alpha = 1; sig_bit.alpha = prec;
2673         alpha = image->comps[1].data;
2674         color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
2675   }
2676     width = image->comps[0].w;
2677     height = image->comps[0].h;
2678
2679         png_set_IHDR(png, info, width, height, sig_bit.gray,
2680      color_type,
2681      PNG_INTERLACE_NONE,
2682      PNG_COMPRESSION_TYPE_BASE,  PNG_FILTER_TYPE_BASE);
2683
2684         png_set_sBIT(png, info, &sig_bit);
2685 /*=============================*/
2686         png_write_info(png, info);
2687 /*=============================*/
2688         adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
2689
2690         if(opj_prec < 8)
2691   {
2692         png_set_packing(png);
2693   }
2694
2695         if(prec > 8)
2696   {
2697 /* Network byte order */
2698
2699
2700         row_buf = (unsigned char*)
2701          malloc(width * nr_comp * sizeof(unsigned short));
2702
2703         for(y = 0; y < height; ++y)
2704  {
2705         d = row_buf;
2706
2707                 for(x = 0; x < width; ++x)
2708            {
2709                 v = *red + adjustR; ++red;
2710
2711                 if(force16) { v = (v<<ushift) + (v>>dshift); }
2712
2713 #if BYTE_ORDER == LITTLE_ENDIAN
2714             *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
2715 #else
2716                  *d++ = (unsigned char)(v>>24);  *d++ = (unsigned char)(v>>16);
2717 #endif
2718
2719                 if(has_alpha)
2720           {
2721                 v = *alpha++;
2722
2723                 if(force16) { v = (v<<ushift) + (v>>dshift); }
2724
2725 #if BYTE_ORDER == LITTLE_ENDIAN
2726             *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
2727 #else
2728                  *d++ = (unsigned char)(v>>24);  *d++ = (unsigned char)(v>>16);
2729 #endif
2730           }
2731            }/* for(x) */
2732         png_write_row(png, row_buf);
2733
2734  }      /* for(y) */
2735         free(row_buf);
2736   }
2737         else /* prec <= 8 */
2738   {
2739         row_buf = (unsigned char*)calloc(width, nr_comp * 2);
2740
2741         for(y = 0; y < height; ++y)
2742  {
2743         d = row_buf;
2744
2745                 for(x = 0; x < width; ++x)
2746            {
2747                 *d++ = (unsigned char)((*red + adjustR) & mask); ++red;
2748
2749                 if(has_alpha)
2750           {
2751                 *d++ = (unsigned char)(*alpha & mask); ++alpha;
2752           }
2753            }/* for(x) */
2754
2755         png_write_row(png, row_buf);
2756
2757  }      /* for(y) */
2758         free(row_buf);
2759   }
2760    }
2761         else
2762    {
2763         fprintf(stderr,"imagetopng: can not create %s\n",write_idf);
2764         goto fin;
2765    }
2766         png_write_end(png, info);
2767
2768         fails = 0;
2769
2770 fin:
2771
2772         if(png)
2773    {
2774     png_destroy_write_struct(&png, &info);
2775    }
2776         fclose(writer);
2777
2778         if(fails) remove(write_idf);
2779
2780         return fails;
2781 }/* imagetopng() */
2782 #endif /* HAVE_LIBPNG */