Yalantis/uCrop · warning

save_pnm(): Instance has pixel values in [%g,%g], probable t

Error message

save_pnm(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.

What it means

CImg's save_pnm() emits this non-fatal warning when the image's pixel value range cannot be represented in the PNM output bit depth (8-bit when max<256, else 16-bit). PNM only supports unsigned integer samples, so negative values or values above the representable maximum will silently wrap/clamp on write. The library warns via cimg::warn() so the developer knows output pixels may be corrupted.

Source

Thrown at ucrop/src/main/jni/CImg.h:62292

      if (!file && !filename)
        throw CImgArgumentException(_cimg_instance
                                    "save_pnm(): Specified filename is (null).",
                                    cimg_instance);
      if (is_empty()) { cimg::fempty(file,filename); return *this; }

      double stmin, stmax = (double)max_min(stmin);
      if (_depth>1)
        cimg::warn(_cimg_instance
                   "save_pnm(): Instance is volumetric, only the first slice will be saved in file '%s'.",
                   cimg_instance,
                   filename?filename:"(FILE*)");
      if (_spectrum>3)
        cimg::warn(_cimg_instance
                   "save_pnm(): Instance is multispectral, only the three first channels will be saved in file '%s'.",
                   cimg_instance,
                   filename?filename:"(FILE*)");
      if (stmin<0 || (bytes_per_pixel==1 && stmax>=256) || stmax>=65536)
        cimg::warn(_cimg_instance
                   "save_pnm(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.",
                   cimg_instance,
                   stmin,stmax,filename?filename:"(FILE*)");

      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
      const T
        *ptr_r = data(0,0,0,0),
        *ptr_g = (_spectrum>=2)?data(0,0,0,1):0,
        *ptr_b = (_spectrum>=3)?data(0,0,0,2):0;
      const ulongT buf_size = std::min((ulongT)(1024*1024),(ulongT)(_width*_height*(_spectrum==1?1UL:3UL)));

      std::fprintf(nfile,"P%c\n%u %u\n%u\n",
                   (_spectrum==1?'5':'6'),_width,_height,stmax<256?255:(stmax<4096?4095:65535));

      switch (_spectrum) {
      case 1 : { // Scalar image
        if (bytes_per_pixel==1 || (!bytes_per_pixel && stmax<256)) { // Binary PGM 8 bits
          CImg<ucharT> buf((unsigned int)buf_size);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Normalize the image before saving: img.normalize(0,255) (or cut(0,255)) so the range fits the PNM bit depth
  2. If negative values are expected, cut them: img.cut(0,255) prior to save
  3. Save in a format supporting arbitrary ranges (PNG, TIFF, PFM, EXR) instead of PNM
  4. If the overflow is intentional/acceptable, raise the warning threshold or ignore cimg warnings via cimg::exception_mode

Example fix

// before
img.save_pnm("out.pnm");            // warns: pixel range [0.3,12.7]
// after
img.get_normalize(0,255).save_pnm("out.pnm");
Defensive patterns

Strategy: validation

Validate before calling

if (img.min() < 0 || img.max() >= (img.pixel_type_size()==1 ? 256 : 65536))
  img.normalize(0, 255); // or choose a range-appropriate format
img.save_pnm("out.pnm");

Try / catch

try { img.save_pnm("out.pnm"); } catch (CImgException& e) { /* handle save failure */ }

Prevention

When it happens

Trigger: Calling save_pnm()/save_pnm_pnm()/save_pnm_pgm()/save_pnm_ppm() on a CImg<T> whose minimum value stmin is negative, or whose maximum stmax is >=256 with 1-byte pixels, or >=65536 generally. Typical with float images (values 0..1 saved fine, but unnormalized floats or signed images overflow) or int16/int32 images with negative pixels.

Common situations: Saving a processed image that was computed in signed or float space (e.g. after subtracting images, convolution results, gradients) directly to PNM/PGM/PPM without normalizing to [0,255] or [0,65535]. Loading a 16-bit image and saving as 8-bit PNM. Debug pixel values outside [0,255] due to a bad normalization formula.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/2f852b9e5a01ff67. Report an issue: GitHub.