diff --git a/cmake/FindLibraw.cmake b/cmake/FindLibraw.cmake new file mode 100644 index 000000000..803b824f1 --- /dev/null +++ b/cmake/FindLibraw.cmake @@ -0,0 +1,41 @@ +# - Try to find libraw +# +# libraw_FOUND - system has libraw +# libraw_INCLUDE_DIRS - the libraw include directories +# libraw_LIBRARIES - link these to use libraw + +FIND_PATH( + libraw_INCLUDE_DIRS + NAMES libraw/libraw.h + PATHS + ${LIBRAW_DIR} + ${LIBRAW_DIR}/include + /usr/include/ + /usr/local/include + /opt/local/include +) + +FIND_LIBRARY( + libraw_LIBRARIES + NAMES raw_r + PATHS + ${LIBRAW_DIR} + ${LIBRAW_DIR}/lib + /usr/lib + /usr/local/lib + /opt/local/lib +) + +IF (libraw_INCLUDE_DIRS AND libraw_LIBRARIES) + SET(libraw_FOUND TRUE) +ENDIF (libraw_INCLUDE_DIRS AND libraw_LIBRARIES) + +IF (libraw_FOUND) + IF (NOT libraw_FIND_QUIETLY) + MESSAGE(STATUS "Found libraw: ${libraw_LIBRARIES}") + ENDIF (NOT libraw_FIND_QUIETLY) +ELSE (libraw_FOUND) + IF (libraw_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find libraw") + ENDIF (libraw_FIND_REQUIRED) +ENDIF (libraw_FOUND) diff --git a/components/pango_image/CMakeLists.txt b/components/pango_image/CMakeLists.txt index 0eff5ec79..63eaec374 100644 --- a/components/pango_image/CMakeLists.txt +++ b/components/pango_image/CMakeLists.txt @@ -72,6 +72,17 @@ if(BUILD_PANGOLIN_ZSTD) endif() endif() +option(BUILD_PANGOLIN_LIBRAW "Build support for raw images (libraw)" ON) +if(BUILD_PANGOLIN_LIBRAW) + find_package(libraw QUIET) + if(libraw_FOUND) + target_compile_definitions(${COMPONENT} PRIVATE HAVE_LIBRAW) + target_include_directories(${COMPONENT} PRIVATE ${libraw_INCLUDE_DIR} ) + target_link_libraries(${COMPONENT} PRIVATE ${libraw_LIBRARIES}) + message(STATUS "libraw Found and Enabled") + endif() +endif() + target_sources( ${COMPONENT} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/pixel_format.cpp @@ -87,6 +98,7 @@ PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/image_io_tga.cpp ${CMAKE_CURRENT_LIST_DIR}/src/image_io_bmp.cpp ${CMAKE_CURRENT_LIST_DIR}/src/image_io_zstd.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/image_io_libraw.cpp ) target_link_libraries(${COMPONENT} PUBLIC pango_core) diff --git a/components/pango_image/src/image_io.cpp b/components/pango_image/src/image_io.cpp index c95d628a2..aa43e8b1f 100644 --- a/components/pango_image/src/image_io.cpp +++ b/components/pango_image/src/image_io.cpp @@ -70,6 +70,9 @@ void SaveLz4(const Image& image, const pangolin::PixelFormat& fmt TypedImage LoadPacked12bit(std::istream& in); void SavePacked12bit(const Image& image, const pangolin::PixelFormat& fmt, std::ostream& out); +// LibRaw raw camera files +TypedImage LoadLibRaw(const std::string& filename); + TypedImage LoadImage(std::istream& in, ImageFileType file_type) { switch (file_type) { @@ -114,6 +117,10 @@ TypedImage LoadImage(const std::string& filename, ImageFileType file_type) } case ImageFileTypePango: return LoadPango(filename); + case ImageFileTypeArw: + [[fallthrough]]; + case ImageFileTypeTiff: + return LoadLibRaw(filename); default: throw std::runtime_error("Unsupported image file type, '" + filename + "'"); } diff --git a/components/pango_image/src/image_io_libraw.cpp b/components/pango_image/src/image_io_libraw.cpp new file mode 100644 index 000000000..bb77227b4 --- /dev/null +++ b/components/pango_image/src/image_io_libraw.cpp @@ -0,0 +1,48 @@ +#include +#include + +#ifdef HAVE_LIBRAW +# include +#endif + +namespace pangolin { + +TypedImage LoadLibRaw( + const std::string& filename +) { +#ifdef HAVE_LIBRAW + static LibRaw RawProcessor; + + int ret; + + if ((ret = RawProcessor.open_file(filename.c_str())) != LIBRAW_SUCCESS) + { + throw std::runtime_error(libraw_strerror(ret)); + } + + if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) + { + throw std::runtime_error(libraw_strerror(ret)); + } + + const auto& S = RawProcessor.imgdata.sizes; + TypedImage image(S.width, S.height, PixelFormatFromString("GRAY16LE"), sizeof(uint16_t) * S.raw_width); + PitchedCopy((char*)image.ptr, image.pitch, (char*)RawProcessor.imgdata.rawdata.raw_image, sizeof(uint16_t) * S.raw_width, sizeof(uint16_t) * image.w, image.h); + + // TODO: Support image metadata so that we can extract these fields. + // RawProcessor.imgdata.other.iso_speed + // RawProcessor.imgdata.other.aperture + // RawProcessor.imgdata.other.focal_len + // RawProcessor.imgdata.other.shutter + // RawProcessor.imgdata.other.timestamp + // RawProcessor.imgdata.makernotes.common.exifCameraElevationAngle + // RawProcessor.imgdata.makernotes.sony.SonyDateTime + + return image; +#else + PANGOLIN_UNUSED(filename); + throw std::runtime_error("Rebuild Pangolin for libraw support."); +#endif +} + +}