Skip to content
Snippets Groups Projects
image.cpp 100.26 KiB
#include <algorithm>
#include <numeric>
#include <type_traits>
#include <sstream>

#include "filesystem.h"

#include <gdal.h>
#include <gdal_priv.h>
#include <gdalwarper.h>
#include <gdal_utils.h>
#include <cpl_string.h>

#include "logging.h"
#include "image.h"
#include "geoinfo.h"

namespace {

template <typename Imgtype>
imagefusion::Image merge_impl(std::vector<Imgtype> const& images) {
    std::vector<cv::Mat> cvImages;
    cvImages.reserve(images.size());
    for (auto const& i : images)
        cvImages.push_back(i.cvMat()); // OpenCV shared copy

//    unsigned int totalChannels = std::accumulate(images.begin(), images.end(), 0, [] (Imgtype const& i, unsigned int count) { return count + i.channels(); });
    imagefusion::Image multichannel;
    cv::merge(cvImages, multichannel.cvMat());
    return multichannel;
}


std::string getGDALMemOptionString(imagefusion::ConstImage const& i) {
    char szPtrValue[128] = { '\0' };
    int nRet = CPLPrintPointer(szPtrValue,
                               reinterpret_cast<void*>(const_cast<uchar*>(i.cvMat().ptr())),
                               sizeof(szPtrValue));
    szPtrValue[nRet] = 0;

    std::ostringstream ss;
    ss << "MEM:::DATAPOINTER=" << szPtrValue
       << ",PIXELS="           << i.width()
       << ",LINES="            << i.height()
       << ",BANDS="            << i.channels()
       << ",DATATYPE="         << GDALGetDataTypeName(toGDALDepth(i.type()))
       << ",PIXELOFFSET="      << i.cvMat().elemSize()
       << ",LINEOFFSET="       << i.cvMat().ptr(1) - i.cvMat().ptr(0)
       << ",BANDOFFSET="       << i.cvMat().elemSize1();
    return ss.str();
}

} /* anonymous namespace */

namespace imagefusion {

// Implementation

GDALDataset const* ConstImage::asGDALDataset() const {
    // This reads the OpenCV Mat as GDAL Dataset. See ConstImage::write for more info!
    std::string optStr = getGDALMemOptionString(*this);
    return (GDALDataset*) GDALOpen(optStr.c_str(), GA_ReadOnly);
}


GDALDataset* Image::asGDALDataset() {
    // This reads the OpenCV Mat as GDAL Dataset. See ConstImage::write for more info!
    std::string optStr = getGDALMemOptionString(*this);
    return (GDALDataset*) GDALOpen(optStr.c_str(), GA_Update);
}