Commit d53f5619b for imagemagick.org
commit d53f5619b221a0c9168314d20ad4c8026cd865fc
Author: AutoJanitor <crypteauxcajun@gmail.com>
Date: Sun Jun 28 09:05:16 2026 -0500
Read Cairo ARGB32 in host byte order so SVG colors are correct on big-endian (#8825)
RenderRSVGImage read the Cairo CAIRO_FORMAT_ARGB32 surface as a fixed
B,G,R,A byte sequence. ARGB32 is a native-endian 32-bit word, so that
byte order is only correct on little-endian hosts. On big-endian the
bytes are laid out A,R,G,B, so the channels and alpha were misread and
SVG colors rendered incorrectly (#8596).
Detect the host byte order and read B,G,R,A on little-endian or A,R,G,B
on big-endian.
Tested on a native big-endian ppc64 (POWER8) host. Before the change an
opaque #ff8040 rect rendered through the rsvg coder as ff ff ff ff;
after it renders ff 80 40 ff, matching rsvg-convert. Red, green, blue and
semi-transparent fills render correctly as well, and the nix-snowflake
test image renders with the correct colors instead of solid white.
Little-endian output is unchanged.
diff --git a/coders/svg.c b/coders/svg.c
index 42f62b009..1aaddbb62 100644
--- a/coders/svg.c
+++ b/coders/svg.c
@@ -374,6 +374,9 @@ static Image *RenderRSVGImage(const ImageInfo *image_info,Image *image,
MagickBooleanType
apply_density;
+ EndianType
+ endian;
+
MemoryInfo
*pixel_info;
@@ -591,6 +594,9 @@ static Image *RenderRSVGImage(const ImageInfo *image_info,Image *image,
p=gdk_pixbuf_get_pixels(pixel_buffer);
#endif
GetPixelInfo(image,&fill_color);
+#if defined(MAGICKCORE_CAIRO_DELEGATE)
+ endian=GetHostEndian();
+#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
@@ -599,15 +605,26 @@ static Image *RenderRSVGImage(const ImageInfo *image_info,Image *image,
for (x=0; x < (ssize_t) image->columns; x++)
{
#if defined(MAGICKCORE_CAIRO_DELEGATE)
- fill_color.blue=ScaleCharToQuantum(*p++);
- fill_color.green=ScaleCharToQuantum(*p++);
- fill_color.red=ScaleCharToQuantum(*p++);
+ if (endian == LSBEndian)
+ {
+ fill_color.blue=ScaleCharToQuantum(*p++);
+ fill_color.green=ScaleCharToQuantum(*p++);
+ fill_color.red=ScaleCharToQuantum(*p++);
+ fill_color.alpha=ScaleCharToQuantum(*p++);
+ }
+ else
+ {
+ fill_color.alpha=ScaleCharToQuantum(*p++);
+ fill_color.red=ScaleCharToQuantum(*p++);
+ fill_color.green=ScaleCharToQuantum(*p++);
+ fill_color.blue=ScaleCharToQuantum(*p++);
+ }
#else
fill_color.red=ScaleCharToQuantum(*p++);
fill_color.green=ScaleCharToQuantum(*p++);
fill_color.blue=ScaleCharToQuantum(*p++);
-#endif
fill_color.alpha=ScaleCharToQuantum(*p++);
+#endif
#if defined(MAGICKCORE_CAIRO_DELEGATE)
{
double