From ff2702863919cdb34d85e388d37da8c66abc5e69 Mon Sep 17 00:00:00 2001 From: Rasim Date: Sat, 8 Feb 2020 22:15:02 +0300 Subject: [PATCH] Remove redundant abstract class in IO. Refactor CMakeLists. --- CMakeLists.txt | 16 ++++++++++----- macro.cmake | 9 +++++++++ src/Burst.cpp | 8 ++++---- src/Burst.h | 20 +++++++++---------- src/HDRPlus.cpp | 47 ++++++++++++++++++++++----------------------- src/InputSource.cpp | 32 +++++++++++++++++------------- src/InputSource.h | 36 ++++++++++++---------------------- 7 files changed, 88 insertions(+), 80 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80e2e8d..4f0fab7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,14 @@ cmake_minimum_required(VERSION 3.10) project(HDR_PLUS) +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + include("macro.cmake") set(CMAKE_CXX_STANDARD 11) # Define dependencies link_halide() +link_libtiff() find_package(PNG REQUIRED) find_library(LIBRAW_LIBRARY @@ -13,20 +16,23 @@ find_library(LIBRAW_LIBRARY ) set(src_files - src/HDRPlus.cpp src/align.cpp src/finish.cpp src/merge.cpp src/util.cpp src/InputSource.cpp + src/Burst.cpp) + +set(header_files src/InputSource.h - src/Burst.cpp - src/Burst.h) + src/Burst.h + src/dngwriter.h) include_directories(/usr/local/lib /usr/local/include ${HALIDE_DISTRIB_DIR}/include ${HALIDE_DISTRIB_DIR}/tools) link_directories(/usr/local/lib /usr/local/include) +add_executable(stack_frames src/stack_frames.cpp ${src_files}) +target_link_libraries(stack_frames Halide png ${LIBRAW_LIBRARY} ${TIFF_LIBRARIES}) -add_executable(hdrplus ${src_files}) - +add_executable(hdrplus src/HDRPlus.cpp ${src_files}) target_link_libraries(hdrplus Halide png ${LIBRAW_LIBRARY}) diff --git a/macro.cmake b/macro.cmake index bb2a05d..12d34cc 100644 --- a/macro.cmake +++ b/macro.cmake @@ -8,3 +8,12 @@ macro(link_halide) include_directories(${HALIDE_DISTRIB_DIR}/include ${HALIDE_DISTRIB_DIR}/tools) link_directories(${HALIDE_DISTRIB_DIR}/lib ${HALIDE_DISTRIB_DIR}/bin) endmacro() + +macro(link_libtiff) + # Link as follows: + # target_link_libraries(TARGET ${TIFF_LIBRARIES}) + find_package(TIFF REQUIRED) + if (TIFF_FOUND) + include_directories(${TIFF_INCLUDE_DIRS}) + endif() +endmacro() diff --git a/src/Burst.cpp b/src/Burst.cpp index 9d08fd8..69187df 100644 --- a/src/Burst.cpp +++ b/src/Burst.cpp @@ -8,7 +8,7 @@ Halide::Runtime::Buffer Burst::ToBuffer() const { Halide::Runtime::Buffer result(GetWidth(), GetHeight(), Raws.size()); for (int i = 0; i < Raws.size(); ++i) { auto resultSlice = result.sliced(2, i); - Raws[i]->CopyToBuffer(resultSlice); + Raws[i].CopyToBuffer(resultSlice); } return result; } @@ -17,11 +17,11 @@ void Burst::CopyToBuffer(Halide::Runtime::Buffer &buffer) const { buffer.copy_from(ToBuffer()); } -std::vector Burst::LoadRaws(const std::string &dirPath, std::vector &inputs) { - std::vector result; +std::vector Burst::LoadRaws(const std::string &dirPath, std::vector &inputs) { + std::vector result; for (const auto& input : inputs) { const std::string img_path = dirPath + "/" + input; - result.emplace_back(std::make_shared(img_path)); + result.emplace_back(img_path); } return result; } diff --git a/src/Burst.h b/src/Burst.h index 5d846a1..3b5581e 100644 --- a/src/Burst.h +++ b/src/Burst.h @@ -8,7 +8,7 @@ #include #include -class Burst : public AbstractInputSource { +class Burst { public: Burst(std::string dir_path, std::vector inputs) : Dir(std::move(dir_path)) @@ -16,27 +16,27 @@ class Burst : public AbstractInputSource { , Raws(LoadRaws(Dir, Inputs)) {} - ~Burst() override = default; + ~Burst() = default; - int GetWidth() const override { return Raws.empty() ? -1 : Raws[0]->GetWidth(); } + int GetWidth() const { return Raws.empty() ? -1 : Raws[0].GetWidth(); } - int GetHeight() const override { return Raws.empty() ? -1 : Raws[0]->GetHeight(); } + int GetHeight() const { return Raws.empty() ? -1 : Raws[0].GetHeight(); } - int GetBlackLevel() const override { return Raws.empty() ? -1 : Raws[0]->GetBlackLevel(); } + int GetBlackLevel() const { return Raws.empty() ? -1 : Raws[0].GetBlackLevel(); } - int GetWhiteLevel() const override { return Raws.empty() ? -1 : Raws[0]->GetWhiteLevel(); } + int GetWhiteLevel() const { return Raws.empty() ? -1 : Raws[0].GetWhiteLevel(); } - WhiteBalance GetWhiteBalance() const override { return Raws.empty() ? WhiteBalance{-1, -1, -1, -1} : Raws[0]->GetWhiteBalance(); } + WhiteBalance GetWhiteBalance() const { return Raws.empty() ? WhiteBalance{-1, -1, -1, -1} : Raws[0].GetWhiteBalance(); } Halide::Runtime::Buffer ToBuffer() const; - void CopyToBuffer(Halide::Runtime::Buffer& buffer) const override; + void CopyToBuffer(Halide::Runtime::Buffer& buffer) const; private: std::string Dir; std::vector Inputs; - std::vector Raws; + std::vector Raws; private: - static std::vector LoadRaws(const std::string& dirPath, std::vector& inputs); + static std::vector LoadRaws(const std::string& dirPath, std::vector& inputs); }; diff --git a/src/HDRPlus.cpp b/src/HDRPlus.cpp index 4ed5660..137aef8 100644 --- a/src/HDRPlus.cpp +++ b/src/HDRPlus.cpp @@ -19,17 +19,17 @@ using namespace std; * processes main stages of the pipeline. */ class HDRPlus { - + private: - + const Halide::Runtime::Buffer imgs; - + public: - + const int width; const int height; - + const BlackPoint bp; const WhitePoint wp; const WhiteBalance wb; @@ -38,7 +38,7 @@ class HDRPlus { char *readfile; std::string readfilestring; void imagesize(); - + HDRPlus(Halide::Runtime::Buffer imgs, BlackPoint bp, WhitePoint wp, WhiteBalance wb, Compression c, Gain g) : imgs(imgs) , width(imgs.width()) @@ -52,7 +52,7 @@ class HDRPlus { assert(imgs.dimensions() == 3); // width * height * img_idx assert(imgs.extent(2) >= 2); // must have at least one alternate image } - + /* * process -- Calls all of the main stages (align, merge, finish) of the pipeline. */ @@ -62,47 +62,47 @@ class HDRPlus { Func alignment = align(imgsBuffer); Func merged = merge(imgsBuffer, alignment); Func finished = finish(merged, width, height, bp, wp, wb, c, g); - + /////////////////////////////////////////////////////////////////////////// // realize image /////////////////////////////////////////////////////////////////////////// - + Buffer output_img(3, width, height); - + finished.compile_jit(); finished.realize(output_img); - + // transpose to account for interleaved layout - + output_img.transpose(0, 1); output_img.transpose(1, 2); - + return output_img; } - + /* * save_png -- Writes an interleaved Halide image to an output file. */ static bool save_png(std::string dir_path, std::string img_name, Buffer &img) { - + std::string img_path = dir_path + "/" + img_name; - + std::remove(img_path.c_str()); - + int stride_in_bytes = img.width() * img.channels(); - + if(!stbi_write_png(img_path.c_str(), img.width(), img.height(), img.channels(), img.data(), stride_in_bytes)) { - + std::cerr << "Unable to write output image '" << img_name << "'" << std::endl; return false; } - + return true; } }; int main(int argc, char* argv[]) { - + if (argc < 5) { std::cerr << "Usage: " << argv[0] << " [-c comp -g gain (optional)] dir_path out_img raw_img1 raw_img2 [...]" << std::endl; return 1; @@ -145,13 +145,12 @@ int main(int argc, char* argv[]) { while (i < argc) in_names.push_back(argv[i++]); Burst burst(dir_path, in_names); - Halide::Runtime::Buffer imgs = burst.ToBuffer(); if (imgs.channels() < 2) { return EXIT_FAILURE; } - HDRPlus hdr_plus = HDRPlus( + HDRPlus hdr_plus( imgs, burst.GetBlackLevel(), burst.GetWhiteLevel(), @@ -160,7 +159,7 @@ int main(int argc, char* argv[]) { g); Buffer output = hdr_plus.process(); - + if(!HDRPlus::save_png(dir_path, out_name, output)) return -1; return 0; diff --git a/src/InputSource.cpp b/src/InputSource.cpp index f39930d..3bfdc75 100644 --- a/src/InputSource.cpp +++ b/src/InputSource.cpp @@ -1,25 +1,26 @@ #include "InputSource.h" -RawSource::RawSource(const std::string &path) - : RawProcessor() +RawImage::RawImage(const std::string &path) + : RawProcessor(std::make_shared()) { - if (int err = RawProcessor.open_file(path.c_str())) { + std::cerr << "Opening " << path << std::endl; + if (int err = RawProcessor->open_file(path.c_str())) { std::cerr << "Cannot open file " << path << " error: " << libraw_strerror(err) << std::endl; throw std::runtime_error("Error opening " + path); } - if (int err = RawProcessor.unpack()) + if (int err = RawProcessor->unpack()) { std::cerr << "Cannot unpack file " << path << " error: " << libraw_strerror(err) << std::endl; throw std::runtime_error("Error opening " + path); } - if (int ret = RawProcessor.raw2image()) { + if (int ret = RawProcessor->raw2image()) { std::cerr << "Cannot do raw2image on " << path << " error: " << libraw_strerror(ret) << std::endl; throw std::runtime_error("Error opening " + path); } } -WhiteBalance RawSource::GetWhiteBalance() const { - const auto coeffs = RawProcessor.imgdata.color.cam_mul; +WhiteBalance RawImage::GetWhiteBalance() const { + const auto coeffs = RawProcessor->imgdata.color.cam_mul; // Scale multipliers to green channel const float r = coeffs[0] / coeffs[1]; const float g0 = 1.f; // same as coeffs[1] / coeffs[1]; @@ -28,13 +29,18 @@ WhiteBalance RawSource::GetWhiteBalance() const { return WhiteBalance{r, g0, g1, b}; } -void RawSource::CopyToBuffer(Halide::Runtime::Buffer &buffer) const { - const auto image_data = (uint16_t*)RawProcessor.imgdata.rawdata.raw_image; - const auto raw_width = RawProcessor.imgdata.rawdata.sizes.raw_width; - const auto raw_height = RawProcessor.imgdata.rawdata.sizes.raw_height; - const auto top = RawProcessor.imgdata.rawdata.sizes.top_margin; - const auto left = RawProcessor.imgdata.rawdata.sizes.left_margin; +void RawImage::CopyToBuffer(Halide::Runtime::Buffer &buffer) const { + const auto image_data = (uint16_t*)RawProcessor->imgdata.rawdata.raw_image; + const auto raw_width = RawProcessor->imgdata.rawdata.sizes.raw_width; + const auto raw_height = RawProcessor->imgdata.rawdata.sizes.raw_height; + const auto top = RawProcessor->imgdata.rawdata.sizes.top_margin; + const auto left = RawProcessor->imgdata.rawdata.sizes.left_margin; Halide::Runtime::Buffer raw_buffer(image_data, raw_width, raw_height); buffer.copy_from(raw_buffer.translated({-left, -top})); } +void RawImage::WriteDng(const std::string &path, const Halide::Runtime::Buffer &buffer) const +{ + +} + diff --git a/src/InputSource.h b/src/InputSource.h index 8232419..3d24577 100644 --- a/src/InputSource.h +++ b/src/InputSource.h @@ -7,39 +7,27 @@ #include #include "finish.h" -class AbstractInputSource { +class RawImage { public: - virtual ~AbstractInputSource() = default; - virtual int GetWidth() const = 0; - virtual int GetHeight() const = 0; - virtual int GetBlackLevel() const = 0; - virtual int GetWhiteLevel() const = 0; - virtual WhiteBalance GetWhiteBalance() const = 0; - virtual void CopyToBuffer(Halide::Runtime::Buffer& buffer) const = 0; - - using SPtr = std::shared_ptr; -}; + explicit RawImage(const std::string& path); -class RawSource : public AbstractInputSource { -public: - explicit RawSource(const std::string& path); + ~RawImage() = default; - ~RawSource() override { - RawProcessor.free_image(); - } + int GetWidth() const { return RawProcessor->imgdata.rawdata.sizes.width; } - int GetWidth() const override { return RawProcessor.imgdata.rawdata.sizes.width; } + int GetHeight() const { return RawProcessor->imgdata.rawdata.sizes.height; } - int GetHeight() const override { return RawProcessor.imgdata.rawdata.sizes.height; } + int GetBlackLevel() const { return RawProcessor->imgdata.color.black; } - int GetBlackLevel() const override { return RawProcessor.imgdata.color.black; } + int GetWhiteLevel() const { return RawProcessor->imgdata.color.maximum; } - int GetWhiteLevel() const override { return RawProcessor.imgdata.color.maximum; } + WhiteBalance GetWhiteBalance() const; - WhiteBalance GetWhiteBalance() const override; + void CopyToBuffer(Halide::Runtime::Buffer& buffer) const; - void CopyToBuffer(Halide::Runtime::Buffer& buffer) const override; + // Writes current RawImage as DNG. If buffer was provided, then use it instead of internal buffer. + void WriteDng(const std::string& path, const Halide::Runtime::Buffer& buffer = {}) const; private: - LibRaw RawProcessor; + std::shared_ptr RawProcessor; };