Page 1 of 1

Different output between 6.3.3 Q8 and 6.3.3 Q16

Posted: 2007-03-18T11:56:09-07:00
by rmagick
This may be the expected behavior but I want to confirm it before I respond to the RMagick user who reported it. There is an example C program at the bottom of this post. When built with 6.3.3-1 Q16 it produces this image:
Image

When I build the example program with 6.3.3-1 Q8 it produces this image:
Image

Is this the expected behavior? If so, is there a workaround to get the Q8 version to produce an image closer to the Q16 version of the image?

Here's the input image "bolilla.png" for this test: Image

Code: Select all

/*
gcc `Magick-config --cflags --cppflags` tbe.c `Magick-config --ldflags --libs` -o tbe
*/
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <magick/api.h>


int main(int argc, char **argv)
{
    Image *click_image, *image;
    ImageInfo *image_info;
    ExceptionInfo exception;
    MagickBooleanType okay;
    PixelPacket white;
    unsigned long version;
    char name[50];
    int x;

    InitializeMagick("Test");
    (void) GetMagickVersion(&version);

    GetExceptionInfo(&exception);
    okay = QueryColorDatabase("white", &white, &exception);
    if (!okay)
    {
        MagickFatalError(exception.severity, exception.reason, exception.description);
    }

    image_info=CloneImageInfo((ImageInfo *) NULL);
    strcpy(image_info->filename, "bolilla.png");

    GetExceptionInfo(&exception);

    click_image = ReadImage(image_info, &exception);
    if (exception.severity != UndefinedException)
    {
      MagickFatalError(exception.severity, exception.reason, exception.description);
    }

    image = ColorizeImage(click_image, "97/97/97", white, &exception);
    if (!image)
    {
        MagickFatalError(exception.severity, exception.reason, exception.description);
    }
    DestroyImage(click_image);
    click_image = image;

    DestroyImageInfo(image_info);
    image_info=CloneImageInfo((ImageInfo *) NULL);
    image_info->size = AcquireMemory(sizeof("100x300"));
    strcpy(image_info->size, "100x300");

    okay = QueryColorDatabase("white", &image_info->background_color, &exception);
    if (!okay)
    {
        MagickFatalError(exception.severity, exception.reason, exception.description);
    }

    image_info->background_color = white;

    image = AllocateImage(image_info);
    if (image == (Image *) NULL)
    {
        MagickFatalError(ResourceLimitError, "Unable to allocate image", "Memory allocation failed");
    }

    // (void) SetImageBackgroundColor(image); not available in 6.0.6
    (void) SetImage(image, OpaqueOpacity);

    // Here's the meat
    for (x = 0; x < 50; x++)
    {
        (void) CompositeImage(image, MultiplyCompositeOp, click_image, 20, 30);
        if (exception.severity != UndefinedException)
        {
          MagickFatalError(exception.severity, exception.reason, exception.description);
        }
    }

    NegateImage(image, MagickFalse);

    DestroyImageInfo(image_info);
    image_info = CloneImageInfo((ImageInfo *) NULL);

    sprintf(name, "tbe_output-%3lx.png", version);
    strcpy(image_info->filename, name);
    strcpy(image->filename, image_info->filename);
    WriteImage(image_info, image);

    (void) DestroyExceptionInfo(&exception);
    (void) DestroyImage(image);
    (void) DestroyImage(click_image);
    (void) DestroyImageInfo(image_info);
    (void) DestroyMagick();

    return 0;
}

Re: Different output between 6.3.3 Q8 and 6.3.3 Q16

Posted: 2007-03-20T11:45:57-07:00
by magick
The problem appears to be cumulative round-off error. You can visualize the effect by varying the composite loop from 10 to 50 by 10. Each step introduces additional quantization levels for the Q8 version. We assume the Q32 version of ImageMagick would have a smoother gradient than the Q16 version. The solution may be in an upcoming release where we permit floating point pixels for Q8 and Q16 pixel component depts. This provides for smoother transitions for algorithms such as the one you present here.

Re: Different output between 6.3.3 Q8 and 6.3.3 Q16

Posted: 2007-03-20T12:57:41-07:00
by tbe
magick,

I'm the rmagick user who first reported this problem. When could I expect this new release?

Re: Different output between 6.3.3 Q8 and 6.3.3 Q16

Posted: 2007-03-20T18:32:59-07:00
by anthony
Don't hold your breath.

Cristy is swamped with 'todo' itmes. He also give priority to bugs, rather than new features. SVG gradients and perspective distortions for examples have been waiting to be added for some time.

If other users would like to help, please grab the source and create a patch. If cristy finds your work acceptabe, and you are keen to continue, you can also get direct SVN update access.

I myself have SVN update access, and use it to fix some problems. I also do the occasional update to the command line options description page.

Right now I am looking at the additions needed for GIF animation improvements. Such as...
  • simple transparency optimization,
  • -reverse and -shuffle image sequence ordering,
  • RemoveDups and RemoveZeroDelay -layer frame removal options,
  • and image sequence alpha composition (overlay static source, overlay onto static destination, paired image composition).
All of which I talk about in IM Examples.

Hmmm sorry for the rant, but it was time for an FYI, so you have no illusions about what is happening.

Re: Different output between 6.3.3 Q8 and 6.3.3 Q16

Posted: 2007-03-20T18:37:44-07:00
by magick
Floating point support will take some time. We're 95% there but like Anthony mentioned, bug reports and high priority enhancements take priority over new features.