On Sat, Aug 09, 2008, Anthony Thyssen wrote:

>   1/ Your patch just completely replaces the Hilbert Curve.
> 
>   2/ Cristy has applied your patch directly, and has now started the
>      release of IM v6.4.2-7.  So that will have FS dither, rather than
>      a Hilbret Curve Dither.
> 
>      This has removed the old dither completely (I have saved a copy)
> 
>      It will also mean that every GIF image in IM Examples will on the
>      next update flag as having changed!! Arrrggghhhh....

   Sorry, I really didn't mean it to happen like that. I hope things can
still be sorted out.

>   3/ It is doing direct ratios of the error, with no 'remainer' to
>      add to the last color being updated.  As such its error distribution
>      and rounding errors.
> 
>      See notes in probably one of the best (and oldest) guides..
>         Dithering and Halftoning  "DHALF.TXT"
> 
>   4/ From that text...
>           Floyd and Steinberg carefully chose this filter so that it
>           would produce a checkerboard pattern in areas with intensity
>           of 1/2.
>      Your Serpentine implementation does NOT provide that effect, but
>      produces columns of pixels.

   I disagree here. Since the code is handling RealPixelPacket variables
there is no practical benefit in handling the rounding error. I once
simulated Floyd-Steinberg on a 50% gray 1000000x1000000 image and even
with floats instead of doubles or long doubles the result was a perfect
checkerboard.

   However, there are indeed several problems right now that cause this
issue. First, my patch was modified and the code that was checked in is
now incorrect:

[...]
           pixel.red+=previous[u-v].red-15*previous[u-v].red/16;
           pixel.green+=previous[u-v].red-15*previous[u-v].green/16;
                                      ^^^ should be "green"
           pixel.blue+=previous[u-v].red-15*previous[u-v].blue/16;
                                     ^^^ should be "blue"
           if (IsAssociatedAlpha(image,cube_info) != MagickFalse)
             pixel.opacity+=previous[u-v].red-15*previous[u-v].opacity/16;
                                          ^^^ should be "opacity"
[...]

   Second, I mistakenly assumed that AcquireQuantumMemory would
zero the memory, which it apparently doesn't do. The following code
is therefore required after the AcquireQuantumMemory() call in
FloydSteinbergDither():

      memset(scanlines, 0, 2*sizeof(*scanlines) * image->columns);

   Third, and I am afraid you are never going to see a perfect
checkerboard until this is dealt with, the IM RealPixelPacket values for
a 50% gray pixel are 32639 instead of 32767. Not sure where to fix that.

> Hmmm it has a fault however...
> 
> Compare the results for the IM examples  alpha_dither_monochrome.gif
> (from IM Examples, Quantization and Dithering,
>   Color Quantization and Transparency
>      http://www.imagemagick.org/Usage/quantize/#color_trans
> 
>   convert xc:red xc:yellow xc:green1 xc:cyan xc:blue \
>           +append -filter Cubic -resize 100x100\!  -size 100x100 \
>           gradient: +matte -compose CopyOpacity -composite alpha_gradient.png
> 
>   convert alpha_gradient.png -channel RGBA -separate \
>           \( +clone -monochrome \) +swap +delete \
>           -combine alpha_dither_monochrome.gif
> 
> The dither starts, but then just seems to die about half way through!
> I have attempted to simplify the above example as yet.
> 
> If you can't see the problem, let me know and I'll post you the images.
> and try to simplify the problem.

   I can reproduce the problem, but I don't really know where to look.
It looks like a problem somewhere else: IsAssociatedAlpha() always
returns false here, so the opacity error is never computed.

Cheers,
-- 
Sam.
_______________________________________________
Magick-developers mailing list
Magick-developers@imagemagick.org
http://studio.imagemagick.org/mailman/listinfo/magick-developers

Reply via email to