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_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;
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)
91 for (y = height; y != 0U; --y) {
94 for(x = 0; x < width; x++)
96 pDst[x] = pLUT[pSrc[x]];
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)
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];
117 for (y = height; y != 0U; --y) {
120 for(x = 0; x < width; x++)
122 OPJ_UINT8 idx = pSrc[x];
134 static void bmp24toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image)
137 OPJ_UINT32 width, height;
139 const OPJ_UINT8 *pSrc = NULL;
141 width = image->comps[0].w;
142 height = image->comps[0].h;
145 pSrc = pData + (height - 1U) * stride;
146 for(y = 0; y < height; y++)
148 for(x = 0; x < width; x++)
150 image->comps[0].data[index] = pSrc[3*x+2]; /* R */
151 image->comps[1].data[index] = pSrc[3*x+1]; /* G */
152 image->comps[2].data[index] = pSrc[3*x+0]; /* B */
159 static void bmp_mask_get_shift_and_prec(OPJ_UINT32 mask, OPJ_UINT32* shift, OPJ_UINT32* prec)
161 OPJ_UINT32 l_shift, l_prec;
163 l_shift = l_prec = 0U;
166 while ((mask & 1U) == 0U) {
175 *shift = l_shift; *prec = l_prec;
178 static void bmpmask32toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT32 redMask, OPJ_UINT32 greenMask, OPJ_UINT32 blueMask, OPJ_UINT32 alphaMask)
181 OPJ_UINT32 width, height;
183 const OPJ_UINT8 *pSrc = NULL;
184 OPJ_BOOL hasAlpha = OPJ_FALSE;
185 OPJ_UINT32 redShift, redPrec;
186 OPJ_UINT32 greenShift, greenPrec;
187 OPJ_UINT32 blueShift, bluePrec;
188 OPJ_UINT32 alphaShift, alphaPrec;
190 width = image->comps[0].w;
191 height = image->comps[0].h;
193 hasAlpha = image->numcomps > 3U;
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);
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;
207 image->comps[3].bpp = alphaPrec;
208 image->comps[3].prec = alphaPrec;
212 pSrc = pData + (height - 1U) * stride;
213 for(y = 0; y < height; y++)
215 for(x = 0; x < width; x++)
217 OPJ_UINT32 value = 0U;
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;
224 image->comps[0].data[index] = (value & redMask) >> redShift; /* R */
225 image->comps[1].data[index] = (value & greenMask) >> greenShift; /* G */
226 image->comps[2].data[index] = (value & blueMask) >> blueShift; /* B */
228 image->comps[3].data[index] = (value & alphaMask) >> alphaShift; /* A */
236 static void bmpmask16toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT32 redMask, OPJ_UINT32 greenMask, OPJ_UINT32 blueMask, OPJ_UINT32 alphaMask)
239 OPJ_UINT32 width, height;
241 const OPJ_UINT8 *pSrc = NULL;
242 OPJ_BOOL hasAlpha = OPJ_FALSE;
243 OPJ_UINT32 redShift, redPrec;
244 OPJ_UINT32 greenShift, greenPrec;
245 OPJ_UINT32 blueShift, bluePrec;
246 OPJ_UINT32 alphaShift, alphaPrec;
248 width = image->comps[0].w;
249 height = image->comps[0].h;
251 hasAlpha = image->numcomps > 3U;
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);
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;
265 image->comps[3].bpp = alphaPrec;
266 image->comps[3].prec = alphaPrec;
270 pSrc = pData + (height - 1U) * stride;
271 for(y = 0; y < height; y++)
273 for(x = 0; x < width; x++)
275 OPJ_UINT32 value = 0U;
277 value |= ((OPJ_UINT32)pSrc[2*x+0]) << 0;
278 value |= ((OPJ_UINT32)pSrc[2*x+1]) << 8;
280 image->comps[0].data[index] = (value & redMask) >> redShift; /* R */
281 image->comps[1].data[index] = (value & greenMask) >> greenShift; /* G */
282 image->comps[2].data[index] = (value & blueMask) >> blueShift; /* B */
284 image->comps[3].data[index] = (value & alphaMask) >> alphaShift; /* A */
292 static opj_image_t* bmp8toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT8 const* const* pLUT)
294 OPJ_UINT32 width, height;
295 const OPJ_UINT8 *pSrc = NULL;
297 width = image->comps[0].w;
298 height = image->comps[0].h;
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);
305 OPJ_INT32* pDst[] = { image->comps[0].data, image->comps[1].data, image->comps[2].data };
306 OPJ_INT32 pDstStride[] = { (OPJ_INT32)width, (OPJ_INT32)width, (OPJ_INT32)width };
308 opj_applyLUT8u_8u32s_C1P3R(pSrc, -(OPJ_INT32)stride, pDst, pDstStride, pLUT, width, height);
313 static OPJ_BOOL bmp_read_file_header(FILE* IN, OPJ_BITMAPFILEHEADER* header)
315 header->bfType = (OPJ_UINT16)getc(IN);
316 header->bfType += (OPJ_UINT16)(getc(IN) << 8);
318 if (header->bfType != 19778) {
319 fprintf(stderr,"Error, not a BMP file!\n");
325 header->bfSize = (OPJ_UINT32)getc(IN);
326 header->bfSize += (OPJ_UINT32)(getc(IN) << 8);
327 header->bfSize += (OPJ_UINT32)(getc(IN) << 16);
328 header->bfSize += (OPJ_UINT32)(getc(IN) << 24);
330 header->bfReserved1 = (OPJ_UINT16)getc(IN);
331 header->bfReserved1 += (OPJ_UINT16)(getc(IN) << 8);
333 header->bfReserved2 = (OPJ_UINT16)getc(IN);
334 header->bfReserved2 += (OPJ_UINT16)(getc(IN) << 8);
336 header->bfOffBits = (OPJ_UINT32)getc(IN);
337 header->bfOffBits += (OPJ_UINT32)(getc(IN) << 8);
338 header->bfOffBits += (OPJ_UINT32)(getc(IN) << 16);
339 header->bfOffBits += (OPJ_UINT32)(getc(IN) << 24);
342 static OPJ_BOOL bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
344 memset(header, 0, sizeof(*header));
347 header->biSize = (OPJ_UINT32)getc(IN);
348 header->biSize += (OPJ_UINT32)(getc(IN) << 8);
349 header->biSize += (OPJ_UINT32)(getc(IN) << 16);
350 header->biSize += (OPJ_UINT32)(getc(IN) << 24);
352 switch (header->biSize) {
353 case 12U: /* BITMAPCOREHEADER */
354 case 40U: /* BITMAPINFOHEADER */
355 case 52U: /* BITMAPV2INFOHEADER */
356 case 56U: /* BITMAPV3INFOHEADER */
357 case 108U: /* BITMAPV4HEADER */
358 case 124U: /* BITMAPV5HEADER */
361 fprintf(stderr,"Error, unknown BMP header size %d\n", header->biSize);
365 header->biWidth = (OPJ_UINT32)getc(IN);
366 header->biWidth += (OPJ_UINT32)(getc(IN) << 8);
367 header->biWidth += (OPJ_UINT32)(getc(IN) << 16);
368 header->biWidth += (OPJ_UINT32)(getc(IN) << 24);
370 header->biHeight = (OPJ_UINT32)getc(IN);
371 header->biHeight += (OPJ_UINT32)(getc(IN) << 8);
372 header->biHeight += (OPJ_UINT32)(getc(IN) << 16);
373 header->biHeight += (OPJ_UINT32)(getc(IN) << 24);
375 header->biPlanes = (OPJ_UINT16)getc(IN);
376 header->biPlanes += (OPJ_UINT16)(getc(IN) << 8);
378 header->biBitCount = (OPJ_UINT16)getc(IN);
379 header->biBitCount += (OPJ_UINT16)(getc(IN) << 8);
381 if(header->biSize >= 40U) {
382 header->biCompression = (OPJ_UINT32)getc(IN);
383 header->biCompression += (OPJ_UINT32)(getc(IN) << 8);
384 header->biCompression += (OPJ_UINT32)(getc(IN) << 16);
385 header->biCompression += (OPJ_UINT32)(getc(IN) << 24);
387 header->biSizeImage = (OPJ_UINT32)getc(IN);
388 header->biSizeImage += (OPJ_UINT32)(getc(IN) << 8);
389 header->biSizeImage += (OPJ_UINT32)(getc(IN) << 16);
390 header->biSizeImage += (OPJ_UINT32)(getc(IN) << 24);
392 header->biXpelsPerMeter = (OPJ_UINT32)getc(IN);
393 header->biXpelsPerMeter += (OPJ_UINT32)(getc(IN) << 8);
394 header->biXpelsPerMeter += (OPJ_UINT32)(getc(IN) << 16);
395 header->biXpelsPerMeter += (OPJ_UINT32)(getc(IN) << 24);
397 header->biYpelsPerMeter = (OPJ_UINT32)getc(IN);
398 header->biYpelsPerMeter += (OPJ_UINT32)(getc(IN) << 8);
399 header->biYpelsPerMeter += (OPJ_UINT32)(getc(IN) << 16);
400 header->biYpelsPerMeter += (OPJ_UINT32)(getc(IN) << 24);
402 header->biClrUsed = (OPJ_UINT32)getc(IN);
403 header->biClrUsed += (OPJ_UINT32)(getc(IN) << 8);
404 header->biClrUsed += (OPJ_UINT32)(getc(IN) << 16);
405 header->biClrUsed += (OPJ_UINT32)(getc(IN) << 24);
407 header->biClrImportant = (OPJ_UINT32)getc(IN);
408 header->biClrImportant += (OPJ_UINT32)(getc(IN) << 8);
409 header->biClrImportant += (OPJ_UINT32)(getc(IN) << 16);
410 header->biClrImportant += (OPJ_UINT32)(getc(IN) << 24);
413 if(header->biSize >= 56U) {
414 header->biRedMask = (OPJ_UINT32)getc(IN);
415 header->biRedMask += (OPJ_UINT32)(getc(IN) << 8);
416 header->biRedMask += (OPJ_UINT32)(getc(IN) << 16);
417 header->biRedMask += (OPJ_UINT32)(getc(IN) << 24);
419 header->biGreenMask = (OPJ_UINT32)getc(IN);
420 header->biGreenMask += (OPJ_UINT32)(getc(IN) << 8);
421 header->biGreenMask += (OPJ_UINT32)(getc(IN) << 16);
422 header->biGreenMask += (OPJ_UINT32)(getc(IN) << 24);
424 header->biBlueMask = (OPJ_UINT32)getc(IN);
425 header->biBlueMask += (OPJ_UINT32)(getc(IN) << 8);
426 header->biBlueMask += (OPJ_UINT32)(getc(IN) << 16);
427 header->biBlueMask += (OPJ_UINT32)(getc(IN) << 24);
429 header->biAlphaMask = (OPJ_UINT32)getc(IN);
430 header->biAlphaMask += (OPJ_UINT32)(getc(IN) << 8);
431 header->biAlphaMask += (OPJ_UINT32)(getc(IN) << 16);
432 header->biAlphaMask += (OPJ_UINT32)(getc(IN) << 24);
435 if(header->biSize >= 108U) {
436 header->biColorSpaceType = (OPJ_UINT32)getc(IN);
437 header->biColorSpaceType += (OPJ_UINT32)(getc(IN) << 8);
438 header->biColorSpaceType += (OPJ_UINT32)(getc(IN) << 16);
439 header->biColorSpaceType += (OPJ_UINT32)(getc(IN) << 24);
441 fread(&(header->biColorSpaceEP), 1U, sizeof(header->biColorSpaceEP), IN);
443 header->biRedGamma = (OPJ_UINT32)getc(IN);
444 header->biRedGamma += (OPJ_UINT32)(getc(IN) << 8);
445 header->biRedGamma += (OPJ_UINT32)(getc(IN) << 16);
446 header->biRedGamma += (OPJ_UINT32)(getc(IN) << 24);
448 header->biGreenGamma = (OPJ_UINT32)getc(IN);
449 header->biGreenGamma += (OPJ_UINT32)(getc(IN) << 8);
450 header->biGreenGamma += (OPJ_UINT32)(getc(IN) << 16);
451 header->biGreenGamma += (OPJ_UINT32)(getc(IN) << 24);
453 header->biBlueGamma = (OPJ_UINT32)getc(IN);
454 header->biBlueGamma += (OPJ_UINT32)(getc(IN) << 8);
455 header->biBlueGamma += (OPJ_UINT32)(getc(IN) << 16);
456 header->biBlueGamma += (OPJ_UINT32)(getc(IN) << 24);
459 if(header->biSize >= 124U) {
460 header->biIntent = (OPJ_UINT32)getc(IN);
461 header->biIntent += (OPJ_UINT32)(getc(IN) << 8);
462 header->biIntent += (OPJ_UINT32)(getc(IN) << 16);
463 header->biIntent += (OPJ_UINT32)(getc(IN) << 24);
465 header->biIccProfileData = (OPJ_UINT32)getc(IN);
466 header->biIccProfileData += (OPJ_UINT32)(getc(IN) << 8);
467 header->biIccProfileData += (OPJ_UINT32)(getc(IN) << 16);
468 header->biIccProfileData += (OPJ_UINT32)(getc(IN) << 24);
470 header->biIccProfileSize = (OPJ_UINT32)getc(IN);
471 header->biIccProfileSize += (OPJ_UINT32)(getc(IN) << 8);
472 header->biIccProfileSize += (OPJ_UINT32)(getc(IN) << 16);
473 header->biIccProfileSize += (OPJ_UINT32)(getc(IN) << 24);
475 header->biReserved = (OPJ_UINT32)getc(IN);
476 header->biReserved += (OPJ_UINT32)(getc(IN) << 8);
477 header->biReserved += (OPJ_UINT32)(getc(IN) << 16);
478 header->biReserved += (OPJ_UINT32)(getc(IN) << 24);
483 static OPJ_BOOL bmp_read_raw_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
485 if ( fread(pData, sizeof(OPJ_UINT8), stride * height, IN) != (stride * height) )
487 fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
493 static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
497 const OPJ_UINT8 *beyond;
499 beyond = pData + stride * height;
509 OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
511 for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
517 if (c == 0x00) { /* EOL */
520 pix = pData + y * stride + x;
522 else if (c == 0x01) { /* EOP */
525 else if (c == 0x02) { /* MOVE by dxdy */
530 pix = pData + y * stride + x;
535 for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++)
537 OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
540 if ((OPJ_UINT32)c & 1U) { /* skip padding byte */
549 static OPJ_BOOL bmp_read_rle4_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
553 const OPJ_UINT8 *beyond;
555 beyond = pData + stride * height;
563 if(c) {/* encoded mode */
565 OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
567 for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
568 *pix = (j&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
571 else { /* absolute mode */
575 if(c == 0x00) { /* EOL */
576 x = 0; y++; pix = pData + y * stride;
578 else if(c == 0x01) { /* EOP */
581 else if(c == 0x02) { /* MOVE by dxdy */
582 c = getc(IN); x += c;
583 c = getc(IN); y += c;
584 pix = pData + y * stride + x;
586 else { /* 03 .. 255 : absolute mode */
590 for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
594 *pix = (j&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
596 if(((c&3) == 1) || ((c&3) == 2)) { /* skip padding byte */
601 } /* while(y < height) */
605 opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
607 opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */
608 OPJ_UINT8 lut_R[256], lut_G[256], lut_B[256];
609 OPJ_UINT8 const* pLUT[] = { lut_R, lut_G, lut_B };
610 opj_image_t * image = NULL;
612 OPJ_BITMAPFILEHEADER File_h;
613 OPJ_BITMAPINFOHEADER Info_h;
614 OPJ_UINT32 i, palette_len, numcmpts = 1U;
615 OPJ_BOOL l_result = OPJ_FALSE;
616 OPJ_UINT8* pData = NULL;
619 IN = fopen(filename, "rb");
622 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
626 if (!bmp_read_file_header(IN, &File_h)) {
630 if (!bmp_read_info_header(IN, &Info_h)) {
636 if (Info_h.biBitCount <= 8U)
638 memset(&lut_R[0], 0, sizeof(lut_R));
639 memset(&lut_G[0], 0, sizeof(lut_G));
640 memset(&lut_B[0], 0, sizeof(lut_B));
642 palette_len = Info_h.biClrUsed;
643 if((palette_len == 0U) && (Info_h.biBitCount <= 8U)) {
644 palette_len = (1U << Info_h.biBitCount);
646 if (palette_len > 256U) {
649 if (palette_len > 0U) {
650 OPJ_UINT8 has_color = 0U;
651 for (i = 0U; i < palette_len; i++) {
652 lut_B[i] = (OPJ_UINT8)getc(IN);
653 lut_G[i] = (OPJ_UINT8)getc(IN);
654 lut_R[i] = (OPJ_UINT8)getc(IN);
655 (void)getc(IN); /* padding */
656 has_color |= (lut_B[i] ^ lut_G[i]) | (lut_G[i] ^ lut_R[i]);
664 if (Info_h.biAlphaMask != 0U) {
669 stride = ((Info_h.biWidth * Info_h.biBitCount + 31U) / 32U) * 4U; // rows are aligned on 32bits
670 if (Info_h.biBitCount == 4 && Info_h.biCompression == 2) { /* RLE 4 gets decoded as 8 bits data for now... */
671 stride = ((Info_h.biWidth * 8U + 31U) / 32U) * 4U; // rows are aligned on 32bits
673 pData = (OPJ_UINT8 *) calloc(1, stride * Info_h.biHeight * sizeof(OPJ_UINT8));
678 /* Place the cursor at the beginning of the image information */
679 fseek(IN, 0, SEEK_SET);
680 fseek(IN, (long)File_h.bfOffBits, SEEK_SET);
682 switch (Info_h.biCompression) {
686 l_result = bmp_read_raw_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
690 l_result = bmp_read_rle8_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
694 l_result = bmp_read_rle4_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
697 fprintf(stderr, "Unsupported BMP compression\n");
698 l_result = OPJ_FALSE;
707 /* create the image */
708 memset(&cmptparm[0], 0, sizeof(cmptparm));
709 for(i = 0; i < 4U; i++)
711 cmptparm[i].prec = 8;
713 cmptparm[i].sgnd = 0;
714 cmptparm[i].dx = (OPJ_UINT32)parameters->subsampling_dx;
715 cmptparm[i].dy = (OPJ_UINT32)parameters->subsampling_dy;
716 cmptparm[i].w = Info_h.biWidth;
717 cmptparm[i].h = Info_h.biHeight;
720 image = opj_image_create(numcmpts, &cmptparm[0], (numcmpts == 1U) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB);
725 if (numcmpts == 4U) {
726 image->comps[3].alpha = 1;
729 /* set image offset and reference grid */
730 image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
731 image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
732 image->x1 = image->x0 + (Info_h.biWidth - 1U) * (OPJ_UINT32)parameters->subsampling_dx + 1U;
733 image->y1 = image->y0 + (Info_h.biHeight - 1U) * (OPJ_UINT32)parameters->subsampling_dy + 1U;
736 if (Info_h.biBitCount == 24 && Info_h.biCompression == 0) { /*RGB */
737 bmp24toimage(IN, pData, stride, image);
739 else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { /* RGB 8bpp Indexed */
740 bmp8toimage(IN, pData, stride, image, pLUT);
742 else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { /*RLE8*/
743 bmp8toimage(IN, pData, stride, image, pLUT);
745 else if (Info_h.biBitCount == 4 && Info_h.biCompression == 2) { /*RLE4*/
746 bmp8toimage(IN, pData, stride, image, pLUT); /* RLE 4 gets decoded as 8 bits data for now */
748 else if (Info_h.biBitCount == 32 && Info_h.biCompression == 3) { /* bitmask */
749 bmpmask32toimage(IN, pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
751 else if (Info_h.biBitCount == 16 && Info_h.biCompression == 3) { /* bitmask */
752 bmpmask16toimage(IN, pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
755 opj_image_destroy(image);
757 fprintf(stderr, "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount);
764 int imagetobmp(opj_image_t * image, const char *outfile) {
768 int adjustR, adjustG, adjustB;
770 if (image->comps[0].prec < 8) {
771 fprintf(stderr, "Unsupported number of components: %d\n", image->comps[0].prec);
774 if (image->numcomps >= 3 && image->comps[0].dx == image->comps[1].dx
775 && image->comps[1].dx == image->comps[2].dx
776 && image->comps[0].dy == image->comps[1].dy
777 && image->comps[1].dy == image->comps[2].dy
778 && image->comps[0].prec == image->comps[1].prec
779 && image->comps[1].prec == image->comps[2].prec) {
781 /* -->> -->> -->> -->>
783 <<-- <<-- <<-- <<-- */
785 fdest = fopen(outfile, "wb");
787 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
791 w = (int)image->comps[0].w;
792 h = (int)image->comps[0].h;
794 fprintf(fdest, "BM");
798 fprintf(fdest, "%c%c%c%c",
799 (OPJ_UINT8) (h * w * 3 + 3 * h * (w % 2) + 54) & 0xff,
800 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 8) & 0xff,
801 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 16) & 0xff,
802 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 24) & 0xff);
803 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
804 fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
808 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
809 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((w) & 0xff),
810 (OPJ_UINT8) ((w) >> 8) & 0xff,
811 (OPJ_UINT8) ((w) >> 16) & 0xff,
812 (OPJ_UINT8) ((w) >> 24) & 0xff);
813 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((h) & 0xff),
814 (OPJ_UINT8) ((h) >> 8) & 0xff,
815 (OPJ_UINT8) ((h) >> 16) & 0xff,
816 (OPJ_UINT8) ((h) >> 24) & 0xff);
817 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
818 fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
819 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
820 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) (3 * h * w + 3 * h * (w % 2)) & 0xff,
821 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2)) >> 8) & 0xff,
822 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2)) >> 16) & 0xff,
823 (OPJ_UINT8) ((h * w * 3 + 3 * h * (w % 2)) >> 24) & 0xff);
824 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
825 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
826 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
827 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
829 if (image->comps[0].prec > 8) {
830 adjustR = (int)image->comps[0].prec - 8;
831 printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
835 if (image->comps[1].prec > 8) {
836 adjustG = (int)image->comps[1].prec - 8;
837 printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
841 if (image->comps[2].prec > 8) {
842 adjustB = (int)image->comps[2].prec - 8;
843 printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
848 for (i = 0; i < w * h; i++) {
849 OPJ_UINT8 rc, gc, bc;
852 r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
853 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
854 r = ((r >> adjustR)+((r >> (adjustR-1))%2));
855 if(r > 255) r = 255; else if(r < 0) r = 0;
858 g = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
859 g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
860 g = ((g >> adjustG)+((g >> (adjustG-1))%2));
861 if(g > 255) g = 255; else if(g < 0) g = 0;
864 b = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
865 b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
866 b = ((b >> adjustB)+((b >> (adjustB-1))%2));
867 if(b > 255) b = 255; else if(b < 0) b = 0;
870 fprintf(fdest, "%c%c%c", bc, gc, rc);
872 if ((i + 1) % w == 0) {
873 for (pad = (3 * w) % 4 ? 4 - (3 * w) % 4 : 0; pad > 0; pad--) /* ADD */
874 fprintf(fdest, "%c", 0);
878 } else { /* Gray-scale */
880 /* -->> -->> -->> -->>
881 8 bits non code (Gray scale)
882 <<-- <<-- <<-- <<-- */
884 fdest = fopen(outfile, "wb");
885 w = (int)image->comps[0].w;
886 h = (int)image->comps[0].h;
888 fprintf(fdest, "BM");
892 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) (h * w + 54 + 1024 + h * (w % 2)) & 0xff,
893 (OPJ_UINT8) ((h * w + 54 + 1024 + h * (w % 2)) >> 8) & 0xff,
894 (OPJ_UINT8) ((h * w + 54 + 1024 + h * (w % 2)) >> 16) & 0xff,
895 (OPJ_UINT8) ((h * w + 54 + 1024 + w * (w % 2)) >> 24) & 0xff);
896 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
897 fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff,
898 ((54 + 1024) >> 16) & 0xff,
899 ((54 + 1024) >> 24) & 0xff);
903 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
904 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((w) & 0xff),
905 (OPJ_UINT8) ((w) >> 8) & 0xff,
906 (OPJ_UINT8) ((w) >> 16) & 0xff,
907 (OPJ_UINT8) ((w) >> 24) & 0xff);
908 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) ((h) & 0xff),
909 (OPJ_UINT8) ((h) >> 8) & 0xff,
910 (OPJ_UINT8) ((h) >> 16) & 0xff,
911 (OPJ_UINT8) ((h) >> 24) & 0xff);
912 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
913 fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
914 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
915 fprintf(fdest, "%c%c%c%c", (OPJ_UINT8) (h * w + h * (w % 2)) & 0xff,
916 (OPJ_UINT8) ((h * w + h * (w % 2)) >> 8) & 0xff,
917 (OPJ_UINT8) ((h * w + h * (w % 2)) >> 16) & 0xff,
918 (OPJ_UINT8) ((h * w + h * (w % 2)) >> 24) & 0xff);
919 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
920 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
921 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
922 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
924 if (image->comps[0].prec > 8) {
925 adjustR = (int)image->comps[0].prec - 8;
926 printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
930 for (i = 0; i < 256; i++) {
931 fprintf(fdest, "%c%c%c%c", i, i, i, 0);
934 for (i = 0; i < w * h; i++) {
937 r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
938 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
939 r = ((r >> adjustR)+((r >> (adjustR-1))%2));
940 if(r > 255) r = 255; else if(r < 0) r = 0;
942 fprintf(fdest, "%c", (OPJ_UINT8)r);
944 if ((i + 1) % w == 0) {
945 for (pad = w % 4 ? 4 - w % 4 : 0; pad > 0; pad--) /* ADD */
946 fprintf(fdest, "%c", 0);