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