Skip to content

Instantly share code, notes, and snippets.

@eikeon
Created March 8, 2013 20:30
Show Gist options
  • Save eikeon/5119599 to your computer and use it in GitHub Desktop.
Save eikeon/5119599 to your computer and use it in GitHub Desktop.
--- openjpeg-trunk-r2299-2/CMakeLists.txt.orig 2013-03-01 12:43:57.000000000 +0100
+++ openjpeg-trunk-r2299-2/CMakeLists.txt 2013-03-07 21:46:29.845377357 +0100
@@ -233,7 +233,12 @@
${CMAKE_CURRENT_BINARY_DIR}/src/lib/openjp2/opj_config.h
@ONLY
)
-
+#
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/openjp2/opj_libconf.h.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/src/lib/openjp2/opj_libconf.h
+ @ONLY
+)
#-----------------------------------------------------------------------------
# Build DOCUMENTATION (not in ALL target and only if Doxygen is found)
option(BUILD_DOC "Build the HTML documentation (with doxygen if available)." OFF)
@@ -295,4 +300,4 @@
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libopenjp2.pc DESTINATION
${OPENJPEG_INSTALL_LIB_DIR}/pkgconfig )
endif()
-#-----------------------------------------------------------------------------
\ No newline at end of file
+#-----------------------------------------------------------------------------
--- openjpeg-trunk-r2299-2/src/lib/openmj2/j2k.c.orig 2013-03-01 12:43:55.000000000 +0100
+++ openjpeg-trunk-r2299-2/src/lib/openmj2/j2k.c 2013-03-07 21:46:29.845377357 +0100
@@ -1537,7 +1537,7 @@
if (len == cio_numbytesleft(cio) + 1) {
truncate = 1; /* Case of a truncate codestream */
}
-
+#ifdef UNUSED_CODE
{/* chop padding bytes: */
unsigned char *s, *e;
@@ -1555,7 +1555,7 @@
}
}
}
-
+#endif /* UNUSED_CODE */
data = j2k->tile_data[curtileno];
data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char));
--- openjpeg-trunk-r2299-2/src/lib/openjp2/opj_stdint.h.orig 2013-03-01 12:43:55.000000000 +0100
+++ openjpeg-trunk-r2299-2/src/lib/openjp2/opj_stdint.h 2013-03-07 21:46:29.846377357 +0100
@@ -26,7 +26,7 @@
#ifndef OPJ_STDINT_H
#define OPJ_STDINT_H
-#include "opj_config.h"
+#include "opj_libconf.h"
#ifdef OPJ_HAVE_STDINT_H
#include <stdint.h>
#else
--- openjpeg-trunk-r2299-2/src/lib/openjp2/jp2.c.orig 2013-03-01 12:43:55.000000000 +0100
+++ openjpeg-trunk-r2299-2/src/lib/openjp2/jp2.c 2013-03-08 17:57:29.694246250 +0100
@@ -452,28 +452,41 @@
/* process read data */
opj_read_bytes(l_data_header,&(box->length), 4);
opj_read_bytes(l_data_header+4,&(box->type), 4);
-
+
+ if(box->length == 0)/* last box */
+ {
+ box->length = opj_stream_get_number_byte_left(cio);
+ return OPJ_TRUE;
+ }
/* do we have a "special very large box ?" */
/* read then the XLBox */
- if (box->length == 1) {
- OPJ_UINT32 l_xl_part_size;
+ if (box->length == 1)
+ {
+ OPJ_UINT32 l_xl_part_size;
+
+ OPJ_UINT32 l_nb_bytes_read = opj_stream_read_data(cio,l_data_header,8,p_manager);
+
+ if (l_nb_bytes_read != 8)
+ {
+ if (l_nb_bytes_read > 0)
+ {
+ *p_number_bytes_read += l_nb_bytes_read;
+ }
+ return OPJ_FALSE;
+ }
+ *p_number_bytes_read = 12;
+
+ opj_read_bytes(l_data_header,&l_xl_part_size, 4);
+
+ if (l_xl_part_size != 0)
+ {
+ opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
+ return OPJ_FALSE;
+ }
+ opj_read_bytes(l_data_header + 4,&(box->length), 4);
- OPJ_UINT32 l_nb_bytes_read = opj_stream_read_data(cio,l_data_header,8,p_manager);
- if (l_nb_bytes_read != 8) {
- if (l_nb_bytes_read > 0) {
- *p_number_bytes_read += l_nb_bytes_read;
- }
-
- return OPJ_FALSE;
- }
-
- opj_read_bytes(l_data_header,&l_xl_part_size, 4);
- if (l_xl_part_size != 0) {
- opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
- return OPJ_FALSE;
- }
- opj_read_bytes(l_data_header,&(box->length), 4);
- }
+ *p_number_bytes_read = 16;
+ }
return OPJ_TRUE;
}
@@ -1121,6 +1134,24 @@
}
}
+ else
+ if(jp2->meth == 3)
+ {
+/* ISO/IEC 15444-1:2004 (E), Table I.9 ­ Legal METH values:
+ conforming JP2 reader shall ignore the entire Colour Specification box.
+*/
+#ifdef UNUSED_CODE
+ OPJ_INT32 i;
+
+ i = p_colr_header_size - 3;
+
+ while(--i >= 0)
+ {
+ opj_read_bytes(p_colr_header_data,&l_value,1);
+ ++p_colr_header_data;
+ }
+#endif /* UNUSED_CODE */
+ }
else
opj_event_msg(p_manager, EVT_INFO, "COLR BOX meth value is not a regular value (%d), so we will skip the fields following the approx field.\n", jp2->meth);
@@ -1678,6 +1709,15 @@
l_current_handler = opj_jp2_find_handler(box.type);
l_current_data_size = box.length - l_nb_bytes_read;
+#ifdef UNUSED_CODE
+ if(box.type == 0x786D6C20 /* 'xml ' */
+ || box.type == 0x584D4C20) /* 'XML ' */
+ {
+ opj_stream_skip(stream,l_current_data_size,p_manager);
+
+ continue;
+ }
+#endif /* UNUSED_CODE */
if (l_current_handler != 00) {
if (l_current_data_size > l_last_data_size) {
--- openjpeg-trunk-r2299-2/src/lib/openjp2/j2k.c.orig 2013-03-01 12:43:55.000000000 +0100
+++ openjpeg-trunk-r2299-2/src/lib/openjp2/j2k.c 2013-03-07 21:46:29.849377357 +0100
@@ -7275,6 +7275,11 @@
else if (l_current_marker != J2K_MS_SOT)
{
opj_event_msg(p_manager, EVT_ERROR, "Stream too short, expected SOT\n");
+ if(opj_stream_get_number_byte_left(p_stream) == 0)
+ {
+ p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
+ return OPJ_TRUE;
+ }
return OPJ_FALSE;
}
}
@@ -8740,6 +8745,9 @@
}
opj_event_msg(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no + 1);
+ if(opj_stream_get_number_byte_left(p_stream) == 0
+ && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC)
+ break;
}
opj_free(l_current_data);
--- openjpeg-trunk-r2299-2/src/lib/openjp2/CMakeLists.txt.orig 2013-03-01 12:43:55.000000000 +0100
+++ openjpeg-trunk-r2299-2/src/lib/openjp2/CMakeLists.txt 2013-03-07 21:46:29.850377357 +0100
@@ -1,11 +1,11 @@
include_regular_expression("^.*$")
#
-install( FILES ${CMAKE_CURRENT_BINARY_DIR}/opj_config.h
+install( FILES ${CMAKE_CURRENT_BINARY_DIR}/opj_libconf.h
DESTINATION ${OPENJPEG_INSTALL_INCLUDE_DIR} COMPONENT Headers)
include_directories(
- ${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h
+ ${OPENJPEG_BINARY_DIR}/src/lib/openjp2
)
# Defines the source code for the library
set(OPENJPEG_SRCS
--- openjpeg-trunk-r2299-2/src/lib/openjp2/opj_inttypes.h.orig 2013-03-01 12:43:55.000000000 +0100
+++ openjpeg-trunk-r2299-2/src/lib/openjp2/opj_inttypes.h 2013-03-07 21:46:29.850377357 +0100
@@ -26,7 +26,7 @@
#ifndef OPJ_INTTYPES_H
#define OPJ_INTTYPES_H
-#include "opj_config.h"
+#include "opj_libconf.h"
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#else
--- openjpeg-trunk-r2299-2/src/lib/openjp2/opj_libconf.h.cmake.in.orig 2013-03-07 21:46:29.851377357 +0100
+++ openjpeg-trunk-r2299-2/src/lib/openjp2/opj_libconf.h.cmake.in 2013-03-07 21:46:29.851377357 +0100
@@ -0,0 +1,19 @@
+#ifndef OPJ_HAVE_STDINT_H
+#cmakedefine OPJ_HAVE_STDINT_H @OPJ_HAVE_STDINT_H@
+#endif
+#ifndef HAVE_INTTYPES_H
+#cmakedefine HAVE_INTTYPES_H @HAVE_INTTYPES_H@
+#endif
+#ifndef HAVE_STDINT_H
+#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@
+#endif
+#ifndef HAVE_SSIZE_T
+#cmakedefine HAVE_SSIZE_T @HAVE_SSIZE_T@
+#endif
+/* Byte order. */
+#if !defined(__APPLE__)
+#cmakedefine OPJ_BIG_ENDIAN
+#elif defined(__BIG_ENDIAN__)
+# define OPJ_BIG_ENDIAN
+#endif
+
--- openjpeg-trunk-r2299-2/src/lib/openjp2/cio.h.orig 2013-03-01 12:43:55.000000000 +0100
+++ openjpeg-trunk-r2299-2/src/lib/openjp2/cio.h 2013-03-07 21:46:29.851377357 +0100
@@ -43,7 +43,7 @@
/** @defgroup CIO CIO - byte input-output stream */
/*@{*/
-#include "opj_config.h"
+#include "opj_libconf.h"
/* ----------------------------------------------------------------------- */
--- openjpeg-trunk-r2299-2/src/bin/jp2/convert.c.orig 2013-03-01 12:43:56.000000000 +0100
+++ openjpeg-trunk-r2299-2/src/bin/jp2/convert.c 2013-03-07 21:46:29.853377357 +0100
@@ -506,503 +506,894 @@
<<-- <<-- <<-- <<-- */
-/* WORD defines a two byte word */
-typedef unsigned short int WORD;
+typedef struct bmp_info
+{
+ unsigned int offset;
+ unsigned int hdr_size;
+ unsigned int width;
+ unsigned int height;
+ unsigned short planes;
+ unsigned short bit_cnt;
+
+ char compression[4];
+ unsigned int image_size;
+ unsigned int xpels_meter;
+ unsigned int ypels_meter;
+ unsigned int num_colors;
+ unsigned int important_colors;
+}BmpInfo;
+
+typedef struct bmp12_info
+{
+ unsigned int offset;
+ unsigned int hdr_size;
+ unsigned short width;
+ unsigned short height;
+ unsigned short planes;
+ unsigned short bit_cnt;
+
+}Bmp12Info;
+
+typedef struct size_info
+{
+ unsigned int offset;
+ unsigned int hdr_size;
+}SizeInfo;
+
+struct bmp_cmap
+{
+ unsigned char blue;
+ unsigned char green;
+ unsigned char red;
+ unsigned char alpha;
+};
+
+/* FORWARD */
+
+#if WORDS_BIGENDIAN == 1
+static inline int32_t swap32(int32_t x){
+ return((((u_int32_t)x & 0x000000ffU) << 24) |
+ (((u_int32_t)x & 0x0000ff00U) << 8) |
+ (((u_int32_t)x & 0x00ff0000U) >> 8) |
+ (((u_int32_t)x & 0xff000000U) >> 24));
+}
+
+static inline int16_t swap16(int16_t x){
+ return((((u_int16_t)x & 0x00ffU) << 8) |
+ (((u_int16_t)x & 0xff00U) >> 8));
+}
+#endif /* WORDS_BIGENDIAN */
+
+static unsigned int RED_mask, GREEN_mask, BLUE_mask, ALPHA_mask;
+static int RED_bits, GREEN_bits, BLUE_bits, ALPHA_bits;
+static int RED_shift, GREEN_shift, BLUE_shift, ALPHA_shift;
+
+static unsigned int colormask[4];
+
+static const char *enc_type[]=
+{
+"ENC_RGB",
+"ENC_RLE8",
+"ENC_RLE4",
+"ENC_BITFIELDS",
+"ENC_JPEG",
+"ENC_PNG",
+"ENC_UNKNOWN",
+NULL
+
+};
+
+#define ENC_RGB 0 /* BI_RGB */
+#define ENC_RLE8 1 /* BI_RLE8 */
+#define ENC_RLE4 2 /* BI_RLE4 */
+#define ENC_BITFIELDS 3 /* BI_BITFIELDS */
+#define ENC_JPEG 4 /* BI_JPEG */
+#define ENC_PNG 5 /* BI_PNG */
+
+static void BMP_read(unsigned int line,
+ BmpInfo *hdr, struct bmp_cmap bmap[256], FILE *reader,
+ unsigned int encoding, int *red, int *green, int *blue)
+{
+ unsigned int w, start_pos, y, x, pixel, byte = 0;
+
+ w = hdr->width;
-/* DWORD defines a four byte word */
-typedef unsigned int DWORD;
+ start_pos = (((w * hdr->bit_cnt + 31) & ~0x1f) >> 3);
+ y = hdr->height - line - 1;
+ fseek(reader,hdr->offset + y * start_pos,SEEK_SET);
-typedef struct {
- WORD bfType; /* 'BM' for Bitmap (19776) */
- DWORD bfSize; /* Size of the file */
- WORD bfReserved1; /* Reserved : 0 */
- WORD bfReserved2; /* Reserved : 0 */
- DWORD bfOffBits; /* Offset */
-} BITMAPFILEHEADER_t;
-
-typedef struct {
- DWORD biSize; /* Size of the structure in bytes */
- DWORD biWidth; /* Width of the image in pixels */
- DWORD biHeight; /* Heigth of the image in pixels */
- WORD biPlanes; /* 1 */
- WORD biBitCount; /* Number of color bits by pixels */
- DWORD biCompression; /* Type of encoding 0: none 1: RLE8 2: RLE4 */
- DWORD biSizeImage; /* Size of the image in bytes */
- DWORD biXpelsPerMeter; /* Horizontal (X) resolution in pixels/meter */
- DWORD biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */
- DWORD biClrUsed; /* Number of color used in the image (0: ALL) */
- DWORD biClrImportant; /* Number of important color (0: ALL) */
-} BITMAPINFOHEADER_t;
-
-opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
-{
- int subsampling_dx = parameters->subsampling_dx;
- int subsampling_dy = parameters->subsampling_dy;
-
- int i, numcomps, w, h;
- OPJ_COLOR_SPACE color_space;
- opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
- opj_image_t * image = NULL;
-
- FILE *IN;
- BITMAPFILEHEADER_t File_h;
- BITMAPINFOHEADER_t Info_h;
- unsigned char *RGB;
- unsigned char *table_R, *table_G, *table_B;
- unsigned int j, PAD = 0;
-
- int x, y, index;
- int gray_scale = 1;
- int has_color;
- DWORD W, H;
-
- IN = fopen(filename, "rb");
- if (!IN)
+ switch (hdr->bit_cnt)
{
- fprintf(stderr, "Failed to open %s for reading !!\n", filename);
- return NULL;
+ case 1:
+ for(x = 0; x < w; ++x)
+ {
+ if((x & 0x07) == 0)
+ byte = fgetc(reader);
+ pixel = byte & (0x80 >> (x & 0x07)) ? 1 : 0;
+ red[x] = bmap[pixel].red;
+ green[x] = bmap[pixel].green;
+ blue[x] = bmap[pixel].blue;
+ }
+ break;
+ case 4:
+ if(encoding == ENC_RGB)
+ {
+ for(x = 0; x < w; ++x)
+ {
+ if(x & 1)
+ {
+ pixel = byte & 0xf;
+ }
+ else
+ {
+ byte = fgetc(reader);
+ pixel = byte >> 4;
+ }
+ red[x] = (unsigned char)bmap[pixel].red;
+ green[x] = (unsigned char)bmap[pixel].green;
+ blue[x] = (unsigned char)bmap[pixel].blue;
+ }
+ }/* if(encoding == ENC_RGB) */
+ break;
+ case 8:
+ if(encoding == ENC_RGB)
+ {
+ for(x = 0; x < w; ++x)
+ {
+ pixel = fgetc(reader);
+ red[x] = (unsigned char)bmap[pixel].red;
+ green[x] = (unsigned char)bmap[pixel].green;
+ blue[x] = (unsigned char)bmap[pixel].blue;
+ }
+ }/* if(encoding == ENC_RGB) */
+ break;
+ case 24:
+ if(encoding == ENC_RGB)
+ {
+ for(x = 0; x < w; ++x)
+ {
+ blue[x] = (unsigned char)fgetc(reader); /* blue */
+ green[x] = (unsigned char)fgetc(reader); /* green */
+ red[x] = (unsigned char)fgetc(reader); /* red */
+ }
+ }/* if(encoding == ENC_RGB) */
+ break;
+ case 32:
+ if(encoding == ENC_RGB)
+ {
+ for(x = 0; x < w; ++x)
+ {
+ blue[x] = (unsigned char)fgetc(reader); /* blue */
+ green[x] = (unsigned char)fgetc(reader); /* green */
+ red[x] = (unsigned char)fgetc(reader); /* red */
+ fgetc(reader);
+ }
+ }/* if(encoding == ENC_RGB) */
+ break;
+
+ default:
+ break;
}
-
- File_h.bfType = getc(IN);
- File_h.bfType = (getc(IN) << 8) + File_h.bfType;
-
- if (File_h.bfType != 19778)
+}
+
+static void RLE4_decoder(FILE *reader, unsigned int width,
+ unsigned int height, unsigned char *dst_buf)
+{
+ unsigned char *dst, *beyond;
+ unsigned int x, y;
+ int i, c, c1;
+
+ x = y = 0;
+ beyond = dst_buf + width * height;
+ dst = beyond - width;
+
+ while(y < height)
{
- fprintf(stderr,"Error, not a BMP file!\n");
- fclose(IN);
- return NULL;
- }
- /* FILE HEADER */
- /* ------------- */
- File_h.bfSize = getc(IN);
- File_h.bfSize = (getc(IN) << 8) + File_h.bfSize;
- File_h.bfSize = (getc(IN) << 16) + File_h.bfSize;
- File_h.bfSize = (getc(IN) << 24) + File_h.bfSize;
-
- File_h.bfReserved1 = getc(IN);
- File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1;
-
- File_h.bfReserved2 = getc(IN);
- File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2;
-
- File_h.bfOffBits = getc(IN);
- File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits;
- File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits;
- File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits;
-
- /* INFO HEADER */
- /* ------------- */
-
- Info_h.biSize = getc(IN);
- Info_h.biSize = (getc(IN) << 8) + Info_h.biSize;
- Info_h.biSize = (getc(IN) << 16) + Info_h.biSize;
- Info_h.biSize = (getc(IN) << 24) + Info_h.biSize;
+ c = getc(reader);
+ if(c == EOF) break;
- if(Info_h.biSize != 40)
+ if(c) /* encoded mode */
+ {
+ c1 = getc(reader);
+
+ for(i = 0; i < c && x < width && dst < beyond; i++, x++, dst++)
+ {
+ *dst = (unsigned char)((i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f));
+ }
+ }
+ else /* absolute mode */
+ {
+ c = getc(reader);
+ if(c == EOF) break;
+
+ if(c == 0x00) /* EOL */
+ {
+ x = 0; y++; dst = dst_buf + (height - y - 1) * width;
+ }
+ else
+ if(c == 0x01) /* EOP */
+ break;
+ else
+ if(c == 0x02) /* MOVE by dxdy */
+ {
+ c = getc(reader); x += c;
+ c = getc(reader); y += c;
+ dst = dst_buf + x + (height - y - 1) * width;
+ }
+ else /* 03 .. 255 : absolute mode */
+ {
+ c1 = 0;
+ for(i = 0; i < c && x < width && dst < beyond; i++, x++, dst++)
+ {
+ if((i&1) == 0)
+ c1 = getc(reader);
+ *dst = (unsigned char)((i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f));
+ }
+ if(((c&3) == 1) || ((c&3) == 2)) /* skip padding byte */
+ getc(reader);
+ }
+ }
+ } /* while(y < height) */
+
+}/* RLE4_decoder() */
+
+static void decode_RLE4_image(FILE *reader,
+ struct bmp_cmap bmap[256],
+ unsigned int width, unsigned int height, int has_alpha,
+ int *red, int *green, int *blue, int *alpha)
+{
+ unsigned char *pixbuf, *pix;
+ unsigned int i, max;
+ unsigned char uc;
+
+ max = width * height;
+ pixbuf = (unsigned char*)calloc(1, max);
+
+ RLE4_decoder(reader, width, height, pixbuf);
+
+ pix = pixbuf;
+
+ for(i = 0; i < max; ++i)
{
- fprintf(stderr,"Error, unknown BMP header size %d\n", Info_h.biSize);
- fclose(IN);
- return NULL;
+ uc = *pix++;
+
+ red[i] = (unsigned char)bmap[uc].red;
+ green[i] = (unsigned char)bmap[uc].green;
+ blue[i] = (unsigned char)bmap[uc].blue;
+
+ if(has_alpha) alpha[i] = bmap[uc].alpha;
}
- Info_h.biWidth = getc(IN);
- Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth;
- Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth;
- Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth;
- w = Info_h.biWidth;
-
- Info_h.biHeight = getc(IN);
- Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight;
- Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight;
- Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight;
- h = Info_h.biHeight;
-
- Info_h.biPlanes = getc(IN);
- Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes;
-
- Info_h.biBitCount = getc(IN);
- Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount;
-
- Info_h.biCompression = getc(IN);
- Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression;
- Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression;
- Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression;
-
- Info_h.biSizeImage = getc(IN);
- Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage;
- Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage;
- Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage;
-
- Info_h.biXpelsPerMeter = getc(IN);
- Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter;
- Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter;
- Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter;
-
- Info_h.biYpelsPerMeter = getc(IN);
- Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter;
- Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter;
- Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter;
-
- Info_h.biClrUsed = getc(IN);
- Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed;
- Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed;
- Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed;
-
- Info_h.biClrImportant = getc(IN);
- Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant;
- Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant;
- Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant;
+ free(pixbuf);
+}/* decode_RLE4_image() */
- /* Read the data and store them in the OUT file */
+static void RLE8_decoder(FILE *reader,
+ unsigned int width, unsigned int height, unsigned char *dst_buf)
+{
+ unsigned char *dst, *beyond;
+ unsigned int x, y;
+ int i, c, c1;
+
+ x = y = 0;
+ beyond = dst_buf + width * height;
+ dst = beyond - width;
- if (Info_h.biBitCount == 24)
+ while(y < height)
{
- numcomps = 3;
- color_space = OPJ_CLRSPC_SRGB;
- /* initialize image components */
- memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
- for(i = 0; i < numcomps; i++)
- {
- cmptparm[i].prec = 8;
- cmptparm[i].bpp = 8;
- cmptparm[i].sgnd = 0;
- cmptparm[i].dx = subsampling_dx;
- cmptparm[i].dy = subsampling_dy;
- cmptparm[i].w = w;
- cmptparm[i].h = h;
+ c = getc(reader);
+ if(c == EOF) break;
+
+ if(c) /* encoded mode */
+ {
+ c1 = getc(reader);
+
+ for(i = 0; i < c && x < width && dst < beyond; i++, x++, dst++)
+ *dst = (unsigned char)c1;
}
- /* create the image */
- image = opj_image_create(numcomps, &cmptparm[0], color_space);
- if(!image)
+ else /* absolute mode */
{
- fclose(IN);
- return NULL;
+ c = getc(reader);
+ if(c == EOF) break;
+
+ if(c == 0x00) /* EOL */
+ {
+ x = 0; y++; dst = dst_buf + x + (height - y - 1) * width;
+ }
+ else
+ if(c == 0x01) /* EOP */
+ break;
+ else
+ if(c == 0x02) /* MOVE by dxdy */
+ {
+ c = getc(reader); x += c;
+ c = getc(reader); y += c;
+ dst = dst_buf + x + (height - y - 1) * width;
+ }
+ else
+ {
+ i = 0;
+ for(; i < c && x < width && dst < beyond; i++, x++, dst++)
+ {
+ c1 = getc(reader);
+ *dst = (unsigned char)c1;
+ }
+ if(c & 1) /* skip padding byte */
+ getc(reader);
+ }
}
+ } /* while */
+}/* RLE8_decoder() */
+
+static void decode_RLE8_image(FILE *reader,
+ struct bmp_cmap bmap[256],
+ unsigned int width, unsigned int height, int has_alpha,
+ int *red, int *green, int *blue, int *alpha)
+{
+ unsigned char *src_buf, *src;
+ unsigned int i, max;
+ unsigned char uc;
+
+ max = width * height;
+ src_buf = (unsigned char*)calloc(1, max);
+
+ RLE8_decoder(reader, width, height, src_buf);
+
+ src = src_buf;
+
+ for(i = 0; i < max; ++i)
+ {
+ uc = *src++;
+
+ red[i] = (unsigned char)bmap[uc].red;
+ green[i] = (unsigned char)bmap[uc].green;
+ blue[i] = (unsigned char)bmap[uc].blue;
+
+ if(has_alpha) alpha[i] = (unsigned char)bmap[uc].alpha;
+ }
+ free(src_buf);
+}/* decode_RLE8_image() */
+
+static void find_mask_bits(unsigned int mask, int* out_shifts, int* out_bits)
+{
+ int i, shifts, bits;
+
+ shifts = bits = 0;
+
+ for(i = 31; i >= 0; --i)
+ {
+ if(mask & (1 << i)) { shifts = i; ++bits; }
+ }
+ *out_shifts = shifts; *out_bits = bits;
+}
+
+static void decode_colormask(unsigned int hdr_size, unsigned short bit_cnt)
+{
+ unsigned char *buf;
+
+ ALPHA_mask = 0; ALPHA_shift = ALPHA_bits = 0;
+
+ buf = (unsigned char*)&colormask[0];
+
+ RED_mask =
+ buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+
+ buf = (unsigned char*)&colormask[1];
- /* set image offset and reference grid */
- image->x0 = parameters->image_offset_x0;
- image->y0 = parameters->image_offset_y0;
- image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
- image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
-
- /* set image data */
-
- /* Place the cursor at the beginning of the image information */
- fseek(IN, 0, SEEK_SET);
- fseek(IN, File_h.bfOffBits, SEEK_SET);
-
- W = Info_h.biWidth;
- H = Info_h.biHeight;
-
- /* PAD = 4 - (3 * W) % 4; */
- /* PAD = (PAD == 4) ? 0 : PAD; */
- PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0;
-
- RGB = (unsigned char *)
- malloc((3 * W + PAD) * H * sizeof(unsigned char));
-
- if ( fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN) != (3 * W + PAD) * H )
- {
- free(RGB);
- opj_image_destroy(image);
- fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
- return NULL;
- }
-
- index = 0;
+ GREEN_mask =
+ buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
- for(y = 0; y < (int)H; y++)
+ buf = (unsigned char*)&colormask[2];
+
+ BLUE_mask =
+ buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+
+ find_mask_bits(RED_mask, &RED_shift, &RED_bits);
+ find_mask_bits(GREEN_mask, &GREEN_shift, &GREEN_bits);
+ find_mask_bits(BLUE_mask, &BLUE_shift, &BLUE_bits);
+
+/* v4 and v5 have an alpha mask */
+ if(hdr_size == 108
+ || hdr_size == 124)
+ {
+ buf = (unsigned char*)&colormask[3];
+
+ ALPHA_mask =
+ buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+
+ find_mask_bits(ALPHA_mask, &ALPHA_shift, &ALPHA_bits);
+ }
+
+ if(RED_bits == 0
+ || GREEN_bits == 0
+ || BLUE_bits == 0)
+ {
+ if(bit_cnt == 16)
{
- unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y);
- for(x = 0; x < (int)W; x++)
- {
- unsigned char *pixel = &scanline[3 * x];
- image->comps[0].data[index] = pixel[2]; /* R */
- image->comps[1].data[index] = pixel[1]; /* G */
- image->comps[2].data[index] = pixel[0]; /* B */
- index++;
- }
+ RED_mask = 0x7c00;
+ RED_shift = 10;
+
+ GREEN_mask = 0x03e0;
+ GREEN_shift = 5;
+
+ BLUE_mask = 0x001f;
+ BLUE_shift = 0;
+
+ RED_bits = GREEN_bits = BLUE_bits = 5;
}
- free(RGB);
- }/* if (Info_h.biBitCount == 24) */
else
- if (Info_h.biBitCount == 8 && Info_h.biCompression == 0)/*RGB */
+ {
+ RED_mask = 0x00ff0000;
+ RED_shift = 16;
+
+ GREEN_mask = 0x0000ff00;
+ GREEN_shift = 8;
+
+ BLUE_mask = 0x000000ff;
+ BLUE_shift = 0;
+
+ ALPHA_mask = 0xff000000;
+ ALPHA_shift = 24;
+
+ RED_bits = GREEN_bits = BLUE_bits = ALPHA_bits = 8;
+ }
+ }
+
+ if(RED_bits > 8)
+ {
+ RED_shift += RED_bits - 8;
+ RED_bits = 8;
+ }
+ if(GREEN_bits > 8)
+ {
+ GREEN_shift += GREEN_bits - 8;
+ GREEN_bits = 8;
+ }
+ if(BLUE_bits > 8)
+ {
+ BLUE_shift += BLUE_bits - 8;
+ BLUE_bits = 8;
+ }
+ if(ALPHA_bits > 8)
+ {
+ ALPHA_shift += ALPHA_bits - 8;
+ ALPHA_bits = 8;
+ }
+}
+
+static void decode_BITFIELDS32_image(FILE *reader,
+ unsigned int width, unsigned int height,
+ int has_alpha, int *red, int *green, int *blue, int *alpha)
+{
+ unsigned char *dst_buf, *dst, *row_start;
+ unsigned char src[4];
+ unsigned int i, max;
+ int x, y, ww, hh, row_size;
+ int r_lshift, r_rshift;
+ int g_lshift, g_rshift;
+ int b_lshift, b_rshift;
+ int a_lshift, a_rshift;
+
+ ww = (int)width; hh = (int)height;
+ row_size = (int)(width * (3 + has_alpha));
+ dst_buf = (unsigned char*)calloc(height, width * (3 + has_alpha));
+
+ if(hh > 0)
{
- if(Info_h.biClrUsed == 0) Info_h.biClrUsed = 256;
+ row_start = dst_buf + (hh - 1) * row_size;
+ row_size = -row_size;
+ }
else
- if(Info_h.biClrUsed > 256) Info_h.biClrUsed = 256;
+ {
+ hh = -height;
+ row_start = dst_buf;
+ }
- table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
- table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
- table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
-
- has_color = 0;
- for (j = 0; j < Info_h.biClrUsed; j++)
- {
- table_B[j] = (unsigned char)getc(IN);
- table_G[j] = (unsigned char)getc(IN);
- table_R[j] = (unsigned char)getc(IN);
- getc(IN);
- has_color +=
- !(table_R[j] == table_G[j] && table_R[j] == table_B[j]);
- }
- if(has_color) gray_scale = 0;
-
- /* Place the cursor at the beginning of the image information */
- fseek(IN, 0, SEEK_SET);
- fseek(IN, File_h.bfOffBits, SEEK_SET);
-
- W = Info_h.biWidth;
- H = Info_h.biHeight;
- if (Info_h.biWidth % 2)
- W++;
-
- numcomps = gray_scale ? 1 : 3;
- color_space = gray_scale ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB;
- /* initialize image components */
- memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
- for(i = 0; i < numcomps; i++)
- {
- cmptparm[i].prec = 8;
- cmptparm[i].bpp = 8;
- cmptparm[i].sgnd = 0;
- cmptparm[i].dx = subsampling_dx;
- cmptparm[i].dy = subsampling_dy;
- cmptparm[i].w = w;
- cmptparm[i].h = h;
- }
- /* create the image */
- image = opj_image_create(numcomps, &cmptparm[0], color_space);
- if(!image)
+ r_lshift = 8 - RED_bits;
+ g_lshift = 8 - GREEN_bits;
+ b_lshift = 8 - BLUE_bits;
+ a_lshift = 8 - ALPHA_bits;
+
+ r_rshift = RED_bits - r_lshift;
+ g_rshift = GREEN_bits - g_lshift;
+ b_rshift = BLUE_bits - b_lshift;
+
+ if(has_alpha)
+ a_rshift = ALPHA_bits - a_lshift;
+
+ for(y = 0; y < hh; ++y)
+ {
+ dst = row_start;
+
+ for(x = 0; x < ww; ++x)
{
- fclose(IN);
- free(table_R); free(table_G); free(table_B);
- return NULL;
+ unsigned int v, r, g, b, a;
+
+ fread(src, 1, 4, reader);
+
+ v = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+
+ r = (v & RED_mask) >> RED_shift;
+ g = (v & GREEN_mask) >> GREEN_shift;
+ b = (v & BLUE_mask) >> BLUE_shift;
+
+ *dst++ = (unsigned char)((r << r_lshift) | (r >> r_rshift));
+ *dst++ = (unsigned char)((g << g_lshift) | (g >> g_rshift));
+ *dst++ = (unsigned char)((b << b_lshift) | (b >> b_rshift));
+
+ if(has_alpha)
+ {
+ a = (v & ALPHA_mask) >> ALPHA_shift;
+ *dst++ = (unsigned char)((a << a_lshift) | (a >> a_rshift));
+ }
}
+ row_start += row_size;
+ }
+ dst = dst_buf;
+ max = width * height;
+
+ for(i = 0; i < max; ++i)
+ {
+ red[i] = *dst++; green[i] = *dst++; blue[i] = *dst++;
- /* set image offset and reference grid */
- image->x0 = parameters->image_offset_x0;
- image->y0 = parameters->image_offset_y0;
- image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
- image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
-
- /* set image data */
-
- RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char));
-
- if ( fread(RGB, sizeof(unsigned char), W * H, IN) != W * H )
- {
- free(table_R);
- free(table_G);
- free(table_B);
- free(RGB);
- opj_image_destroy(image);
- fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
- return NULL;
- }
- if (gray_scale)
+ if(has_alpha) alpha[i] = *dst++;
+ }
+ free(dst_buf);
+
+}/* decode_BITFIELDS32_image() */
+
+static void decode_image_16(FILE *reader,
+ unsigned int width, unsigned int height,
+ unsigned int encoding,
+ int *red, int *green, int *blue)
+{
+ unsigned char *dst, *dst_buf, *row_start;
+ int x, y, ww, hh, row_size, padded;
+ unsigned int i, max;
+ unsigned char src[2];
+
+ dst_buf = (unsigned char*)calloc(height, width * 3);
+
+ ww = (int)width; hh = (int)height;
+
+ if((padded = (width * 2 + 3) - ((width * 2 + 3) & ~3)) > 1)
+ padded = 0;
+
+ row_size = width * 3;
+
+ if(hh > 0)
+ {
+ row_start = dst_buf + (hh - 1) * row_size;
+ row_size = -row_size;
+ }
+ else
+ {
+ hh = -hh;
+ row_start = dst_buf;
+ }
+
+ if(encoding == ENC_BITFIELDS)
+ {
+ int r_lshift, r_rshift;
+ int g_lshift, g_rshift;
+ int b_lshift, b_rshift;
+
+ r_lshift = 8 - RED_bits;
+ g_lshift = 8 - GREEN_bits;
+ b_lshift = 8 - BLUE_bits;
+
+ r_rshift = RED_bits - r_lshift;
+ g_rshift = GREEN_bits - g_lshift;
+ b_rshift = BLUE_bits - b_lshift;
+
+ for(y = 0; y < hh; ++y)
{
- index = 0;
- for (j = 0; j < W * H; j++)
+ dst = row_start;
+
+ for(x = 0; x < ww; x++)
{
- if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2))
- {
- image->comps[0].data[index] =
- table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]];
- index++;
- }
- }
+ int v, r, g, b;
+ fread(src, 1, 2, reader);
+
+ v = (int) src[0] | ((int) src[1] << 8);
+
+ r = (v & RED_mask) >> RED_shift;
+ g = (v & GREEN_mask) >> GREEN_shift;
+ b = (v & BLUE_mask) >> BLUE_shift;
+
+ *dst++ = (unsigned char)((r << r_lshift) | (r >> r_rshift));
+ *dst++ = (unsigned char)((g << g_lshift) | (g >> g_rshift));
+ *dst++ = (unsigned char)((b << b_lshift) | (b >> b_rshift));
+ }
+ if(padded) fread(src, 1, 2, reader);
+ row_start += row_size;
}
- else
+ }//ENC_BITFIELDS
+ else
+ {
+ for(y = 0; y < hh; ++y)
{
- index = 0;
- for (j = 0; j < W * H; j++)
+ dst = row_start;
+
+ for(x = 0; x < ww; x++)
{
- if ((j % W < W - 1 && Info_h.biWidth % 2)
- || !(Info_h.biWidth % 2))
- {
- unsigned char pixel_index =
- RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)];
- image->comps[0].data[index] = table_R[pixel_index];
- image->comps[1].data[index] = table_G[pixel_index];
- image->comps[2].data[index] = table_B[pixel_index];
- index++;
- }
+ int v, r, g, b;
+
+ fread(src, 1, 2, reader);
+
+ v = src[0] | (src[1] << 8);
+
+ r = (v >> 10) & 0x1f;
+ g = (v >> 5) & 0x1f;
+ b = v & 0x1f;
+
+ *dst++ = (unsigned char)((r << 3) | (r >> 2));
+ *dst++ = (unsigned char)((g << 3) | (g >> 2));
+ *dst++ = (unsigned char)((b << 3) | (b >> 2));
}
+ if(padded) fread(src, 1, 2, reader);
+ row_start += row_size;
}
- free(RGB);
- free(table_R);
- free(table_G);
- free(table_B);
- }/* RGB8 */
- else
- if (Info_h.biBitCount == 8 && Info_h.biCompression == 1)/*RLE8*/
- {
- unsigned char *pix, *beyond;
- int *gray, *red, *green, *blue;
- unsigned int x, y, max;
- int i, c, c1;
- unsigned char uc;
-
- if (Info_h.biClrUsed == 0)
- Info_h.biClrUsed = 256;
- else if (Info_h.biClrUsed > 256)
- Info_h.biClrUsed = 256;
-
- table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
- table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
- table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
-
- has_color = 0;
- for (j = 0; j < Info_h.biClrUsed; j++)
- {
- table_B[j] = (unsigned char)getc(IN);
- table_G[j] = (unsigned char)getc(IN);
- table_R[j] = (unsigned char)getc(IN);
- getc(IN);
- has_color += !(table_R[j] == table_G[j] && table_R[j] == table_B[j]);
- }
-
- if (has_color)
- gray_scale = 0;
-
- numcomps = gray_scale ? 1 : 3;
- color_space = gray_scale ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB;
- /* initialize image components */
- memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
- for (i = 0; i < numcomps; i++)
- {
- cmptparm[i].prec = 8;
- cmptparm[i].bpp = 8;
- cmptparm[i].sgnd = 0;
- cmptparm[i].dx = subsampling_dx;
- cmptparm[i].dy = subsampling_dy;
- cmptparm[i].w = w;
- cmptparm[i].h = h;
- }
- /* create the image */
- image = opj_image_create(numcomps, &cmptparm[0], color_space);
- if (!image)
- {
- fclose(IN);
- free(table_R);
- free(table_G);
- free(table_B);
- return NULL;
- }
-
- /* set image offset and reference grid */
- image->x0 = parameters->image_offset_x0;
- image->y0 = parameters->image_offset_y0;
- image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w
- - 1) * subsampling_dx + 1;
- image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h
- - 1) * subsampling_dy + 1;
-
- /* set image data */
-
- /* Place the cursor at the beginning of the image information */
- fseek(IN, 0, SEEK_SET);
- fseek(IN, File_h.bfOffBits, SEEK_SET);
-
- W = Info_h.biWidth;
- H = Info_h.biHeight;
- RGB = (unsigned char *) calloc(1, W * H * sizeof(unsigned char));
- beyond = RGB + W * H;
- pix = beyond - W;
- x = y = 0;
-
- while (y < H)
- {
- c = getc(IN);
-
- if (c)
- {
- c1 = getc(IN);
-
- for (i = 0; i < c && x < W && pix < beyond; i++, x++, pix++)
- *pix = (unsigned char)c1;
- }
- else
- {
- c = getc(IN);
-
- if (c == 0x00) /* EOL */
- {
- x = 0;
- ++y;
- pix = RGB + x + (H - y - 1) * W;
- }
- else if (c == 0x01) /* EOP */
- break;
- else if (c == 0x02) /* MOVE by dxdy */
- {
- c = getc(IN);
- x += c;
- c = getc(IN);
- y += c;
- pix = RGB + (H - y - 1) * W + x;
- }
- else /* 03 .. 255 */
- {
- i = 0;
- for (; i < c && x < W && pix < beyond; i++, x++, pix++)
- {
- c1 = getc(IN);
- *pix = (unsigned char)c1;
- }
- if (c & 1) /* skip padding byte */
- getc(IN);
- }
- }
- }/* while() */
-
- if (gray_scale)
- {
- gray = image->comps[0].data;
- pix = RGB;
- max = W * H;
-
- while (max--)
- {
- uc = *pix++;
-
- *gray++ = table_R[uc];
- }
- }
- else
- {
- /*int *red, *green, *blue;*/
-
- red = image->comps[0].data;
- green = image->comps[1].data;
- blue = image->comps[2].data;
- pix = RGB;
- max = W * H;
-
- while (max--)
- {
- uc = *pix++;
-
- *red++ = table_R[uc];
- *green++ = table_G[uc];
- *blue++ = table_B[uc];
- }
- }
- free(RGB);
- free(table_R);
- free(table_G);
- free(table_B);
- }/* RLE8 */
- else
+ }
+ dst = dst_buf;
+ max = width * height;
+
+ for(i = 0; i < max; ++i)
+ {
+ red[i] = *dst++; green[i] = *dst++; blue[i] = *dst++;
+ }
+ free(dst_buf);
+
+}/* decode_image_16() */
+
+/*
+ * NOTE: v4 and v5 may have alpha values
+*/
+opj_image_t* bmptoimage(const char *fname, opj_cparameters_t *parameters)
+{
+ int *red, *green, *blue, *alpha;
+ FILE *reader;
+ opj_image_t * image;
+ unsigned int i, encoding, width, height;
+ int j, numcomps, has_alpha;
+ unsigned short type;
+ OPJ_COLOR_SPACE color_space;
+ BmpInfo hdr;
+ Bmp12Info hdr12;
+ SizeInfo hdrsize;
+ struct bmp_cmap cmap[256];
+ fpos_t pos;
+ opj_image_cmptparm_t cmptparm[4];
+ int subsampling_dx = parameters->subsampling_dx;
+ int subsampling_dy = parameters->subsampling_dy;
+
+ image = NULL;
+
+ reader = fopen(fname, "rb");
+ if(reader == NULL)
+ {
+ fprintf(stderr, "bmptoimage: failed to open\n%s\nfor reading\n", fname);
+ return NULL;
+ }
+ type = (unsigned char)getc(reader);
+ type = ((unsigned char)getc(reader)<<8) + type;
+
+ if(type != 19778)/* BM */
+ {
+ fprintf(stderr,"bmptopimage:\n%s\nis not a BMP file\n",fname);
+ goto fin;
+ }
+/* type(2) + filesize(4) + reserved1(2) + reserved2(2) ==> 10
+*/
+ fseek(reader,10,SEEK_SET);
+ fgetpos(reader, &pos);
+
+ fread(&hdrsize, sizeof(SizeInfo), 1, reader);
+#if WORDS_BIGENDIAN == 1
+ hdrsize.offset = swap32(hdrsize.offset);
+ hdrsize.hdr_size = swap32(hdrsize.hdr_size);
+#endif
+ fsetpos(reader, &pos);
+
+ memset(&hdr, 0, sizeof(BmpInfo));
+ encoding = 0;
+
+ if(hdrsize.hdr_size == 12)
+ {
+ fread(&hdr12, sizeof(Bmp12Info), 1, reader);
+#if WORDS_BIGENDIAN == 1
+ hdr12.offset = swap32(hdr12.offset);
+ hdr12.hdr_size = swap32(hdr12.hdr_size);
+ hdr12.width = swap16(hdr12.width);
+ hdr12.height = swap16(hdr12.height);
+ hdr12.planes = swap16(hdr12.planes);
+ hdr12.bit_cnt = swap16(hdr12.bit_cnt);
+#endif
+ hdr.offset = hdr12.offset;
+ hdr.hdr_size = hdr12.hdr_size;
+ hdr.width = (int)hdr12.width;
+ hdr.height = (int)hdr12.height;
+ hdr.planes = hdr12.planes;
+ hdr.bit_cnt = hdr12.bit_cnt;
+ hdr.num_colors = (1<<hdr12.bit_cnt);
+ }
+ else
+ {
+ fread(&hdr,sizeof(BmpInfo),1,reader);
+#if WORDS_BIGENDIAN == 1
+ hdr.offset = swap32(hdr.offset);
+ hdr.hdr_size = swap32(hdr.hdr_size);
+ hdr.width = swap32(hdr.width);
+ hdr.height = swap32(hdr.height);
+
+ hdr.planes = swap16(hdr.planes);
+ hdr.bit_cnt = swap16(hdr.bit_cnt);
+
+ hdr.image_size = swap32(hdr.image_size);
+ hdr.xpels_meter = swap32(hdr.xpels_meter);
+ hdr.ypels_meter = swap32(hdr.ypels_meter);
+ hdr.num_colors = swap32(hdr.num_colors);
+ hdr.important_colors = swap32(hdr.important_colors);
+#endif
+ encoding = hdr.compression[0] | (hdr.compression[1]<<8)
+ | (hdr.compression[2]<<16) | (hdr.compression[3]<<24);
+
+ if(encoding > ENC_PNG) encoding = ENC_PNG + 1;
+
+ i = hdrsize.hdr_size - 40;
+ while(i > 0)
+ {
+ fgetc(reader); --i;
+ }
+ }
+
+ if(hdr.bit_cnt != 1 && hdr.bit_cnt != 4 && hdr.bit_cnt != 8
+ && hdr.bit_cnt != 16 && hdr.bit_cnt != 24 && hdr.bit_cnt != 32)
{
- fprintf(stderr,
- "Other system than 24 bits/pixels or 8 bits (no RLE coding) "
- "is not yet implemented [%d]\n", Info_h.biBitCount);
+ fprintf(stderr,"bmptoimage: can not handle depth %d\n",hdr.bit_cnt);
+ goto fin;
+ }
+ if(encoding > ENC_BITFIELDS)
+ {
+ fprintf(stderr,"bmptoimage: can not handle compressed bitmaps %s\n",
+ enc_type[encoding]);
+ goto fin;
+ }
+ has_alpha = 0;
+
+ if(encoding == ENC_BITFIELDS)
+ {
+ int n;
+
+ n = 12;//RGB
+ if(hdr.hdr_size == 108 || hdr.hdr_size == 124)//v4 or v5: RGBA
+ n = 16;
+
+ memset(colormask, 0, 4*sizeof(unsigned int));
+ fread(colormask, 1, n, reader);
+
+/* mask[0] != mask[1] != mask[2] != mask[3]:
+*/
+ if(colormask[0] == colormask[1])
+ encoding = ENC_RGB;
+ else // test for overlap
+ if((colormask[0] & colormask[1])
+ || (colormask[0] & colormask[2])
+ || (colormask[0] & colormask[3])
+ || (colormask[1] & colormask[2])
+ || (colormask[1] & colormask[3])
+ || (colormask[2] & colormask[3])
+ )
+ encoding = ENC_RGB;
+ else
+ decode_colormask(hdr.hdr_size, hdr.bit_cnt);
}
- fclose(IN);
+
+ if(hdr.num_colors == 0
+ && hdr.bit_cnt <= 8)
+ hdr.num_colors = (1 << hdr.bit_cnt);
+
+ if(hdr.num_colors > 256)
+ hdr.num_colors = 256;
+
+ if(hdr.num_colors)
+ {
+ unsigned int max;
+ unsigned char r, g, b, a;
+
+ has_alpha = (hdr.hdr_size == 40);
+
+ max = hdr.num_colors; a = 255;/* OPAQUE */
+
+ fseek(reader, 14+hdr.hdr_size, SEEK_SET);
+ memset(&cmap, 0, sizeof(struct bmp_cmap) * 256);
+
+ for(i = 0; i < max; ++i)
+ {
+ cmap[i].blue = (unsigned char)fgetc(reader);
+ cmap[i].green = (unsigned char)fgetc(reader);
+ cmap[i].red = (unsigned char)fgetc(reader);
+
+ if(has_alpha) cmap[i].alpha = (unsigned char)fgetc(reader);
+ }
+ has_alpha = 0;
+ }
+ else
+ has_alpha = (ALPHA_bits != 0);
+
+/*---------------------------------------------------------*/
+ width = hdr.width; height = hdr.height;
+ numcomps = 3 + has_alpha;
+ color_space = OPJ_CLRSPC_SRGB;
+ memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
+
+ for(j = 0; j < numcomps; ++j)
+ {
+ cmptparm[j].prec = 8;
+ cmptparm[j].bpp = 8;
+ cmptparm[j].sgnd = 0;
+ cmptparm[j].dx = subsampling_dx;
+ cmptparm[j].dy = subsampling_dy;
+ cmptparm[j].w = width;
+ cmptparm[j].h = height;
+ }
+ image = opj_image_create(numcomps, &cmptparm[0], color_space);
+
+ if(image == NULL)
+ {
+ fprintf(stderr,"bmptopimage: failed to get an image.\n");
+ goto fin;
+ }
+
+ image->x0 = parameters->image_offset_x0;
+ image->y0 = parameters->image_offset_y0;
+
+ image->x1 = !image->x0 ? (width - 1) * subsampling_dx + 1 :
+ image->x0 + (width - 1) * subsampling_dx + 1;
+ image->y1 = !image->y0 ? (height - 1) * subsampling_dy + 1 :
+ image->y0 + (height - 1) * subsampling_dy + 1;
+
+
+ red = image->comps[0].data;
+ green = image->comps[1].data;
+ blue = image->comps[2].data;
+
+ if(has_alpha) alpha = image->comps[3].data; else alpha = NULL;
+/*---------------------------------------------------------*/
+ if(hdr.bit_cnt == 4 && encoding == ENC_RLE4)
+ {
+ decode_RLE4_image(reader, cmap, width, height, has_alpha,
+ red, green, blue, alpha);
+ }
+ else
+ if(hdr.bit_cnt == 8 && encoding == ENC_RLE8)
+ {
+ decode_RLE8_image(reader, cmap, width, height, has_alpha,
+ red, green, blue, alpha);
+ }
+ else
+ if(hdr.bit_cnt == 16)
+ {
+ decode_image_16(reader, width, height, encoding,
+ red, green, blue);
+ }
+ else
+ if(hdr.bit_cnt == 32 && encoding == ENC_BITFIELDS)
+ {
+ decode_BITFIELDS32_image(reader, width, height, has_alpha,
+ red, green, blue, alpha);
+ }
+ else
+ for(i = 0; i < height; ++i)
+ {
+ BMP_read(i, &hdr, cmap, reader, encoding, red, green, blue);
+
+ red += width; green += width; blue += width;
+ }
+ fin:
+ fclose(reader);
return image;
-}
+
+}/* bmptoimage() */
int imagetobmp(opj_image_t * image, const char *outfile) {
int w, h;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment