summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathieu Malaterre <mathieu.malaterre@gmail.com>2012-05-29 13:55:49 +0000
committerMathieu Malaterre <mathieu.malaterre@gmail.com>2012-05-29 13:55:49 +0000
commit0d0e7a1008e9ef3b7af2558cb5f0553626461862 (patch)
tree928f7abce726022158e6071b810ca2de43b875b0
parent806545df34b2e56e8dc9424e8c4496f40e0d57e2 (diff)
[trunk] The two files in Issue145 have a precision < 8-bit:
therefore 'jp2_read_pclr' must be changed. j2k_to_image fails to create RGB/RGBA images with a precision < 8-bit: therefore 'imagetopng' must be changed. Fixes issue 145
-rw-r--r--applications/codec/convert.c90
-rw-r--r--libopenjpeg/jp2.c9
2 files changed, 68 insertions, 31 deletions
diff --git a/applications/codec/convert.c b/applications/codec/convert.c
index dee780d4..59af469b 100644
--- a/applications/codec/convert.c
+++ b/applications/codec/convert.c
@@ -3277,18 +3277,27 @@ int imagetopng(opj_image_t * image, const char *write_idf)
int *red, *green, *blue, *alpha;
unsigned char *row_buf, *d;
int has_alpha, width, height, nr_comp, color_type;
- int adjustR, adjustG, adjustB, x, y, fails, is16, force16;
- int opj_prec, prec, ushift, dshift;
+ int adjustR, adjustG, adjustB, adjustA, x, y, fails;
+ int prec, ushift, dshift, is16, force16, force8;
unsigned short mask = 0xffff;
png_color_8 sig_bit;
- is16 = force16 = ushift = dshift = 0; fails = 1;
- prec = opj_prec = image->comps[0].prec;
+ is16 = force16 = force8 = ushift = dshift = 0; fails = 1;
+ prec = image->comps[0].prec;
+ nr_comp = image->numcomps;
if(prec > 8 && prec < 16)
{
- prec = 16; force16 = 1;
+ ushift = 16 - prec; dshift = prec - ushift;
+ prec = 16; force16 = 1;
}
+ else
+ if(prec < 8 && nr_comp > 1)/* GRAY_ALPHA, RGB, RGB_ALPHA */
+ {
+ ushift = 8 - prec; dshift = 8 - ushift;
+ prec = 8; force8 = 1;
+ }
+
if(prec != 1 && prec != 2 && prec != 4 && prec != 8 && prec != 16)
{
fprintf(stderr,"imagetopng: can not create %s"
@@ -3336,6 +3345,14 @@ int imagetopng(opj_image_t * image, const char *write_idf)
* PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
* currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE.
* REQUIRED
+ *
+ * ERRORS:
+ *
+ * color_type == PNG_COLOR_TYPE_PALETTE && bit_depth > 8
+ * color_type == PNG_COLOR_TYPE_RGB && bit_depth < 8
+ * color_type == PNG_COLOR_TYPE_GRAY_ALPHA && bit_depth < 8
+ * color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8
+ *
*/
png_set_compression_level(png, Z_BEST_COMPRESSION);
@@ -3349,8 +3366,6 @@ int imagetopng(opj_image_t * image, const char *write_idf)
else
if(prec == 1) mask = 0x0001;
- nr_comp = image->numcomps;
-
if(nr_comp >= 3
&& image->comps[0].dx == image->comps[1].dx
&& image->comps[1].dx == image->comps[2].dx
@@ -3379,11 +3394,13 @@ int imagetopng(opj_image_t * image, const char *write_idf)
sig_bit.alpha = prec;
alpha = image->comps[3].data;
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ adjustA = (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
}
else
{
sig_bit.alpha = 0; alpha = NULL;
color_type = PNG_COLOR_TYPE_RGB;
+ adjustA = 0;
}
png_set_sBIT(png, info, &sig_bit);
@@ -3391,18 +3408,13 @@ int imagetopng(opj_image_t * image, const char *write_idf)
color_type,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
/*=============================*/
png_write_info(png, info);
/*=============================*/
- if(opj_prec < 8)
+ if(prec < 8)
{
png_set_packing(png);
}
- if(force16)
- {
- ushift = 16 - opj_prec; dshift = opj_prec - ushift;
- }
adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
@@ -3437,21 +3449,40 @@ int imagetopng(opj_image_t * image, const char *write_idf)
if(has_alpha)
{
- v = *alpha++;
+ v = *alpha + adjustA; ++alpha;
if(force16) { v = (v<<ushift) + (v>>dshift); }
*d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
}
continue;
- }
- *d++ = (unsigned char)((*red + adjustR) & mask); ++red;
- *d++ = (unsigned char)((*green + adjustG) & mask); ++green;
- *d++ = (unsigned char)((*blue + adjustB) & mask); ++blue;
+ }/* if(is16) */
+
+ v = *red + adjustR; ++red;
+
+ if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+ *d++ = (unsigned char)(v & mask);
+
+ v = *green + adjustG; ++green;
+
+ if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+ *d++ = (unsigned char)(v & mask);
+
+ v = *blue + adjustB; ++blue;
+
+ if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+ *d++ = (unsigned char)(v & mask);
if(has_alpha)
{
- *d++ = (unsigned char)(*alpha & mask); ++alpha;
+ v = *alpha + adjustA; ++alpha;
+
+ if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+ *d++ = (unsigned char)(v & mask);
}
} /* for(x) */
@@ -3472,13 +3503,9 @@ int imagetopng(opj_image_t * image, const char *write_idf)
red = image->comps[0].data;
- if(force16)
- {
- ushift = 16 - opj_prec; dshift = opj_prec - ushift;
- }
sig_bit.gray = prec;
sig_bit.red = sig_bit.green = sig_bit.blue = sig_bit.alpha = 0;
- alpha = NULL;
+ alpha = NULL; adjustA = 0;
color_type = PNG_COLOR_TYPE_GRAY;
if(nr_comp == 2)
@@ -3486,6 +3513,7 @@ int imagetopng(opj_image_t * image, const char *write_idf)
has_alpha = 1; sig_bit.alpha = prec;
alpha = image->comps[1].data;
color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+ adjustA = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
}
width = image->comps[0].w;
height = image->comps[0].h;
@@ -3501,7 +3529,7 @@ int imagetopng(opj_image_t * image, const char *write_idf)
/*=============================*/
adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
- if(opj_prec < 8)
+ if(prec < 8)
{
png_set_packing(png);
}
@@ -3547,11 +3575,19 @@ int imagetopng(opj_image_t * image, const char *write_idf)
for(x = 0; x < width; ++x)
{
- *d++ = (unsigned char)((*red + adjustR) & mask); ++red;
+ v = *red + adjustR; ++red;
+
+ if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+ *d++ = (unsigned char)(v & mask);
if(has_alpha)
{
- *d++ = (unsigned char)(*alpha & mask); ++alpha;
+ v = *alpha + adjustA; ++alpha;
+
+ if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+ *d++ = (unsigned char)(v & mask);
}
}/* for(x) */
diff --git a/libopenjpeg/jp2.c b/libopenjpeg/jp2.c
index c4cc9fe9..73744f7e 100644
--- a/libopenjpeg/jp2.c
+++ b/libopenjpeg/jp2.c
@@ -1160,7 +1160,7 @@ static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
for(i = 0; i < nr_channels; ++i)
{
/* Cji */
- *entries++ = cio_read(cio, channel_size[i]>>3);
+ *entries++ = cio_read(cio, (channel_size[i]+7)>>3);
}
}
@@ -1230,9 +1230,10 @@ opj_bool jp2_read_pclr_v2( opj_jp2_v2_t *jp2,
for(j = 0; j < nr_entries; ++j) {
for(i = 0; i < nr_channels; ++i) {
- /**entries++ = cio_read(cio, channel_size[i]>>3); */
- opj_read_bytes(p_pclr_header_data, &l_value , channel_size[i]>>3); /* Cji */
- p_pclr_header_data += channel_size[i]>>3;
+ int bytes_to_read = (channel_size[i]+7)>>3;
+
+ opj_read_bytes(p_pclr_header_data, &l_value , bytes_to_read); /* Cji */
+ p_pclr_header_data += bytes_to_read;
*entries = (OPJ_UINT32) l_value;
entries++;
}