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