Commit 0c76bb631 for imagemagick.org
commit 0c76bb631db4ede005d4eeef7714d6d7951b40ce
Author: Dirk Lemstra <dirk@lemstra.org>
Date: Sat Nov 7 12:06:57 2026 +0100
Use a small stack buffer when writing bytes for padding instead of writing them separately.
diff --git a/MagickCore/blob-private.h b/MagickCore/blob-private.h
index 7e08e6884..b3c6cd64e 100644
--- a/MagickCore/blob-private.h
+++ b/MagickCore/blob-private.h
@@ -126,6 +126,7 @@ extern MagickExport ssize_t
WriteBlobMSBLong(Image *,const unsigned int),
WriteBlobMSBShort(Image *,const unsigned short),
WriteBlobMSBSignedShort(Image *,const signed short),
+ WriteBlobPadding(Image *,const size_t,const unsigned char),
WriteBlobString(Image *,const char *);
extern MagickExport unsigned int
diff --git a/MagickCore/blob.c b/MagickCore/blob.c
index cdd8eb4a5..c93b0d4bc 100644
--- a/MagickCore/blob.c
+++ b/MagickCore/blob.c
@@ -6193,6 +6193,74 @@ MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
}
return(count);
}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b P a d d i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteBlobPadding() writes length copies of a byte value to a blob. It
+% returns the number of bytes written, stopping on a short or failed write.
+% Lengths greater than MAGICK_SSIZE_MAX return zero and set errno to EOVERFLOW.
+%
+% The format of the WriteBlobPadding method is:
+%
+% ssize_t WriteBlobPadding(Image *image,const size_t length,
+% const unsigned char value)
+%
+% A description of each parameter follows.
+%
+% o image: the image.
+%
+% o length: the number of bytes to write.
+%
+% o value: the byte value to repeat.
+%
+*/
+MagickExport ssize_t WriteBlobPadding(Image *image,const size_t length,
+ const unsigned char value)
+{
+ size_t
+ extent;
+
+ ssize_t
+ count,
+ total;
+
+ unsigned char
+ padding[1024];
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickCoreSignature);
+ assert(image->blob != (BlobInfo *) NULL);
+ assert(image->blob->type != UndefinedStream);
+ if (length == 0)
+ return(0);
+ if (length > (size_t) MAGICK_SSIZE_MAX)
+ {
+ errno=EOVERFLOW;
+ return(0);
+ }
+ (void) memset(padding,value,sizeof(padding));
+ total=0;
+ while ((size_t) total < length)
+ {
+ extent=MagickMin(sizeof(padding),length-(size_t) total);
+ count=WriteBlob(image,extent,padding);
+ if (count <= 0)
+ break;
+ total+=count;
+ if (count != (ssize_t) extent)
+ break;
+ }
+ return(total);
+}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/coders/ase.c b/coders/ase.c
index b2678ed07..8c37a2b4c 100644
--- a/coders/ase.c
+++ b/coders/ase.c
@@ -1393,8 +1393,7 @@ static MagickBooleanType WriteASEImage(const ImageInfo *image_info,
(void) WriteBlobByte(image,0);
(void) WriteBlobLSBShort(image,1);
(void) WriteBlobLSBShort(image,1);
- for (i=0; i < 46; i++)
- (void) WriteBlobLSBShort(image,0); /* grid x/y/width/height + reserved[84] */
+ (void) WriteBlobPadding(image,92,'\0'); /* grid x/y/width/height + reserved[84] */
pixel_count=image->columns*image->rows;
pixels=(uint8_t *) AcquireQuantumMemory(pixel_count,bytes_per_pixel);
if (pixels == (uint8_t *) NULL)
diff --git a/coders/cals.c b/coders/cals.c
index 416d71b57..70c8d06ed 100644
--- a/coders/cals.c
+++ b/coders/cals.c
@@ -403,9 +403,6 @@ ModuleExport void UnregisterCALSImage(void)
static ssize_t WriteCALSRecord(Image *image,const char *data)
{
- char
- pad[128];
-
const char
*p;
@@ -426,8 +423,7 @@ static ssize_t WriteCALSRecord(Image *image,const char *data)
if (i < 128)
{
i=128-i;
- (void) memset(pad,' ',(size_t) i);
- count=WriteBlob(image,(size_t) i,(const unsigned char *) pad);
+ count=WriteBlobPadding(image,(size_t) i,' ');
}
return(count);
}
diff --git a/coders/dpx.c b/coders/dpx.c
index 3fa79037e..853c20acc 100644
--- a/coders/dpx.c
+++ b/coders/dpx.c
@@ -1979,15 +1979,14 @@ static MagickBooleanType WriteDPXImage(const ImageInfo *image_info,Image *image,
if (profile != (StringInfo *) NULL)
offset+=WriteBlob(image,GetStringInfoLength(profile),
GetStringInfoDatum(profile));
- while (offset < (MagickOffsetType) dpx.image.image_element[0].data_offset)
+ if (offset < (MagickOffsetType) dpx.image.image_element[0].data_offset)
{
- count=WriteBlobByte(image,0x00);
- if (count != 1)
- {
- ThrowFileException(exception,FileOpenError,"UnableToWriteFile",
- image->filename);
- break;
- }
+ extent=(size_t) ((MagickOffsetType)
+ dpx.image.image_element[0].data_offset-offset);
+ count=WriteBlobPadding(image,extent,'\0');
+ if (count != (ssize_t) extent)
+ ThrowFileException(exception,FileOpenError,"UnableToWriteFile",
+ image->filename);
offset+=count;
}
/*
diff --git a/coders/icon.c b/coders/icon.c
index 8be917ef6..b08721c5d 100644
--- a/coders/icon.c
+++ b/coders/icon.c
@@ -1514,8 +1514,7 @@ static MagickBooleanType WriteICONImage(const ImageInfo *image_info,
}
if (bit != 0)
(void) WriteBlobByte(image,(unsigned char) (byte << (8-bit)));
- for (i=0; i < (ssize_t) scanline_pad; i++)
- (void) WriteBlobByte(image,(unsigned char) 0);
+ (void) WriteBlobPadding(image,scanline_pad,'\0');
}
}
if (GetNextImageInList(frame) == (Image *) NULL)
diff --git a/coders/mat.c b/coders/mat.c
index c7d90e39f..fd16ad89f 100644
--- a/coders/mat.c
+++ b/coders/mat.c
@@ -1777,8 +1777,7 @@ static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image,
if (SyncAuthenticPixels(image,exception) == MagickFalse)
break;
} while (z-- >= 2);
- while (padding-- > 0)
- (void) WriteBlobByte(image,0);
+ (void) WriteBlobPadding(image,padding,'\0');
quantum_info=DestroyQuantumInfo(quantum_info);
if (GetNextImageInList(image) == (Image *) NULL)
break;
diff --git a/coders/palm.c b/coders/palm.c
index b09ae0939..ef65ac83f 100644
--- a/coders/palm.c
+++ b/coders/palm.c
@@ -701,9 +701,6 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
offset,
scene;
- MagickSizeType
- cc;
-
PixelInfo
transpix;
@@ -1018,8 +1015,7 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
if (GetNextImageInList(image) == (Image *) NULL)
break;
/* padding to 4 byte word */
- for (cc=(GetBlobSize(image)) % 4; cc > 0; cc--)
- (void) WriteBlobByte(image,0);
+ (void) WriteBlobPadding(image,(size_t) (GetBlobSize(image) % 4),'\0');
/* write nextDepthOffset and return to end of image */
offset=SeekBlob(image,currentOffset+10,SEEK_SET);
nextDepthOffset=(size_t) (((MagickOffsetType) GetBlobSize(image)-
diff --git a/coders/pcd.c b/coders/pcd.c
index 37df0adfd..98af6ea86 100644
--- a/coders/pcd.c
+++ b/coders/pcd.c
@@ -1004,7 +1004,6 @@ static MagickBooleanType WritePCDTile(Image *image,const char *page_geometry,
*q;
ssize_t
- i,
x;
ssize_t
@@ -1106,8 +1105,7 @@ static MagickBooleanType WritePCDTile(Image *image,const char *page_geometry,
if (status == MagickFalse)
break;
}
- for (i=0; i < 0x800; i++)
- (void) WriteBlobByte(image,'\0');
+ (void) WriteBlobPadding(image,0x800,'\0');
downsample_image=DestroyImage(downsample_image);
tile_image=DestroyImage(tile_image);
return(MagickTrue);
@@ -1122,9 +1120,6 @@ static MagickBooleanType WritePCDImage(const ImageInfo *image_info,Image *image,
MagickBooleanType
status;
- ssize_t
- i;
-
assert(image_info != (const ImageInfo *) NULL);
assert(image_info->signature == MagickCoreSignature);
assert(image != (Image *) NULL);
@@ -1162,36 +1157,24 @@ static MagickBooleanType WritePCDImage(const ImageInfo *image_info,Image *image,
/*
Write PCD image header.
*/
- for (i=0; i < 32; i++)
- (void) WriteBlobByte(pcd_image,0xff);
- for (i=0; i < 4; i++)
- (void) WriteBlobByte(pcd_image,0x0e);
- for (i=0; i < 8; i++)
- (void) WriteBlobByte(pcd_image,'\0');
- for (i=0; i < 4; i++)
- (void) WriteBlobByte(pcd_image,0x01);
- for (i=0; i < 4; i++)
- (void) WriteBlobByte(pcd_image,0x05);
- for (i=0; i < 8; i++)
- (void) WriteBlobByte(pcd_image,'\0');
- for (i=0; i < 4; i++)
- (void) WriteBlobByte(pcd_image,0x0A);
- for (i=0; i < 36; i++)
- (void) WriteBlobByte(pcd_image,'\0');
- for (i=0; i < 4; i++)
- (void) WriteBlobByte(pcd_image,0x01);
- for (i=0; i < 1944; i++)
- (void) WriteBlobByte(pcd_image,'\0');
+ (void) WriteBlobPadding(pcd_image,32,'\xff');
+ (void) WriteBlobPadding(pcd_image,4,'\x0e');
+ (void) WriteBlobPadding(pcd_image,8,'\0');
+ (void) WriteBlobPadding(pcd_image,4,'\x01');
+ (void) WriteBlobPadding(pcd_image,4,'\x05');
+ (void) WriteBlobPadding(pcd_image,8,'\0');
+ (void) WriteBlobPadding(pcd_image,4,'\x0a');
+ (void) WriteBlobPadding(pcd_image,36,'\0');
+ (void) WriteBlobPadding(pcd_image,4,'\x01');
+ (void) WriteBlobPadding(pcd_image,1944,'\0');
(void) WriteBlob(pcd_image,7,(const unsigned char *) "PCD_IPI");
(void) WriteBlobByte(pcd_image,0x06);
- for (i=0; i < 1530; i++)
- (void) WriteBlobByte(pcd_image,'\0');
+ (void) WriteBlobPadding(pcd_image,1530,'\0');
if (image->columns < image->rows)
(void) WriteBlobByte(pcd_image,'\1');
else
(void) WriteBlobByte(pcd_image,'\0');
- for (i=0; i < (3*0x800-1539); i++)
- (void) WriteBlobByte(pcd_image,'\0');
+ (void) WriteBlobPadding(pcd_image,3*0x800-1539,'\0');
/*
Write PCD tiles.
*/
diff --git a/coders/pcx.c b/coders/pcx.c
index 3bae83a8d..8f8e13d15 100644
--- a/coders/pcx.c
+++ b/coders/pcx.c
@@ -1037,8 +1037,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image,
(void) WriteBlobByte(image,pcx_info.planes);
(void) WriteBlobLSBShort(image,pcx_info.bytes_per_line);
(void) WriteBlobLSBShort(image,pcx_info.palette_info);
- for (i=0; i < 58; i++)
- (void) WriteBlobByte(image,'\0');
+ (void) WriteBlobPadding(image,58,'\0');
length=(size_t) pcx_info.bytes_per_line;
pixel_info=AcquireVirtualMemory(length,pcx_info.planes*sizeof(*pixels));
if (pixel_info == (MemoryInfo *) NULL)
diff --git a/coders/psd.c b/coders/psd.c
index 2b0ea6c4c..bf467ef68 100644
--- a/coders/psd.c
+++ b/coders/psd.c
@@ -3427,8 +3427,7 @@ static size_t WritePascalString(Image *image,const char *value,size_t padding)
length;
ssize_t
- count,
- i;
+ count;
/*
Max length is 255.
@@ -3445,8 +3444,7 @@ static size_t WritePascalString(Image *image,const char *value,size_t padding)
length++;
if ((length % padding) == 0)
return((size_t) count);
- for (i=0; i < (ssize_t) (padding-(length % padding)); i++)
- count+=WriteBlobByte(image,0);
+ count+=WriteBlobPadding(image,padding-(length % padding),'\0');
return((size_t) count);
}
@@ -3979,8 +3977,7 @@ static MagickBooleanType WritePSDImage(const ImageInfo *image_info,
psd_info.version=2;
(void) WriteBlob(image,4,(const unsigned char *) "8BPS");
(void) WriteBlobMSBShort(image,psd_info.version); /* version */
- for (i=1; i <= 6; i++)
- (void) WriteBlobByte(image, 0); /* 6 bytes of reserved */
+ (void) WriteBlobPadding(image,6,'\0'); /* 6 bytes of reserved */
if ((GetImageProfile(image,"icc") == (StringInfo *) NULL) &&
(SetImageGray(image,exception) != MagickFalse))
num_channels=1;
@@ -4050,18 +4047,15 @@ static MagickBooleanType WritePSDImage(const ImageInfo *image_info,
for (i=0; i < (ssize_t) image->colors; i++)
(void) WriteBlobByte(image,ScaleQuantumToChar(ClampToQuantum(
image->colormap[i].red)));
- for ( ; i < 256; i++)
- (void) WriteBlobByte(image,0);
+ (void) WriteBlobPadding(image,256-image->colors,'\0');
for (i=0; i < (ssize_t) image->colors; i++)
(void) WriteBlobByte(image,ScaleQuantumToChar(ClampToQuantum(
image->colormap[i].green)));
- for ( ; i < 256; i++)
- (void) WriteBlobByte(image,0);
+ (void) WriteBlobPadding(image,256-image->colors,'\0');
for (i=0; i < (ssize_t) image->colors; i++)
(void) WriteBlobByte(image,ScaleQuantumToChar(ClampToQuantum(
image->colormap[i].blue)));
- for ( ; i < 256; i++)
- (void) WriteBlobByte(image,0);
+ (void) WriteBlobPadding(image,256-image->colors,'\0');
}
/*
Image resource block.
diff --git a/coders/qoi.c b/coders/qoi.c
index 43cc4db2c..b78a3870d 100644
--- a/coders/qoi.c
+++ b/coders/qoi.c
@@ -598,8 +598,7 @@ static MagickBooleanType WriteQOIImage(const ImageInfo *image_info,Image *image,
/*
Write the QOI end marker: seven 0x00 bytes followed by 0x01.
*/
- for (i=0; i < 7; i++)
- (void) WriteBlobByte(image,0x00);
+ (void) WriteBlobPadding(image,7,'\0');
(void) WriteBlobByte(image,0x01);
if (CloseBlob(image) == MagickFalse)
status=MagickFalse;
diff --git a/coders/viff.c b/coders/viff.c
index 806b6d98c..bda8fa3b4 100644
--- a/coders/viff.c
+++ b/coders/viff.c
@@ -1088,8 +1088,7 @@ static MagickBooleanType WriteVIFFImage(const ImageInfo *image_info,
(void) WriteBlobMSBLong(image,(unsigned int) viff_info.map_enable);
(void) WriteBlobMSBLong(image,(unsigned int) viff_info.maps_per_cycle);
(void) WriteBlobMSBLong(image,(unsigned int) viff_info.color_space_model);
- for (i=0; i < 420; i++)
- (void) WriteBlobByte(image,'\0');
+ (void) WriteBlobPadding(image,420,'\0');
/*
Convert MIFF to VIFF raster pixels.
*/
diff --git a/coders/vips.c b/coders/vips.c
index d54bca1cb..3dc455d2f 100644
--- a/coders/vips.c
+++ b/coders/vips.c
@@ -726,8 +726,7 @@ static MagickBooleanType WriteVIPSImage(const ImageInfo *image_info,
/*
Legacy, offsets, future.
*/
- for (y=0; y < 24; y++)
- (void) WriteBlobByte(image,0);
+ (void) WriteBlobPadding(image,24,'\0');
for (y=0; y < (ssize_t) image->rows; y++)
{
p=GetVirtualPixels(image,0,y,image->columns,1,exception);