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