Yalantis/uCrop · error · CImgIOException
load_png(): Invalid bit depth %u in file '%s'.
Error message
load_png(): Invalid bit depth %u in file '%s'.
What it means
After reading the PNG header, CImg only supports 8-bit and 16-bit per-channel depths (bit_depth != 8 && != 16). Any other depth (1, 2, or 4 bits per pixel) causes CImgIOException, since CImg's pixel buffer cannot represent them directly.
Source
Thrown at ucrop/src/main/jni/CImg.h:57470
bit_depth = 8;
}
if (png_get_valid(png_ptr,info_ptr,PNG_INFO_tRNS)) {
png_set_tRNS_to_alpha(png_ptr);
color_type |= PNG_COLOR_MASK_ALPHA;
}
if (color_type==PNG_COLOR_TYPE_GRAY || color_type==PNG_COLOR_TYPE_GRAY_ALPHA) {
png_set_gray_to_rgb(png_ptr);
color_type |= PNG_COLOR_MASK_COLOR;
is_gray = true;
}
if (color_type==PNG_COLOR_TYPE_RGB)
png_set_filler(png_ptr,0xffffU,PNG_FILLER_AFTER);
png_read_update_info(png_ptr,info_ptr);
if (bit_depth!=8 && bit_depth!=16) {
if (!file) cimg::fclose(nfile);
png_destroy_read_struct(&png_ptr,&end_info,(png_infopp)0);
throw CImgIOException(_cimg_instance
"load_png(): Invalid bit depth %u in file '%s'.",
cimg_instance,
bit_depth,nfilename?nfilename:"(FILE*)");
}
const int byte_depth = bit_depth>>3;
// Allocate memory for image reading.
png_bytep *const imgData = new png_bytep[H];
for (unsigned int row = 0; row<H; ++row) imgData[row] = new png_byte[(size_t)byte_depth*4*W];
png_read_image(png_ptr,imgData);
png_read_end(png_ptr,end_info);
// Read pixel data.
if (color_type!=PNG_COLOR_TYPE_RGB && color_type!=PNG_COLOR_TYPE_RGB_ALPHA) {
if (!file) cimg::fclose(nfile);
png_destroy_read_struct(&png_ptr,&end_info,(png_infopp)0);
throw CImgIOException(_cimg_instance
"load_png(): Invalid color coding type %u in file '%s'.",View on GitHub (pinned to f788b534b4)
Solutions
- Re-export the image as 8-bit or 16-bit truecolor/grayscale PNG (e.g. magick input.png -depth 8 out.png).
- If using pngquant/oxipng, raise the minimum bit depth or skip depth reduction for files destined for CImg.
- Check the file with pngcheck -v or magick identify to confirm its bit depth.
Example fix
// shell: before (1/2/4-bit png) -> after
// magick icon.png -define png:color-type=6 -depth 8 icon8.png
img.load_png("icon8.png"); // now 8-bit, loads fine Defensive patterns
Strategy: fallback
Validate before calling
// inspect IHDR bit depth (byte 24 of the file) before loading
bool supportedDepth(const char *p) {
unsigned char h[26] = {}; std::FILE *f = std::fopen(p,"rb");
if (!f) return false;
size_t n = std::fread(h,1,26,f); std::fclose(f);
return n==26 && (h[24]==8 || h[24]==16);
} Try / catch
try { img.load_png(path); }
catch (CImgIOException &e) {
img.load(path); // fallback loader / pre-converted 8-bit copy
} Prevention
- Standardize image assets on 8-bit PNGs for processing pipelines
- Check bit depth with pngcheck/identify during asset ingestion
- Avoid depth-reducing optimizers (pngquant) on inputs fed to CImg
When it happens
Trigger: Loading a paletted or grayscale PNG stored with 1/2/4-bit depth (common for icons, small sprites, optimized PNGs) via load_png().
Common situations: Icons exported from design tools with 'PNG-8'/indexed or bit-depth-reduced settings; optimized PNGs from compressors like pngquant/oxipng; low-color screenshots.
Related errors
- load_png(): Invalid color coding type %u in file '%s'.
- load_png(): Invalid PNG file '%s'.
- load_pnm(): PNM type 'P%d' found, but type is not supported.
- load_webp(): Does not support animated WebP '%s'.
- cimg::SDL3_attr(): %s
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/c72269cfc21161c5.
Report an issue: GitHub.