{"record":{"id":"b9600333a88c1200","repo":"Yalantis/uCrop","slug":"haar-sub-image-width-u-is-not-even","errorCode":null,"errorMessage":"haar(): Sub-image width %u is not even.","messagePattern":"haar\\(\\): Sub-image width %u is not even\\.","errorType":"exception","errorClass":"CImgInstanceException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":47390,"sourceCode":"       \\param invert Set inverse of direct transform.\n       \\param nb_scales Number of scales used for the transform.\n    **/\n    CImg<T>& haar(const char axis, const bool invert=false, const unsigned int nb_scales=1) {\n      return get_haar(axis,invert,nb_scales).move_to(*this);\n    }\n\n    //! Compute Haar multiscale wavelet transform \\newinstance.\n    CImg<Tfloat> get_haar(const char axis, const bool invert=false, const unsigned int nb_scales=1) const {\n      if (is_empty() || !nb_scales) return +*this;\n      CImg<Tfloat> res;\n      const Tfloat sqrt2 = std::sqrt(2.f);\n      if (nb_scales==1) {\n        switch (cimg::lowercase(axis)) { // Single scale transform\n        case 'x' : {\n          const unsigned int w = _width/2;\n          if (w) {\n            if ((w%2) && w!=1)\n              throw CImgInstanceException(_cimg_instance\n                                          \"haar(): Sub-image width %u is not even.\",\n                                          cimg_instance,\n                                          w);\n\n            res.assign(_width,_height,_depth,_spectrum);\n            if (invert) cimg_forYZC(*this,y,z,c) { // Inverse transform along X\n              for (unsigned int x = 0, xw = w, x2 = 0; x<w; ++x, ++xw) {\n                const Tfloat val0 = (Tfloat)(*this)(x,y,z,c), val1 = (Tfloat)(*this)(xw,y,z,c);\n                res(x2++,y,z,c) = (val0 - val1)/sqrt2;\n                res(x2++,y,z,c) = (val0 + val1)/sqrt2;\n              }\n            } else cimg_forYZC(*this,y,z,c) { // Direct transform along X\n              for (unsigned int x = 0, xw = w, x2 = 0; x<w; ++x, ++xw) {\n                const Tfloat val0 = (Tfloat)(*this)(x2++,y,z,c), val1 = (Tfloat)(*this)(x2++,y,z,c);\n                res(x,y,z,c) = (val0 + val1)/sqrt2;\n                res(xw,y,z,c) = (val1 - val0)/sqrt2;\n              }\n            }","sourceCodeStart":47372,"sourceCodeEnd":47408,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L47372-L47408","documentation":"CImg::haar() performs a Haar wavelet transform along the X axis. For a single-scale transform it splits the width in half (w = _width/2) and requires each sub-image width to be even (w%2==0) or equal to 1; otherwise the recursive sub-division of the signal is impossible and it throws CImgInstanceException.","triggerScenarios":"Calling img.get_haar('x', invert, nb_scales=1) when the half-width (width/2) is odd and greater than 1 — e.g. width = 6, 10, 14 (half = 3, 5, 7) or any width where width/2 is odd.","commonSituations":"Applying the Haar transform to arbitrarily sized images (e.g. odd or non-power-of-two widths from a camera or crop), passing nb_scales=1 on an image whose width/2 is odd, inverting a transform applied to a resized image.","solutions":["Use an image width that is a power of two (or ensure width/2 is even or 1).","Resize/pad the image to the next power of two before calling: img.get_resize(w2,h2) or pad with zeros.","Increase nb_scales to use the multi-scale version, which handles sizes differently.","Compute the largest valid scale: only descend while (dim/2) is even."],"exampleFix":"// before\nCImg<> out = img6x8.get_haar('x', false, 1); // width 6 -> half 3, odd\n// after\nCImg<> padded = img6x8.get_resize(8, img6x8.height());\nCImg<> out = padded.get_haar('x', false, 1);","handlingStrategy":"validation","validationCode":"if (unsigned w = img.width()/2; (w % 2) && w != 1) img = img.get_resize(nextPow2(img.width()), img.height());","typeGuard":"bool haarXOk(const CImg<T>& img) {\n  unsigned w = img.width()/2;\n  return w == 0 || !(w % 2) || w == 1;\n}","tryCatchPattern":"try {\n  res = img.get_haar('x', invert, nb_scales);\n} catch (const CImgInstanceException& e) {\n  res = img.get_resize(pow2ceil(img.width()), img.height()).get_haar('x', invert, nb_scales);\n}","preventionTips":["Prefer power-of-two image widths for wavelet work.","Pad with zeros to the next power of two before transforming.","Remember the constraint applies to width/2, not width itself."],"tags":["cimg","wavelet","haar","dimension-mismatch"],"backgroundTag":"invalid-argument-value","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}