SixLabors/ImageSharp · error · InvalidMemoryOperationException

The CCITT output buffer is too small for the encoded data.

Error message

The CCITT output buffer is too small for the encoded data.

What it means

The CCITT (T4/T6) TIFF compressor bit-writes encoded runs into a caller-provided destination span. Before writing each Huffman code, WriteCode computes the remaining free bits ((buffer length - bytePosition) * 8 - bitPosition); if the code does not fit, it throws InvalidMemoryOperationException. This is an internal capacity guard: the compressed output would overflow the estimated buffer.

Solutions

  1. Ensure the image is saved as bilevel (1-bit) or grayscale as expected; CCITT encoding of unexpected pixel data can produce larger codes — convert to a supported pixel type before saving.
  2. Report/upgrade: this indicates an internal buffer-sizing bug in the CCITT compressor; check for a newer ImageSharp version with a fix.
  3. As a workaround, save with TiffCompression.None or Deflate/Lzw instead of CCITT.

Example fix

// before
image.Save(path, new TiffEncoder { Compression = TiffCompression.CcittGroup4 });
// after
// convert to bilevel-compatible pixel type or use a non-CCITT compression
image.Save(path, new TiffEncoder { Compression = TiffCompression.Deflate });
Defensive patterns

Strategy: try-catch

Validate before calling

if (image.PixelType.PixelTypeInformation?.BitsPerPixel > 8)
    throw new InvalidOperationException("CCITT requires bilevel-compatible input");

Try / catch

try
{
    image.Save(path, new TiffEncoder { Compression = TiffCompression.CcittGroup4 });
}
catch (InvalidMemoryOperationException ex)
{
    // fall back to a non-CCITT compression
    image.Save(path, new TiffEncoder { Compression = TiffCompression.Deflate });
}

Prevention

When it happens

Trigger: Encoding a TIFF row/strip with CCITT G3/G4 compression where the compressor's pre-allocated compressedData span is smaller than the actual encoded bitstream for that strip — e.g. very wide rows with many short white runs producing more code bits than the allocated bytes*8.

Common situations: Encoding black-and-white ( bilevel ) images with TiffCompression.CcittGroup3/4 where row width or strip sizing assumptions in the encoder under-estimate encoded size; custom code calling the compressor internals with a hand-sized buffer.

Related errors


AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13). Data as JSON: /api/errors/5c70ec13f543a762. Report an issue: GitHub.

Appendix: source

Thrown at src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffCcittCompressor.cs:471

        {
            // Skip padding bits, move to next byte.
            this.bytePosition++;
            this.bitPosition = 0;
        }
    }

    /// <summary>
    /// Writes a code to the output.
    /// </summary>
    /// <param name="codeLength">The length of the code to write.</param>
    /// <param name="code">The code to be written.</param>
    /// <param name="compressedData">The destination buffer to write the code to.</param>
    protected void WriteCode(uint codeLength, uint code, Span<byte> compressedData)
    {
        long availableBits = (((long)compressedData.Length - this.bytePosition) * 8) - this.bitPosition;
        if (codeLength > availableBits)
        {
            throw new InvalidMemoryOperationException("The CCITT output buffer is too small for the encoded data.");
        }

        while (codeLength > 0)
        {
            int bitNumber = (int)codeLength;
            bool bit = (code & (1 << (bitNumber - 1))) != 0;
            if (bit)
            {
                BitWriterUtils.WriteBit(compressedData, this.bytePosition, this.bitPosition);
            }
            else
            {
                BitWriterUtils.WriteZeroBit(compressedData, this.bytePosition, this.bitPosition);
            }

            this.bitPosition++;
            if (this.bitPosition == 8)
            {

View on GitHub (pinned to 59ce6af6fc)