Yalantis/uCrop · error · CImgInstanceException

YUVtoRGB(): Instance is not a YUV image.

Error message

YUVtoRGB(): Instance is not a YUV image.

What it means

YUVtoRGB() converts channels from YUV back to RGB in place and, despite the message saying 'not a YUV image', the actual check is the same _spectrum!=3 precondition shared by all 3-channel color conversions. Any image without exactly three channels throws.

Source

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

          G = (Tfloat)p2[N]/255,
          B = (Tfloat)p3[N]/255,
          Y = 0.299f*R + 0.587f*G + 0.114f*B;
        p1[N] = (T)Y;
        p2[N] = (T)(0.492f*(B - Y));
        p3[N] = (T)(0.877*(R - Y));
      }
      return *this;
    }

    //! Convert pixel values from RGB to YUV color spaces \newinstance.
    CImg<Tfloat> get_RGBtoYUV() const {
      return CImg<Tfloat>(*this,false).RGBtoYUV();
    }

    //! Convert pixel values from YUV to RGB color spaces.
    CImg<T>& YUVtoRGB() {
      if (_spectrum!=3)
        throw CImgInstanceException(_cimg_instance
                                    "YUVtoRGB(): Instance is not a YUV image.",
                                    cimg_instance);

      T *p1 = data(0,0,0,0), *p2 = data(0,0,0,1), *p3 = data(0,0,0,2);
      const longT whd = (longT)width()*height()*depth();
      cimg_pragma_openmp(parallel for cimg_openmp_if_size(whd,16384))
      for (longT N = 0; N<whd; ++N) {
        const Tfloat
          Y = (Tfloat)p1[N],
          U = (Tfloat)p2[N],
          V = (Tfloat)p3[N],
          R = (Y + 1.140f*V)*255,
          G = (Y - 0.395f*U - 0.581f*V)*255,
          B = (Y + 2.032f*U)*255;
        p1[N] = (T)cimg::cut(R,0,255),
        p2[N] = (T)cimg::cut(G,0,255),
        p3[N] = (T)cimg::cut(B,0,255);
      }

View on GitHub (pinned to f788b534b4)

Solutions

  1. Check spectrum()==3 before calling.
  2. Reduce 4-channel inputs with channels(0,2); expand 1-channel with get_append.
  3. Verify the preceding RGBtoYUV() actually succeeded on a 3-channel image.
  4. Catch CImgInstanceException with a diagnostic including img.spectrum().

Example fix

// before
img.YUVtoRGB();
// after
assert(img.spectrum()==3);
img.YUVtoRGB();
Defensive patterns

Strategy: validation

Validate before calling

assert(img.spectrum()==3);
if (img.spectrum()!=3) throw std::runtime_error("YUV image must have 3 channels");

Type guard

bool isYUV(const cimg_library::CImg<T>& img) { return img.spectrum()==3; }

Try / catch

try {
  img.YUVtoRGB();
} catch (const cimg_library::CImgInstanceException& e) {
  std::cerr << "YUVtoRGB failed: " << e.what() << std::endl;
}

Prevention

When it happens

Trigger: Calling img.YUVtoRGB() on grayscale, RGBA, 4-channel (e.g. leftover CMYK), or empty images.

Common situations: Decoders that output 4-channel buffers; pipelines where YUVtoRGB is called on already-RGB images that were later reduced to one channel; mis-constructed CImg buffers.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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