Created
March 8, 2013 20:30
-
-
Save eikeon/5119599 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- 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