xuewend / openjpeg

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

image->numcomps > 4 #333

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
In Issue 327 one can find the image '18_1805_a4_2.jp2'.

------------ start cdef -------------------
[0]c(0) typ(0) asoc(1)
[1]c(1) typ(0) asoc(2)
[2]c(2) typ(0) asoc(3)
[3]c(3) typ(1) asoc(0)
[4]c(4) typ(65535) asoc(5)
------------ end cdef ---------------------

These cdef values mean: three RGB channels (type == 0) and
one alpha channel (type == 1).

But openjpeg-2.x-trunk-r2833 reads 5 numcomps:

 * in j2k.c the SIZ marker has a value of 5 for CSIZ.

 * in jp2.c, opj_jp2_read_cdef() and opj_jp2_apply_cdef()
   accept 5 numcomps.

In convert.c the confusion is perfect.

Here is the code of

>void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
>{
>   opj_jp2_cdef_info_t *info;
>   OPJ_UINT16 i, n, cn, asoc, acn;
>
>   info = color->jp2_cdef->info;
>   n = color->jp2_cdef->n;
>
>  for(i = 0; i < n; ++i)
>    {
>    /* WATCH: acn = asoc - 1 ! */
>    asoc = info[i].asoc;
>    if(asoc == 0 || asoc == 65535)
>      {
>      if (i < image->numcomps)
>        image->comps[i].alpha = info[i].typ;
>      continue;
>      }

     if(asoc == 65535 || info[i].typ == 65535) continue;

     image->comps[i].alpha = (asoc == 0 && info[i].typ == 1);

>    cn = info[i].cn;
>    acn = (OPJ_UINT16)(asoc - 1);
>    if( cn >= image->numcomps || acn >= image->numcomps )
>      {
>      fprintf(stderr, "cn=%d, acn=%d, numcomps=%d\n", cn, acn, 
image->numcomps);
>      continue;
>      }
>
>       if(cn != acn)
>       {
>           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);
>       }
>
>       image->comps[cn].alpha = info[i].typ;

        image->comps[cn].alpha = (info[i].typ == 1);/* Opacity */

>   }
>
>   if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
>
>   opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
>
>}/* jp2_apply_cdef() */

The line

 if(asoc == 65535 || info[i].typ == 65535) continue;

should

 * remove the image->comps[i] completely

 * reduce the image->numcomps by one

Table I.18 in ISO/IEC 15444-1:2002 (E) shows that only CMYK
(and RGBA) has 4 values.

The 'kdu_show' image is sharp and clear. The 'opj_decompress'
images are blurred. Could this be a result of the 5th component?

winfried

Original issue reported on code.google.com by szukw...@arcor.de on 4 Apr 2014 at 8:18

GoogleCodeExporter commented 8 years ago
Here is my proposal for :

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;

    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;

    image->comps[i].alpha = (asoc == 0 && info[i].typ == 1);

    if(asoc == 0) continue;/* Opacity */

    cn = info[i].cn;
    acn = (OPJ_UINT16)(asoc - 1);
    if( cn >= image->numcomps || acn >= image->numcomps )
      {
      fprintf(stderr, "cn=%d, acn=%d, numcomps=%d\n", cn, acn, image->numcomps);
      continue;
      }

        if(cn != acn)
        {
            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);
        }
    }

    if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);

    opj_free(color->jp2_cdef); color->jp2_cdef = NULL;

}/* jp2_apply_cdef() */

For the image '18_1805_a4_2.jp2' I now get 4 numcomps (R, G, B, Alpha).
But the resulting image of 'opj_decompress' remains blurred.

winfried

Original comment by szukw...@arcor.de on 5 Apr 2014 at 12:07

GoogleCodeExporter commented 8 years ago
Cnf. my proposal in Issue 254 Comment #13.

winfried

Original comment by szukw...@arcor.de on 26 Apr 2014 at 8:21

GoogleCodeExporter commented 8 years ago

Original comment by mathieu.malaterre on 28 Apr 2014 at 7:47