Skip to content

Commit

Permalink
Merge pull request #49 from brotherofken/44-save-merged-dng
Browse files Browse the repository at this point in the history
#44 save merged buffer as dng
  • Loading branch information
Titaniumtown authored Feb 24, 2020
2 parents 7435e79 + a386db5 commit 3bdea3b
Show file tree
Hide file tree
Showing 10 changed files with 324 additions and 73 deletions.
40 changes: 22 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
cmake_minimum_required(VERSION 3.10)
project(HDR_PLUS)

set(CMAKE_CXX_STANDARD 11)
#set(CMAKE_CXX_FLAGS "-O3 -v -g -Wall") # Use -DCMAKE_BUILD_TYPE=Release/Debug instead
find_package(PNG REQUIRED)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

set(HALIDE_ROOT_DIR "")
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
include("macro.cmake")
set(CMAKE_CXX_STANDARD 11)

if(" ${HALIDE_ROOT_DIR}" STREQUAL " ")
message( FATAL_ERROR "Specify HALIDE_ROOT_DIR variable in the cmake file." )
endif()
# Define dependencies
link_halide()
link_libtiff()

find_library(LIBRAW_LIBRARY
NAMES raw raw_r
)
find_package(ZLIB REQUIRED)
find_package(PNG REQUIRED)
find_package(JPEG REQUIRED)
find_library(LIBRAW_LIBRARY NAMES raw raw_r)

set(src_files
src/HDRPlus.cpp
src/align.cpp
src/finish.cpp
src/merge.cpp
src/util.cpp
src/InputSource.cpp
src/InputSource.h
src/Burst.cpp
src/Burst.h)

include_directories(/usr/local/lib /usr/local/include ${HALIDE_ROOT_DIR}/bin ${HALIDE_ROOT_DIR}/lib ${HALIDE_ROOT_DIR}/include ${HALIDE_ROOT_DIR}/tools)
src/LibRaw2DngConverter.cpp)

link_directories(/usr/local/lib /usr/local/include ${HALIDE_ROOT_DIR}/bin ${HALIDE_ROOT_DIR}/lib ${HALIDE_ROOT_DIR}/include ${HALIDE_ROOT_DIR}/tools)
set(header_files
src/InputSource.h
src/Burst.h
src/dngwriter.h
src/LibRaw2DngConverter.h)

include_directories(${HALIDE_DISTRIB_DIR}/include ${HALIDE_DISTRIB_DIR}/tools ${RAW2DNG_INCLUDE_DIRS})

add_executable(hdrplus ${src_files})
add_executable(hdrplus src/HDRPlus.cpp ${src_files})
target_link_libraries(hdrplus Halide png ${LIBRAW_LIBRARY} ${TIFF_LIBRARIES} ${TIFFXX_LIBRARY})

target_link_libraries(hdrplus Halide png ${LIBRAW_LIBRARY})
add_executable(stack_frames src/stack_frames.cpp ${src_files})
target_link_libraries(stack_frames Halide ${LIBRAW_LIBRARY} ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARIES} ${TIFFXX_LIBRARY})
24 changes: 24 additions & 0 deletions macro.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.10)

macro(link_halide)
if("${HALIDE_DISTRIB_DIR}" STREQUAL " ")
message(FATAL_ERROR "Specify HALIDE_DISTRIB_DIR variable in the cmake options.")
endif()
find_package(Threads) # fix dynamic linking for halide
set(HALIDE_DISTRIB_USE_STATIC_LIBRARY OFF)
include(${HALIDE_DISTRIB_DIR}/halide.cmake)
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()

find_library(TIFFXX_LIBRARY NAMES tiffxx)
message(STATUS "Found tiffxx: ${TIFFXX_LIBRARY}")
endmacro()
12 changes: 8 additions & 4 deletions src/Burst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Halide::Runtime::Buffer<uint16_t> Burst::ToBuffer() const {
Halide::Runtime::Buffer<uint16_t> 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;
}
Expand All @@ -17,11 +17,15 @@ void Burst::CopyToBuffer(Halide::Runtime::Buffer<uint16_t> &buffer) const {
buffer.copy_from(ToBuffer());
}

