#ifndef _OTB_TRISKELE_COMP_ATTRIBUTE_TPP #define _OTB_TRISKELE_COMP_ATTRIBUTE_TPP template inline CompAttribute::CompAttribute (const Tree &tree) : tree (tree), leafCount (0), values (nullptr) { updateTranscient (); } template inline CompAttribute::~CompAttribute () { free (); } template inline void CompAttribute::updateTranscient () { book (tree.getLeafCount ()); } template inline const AttrT * CompAttribute::getValues () const { return values; } template inline AttrT * CompAttribute::getValues () { return values; } template inline AttrT CompAttribute::getMaxValue () const { if (!leafCount) return 0; AttrT max = values[0]; CompAttribute::tree.forEachComp ([this, &max] (const DimImg &compId) { if (values[compId] > max) max = values[compId]; }); return max; } template inline void CompAttribute::printValues (const string &msg) const { cout << "values: " << msg << endl; const Size doubleSize (tree.getSize().width, 2*tree.getSize ().height); printMap (cout, values, doubleSize, tree.getCompCount ()) << endl << endl; } template inline void CompAttribute::free () { if (values) delete[] values; values = nullptr; } template inline void CompAttribute::book (const DimImg &leafCount) { if (this->leafCount == leafCount) return; free (); if (!leafCount) return; this->leafCount = leafCount; values = new AttrT[leafCount]; } // ======================================== template inline CompAttributeC::CompAttributeC (const Tree &tree) : CompAttribute (tree) { } template inline CompAttributeC::~CompAttributeC () { } template inline vector CompAttributeC::getScaledThresholds (const vector &thresholds, const AttrT &maxValue) { vector result; for (AttrT percent : thresholds) result.push_back (percent*maxValue); return result; } template template inline void CompAttributeC::computeSameCompLevel (const CumpFunctPSE &cumpFunctPSE) const { const vector &weightBounds (CompAttribute::tree.getWeightBounds ()); unsigned int coreCount = CompAttribute::tree.getCoreCount (); DEF_LOG ("CompAttributeC::computeSameCompLevel", "coreCount:" << coreCount); if (!weightBounds.size () || CompAttribute::tree.getCompCount ()/weightBounds.size () < coreCount) { LOG ("CompAttributeC::computeSameCompLevel: no thread"); CompAttribute::tree.forEachComp (cumpFunctPSE); return; } DimImg first = weightBounds [0]; for (DimImg curBound = 1; curBound < weightBounds.size (); curBound++) { DimImg next = weightBounds [curBound]; dealThreadRange (next-first, coreCount, [this, &first, &cumpFunctPSE] (const DimImg &id) { const DimImg parentId = id+first; cumpFunctPSE (parentId); }); first = next; } } template template inline void CompAttributeC::cut (vector > &allBands, const AttributeProfiles &attributeProfiles, const AttrT &pixelAttrValue, const vector &thresholds) const { DEF_LOG ("CompAttributeC::cut", "coreCount:" << CompAttribute::tree.getCoreCount () << " thresholds:" << thresholds.size ()); dealThreadRange (CompAttribute::leafCount, CompAttribute::tree.getCoreCount (), [this, &allBands, &attributeProfiles, &pixelAttrValue, &thresholds] (const DimImg &leafId) { cutOnPos (allBands, attributeProfiles, leafId, pixelAttrValue, thresholds); }); } template template inline void CompAttributeC::cutOnPos (vector > &allBands, const AttributeProfiles &attributeProfiles, const DimImg &leafId, const AttrT &pixelAttrValue, const vector &thresholds) const { // no debug (to many pixels) DimImg parentId = CompAttribute::tree.getLeafParent (leafId); DimChanel thresholdsSize = thresholds.size (); if (parentId == DimImg_MAX) { for (DimChanel chanel = 0; chanel < thresholdsSize; ++chanel) allBands[chanel][leafId] = 0; return; } DimNodeId nodeId = leafId; DimImg curId = 0; AttrT curValue = pixelAttrValue; if (curValue == CompAttribute::values [parentId]) { // skip pixel on flat zone curId = parentId; nodeId = ((DimNodeId)curId)+CompAttribute::leafCount; parentId = CompAttribute::tree.getCompParent (curId); } const PixelT *apValues = attributeProfiles.getValues (); DimImg rootId = CompAttribute::tree.getCompRoot (); for (DimChanel chanel = 0; chanel < thresholdsSize; ++chanel) { AttrT ceil = thresholds[chanel]; for ( ; curValue < ceil && curId < rootId; ) { if (parentId == DimImg_MAX || curId >= parentId) { // cerr << "CompAttributeC::cutOnPos find sub-root:" << rootId << " rootId:" << rootId << endl; for (; chanel < thresholdsSize; ++chanel) allBands[chanel][leafId] = curValue; return; } nodeId = ((DimNodeId) CompAttribute::tree.getLeafParent (nodeId))+CompAttribute::leafCount; curId = parentId; curValue = CompAttribute::values [curId]; parentId = CompAttribute::tree.getCompParent (curId); } // XXX si valeur > root ? allBands[chanel][leafId] = apValues [nodeId]; } } #endif // _OTB_TRISKELE_COMP_ATTRIBUTE_TPP