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