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