Page 1 of 1

v7 JPEG 2K generation problem

Posted: 2014-01-12T07:38:38-07:00
by ptitera
I think there is an error in JPEG 2K generation in current trunk version. Generated image is without colors and only one third of it is displayed

The problem is in generation of component data in WriteJP2Image function. After each pixel is generated pointer to next pixel is incremented by one,

Code: Select all

    for (x=0; x < (ssize_t) image->columns; x++)
    {
      for (i=0; i < (ssize_t) channels; i++)
      {
        double
          scale;

        register int
          *q;

        scale=(double) ((1UL << jp2_image->comps[i].prec)-1)/QuantumRange;
        q=jp2_image->comps[i].data+(y/jp2_image->comps[i].dy*
          image->columns/jp2_image->comps[i].dx+x/jp2_image->comps[i].dx);
        switch (i)
        {
          case 0:
          {
            if (jp2_colorspace == OPJ_CLRSPC_GRAY)
              {
                *q=(int) (scale*GetPixelLuma(image,p));
                break;
              }
            *q=(int) (scale*GetPixelRed(image,p));
            break;
          }
          case 1:
          {
            if (jp2_colorspace == OPJ_CLRSPC_GRAY)
              {
                *q=(int) (scale*GetPixelAlpha(image,p));
                break;
              }
            *q=(int) (scale*GetPixelGreen(image,p));
            break;
          }
          case 2:
          {
            *q=(int) (scale*GetPixelBlue(image,p));
            break;
          }
          case 3:
          {
            *q=(int) (scale*GetPixelAlpha(image,p));
            break;
          }
        }
      }
      p++;
    }
but this will bring in only to next Quantum of already processed Pixel. I think this pointer has to be incremented by number of channels in image. Something like this gives me correct results:

Code: Select all

    for (x=0; x < (ssize_t) image->columns; x++)
    {
      for (i=0; i < (ssize_t) channels; i++)
      {
        double
          scale;

        register int
          *q;

        scale=(double) ((1UL << jp2_image->comps[i].prec)-1)/QuantumRange;
        q=jp2_image->comps[i].data+(y/jp2_image->comps[i].dy*
          image->columns/jp2_image->comps[i].dx+x/jp2_image->comps[i].dx);
        switch (i)
        {
          case 0:
          {
            if (jp2_colorspace == OPJ_CLRSPC_GRAY)
              {
                *q=(int) (scale*GetPixelLuma(image,p));
                break;
              }
            *q=(int) (scale*GetPixelRed(image,p));
            break;
          }
          case 1:
          {
            if (jp2_colorspace == OPJ_CLRSPC_GRAY)
              {
                *q=(int) (scale*GetPixelAlpha(image,p));
                break;
              }
            *q=(int) (scale*GetPixelGreen(image,p));
            break;
          }
          case 2:
          {
            *q=(int) (scale*GetPixelBlue(image,p));
            break;
          }
          case 3:
          {
            *q=(int) (scale*GetPixelAlpha(image,p));
            break;
          }
        }
      }
      p += channels;
    }
But I do not know if this is correct solution.

Re: v7 JPEG 2K generation problem

Posted: 2014-01-12T09:49:22-07:00
by magick
We can reproduce the problem you posted and have a patch in ImageMagick 7.0.0-0 Beta. Thanks.

Re: v7 JPEG 2K generation problem

Posted: 2014-01-12T10:50:11-07:00
by ptitera
There are couple more problems with JP2K writing:
  • jp2:quality and jp2:rate options handling is wrong. There is off-by-one error when quality and rate arrays are set. Something like this is required for on both places (I do not know if this is correct fix. My C is very rusty)

    Code: Select all

      if (option != (const char *) NULL)
        {
          register const char
            *p;
    
          /*
            Set compression rate.
          */
          p=option;
          for (i=0; sscanf(p,"%f",&parameters.tcp_rates[i]) == 1; i++)
          {
            if (i >= 100)
              break;
            while ((*p != '\0') && (*p != ','))
              p++;
            if (*p == '\0')
              break;
            p++;
          }
          parameters.tcp_numlayers=i+1;
          parameters.cp_disto_alloc=OPJ_TRUE;
        }
    
  • If I use JPEG as source image, its embedded quality option will override jp2:rate option completely. I think that quality from source image should be used only when no other quality affecting setting was set.
  • jp2:rate values use different logic than in version 6. I know that this is defined on website but I do not know how you handle this kind of parameter logic change
Petr Titera

Re: v7 JPEG 2K generation problem

Posted: 2014-01-12T12:30:54-07:00
by magick
We can reproduce the problem you posted and have a patch in ImageMagick 7.0.0-0 Beta, available in an hour or two. Thanks.