d264823f09bcb36d667bbbc0be50228d7391b06f
[openjpeg.git] / src / bin / jp2 / convertbmp.c
1 /*
2  * The copyright in this software is being made available under the 2-clauses 
3  * BSD License, included below. This software may be subject to other third 
4  * party and contributor rights, including patent rights, and no such rights
5  * are granted under this license.
6  *
7  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8  * Copyright (c) 2002-2014, Professor Benoit Macq
9  * Copyright (c) 2001-2003, David Janssens
10  * Copyright (c) 2002-2003, Yannick Verschueren
11  * Copyright (c) 2003-2007, Francois-Olivier Devaux 
12  * Copyright (c) 2003-2014, Antonin Descampe
13  * Copyright (c) 2005, Herve Drolon, FreeImage Team
14  * Copyright (c) 2006-2007, Parvatha Elangovan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
27  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 #include "opj_apps_config.h"
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <ctype.h>
44
45 #include "openjpeg.h"
46 #include "convert.h"
47
48 typedef struct {
49         OPJ_UINT16 bfType;      /* 'BM' for Bitmap (19776) */
50         OPJ_UINT32 bfSize;      /* Size of the file        */
51         OPJ_UINT16 bfReserved1; /* Reserved : 0            */
52         OPJ_UINT16 bfReserved2; /* Reserved : 0            */
53         OPJ_UINT32 bfOffBits;   /* Offset                  */
54 } OPJ_BITMAPFILEHEADER;
55
56 typedef struct {
57         OPJ_UINT32 biSize;             /* Size of the structure in bytes */
58         OPJ_UINT32 biWidth;            /* Width of the image in pixels */
59         OPJ_UINT32 biHeight;           /* Heigth of the image in pixels */
60         OPJ_UINT16 biPlanes;           /* 1 */
61         OPJ_UINT16 biBitCount;         /* Number of color bits by pixels */
62         OPJ_UINT32 biCompression;      /* Type of encoding 0: none 1: RLE8 2: RLE4 */
63         OPJ_UINT32 biSizeImage;        /* Size of the image in bytes */
64         OPJ_UINT32 biXpelsPerMeter;    /* Horizontal (X) resolution in pixels/meter */
65         OPJ_UINT32 biYpelsPerMeter;    /* Vertical (Y) resolution in pixels/meter */
66         OPJ_UINT32 biClrUsed;          /* Number of color used in the image (0: ALL) */
67         OPJ_UINT32 biClrImportant;     /* Number of important color (0: ALL) */
68         OPJ_UINT32 biRedMask;          /* Red channel bit mask */
69         OPJ_UINT32 biGreenMask;        /* Green channel bit mask */
70         OPJ_UINT32 biBlueMask;         /* Blue channel bit mask */
71         OPJ_UINT32 biAlphaMask;        /* Alpha channel bit mask */
72         OPJ_UINT32 biColorSpaceType;   /* Color space type */
73         OPJ_UINT8  biColorSpaceEP[36]; /* Color space end points */
74         OPJ_UINT32 biRedGamma;         /* Red channel gamma */
75         OPJ_UINT32 biGreenGamma;       /* Green channel gamma */
76         OPJ_UINT32 biBlueGamma;        /* Blue channel gamma */
77         OPJ_UINT32 biIntent;           /* Intent */
78         OPJ_UINT32 biIccProfileData;   /* ICC profile data */
79         OPJ_UINT32 biIccProfileSize;   /* ICC profile size */
80         OPJ_UINT32 biReserved;         /* Reserved */
81 } OPJ_BITMAPINFOHEADER;
82
83 static void opj_applyLUT8u_8u32s_C1R(
84         OPJ_UINT8 const* pSrc, OPJ_INT32 srcStride,
85         OPJ_INT32* pDst, OPJ_INT32 dstStride,
86         OPJ_UINT8 const* pLUT,
87         OPJ_UINT32 width, OPJ_UINT32 height)
88 {
89         OPJ_UINT32 y;
90         
91         for (y = height; y != 0U; --y) {
92                 OPJ_UINT32 x;
93                 
94                 for(x = 0; x < width; x++)
95                 {
96                         pDst[x] = (OPJ_INT32)pLUT[pSrc[x]];
97                 }
98                 pSrc += srcStride;
99                 pDst += dstStride;
100         }
101 }
102
103 static void opj_applyLUT8u_8u32s_C1P3R(
104         OPJ_UINT8 const* pSrc, OPJ_INT32 srcStride,
105         OPJ_INT32* const* pDst, OPJ_INT32 const* pDstStride,
106         OPJ_UINT8 const* const* pLUT,
107         OPJ_UINT32 width, OPJ_UINT32 height)
108 {
109         OPJ_UINT32 y;
110         OPJ_INT32* pR = pDst[0];
111         OPJ_INT32* pG = pDst[1];
112         OPJ_INT32* pB = pDst[2];
113         OPJ_UINT8 const* pLUT_R = pLUT[0];
114         OPJ_UINT8 const* pLUT_G = pLUT[1];
115         OPJ_UINT8 const* pLUT_B = pLUT[2];
116         
117         for (y = height; y != 0U; --y) {
118                 OPJ_UINT32 x;
119                 
120                 for(x = 0; x < width; x++)
121                 {
122                         OPJ_UINT8 idx = pSrc[x];
123                         pR[x] = (OPJ_INT32)pLUT_R[idx];
124                         pG[x] = (OPJ_INT32)pLUT_G[idx];
125                         pB[x] = (OPJ_INT32)pLUT_B[idx];
126                 }
127                 pSrc += srcStride;
128                 pR += pDstStride[0];
129                 pG += pDstStride[1];
130                 pB += pDstStride[2];
131         }
132 }
133
134 static void bmp24toimage(const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image)
135 {
136         int index;
137         OPJ_UINT32 width, height;
138         OPJ_UINT32 x, y;
139         const OPJ_UINT8 *pSrc = NULL;
140
141         width  = image->comps[0].w;
142         height = image->comps[0].h;
143         
144         index = 0;
145         pSrc = pData + (height - 1U) * stride;
146         for(y = 0; y < height; y++)
147         {
148                 for(x = 0; x < width; x++)
149                 {
150                         image->comps[0].data[index] = (OPJ_INT32)pSrc[3*x+2];   /* R */
151                         image->comps[1].data[index] = (OPJ_INT32)pSrc[3*x+1];   /* G */
152                         image->comps[2].data[index] = (OPJ_INT32)pSrc[3*x+0];   /* B */
153                         index++;
154                 }
155                 pSrc -= stride;
156         }
157 }
158
159 static void bmp_mask_get_shift_and_prec(OPJ_UINT32 mask, OPJ_UINT32* shift, OPJ_UINT32* prec)
160 {
161         OPJ_UINT32 l_shift, l_prec;
162         
163         l_shift = l_prec = 0U;
164         
165         if (mask != 0U) {
166                 while ((mask & 1U) == 0U) {
167                         mask >>= 1;
168                         l_shift++;
169                 }
170                 while (mask & 1U) {
171                         mask >>= 1;
172                         l_prec++;
173                 }
174         }
175         *shift = l_shift; *prec = l_prec;
176 }
177
178 static void bmpmask32toimage(const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT32 redMask, OPJ_UINT32 greenMask, OPJ_UINT32 blueMask, OPJ_UINT32 alphaMask)
179 {
180         int index;
181         OPJ_UINT32 width, height;
182         OPJ_UINT32 x, y;
183         const OPJ_UINT8 *pSrc = NULL;
184         OPJ_BOOL hasAlpha;
185         OPJ_UINT32 redShift,   redPrec;
186         OPJ_UINT32 greenShift, greenPrec;
187         OPJ_UINT32 blueShift,  bluePrec;
188         OPJ_UINT32 alphaShift, alphaPrec;
189         
190         width  = image->comps[0].w;
191         height = image->comps[0].h;
192         
193         hasAlpha = image->numcomps > 3U;
194         
195         bmp_mask_get_shift_and_prec(redMask,   &redShift,   &redPrec);
196         bmp_mask_get_shift_and_prec(greenMask, &greenShift, &greenPrec);
197         bmp_mask_get_shift_and_prec(blueMask,  &blueShift,  &bluePrec);
198         bmp_mask_get_shift_and_prec(alphaMask, &alphaShift, &alphaPrec);
199         
200         image->comps[0].bpp = redPrec;
201         image->comps[0].prec = redPrec;
202         image->comps[1].bpp = greenPrec;
203         image->comps[1].prec = greenPrec;
204         image->comps[2].bpp = bluePrec;
205         image->comps[2].prec = bluePrec;
206         if (hasAlpha) {
207                 image->comps[3].bpp = alphaPrec;
208                 image->comps[3].prec = alphaPrec;
209         }
210         
211         index = 0;
212         pSrc = pData + (height - 1U) * stride;
213         for(y = 0; y < height; y++)
214         {
215                 for(x = 0; x < width; x++)
216                 {
217                         OPJ_UINT32 value = 0U;
218                         
219                         value |= ((OPJ_UINT32)pSrc[4*x+0]) <<  0;
220                         value |= ((OPJ_UINT32)pSrc[4*x+1]) <<  8;
221                         value |= ((OPJ_UINT32)pSrc[4*x+2]) << 16;
222                         value |= ((OPJ_UINT32)pSrc[4*x+3]) << 24;
223                         
224                         image->comps[0].data[index] = (OPJ_INT32)((value & redMask)   >> redShift);   /* R */
225                         image->comps[1].data[index] = (OPJ_INT32)((value & greenMask) >> greenShift); /* G */
226                         image->comps[2].data[index] = (OPJ_INT32)((value & blueMask)  >> blueShift);  /* B */
227                         if (hasAlpha) {
228                                 image->comps[3].data[index] = (OPJ_INT32)((value & alphaMask)  >> alphaShift);  /* A */
229                         }
230                         index++;
231                 }
232                 pSrc -= stride;
233         }
234 }
235
236 static void bmpmask16toimage(const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT32 redMask, OPJ_UINT32 greenMask, OPJ_UINT32 blueMask, OPJ_UINT32 alphaMask)
237 {
238         int index;
239         OPJ_UINT32 width, height;
240         OPJ_UINT32 x, y;
241         const OPJ_UINT8 *pSrc = NULL;
242         OPJ_BOOL hasAlpha;
243         OPJ_UINT32 redShift,   redPrec;
244         OPJ_UINT32 greenShift, greenPrec;
245         OPJ_UINT32 blueShift,  bluePrec;
246         OPJ_UINT32 alphaShift, alphaPrec;
247         
248         width  = image->comps[0].w;
249         height = image->comps[0].h;
250         
251         hasAlpha = image->numcomps > 3U;
252         
253         bmp_mask_get_shift_and_prec(redMask,   &redShift,   &redPrec);
254         bmp_mask_get_shift_and_prec(greenMask, &greenShift, &greenPrec);
255         bmp_mask_get_shift_and_prec(blueMask,  &blueShift,  &bluePrec);
256         bmp_mask_get_shift_and_prec(alphaMask, &alphaShift, &alphaPrec);
257         
258         image->comps[0].bpp = redPrec;
259         image->comps[0].prec = redPrec;
260         image->comps[1].bpp = greenPrec;
261         image->comps[1].prec = greenPrec;
262         image->comps[2].bpp = bluePrec;
263         image->comps[2].prec = bluePrec;
264         if (hasAlpha) {
265                 image->comps[3].bpp = alphaPrec;
266                 image->comps[3].prec = alphaPrec;
267         }
268         
269         index = 0;
270         pSrc = pData + (height - 1U) * stride;
271         for(y = 0; y < height; y++)
272         {
273                 for(x = 0; x < width; x++)
274                 {
275                         OPJ_UINT32 value = 0U;
276                         
277                         value |= ((OPJ_UINT32)pSrc[2*x+0]) <<  0;
278                         value |= ((OPJ_UINT32)pSrc[2*x+1]) <<  8;
279                         
280                         image->comps[0].data[index] = (OPJ_INT32)((value & redMask)   >> redShift);   /* R */
281                         image->comps[1].data[index] = (OPJ_INT32)((value & greenMask) >> greenShift); /* G */
282                         image->comps[2].data[index] = (OPJ_INT32)((value & blueMask)  >> blueShift);  /* B */
283                         if (hasAlpha) {
284                                 image->comps[3].data[index] = (OPJ_INT32)((value & alphaMask)  >> alphaShift);  /* A */
285                         }
286                         index++;
287                 }
288                 pSrc -= stride;
289         }
290 }
291
292 static opj_image_t* bmp8toimage(const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT8 const* const* pLUT)
293 {
294         OPJ_UINT32 width, height;
295         const OPJ_UINT8 *pSrc = NULL;
296         
297         width  = image->comps[0].w;
298         height = image->comps[0].h;
299         
300         pSrc = pData + (height - 1U) * stride;
301         if (image->numcomps == 1U) {
302                 opj_applyLUT8u_8u32s_C1R(pSrc, -(OPJ_INT32)stride, image->comps[0].data, (OPJ_INT32)width, pLUT[0], width, height);
303         }
304         else {
305                 OPJ_INT32* pDst[3];
306                 OPJ_INT32  pDstStride[3];
307                 
308                 pDst[0] = image->comps[0].data; pDst[1] = image->comps[1].data; pDst[2] = image->comps[2].data;
309                 pDstStride[0] = (OPJ_INT32)width; pDstStride[1] = (OPJ_INT32)width; pDstStride[2] = (OPJ_INT32)width;
310                 opj_applyLUT8u_8u32s_C1P3R(pSrc, -(OPJ_INT32)stride, pDst, pDstStride, pLUT, width, height);
311         }
312         return image;
313 }
314
315 static OPJ_BOOL bmp_read_file_header(FILE* IN, OPJ_BITMAPFILEHEADER* header)
316 {
317         header->bfType  = (OPJ_UINT16)getc(IN);
318         header->bfType |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
319         
320         if (header->bfType != 19778) {
321                 fprintf(stderr,"Error, not a BMP file!\n");
322                 return OPJ_FALSE;
323         }
324         
325         /* FILE HEADER */
326         /* ------------- */
327         header->bfSize  = (OPJ_UINT32)getc(IN);
328         header->bfSize |= (OPJ_UINT32)getc(IN) << 8;
329         header->bfSize |= (OPJ_UINT32)getc(IN) << 16;
330         header->bfSize |= (OPJ_UINT32)getc(IN) << 24;
331         
332         header->bfReserved1  = (OPJ_UINT16)getc(IN);
333         header->bfReserved1 |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
334         
335         header->bfReserved2  = (OPJ_UINT16)getc(IN);
336         header->bfReserved2 |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
337         
338         header->bfOffBits  = (OPJ_UINT32)getc(IN);
339         header->bfOffBits |= (OPJ_UINT32)getc(IN) << 8;
340         header->bfOffBits |= (OPJ_UINT32)getc(IN) << 16;
341         header->bfOffBits |= (OPJ_UINT32)getc(IN) << 24;
342         return OPJ_TRUE;
343 }
344 static OPJ_BOOL bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
345 {
346         memset(header, 0, sizeof(*header));
347         /* INFO HEADER */
348         /* ------------- */
349         header->biSize  = (OPJ_UINT32)getc(IN);
350         header->biSize |= (OPJ_UINT32)getc(IN) << 8;
351         header->biSize |= (OPJ_UINT32)getc(IN) << 16;
352         header->biSize |= (OPJ_UINT32)getc(IN) << 24;
353         
354         switch (header->biSize) {
355                 case 12U:  /* BITMAPCOREHEADER */
356                 case 40U:  /* BITMAPINFOHEADER */
357                 case 52U:  /* BITMAPV2INFOHEADER */
358                 case 56U:  /* BITMAPV3INFOHEADER */
359                 case 108U: /* BITMAPV4HEADER */
360                 case 124U: /* BITMAPV5HEADER */
361                         break;
362   default:
363                         fprintf(stderr,"Error, unknown BMP header size %d\n", header->biSize);
364                         return OPJ_FALSE;
365         }
366         
367         header->biWidth  = (OPJ_UINT32)getc(IN);
368         header->biWidth |= (OPJ_UINT32)getc(IN) << 8;
369         header->biWidth |= (OPJ_UINT32)getc(IN) << 16;
370         header->biWidth |= (OPJ_UINT32)getc(IN) << 24;
371         
372         header->biHeight  = (OPJ_UINT32)getc(IN);
373         header->biHeight |= (OPJ_UINT32)getc(IN) << 8;
374         header->biHeight |= (OPJ_UINT32)getc(IN) << 16;
375         header->biHeight |= (OPJ_UINT32)getc(IN) << 24;
376         
377         header->biPlanes  = (OPJ_UINT16)getc(IN);
378         header->biPlanes |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
379         
380         header->biBitCount  = (OPJ_UINT16)getc(IN);
381         header->biBitCount |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
382         
383         if(header->biSize >= 40U) {
384                 header->biCompression  = (OPJ_UINT32)getc(IN);
385                 header->biCompression |= (OPJ_UINT32)getc(IN) << 8;
386                 header->biCompression |= (OPJ_UINT32)getc(IN) << 16;
387                 header->biCompression |= (OPJ_UINT32)getc(IN) << 24;
388                 
389                 header->biSizeImage  = (OPJ_UINT32)getc(IN);
390                 header->biSizeImage |= (OPJ_UINT32)getc(IN) << 8;
391                 header->biSizeImage |= (OPJ_UINT32)getc(IN) << 16;
392                 header->biSizeImage |= (OPJ_UINT32)getc(IN) << 24;
393                 
394                 header->biXpelsPerMeter  = (OPJ_UINT32)getc(IN);
395                 header->biXpelsPerMeter |= (OPJ_UINT32)getc(IN) << 8;
396                 header->biXpelsPerMeter |= (OPJ_UINT32)getc(IN) << 16;
397                 header->biXpelsPerMeter |= (OPJ_UINT32)getc(IN) << 24;
398                 
399                 header->biYpelsPerMeter  = (OPJ_UINT32)getc(IN);
400                 header->biYpelsPerMeter |= (OPJ_UINT32)getc(IN) << 8;
401                 header->biYpelsPerMeter |= (OPJ_UINT32)getc(IN) << 16;
402                 header->biYpelsPerMeter |= (OPJ_UINT32)getc(IN) << 24;
403                 
404                 header->biClrUsed  = (OPJ_UINT32)getc(IN);
405                 header->biClrUsed |= (OPJ_UINT32)getc(IN) << 8;
406                 header->biClrUsed |= (OPJ_UINT32)getc(IN) << 16;
407                 header->biClrUsed |= (OPJ_UINT32)getc(IN) << 24;
408                 
409                 header->biClrImportant  = (OPJ_UINT32)getc(IN);
410                 header->biClrImportant |= (OPJ_UINT32)getc(IN) << 8;
411                 header->biClrImportant |= (OPJ_UINT32)getc(IN) << 16;
412                 header->biClrImportant |= (OPJ_UINT32)getc(IN) << 24;
413         }
414         
415         if(header->biSize >= 56U) {
416                 header->biRedMask  = (OPJ_UINT32)getc(IN);
417                 header->biRedMask |= (OPJ_UINT32)getc(IN) << 8;
418                 header->biRedMask |= (OPJ_UINT32)getc(IN) << 16;
419                 header->biRedMask |= (OPJ_UINT32)getc(IN) << 24;
420                 
421                 header->biGreenMask  = (OPJ_UINT32)getc(IN);
422                 header->biGreenMask |= (OPJ_UINT32)getc(IN) << 8;
423                 header->biGreenMask |= (OPJ_UINT32)getc(IN) << 16;
424                 header->biGreenMask |= (OPJ_UINT32)getc(IN) << 24;
425                 
426                 header->biBlueMask  = (OPJ_UINT32)getc(IN);
427                 header->biBlueMask |= (OPJ_UINT32)getc(IN) << 8;
428                 header->biBlueMask |= (OPJ_UINT32)getc(IN) << 16;
429                 header->biBlueMask |= (OPJ_UINT32)getc(IN) << 24;
430                 
431                 header->biAlphaMask  = (OPJ_UINT32)getc(IN);
432                 header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 8;
433                 header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 16;
434                 header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 24;
435         }
436         
437         if(header->biSize >= 108U) {
438                 header->biColorSpaceType  = (OPJ_UINT32)getc(IN);
439                 header->biColorSpaceType |= (OPJ_UINT32)getc(IN) << 8;
440                 header->biColorSpaceType |= (OPJ_UINT32)getc(IN) << 16;
441                 header->biColorSpaceType |= (OPJ_UINT32)getc(IN) << 24;
442                 
443                 if (fread(&(header->biColorSpaceEP), 1U, sizeof(header->biColorSpaceEP), IN) != sizeof(header->biColorSpaceEP)) {
444                         fprintf(stderr,"Error, can't  read BMP header\n");
445                         return OPJ_FALSE;
446                 }
447                 
448                 header->biRedGamma  = (OPJ_UINT32)getc(IN);
449                 header->biRedGamma |= (OPJ_UINT32)getc(IN) << 8;
450                 header->biRedGamma |= (OPJ_UINT32)getc(IN) << 16;
451                 header->biRedGamma |= (OPJ_UINT32)getc(IN) << 24;
452                 
453                 header->biGreenGamma  = (OPJ_UINT32)getc(IN);
454                 header->biGreenGamma |= (OPJ_UINT32)getc(IN) << 8;
455                 header->biGreenGamma |= (OPJ_UINT32)getc(IN) << 16;
456                 header->biGreenGamma |= (OPJ_UINT32)getc(IN) << 24;
457                 
458                 header->biBlueGamma  = (OPJ_UINT32)getc(IN);
459                 header->biBlueGamma |= (OPJ_UINT32)getc(IN) << 8;
460                 header->biBlueGamma |= (OPJ_UINT32)getc(IN) << 16;
461                 header->biBlueGamma |= (OPJ_UINT32)getc(IN) << 24;
462         }
463         
464         if(header->biSize >= 124U) {
465                 header->biIntent  = (OPJ_UINT32)getc(IN);
466                 header->biIntent |= (OPJ_UINT32)getc(IN) << 8;
467                 header->biIntent |= (OPJ_UINT32)getc(IN) << 16;
468                 header->biIntent |= (OPJ_UINT32)getc(IN) << 24;
469                 
470                 header->biIccProfileData  = (OPJ_UINT32)getc(IN);
471                 header->biIccProfileData |= (OPJ_UINT32)getc(IN) << 8;
472                 header->biIccProfileData |= (OPJ_UINT32)getc(IN) << 16;
473                 header->biIccProfileData |= (OPJ_UINT32)getc(IN) << 24;
474                 
475                 header->biIccProfileSize  = (OPJ_UINT32)getc(IN);
476                 header->biIccProfileSize |= (OPJ_UINT32)getc(IN) << 8;
477                 header->biIccProfileSize |= (OPJ_UINT32)getc(IN) << 16;
478                 header->biIccProfileSize |= (OPJ_UINT32)getc(IN) << 24;
479                 
480                 header->biReserved  = (OPJ_UINT32)getc(IN);
481                 header->biReserved |= (OPJ_UINT32)getc(IN) << 8;
482                 header->biReserved |= (OPJ_UINT32)getc(IN) << 16;
483                 header->biReserved |= (OPJ_UINT32)getc(IN) << 24;
484         }
485         return OPJ_TRUE;
486 }
487
488 static OPJ_BOOL bmp_read_raw_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
489 {
490         OPJ_ARG_NOT_USED(width);
491         
492         if ( fread(pData, sizeof(OPJ_UINT8), stride * height, IN) != (stride * height) )
493         {
494                 fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
495                 return OPJ_FALSE;
496         }
497         return OPJ_TRUE;
498 }
499
500 static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
501 {
502         OPJ_UINT32 x, y;
503         OPJ_UINT8 *pix;
504         const OPJ_UINT8 *beyond;
505         
506         beyond = pData + stride * height;
507         pix = pData;
508         
509         x = y = 0U;
510         while (y < height)
511         {
512                 int c = getc(IN);
513                 
514                 if (c) {
515                         int j;
516                         OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
517                         
518                         for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
519                                 *pix = c1;
520                         }
521                 }
522                 else {
523                         c = getc(IN);
524                         if (c == 0x00) { /* EOL */
525                                 x = 0;
526                                 ++y;
527                                 pix = pData + y * stride + x;
528                         }
529                         else if (c == 0x01) { /* EOP */
530                                 break;
531                         }
532                         else if (c == 0x02) { /* MOVE by dxdy */
533                                 c = getc(IN);
534                                 x += (OPJ_UINT32)c;
535                                 c = getc(IN);
536                                 y += (OPJ_UINT32)c;
537                                 pix = pData + y * stride + x;
538                         }
539                         else /* 03 .. 255 */
540                         {
541                                 int j;
542                                 for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++)
543                                 {
544                                         OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
545                                         *pix = c1;
546                                 }
547                                 if ((OPJ_UINT32)c & 1U) { /* skip padding byte */
548                                         getc(IN);
549                                 }
550                         }
551                 }
552         }/* while() */
553         return OPJ_TRUE;
554 }
555
556 static OPJ_BOOL bmp_read_rle4_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
557 {
558         OPJ_UINT32 x, y;
559         OPJ_UINT8 *pix;
560         const OPJ_UINT8 *beyond;
561         
562         beyond = pData + stride * height;
563         pix = pData;
564         x = y = 0U;
565         while(y < height)
566         {
567                 int c = getc(IN);
568                 if(c == EOF) break;
569                 
570                 if(c) {/* encoded mode */
571                         int j;
572                         OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
573                 
574                         for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
575                                 *pix = (OPJ_UINT8)((j&1) ? (c1 & 0x0fU) : ((c1>>4)&0x0fU));
576                         }
577                 }
578                 else { /* absolute mode */
579                         c = getc(IN);
580                         if(c == EOF) break;
581                 
582                         if(c == 0x00) { /* EOL */
583                                 x = 0;  y++;  pix = pData + y * stride;
584                         }
585                         else if(c == 0x01) { /* EOP */
586                                 break;
587                         }
588                         else if(c == 0x02) { /* MOVE by dxdy */
589                                 c = getc(IN);  x += (OPJ_UINT32)c;
590                                 c = getc(IN);  y += (OPJ_UINT32)c;
591                                 pix = pData + y * stride + x;
592                         }
593                         else { /* 03 .. 255 : absolute mode */
594                                 int j;
595                                 OPJ_UINT8 c1 = 0U;
596                                 
597                                 for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
598                                         if((j&1) == 0) {
599                                                         c1 = (OPJ_UINT8)getc(IN);
600                                         }
601                                         *pix =  (OPJ_UINT8)((j&1) ? (c1 & 0x0fU) : ((c1>>4)&0x0fU));
602                                 }
603                                 if(((c&3) == 1) || ((c&3) == 2)) { /* skip padding byte */
604                                                 getc(IN);
605                                 }
606                         }
607                 }
608         }  /* while(y < height) */
609         return OPJ_TRUE;
610 }
611
612 opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
613 {
614         opj_image_cmptparm_t cmptparm[4];       /* maximum of 4 components */
615         OPJ_UINT8 lut_R[256], lut_G[256], lut_B[256];
616         OPJ_UINT8 const* pLUT[3];
617         opj_image_t * image = NULL;
618         FILE *IN;
619         OPJ_BITMAPFILEHEADER File_h;
620         OPJ_BITMAPINFOHEADER Info_h;
621         OPJ_UINT32 i, palette_len, numcmpts = 1U;
622         OPJ_BOOL l_result = OPJ_FALSE;
623         OPJ_UINT8* pData = NULL;
624         OPJ_UINT32 stride;
625         
626         pLUT[0] = lut_R; pLUT[1] = lut_G; pLUT[2] = lut_B;
627         
628         IN = fopen(filename, "rb");
629         if (!IN)
630         {
631                 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
632                 return NULL;
633         }
634
635         if (!bmp_read_file_header(IN, &File_h)) {
636                 fclose(IN);
637                 return NULL;
638         }
639         if (!bmp_read_info_header(IN, &Info_h)) {
640                 fclose(IN);
641                 return NULL;
642         }
643         
644         /* Load palette */
645         if (Info_h.biBitCount <= 8U)
646         {
647                 memset(&lut_R[0], 0, sizeof(lut_R));
648                 memset(&lut_G[0], 0, sizeof(lut_G));
649                 memset(&lut_B[0], 0, sizeof(lut_B));
650                 
651                 palette_len = Info_h.biClrUsed;
652                 if((palette_len == 0U) && (Info_h.biBitCount <= 8U)) {
653                         palette_len = (1U << Info_h.biBitCount);
654                 }
655                 if (palette_len > 256U) {
656                         palette_len = 256U;
657                 }
658                 if (palette_len > 0U) {
659                         OPJ_UINT8 has_color = 0U;
660                         for (i = 0U; i < palette_len; i++) {
661                                 lut_B[i] = (OPJ_UINT8)getc(IN);
662                                 lut_G[i] = (OPJ_UINT8)getc(IN);
663                                 lut_R[i] = (OPJ_UINT8)getc(IN);
664                                 (void)getc(IN); /* padding */
665                                 has_color |= (lut_B[i] ^ lut_G[i]) | (lut_G[i] ^ lut_R[i]);
666                         }
667                         if(has_color) {
668                                 numcmpts = 3U;
669                         }
670                 }
671         } else {
672                 numcmpts = 3U;
673                 if ((Info_h.biCompression == 3) && (Info_h.biAlphaMask != 0U)) {
674                         numcmpts++;
675                 }
676         }
677         
678         stride = ((Info_h.biWidth * Info_h.biBitCount + 31U) / 32U) * 4U; /* rows are aligned on 32bits */
679         if (Info_h.biBitCount == 4 && Info_h.biCompression == 2) { /* RLE 4 gets decoded as 8 bits data for now... */
680                 stride = ((Info_h.biWidth * 8U + 31U) / 32U) * 4U;
681         }
682         pData = (OPJ_UINT8 *) calloc(1, stride * Info_h.biHeight * sizeof(OPJ_UINT8));
683         if (pData == NULL) {
684                 fclose(IN);
685                 return NULL;
686         }
687         /* Place the cursor at the beginning of the image information */
688         fseek(IN, 0, SEEK_SET);
689         fseek(IN, (long)File_h.bfOffBits, SEEK_SET);
690         
691         switch (Info_h.biCompression) {
692                 case 0:
693                 case 3:
694                         /* read raw data */
695                         l_result = bmp_read_raw_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
696                         break;
697                 case 1:
698                         /* read rle8 data */
699                         l_result = bmp_read_rle8_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
700                         break;
701                 case 2:
702                         /* read rle4 data */
703                         l_result = bmp_read_rle4_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
704                         break;
705   default:
706                         fprintf(stderr, "Unsupported BMP compression\n");
707                         l_result = OPJ_FALSE;
708                         break;
709         }
710         if (!l_result) {
711                 free(pData);
712                 fclose(IN);
713                 return NULL;
714         }
715         
716         /* create the image */
717         memset(&cmptparm[0], 0, sizeof(cmptparm));
718         for(i = 0; i < 4U; i++)
719         {
720                 cmptparm[i].prec = 8;
721                 cmptparm[i].bpp  = 8;
722                 cmptparm[i].sgnd = 0;
723                 cmptparm[i].dx   = (OPJ_UINT32)parameters->subsampling_dx;
724                 cmptparm[i].dy   = (OPJ_UINT32)parameters->subsampling_dy;
725                 cmptparm[i].w    = Info_h.biWidth;
726                 cmptparm[i].h    = Info_h.biHeight;
727         }
728
729         image = opj_image_create(numcmpts, &cmptparm[0], (numcmpts == 1U) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB);
730         if(!image) {
731                 fclose(IN);
732                 free(pData);
733                 return NULL;
734         }
735         if (numcmpts == 4U) {
736                 image->comps[3].alpha = 1;
737         }
738         
739         /* set image offset and reference grid */
740         image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
741         image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
742         image->x1 =     image->x0 + (Info_h.biWidth  - 1U) * (OPJ_UINT32)parameters->subsampling_dx + 1U;
743         image->y1 = image->y0 + (Info_h.biHeight - 1U) * (OPJ_UINT32)parameters->subsampling_dy + 1U;
744         
745         /* Read the data */
746         if (Info_h.biBitCount == 24 && Info_h.biCompression == 0) { /*RGB */
747                 bmp24toimage(pData, stride, image);
748         }
749         else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { /* RGB 8bpp Indexed */
750                 bmp8toimage(pData, stride, image, pLUT);
751         }
752         else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { /*RLE8*/
753                 bmp8toimage(pData, stride, image, pLUT);
754         }
755         else if (Info_h.biBitCount == 4 && Info_h.biCompression == 2) { /*RLE4*/
756                 bmp8toimage(pData, stride, image, pLUT); /* RLE 4 gets decoded as 8 bits data for now */
757         }
758         else if (Info_h.biBitCount == 32 && Info_h.biCompression == 0) { /* RGBX */
759                 bmpmask32toimage(pData, stride, image, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, 0x00000000U);
760         }
761         else if (Info_h.biBitCount == 32 && Info_h.biCompression == 3) { /* bitmask */
762                 bmpmask32toimage(pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
763         }
764         else if (Info_h.biBitCount == 16 && Info_h.biCompression == 0) { /* RGBX */
765                 bmpmask16toimage(pData, stride, image, 0x7C00U, 0x03E0U, 0x001FU, 0x0000U);
766         }
767         else if (Info_h.biBitCount == 16 && Info_h.biCompression == 3) { /* bitmask */
768                 if ((Info_h.biRedMask == 0U) && (Info_h.biGreenMask == 0U) && (Info_h.biBlueMask == 0U)) {
769                         Info_h.biRedMask   = 0xF800U;
770                         Info_h.biGreenMask = 0x07E0U;
771                         Info_h.biBlueMask  = 0x001FU;
772                 }
773                 bmpmask16toimage(pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
774         }
775         else {
776                 opj_image_destroy(image);
777                 image = NULL;
778                 fprintf(stderr, "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount);
779         }
780         free(pData);
781         fclose(IN);
782         return image;
783 }
784
785 int imagetobmp(opj_image_t * image, const char *outfile) {
786     int w, h;
787     int i, pad;
788     FILE *fdest = NULL;
789     int adjustR, adjustG, adjustB;
790
791     if (image->comps[0].prec < 8) {
792         fprintf(stderr, "Unsupported number of components: %d\n", image->comps[0].prec);
793         return 1;
794     }
795     if (image->numcomps >= 3 && image->comps[0].dx == image->comps[1].dx
796             && image->comps[1].dx == image->comps[2].dx
797             && image->comps[0].dy == image->comps[1].dy
798             && image->comps[1].dy == image->comps[2].dy
799             && image->comps[0].prec == image->comps[1].prec
800             && image->comps[1].prec == image->comps[2].prec) {
801
802         /* -->> -->> -->> -->>
803         24 bits color
804         <<-- <<-- <<-- <<-- */
805
806         fdest = fopen(outfile, "wb");
807         if (!fdest) {
808             fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
809             return 1;
810         }
811
812         w = (int)image->comps[0].w;
813         h = (int)image->comps[0].h;
814
815         fprintf(fdest, "BM");
816
817         /* FILE HEADER */
818         /* ------------- */
819         fprintf(fdest, "%c%c%c%c",
820                 (OPJ_UINT8) (h * w * 3 + 3 * h * (w % 2) + 54) & 0xff,
821                 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 8) & 0xff,
822                 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 16) & 0xff,
823                 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 24) & 0xff);
824         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
825         fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
826
827         /* INFO HEADER   */
828         /* ------------- */
829         fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
830         fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((w) & 0xff),
831                 (OPJ_UINT8) ((w) >> 8) & 0xff,
832                 (OPJ_UINT8) ((w) >> 16) & 0xff,
833                 (OPJ_UINT8) ((w) >> 24) & 0xff);
834         fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((h) & 0xff),
835                 (OPJ_UINT8) ((h) >> 8) & 0xff,
836                 (OPJ_UINT8) ((h) >> 16) & 0xff,
837                 (OPJ_UINT8) ((h) >> 24) & 0xff);
838         fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
839         fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
840         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
841         fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) (3 * h * w + 3 * h * (w % 2)) & 0xff,
842                 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2)) >> 8) & 0xff,
843                 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2)) >> 16) & 0xff,
844                 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2)) >> 24) & 0xff);
845         fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
846         fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
847         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
848         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
849
850         if (image->comps[0].prec > 8) {
851             adjustR = (int)image->comps[0].prec - 8;
852             printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
853         }
854         else
855             adjustR = 0;
856         if (image->comps[1].prec > 8) {
857             adjustG = (int)image->comps[1].prec - 8;
858             printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
859         }
860         else
861             adjustG = 0;
862         if (image->comps[2].prec > 8) {
863             adjustB = (int)image->comps[2].prec - 8;
864             printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
865         }
866         else
867             adjustB = 0;
868
869         for (i = 0; i < w * h; i++) {
870             OPJ_UINT8 rc, gc, bc;
871             int r, g, b;
872
873             r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
874             r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
875             r = ((r >> adjustR)+((r >> (adjustR-1))%2));
876             if(r > 255) r = 255; else if(r < 0) r = 0;
877             rc = (OPJ_UINT8)r;
878
879             g = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
880             g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
881             g = ((g >> adjustG)+((g >> (adjustG-1))%2));
882             if(g > 255) g = 255; else if(g < 0) g = 0;
883             gc = (OPJ_UINT8)g;
884
885             b = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
886             b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
887             b = ((b >> adjustB)+((b >> (adjustB-1))%2));
888             if(b > 255) b = 255; else if(b < 0) b = 0;
889             bc = (OPJ_UINT8)b;
890
891             fprintf(fdest, "%c%c%c", bc, gc, rc);
892
893             if ((i + 1) % w == 0) {
894                 for (pad = ((3 * w) % 4) ? (4 - (3 * w) % 4) : 0; pad > 0; pad--)       /* ADD */
895                     fprintf(fdest, "%c", 0);
896             }
897         }
898         fclose(fdest);
899     } else {                    /* Gray-scale */
900
901         /* -->> -->> -->> -->>
902         8 bits non code (Gray scale)
903         <<-- <<-- <<-- <<-- */
904
905         fdest = fopen(outfile, "wb");
906         if (!fdest) {
907             fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
908             return 1;
909         }
910         w = (int)image->comps[0].w;
911         h = (int)image->comps[0].h;
912
913         fprintf(fdest, "BM");
914
915         /* FILE HEADER */
916         /* ------------- */
917         fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) (h * w + 54 + 1024 + h * (w % 2)) & 0xff,
918                 (OPJ_UINT8) ((h * w + 54 + 1024 + h * (w % 2)) >> 8) & 0xff,
919                 (OPJ_UINT8) ((h * w + 54 + 1024 + h * (w % 2)) >> 16) & 0xff,
920                 (OPJ_UINT8) ((h * w + 54 + 1024 + w * (w % 2)) >> 24) & 0xff);
921         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
922         fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff,
923                 ((54 + 1024) >> 16) & 0xff,
924                 ((54 + 1024) >> 24) & 0xff);
925
926         /* INFO HEADER */
927         /* ------------- */
928         fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
929         fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((w) & 0xff),
930                 (OPJ_UINT8) ((w) >> 8) & 0xff,
931                 (OPJ_UINT8) ((w) >> 16) & 0xff,
932                 (OPJ_UINT8) ((w) >> 24) & 0xff);
933         fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((h) & 0xff),
934                 (OPJ_UINT8) ((h) >> 8) & 0xff,
935                 (OPJ_UINT8) ((h) >> 16) & 0xff,
936                 (OPJ_UINT8) ((h) >> 24) & 0xff);
937         fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
938         fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
939         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
940         fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) (h * w + h * (w % 2)) & 0xff,
941                 (OPJ_UINT8) ((h * w + h * (w % 2)) >> 8) &      0xff,
942                 (OPJ_UINT8) ((h * w + h * (w % 2)) >> 16) &     0xff,
943                 (OPJ_UINT8) ((h * w + h * (w % 2)) >> 24) & 0xff);
944         fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
945         fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
946         fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
947         fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
948
949         if (image->comps[0].prec > 8) {
950             adjustR = (int)image->comps[0].prec - 8;
951             printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
952         }else
953             adjustR = 0;
954
955         for (i = 0; i < 256; i++) {
956             fprintf(fdest, "%c%c%c%c", i, i, i, 0);
957         }
958
959         for (i = 0; i < w * h; i++) {
960             int r;
961
962             r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
963             r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
964             r = ((r >> adjustR)+((r >> (adjustR-1))%2));
965             if(r > 255) r = 255; else if(r < 0) r = 0;
966
967             fprintf(fdest, "%c", (OPJ_UINT8)r);
968
969             if ((i + 1) % w == 0) {
970                 for (pad = (w % 4) ? (4 - w % 4) : 0; pad > 0; pad--)   /* ADD */
971                     fprintf(fdest, "%c", 0);
972             }
973         }
974         fclose(fdest);
975     }
976
977     return 0;
978 }