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