GraphicsMagick: MagickSetImagePixels(): Promote image to matte a...

GraphicsMagick Commits <[email protected]> Fri, 24 Jan 2025 09:54:47 -0600
Newsgroups gmane.comp.video.graphicsmagick.cvs
Message-ID <mailman.49670.1737734100.1470.graphicsmagick-commit@lists.sourceforge.net>
changeset b91cc8aa0f26 in /hg/GraphicsMagick
details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=b91cc8aa0f26
summary: MagickSetImagePixels(): Promote image to matte automatically.  Support updating individual channels.

diffstat:

 ChangeLog                              |   8 ++++
 VisualMagick/installer/inc/version.isx |   4 +-
 magick/version.h                       |   4 +-
 wand/magick_wand.c                     |  68 ++++++++++++++++++++++++++++++++-
 www/ChangeLog.html                     |  10 +++++
 www/wand/magick_wand.html              |  12 +++++-
 6 files changed, 97 insertions(+), 9 deletions(-)

diffs (178 lines):

diff -r efac1f4750fb -r b91cc8aa0f26 ChangeLog
--- a/ChangeLog	Fri Jan 17 08:45:42 2025 -0600
+++ b/ChangeLog	Fri Jan 24 09:53:11 2025 -0600
@@ -1,3 +1,11 @@
+2025-01-24  Bob Friesenhahn  <[email protected]>
+
+	* wand/magick_wand.c (MagickSetImagePixels): If update image has
+	matte, then promote canvas image to have matte.  Support composing
+	individual channels 'R', 'G', 'B', 'A', 'O', 'T', 'C', 'M', 'Y',
+	'K'. Intended to address SourceForge issue #752
+	"MagickResizeImage() discarding alpha values".
+
 2025-01-17  Bob Friesenhahn  <[email protected]>
 
 	* tests/rwfile.c: Fix another GCC warning.
diff -r efac1f4750fb -r b91cc8aa0f26 VisualMagick/installer/inc/version.isx
--- a/VisualMagick/installer/inc/version.isx	Fri Jan 17 08:45:42 2025 -0600
+++ b/VisualMagick/installer/inc/version.isx	Fri Jan 24 09:53:11 2025 -0600
@@ -10,5 +10,5 @@
 
 #define public MagickPackageName "GraphicsMagick"
 #define public MagickPackageVersion "1.4"
-#define public MagickPackageVersionAddendum ".020250117"
-#define public MagickPackageReleaseDate "snapshot-20250117"
+#define public MagickPackageVersionAddendum ".020250124"
+#define public MagickPackageReleaseDate "snapshot-20250124"
diff -r efac1f4750fb -r b91cc8aa0f26 magick/version.h
--- a/magick/version.h	Fri Jan 17 08:45:42 2025 -0600
+++ b/magick/version.h	Fri Jan 24 09:53:11 2025 -0600
@@ -38,8 +38,8 @@
 #define MagickLibVersion  0x282502
 #define MagickLibVersionText  "1.4"
 #define MagickLibVersionNumber 28,25,2
