QL-Win/QuickLook · error · ArgumentException
1 BPP mask underrun parsing ICNS file
Error message
1 BPP mask underrun parsing ICNS file
What it means
Thrown by IcnsProvider.Apply1BPPMask when the mask data buffer is shorter than expected. For 1-bit-per-pixel ICNS icons the entry packs image data then mask data contiguously; the method computes totalBytes = (W*H+7)/8 and requires maskData.Length >= 2*totalBytes so it can start the mask at offset totalBytes. If the buffer is shorter, the mask underruns and parsing is aborted with ArgumentException.
Source
Thrown at QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/IcnsProvider.cs:305
(0xffu & imageData[4 * (y * imageType.Width + x) + 3]));
SetPixel(image, x, y, argb);
}
}
private static void Apply1BPPMask(byte[] maskData, BitmapData image)
{
int position;
int bitsLeft = 0;
int value = 0;
// 1 bit icon types have image data followed by mask data in the same entry
int totalBytes = (image.Width * image.Height + 7) / 8;
if (maskData.Length >= 2 * totalBytes)
position = totalBytes;
else
throw new ArgumentException("1 BPP mask underrun parsing ICNS file");
for (int y = 0; y < image.Height; y++)
for (int x = 0; x < image.Width; x++)
{
if (bitsLeft == 0)
{
value = 0xff & maskData[position++];
bitsLeft = 8;
}
uint alpha;
alpha = (value & 0x80u) != 0 ? 0xffu : 0x00u;
value <<= 1;
bitsLeft--;
SetPixel(image, x, y, (alpha << 24) | (0xffffffu & GetPixel(image, x, y)));
}
}View on GitHub (pinned to cb5d9c429c)
Solutions
- Re-export the ICNS with a spec-compliant tool (iconutil, Axialis, or sips) that writes the full image+mask block.
- Pad the mask buffer to 2*totalBytes with zeros before calling Apply1BPPMask so underrun cannot occur.
- Catch ArgumentException during ICNS decode and skip the offending icon rather than failing the whole file.
- Verify the element's declared length equals the expected bytes for its 1BPP type before decoding.
Example fix
// before
if (maskData.Length >= 2 * totalBytes)
position = totalBytes;
else
throw new ArgumentException("1 BPP mask underrun parsing ICNS file");
// after — tolerate a short mask by clamping
position = Math.Min(totalBytes, Math.Max(0, maskData.Length - totalBytes)); Defensive patterns
Strategy: validation
Validate before calling
int totalBytes = (image.Width*image.Height + 7)/8; bool maskOk = maskData.Length >= 2*totalBytes; // only call Apply1BPPMask when maskOk; otherwise pad: Array.Resize(ref maskData, 2*totalBytes);
Type guard
static bool HasFull1BppMask(int w, int h, byte[] data) { int t=(w*h+7)/8; return data != null && data.Length >= 2*t; } Try / catch
try { Apply1BPPMask(maskData, bitmapData); }
catch (ArgumentException) { /* skip mask, keep image */ } Prevention
- Verify element declared length matches expected 2*ceil(W*H/8) for 1BPP icons.
- Pad short mask buffers with zeros rather than throwing.
- Re-export ICNS with iconutil for spec-compliant masks.
When it happens
Trigger: For a 1BPP ICNS type, the element's data array has fewer than 2*ceil(W*H/8) bytes, so the mask half is missing or partial. Occurs with hand-edited, truncated, or non-spec ICNS files where the icon entry was not fully written.
Common situations: An ICNS exported by a tool that omits the mask channel for monochrome icons; a file truncated mid-entry; an icon type misidentified as 1BPP due to a wrong type-code mapping.
Related errors
- Unsupport mask bit depth {maskType.BitsPerPixel}
- Unsupported bit depth {imageType.BitsPerPixel}
- No icons in ICNS file
- DS_Store: unknown record type '{stype}'
- DS_Store header too short
AI-assisted analysis of QL-Win/QuickLook@cb5d9c429c (2026-08-13).
Data as JSON: /api/errors/db57cbde866da744.
Report an issue: GitHub.