Open GoogleCodeExporter opened 9 years ago
Winfried,
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 ?
Original comment by m.darb...@gmail.com
on 14 Nov 2014 at 9:50
Here 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
Original comment by szukw...@arcor.de
on 15 Nov 2014 at 3:43
Here is the patch for changing the numcomps value in the binaries.
winfried
Original comment by szukw...@arcor.de
on 18 Nov 2014 at 8:18
Attachments:
Original issue reported on code.google.com by
szukw...@arcor.de
on 9 Nov 2014 at 1:29