std::vector<AbstractInputSource::SPtr> Burst::LoadRaws(const std::string &dirPath, std::vector<std::string> &inputs) {
std::vector<AbstractInputSource::SPtr> result;
std::vector<RawImage> Burst::LoadRaws(const std::string &dirPath, std::vector<std::string> &inputs) {
std::vector<RawImage> result;
for (const auto& input : inputs) {
const std::string img_path = dirPath + "/" + input;
result.emplace_back(std::make_shared<RawSource>(img_path));
result.emplace_back(img_path);
}
return result;
}

const RawImage& Burst::GetRaw(const size_t i) const {
return this->Raws[i];
}
22 changes: 12 additions & 10 deletions src/Burst.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,37 @@
#include <vector>
#include <Halide.h>

class Burst : public AbstractInputSource {
class Burst {
public:
Burst(std::string dir_path, std::vector<std::string> inputs)
: Dir(std::move(dir_path))
, Inputs(std::move(inputs))
, 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<uint16_t> ToBuffer() const;

void CopyToBuffer(Halide::Runtime::Buffer<uint16_t>& buffer) const override;
void CopyToBuffer(Halide::Runtime::Buffer<uint16_t>& buffer) const;

const RawImage& GetRaw(const size_t i) const;

private:
std::string Dir;
std::vector<std::string> Inputs;
std::vector<AbstractInputSource::SPtr> Raws;
std::vector<RawImage> Raws;

private:
static std::vector<AbstractInputSource::SPtr> LoadRaws(const std::string& dirPath, std::vector<std::string>& inputs);
static std::vector<RawImage> LoadRaws(const std::string& dirPath, std::vector<std::string>& inputs);
};
9 changes: 5 additions & 4 deletions src/HDRPlus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint16_t> imgs = burst.ToBuffer();
if (imgs.channels() < 2) {
return EXIT_FAILURE;
}

HDRPlus hdr_plus = HDRPlus(
HDRPlus hdr_plus(
imgs,
burst.GetBlackLevel(),
burst.GetWhiteLevel(),
Expand All @@ -160,8 +159,10 @@ int main(int argc, char* argv[]) {
g);

Buffer<uint8_t> output = hdr_plus.process();

if(!HDRPlus::save_png(dir_path, out_name, output)) return -1;

if (!HDRPlus::save_png(dir_path, out_name, output)) {
return EXIT_FAILURE;
}

return 0;
}
38 changes: 25 additions & 13 deletions src/InputSource.cpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
#include "InputSource.h"
#include "LibRaw2DngConverter.h"

RawSource::RawSource(const std::string &path)
: RawProcessor()
RawImage::RawImage(const std::string &path)
: Path(path)
, RawProcessor(std::make_shared<LibRaw>())
{
if (int err = RawProcessor.open_file(path.c_str())) {
// TODO: Check LibRaw parametres.
// RawProcessor->imgdata.params.X = Y;

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];
Expand All @@ -28,13 +34,19 @@ WhiteBalance RawSource::GetWhiteBalance() const {
return WhiteBalance{r, g0, g1, b};
}

void RawSource::CopyToBuffer(Halide::Runtime::Buffer<uint16_t> &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<uint16_t> &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<uint16_t> raw_buffer(image_data, raw_width, raw_height);
buffer.copy_from(raw_buffer.translated({-left, -top}));
}

void RawImage::WriteDng(const std::string &output_path, const Halide::Runtime::Buffer<uint16_t> &buffer) const
{
LibRaw2DngConverter converter(*RawProcessor);
converter.SetBuffer(buffer);
converter.Write(output_path);
}
37 changes: 13 additions & 24 deletions src/InputSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,28 @@
#include <Halide.h>
#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<uint16_t>& buffer) const = 0;

using SPtr = std::shared_ptr<AbstractInputSource>;
};
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<uint16_t>& buffer) const;

void CopyToBuffer(Halide::Runtime::Buffer<uint16_t>& 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<uint16_t>& buffer = {}) const;

private:
LibRaw RawProcessor;
std::string Path;
std::shared_ptr<LibRaw> RawProcessor;
};
Loading

0 comments on commit 3bdea3b

Please sign in to comment.