{"record":{"id":"8861c542e365bb17","repo":"Yalantis/uCrop","slug":"draw-circle-specified-color-is-null","errorCode":null,"errorMessage":"draw_circle(): Specified color is (null).","messagePattern":"draw_circle\\(\\): Specified color is \\(null\\)\\.","errorType":"validation","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":52567,"sourceCode":"    }\n\n    //! Draw a filled 2D circle.\n    /**\n       \\param x0 X-coordinate of the circle center.\n       \\param y0 Y-coordinate of the circle center.\n       \\param radius  Circle radius.\n       \\param color Pointer to \\c spectrum() consecutive values, defining the drawing color.\n       \\param opacity Drawing opacity.\n       \\note\n       - Circle version of the Bresenham's algorithm is used.\n    **/\n    template<typename tc>\n    CImg<T>& draw_circle(const int x0, const int y0, int radius,\n                         const tc *const color, const float opacity=1) {\n      if (is_empty()) return *this;\n      if (radius<0 || x0 - radius>=width() || y0 + radius<0 || y0 - radius>=height()) return *this;\n      if (!color)\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_circle(): Specified color is (null).\",\n                                    cimg_instance);\n      if (!radius) return draw_point(x0,y0,color,opacity);\n      cimg_init_scanline(opacity);\n      if (y0>=0 && y0<height()) cimg_draw_scanline(x0 - radius,x0 + radius,y0,color,opacity,1);\n      for (int f = 1 - radius, ddFx = 0, ddFy = -(radius<<1), x = 0, y = radius; x<y; ) {\n        if (f>=0) {\n          const int x1 = x0 - x, x2 = x0 + x, y1 = y0 - y, y2 = y0 + y;\n          if (y1>=0 && y1<height()) cimg_draw_scanline(x1,x2,y1,color,opacity,1);\n          if (y2>=0 && y2<height()) cimg_draw_scanline(x1,x2,y2,color,opacity,1);\n          f+=(ddFy+=2); --y;\n        }\n        const bool no_diag = y!=(x++);\n        ++(f+=(ddFx+=2));\n        const int x1 = x0 - y, x2 = x0 + y, y1 = y0 - x, y2 = y0 + x;\n        if (no_diag) {\n          if (y1>=0 && y1<height()) cimg_draw_scanline(x1,x2,y1,color,opacity,1);\n          if (y2>=0 && y2<height()) cimg_draw_scanline(x1,x2,y2,color,opacity,1);","sourceCodeStart":52549,"sourceCodeEnd":52585,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L52549-L52585","documentation":"The filled-circle overload of draw_circle() throws CImgArgumentException when the color pointer is null. Like the other CImg drawing primitives it validates color after cheap early returns (empty image, radius<0 or fully off-canvas), so the throw fires only for calls that would otherwise draw. The color must point to at least spectrum() channel values.","triggerScenarios":"img.draw_circle(x0,y0,radius,NULL) with a literal null; a color buffer pointer that was never initialized or already freed; wrapper code (JNI/other language binding) passing a null array through as the color parameter.","commonSituations":"Theme/palette lookup returning null for an unknown color name; refactoring that changed argument order so the opacity or radius slot ends up as the color parameter; deserialized color struct with missing data.","solutions":["Supply a valid color array matching the image's spectrum, e.g. unsigned char col[3]={0,255,0}.","Null-check the color before calling and substitute a default or return early.","Verify the overload you call: the pattern-based overload forwards to draw_ellipse, but both require non-null color.","In binding layers, reject null color arrays with a clear managed-language exception before invoking native code."],"exampleFix":"// before\nimg.draw_circle(cx,cy,r,palette.get(name)); // palette.get() can return NULL\n// after\nconst unsigned char* c = palette.get(name);\nif (!c) c = fallbackColor;\nimg.draw_circle(cx,cy,r,c);","handlingStrategy":"validation","validationCode":"if (!color) color = fallbackColor;\nimg.draw_circle(cx,cy,radius,color);","typeGuard":"template<typename T> bool isValidColor(const T* c, int channels){ return c != nullptr; }","tryCatchPattern":"try { img.draw_circle(x0,y0,r,color,opacity); }\ncatch (CImgArgumentException& e) { log_error(\"draw_circle: %s\", e.what()); }","preventionTips":["Null-check color arguments at API boundaries before any CImg draw.","Keep a static default color buffer for fallback.","Verify overload argument order after refactors (color precedes opacity/pattern).","Avoid caching color pointers to buffers you may free before drawing."],"tags":["cimg","image-processing","null-pointer"],"backgroundTag":"null-argument","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"}