d2phap/ImageGlass · error · Exception

Can't allocate memory in WebPPictureImportBGR

Error message

Can't allocate memory in WebPPictureImportBGR

What it means

Thrown by AdvancedEncode when LibWebp.WebPPictureImportBGR returns != 1 for a Format24bppRgb bitmap. Same root cause as the BGRA variant: the import into a libwebp-owned buffer failed, usually an allocation failure or a bad WebPPicture state.

Source

Thrown at v9/Components/ImageGlass.WebP/WebPWrapper.cs:906

            wpic.height = (int)bmp.Height;
            wpic.use_argb = 1;

            if (bmp.PixelFormat == PixelFormat.Format32bppArgb)
            {
                // Put the bitmap componets in wpic
                int result = LibWebp.WebPPictureImportBGRA(ref wpic, bmpData.Scan0, bmpData.Stride);
                if (result != 1)
                    throw new Exception("Can't allocate memory in WebPPictureImportBGRA");
                wpic.colorspace = (uint)WEBP_CSP_MODE.MODE_bgrA;
                dataWebpSize = bmp.Width * bmp.Height * 32;
                dataWebp = new byte[bmp.Width * bmp.Height * 32]; // Memory for WebP output
            }
            else
            {
                // Put the bitmap contents in WebPPicture instance
                int result = LibWebp.WebPPictureImportBGR(ref wpic, bmpData.Scan0, bmpData.Stride);
                if (result != 1)
                    throw new Exception("Can't allocate memory in WebPPictureImportBGR");
                dataWebpSize = bmp.Width * bmp.Height * 24;

            }

            // Set up statistics of compression
            if (info)
            {
                stats = new WebPAuxStats();
                ptrStats = Marshal.AllocHGlobal(Marshal.SizeOf(stats));
                Marshal.StructureToPtr(stats, ptrStats, false);
                wpic.stats = ptrStats;
            }

            // Memory for WebP output
            if (dataWebpSize > 2_147_483_591) dataWebpSize = 2_147_483_591;
            dataWebp = new byte[bmp.Width * bmp.Height * 32];
            pinnedArrayHandle = GCHandle.Alloc(dataWebp, GCHandleType.Pinned);
            var initPtr = pinnedArrayHandle.AddrOfPinnedObject();

View on GitHub (pinned to 4a3c4fecef)

Solutions

  1. Reduce the bitmap dimensions before encoding.
  2. Run as a 64-bit process.
  3. Throttle concurrent encodes to bound peak memory.
  4. Confirm the wpic was successfully initialized via WebPPictureInitInternal immediately before.

Example fix

// before
var bytes = webp.EncodeLossy(bigRgb, quality, speed);

// after
using var smaller = new Bitmap(bigRgb.Width / 2, bigRgb.Height / 2, PixelFormat.Format24bppRgb);
using (var g = Graphics.FromImage(smaller)) g.DrawImage(bigRgb, 0, 0, smaller.Width, smaller.Height);
var bytes = webp.EncodeLossy(smaller, quality, speed);
Defensive patterns

Strategy: validation

Validate before calling

if (Environment.Is64BitProcess == false && bmp.Width * bmp.Height > 75_000_000)
    bmp = DownscaleTo(bmp, Math.Max(bmp.Width / 2, 1), Math.Max(bmp.Height / 2, 1), PixelFormat.Format24bppRgb);

Type guard

static bool LikelyFitsInMemory(Bitmap bmp) =>
    (long)bmp.Width * bmp.Height * 3 < (Environment.Is64BitProcess ? 1L << 40 : 1_500_000_000L);

Try / catch

try { var bytes = webp.EncodeLossy(bmp, quality, speed); }
catch (Exception ex) when (ex.Message.Contains("WebPPictureImportBGR"))
{ bmp = DownscaleTo(bmp, bmp.Width / 2, bmp.Height / 2, PixelFormat.Format24bppRgb); /* retry */ }

Prevention

When it happens

Trigger: Advanced encode of a Format24bppRgb bitmap where WebPPictureImportBGR cannot allocate/import — large dimensions, low address space, or a corrupt wpic.

Common situations: Encoding very large 24bpp images; 32-bit process memory pressure; concurrent encodes; a failed prior init.

Related errors


AI-assisted analysis of d2phap/ImageGlass@4a3c4fecef (2026-08-13). Data as JSON: /api/errors/6b51d9a95ace3e09. Report an issue: GitHub.