Hald Clut interpolation

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
snibgo
Posts: 12897
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Hald Clut interpolation

Post by snibgo »

"-hald-clut" works fine with the default interpolation, which is "bilinear" (actually, tri-linear as a hald clut is 3D).

It is not satisfactory with other interpolation methods, eg "nearest". The problem is that enhance.c HaldClutImage() uses two functions for interpolation: InterpolatePixelInfo() which is sensitive to the interpolation method, and CompositePixelInfoAreaBlend() which always uses linear interpolation.

Fixing this for all interpolations isn't trivial. But a fix for "nearest" is simple. The diff for v7.0.8-64 is:

Code: Select all

--- "distrib\\enhance.c"	2019-09-08 06:16:22.000000000 +0100
+++ "magickcore\\enhance.c"	2019-10-20 15:04:36.856064900 +0100
@@ -2754,7 +2754,8 @@
     for (x=0; x < (ssize_t) image->columns; x++)
     {
       double
-        offset;
+        offset,
+        area;
 
       HaldInfo
         point;
@@ -2784,8 +2785,11 @@
       if (status == MagickFalse)
         break;
       pixel3=zero;
+      area=point.y;
+      if (hald_image->interpolate==NearestInterpolatePixel)
+        area=(point.y<0.5)?0:1;
       CompositePixelInfoAreaBlend(&pixel1,pixel1.alpha,&pixel2,pixel2.alpha,
-        point.y,&pixel3);
+        area,&pixel3);
       offset+=cube_size;
       status=InterpolatePixelInfo(hald_image,hald_view,hald_image->interpolate,
         fmod(offset,width),floor(offset/width),&pixel1,exception);
@@ -2797,10 +2801,13 @@
         break;
       pixel4=zero;
       CompositePixelInfoAreaBlend(&pixel1,pixel1.alpha,&pixel2,pixel2.alpha,
-        point.y,&pixel4);
+        area,&pixel4);
       pixel=zero;
+      area=point.z;
+      if (hald_image->interpolate==NearestInterpolatePixel)
+        area=(point.z<0.5)?0:1;
       CompositePixelInfoAreaBlend(&pixel3,pixel3.alpha,&pixel4,pixel4.alpha,
-        point.z,&pixel);
+        area,&pixel);
       if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
         SetPixelRed(image,ClampToQuantum(pixel.red),q);
       if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)

Sample usage:

Code: Select all

magick toes.png hald:2 -interpolate nearest -hald-clut toes_hald_near.png
Image
snibgo's IM pages: im.snibgo.com

User avatar
magick
Site Admin
Posts: 11216
Joined: 2003-05-31T11:32:55-07:00

Re: Hald Clut interpolation

Post by magick »

Thanks for the patch. We just applied it to the ImageMagick trunk.

Post Reply