ylb11 / openjpeg

Automatically exported from code.google.com/p/openjpeg
Other
0 stars 0 forks source link

issue414 revisited #426

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
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

Original issue reported on code.google.com by szukw...@arcor.de on 9 Nov 2014 at 1:29

GoogleCodeExporter commented 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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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: