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