Yalantis/uCrop · error · CImgInstanceException
CMYtoRGB(): Instance is not a CMY image.
Error message
CMYtoRGB(): Instance is not a CMY image.
What it means
CMYtoRGB() converts CMY channels back to RGB in place and requires exactly 3 channels; the same _spectrum!=3 check triggers the exception. The message 'not a CMY image' reflects the expected source color space, but the check is purely channel-count based.
Source
Thrown at ucrop/src/main/jni/CImg.h:37432
C = 255 - R,
M = 255 - G,
Y = 255 - B;
p1[N] = (T)cimg::cut(C,0,255),
p2[N] = (T)cimg::cut(M,0,255),
p3[N] = (T)cimg::cut(Y,0,255);
}
return *this;
}
//! Convert pixel values from RGB to CMY color spaces \newinstance.
CImg<Tuchar> get_RGBtoCMY() const {
return CImg<Tfloat>(*this,false).RGBtoCMY();
}
//! Convert pixel values from CMY to RGB color spaces.
CImg<T>& CMYtoRGB() {
if (_spectrum!=3)
throw CImgInstanceException(_cimg_instance
"CMYtoRGB(): Instance is not a CMY 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,2048))
for (longT N = 0; N<whd; ++N) {
const Tfloat
C = (Tfloat)p1[N],
M = (Tfloat)p2[N],
Y = (Tfloat)p3[N],
R = 255 - C,
G = 255 - M,
B = 255 - Y;
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
- Check spectrum()==3 before calling.
- If the image is CMYK (4 channels), call CMYKtoCMY() first, then CMYtoRGB().
- Expand grayscale to 3 channels with get_append before treating as CMY.
- Catch CImgInstanceException and log the actual spectrum.
Example fix
// before CImg<float> img = loadCMYK(); // spectrum 4 img.CMYtoRGB(); // after CImg<float> img = loadCMYK(); if (img.spectrum()==4) img.CMYKtoCMY().CMYtoRGB(); else if (img.spectrum()==3) img.CMYtoRGB();
Defensive patterns
Strategy: validation
Validate before calling
if (img.spectrum()==4) img.CMYKtoCMY();
if (img.spectrum()!=3) throw std::runtime_error("CMY image with 3 channels required"); Type guard
bool isCMY(const cimg_library::CImg<T>& img) { return img.spectrum()==3; } Try / catch
try {
img.CMYtoRGB();
} catch (const cimg_library::CImgInstanceException& e) {
std::cerr << "CMY required; spectrum=" << img.spectrum() << std::endl;
} Prevention
- Route by spectrum: 4 channels => CMYK path, 3 channels => CMY path
- Only convert from CMY that was produced by RGBtoCMY()
- Log spectrum values when conversion pipelines fail
When it happens
Trigger: Calling img.CMYtoRGB() on grayscale, RGBA, 4-channel CMYK, or empty images.
Common situations: Print workflows where a 4-channel CMYK buffer is passed directly instead of being reduced to CMY; RGB images converted twice; images loaded with unexpected channel counts.
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
- RGBtoYCbCr(): Instance is not a RGB image.
- YCbCrtoRGB(): Instance is not a YCbCr image.
- RGBtoYUV(): Instance is not a RGB image.
- YUVtoRGB(): Instance is not a YUV image.
- RGBtoCMY(): Instance is not a RGB image.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/085c2fc26bf51d76.
Report an issue: GitHub.