wmjordan/PDFPatcher · error · QuantizationException

The image you are attempting to quantize does not contain a

Error message

The image you are attempting to quantize does not contain a 32 bit ARGB palette. This image has a bit depth of {0} with {1} colors.

What it means

WuColorQuantizer.BuildHistogram throws QuantizationException when the source bitmap's pixel bit depth is not 32 or 24 (checked via Image.GetPixelFormatSize). The Wu quantizer only operates on 24/32-bit RGB/ARGB data; other depths (1/4/8-bit indexed, 16-bit, etc.) are rejected because the histogram buffer access assumes 3-4 bytes per pixel.

Source

Thrown at App/Processor/Imaging/WuColorQuantizer.cs:73

			finally {
				if (targetData != null)
					result.UnlockBits(targetData);
			}
			result.SetResolution(source.HorizontalResolution, source.VerticalResolution);
			return result;
		}

		static ColorData BuildHistogram(Bitmap sourceImage) {
			int bitmapWidth = sourceImage.Width;
			int bitmapHeight = sourceImage.Height;

			var data = sourceImage.LockBits(false);
			var colorData = new ColorData(__MaxSideIndex, bitmapWidth, bitmapHeight);

			try {
				var bitDepth = Image.GetPixelFormatSize(sourceImage.PixelFormat);
				if (bitDepth != 32 && bitDepth != 24)
					throw new QuantizationException(string.Format("The image you are attempting to quantize does not contain a 32 bit ARGB palette. This image has a bit depth of {0} with {1} colors.", bitDepth, sourceImage.Palette.Entries.Length));
				var byteLength = data.Stride < 0 ? -data.Stride : data.Stride;
				var offset = 0;
				var buffer = new Byte[byteLength * sourceImage.Height];

				System.Runtime.InteropServices.Marshal.Copy(data.Scan0, buffer, 0, buffer.Length);
				var t = new int[__MaxColor];
				for (var i = 0; i < __MaxColor; ++i) {
					t[i] = i * i;
				}
				int pos;
				byte vr, vg, vb, r, g, b;
				var w = colorData.Weights;
				var mr = colorData.MomentsRed;
				var mg = colorData.MomentsGreen;
				var mb = colorData.MomentsBlue;
				var m = colorData.Moments;
				for (int y = 0; y < bitmapHeight; y++) {
					var index = 0;

View on GitHub (pinned to 4782bbd9ad)

Solutions

  1. Convert the source Bitmap to 32bppArgb (or 24bppRgb) via Clone(..., PixelFormat.Format32bppArgb) before quantizing.
  2. Guard the quantizer entry point with a pixel-format check and promote non-conforming bitmaps.
  3. For indexed sources, expand to full color before invoking WuColorQuantizer.

Example fix

// before
var result = WuColorQuantizer.Quantize(sourceImage);

// after
if (Image.GetPixelFormatSize(sourceImage.PixelFormat) is not (32 or 24)) {
  sourceImage = sourceImage.Clone(
    new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
    PixelFormat.Format32bppArgb);
}
var result = WuColorQuantizer.Quantize(sourceImage);
Defensive patterns

Strategy: validation

Validate before calling

int bd = Image.GetPixelFormatSize(src.PixelFormat);
if (bd != 32 && bd != 24)
    src = src.Clone(new Rectangle(0,0,src.Width,src.Height), PixelFormat.Format32bppArgb);

Type guard

static bool IsQuantizable(Bitmap b) {
  int d = Image.GetPixelFormatSize(b.PixelFormat);
  return d == 32 || d == 24;
}

Prevention

When it happens

Trigger: Calling the quantizer (BuildHistogram / Quantize) on a Bitmap whose PixelFormat is not 32bppRgb/32bppArgb or 24bppRgb — e.g. an 8-bit indexed image, a 1-bit黑白 image, or a 16-bit image passed directly without prior promotion.

Common situations: Loading an indexed-color PNG/GIF or a 1-bit scanned image and passing it to the quantizer without converting its pixel format first; extracting images from a PDF in indexed formats; a bitmap created with a default format that isn't 24/32-bit.

Related errors


AI-assisted analysis of wmjordan/PDFPatcher@4782bbd9ad (2026-08-13). Data as JSON: /api/errors/4cb12607410de766. Report an issue: GitHub.