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.
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.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
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.
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.
38 #include "opj_apps_config.h"
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;
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_BITMAPINFOHEADER;
70 static void opj_applyLUT8u_8u32s_C1R(
71 OPJ_UINT8 const* pSrc, OPJ_INT32 srcStride,
72 OPJ_INT32* pDst, OPJ_INT32 dstStride,
73 OPJ_UINT8 const* pLUT,
74 OPJ_UINT32 width, OPJ_UINT32 height)
78 for (y = height; y != 0U; --y) {
81 for(x = 0; x < width; x++)
83 pDst[x] = pLUT[pSrc[x]];
90 static void opj_applyLUT8u_8u32s_C1P3R(
91 OPJ_UINT8 const* pSrc, OPJ_INT32 srcStride,
92 OPJ_INT32* const* pDst, OPJ_INT32 const* pDstStride,
93 OPJ_UINT8 const* const* pLUT,
94 OPJ_UINT32 width, OPJ_UINT32 height)
97 OPJ_INT32* pR = pDst[0];
98 OPJ_INT32* pG = pDst[1];
99 OPJ_INT32* pB = pDst[2];
100 OPJ_UINT8 const* pLUT_R = pLUT[0];
101 OPJ_UINT8 const* pLUT_G = pLUT[1];
102 OPJ_UINT8 const* pLUT_B = pLUT[2];
104 for (y = height; y != 0U; --y) {
107 for(x = 0; x < width; x++)
109 OPJ_UINT8 idx = pSrc[x];
121 static opj_image_t* bmp24toimage(FILE *IN, const OPJ_BITMAPFILEHEADER* File_h, const OPJ_BITMAPINFOHEADER* Info_h, const opj_cparameters_t *parameters)
123 opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
124 opj_image_t * image = NULL;
126 OPJ_UINT32 width, height, stride;
128 OPJ_UINT8 *pData = NULL;
129 const OPJ_UINT8 *pSrc = NULL;
131 width = Info_h->biWidth;
132 height = Info_h->biHeight;
134 /* initialize image components */
135 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
136 for(i = 0; i < 3; i++)
138 cmptparm[i].prec = 8;
140 cmptparm[i].sgnd = 0;
141 cmptparm[i].dx = (OPJ_UINT32)parameters->subsampling_dx;
142 cmptparm[i].dy = (OPJ_UINT32)parameters->subsampling_dy;
143 cmptparm[i].w = (OPJ_UINT32)width;
144 cmptparm[i].h = (OPJ_UINT32)height;
146 /* create the image */
147 image = opj_image_create(3U, &cmptparm[0], OPJ_CLRSPC_SRGB);
153 /* set image offset and reference grid */
154 image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
155 image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
156 image->x1 = image->x0 + (OPJ_UINT32)(width - 1U) * (OPJ_UINT32)parameters->subsampling_dx + 1U;
157 image->y1 = image->y0 + (OPJ_UINT32)(height - 1U) * (OPJ_UINT32)parameters->subsampling_dy + 1U;
161 /* Place the cursor at the beginning of the image information */
162 fseek(IN, 0, SEEK_SET);
163 fseek(IN, (long)File_h->bfOffBits, SEEK_SET);
166 /* line is 32 bits aligned */
168 stride += 4U - (stride & 3U);
171 pData = (OPJ_UINT8 *)malloc(stride * height * sizeof(OPJ_UINT8));
173 if ( fread(pData, sizeof(OPJ_UINT8), stride * height, IN) != (stride * height) )
176 opj_image_destroy(image);
177 fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
182 pSrc = pData + (height - 1U) * stride;
183 for(y = 0; y < height; y++)
185 for(x = 0; x < width; x++)
187 image->comps[0].data[index] = pSrc[3*x+2]; /* R */
188 image->comps[1].data[index] = pSrc[3*x+1]; /* G */
189 image->comps[2].data[index] = pSrc[3*x+0]; /* B */
198 static opj_image_t* bmp8toimage(FILE *IN, const OPJ_BITMAPFILEHEADER* File_h, const OPJ_BITMAPINFOHEADER* Info_h, const opj_cparameters_t *parameters)
200 OPJ_UINT8 lut_R[256], lut_G[256], lut_B[256];
201 opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
202 opj_image_t * image = NULL;
204 OPJ_UINT32 i, palette_len;
205 OPJ_UINT32 width, height, stride;
206 OPJ_UINT8 *pData = NULL;
207 const OPJ_UINT8 *pSrc = NULL;
208 OPJ_UINT32 numcmpts = 1U; /* grayscale by default */
210 width = Info_h->biWidth;
211 height = Info_h->biHeight;
214 memset(&cmptparm[0], 0, sizeof(cmptparm));
215 memset(&lut_R[0], 0, sizeof(lut_R));
216 memset(&lut_G[0], 0, sizeof(lut_G));
217 memset(&lut_B[0], 0, sizeof(lut_B));
219 palette_len = Info_h->biClrUsed;
220 if ((palette_len == 0U) || (palette_len > 256U)) {
226 OPJ_UINT8 has_color = 0U;
227 for (i = 0; i < palette_len; i++) {
228 lut_B[i] = (OPJ_UINT8)getc(IN);
229 lut_G[i] = (OPJ_UINT8)getc(IN);
230 lut_R[i] = (OPJ_UINT8)getc(IN);
231 getc(IN); /* padding */
232 has_color |= lut_B[i] ^ (lut_G[i] | lut_R[i]);
240 for(i = 0; i < numcmpts; i++)
242 cmptparm[i].prec = 8;
244 cmptparm[i].sgnd = 0;
245 cmptparm[i].dx = (OPJ_UINT32)parameters->subsampling_dx;
246 cmptparm[i].dy = (OPJ_UINT32)parameters->subsampling_dy;
247 cmptparm[i].w = width;
248 cmptparm[i].h = height;
250 /* create the image */
251 image = opj_image_create(numcmpts, &cmptparm[0], (numcmpts == 1U) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB);
257 /* set image offset and reference grid */
258 image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
259 image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
260 image->x1 = image->x0 + (width - 1U) * (OPJ_UINT32)parameters->subsampling_dx + 1U;
261 image->y1 = image->y0 + (height - 1U) * (OPJ_UINT32)parameters->subsampling_dy + 1U;
265 /* Place the cursor at the beginning of the image information */
266 fseek(IN, 0, SEEK_SET);
267 fseek(IN, (long)File_h->bfOffBits, SEEK_SET);
270 /* line is 32 bits aligned */
272 stride += 4U - (stride & 3U);
275 pData = (OPJ_UINT8 *)malloc(stride * height * sizeof(OPJ_UINT8));
277 if ( fread(pData, sizeof(OPJ_UINT8), stride * height, IN) != (stride * height) )
280 opj_image_destroy(image);
281 fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
286 pSrc = pData + (height - 1U) * stride;
287 if (numcmpts == 1U) {
288 opj_applyLUT8u_8u32s_C1R(pSrc, -(OPJ_INT32)stride, image->comps[0].data, (OPJ_INT32)width, lut_R, width, height);
291 OPJ_INT32* pDst[] = { image->comps[0].data, image->comps[1].data, image->comps[2].data };
292 OPJ_INT32 pDstStride[] = { (OPJ_INT32)width, (OPJ_INT32)width, (OPJ_INT32)width };
293 OPJ_UINT8 const* pLUT[] = { lut_R, lut_G, lut_B };
295 opj_applyLUT8u_8u32s_C1P3R(pSrc, -(OPJ_INT32)stride, pDst, pDstStride, pLUT, width, height);
302 static opj_image_t* bmprle8toimage(FILE *IN, const OPJ_BITMAPFILEHEADER* File_h, const OPJ_BITMAPINFOHEADER* Info_h, const opj_cparameters_t *parameters)
304 OPJ_UINT8 lut_R[256], lut_G[256], lut_B[256];
305 opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
306 opj_image_t * image = NULL;
308 OPJ_UINT32 i, palette_len;
309 OPJ_UINT32 x, y, width, height;
310 OPJ_UINT8 *pData = NULL, *pix;
311 const OPJ_UINT8 *beyond;
312 OPJ_UINT32 numcmpts = 1U; /* grayscale by default */
314 width = Info_h->biWidth;
315 height = Info_h->biHeight;
318 memset(&cmptparm[0], 0, sizeof(cmptparm));
319 memset(&lut_R[0], 0, sizeof(lut_R));
320 memset(&lut_G[0], 0, sizeof(lut_G));
321 memset(&lut_B[0], 0, sizeof(lut_B));
323 palette_len = Info_h->biClrUsed;
324 if ((palette_len == 0U) || (palette_len > 256U)) {
330 OPJ_UINT8 has_color = 0U;
331 for (i = 0; i < palette_len; i++) {
332 lut_B[i] = (OPJ_UINT8)getc(IN);
333 lut_G[i] = (OPJ_UINT8)getc(IN);
334 lut_R[i] = (OPJ_UINT8)getc(IN);
335 getc(IN); /* padding */
336 has_color |= lut_B[i] ^ (lut_G[i] | lut_R[i]);
344 for(i = 0; i < numcmpts; i++)
346 cmptparm[i].prec = 8;
348 cmptparm[i].sgnd = 0;
349 cmptparm[i].dx = (OPJ_UINT32)parameters->subsampling_dx;
350 cmptparm[i].dy = (OPJ_UINT32)parameters->subsampling_dy;
351 cmptparm[i].w = width;
352 cmptparm[i].h = height;
354 /* create the image */
355 image = opj_image_create(numcmpts, &cmptparm[0], (numcmpts == 1U) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB);
361 /* set image offset and reference grid */
362 image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
363 image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
364 image->x1 = image->x0 + (width - 1U) * (OPJ_UINT32)parameters->subsampling_dx + 1U;
365 image->y1 = image->y0 + (height - 1U) * (OPJ_UINT32)parameters->subsampling_dy + 1U;
369 /* Place the cursor at the beginning of the image information */
370 fseek(IN, 0, SEEK_SET);
371 fseek(IN, (long)File_h->bfOffBits, SEEK_SET);
373 pData = (OPJ_UINT8 *) calloc(1, width * height * sizeof(OPJ_UINT8));
374 beyond = pData + width * height;
375 pix = (OPJ_UINT8 *)(beyond - width);
383 OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
385 for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
391 if (c == 0x00) { /* EOL */
394 pix = pData + (height - y - 1U) * width + x;
396 else if (c == 0x01) { /* EOP */
399 else if (c == 0x02) { /* MOVE by dxdy */
404 pix = pData + (height - y - 1U) * width + x;
409 for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++)
411 OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
414 if ((OPJ_UINT32)c & 1U) { /* skip padding byte */
423 opj_applyLUT8u_8u32s_C1R(pData, (OPJ_INT32)width, image->comps[0].data, (OPJ_INT32)width, lut_R, width, height);
426 OPJ_INT32* pDst[] = { image->comps[0].data, image->comps[1].data, image->comps[2].data };
427 OPJ_INT32 pDstStride[] = { (OPJ_INT32)width, (OPJ_INT32)width, (OPJ_INT32)width };
428 OPJ_UINT8 const* pLUT[] = { lut_R, lut_G, lut_B };
430 opj_applyLUT8u_8u32s_C1P3R(pData, (OPJ_INT32)width, pDst, pDstStride, pLUT, width, height);
437 opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
439 opj_image_t * image = NULL;
442 OPJ_BITMAPFILEHEADER File_h;
443 OPJ_BITMAPINFOHEADER Info_h;
445 IN = fopen(filename, "rb");
448 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
452 File_h.bfType = (OPJ_UINT16)getc(IN);
453 File_h.bfType = (OPJ_UINT16)((getc(IN) << 8) + File_h.bfType);
455 if (File_h.bfType != 19778) {
456 fprintf(stderr,"Error, not a BMP file!\n");
463 File_h.bfSize = (OPJ_UINT32)getc(IN);
464 File_h.bfSize = (OPJ_UINT32)(getc(IN) << 8) + File_h.bfSize;
465 File_h.bfSize = (OPJ_UINT32)(getc(IN) << 16) + File_h.bfSize;
466 File_h.bfSize = (OPJ_UINT32)(getc(IN) << 24) + File_h.bfSize;
468 File_h.bfReserved1 = (OPJ_UINT16)getc(IN);
469 File_h.bfReserved1 = (OPJ_UINT16)((getc(IN) << 8) + File_h.bfReserved1);
471 File_h.bfReserved2 = (OPJ_UINT16)getc(IN);
472 File_h.bfReserved2 = (OPJ_UINT16)((getc(IN) << 8) + File_h.bfReserved2);
474 File_h.bfOffBits = (OPJ_UINT32)getc(IN);
475 File_h.bfOffBits = (OPJ_UINT32)(getc(IN) << 8) + File_h.bfOffBits;
476 File_h.bfOffBits = (OPJ_UINT32)(getc(IN) << 16) + File_h.bfOffBits;
477 File_h.bfOffBits = (OPJ_UINT32)(getc(IN) << 24) + File_h.bfOffBits;
482 Info_h.biSize = (OPJ_UINT32)getc(IN);
483 Info_h.biSize = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biSize;
484 Info_h.biSize = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biSize;
485 Info_h.biSize = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biSize;
487 if(Info_h.biSize != 40) {
488 fprintf(stderr,"Error, unknown BMP header size %d\n", Info_h.biSize);
493 Info_h.biWidth = (OPJ_UINT32)getc(IN);
494 Info_h.biWidth = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biWidth;
495 Info_h.biWidth = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biWidth;
496 Info_h.biWidth = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biWidth;
498 Info_h.biHeight = (OPJ_UINT32)getc(IN);
499 Info_h.biHeight = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biHeight;
500 Info_h.biHeight = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biHeight;
501 Info_h.biHeight = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biHeight;
503 Info_h.biPlanes = (OPJ_UINT16)getc(IN);
504 Info_h.biPlanes = (OPJ_UINT16)((getc(IN) << 8) + Info_h.biPlanes);
506 Info_h.biBitCount = (OPJ_UINT16)getc(IN);
507 Info_h.biBitCount = (OPJ_UINT16)((getc(IN) << 8) + Info_h.biBitCount);
509 Info_h.biCompression = (OPJ_UINT32)getc(IN);
510 Info_h.biCompression = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biCompression;
511 Info_h.biCompression = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biCompression;
512 Info_h.biCompression = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biCompression;
514 Info_h.biSizeImage = (OPJ_UINT32)getc(IN);
515 Info_h.biSizeImage = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biSizeImage;
516 Info_h.biSizeImage = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biSizeImage;
517 Info_h.biSizeImage = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biSizeImage;
519 Info_h.biXpelsPerMeter = (OPJ_UINT32)getc(IN);
520 Info_h.biXpelsPerMeter = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biXpelsPerMeter;
521 Info_h.biXpelsPerMeter = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biXpelsPerMeter;
522 Info_h.biXpelsPerMeter = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biXpelsPerMeter;
524 Info_h.biYpelsPerMeter = (OPJ_UINT32)getc(IN);
525 Info_h.biYpelsPerMeter = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biYpelsPerMeter;
526 Info_h.biYpelsPerMeter = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biYpelsPerMeter;
527 Info_h.biYpelsPerMeter = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biYpelsPerMeter;
529 Info_h.biClrUsed = (OPJ_UINT32)getc(IN);
530 Info_h.biClrUsed = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biClrUsed;
531 Info_h.biClrUsed = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biClrUsed;
532 Info_h.biClrUsed = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biClrUsed;
534 Info_h.biClrImportant = (OPJ_UINT32)getc(IN);
535 Info_h.biClrImportant = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biClrImportant;
536 Info_h.biClrImportant = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biClrImportant;
537 Info_h.biClrImportant = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biClrImportant;
540 if (Info_h.biBitCount == 24) { /*RGB */
541 image = bmp24toimage(IN, &File_h, &Info_h, parameters);
543 else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { /* RGB 8bpp Indexed */
544 image = bmp8toimage(IN, &File_h, &Info_h, parameters);
546 else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { /*RLE8*/
547 image = bmprle8toimage(IN, &File_h, &Info_h, parameters);
550 fprintf(stderr, "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount);
556 int imagetobmp(opj_image_t * image, const char *outfile) {
560 int adjustR, adjustG, adjustB;
562 if (image->comps[0].prec < 8) {
563 fprintf(stderr, "Unsupported number of components: %d\n", image->comps[0].prec);
566 if (image->numcomps >= 3 && image->comps[0].dx == image->comps[1].dx
567 && image->comps[1].dx == image->comps[2].dx
568 && image->comps[0].dy == image->comps[1].dy
569 && image->comps[1].dy == image->comps[2].dy
570 && image->comps[0].prec == image->comps[1].prec
571 && image->comps[1].prec == image->comps[2].prec) {
573 /* -->> -->> -->> -->>
575 <<-- <<-- <<-- <<-- */
577 fdest = fopen(outfile, "wb");
579 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
583 w = (int)image->comps[0].w;
584 h = (int)image->comps[0].h;
586 fprintf(fdest, "BM");
590 fprintf(fdest, "%c%c%c%c",
591 (OPJ_UINT8) (h * w * 3 + 3 * h * (w % 2) + 54) & 0xff,
592 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 8) & 0xff,
593 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 16) & 0xff,
594 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 24) & 0xff);
595 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
596 fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
600 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
601 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((w) & 0xff),
602 (OPJ_UINT8) ((w) >> 8) & 0xff,
603 (OPJ_UINT8) ((w) >> 16) & 0xff,
604 (OPJ_UINT8) ((w) >> 24) & 0xff);
605 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((h) & 0xff),
606 (OPJ_UINT8) ((h) >> 8) & 0xff,
607 (OPJ_UINT8) ((h) >> 16) & 0xff,
608 (OPJ_UINT8) ((h) >> 24) & 0xff);
609 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
610 fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
611 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
612 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) (3 * h * w + 3 * h * (w % 2)) & 0xff,
613 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2)) >> 8) & 0xff,
614 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2)) >> 16) & 0xff,
615 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2)) >> 24) & 0xff);
616 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
617 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
618 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
619 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
621 if (image->comps[0].prec > 8) {
622 adjustR = (int)image->comps[0].prec - 8;
623 printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
627 if (image->comps[1].prec > 8) {
628 adjustG = (int)image->comps[1].prec - 8;
629 printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
633 if (image->comps[2].prec > 8) {
634 adjustB = (int)image->comps[2].prec - 8;
635 printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
640 for (i = 0; i < w * h; i++) {
641 OPJ_UINT8 rc, gc, bc;
644 r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
645 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
646 r = ((r >> adjustR)+((r >> (adjustR-1))%2));
647 if(r > 255) r = 255; else if(r < 0) r = 0;
650 g = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
651 g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
652 g = ((g >> adjustG)+((g >> (adjustG-1))%2));
653 if(g > 255) g = 255; else if(g < 0) g = 0;
656 b = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
657 b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
658 b = ((b >> adjustB)+((b >> (adjustB-1))%2));
659 if(b > 255) b = 255; else if(b < 0) b = 0;
662 fprintf(fdest, "%c%c%c", bc, gc, rc);
664 if ((i + 1) % w == 0) {
665 for (pad = (3 * w) % 4 ? 4 - (3 * w) % 4 : 0; pad > 0; pad--) /* ADD */
666 fprintf(fdest, "%c", 0);
670 } else { /* Gray-scale */
672 /* -->> -->> -->> -->>
673 8 bits non code (Gray scale)
674 <<-- <<-- <<-- <<-- */
676 fdest = fopen(outfile, "wb");
677 w = (int)image->comps[0].w;
678 h = (int)image->comps[0].h;
680 fprintf(fdest, "BM");
684 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) (h * w + 54 + 1024 + h * (w % 2)) & 0xff,
685 (OPJ_UINT8) ((h * w + 54 + 1024 + h * (w % 2)) >> 8) & 0xff,
686 (OPJ_UINT8) ((h * w + 54 + 1024 + h * (w % 2)) >> 16) & 0xff,
687 (OPJ_UINT8) ((h * w + 54 + 1024 + w * (w % 2)) >> 24) & 0xff);
688 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
689 fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff,
690 ((54 + 1024) >> 16) & 0xff,
691 ((54 + 1024) >> 24) & 0xff);
695 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
696 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((w) & 0xff),
697 (OPJ_UINT8) ((w) >> 8) & 0xff,
698 (OPJ_UINT8) ((w) >> 16) & 0xff,
699 (OPJ_UINT8) ((w) >> 24) & 0xff);
700 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((h) & 0xff),
701 (OPJ_UINT8) ((h) >> 8) & 0xff,
702 (OPJ_UINT8) ((h) >> 16) & 0xff,
703 (OPJ_UINT8) ((h) >> 24) & 0xff);
704 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
705 fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
706 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
707 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) (h * w + h * (w % 2)) & 0xff,
708 (OPJ_UINT8) ((h * w + h * (w % 2)) >> 8) & 0xff,
709 (OPJ_UINT8) ((h * w + h * (w % 2)) >> 16) & 0xff,
710 (OPJ_UINT8) ((h * w + h * (w % 2)) >> 24) & 0xff);
711 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
712 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
713 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
714 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
716 if (image->comps[0].prec > 8) {
717 adjustR = (int)image->comps[0].prec - 8;
718 printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
722 for (i = 0; i < 256; i++) {
723 fprintf(fdest, "%c%c%c%c", i, i, i, 0);
726 for (i = 0; i < w * h; i++) {
729 r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
730 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
731 r = ((r >> adjustR)+((r >> (adjustR-1))%2));
732 if(r > 255) r = 255; else if(r < 0) r = 0;
734 fprintf(fdest, "%c", (OPJ_UINT8)r);
736 if ((i + 1) % w == 0) {
737 for (pad = w % 4 ? 4 - w % 4 : 0; pad > 0; pad--) /* ADD */
738 fprintf(fdest, "%c", 0);