Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

image->numcomps > 4 #333

Closed
gcode-importer opened this issue Apr 4, 2014 · 4 comments
Closed

image->numcomps > 4 #333

gcode-importer opened this issue Apr 4, 2014 · 4 comments
Assignees

Comments

@gcode-importer
Copy link

Originally reported on Google Code with ID 333

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

Reported by szukw000 on 2014-04-04 20:18:04

@gcode-importer
Copy link
Author

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

Reported by szukw000 on 2014-04-05 12:07:50

@gcode-importer
Copy link
Author

Cnf. my proposal in Issue 254 Comment #13.

winfried

Reported by szukw000 on 2014-04-26 20:21:42

@gcode-importer
Copy link
Author

Reported by malaterre on 2014-04-28 07:47:12

  • Labels added: Priority-Low
  • Labels removed: Priority-Medium

@rouault
Copy link
Collaborator

rouault commented Sep 2, 2017

@rouault rouault closed this as completed Sep 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants