The specification ISO/IEC 15444-1:2002 (E) says
and in Table I.16 (page 143):
typ[i] == 0 : Colour typ[i] == 1 : Opacity typ[i] == 2 : Premultiplied opacity typ[i] == 3 ... 65534: Reserved for ISO use typ[i] == 65535 : The type of this channel is not specified
and in Table I.17 (page 143):
asoc[i] == 0 : This channel is associated as the image as a whole asoc[i] == 1 .. 65534: This channel is associated with a particular colour as indicated by this value. asoc[i] == 65535 : This channel is not associated with any particular colour.
"There shall not be more than one channel in a JP2 file with a the same Typ[i] and Asoc[i] value pair, with the exception of Typ[i] and Asoc[i] values of 2^(16) 1 (not specified)."(page 144)
NOTE: "2^(16) 1" is 65535.
This means:
typ[i] == 65535 and asoc[i] == 65535 must be skipped.
image->comps[cn].alpha = (info[i].typ == 1);
File '5C-cdef.jp2' has the following values:
n(6)
CDEF[0]cn(4) typ(0) asoc(1)
CDEF[1]cn(2) typ(0) asoc(2)
CDEF[2]cn(3) typ(0) asoc(3)
CDEF[3]cn(0) typ(1) asoc(1)
CDEF[4]cn(0) typ(1) asoc(2)
CDEF[5]cn(1) typ(1) asoc(3)
numcomps(5)
IMAGE[0]w(128) w(128) alpha(0)
IMAGE[1]w(128) w(128) alpha(0)
IMAGE[2]w(128) w(128) alpha(0)
IMAGE[3]w(128) w(128) alpha(1)
IMAGE[4]w(128) w(128) alpha(1)
But '18_1805_a4_2.jp2' of issue327 has the following values:
n(5)
CDEF[0]cn(0) typ(0) asoc(1)
CDEF[1]cn(1) typ(0) asoc(2)
CDEF[2]cn(2) typ(0) asoc(3)
CDEF[3]cn(3) typ(1) asoc(0)
CDEF[4]cn(4) typ(65535) asoc(5)
numcomps(5)
IMAGE[0]w(300) w(400) alpha(0)
IMAGE[1]w(300) w(400) alpha(0)
IMAGE[2]w(300) w(400) alpha(0)
IMAGE[3]w(300) w(400) alpha(1)
IMAGE[4]w(300) w(400) alpha(65535)
winfried
Comment #1
Posted on Nov 14, 2014 by Quick LionWinfried,
The resulting op_image_t is "wrong"/misleading in both cases.
5C-cdef.jp2 has per channel alpha ( 1 alpha channel for color 1 & 2 + 1 alpha channel for color 3). This information is lost in opj_image_t. The goal of issue 414 was to get at least color channels in the proper order. There's no way to get the information missing back. At least with image from issue 327, one can infer that alpha value of 65535 is an auxiliary channel that can be dismissed (or kept by specific applications).
What you're asking, if I understand correctly, is to get alpha = 0 for type 65535 / asoc 65535 ?
Comment #2
Posted on Nov 15, 2014 by Grumpy ElephantHere is my proposal:
void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color) { opj_jp2_cdef_info_t *info; OPJ_UINT16 i, j, n, cn, asoc, acn, last, typ;
info = color->jp2_cdef->info;
n = color->jp2_cdef->n;
for(i = 0; i < n; ++i)
{ if(info[i].asoc != 65535 && info[i].typ != 65535) continue;
opj_free(image->comps[i].data);
image->comps[i].data = NULL;
last = n - 1;
for(j = i; j < last; ++j)
{ image->comps[j] = image->comps[j+1]; info[j] = info[j+1]; } --n; --color->jp2_cdef->n; --image->numcomps; }
for(i = 0; i < n; ++i)
{ /* WATCH: acn = asoc - 1 ! */ asoc = info[i].asoc; typ = info[i].typ;
image->comps[i].alpha = (typ == 1);
if(typ == 1) continue;
if(asoc == 0) continue;
cn = info[i].cn;
acn = (OPJ_UINT16)(asoc - 1);
if( cn >= image->numcomps || acn >= image->numcomps )
{ fprintf(stderr, "\tINFO[%d]cn=%d, acn=%d, numcomps=%d: SKIP.\n", i,cn, acn, image->numcomps); continue; }
if(cn != acn && typ == 0)
{ opj_image_comp_t saved;
memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
info[i].asoc = (OPJ_UINT16)(cn + 1);
info[acn].asoc = (OPJ_UINT16)(info[acn].cn + 1);
} } //MARK1 if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
}/* jp2_apply_cdef() */
In the line marked with '//MARK1' one could add e.g.: for(i = 4; i < n; ++i) { opj_free(image->comps[i].data); image->comps[i].data = NULL;
last = n - 1;
for(j = i; j < last; ++j)
{ image->comps[j] = image->comps[j+1]; info[j] = info[j+1]; } --n; --color->jp2_cdef->n; --image->numcomps; }
So the resulting 'image->numcomps' can never be larger than 4. Otherwise the code for applications using ALPHA (e.g. 'imagetopng()') must be changed, e.g.
numcomps = image->numcomps; if(numcomps > 4) numcomps = 4;
winfried
Comment #3
Posted on Nov 18, 2014 by Grumpy ElephantHere is the patch for changing the numcomps value in the binaries.
winfried
- convert.c.dif 4.8KB
Status: Accepted
Labels:
Type-Defect
Priority-Medium