From 1b1c085cfec926af5bc1cfc85c10a0ca6f89d143 Mon Sep 17 00:00:00 2001 From: Piotr Bartman Date: Thu, 31 Mar 2022 11:26:20 +0200 Subject: [PATCH] libraw: data checking --- contrib/libraw/CMakeLists.txt | 2 + contrib/libraw/example/main.cc | 88 ++++++++++++++++------------ contrib/libraw/sandboxed.h | 7 --- contrib/libraw/test/libraw_test.cc | 7 ++- contrib/libraw/utils/utils_libraw.cc | 52 ++++++++++++++-- contrib/libraw/utils/utils_libraw.h | 5 +- 6 files changed, 109 insertions(+), 52 deletions(-) diff --git a/contrib/libraw/CMakeLists.txt b/contrib/libraw/CMakeLists.txt index e1194d8..434d2b7 100644 --- a/contrib/libraw/CMakeLists.txt +++ b/contrib/libraw/CMakeLists.txt @@ -65,6 +65,8 @@ add_sapi_library( libraw_cameraCount libraw_COLOR + libraw_get_raw_height + libraw_get_raw_width INPUTS "${CMAKE_BINARY_DIR}/raw.gen.h" diff --git a/contrib/libraw/example/main.cc b/contrib/libraw/example/main.cc index eff6b70..cdf054e 100644 --- a/contrib/libraw/example/main.cc +++ b/contrib/libraw/example/main.cc @@ -66,16 +66,18 @@ int main(int ac, char* av[]) { LibRaw lr(&sandbox, av[1]); if (not lr.CheckIsInit().ok()) { std::cerr << "Unable init LibRaw"; + std::cerr << lr.CheckIsInit().status(); return EXIT_FAILURE; } status = lr.OpenFile(); if (not status.ok()) { std::cerr << "Unable to open file" << av[1] << "\n"; + std::cerr << status; return EXIT_FAILURE; } - if ((lr.GetImgData().idata.colors == 1 and channel > 0) or (channel > 3)) { + if ((lr.GetColorCount() == 1 and channel > 0) or (channel > 3)) { std::cerr << "Incorrect CHANNEL specified:" << channel << "\n"; return EXIT_FAILURE; } @@ -83,66 +85,78 @@ int main(int ac, char* av[]) { status = lr.Unpack(); if (not status.ok()) { std::cerr << "Unable to unpack file" << av[1] << "\n"; + std::cerr << status; return EXIT_FAILURE; } status = lr.SubtractBlack(); if (not status.ok()) { std::cerr << "Unable to subtract black level"; + std::cerr << status; + // ok, but different output } + absl::StatusOr> rawdata = lr.RawData(); + if (not rawdata.ok()) { + std::cerr << "Unable to get raw data\n"; + std::cerr << rawdata.status(); + return EXIT_FAILURE; + } + + absl::StatusOr raw_height = lr.GetRawHeight(); + absl::StatusOr raw_width = lr.GetRawWidth(); + if (not raw_height.ok() or not raw_width.ok()) { + std::cerr << "Unable to get raw image sizes."; + return EXIT_FAILURE; + } + + // header std::cout << av[1] << "\t" << colstart << "-" << rowstart << "-" << width << "x" << height << "\t" << "channel: " << channel << "\n"; std::cout << std::setw(6) << "R\\C"; for (int col = colstart; - col < colstart + width and col < lr.GetImgData().sizes.raw_width; + col < colstart + width and col < *raw_width; col++) { std::cout << std::setw(6) << col; } std::cout << "\n"; - if (lr.GetImgData().rawdata.raw_image) { - absl::StatusOr> rawdata = lr.RawData(); - if (not rawdata.ok()) { - std::cerr << "Unable to get raw data\n"; - return EXIT_FAILURE; + // dump raw to output + for (int row = rowstart; + row < rowstart + height && row < *raw_height; + row++) { + unsigned rcolors[48]; + if (lr.GetColorCount() > 1) { + absl::StatusOr color; + for (int c = 0; c < 48; c++) { + color = lr.COLOR(row, c); + if (color.ok()) rcolors[c] = *color; + } + } else { + memset(rcolors, 0, sizeof(rcolors)); } + std::cout << std::setw(6) << row; - for (int row = rowstart; - row < rowstart + height && row < lr.GetImgData().sizes.raw_height; - row++) { - unsigned rcolors[48]; - if (lr.GetImgData().idata.colors > 1) { - absl::StatusOr color; - for (int c = 0; c < 48; c++) { - color = lr.COLOR(row, c); - if (color.ok()) rcolors[c] = *color; + for (int col = colstart; + col < colstart + width && col < *raw_width; + col++) { + int idx = row * lr.GetImgData().sizes.raw_pitch / 2 + col; + + if (rcolors[col % 48] == (unsigned)channel) { + absl::StatusOr cblack = lr.GetCBlack(channel); + if (not cblack.ok()) { + std::cerr << "Unable to get cblack for channel " << channel; + std::cerr << cblack.status(); + return EXIT_FAILURE; } + std::cout << std::setw(6) + << subtract_bl((*rawdata).at(idx), *cblack); } else { - memset(rcolors, 0, sizeof(rcolors)); + std::cout << " -"; } - std::cout << std::setw(6) << row; - - for (int col = colstart; - col < colstart + width && col < lr.GetImgData().sizes.raw_width; - col++) { - int idx = row * lr.GetImgData().sizes.raw_pitch / 2 + col; - - if (rcolors[col % 48] == (unsigned)channel) { - std::cout << std::setw(6) - << subtract_bl((*rawdata)[idx], - lr.GetImgData().color.cblack[channel]); - } else { - std::cout << " -"; - } - } - std::cout << "\n"; } - } else { - std::cout - << "Unsupported file data (e.g. floating point format), or incorrect " - "channel specified\n"; + std::cout << "\n"; } return EXIT_SUCCESS; diff --git a/contrib/libraw/sandboxed.h b/contrib/libraw/sandboxed.h index 6719aef..b617273 100644 --- a/contrib/libraw/sandboxed.h +++ b/contrib/libraw/sandboxed.h @@ -31,21 +31,14 @@ class LibRawSapiSandbox : public LibRawSandbox { std::unique_ptr ModifyPolicy( sandbox2::PolicyBuilder*) override { return sandbox2::PolicyBuilder() - .AllowStaticStartup() .AllowDynamicStartup() - .AllowTcMalloc() - .AllowSystemMalloc() - .AllowScudoMalloc() .AllowOpen() .AllowRead() .AllowWrite() .AllowSystemMalloc() .AllowExit() - .AllowSafeFcntl() .AllowSyscalls({__NR_recvmsg}) .AddFile(file_name_, /*is_ro=*/true) - .AllowRestartableSequencesWithProcFiles( - sandbox2::PolicyBuilder::kAllowSlowFences) // hangs without it? .BuildOrDie(); } diff --git a/contrib/libraw/test/libraw_test.cc b/contrib/libraw/test/libraw_test.cc index d84b029..0ab2e5a 100644 --- a/contrib/libraw/test/libraw_test.cc +++ b/contrib/libraw/test/libraw_test.cc @@ -97,10 +97,11 @@ TEST_P(LibRawTestFiles, TestSize) { SAPI_ASSERT_OK(lr.OpenFile()); SAPI_ASSERT_OK(lr.Unpack()); - libraw_data_t lr_data = lr.GetImgData(); + SAPI_ASSERT_OK_AND_ASSIGN(ushort raw_height, lr.GetRawHeight()); + SAPI_ASSERT_OK_AND_ASSIGN(ushort raw_width, lr.GetRawWidth()); - ASSERT_EQ(lr_data.sizes.raw_height, tv.raw_height); - ASSERT_EQ(lr_data.sizes.raw_width, tv.raw_width); + ASSERT_EQ(raw_height, tv.raw_height); + ASSERT_EQ(raw_width, tv.raw_width); } TEST_P(LibRawTestFiles, TestCameraList) { diff --git a/contrib/libraw/utils/utils_libraw.cc b/contrib/libraw/utils/utils_libraw.cc index 413a106..052bf38 100644 --- a/contrib/libraw/utils/utils_libraw.cc +++ b/contrib/libraw/utils/utils_libraw.cc @@ -95,19 +95,63 @@ absl::StatusOr LibRaw::COLOR(int row, int col) { SAPI_RETURN_IF_ERROR(CheckIsInit()); int color; - SAPI_ASSIGN_OR_RETURN( color, api_.libraw_COLOR(sapi_libraw_data_t_.PtrNone(), row, col)); return color; } +absl::StatusOr LibRaw::GetRawHeight() { + SAPI_RETURN_IF_ERROR(CheckIsInit()); + + ushort height; + SAPI_ASSIGN_OR_RETURN( + height, api_.libraw_get_raw_height(sapi_libraw_data_t_.PtrNone())); + + return height; +} + +absl::StatusOr LibRaw::GetRawWidth() { + SAPI_RETURN_IF_ERROR(CheckIsInit()); + + ushort width; + SAPI_ASSIGN_OR_RETURN( + width, api_.libraw_get_raw_width(sapi_libraw_data_t_.PtrNone())); + + return width; +} + +absl::StatusOr LibRaw::GetCBlack(int channel) { + SAPI_RETURN_IF_ERROR(CheckIsInit()); + + if (channel < 0 or channel >= LIBRAW_CBLACK_SIZE) { + return absl::OutOfRangeError( + absl::string_view(std::to_string(channel) + + " is out of range for array with size " + + std::to_string(LIBRAW_CBLACK_SIZE))); + } + + return GetImgData().color.cblack[channel]; + + ushort width; + SAPI_ASSIGN_OR_RETURN( + width, api_.libraw_get_raw_width(sapi_libraw_data_t_.PtrNone())); + + return width; +} + +int LibRaw::GetColorCount() { + return GetImgData().idata.colors; +} + absl::StatusOr> LibRaw::RawData() { SAPI_RETURN_IF_ERROR(CheckIsInit()); - int size = sapi_libraw_data_t_.data().sizes.raw_height * - sapi_libraw_data_t_.data().sizes.raw_width; - + ushort raw_height; + ushort raw_width; + SAPI_ASSIGN_OR_RETURN(raw_height, GetRawHeight()); + SAPI_ASSIGN_OR_RETURN(raw_width, GetRawWidth()); + unsigned size = raw_height * raw_width; std::vector buf(size); sapi::v::Array rawdata(buf.data(), buf.size()); diff --git a/contrib/libraw/utils/utils_libraw.h b/contrib/libraw/utils/utils_libraw.h index 28e7c0a..0f7ad68 100644 --- a/contrib/libraw/utils/utils_libraw.h +++ b/contrib/libraw/utils/utils_libraw.h @@ -60,6 +60,10 @@ class LibRaw { absl::Status SubtractBlack(); absl::StatusOr> GetCameraList(); absl::StatusOr COLOR(int row, int col); + absl::StatusOr GetRawHeight(); + absl::StatusOr GetRawWidth(); + absl::StatusOr GetCBlack(int channel); + int GetColorCount(); private: absl::Status InitLibRaw(); @@ -70,7 +74,6 @@ class LibRaw { std::string file_name_; - public: sapi::v::Struct sapi_libraw_data_t_; };