/* * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES) * * This file is part of Orfeo Toolbox * * https://www.orfeo-toolbox.org/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef otbNoDataHelper_h #define otbNoDataHelper_h #include #include #include "vnl/vnl_math.h" #include #include "OTBMetadataExport.h" namespace itk { class MetaDataDictionary; } namespace otb { /** * Reads no data flag from the MetaDataDictionary dict to flags and values * vectors. Returns true upon success. */ bool OTBMetadata_EXPORT ReadNoDataFlags(const itk::MetaDataDictionary& dict, std::vector& flags, std::vector& values); /** * Write no data flags to the MetaDataDictionary dict from flags and values * vectors. Returns true upon success. */ void OTBMetadata_EXPORT WriteNoDataFlags(const std::vector& flags, const std::vector& values, itk::MetaDataDictionary& dict); /** * Test if the pixel corresponds to a no data pixel according to a * vector of no data flags, and a vector of no data values. * \param pixel The pixel to test * \param flags A vector of size > 1 containing a flag per band to * indicate if a no data value is available for this band * \param values A vector of size > 1 corresponding to the no data * value for each band. If flag is 0, the value will be ignored. * \param nanIsNoData If true, NaN values will be reported as no-data. */ template bool IsNoData(const T& pixel, const std::vector& flags, const std::vector& values, bool nanIsNoData = false) { assert(flags.size() > 0); assert(values.size() > 0); return ((nanIsNoData && vnl_math_isnan(pixel)) || (flags[0] && (pixel == values[0]))); } /** * Reads a pixel and change the no data value if it is found. No data * value is changed either if the pixel value is NaN or if the pixel * value equals the no data value and flag is true. * * \param pixel The pixel to process \param flags A vector of size > 1 * containing a flag per band to indicate if a no data value is * available for this band * \param values A vector of size > 1 corresponding to the current no data * value for each band. If flag is 0, the value will be ignored. * \param newValues A vector of size > 1 corresponding to the new no data * value for each band. If flag is 0, the value will be ignored * \param nanIsNoData If true, NaN values will be considered as no-data * and changed as well. * */ template T ChangeNoData(const T& pixel, const std::vector& flags, const std::vector& values, const std::vector& newValues, bool nanIsNoData = false) { assert(flags.size() > 0); assert(values.size() > 0); assert(newValues.size() > 0); if (nanIsNoData && vnl_math_isnan(pixel)) { return static_cast(newValues[0]); } if (flags[0] && pixel == values[0]) { return static_cast(newValues[0]); } return pixel; } /** * Specialization of IsNoData function to handle itk::VariableLengthVector */ template bool IsNoData(const itk::VariableLengthVector& pixel, const std::vector& flags, const std::vector& values, bool nanIsNoData = false) { assert(flags.size() >= pixel.Size()); assert(values.size() >= pixel.Size()); for (unsigned int i = 0; i < pixel.Size(); ++i) { if ((nanIsNoData && vnl_math_isnan(pixel[i])) || (flags[i] && (pixel[i] == values[i]))) { return true; } } return false; } /** * Specialization of ChangeNoData function to handle itk::VariableLengthVector */ template itk::VariableLengthVector ChangeNoData(const itk::VariableLengthVector& pixel, const std::vector& flags, const std::vector& values, const std::vector& newValues, bool nanIsNoData = false) { assert(flags.size() >= pixel.Size()); assert(values.size() >= pixel.Size()); assert(newValues.size() >= pixel.Size()); itk::VariableLengthVector outPixel(pixel.Size()); for (unsigned int i = 0; i < pixel.Size(); ++i) { if ((nanIsNoData && vnl_math_isnan(pixel[i])) || (flags[i] && (pixel[i] == values[i]))) { outPixel[i] = newValues[i]; } else { outPixel[i] = pixel[i]; } } return outPixel; } } // End namespace otb #endif