{"record":{"id":"c98a88fd5bf6618c","repo":"Yalantis/uCrop","slug":"save-exr-specified-filename-is-null","errorCode":null,"errorMessage":"save_exr(): Specified filename is (null).","messagePattern":"save_exr\\(\\): Specified filename is \\(null\\)\\.","errorType":"exception","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":63119,"sourceCode":"                          voxel_size[0],voxel_size[1],voxel_size[2]);\n      err+=cimg_snprintf(header._data + err,128,\"TYPE=%s\\nCPU=%s\\n\",\n                         inrtype,cimg::endianness()?\"sun\":\"decm\");\n      std::memset(header._data + err,'\\n',252 - err);\n      std::memcpy(header._data + 252,\"##}\\n\",4);\n      cimg::fwrite(header._data,256,nfile);\n      cimg_forXYZ(*this,x,y,z) cimg_forC(*this,c) cimg::fwrite(&((*this)(x,y,z,c)),1,nfile);\n      if (!file) cimg::fclose(nfile);\n      return *this;\n    }\n\n    //! Save image as an OpenEXR file.\n    /**\n       \\param filename Filename, as a C-string.\n       \\note The OpenEXR file format is <a href=\"http://en.wikipedia.org/wiki/OpenEXR\">described here</a>.\n    **/\n    const CImg<T>& save_exr(const char *const filename) const {\n      if (!filename)\n        throw CImgArgumentException(_cimg_instance\n                                    \"save_exr(): Specified filename is (null).\",\n                                    cimg_instance);\n      if (is_empty()) { cimg::fempty(0,filename); return *this; }\n      if (_depth>1)\n        cimg::warn(_cimg_instance\n                   \"save_exr(): Instance is volumetric, only the first slice will be saved in file '%s'.\",\n                   cimg_instance,\n                   filename);\n\n#ifndef cimg_use_openexr\n      return save_other(filename);\n#else\n      Imf::Rgba *const ptrd0 = new Imf::Rgba[(size_t)_width*_height], *ptrd = ptrd0, rgba;\n      switch (_spectrum) {\n      case 1 : { // Grayscale image\n        for (const T *ptr_r = data(), *const ptr_e = ptr_r + (ulongT)_width*_height; ptr_r<ptr_e;) {\n          rgba.r = (half)(*(ptr_r));\n          rgba.g = (half)(*(ptr_r));","sourceCodeStart":63101,"sourceCodeEnd":63137,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L63101-L63137","documentation":"save_exr() validates its filename argument before touching OpenEXR and throws CImgArgumentException on a null C-string, printing the literal '(null)'. It is the standard null-check guard used by all CImg savers, raised before the volumetric-slice warning or any file I/O.","triggerScenarios":"Calling CImg::save_exr(NULL) or forwarding a null filename through save(); typically from an uninitialized pointer, a getenv() that returned NULL, or a failed path computation whose result was not checked. Note this error requires OpenEXR support to even be reachable in some builds.","commonSituations":"EXR output path read from config/env that was unset; string helper returning NULL on failure; caller passing a std::string::c_str() of an empty-constructed-from-null pointer.","solutions":["Check the filename for null/empty before the call and raise a clear error identifying the missing path source.","Fix the upstream path producer (env var, config key, argument parsing) so it yields a valid string.","If holding an open stream is more natural, use a writer overload accepting FILE* if available for your format, or open the file yourself first.","Centralize filename validation in a save helper so all export paths get the same guard."],"exampleFix":"// before\nconst char *out = getenv(\"EXR_PATH\");\nimg.save_exr(out); // throws when EXR_PATH unset\n\n// after\nconst char *out = getenv(\"EXR_PATH\");\nif (!out || !*out) throw std::runtime_error(\"EXR_PATH is required\");\nimg.save_exr(out);","handlingStrategy":"validation","validationCode":"if (!filename || !*filename)\n  throw std::invalid_argument(\"save_exr: filename is null or empty\");","typeGuard":"bool valid_path(const char* p) { return p != nullptr && *p != '\\0'; }","tryCatchPattern":"try {\n  img.save_exr(path.c_str());\n} catch (const CImgArgumentException& e) {\n  std::fprintf(stderr, \"EXR save failed, no filename: %s\\n\", e.what());\n}","preventionTips":["Guard getenv()/config path lookups for null","Remember volumetric EXR saves only the first slice — warn on depth>1","Centralize filename validation before all save_* calls"],"tags":["cimg","openexr","null-argument","filename"],"backgroundTag":"null-argument","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}