Commit ac86143c9 for imagemagick.org

commit ac86143c9b4c30931ed11441941e3081d2de4fa9
Author: Dirk Lemstra <dirk@lemstra.org>
Date:   Sat Nov 7 14:59:34 2026 +0100

    Buffer CIP pixel output per row.

diff --git a/coders/cip.c b/coders/cip.c
index 1a29193a3..67378bdbe 100644
--- a/coders/cip.c
+++ b/coders/cip.c
@@ -166,6 +166,7 @@ static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image,
     *escaped;

   const char
+    *hex_digits="0123456789abcdef",
     *value;

   MagickBooleanType
@@ -174,6 +175,9 @@ static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image,
   const Quantum
     *p;

+  size_t
+    row_extent;
+
   ssize_t
     i,
     x;
@@ -182,7 +186,9 @@ static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image,
     y;

   unsigned char
-    byte;
+    byte,
+    *pixels,
+    *q;

   /*
     Open output image file.
@@ -228,11 +234,23 @@ static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image,
   (void) WriteBlobString(image,"<Data>");
   if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
     (void) TransformImageColorspace(image,sRGBColorspace,exception);
+  row_extent=image->columns/4;
+  if (row_extent > ((size_t) MAGICK_SSIZE_MAX-2*sizeof(unsigned int))/2)
+    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+  /* Allow space for the existing trailing-byte hexadecimal formatting. */
+  row_extent=2*row_extent+2*sizeof(unsigned int);
+  pixels=(unsigned char *) AcquireQuantumMemory(row_extent,sizeof(*pixels));
+  if (pixels == (unsigned char *) NULL)
+    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   for (y=0; y < (ssize_t) image->rows; y++)
   {
     p=GetVirtualPixels(image,0,y,image->columns,1,exception);
     if (p == (const Quantum *) NULL)
-      break;
+      {
+        status=MagickFalse;
+        break;
+      }
+    q=pixels;
     for (x=0; x < ((ssize_t) image->columns-3); x+=4)
     {
       byte=(unsigned char)
@@ -240,8 +258,8 @@ static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image,
          (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+2*GetPixelChannels(image)))/QuantumRange) & 0x03) << 4) |
          (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+1*GetPixelChannels(image)))/QuantumRange) & 0x03) << 2) |
          (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+0*GetPixelChannels(image)))/QuantumRange) & 0x03) << 0));
-      (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",byte);
-      (void) WriteBlobString(image,buffer);
+      *q++=(unsigned char) hex_digits[byte >> 4];
+      *q++=(unsigned char) hex_digits[byte & 0x0f];
       p+=(ptrdiff_t) GetPixelChannels(image);
     }
     if ((image->columns % 4) != 0)
@@ -283,13 +301,20 @@ static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image,
           }
         }
         (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",~byte);
-        (void) WriteBlobString(image,buffer);
+        (void) memcpy(q,buffer,strlen(buffer));
+        q+=strlen(buffer);
+      }
+    if (WriteBlob(image,(size_t) (q-pixels),pixels) != (ssize_t) (q-pixels))
+      {
+        status=MagickFalse;
+        break;
       }
     status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
       image->rows);
     if (status == MagickFalse)
       break;
   }
+  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
   (void) WriteBlobString(image,"</Data>\n");
   (void) WriteBlobString(image,"</CiscoIPPhoneImage>\n");
   if (CloseBlob(image) == MagickFalse)