QL-Win/QuickLook · error · NotSupportedException

Unsupported PixelFormat: {pixelFormat}

Error message

Unsupported PixelFormat: {pixelFormat}

What it means

Thrown by CursorProvider.ToWriteableBitmap when a System.Drawing.Bitmap's PixelFormat is neither Format32bppArgb nor Format24bppRgb. The extension only knows how to copy those two layouts into a WPF WriteableBitmap, so any other format (16bpp, 8bpp indexed, 48bpp, etc.) is rejected with NotSupportedException.

Source

Thrown at QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/CursorProvider.cs:299

        Bitmap?.Dispose();
    }
}

file static class Extension
{
    public static WriteableBitmap ToWriteableBitmap(this Bitmap bitmap)
    {
        if (bitmap == null) throw new ArgumentNullException(nameof(bitmap));

        var pixelFormat = bitmap.PixelFormat;
        var width = bitmap.Width;
        var height = bitmap.Height;

        var wpfPixelFormat = pixelFormat switch
        {
            PixelFormat.Format32bppArgb => PixelFormats.Bgra32,
            PixelFormat.Format24bppRgb => PixelFormats.Bgr24,
            _ => throw new NotSupportedException($"Unsupported PixelFormat: {pixelFormat}")
        };

        var writeableBitmap = new WriteableBitmap(width, height, 96, 96, wpfPixelFormat, null);

        var bitmapData = bitmap.LockBits(
            new Rectangle(0, 0, width, height),
            ImageLockMode.ReadOnly,
            pixelFormat);

        try
        {
            writeableBitmap.Lock();
            unsafe
            {
                Buffer.MemoryCopy(
                    source: bitmapData.Scan0.ToPointer(),
                    destination: writeableBitmap.BackBuffer.ToPointer(),
                    destinationSizeInBytes: writeableBitmap.BackBufferStride * height,

View on GitHub (pinned to cb5d9c429c)

Solutions

  1. Before calling ToWriteableBitmap, clone the bitmap into Format32bppArgb: Bitmap.Clone(rect, PixelFormat.Format32bppArgb).
  2. Use Graphics.DrawImage to paint the source onto a new 32bppArgb canvas of the same dimensions.
  3. Extend the switch to handle the missing format (e.g. Format8bppIndexed -> PaletteMapping) if you control the provider.
  4. Validate bitmap.PixelFormat up front and skip/replace the frame if unsupported.

Example fix

// before
var wpfPixelFormat = pixelFormat switch
{
    PixelFormat.Format32bppArgb => PixelFormats.Bgra32,
    PixelFormat.Format24bppRgb => PixelFormats.Bgr24,
    _ => throw new NotSupportedException(...)
};

// after — normalize to 32bppArgb first
if (pixelFormat != PixelFormat.Format32bppArgb && pixelFormat != PixelFormat.Format24bppRgb)
    bitmap = bitmap.Clone(new Rectangle(0,0,bitmap.Width,bitmap.Height), PixelFormat.Format32bppArgb);
Defensive patterns

Strategy: validation

Validate before calling

var pf = bitmap.PixelFormat;
if (pf != System.Drawing.Imaging.PixelFormat.Format32bppArgb
 && pf != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
    bitmap = bitmap.Clone(new Rectangle(0,0,bitmap.Width,bitmap.Height),
                          System.Drawing.Imaging.PixelFormat.Format32bppArgb);

Type guard

static bool IsSupportedCursorFormat(System.Drawing.Bitmap b) => b.PixelFormat is System.Drawing.Imaging.PixelFormat.Format32bppArgb or System.Drawing.Imaging.PixelFormat.Format24bppRgb;

Try / catch

try { wb = bitmap.ToWriteableBitmap(); }
catch (NotSupportedException) { wb = bitmap.Clone(rect, Format32bppArgb).ToWriteableBitmap(); }

Prevention

When it happens

Trigger: bitmap.PixelFormat returns a value outside {Format32bppArgb, Format24bppRgb}; the switch expression hits its '_' arm. Happens when a .cur/.ani decoder (or a resize/conversion step) yields an indexed or 16-bit bitmap.

Common situations: An old 256-color or 16-color cursor; a cursor decoder that returns Format8bppIndexed; a palette-based .ani frame; a bitmap that passed through a thumbnail/resize API that downgraded color depth.

Related errors


AI-assisted analysis of QL-Win/QuickLook@cb5d9c429c (2026-08-13). Data as JSON: /api/errors/7db064115d536e74. Report an issue: GitHub.