Yalantis/uCrop · error · CImgInstanceException
CMYKtoCMY(): Instance is not a CMYK image.
Error message
CMYKtoCMY(): Instance is not a CMYK image.
What it means
get_CMYKtoCMY() converts a 4-channel CMYK image to a new 3-channel CMY image; it requires _spectrum==4. CImg throws CImgInstanceException when the image does not have four channels, since it reads four source planes including the K (black) plane.
Solutions
- Guard with if (img.spectrum()==4) before calling.
- For RGB input, call RGBtoCMY() instead of CMYKtoCMY().
- Verify the source really is CMYK from the loader/ICC profile, not just channel count.
- Catch CImgInstanceException and route by spectrum.
Example fix
// before img.CMYKtoCMY(); // img is RGB, spectrum=3 // after if (img.spectrum()==4) img.CMYKtoCMY(); else if (img.spectrum()==3) img.RGBtoCMY();
Defensive patterns
Strategy: validation
Validate before calling
if (img.spectrum()!=4) throw std::runtime_error("CMYKtoCMY requires 4-channel CMYK image");
CImg<float> cmy = img.get_CMYKtoCMY(); Type guard
bool isCMYK(const cimg_library::CImg<T>& img) { return img.spectrum()==4; } Try / catch
try {
img.CMYKtoCMY();
} catch (const cimg_library::CImgInstanceException& e) {
std::cerr << "Need CMYK (4 channels), got " << img.spectrum() << std::endl;
} Prevention
- Confirm the loader actually produced CMYK (spectrum==4) before this path
- Use RGBtoCMY() for RGB sources instead of forcing the CMYK path
- Dispatch conversions by img.spectrum() rather than assumed file format
When it happens
Trigger: Calling img.CMYKtoCMY() or img.get_CMYKtoCMY() on RGB (3-channel), grayscale, or empty images.
Common situations: Mixed print pipelines where RGB files reach a CMYK-only code path; images whose alpha or extra channel made the count 3 or 5; incorrect loading order.
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
- CMYtoCMYK(): Instance is not a CMY image.
- CMYtoRGB(): Instance is not a CMY image.
- RGBtoCMY(): Instance is not a RGB image.
- RGBtoXYZ(): Instance is not a RGB image.
- RGBtoYCbCr(): Instance is not a RGB image.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/fbbd743181d890c6.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:37500
if (K>=255) C = M = Y = 0;
else { const Tfloat K1 = 255 - K; C = 255*(C - K)/K1; M = 255*(M - K)/K1; Y = 255*(Y - K)/K1; }
pd1[N] = (Tfloat)cimg::cut(C,0,255),
pd2[N] = (Tfloat)cimg::cut(M,0,255),
pd3[N] = (Tfloat)cimg::cut(Y,0,255),
pd4[N] = (Tfloat)cimg::cut(K,0,255);
}
return res;
}
//! Convert pixel values from CMYK to CMY color spaces.
CImg<T>& CMYKtoCMY() {
return get_CMYKtoCMY().move_to(*this);
}
//! Convert pixel values from CMYK to CMY color spaces \newinstance.
CImg<Tfloat> get_CMYKtoCMY() const {
if (_spectrum!=4)
throw CImgInstanceException(_cimg_instance
"CMYKtoCMY(): Instance is not a CMYK image.",
cimg_instance);
CImg<Tfloat> res(_width,_height,_depth,3);
const T *ps1 = data(0,0,0,0), *ps2 = data(0,0,0,1), *ps3 = data(0,0,0,2), *ps4 = data(0,0,0,3);
Tfloat *pd1 = res.data(0,0,0,0), *pd2 = res.data(0,0,0,1), *pd3 = res.data(0,0,0,2);
const longT whd = (longT)width()*height()*depth();
cimg_pragma_openmp(parallel for cimg_openmp_if_size(whd,1024))
for (longT N = 0; N<whd; ++N) {
const Tfloat
C = (Tfloat)ps1[N],
M = (Tfloat)ps2[N],
Y = (Tfloat)ps3[N],
K = (Tfloat)ps4[N],
K1 = 1 - K/255,
nC = C*K1 + K,
nM = M*K1 + K,
nY = Y*K1 + K;View on GitHub (pinned to f788b534b4)