-#define MagickChangeDate   "20250117"
-#define MagickReleaseDate  "snapshot-20250117"
+#define MagickChangeDate   "20250124"
+#define MagickReleaseDate  "snapshot-20250124"
 
 /*
   The MagickLibInterfaceNewest and MagickLibInterfaceOldest defines
diff -r efac1f4750fb -r b91cc8aa0f26 wand/magick_wand.c
--- a/wand/magick_wand.c	Fri Jan 17 08:45:42 2025 -0600
+++ b/wand/magick_wand.c	Fri Jan 24 09:53:11 2025 -0600
@@ -9185,15 +9185,24 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  MagickSetImagePixels() accepts pixel data and stores it in the image at the
-%  location you specify.  The method returns False on success otherwise True
+%  location you specify.  The method returns False on success, otherwise True
 %  if an error is encountered.  The pixel data can be either char, short int,
 %  int, long, float, or double in the order specified by map.
 %
-%  Suppose your want want to upload the first scanline of a 640x480 image from
+%  Suppose you want to upload the first scanline of a 640x480 image from
 %  character data in red-green-blue order:
 %
 %      MagickSetImagePixels(wand,0,0,0,640,1,"RGB",CharPixel,pixels);
 %
+%  The API user is responsible for assuring that pixels in the entire
+%  image are initialized properly.  If non-opaque pixels are to be
+%  supported (e.g. "RGBA") but the image does not already have an
+%  opacity channel (e.g. MagickGetImageMatte() returns False), please use
+%  MagickSetImageMatte() to set Matte true, and then assure that the
+%  opacity channel is initialized for all of the pixels.  This is necessary
+%  even if the region specified to MagickSetImagePixels() includes the
+%  entire image.
+%
 %  The format of the MagickSetImagePixels method is:
 %
 %       unsigned int MagickSetImagePixels(MagickWand *wand,
@@ -9251,7 +9260,60 @@
     ConstituteImage(columns,rows,map,storage,pixels,&image->exception);
   if (constitute_image)
     {
-      (void) CompositeImage(image,CopyCompositeOp,constitute_image,x_offset,
+      CompositeOperator
+        compose = CopyCompositeOp;
+
+      /*
+        Support the ability to update an individual image channel
+        (e.g. 'A').  This is not efficient given that it requires
+        creating a whole image.
+
+        FIXME: It would be nice to support updating arbitrary
+        combinations of channels (e.g. "BG", "R", "A") via multiple
+        calls.  This requires a special purpose implementation rather
+        than using CompositeImage().
+      */
+      if (strlen(map) == 1)
+        {
+          switch (map[0])
+            {
+            case 'R':
+              compose = CopyRedCompositeOp;
+              break;
+            case 'G':
+              compose = CopyGreenCompositeOp;
+              break;
+            case 'B':
+              compose = CopyBlueCompositeOp;
+              break;
+            case 'A':
+            case 'O':
+            case 'T':
+              compose = CopyOpacityCompositeOp;
+              break;
+            case 'C':
+              compose = CopyCyanCompositeOp;
+              break;
+            case 'M':
+              compose = CopyMagentaCompositeOp;
+              break;
+            case 'Y':
+              compose = CopyYellowCompositeOp;
+              break;
+            case 'K':
+              compose = CopyBlackCompositeOp;
+              break;
+            default:
+              {
+              }
+            }
+        }
+
+      if (constitute_image->matte && !image->matte)
+        {
+          image->matte = constitute_image->matte;
+        }
+      (void) CompositeImage(image,compose,constitute_image,x_offset,
                             y_offset);
       DestroyImage(constitute_image);
       status = (image->exception.severity == UndefinedException);
diff -r efac1f4750fb -r b91cc8aa0f26 www/ChangeLog.html
--- a/www/ChangeLog.html	Fri Jan 17 08:45:42 2025 -0600
+++ b/www/ChangeLog.html	Fri Jan 24 09:53:11 2025 -0600
@@ -38,6 +38,16 @@
 
 <main id="graphicsmagick-changelog">
 <h1 class="title">GraphicsMagick ChangeLog</h1>
+<p>2025-01-24  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><p>wand/magick_wand.c (MagickSetImagePixels): If update image has
+matte, then promote canvas image to have matte.  Support composing
+individual channels 'R', 'G', 'B', 'A', 'O', 'T', 'C', 'M', 'Y',
+'K'. Intended to address SourceForge issue #752
+&quot;MagickResizeImage() discarding alpha values&quot;.</p></li>
+</ul>
+</blockquote>
 <p>2025-01-17  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
 <blockquote>
 <ul class="simple">
diff -r efac1f4750fb -r b91cc8aa0f26 www/wand/magick_wand.html
--- a/www/wand/magick_wand.html	Fri Jan 17 08:45:42 2025 -0600
+++ b/www/wand/magick_wand.html	Fri Jan 24 09:53:11 2025 -0600
@@ -5234,12 +5234,20 @@
 <section id="id388">
 <h2>Description</h2>
 <p>MagickSetImagePixels() accepts pixel data and stores it in the image at the
-location you specify.  The method returns False on success otherwise True
+location you specify.  The method returns False on success, otherwise True
 if an error is encountered.  The pixel data can be either char, short int,
 int, long, float, or double in the order specified by map.</p>
-<p>Suppose your want want to upload the first scanline of a 640x480 image from
+<p>Suppose you want to upload the first scanline of a 640x480 image from
 character data in red-green-blue order:</p>
 <p>MagickSetImagePixels(wand,0,0,0,640,1,&quot;RGB&quot;,CharPixel,pixels);</p>
+<p>The API user is responsible for assuring that pixels in the entire
+image are initialized properly.  If non-opaque pixels are to be
+supported (e.g. &quot;RGBA&quot;) but the image does not already have an
+opacity channel (e.g. MagickGetImageMatte() returns False), please use
+MagickSetImageMatte() to set Matte true, and then assure that the
+opacity channel is initialized for all of the pixels.  This is necessary
+even if the region specified to MagickSetImagePixels() includes the
+entire image.</p>
 <p>The format of the MagickSetImagePixels method is:</p>
 <pre class="literal-block">unsigned int MagickSetImagePixels( MagickWand *wand, const long x_offset, const long y_offset,
                                    const unsigned long columns, const unsigned long rows,