[trunk] updated BMP format input support
Update issue 203
This commit is contained in:
parent
f7ff08de5a
commit
33a0e66eb1
|
@ -65,6 +65,19 @@ typedef struct {
|
||||||
OPJ_UINT32 biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */
|
OPJ_UINT32 biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */
|
||||||
OPJ_UINT32 biClrUsed; /* Number of color used in the image (0: ALL) */
|
OPJ_UINT32 biClrUsed; /* Number of color used in the image (0: ALL) */
|
||||||
OPJ_UINT32 biClrImportant; /* Number of important color (0: ALL) */
|
OPJ_UINT32 biClrImportant; /* Number of important color (0: ALL) */
|
||||||
|
OPJ_UINT32 biRedMask; /* Red channel bit mask */
|
||||||
|
OPJ_UINT32 biGreenMask; /* Green channel bit mask */
|
||||||
|
OPJ_UINT32 biBlueMask; /* Blue channel bit mask */
|
||||||
|
OPJ_UINT32 biAlphaMask; /* Alpha channel bit mask */
|
||||||
|
OPJ_UINT32 biColorSpaceType; /* Color space type */
|
||||||
|
OPJ_UINT8 biColorSpaceEP[36]; /* Color space end points */
|
||||||
|
OPJ_UINT32 biRedGamma; /* Red channel gamma */
|
||||||
|
OPJ_UINT32 biGreenGamma; /* Green channel gamma */
|
||||||
|
OPJ_UINT32 biBlueGamma; /* Blue channel gamma */
|
||||||
|
OPJ_UINT32 biIntent; /* Intent */
|
||||||
|
OPJ_UINT32 biIccProfileData; /* ICC profile data */
|
||||||
|
OPJ_UINT32 biIccProfileSize; /* ICC profile size */
|
||||||
|
OPJ_UINT32 biReserved; /* Reserved */
|
||||||
} OPJ_BITMAPINFOHEADER;
|
} OPJ_BITMAPINFOHEADER;
|
||||||
|
|
||||||
static void opj_applyLUT8u_8u32s_C1R(
|
static void opj_applyLUT8u_8u32s_C1R(
|
||||||
|
@ -118,65 +131,15 @@ static void opj_applyLUT8u_8u32s_C1P3R(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static opj_image_t* bmp24toimage(FILE *IN, const OPJ_BITMAPFILEHEADER* File_h, const OPJ_BITMAPINFOHEADER* Info_h, const opj_cparameters_t *parameters)
|
static void bmp24toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image)
|
||||||
{
|
{
|
||||||
opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
|
int index;
|
||||||
opj_image_t * image = NULL;
|
OPJ_UINT32 width, height;
|
||||||
int i, index;
|
|
||||||
OPJ_UINT32 width, height, stride;
|
|
||||||
OPJ_UINT32 x, y;
|
OPJ_UINT32 x, y;
|
||||||
OPJ_UINT8 *pData = NULL;
|
|
||||||
const OPJ_UINT8 *pSrc = NULL;
|
const OPJ_UINT8 *pSrc = NULL;
|
||||||
|
|
||||||
width = Info_h->biWidth;
|
width = image->comps[0].w;
|
||||||
height = Info_h->biHeight;
|
height = image->comps[0].h;
|
||||||
|
|
||||||
/* initialize image components */
|
|
||||||
memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
|
|
||||||
for(i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
cmptparm[i].prec = 8;
|
|
||||||
cmptparm[i].bpp = 8;
|
|
||||||
cmptparm[i].sgnd = 0;
|
|
||||||
cmptparm[i].dx = (OPJ_UINT32)parameters->subsampling_dx;
|
|
||||||
cmptparm[i].dy = (OPJ_UINT32)parameters->subsampling_dy;
|
|
||||||
cmptparm[i].w = (OPJ_UINT32)width;
|
|
||||||
cmptparm[i].h = (OPJ_UINT32)height;
|
|
||||||
}
|
|
||||||
/* create the image */
|
|
||||||
image = opj_image_create(3U, &cmptparm[0], OPJ_CLRSPC_SRGB);
|
|
||||||
if(!image)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set image offset and reference grid */
|
|
||||||
image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
|
|
||||||
image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
|
|
||||||
image->x1 = image->x0 + (OPJ_UINT32)(width - 1U) * (OPJ_UINT32)parameters->subsampling_dx + 1U;
|
|
||||||
image->y1 = image->y0 + (OPJ_UINT32)(height - 1U) * (OPJ_UINT32)parameters->subsampling_dy + 1U;
|
|
||||||
|
|
||||||
/* set image data */
|
|
||||||
|
|
||||||
/* Place the cursor at the beginning of the image information */
|
|
||||||
fseek(IN, 0, SEEK_SET);
|
|
||||||
fseek(IN, (long)File_h->bfOffBits, SEEK_SET);
|
|
||||||
|
|
||||||
stride = width * 3U;
|
|
||||||
/* line is 32 bits aligned */
|
|
||||||
if (stride & 3U) {
|
|
||||||
stride += 4U - (stride & 3U);
|
|
||||||
}
|
|
||||||
|
|
||||||
pData = (OPJ_UINT8 *)malloc(stride * height * sizeof(OPJ_UINT8));
|
|
||||||
|
|
||||||
if ( fread(pData, sizeof(OPJ_UINT8), stride * height, IN) != (stride * height) )
|
|
||||||
{
|
|
||||||
free(pData);
|
|
||||||
opj_image_destroy(image);
|
|
||||||
fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
pSrc = pData + (height - 1U) * stride;
|
pSrc = pData + (height - 1U) * stride;
|
||||||
|
@ -191,188 +154,351 @@ static opj_image_t* bmp24toimage(FILE *IN, const OPJ_BITMAPFILEHEADER* File_h, c
|
||||||
}
|
}
|
||||||
pSrc -= stride;
|
pSrc -= stride;
|
||||||
}
|
}
|
||||||
free(pData);
|
|
||||||
return image;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static opj_image_t* bmp8toimage(FILE *IN, const OPJ_BITMAPFILEHEADER* File_h, const OPJ_BITMAPINFOHEADER* Info_h, const opj_cparameters_t *parameters)
|
static void bmp_mask_get_shift_and_prec(OPJ_UINT32 mask, OPJ_UINT32* shift, OPJ_UINT32* prec)
|
||||||
{
|
{
|
||||||
OPJ_UINT8 lut_R[256], lut_G[256], lut_B[256];
|
OPJ_UINT32 l_shift, l_prec;
|
||||||
opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
|
|
||||||
opj_image_t * image = NULL;
|
l_shift = l_prec = 0U;
|
||||||
OPJ_SIZE_T index;
|
|
||||||
OPJ_UINT32 i, palette_len;
|
if (mask != 0U) {
|
||||||
OPJ_UINT32 width, height, stride;
|
while ((mask & 1U) == 0U) {
|
||||||
OPJ_UINT8 *pData = NULL;
|
mask >>= 1;
|
||||||
|
l_shift++;
|
||||||
|
}
|
||||||
|
while (mask & 1U) {
|
||||||
|
mask >>= 1;
|
||||||
|
l_prec++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*shift = l_shift; *prec = l_prec;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
OPJ_UINT32 width, height;
|
||||||
|
OPJ_UINT32 x, y;
|
||||||
const OPJ_UINT8 *pSrc = NULL;
|
const OPJ_UINT8 *pSrc = NULL;
|
||||||
OPJ_UINT32 numcmpts = 1U; /* grayscale by default */
|
OPJ_BOOL hasAlpha = OPJ_FALSE;
|
||||||
|
OPJ_UINT32 redShift, redPrec;
|
||||||
|
OPJ_UINT32 greenShift, greenPrec;
|
||||||
|
OPJ_UINT32 blueShift, bluePrec;
|
||||||
|
OPJ_UINT32 alphaShift, alphaPrec;
|
||||||
|
|
||||||
width = Info_h->biWidth;
|
width = image->comps[0].w;
|
||||||
height = Info_h->biHeight;
|
height = image->comps[0].h;
|
||||||
|
|
||||||
/* initialize */
|
hasAlpha = image->numcomps > 3U;
|
||||||
memset(&cmptparm[0], 0, sizeof(cmptparm));
|
|
||||||
memset(&lut_R[0], 0, sizeof(lut_R));
|
|
||||||
memset(&lut_G[0], 0, sizeof(lut_G));
|
|
||||||
memset(&lut_B[0], 0, sizeof(lut_B));
|
|
||||||
|
|
||||||
palette_len = Info_h->biClrUsed;
|
bmp_mask_get_shift_and_prec(redMask, &redShift, &redPrec);
|
||||||
if ((palette_len == 0U) || (palette_len > 256U)) {
|
bmp_mask_get_shift_and_prec(greenMask, &greenShift, &greenPrec);
|
||||||
palette_len = 256U;
|
bmp_mask_get_shift_and_prec(blueMask, &blueShift, &bluePrec);
|
||||||
}
|
bmp_mask_get_shift_and_prec(alphaMask, &alphaShift, &alphaPrec);
|
||||||
|
|
||||||
/* Load palette */
|
image->comps[0].bpp = redPrec;
|
||||||
{
|
image->comps[0].prec = redPrec;
|
||||||
OPJ_UINT8 has_color = 0U;
|
image->comps[1].bpp = greenPrec;
|
||||||
for (i = 0; i < palette_len; i++) {
|
image->comps[1].prec = greenPrec;
|
||||||
lut_B[i] = (OPJ_UINT8)getc(IN);
|
image->comps[2].bpp = bluePrec;
|
||||||
lut_G[i] = (OPJ_UINT8)getc(IN);
|
image->comps[2].prec = bluePrec;
|
||||||
lut_R[i] = (OPJ_UINT8)getc(IN);
|
if (hasAlpha) {
|
||||||
getc(IN); /* padding */
|
image->comps[3].bpp = alphaPrec;
|
||||||
has_color |= lut_B[i] ^ (lut_G[i] | lut_R[i]);
|
image->comps[3].prec = alphaPrec;
|
||||||
}
|
|
||||||
if(has_color) {
|
|
||||||
numcmpts = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for(i = 0; i < numcmpts; i++)
|
|
||||||
{
|
|
||||||
cmptparm[i].prec = 8;
|
|
||||||
cmptparm[i].bpp = 8;
|
|
||||||
cmptparm[i].sgnd = 0;
|
|
||||||
cmptparm[i].dx = (OPJ_UINT32)parameters->subsampling_dx;
|
|
||||||
cmptparm[i].dy = (OPJ_UINT32)parameters->subsampling_dy;
|
|
||||||
cmptparm[i].w = width;
|
|
||||||
cmptparm[i].h = height;
|
|
||||||
}
|
|
||||||
/* create the image */
|
|
||||||
image = opj_image_create(numcmpts, &cmptparm[0], (numcmpts == 1U) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB);
|
|
||||||
if(!image)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set image offset and reference grid */
|
|
||||||
image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
|
|
||||||
image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
|
|
||||||
image->x1 = image->x0 + (width - 1U) * (OPJ_UINT32)parameters->subsampling_dx + 1U;
|
|
||||||
image->y1 = image->y0 + (height - 1U) * (OPJ_UINT32)parameters->subsampling_dy + 1U;
|
|
||||||
|
|
||||||
/* set image data */
|
|
||||||
|
|
||||||
/* Place the cursor at the beginning of the image information */
|
|
||||||
fseek(IN, 0, SEEK_SET);
|
|
||||||
fseek(IN, (long)File_h->bfOffBits, SEEK_SET);
|
|
||||||
|
|
||||||
stride = width;
|
|
||||||
/* line is 32 bits aligned */
|
|
||||||
if (stride & 3U) {
|
|
||||||
stride += 4U - (stride & 3U);
|
|
||||||
}
|
|
||||||
|
|
||||||
pData = (OPJ_UINT8 *)malloc(stride * height * sizeof(OPJ_UINT8));
|
|
||||||
|
|
||||||
if ( fread(pData, sizeof(OPJ_UINT8), stride * height, IN) != (stride * height) )
|
|
||||||
{
|
|
||||||
free(pData);
|
|
||||||
opj_image_destroy(image);
|
|
||||||
fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
pSrc = pData + (height - 1U) * stride;
|
pSrc = pData + (height - 1U) * stride;
|
||||||
if (numcmpts == 1U) {
|
for(y = 0; y < height; y++)
|
||||||
opj_applyLUT8u_8u32s_C1R(pSrc, -(OPJ_INT32)stride, image->comps[0].data, (OPJ_INT32)width, lut_R, width, height);
|
{
|
||||||
|
for(x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
OPJ_UINT32 value = 0U;
|
||||||
|
|
||||||
|
value |= ((OPJ_UINT32)pSrc[4*x+0]) << 0;
|
||||||
|
value |= ((OPJ_UINT32)pSrc[4*x+1]) << 8;
|
||||||
|
value |= ((OPJ_UINT32)pSrc[4*x+2]) << 16;
|
||||||
|
value |= ((OPJ_UINT32)pSrc[4*x+3]) << 24;
|
||||||
|
|
||||||
|
image->comps[0].data[index] = (value & redMask) >> redShift; /* R */
|
||||||
|
image->comps[1].data[index] = (value & greenMask) >> greenShift; /* G */
|
||||||
|
image->comps[2].data[index] = (value & blueMask) >> blueShift; /* B */
|
||||||
|
if (hasAlpha) {
|
||||||
|
image->comps[3].data[index] = (value & alphaMask) >> alphaShift; /* A */
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
pSrc -= stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
OPJ_UINT32 width, height;
|
||||||
|
OPJ_UINT32 x, y;
|
||||||
|
const OPJ_UINT8 *pSrc = NULL;
|
||||||
|
OPJ_BOOL hasAlpha = OPJ_FALSE;
|
||||||
|
OPJ_UINT32 redShift, redPrec;
|
||||||
|
OPJ_UINT32 greenShift, greenPrec;
|
||||||
|
OPJ_UINT32 blueShift, bluePrec;
|
||||||
|
OPJ_UINT32 alphaShift, alphaPrec;
|
||||||
|
|
||||||
|
width = image->comps[0].w;
|
||||||
|
height = image->comps[0].h;
|
||||||
|
|
||||||
|
hasAlpha = image->numcomps > 3U;
|
||||||
|
|
||||||
|
bmp_mask_get_shift_and_prec(redMask, &redShift, &redPrec);
|
||||||
|
bmp_mask_get_shift_and_prec(greenMask, &greenShift, &greenPrec);
|
||||||
|
bmp_mask_get_shift_and_prec(blueMask, &blueShift, &bluePrec);
|
||||||
|
bmp_mask_get_shift_and_prec(alphaMask, &alphaShift, &alphaPrec);
|
||||||
|
|
||||||
|
image->comps[0].bpp = redPrec;
|
||||||
|
image->comps[0].prec = redPrec;
|
||||||
|
image->comps[1].bpp = greenPrec;
|
||||||
|
image->comps[1].prec = greenPrec;
|
||||||
|
image->comps[2].bpp = bluePrec;
|
||||||
|
image->comps[2].prec = bluePrec;
|
||||||
|
if (hasAlpha) {
|
||||||
|
image->comps[3].bpp = alphaPrec;
|
||||||
|
image->comps[3].prec = alphaPrec;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
pSrc = pData + (height - 1U) * stride;
|
||||||
|
for(y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for(x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
OPJ_UINT32 value = 0U;
|
||||||
|
|
||||||
|
value |= ((OPJ_UINT32)pSrc[2*x+0]) << 0;
|
||||||
|
value |= ((OPJ_UINT32)pSrc[2*x+1]) << 8;
|
||||||
|
|
||||||
|
image->comps[0].data[index] = (value & redMask) >> redShift; /* R */
|
||||||
|
image->comps[1].data[index] = (value & greenMask) >> greenShift; /* G */
|
||||||
|
image->comps[2].data[index] = (value & blueMask) >> blueShift; /* B */
|
||||||
|
if (hasAlpha) {
|
||||||
|
image->comps[3].data[index] = (value & alphaMask) >> alphaShift; /* A */
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
pSrc -= stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static opj_image_t* bmp8toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT8 const* const* pLUT)
|
||||||
|
{
|
||||||
|
OPJ_UINT32 width, height;
|
||||||
|
const OPJ_UINT8 *pSrc = NULL;
|
||||||
|
|
||||||
|
width = image->comps[0].w;
|
||||||
|
height = image->comps[0].h;
|
||||||
|
|
||||||
|
pSrc = pData + (height - 1U) * stride;
|
||||||
|
if (image->numcomps == 1U) {
|
||||||
|
opj_applyLUT8u_8u32s_C1R(pSrc, -(OPJ_INT32)stride, image->comps[0].data, (OPJ_INT32)width, pLUT[0], width, height);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
OPJ_INT32* pDst[] = { image->comps[0].data, image->comps[1].data, image->comps[2].data };
|
OPJ_INT32* pDst[] = { image->comps[0].data, image->comps[1].data, image->comps[2].data };
|
||||||
OPJ_INT32 pDstStride[] = { (OPJ_INT32)width, (OPJ_INT32)width, (OPJ_INT32)width };
|
OPJ_INT32 pDstStride[] = { (OPJ_INT32)width, (OPJ_INT32)width, (OPJ_INT32)width };
|
||||||
OPJ_UINT8 const* pLUT[] = { lut_R, lut_G, lut_B };
|
|
||||||
|
|
||||||
opj_applyLUT8u_8u32s_C1P3R(pSrc, -(OPJ_INT32)stride, pDst, pDstStride, pLUT, width, height);
|
opj_applyLUT8u_8u32s_C1P3R(pSrc, -(OPJ_INT32)stride, pDst, pDstStride, pLUT, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(pData);
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
static opj_image_t* bmprle8toimage(FILE *IN, const OPJ_BITMAPFILEHEADER* File_h, const OPJ_BITMAPINFOHEADER* Info_h, const opj_cparameters_t *parameters)
|
static OPJ_BOOL bmp_read_file_header(FILE* IN, OPJ_BITMAPFILEHEADER* header)
|
||||||
{
|
{
|
||||||
OPJ_UINT8 lut_R[256], lut_G[256], lut_B[256];
|
header->bfType = (OPJ_UINT16)getc(IN);
|
||||||
opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
|
header->bfType += (OPJ_UINT16)(getc(IN) << 8);
|
||||||
opj_image_t * image = NULL;
|
|
||||||
OPJ_SIZE_T index;
|
if (header->bfType != 19778) {
|
||||||
OPJ_UINT32 i, palette_len;
|
fprintf(stderr,"Error, not a BMP file!\n");
|
||||||
OPJ_UINT32 x, y, width, height;
|
return OPJ_FALSE;
|
||||||
OPJ_UINT8 *pData = NULL, *pix;
|
}
|
||||||
|
|
||||||
|
/* FILE HEADER */
|
||||||
|
/* ------------- */
|
||||||
|
header->bfSize = (OPJ_UINT32)getc(IN);
|
||||||
|
header->bfSize += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->bfSize += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->bfSize += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->bfReserved1 = (OPJ_UINT16)getc(IN);
|
||||||
|
header->bfReserved1 += (OPJ_UINT16)(getc(IN) << 8);
|
||||||
|
|
||||||
|
header->bfReserved2 = (OPJ_UINT16)getc(IN);
|
||||||
|
header->bfReserved2 += (OPJ_UINT16)(getc(IN) << 8);
|
||||||
|
|
||||||
|
header->bfOffBits = (OPJ_UINT32)getc(IN);
|
||||||
|
header->bfOffBits += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->bfOffBits += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->bfOffBits += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
return OPJ_TRUE;
|
||||||
|
}
|
||||||
|
static OPJ_BOOL bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
|
||||||
|
{
|
||||||
|
memset(header, 0, sizeof(*header));
|
||||||
|
/* INFO HEADER */
|
||||||
|
/* ------------- */
|
||||||
|
header->biSize = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biSize += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biSize += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biSize += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
switch (header->biSize) {
|
||||||
|
case 12U: /* BITMAPCOREHEADER */
|
||||||
|
case 40U: /* BITMAPINFOHEADER */
|
||||||
|
case 52U: /* BITMAPV2INFOHEADER */
|
||||||
|
case 56U: /* BITMAPV3INFOHEADER */
|
||||||
|
case 108U: /* BITMAPV4HEADER */
|
||||||
|
case 124U: /* BITMAPV5HEADER */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"Error, unknown BMP header size %d\n", header->biSize);
|
||||||
|
return OPJ_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
header->biWidth = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biWidth += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biWidth += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biWidth += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biHeight = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biHeight += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biHeight += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biHeight += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biPlanes = (OPJ_UINT16)getc(IN);
|
||||||
|
header->biPlanes += (OPJ_UINT16)(getc(IN) << 8);
|
||||||
|
|
||||||
|
header->biBitCount = (OPJ_UINT16)getc(IN);
|
||||||
|
header->biBitCount += (OPJ_UINT16)(getc(IN) << 8);
|
||||||
|
|
||||||
|
if(header->biSize >= 40U) {
|
||||||
|
header->biCompression = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biCompression += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biCompression += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biCompression += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biSizeImage = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biSizeImage += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biSizeImage += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biSizeImage += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biXpelsPerMeter = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biXpelsPerMeter += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biXpelsPerMeter += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biXpelsPerMeter += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biYpelsPerMeter = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biYpelsPerMeter += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biYpelsPerMeter += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biYpelsPerMeter += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biClrUsed = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biClrUsed += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biClrUsed += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biClrUsed += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biClrImportant = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biClrImportant += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biClrImportant += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biClrImportant += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(header->biSize >= 56U) {
|
||||||
|
header->biRedMask = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biRedMask += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biRedMask += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biRedMask += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biGreenMask = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biGreenMask += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biGreenMask += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biGreenMask += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biBlueMask = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biBlueMask += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biBlueMask += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biBlueMask += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biAlphaMask = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biAlphaMask += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biAlphaMask += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biAlphaMask += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(header->biSize >= 108U) {
|
||||||
|
header->biColorSpaceType = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biColorSpaceType += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biColorSpaceType += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biColorSpaceType += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
fread(&(header->biColorSpaceEP), 1U, sizeof(header->biColorSpaceEP), IN);
|
||||||
|
|
||||||
|
header->biRedGamma = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biRedGamma += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biRedGamma += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biRedGamma += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biGreenGamma = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biGreenGamma += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biGreenGamma += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biGreenGamma += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biBlueGamma = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biBlueGamma += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biBlueGamma += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biBlueGamma += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(header->biSize >= 124U) {
|
||||||
|
header->biIntent = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biIntent += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biIntent += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biIntent += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biIccProfileData = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biIccProfileData += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biIccProfileData += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biIccProfileData += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biIccProfileSize = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biIccProfileSize += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biIccProfileSize += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biIccProfileSize += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
|
||||||
|
header->biReserved = (OPJ_UINT32)getc(IN);
|
||||||
|
header->biReserved += (OPJ_UINT32)(getc(IN) << 8);
|
||||||
|
header->biReserved += (OPJ_UINT32)(getc(IN) << 16);
|
||||||
|
header->biReserved += (OPJ_UINT32)(getc(IN) << 24);
|
||||||
|
}
|
||||||
|
return OPJ_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OPJ_BOOL bmp_read_raw_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
|
||||||
|
{
|
||||||
|
if ( fread(pData, sizeof(OPJ_UINT8), stride * height, IN) != (stride * height) )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
|
||||||
|
return OPJ_FALSE;
|
||||||
|
}
|
||||||
|
return OPJ_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
|
||||||
|
{
|
||||||
|
OPJ_UINT32 x, y;
|
||||||
|
OPJ_UINT8 *pix;
|
||||||
const OPJ_UINT8 *beyond;
|
const OPJ_UINT8 *beyond;
|
||||||
OPJ_UINT32 numcmpts = 1U; /* grayscale by default */
|
|
||||||
|
|
||||||
width = Info_h->biWidth;
|
beyond = pData + stride * height;
|
||||||
height = Info_h->biHeight;
|
pix = pData;
|
||||||
|
|
||||||
/* initialize */
|
|
||||||
memset(&cmptparm[0], 0, sizeof(cmptparm));
|
|
||||||
memset(&lut_R[0], 0, sizeof(lut_R));
|
|
||||||
memset(&lut_G[0], 0, sizeof(lut_G));
|
|
||||||
memset(&lut_B[0], 0, sizeof(lut_B));
|
|
||||||
|
|
||||||
palette_len = Info_h->biClrUsed;
|
|
||||||
if ((palette_len == 0U) || (palette_len > 256U)) {
|
|
||||||
palette_len = 256U;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load palette */
|
|
||||||
{
|
|
||||||
OPJ_UINT8 has_color = 0U;
|
|
||||||
for (i = 0; i < palette_len; i++) {
|
|
||||||
lut_B[i] = (OPJ_UINT8)getc(IN);
|
|
||||||
lut_G[i] = (OPJ_UINT8)getc(IN);
|
|
||||||
lut_R[i] = (OPJ_UINT8)getc(IN);
|
|
||||||
getc(IN); /* padding */
|
|
||||||
has_color |= lut_B[i] ^ (lut_G[i] | lut_R[i]);
|
|
||||||
}
|
|
||||||
if(has_color) {
|
|
||||||
numcmpts = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for(i = 0; i < numcmpts; i++)
|
|
||||||
{
|
|
||||||
cmptparm[i].prec = 8;
|
|
||||||
cmptparm[i].bpp = 8;
|
|
||||||
cmptparm[i].sgnd = 0;
|
|
||||||
cmptparm[i].dx = (OPJ_UINT32)parameters->subsampling_dx;
|
|
||||||
cmptparm[i].dy = (OPJ_UINT32)parameters->subsampling_dy;
|
|
||||||
cmptparm[i].w = width;
|
|
||||||
cmptparm[i].h = height;
|
|
||||||
}
|
|
||||||
/* create the image */
|
|
||||||
image = opj_image_create(numcmpts, &cmptparm[0], (numcmpts == 1U) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB);
|
|
||||||
if(!image)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set image offset and reference grid */
|
|
||||||
image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
|
|
||||||
image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
|
|
||||||
image->x1 = image->x0 + (width - 1U) * (OPJ_UINT32)parameters->subsampling_dx + 1U;
|
|
||||||
image->y1 = image->y0 + (height - 1U) * (OPJ_UINT32)parameters->subsampling_dy + 1U;
|
|
||||||
|
|
||||||
/* set image data */
|
|
||||||
|
|
||||||
/* Place the cursor at the beginning of the image information */
|
|
||||||
fseek(IN, 0, SEEK_SET);
|
|
||||||
fseek(IN, (long)File_h->bfOffBits, SEEK_SET);
|
|
||||||
|
|
||||||
pData = (OPJ_UINT8 *) calloc(1, width * height * sizeof(OPJ_UINT8));
|
|
||||||
beyond = pData + width * height;
|
|
||||||
pix = (OPJ_UINT8 *)(beyond - width);
|
|
||||||
x = y = 0U;
|
x = y = 0U;
|
||||||
while (y < height)
|
while (y < height)
|
||||||
{
|
{
|
||||||
|
@ -391,7 +517,7 @@ static opj_image_t* bmprle8toimage(FILE *IN, const OPJ_BITMAPFILEHEADER* File_h,
|
||||||
if (c == 0x00) { /* EOL */
|
if (c == 0x00) { /* EOL */
|
||||||
x = 0;
|
x = 0;
|
||||||
++y;
|
++y;
|
||||||
pix = pData + (height - y - 1U) * width + x;
|
pix = pData + y * stride + x;
|
||||||
}
|
}
|
||||||
else if (c == 0x01) { /* EOP */
|
else if (c == 0x01) { /* EOP */
|
||||||
break;
|
break;
|
||||||
|
@ -401,7 +527,7 @@ static opj_image_t* bmprle8toimage(FILE *IN, const OPJ_BITMAPFILEHEADER* File_h,
|
||||||
x += (OPJ_UINT32)c;
|
x += (OPJ_UINT32)c;
|
||||||
c = getc(IN);
|
c = getc(IN);
|
||||||
y += (OPJ_UINT32)c;
|
y += (OPJ_UINT32)c;
|
||||||
pix = pData + (height - y - 1U) * width + x;
|
pix = pData + y * stride + x;
|
||||||
}
|
}
|
||||||
else /* 03 .. 255 */
|
else /* 03 .. 255 */
|
||||||
{
|
{
|
||||||
|
@ -417,30 +543,78 @@ static opj_image_t* bmprle8toimage(FILE *IN, const OPJ_BITMAPFILEHEADER* File_h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}/* while() */
|
}/* while() */
|
||||||
|
return OPJ_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
index = 0;
|
static OPJ_BOOL bmp_read_rle4_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
|
||||||
if (numcmpts == 1) {
|
{
|
||||||
opj_applyLUT8u_8u32s_C1R(pData, (OPJ_INT32)width, image->comps[0].data, (OPJ_INT32)width, lut_R, width, height);
|
OPJ_UINT32 x, y;
|
||||||
|
OPJ_UINT8 *pix;
|
||||||
|
const OPJ_UINT8 *beyond;
|
||||||
|
|
||||||
|
beyond = pData + stride * height;
|
||||||
|
pix = pData;
|
||||||
|
x = y = 0U;
|
||||||
|
while(y < height)
|
||||||
|
{
|
||||||
|
int c = getc(IN);
|
||||||
|
if(c == EOF) break;
|
||||||
|
|
||||||
|
if(c) {/* encoded mode */
|
||||||
|
int j;
|
||||||
|
OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
|
||||||
|
|
||||||
|
for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
|
||||||
|
*pix = (j&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
OPJ_INT32* pDst[] = { image->comps[0].data, image->comps[1].data, image->comps[2].data };
|
|
||||||
OPJ_INT32 pDstStride[] = { (OPJ_INT32)width, (OPJ_INT32)width, (OPJ_INT32)width };
|
|
||||||
OPJ_UINT8 const* pLUT[] = { lut_R, lut_G, lut_B };
|
|
||||||
|
|
||||||
opj_applyLUT8u_8u32s_C1P3R(pData, (OPJ_INT32)width, pDst, pDstStride, pLUT, width, height);
|
|
||||||
}
|
}
|
||||||
|
else { /* absolute mode */
|
||||||
|
c = getc(IN);
|
||||||
|
if(c == EOF) break;
|
||||||
|
|
||||||
free(pData);
|
if(c == 0x00) { /* EOL */
|
||||||
return image;
|
x = 0; y++; pix = pData + y * stride;
|
||||||
|
}
|
||||||
|
else if(c == 0x01) { /* EOP */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(c == 0x02) { /* MOVE by dxdy */
|
||||||
|
c = getc(IN); x += c;
|
||||||
|
c = getc(IN); y += c;
|
||||||
|
pix = pData + y * stride + x;
|
||||||
|
}
|
||||||
|
else { /* 03 .. 255 : absolute mode */
|
||||||
|
int j;
|
||||||
|
OPJ_UINT8 c1 = 0U;
|
||||||
|
|
||||||
|
for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
|
||||||
|
if((j&1) == 0) {
|
||||||
|
c1 = getc(IN);
|
||||||
|
}
|
||||||
|
*pix = (j&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
|
||||||
|
}
|
||||||
|
if(((c&3) == 1) || ((c&3) == 2)) { /* skip padding byte */
|
||||||
|
getc(IN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /* while(y < height) */
|
||||||
|
return OPJ_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
|
opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
|
||||||
{
|
{
|
||||||
|
opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */
|
||||||
|
OPJ_UINT8 lut_R[256], lut_G[256], lut_B[256];
|
||||||
|
OPJ_UINT8 const* pLUT[] = { lut_R, lut_G, lut_B };
|
||||||
opj_image_t * image = NULL;
|
opj_image_t * image = NULL;
|
||||||
|
|
||||||
FILE *IN;
|
FILE *IN;
|
||||||
OPJ_BITMAPFILEHEADER File_h;
|
OPJ_BITMAPFILEHEADER File_h;
|
||||||
OPJ_BITMAPINFOHEADER Info_h;
|
OPJ_BITMAPINFOHEADER Info_h;
|
||||||
|
OPJ_UINT32 i, palette_len, numcmpts = 1U;
|
||||||
|
OPJ_BOOL l_result = OPJ_FALSE;
|
||||||
|
OPJ_UINT8* pData = NULL;
|
||||||
|
OPJ_UINT32 stride;
|
||||||
|
|
||||||
IN = fopen(filename, "rb");
|
IN = fopen(filename, "rb");
|
||||||
if (!IN)
|
if (!IN)
|
||||||
|
@ -449,106 +623,140 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
File_h.bfType = (OPJ_UINT16)getc(IN);
|
if (!bmp_read_file_header(IN, &File_h)) {
|
||||||
File_h.bfType = (OPJ_UINT16)((getc(IN) << 8) + File_h.bfType);
|
fclose(IN);
|
||||||
|
return NULL;
|
||||||
if (File_h.bfType != 19778) {
|
}
|
||||||
fprintf(stderr,"Error, not a BMP file!\n");
|
if (!bmp_read_info_header(IN, &Info_h)) {
|
||||||
fclose(IN);
|
fclose(IN);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FILE HEADER */
|
/* Load palette */
|
||||||
/* ------------- */
|
if (Info_h.biBitCount <= 8U)
|
||||||
File_h.bfSize = (OPJ_UINT32)getc(IN);
|
{
|
||||||
File_h.bfSize = (OPJ_UINT32)(getc(IN) << 8) + File_h.bfSize;
|
memset(&lut_R[0], 0, sizeof(lut_R));
|
||||||
File_h.bfSize = (OPJ_UINT32)(getc(IN) << 16) + File_h.bfSize;
|
memset(&lut_G[0], 0, sizeof(lut_G));
|
||||||
File_h.bfSize = (OPJ_UINT32)(getc(IN) << 24) + File_h.bfSize;
|
memset(&lut_B[0], 0, sizeof(lut_B));
|
||||||
|
|
||||||
File_h.bfReserved1 = (OPJ_UINT16)getc(IN);
|
palette_len = Info_h.biClrUsed;
|
||||||
File_h.bfReserved1 = (OPJ_UINT16)((getc(IN) << 8) + File_h.bfReserved1);
|
if((palette_len == 0U) && (Info_h.biBitCount <= 8U)) {
|
||||||
|
palette_len = (1U << Info_h.biBitCount);
|
||||||
|
}
|
||||||
|
if (palette_len > 256U) {
|
||||||
|
palette_len = 256U;
|
||||||
|
}
|
||||||
|
if (palette_len > 0U) {
|
||||||
|
OPJ_UINT8 has_color = 0U;
|
||||||
|
for (i = 0U; i < palette_len; i++) {
|
||||||
|
lut_B[i] = (OPJ_UINT8)getc(IN);
|
||||||
|
lut_G[i] = (OPJ_UINT8)getc(IN);
|
||||||
|
lut_R[i] = (OPJ_UINT8)getc(IN);
|
||||||
|
(void)getc(IN); /* padding */
|
||||||
|
has_color |= (lut_B[i] ^ lut_G[i]) | (lut_G[i] ^ lut_R[i]);
|
||||||
|
}
|
||||||
|
if(has_color) {
|
||||||
|
numcmpts = 3U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
numcmpts = 3U;
|
||||||
|
if (Info_h.biAlphaMask != 0U) {
|
||||||
|
numcmpts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
File_h.bfReserved2 = (OPJ_UINT16)getc(IN);
|
stride = ((Info_h.biWidth * Info_h.biBitCount + 31U) / 32U) * 4U; // rows are aligned on 32bits
|
||||||
File_h.bfReserved2 = (OPJ_UINT16)((getc(IN) << 8) + File_h.bfReserved2);
|
if (Info_h.biBitCount == 4 && Info_h.biCompression == 2) { /* RLE 4 gets decoded as 8 bits data for now... */
|
||||||
|
stride = ((Info_h.biWidth * 8U + 31U) / 32U) * 4U; // rows are aligned on 32bits
|
||||||
|
}
|
||||||
|
pData = (OPJ_UINT8 *) calloc(1, stride * Info_h.biHeight * sizeof(OPJ_UINT8));
|
||||||
|
if (pData == NULL) {
|
||||||
|
fclose(IN);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* Place the cursor at the beginning of the image information */
|
||||||
|
fseek(IN, 0, SEEK_SET);
|
||||||
|
fseek(IN, (long)File_h.bfOffBits, SEEK_SET);
|
||||||
|
|
||||||
File_h.bfOffBits = (OPJ_UINT32)getc(IN);
|
switch (Info_h.biCompression) {
|
||||||
File_h.bfOffBits = (OPJ_UINT32)(getc(IN) << 8) + File_h.bfOffBits;
|
case 0:
|
||||||
File_h.bfOffBits = (OPJ_UINT32)(getc(IN) << 16) + File_h.bfOffBits;
|
case 3:
|
||||||
File_h.bfOffBits = (OPJ_UINT32)(getc(IN) << 24) + File_h.bfOffBits;
|
/* read raw data */
|
||||||
|
l_result = bmp_read_raw_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
|
||||||
/* INFO HEADER */
|
break;
|
||||||
/* ------------- */
|
case 1:
|
||||||
|
/* read rle8 data */
|
||||||
Info_h.biSize = (OPJ_UINT32)getc(IN);
|
l_result = bmp_read_rle8_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
|
||||||
Info_h.biSize = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biSize;
|
break;
|
||||||
Info_h.biSize = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biSize;
|
case 2:
|
||||||
Info_h.biSize = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biSize;
|
/* read rle4 data */
|
||||||
|
l_result = bmp_read_rle4_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
|
||||||
if(Info_h.biSize != 40) {
|
break;
|
||||||
fprintf(stderr,"Error, unknown BMP header size %d\n", Info_h.biSize);
|
default:
|
||||||
|
fprintf(stderr, "Unsupported BMP compression\n");
|
||||||
|
l_result = OPJ_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!l_result) {
|
||||||
|
free(pData);
|
||||||
fclose(IN);
|
fclose(IN);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info_h.biWidth = (OPJ_UINT32)getc(IN);
|
/* create the image */
|
||||||
Info_h.biWidth = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biWidth;
|
memset(&cmptparm[0], 0, sizeof(cmptparm));
|
||||||
Info_h.biWidth = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biWidth;
|
for(i = 0; i < 4U; i++)
|
||||||
Info_h.biWidth = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biWidth;
|
{
|
||||||
|
cmptparm[i].prec = 8;
|
||||||
|
cmptparm[i].bpp = 8;
|
||||||
|
cmptparm[i].sgnd = 0;
|
||||||
|
cmptparm[i].dx = (OPJ_UINT32)parameters->subsampling_dx;
|
||||||
|
cmptparm[i].dy = (OPJ_UINT32)parameters->subsampling_dy;
|
||||||
|
cmptparm[i].w = Info_h.biWidth;
|
||||||
|
cmptparm[i].h = Info_h.biHeight;
|
||||||
|
}
|
||||||
|
|
||||||
Info_h.biHeight = (OPJ_UINT32)getc(IN);
|
image = opj_image_create(numcmpts, &cmptparm[0], (numcmpts == 1U) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB);
|
||||||
Info_h.biHeight = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biHeight;
|
if(!image) {
|
||||||
Info_h.biHeight = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biHeight;
|
fclose(IN);
|
||||||
Info_h.biHeight = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biHeight;
|
return NULL;
|
||||||
|
}
|
||||||
|
if (numcmpts == 4U) {
|
||||||
|
image->comps[3].alpha = 1;
|
||||||
|
}
|
||||||
|
|
||||||
Info_h.biPlanes = (OPJ_UINT16)getc(IN);
|
/* set image offset and reference grid */
|
||||||
Info_h.biPlanes = (OPJ_UINT16)((getc(IN) << 8) + Info_h.biPlanes);
|
image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
|
||||||
|
image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
|
||||||
Info_h.biBitCount = (OPJ_UINT16)getc(IN);
|
image->x1 = image->x0 + (Info_h.biWidth - 1U) * (OPJ_UINT32)parameters->subsampling_dx + 1U;
|
||||||
Info_h.biBitCount = (OPJ_UINT16)((getc(IN) << 8) + Info_h.biBitCount);
|
image->y1 = image->y0 + (Info_h.biHeight - 1U) * (OPJ_UINT32)parameters->subsampling_dy + 1U;
|
||||||
|
|
||||||
Info_h.biCompression = (OPJ_UINT32)getc(IN);
|
|
||||||
Info_h.biCompression = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biCompression;
|
|
||||||
Info_h.biCompression = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biCompression;
|
|
||||||
Info_h.biCompression = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biCompression;
|
|
||||||
|
|
||||||
Info_h.biSizeImage = (OPJ_UINT32)getc(IN);
|
|
||||||
Info_h.biSizeImage = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biSizeImage;
|
|
||||||
Info_h.biSizeImage = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biSizeImage;
|
|
||||||
Info_h.biSizeImage = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biSizeImage;
|
|
||||||
|
|
||||||
Info_h.biXpelsPerMeter = (OPJ_UINT32)getc(IN);
|
|
||||||
Info_h.biXpelsPerMeter = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biXpelsPerMeter;
|
|
||||||
Info_h.biXpelsPerMeter = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biXpelsPerMeter;
|
|
||||||
Info_h.biXpelsPerMeter = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biXpelsPerMeter;
|
|
||||||
|
|
||||||
Info_h.biYpelsPerMeter = (OPJ_UINT32)getc(IN);
|
|
||||||
Info_h.biYpelsPerMeter = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biYpelsPerMeter;
|
|
||||||
Info_h.biYpelsPerMeter = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biYpelsPerMeter;
|
|
||||||
Info_h.biYpelsPerMeter = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biYpelsPerMeter;
|
|
||||||
|
|
||||||
Info_h.biClrUsed = (OPJ_UINT32)getc(IN);
|
|
||||||
Info_h.biClrUsed = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biClrUsed;
|
|
||||||
Info_h.biClrUsed = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biClrUsed;
|
|
||||||
Info_h.biClrUsed = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biClrUsed;
|
|
||||||
|
|
||||||
Info_h.biClrImportant = (OPJ_UINT32)getc(IN);
|
|
||||||
Info_h.biClrImportant = (OPJ_UINT32)(getc(IN) << 8) + Info_h.biClrImportant;
|
|
||||||
Info_h.biClrImportant = (OPJ_UINT32)(getc(IN) << 16) + Info_h.biClrImportant;
|
|
||||||
Info_h.biClrImportant = (OPJ_UINT32)(getc(IN) << 24) + Info_h.biClrImportant;
|
|
||||||
|
|
||||||
/* Read the data */
|
/* Read the data */
|
||||||
if (Info_h.biBitCount == 24) { /*RGB */
|
if (Info_h.biBitCount == 24 && Info_h.biCompression == 0) { /*RGB */
|
||||||
image = bmp24toimage(IN, &File_h, &Info_h, parameters);
|
bmp24toimage(IN, pData, stride, image);
|
||||||
}
|
}
|
||||||
else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { /* RGB 8bpp Indexed */
|
else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { /* RGB 8bpp Indexed */
|
||||||
image = bmp8toimage(IN, &File_h, &Info_h, parameters);
|
bmp8toimage(IN, pData, stride, image, pLUT);
|
||||||
}
|
}
|
||||||
else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { /*RLE8*/
|
else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { /*RLE8*/
|
||||||
image = bmprle8toimage(IN, &File_h, &Info_h, parameters);
|
bmp8toimage(IN, pData, stride, image, pLUT);
|
||||||
|
}
|
||||||
|
else if (Info_h.biBitCount == 4 && Info_h.biCompression == 2) { /*RLE4*/
|
||||||
|
bmp8toimage(IN, pData, stride, image, pLUT); /* RLE 4 gets decoded as 8 bits data for now */
|
||||||
|
}
|
||||||
|
else if (Info_h.biBitCount == 32 && Info_h.biCompression == 3) { /* bitmask */
|
||||||
|
bmpmask32toimage(IN, pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
|
||||||
|
}
|
||||||
|
else if (Info_h.biBitCount == 16 && Info_h.biCompression == 3) { /* bitmask */
|
||||||
|
bmpmask16toimage(IN, pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
opj_image_destroy(image);
|
||||||
|
image = NULL;
|
||||||
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, "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount);
|
||||||
}
|
}
|
||||||
|
free(pData);
|
||||||
fclose(IN);
|
fclose(IN);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ opj_compress -i @INPUT_NR_PATH@/ElephantDream_4K.tif -o @TEMP_PATH@/ElephantDrea
|
||||||
opj_compress -i @INPUT_NR_PATH@/issue141.rawl -o @TEMP_PATH@/issue141.rawl.j2k -F 2048,32,1,16,u
|
opj_compress -i @INPUT_NR_PATH@/issue141.rawl -o @TEMP_PATH@/issue141.rawl.j2k -F 2048,32,1,16,u
|
||||||
opj_compress -i @INPUT_NR_PATH@/issue141.rawl -o @TEMP_PATH@/issue141-I.rawl.j2k -F 2048,32,1,16,u -I
|
opj_compress -i @INPUT_NR_PATH@/issue141.rawl -o @TEMP_PATH@/issue141-I.rawl.j2k -F 2048,32,1,16,u -I
|
||||||
# issue 46:
|
# issue 46:
|
||||||
opj_compress -i @INPUT_NR_PATH@/Bretagne2.ppm -o @TEMP_PATH@/Bretagne2_0.j2k -c [64,64]
|
opj_compress -i @INPUT_NR_PATH@/Bretagne2.ppm -o @TEMP_PATH@/Bretagne2_5.j2k -c [64,64]
|
||||||
# issue 316
|
# issue 316
|
||||||
opj_compress -i @INPUT_NR_PATH@/issue316.png -o @TEMP_PATH@/issue316.png.jp2
|
opj_compress -i @INPUT_NR_PATH@/issue316.png -o @TEMP_PATH@/issue316.png.jp2
|
||||||
# issue 416 (cdef for png with alpha) + issue 436 (MCT norm read buffer overflow for num comp > 3 + Issue 215 number of decomp levels
|
# issue 416 (cdef for png with alpha) + issue 436 (MCT norm read buffer overflow for num comp > 3 + Issue 215 number of decomp levels
|
||||||
|
@ -51,6 +51,26 @@ opj_compress -i @INPUT_NR_PATH@/basn6a08.png -o @TEMP_PATH@/basn6a08.png.jp2 -n
|
||||||
# issue 203 BMP Files not handled properly
|
# issue 203 BMP Files not handled properly
|
||||||
opj_compress -i @INPUT_NR_PATH@/issue203-8bpp-width1.bmp -o @TEMP_PATH@/issue203-8bpp-width1.bmp.jp2
|
opj_compress -i @INPUT_NR_PATH@/issue203-8bpp-width1.bmp -o @TEMP_PATH@/issue203-8bpp-width1.bmp.jp2
|
||||||
opj_compress -i @INPUT_NR_PATH@/issue203-rle8.bmp -o @TEMP_PATH@/issue203-rle8.bmp.jp2
|
opj_compress -i @INPUT_NR_PATH@/issue203-rle8.bmp -o @TEMP_PATH@/issue203-rle8.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-y8.bmp -o @TEMP_PATH@/issue203-32x32-y8.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-33x33-y8.bmp -o @TEMP_PATH@/issue203-33x33-y8.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-34x34-y8.bmp -o @TEMP_PATH@/issue203-34x34-y8.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-35x35-y8.bmp -o @TEMP_PATH@/issue203-35x35-y8.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-bgr.bmp -o @TEMP_PATH@/issue203-32x32-bgr.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-33x33-bgr.bmp -o @TEMP_PATH@/issue203-33x33-bgr.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-34x34-bgr.bmp -o @TEMP_PATH@/issue203-34x34-bgr.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-35x35-bgr.bmp -o @TEMP_PATH@/issue203-35x35-bgr.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-y-rle8.bmp -o @TEMP_PATH@/issue203-32x32-y-rle8.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-bgr-rle8.bmp -o @TEMP_PATH@/issue203-32x32-bgr-rle8.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-y-rle4.bmp -o @TEMP_PATH@/issue203-32x32-y-rle4.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-bgr-rle4.bmp -o @TEMP_PATH@/issue203-32x32-bgr-rle4.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-bgra.bmp -o @TEMP_PATH@/issue203-32x32-bgra.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-bgrx.bmp -o @TEMP_PATH@/issue203-32x32-bgrx.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-bgr16.bmp -o @TEMP_PATH@/issue203-32x32-bgr16.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-33x33-bgr16.bmp -o @TEMP_PATH@/issue203-33x33-bgr16.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-bgra16.bmp -o @TEMP_PATH@/issue203-32x32-bgra16.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-33x33-bgra16.bmp -o @TEMP_PATH@/issue203-33x33-bgra16.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-32x32-bgrx16.bmp -o @TEMP_PATH@/issue203-32x32-bgrx16.bmp.jp2
|
||||||
|
opj_compress -i @INPUT_NR_PATH@/issue203-33x33-bgrx16.bmp -o @TEMP_PATH@/issue203-33x33-bgrx16.bmp.jp2
|
||||||
|
|
||||||
# DECODER TEST SUITE
|
# DECODER TEST SUITE
|
||||||
opj_decompress -i @INPUT_NR_PATH@/Bretagne2.j2k -o @TEMP_PATH@/Bretagne2.j2k.pgx
|
opj_decompress -i @INPUT_NR_PATH@/Bretagne2.j2k -o @TEMP_PATH@/Bretagne2.j2k.pgx
|
||||||
|
|
Loading…
Reference in New Issue