{"record":{"id":"07db658847579a42","repo":"d2phap/ImageGlass","slug":"crop-options-exceeded-webp-image-dimensions","errorCode":null,"errorMessage":"Crop options exceeded WebP image dimensions","messagePattern":"Crop options exceeded WebP image dimensions","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"v9/Components/ImageGlass.WebP/WebPWrapper.cs","lineNumber":157,"sourceCode":"            if (LibWebp.WebPInitDecoderConfig(ref config) == 0)\n            {\n                throw new Exception(\"WebPInitDecoderConfig failed. Wrong version?\");\n            }\n            // Read the .webp input file information\n            IntPtr ptrRawWebP = pinnedWebP.AddrOfPinnedObject();\n            int height;\n            int width;\n            if (options.use_scaling == 0)\n            {\n                result = LibWebp.WebPGetFeatures(ptrRawWebP, rawWebP.Length, ref config.input);\n                if (result != VP8StatusCode.VP8_STATUS_OK)\n                    throw new Exception(\"Failed WebPGetFeatures with error \" + result);\n\n                //Test cropping values\n                if (options.use_cropping == 1)\n                {\n                    if (options.crop_left + options.crop_width > config.input.Width || options.crop_top + options.crop_height > config.input.Height)\n                        throw new Exception(\"Crop options exceeded WebP image dimensions\");\n                    width = options.crop_width;\n                    height = options.crop_height;\n                }\n            }\n            else\n            {\n                width = options.scaled_width;\n                height = options.scaled_height;\n            }\n\n            config.options.bypass_filtering = options.bypass_filtering;\n            config.options.no_fancy_upsampling = options.no_fancy_upsampling;\n            config.options.use_cropping = options.use_cropping;\n            config.options.crop_left = options.crop_left;\n            config.options.crop_top = options.crop_top;\n            config.options.crop_width = options.crop_width;\n            config.options.crop_height = options.crop_height;\n            config.options.use_scaling = options.use_scaling;","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/d2phap/ImageGlass/blob/4a3c4feceffc5a8bb5e56ba836509634aaae47a9/v9/Components/ImageGlass.WebP/WebPWrapper.cs#L139-L175","documentation":"Thrown in WebPWrapper.Decode when use_cropping==1 and the requested crop rectangle falls outside the image: crop_left+crop_width > input.Width OR crop_top+crop_height > input.Height. The crop options are validated against the real image dimensions reported by WebPGetFeatures, so this is purely a caller-supplied crop-window error, not a decode problem.","triggerScenarios":"Passing WebPDecoderOptions with use_cropping=1 and crop coordinates computed without clamping to the source dimensions; assuming a thumbnail size that exceeds the actual image; off-by-one or sign errors in crop math; reusing crop options across images of different sizes.","commonSituations":"A UI crop tool sends the selection rectangle without intersecting it with the decoded image bounds; generating thumbnails with a fixed crop window on a smaller source image; coordinates swapped (width/height vs right/bottom).","solutions":["Clamp the crop rectangle to the source dimensions: crop_left = clamp(0, W - crop_width); ensure crop_left+crop_width <= W and crop_top+crop_height <= H.","Fetch the image dimensions first (WebPGetFeatures) and compute the crop window from the real W/H rather than an assumption.","If the crop is optional, set use_cropping=0 when it would exceed bounds and decode the full image instead.","Validate crop_left >= 0, crop_top >= 0, crop_width > 0, crop_height > 0 before calling."],"exampleFix":"// before\noptions.use_cropping = 1;\noptions.crop_left = x; options.crop_top = y;\noptions.crop_width = w; options.crop_height = h;\nvar bmp = WebPWrapper.Decode(raw, options);\n\n// after: clamp to image bounds\n// (imgW, imgH come from a prior WebPGetFeatures call)\nw = Math.Min(w, imgW - x); h = Math.Min(h, imgH - y);\nif (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > imgW || y + h > imgH)\n    options.use_cropping = 0;\nvar bmp = WebPWrapper.Decode(raw, options);","handlingStrategy":"validation","validationCode":"// Clamp the crop window to image bounds (imgW/imgH from WebPGetFeatures).\noptions.crop_left = Math.Clamp(options.crop_left, 0, imgW);\noptions.crop_top = Math.Clamp(options.crop_top, 0, imgH);\noptions.crop_width = Math.Min(options.crop_width, imgW - options.crop_left);\noptions.crop_height = Math.Min(options.crop_height, imgH - options.crop_top);\nif (options.crop_width <= 0 || options.crop_height <= 0) options.use_cropping = 0;","typeGuard":null,"tryCatchPattern":"try { bmp = WebPWrapper.Decode(rawWebP, options); }\ncatch (Exception ex) when (ex.Message.Contains(\"Crop options exceeded\"))\n{ options.use_cropping = 0; bmp = WebPWrapper.Decode(rawWebP, options); }","preventionTips":["Always derive crop coordinates from the real decoded dimensions.","Clamp the crop rectangle to [0,W]x[0,H] and ensure positive size.","Disable cropping when the window would be empty."],"tags":["webp","libwebp","crop","bounds-check","decode","imageglass","v9"],"backgroundTag":null,"analyzedSha":"4a3c4feceffc5a8bb5e56ba836509634aaae47a9","analyzedAt":"2026-08-13T16:58:15.523Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}