mxgmn/WaveFunctionCollapse · error · Exception
ERROR: wrong image width * height = {width} * {height}
Error message
ERROR: wrong image width * height = {width} * {height} What it means
SaveBitmap validates its inputs before encoding the pixel buffer to a PNG via ImageSharp. This Exception is thrown when the dimensions are non-positive or when the data array length does not exactly equal width * height, i.e. the buffer cannot represent a complete rectangular image of the stated size. It is a fail-fast guard against writing a corrupt or truncated PNG.
Source
Thrown at Helper.cs:58
}
public static IEnumerable<XElement> Elements(this XElement xelement, params string[] names) => xelement.Elements().Where(e => names.Any(n => n == e.Name));
}
static class BitmapHelper
{
public static (int[], int, int) LoadBitmap(string filename)
{
using var image = Image.Load<Bgra32>(filename);
int width = image.Width, height = image.Height;
int[] result = new int[width * height];
image.CopyPixelDataTo(MemoryMarshal.Cast<int, Bgra32>(result.AsSpan()));
return (result, width, height);
}
unsafe public static void SaveBitmap(int[] data, int width, int height, string filename)
{
if (width <= 0 || height <= 0 || data.Length != width * height) throw new Exception($"ERROR: wrong image width * height = {width} * {height}");
Span<Bgra32> pixelSpan = MemoryMarshal.Cast<int, Bgra32>(data.AsSpan());
using var image = Image.LoadPixelData<Bgra32>(pixelSpan.ToArray(), width, height);
image.SaveAsPng(filename);
}
}
View on GitHub (pinned to de7d22e705)
Solutions
- Log data.Length, width, and height at the call site and verify data.Length == width * height before calling SaveBitmap; fix whichever value is wrong.
- Check whether the source buffer includes stride/row padding; if so, copy only the actual pixel bytes row by row into a tightly packed int[] of width*height.
- Verify width/height come from the same image/region as the pixel data (e.g. re-read them from the same Bitmap object used for CopyPixelDataTo).
- If the image can legitimately be empty, guard the call site and skip saving instead of calling SaveBitmap with 0 dimensions.
- Increase the destination buffer size if a partial copy left it short (result array must be width*height*4 bytes).
Example fix
// before
Helper.SaveBitmap(pixels, headerWidth, data.Length / headerHeight, "out.png");
// after
int width = bitmap.PixelSize.Width;
int height = bitmap.PixelSize.Height;
if (pixels.Length == width * height)
Helper.SaveBitmap(pixels, width, height, "out.png"); Defensive patterns
Strategy: validation
Validate before calling
bool CanSave(int[] data, int width, int height) => width > 0 && height > 0 && data != null && data.Length == checked(width * height);
if (!CanSave(data, width, height)) throw new ArgumentException($"data.Length={data?.Length ?? -1} != {width}*{height}"); Type guard
static bool IsValidBitmapArgs(int[] data, int width, int height) => data is not null && width > 0 && height > 0 && data.Length == width * height;
Try / catch
try
{
Helper.SaveBitmap(data, width, height, path);
}
catch (Exception ex) when (ex.Message.StartsWith("ERROR: wrong image width"))
{
// log width/height/data.Length and fix the buffer/dimension mismatch
} Prevention
- Always derive width and height from the same object that produced the pixel data.
- Keep pixel buffers tightly packed (no stride padding) when handing them to SaveBitmap.
- Assert data.Length == width * height in debug builds before saving.
- Validate dimensions are positive before allocating or copying pixel buffers.
- Wrap save logic in a helper that checks IsValidBitmapArgs first.
When it happens
Trigger: Calling Helper.SaveBitmap with width <= 0 or height <= 0, or with a data array whose Length != width * height (e.g. a cropped/padded buffer, a row-stride mismatch where the buffer includes stride padding, or dimensions read from a different source than the pixel data).
Common situations: Computing width/height from a bitmap header while the copied pixel region was clipped or scaled; including row-alignment padding bytes in the array; off-by-one or integer-division errors when deriving dimensions; passing a partially filled buffer after a failed CopyPixelDataTo; passing 0 dimensions for an empty/hidden window or zero-sized render target.
AI-assisted analysis of mxgmn/WaveFunctionCollapse@de7d22e705 (2026-08-30).
Data as JSON: /api/errors/0775afcd53a4021a.
Report an issue: GitHub.