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