{"record":{"id":"52235c0d53865d84","repo":"Yalantis/uCrop","slug":"cimg-s-s-u-cubic-atxy-empty-instance","errorCode":null,"errorMessage":"CImg<%s>::%s() [%u]: cubic_atXY(): Empty instance.","messagePattern":"CImg<(.+?)>::(.+?)\\(\\) \\[%u\\]: cubic_atXY\\(\\): Empty instance\\.","errorType":"exception","errorClass":"CImgInstanceException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":16447,"sourceCode":"    /**\n       Similar to cubic_atXY(float,float,int,int,const T) const, except that the return value is clamped to stay in the\n       min/max range of the datatype \\c T.\n    **/\n    T cubic_atXY_c(const float fx, const float fy, const int z, const int c, const T& out_value) const {\n      return cimg::type<T>::cut(cubic_atXY(fx,fy,z,c,out_value));\n    }\n\n    //! Return pixel value, using cubic interpolation and Neumann boundary conditions for the X and Y-coordinates.\n    /**\n       Similar to cubic_atX(float,int,int,int) const, except that the cubic interpolation and boundary checking\n       are achieved for both X and Y-coordinates.\n       \\note\n       - If you know your image instance is \\e not empty, you may rather use the slightly faster method\n       \\c _cubic_atXY(float,float,int,int).\n    **/\n    Tfloat cubic_atXY(const float fx, const float fy, const int z=0, const int c=0) const {\n      if (is_empty())\n        throw CImgInstanceException(_cimg_instance\n                                    \"cubic_atXY(): Empty instance.\",\n                                    cimg_instance);\n      return _cubic_atXY(fx,fy,z,c);\n    }\n\n    Tfloat _cubic_atXY(const float fx, const float fy, const int z=0, const int c=0) const {\n      const float\n        nfx = cimg::type<float>::is_nan(fx)?0:cimg::cut(fx,0.f,width() - 1.f),\n        nfy = cimg::type<float>::is_nan(fy)?0:cimg::cut(fy,0.f,height() - 1.f);\n      const int x = (int)nfx, y = (int)nfy;\n      const float dx = nfx - x, dy = nfy - y;\n      const int\n        px = x - 1<0?0:x - 1, nx = dx<=0?x:x + 1, ax = x + 2>=width()?width() - 1:x + 2,\n        py = y - 1<0?0:y - 1, ny = dy<=0?y:y + 1, ay = y + 2>=height()?height() - 1:y + 2;\n      const Tfloat\n        Ipp = (Tfloat)(*this)(px,py,z,c), Icp = (Tfloat)(*this)(x,py,z,c), Inp = (Tfloat)(*this)(nx,py,z,c),\n        Iap = (Tfloat)(*this)(ax,py,z,c),\n        Ip = Icp + 0.5f*(dx*(-Ipp + Inp) + dx*dx*(2*Ipp - 5*Icp + 4*Inp - Iap) + dx*dx*dx*(-Ipp + 3*Icp - 3*Inp + Iap)),","sourceCodeStart":16429,"sourceCodeEnd":16465,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L16429-L16465","documentation":"cubic_atXY() performs bicubic interpolation at floating-point (x,y) coordinates. The empty-instance check throws CImgInstanceException if the image has no pixel data, since bicubic sampling of a null buffer is meaningless and would read out of bounds.","triggerScenarios":"Calling cubic_atXY(fx,fy,...) on a default-constructed CImg, an image after clear(), or one where load() failed (e.g. missing/corrupt file), including calls made indirectly through get_resize/warp-style helpers that use it internally.","commonSituations":"Image warping/undistortion code fed an image that failed to load; crop pipelines in Android JNI (ucrop) where a bitmap decode failed before CImg was filled.","solutions":["Check img.is_empty() (or operator bool) before any interpolation call.","Handle load failures explicitly and propagate an error instead of passing the empty image on.","Assert non-empty dimensions in the crop/transform entry point.","Catch CImgInstanceException at the API boundary and return a meaningful error to the caller."],"exampleFix":"// before\nCImg<float> img = src.get_crop(0,0,-1,-1); // src empty -> crop also empty\nfloat v = img.cubic_atXY(10.2f, 5.7f); // throws\n// after\nif (!src.is_empty()) {\n  CImg<float> img = src.get_crop(0,0,src.width()-1,src.height()-1);\n  float v = img.cubic_atXY(10.2f, 5.7f);\n}","handlingStrategy":"validation","validationCode":"if (img.is_empty()) throw std::runtime_error(\"source image not loaded\");\nfloat v = img.cubic_atXY(fx, fy, z, c);","typeGuard":"explicit operator bool exists in CImg: if (!img) { /* empty */ }","tryCatchPattern":"try {\n  float v = img.cubic_atXY(fx, fy);\n} catch (const CImgInstanceException& e) {\n  Log(\"bicubic on empty image: %s\", e.what());\n  return kFallbackPixel;\n}","preventionTips":["Check the boolean state of the image right after loading/decoding.","In JNI/Android code, verify the decoded bitmap is non-null and non-zero-sized before creating the CImg.","Add debug assertions for non-empty images at function entry.","Centralize image loading in one helper that never returns empty images on success."],"tags":["cimg","image-processing","interpolation","empty-instance"],"backgroundTag":"empty-required-field","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}