Antonin Descampe 2011-07-03 18:23:33 +00:00
parent fa6aea80f5
commit a5130aebab
2 changed files with 399 additions and 316 deletions

View File

@ -6,6 +6,7 @@ What's New for OpenJPEG
+ : added + : added
July 3, 2011 July 3, 2011
* [antonin] fixed bmptoimage (see http://groups.google.com/group/openjpeg/browse_thread/thread/33a24c5896bf6391)
* [antonin] fixed handling of "jp2->meth" value (Restricted ICC profile handling currently not implemented) * [antonin] fixed handling of "jp2->meth" value (Restricted ICC profile handling currently not implemented)
June 30, 2011 June 30, 2011

View File

@ -390,7 +390,8 @@ typedef struct {
DWORD biClrImportant; /* Number of important color (0: ALL) */ DWORD biClrImportant; /* Number of important color (0: ALL) */
} BITMAPINFOHEADER_t; } BITMAPINFOHEADER_t;
opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) { opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
{
int subsampling_dx = parameters->subsampling_dx; int subsampling_dx = parameters->subsampling_dx;
int subsampling_dy = parameters->subsampling_dy; int subsampling_dy = parameters->subsampling_dy;
@ -408,24 +409,27 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
int x, y, index; int x, y, index;
int gray_scale = 1, not_end_file = 1; int gray_scale = 1, not_end_file = 1;
int has_color;
unsigned int line = 0, col = 0; unsigned int line = 0, col = 0;
unsigned char v, v2; unsigned char v, v2;
DWORD W, H; DWORD W, H;
IN = fopen(filename, "rb"); IN = fopen(filename, "rb");
if (!IN) { if (!IN)
{
fprintf(stderr, "Failed to open %s for reading !!\n", filename); fprintf(stderr, "Failed to open %s for reading !!\n", filename);
return 0; return NULL;
} }
File_h.bfType = getc(IN); File_h.bfType = getc(IN);
File_h.bfType = (getc(IN) << 8) + File_h.bfType; File_h.bfType = (getc(IN) << 8) + File_h.bfType;
if (File_h.bfType != 19778) { if (File_h.bfType != 19778)
{
fprintf(stderr,"Error, not a BMP file!\n"); fprintf(stderr,"Error, not a BMP file!\n");
return 0; fclose(IN);
} else { return NULL;
}
/* FILE HEADER */ /* FILE HEADER */
/* ------------- */ /* ------------- */
File_h.bfSize = getc(IN); File_h.bfSize = getc(IN);
@ -452,6 +456,12 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
Info_h.biSize = (getc(IN) << 16) + Info_h.biSize; Info_h.biSize = (getc(IN) << 16) + Info_h.biSize;
Info_h.biSize = (getc(IN) << 24) + Info_h.biSize; Info_h.biSize = (getc(IN) << 24) + Info_h.biSize;
if(Info_h.biSize != 40)
{
fprintf(stderr,"Error, unknown BMP header size %d\n", Info_h.biSize);
fclose(IN);
return NULL;
}
Info_h.biWidth = getc(IN); Info_h.biWidth = getc(IN);
Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth; Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth;
Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth; Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth;
@ -502,12 +512,14 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
/* Read the data and store them in the OUT file */ /* Read the data and store them in the OUT file */
if (Info_h.biBitCount == 24) { if (Info_h.biBitCount == 24)
{
numcomps = 3; numcomps = 3;
color_space = CLRSPC_SRGB; color_space = CLRSPC_SRGB;
/* initialize image components */ /* initialize image components */
memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
for(i = 0; i < numcomps; i++) { for(i = 0; i < numcomps; i++)
{
cmptparm[i].prec = 8; cmptparm[i].prec = 8;
cmptparm[i].bpp = 8; cmptparm[i].bpp = 8;
cmptparm[i].sgnd = 0; cmptparm[i].sgnd = 0;
@ -518,7 +530,8 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
} }
/* create the image */ /* create the image */
image = opj_image_create(numcomps, &cmptparm[0], color_space); image = opj_image_create(numcomps, &cmptparm[0], color_space);
if(!image) { if(!image)
{
fclose(IN); fclose(IN);
return NULL; return NULL;
} }
@ -542,15 +555,18 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
/* PAD = (PAD == 4) ? 0 : PAD; */ /* PAD = (PAD == 4) ? 0 : PAD; */
PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0; PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0;
RGB = (unsigned char *) malloc((3 * W + PAD) * H * sizeof(unsigned char)); RGB = (unsigned char *)
malloc((3 * W + PAD) * H * sizeof(unsigned char));
fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN); fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN);
index = 0; index = 0;
for(y = 0; y < (int)H; y++) { for(y = 0; y < (int)H; y++)
{
unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y); unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y);
for(x = 0; x < (int)W; x++) { for(x = 0; x < (int)W; x++)
{
unsigned char *pixel = &scanline[3 * x]; unsigned char *pixel = &scanline[3 * x];
image->comps[0].data[index] = pixel[2]; /* R */ image->comps[0].data[index] = pixel[2]; /* R */
image->comps[1].data[index] = pixel[1]; /* G */ image->comps[1].data[index] = pixel[1]; /* G */
@ -558,22 +574,30 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
index++; index++;
} }
} }
free(RGB); free(RGB);
}/* if (Info_h.biBitCount == 24) */
else
if (Info_h.biBitCount == 8 && Info_h.biCompression == 0)//RGB
{
if(Info_h.biClrUsed == 0) Info_h.biClrUsed = 256;
else
if(Info_h.biClrUsed > 256) Info_h.biClrUsed = 256;
} else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) {
table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
table_G = (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)); table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
for (j = 0; j < Info_h.biClrUsed; j++) { has_color = 0;
for (j = 0; j < Info_h.biClrUsed; j++)
{
table_B[j] = getc(IN); table_B[j] = getc(IN);
table_G[j] = getc(IN); table_G[j] = getc(IN);
table_R[j] = getc(IN); table_R[j] = getc(IN);
getc(IN); getc(IN);
if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j]) has_color +=
gray_scale = 0; !(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 */ /* Place the cursor at the beginning of the image information */
fseek(IN, 0, SEEK_SET); fseek(IN, 0, SEEK_SET);
@ -588,7 +612,8 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB; color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;
/* initialize image components */ /* initialize image components */
memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
for(i = 0; i < numcomps; i++) { for(i = 0; i < numcomps; i++)
{
cmptparm[i].prec = 8; cmptparm[i].prec = 8;
cmptparm[i].bpp = 8; cmptparm[i].bpp = 8;
cmptparm[i].sgnd = 0; cmptparm[i].sgnd = 0;
@ -599,8 +624,10 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
} }
/* create the image */ /* create the image */
image = opj_image_create(numcomps, &cmptparm[0], color_space); image = opj_image_create(numcomps, &cmptparm[0], color_space);
if(!image) { if(!image)
{
fclose(IN); fclose(IN);
free(table_R); free(table_G); free(table_B);
return NULL; return NULL;
} }
@ -615,20 +642,30 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char)); RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char));
fread(RGB, sizeof(unsigned char), W * H, IN); fread(RGB, sizeof(unsigned char), W * H, IN);
if (gray_scale) { if (gray_scale)
{
index = 0; index = 0;
for (j = 0; j < W * H; j++) { for (j = 0; j < W * H; j++)
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)]]; 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++; index++;
} }
} }
} else { }
else
{
index = 0; index = 0;
for (j = 0; j < W * H; j++) { for (j = 0; j < W * H; j++)
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)]; 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[0].data[index] = table_R[pixel_index];
image->comps[1].data[index] = table_G[pixel_index]; image->comps[1].data[index] = table_G[pixel_index];
image->comps[2].data[index] = table_B[pixel_index]; image->comps[2].data[index] = table_B[pixel_index];
@ -640,25 +677,43 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
free(table_R); free(table_R);
free(table_G); free(table_G);
free(table_B); free(table_B);
} else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { }/* RGB8 */
else
if (Info_h.biBitCount == 8 && Info_h.biCompression == 1)//RLE8
{
unsigned char *pix, *beyond;
unsigned 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_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
table_G = (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)); table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
for (j = 0; j < Info_h.biClrUsed; j++) { has_color = 0;
for (j = 0; j < Info_h.biClrUsed; j++)
{
table_B[j] = getc(IN); table_B[j] = getc(IN);
table_G[j] = getc(IN); table_G[j] = getc(IN);
table_R[j] = getc(IN); table_R[j] = getc(IN);
getc(IN); getc(IN);
if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j]) has_color +=
gray_scale = 0; !(table_R[j] == table_G[j] && table_R[j] == table_B[j]);
} }
if(has_color) gray_scale = 0;
numcomps = gray_scale ? 1 : 3; numcomps = gray_scale ? 1 : 3;
color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB; color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;
/* initialize image components */ /* initialize image components */
memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
for(i = 0; i < numcomps; i++) { for(i = 0; i < numcomps; i++)
{
cmptparm[i].prec = 8; cmptparm[i].prec = 8;
cmptparm[i].bpp = 8; cmptparm[i].bpp = 8;
cmptparm[i].sgnd = 0; cmptparm[i].sgnd = 0;
@ -669,8 +724,10 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
} }
/* create the image */ /* create the image */
image = opj_image_create(numcomps, &cmptparm[0], color_space); image = opj_image_create(numcomps, &cmptparm[0], color_space);
if(!image) { if(!image)
{
fclose(IN); fclose(IN);
free(table_R); free(table_G); free(table_B);
return NULL; return NULL;
} }
@ -686,75 +743,100 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
fseek(IN, 0, SEEK_SET); fseek(IN, 0, SEEK_SET);
fseek(IN, File_h.bfOffBits, SEEK_SET); fseek(IN, File_h.bfOffBits, SEEK_SET);
RGB = (unsigned char *) malloc(Info_h.biWidth * Info_h.biHeight * sizeof(unsigned char)); 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 (not_end_file) { while(y < H)
v = getc(IN); {
if (v) { c = getc(IN);
v2 = getc(IN);
for (i = 0; i < (int) v; i++) { if (c)
RGB[line * Info_h.biWidth + col] = v2; {
col++; c1 = getc(IN);
for (i = 0; i < c && x < W && pix < beyond; i++, x++, pix++)
*pix = c1;
} }
} else { else
v = getc(IN); {
switch (v) { c = getc(IN);
case 0:
col = 0; if(c == 0x00) /* EOL */
line++; {
x = 0; ++y; pix = RGB + x + (H - y - 1) * W;
}
else
if(c == 0x01) /* EOP */
break; break;
case 1: else
line++; if(c == 0x02) /* MOVE by dxdy */
not_end_file = 0; {
break; c = getc(IN); x += c;
case 2: c = getc(IN); y += c;
fprintf(stderr,"No Delta supported\n"); pix = RGB + (H - y - 1) * W + x;
opj_image_destroy(image);
fclose(IN);
return NULL;
default:
for (i = 0; i < v; i++) {
v2 = getc(IN);
RGB[line * Info_h.biWidth + col] = v2;
col++;
} }
if (v % 2) else /* 03 .. 255 */
v2 = getc(IN); {
break; i = 0;
for(; i < c && x < W && pix < beyond; i++, x++, pix++)
{
c1 = getc(IN);
*pix = c1;
}
if(c & 1) /* skip padding byte */
getc(IN);
} }
} }
} }/* while() */
if (gray_scale) {
index = 0; if (gray_scale)
for (line = 0; line < Info_h.biHeight; line++) { {
for (col = 0; col < Info_h.biWidth; col++) { int *gray;
image->comps[0].data[index] = table_R[(int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]];
index++; gray = image->comps[0].data;
pix = RGB;
max = W * H;
while(max--)
{
uc = *pix++;
*gray++ = table_R[uc];
} }
} }
} else { else
index = 0; {
for (line = 0; line < Info_h.biHeight; line++) { int *red, *green, *blue;
for (col = 0; col < Info_h.biWidth; col++) {
unsigned char pixel_index = (int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]; red = image->comps[0].data;
image->comps[0].data[index] = table_R[pixel_index]; green = image->comps[1].data;
image->comps[1].data[index] = table_G[pixel_index]; blue = image->comps[2].data;
image->comps[2].data[index] = table_B[pixel_index]; pix = RGB;
index++; max = W * H;
}
while(max--)
{
uc = *pix++;
*red++ = table_R[uc];
*green++ = table_G[uc];
*blue++ = table_B[uc];
} }
} }
free(RGB); free(RGB);
free(table_R); free(table_R); free(table_G); free(table_B);
free(table_G); }/* RLE8 */
free(table_B); else
} else { {
fprintf(stderr, fprintf(stderr,
"Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount); "Other system than 24 bits/pixels or 8 bits (no RLE coding) "
"is not yet implemented [%d]\n", Info_h.biBitCount);
} }
fclose(IN); fclose(IN);
}
return image; return image;
} }