From 656cd15cb67a2befb3d4c17aecc61c79f17d292f Mon Sep 17 00:00:00 2001 From: Piotr Bartman Date: Fri, 25 Mar 2022 08:54:17 +0100 Subject: [PATCH] LibRaw --- contrib/CMakeLists.txt | 1 + contrib/libraw/CMakeLists.txt | 94 +++++++++++++ contrib/libraw/example/CMakeLists.txt | 27 ++++ contrib/libraw/example/main.cc | 175 +++++++++++++++++++++++++ contrib/libraw/raw.gen.h.in | 17 +++ contrib/libraw/sandboxed.h | 55 ++++++++ contrib/libraw/test/CMakeLists.txt | 33 +++++ contrib/libraw/test/libraw_test.cc | 182 ++++++++++++++++++++++++++ contrib/libraw/utils/utils_libraw.cc | 118 +++++++++++++++++ contrib/libraw/utils/utils_libraw.h | 77 +++++++++++ 10 files changed, 779 insertions(+) create mode 100644 contrib/libraw/CMakeLists.txt create mode 100644 contrib/libraw/example/CMakeLists.txt create mode 100644 contrib/libraw/example/main.cc create mode 100644 contrib/libraw/raw.gen.h.in create mode 100644 contrib/libraw/sandboxed.h create mode 100644 contrib/libraw/test/CMakeLists.txt create mode 100644 contrib/libraw/test/libraw_test.cc create mode 100644 contrib/libraw/utils/utils_libraw.cc create mode 100644 contrib/libraw/utils/utils_libraw.h diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 15dbabc..404ac4f 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -18,6 +18,7 @@ set(SAPI_CONTRIB_SANDBOXES hunspell jsonnet libidn2 + libraw libzip pffft turbojpeg diff --git a/contrib/libraw/CMakeLists.txt b/contrib/libraw/CMakeLists.txt new file mode 100644 index 0000000..0ea84af --- /dev/null +++ b/contrib/libraw/CMakeLists.txt @@ -0,0 +1,94 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required(VERSION 3.13..3.22) + +project(sapi_libraw CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +set(SAPI_ROOT "" CACHE PATH "Path to the Sandboxed API source tree") + +if(NOT TARGET sapi::sapi) + set(SAPI_ROOT "../.." CACHE PATH "Path to the Sandboxed API source tree") + add_subdirectory( + "${SAPI_ROOT}" + "${CMAKE_BINARY_DIR}/sandboxed-api-build" + EXCLUDE_FROM_ALL) +endif() + +FetchContent_Declare( + libraw + + GIT_REPOSITORY https://github.com/LibRaw/LibRaw.git + GIT_TAG adcb898a00746c8aa886eb06cc9f5a1cb1834fca +) +FetchContent_GetProperties(libraw) +FetchContent_Populate(libraw) + +set(LIBRAW_PATH "${libraw_SOURCE_DIR}" CACHE STRING "" FORCE) +set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) +FetchContent_Declare( + libraw_cmake + + GIT_REPOSITORY https://github.com/LibRaw/LibRaw-cmake.git + GIT_TAG b82a1b0101b1e7264eb3113f1e6c1ba2372ebb7f +) +FetchContent_MakeAvailable(libraw_cmake) + +configure_file(raw.gen.h.in raw.gen.h) + +add_sapi_library( + sapi_libraw + + FUNCTIONS + libraw_init + libraw_open_file + libraw_unpack + libraw_close + + libraw_subtract_black # +# libraw_raw2image +# libraw_free_image + + libraw_cameraList + libraw_cameraCount + + libraw_COLOR # +# libraw_dcraw_process +# libraw_dcraw_ppm_tiff_writer + + + INPUTS + "${CMAKE_BINARY_DIR}/raw.gen.h" + + LIBRARY raw + LIBRARY_NAME LibRaw + NAMESPACE "" +) + +target_include_directories( + sapi_libraw INTERFACE + + "${PROJECT_BINARY_DIR}" +) + +if(SAPI_ENABLE_EXAMPLES) + add_subdirectory(example) +endif() + +if(SAPI_ENABLE_TESTS) + add_subdirectory(test) +endif() diff --git a/contrib/libraw/example/CMakeLists.txt b/contrib/libraw/example/CMakeLists.txt new file mode 100644 index 0000000..150d70a --- /dev/null +++ b/contrib/libraw/example/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_executable( + sapi_minilibraw + + main.cc + ../utils/utils_libraw.cc +) + +target_link_libraries( + sapi_minilibraw PRIVATE + + sapi_libraw + sapi::sapi +) diff --git a/contrib/libraw/example/main.cc b/contrib/libraw/example/main.cc new file mode 100644 index 0000000..4df45f2 --- /dev/null +++ b/contrib/libraw/example/main.cc @@ -0,0 +1,175 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "contrib/libraw/sandboxed.h" +#include "contrib/libraw/utils/utils_libraw.h" + +void usage(const char* av) { + printf( + "Dump (small) selecton of RAW file as tab-separated text file\n" + "Usage: %s inputfile COL ROW [CHANNEL] [width] [height]\n" + " COL - start column\n" + " ROW - start row\n" + " CHANNEL - raw channel to dump, default is 0 (red for rggb)\n" + " width - area width to dump, default is 16\n" + " height - area height to dump, default is 4\n", + av); +} + +unsigned subtract_bl(int val, int bl) { + return val > bl ? val - bl : 0; +} + +int main(int ac, char* av[]) { + google::InitGoogleLogging(av[0]); + + if (ac < 4) + { + usage(av[0]); + exit(1); + } + int colstart = atoi(av[2]); + int rowstart = atoi(av[3]); + int channel = 0; + if (ac > 4) channel = atoi(av[4]); + int width = 16; + if (ac > 5) width = atoi(av[5]); + int height = 4; + if (ac > 6) height = atoi(av[6]); + if (width < 1 || height < 1) + { + usage(av[0]); + exit(1); + } + + sapi::v::ConstCStr file_name(av[1]); + + LibRawSapiSandbox sandbox(file_name.GetData()); + if (!sandbox.Init().ok()) + { + std::cerr << "Unable to start sandbox\n"; + return EXIT_FAILURE; + } + + absl::Status status; + + LibRaw lr(&sandbox, av[1]); + if (not lr.CheckIsInit().ok()) + { + fprintf(stderr, "Unable init LibRaw"); + return EXIT_FAILURE; + } + + status = lr.OpenFile(); + if (not status.ok()) + { + fprintf(stderr, "Unable to open file %s\n", av[1]); + return EXIT_FAILURE; + } + + if ((lr.GetImgData().idata.colors == 1 and channel > 0) + or + (channel > 3)) + { + fprintf(stderr, "Incorrect CHANNEL specified: %d\n", channel); + return EXIT_FAILURE; + } + + status = lr.Unpack(); + if (not status.ok()) + { + fprintf(stderr, "Unable to unpack file %s\n", av[1]); + return EXIT_FAILURE; + } + + status = lr.SubtractBlack(); + if (not status.ok()) + { + fprintf(stderr, "Unable to subtract black level"); + } + + printf("%s\t%d-%d-%dx%d\tchannel: %d\n", + av[1], colstart, rowstart, width, height, channel); + printf("%6s", "R\\C"); + for (int col = colstart; + col < colstart + width and + col < lr.GetImgData().sizes.raw_width; + col++) + { + printf("%6u", col); + } + printf("\n"); + + if (lr.GetImgData().rawdata.raw_image) + { + absl::StatusOr> rawdata = lr.RawData(); + if (not rawdata.ok()) + { + fprintf(stderr, "Unable to get raw data\n"); + return EXIT_FAILURE; + } + + 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; + } + } + else + { + memset(rcolors, 0, sizeof(rcolors)); + } + printf("%6u", 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) + { + printf("%6u", + subtract_bl((*rawdata)[idx], + lr.GetImgData().color.cblack[channel])); + } + else + { + printf(" -"); + } + } + printf("\n"); + } + } + else + { + printf( + "Unsupported file data (e.g. floating point format), or incorrect " + "channel specified\n"); + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/contrib/libraw/raw.gen.h.in b/contrib/libraw/raw.gen.h.in new file mode 100644 index 0000000..0e78b50 --- /dev/null +++ b/contrib/libraw/raw.gen.h.in @@ -0,0 +1,17 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#define __time_t uint64_t +#define time_t uint64_t +#include "${libraw_SOURCE_DIR}/libraw/libraw.h" diff --git a/contrib/libraw/sandboxed.h b/contrib/libraw/sandboxed.h new file mode 100644 index 0000000..6719aef --- /dev/null +++ b/contrib/libraw/sandboxed.h @@ -0,0 +1,55 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CONTRIB_LIBRAW_SANDBOXED_H_ +#define CONTRIB_LIBRAW_SANDBOXED_H_ + +#include +#include + +#include + +#include "sapi_libraw.sapi.h" // NOLINT(build/include) + +class LibRawSapiSandbox : public LibRawSandbox { + public: + explicit LibRawSapiSandbox(std::string file_name) + : file_name_(std::move(file_name)) {} + + private: + 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(); + } + + std::string file_name_; +}; + +#endif // CONTRIB_LIBRAW_SANDBOXED_ \ No newline at end of file diff --git a/contrib/libraw/test/CMakeLists.txt b/contrib/libraw/test/CMakeLists.txt new file mode 100644 index 0000000..8b92e94 --- /dev/null +++ b/contrib/libraw/test/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include(GoogleTest) + +add_executable( + sapi_libraw_test + + libraw_test.cc + ../utils/utils_libraw.cc +) + + +target_link_libraries( + sapi_libraw_test PRIVATE + + sapi_libraw + sapi::test_main + sapi::temp_file +) + +gtest_discover_tests(sapi_libraw_test PROPERTIES ENVIRONMENT "TEST_FILES_DIR=${PROJECT_SOURCE_DIR}/files") \ No newline at end of file diff --git a/contrib/libraw/test/libraw_test.cc b/contrib/libraw/test/libraw_test.cc new file mode 100644 index 0000000..d84b029 --- /dev/null +++ b/contrib/libraw/test/libraw_test.cc @@ -0,0 +1,182 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "contrib/libraw/sandboxed.h" +#include "contrib/libraw/utils/utils_libraw.h" +#include "sandboxed_api/util/path.h" +#include "sandboxed_api/util/status_matchers.h" +#include "sandboxed_api/util/temp_file.h" + +namespace { + +using ::sapi::IsOk; + +const struct TestVariant { + std::string filename; + ushort raw_height; + ushort raw_width; + int COLOR[4][4]; + int color_values[4][4]; +} TestData[] = { + {.filename = "img.raw", + .raw_height = 3516, + .raw_width = 5344, + .COLOR = {{3, 2, 3, 2}, + {0, 1, 0, 1}, + {3, 2, 3, 2}, + {0, 1, 0, 1}}, + .color_values = {{14337, 14337, 14337, 14337}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 1, 0}}}}; + +class LibRawBase : public testing::Test { + protected: + std::string GetTestFilePath(const std::string& filename) { + return sapi::file::JoinPath(test_dir_, filename); + } + + void SetUp() override; + + const char* test_dir_; +}; + +class LibRawTestFiles : public LibRawBase, + public testing::WithParamInterface {}; + +void LibRawBase::SetUp() { + test_dir_ = getenv("TEST_FILES_DIR"); + ASSERT_NE(test_dir_, nullptr); +} + +TEST_P(LibRawTestFiles, TestOpen) { + const TestVariant& tv = GetParam(); + std::string test_file_path = GetTestFilePath(tv.filename); + + LibRawSapiSandbox sandbox(test_file_path); + SAPI_ASSERT_OK(sandbox.Init()); + + LibRaw lr(&sandbox, test_file_path); + SAPI_ASSERT_OK(lr.CheckIsInit()); + SAPI_ASSERT_OK(lr.OpenFile()); +} + +TEST_P(LibRawTestFiles, TestUnpack) { + const TestVariant& tv = GetParam(); + std::string test_file_path = GetTestFilePath(tv.filename); + + LibRawSapiSandbox sandbox(test_file_path); + SAPI_ASSERT_OK(sandbox.Init()); + + LibRaw lr(&sandbox, test_file_path); + SAPI_ASSERT_OK(lr.CheckIsInit()); + SAPI_ASSERT_OK(lr.OpenFile()); + SAPI_ASSERT_OK(lr.Unpack()); +} + +TEST_P(LibRawTestFiles, TestSize) { + const TestVariant& tv = GetParam(); + std::string test_file_path = GetTestFilePath(tv.filename); + + LibRawSapiSandbox sandbox(test_file_path); + SAPI_ASSERT_OK(sandbox.Init()); + + LibRaw lr(&sandbox, test_file_path); + SAPI_ASSERT_OK(lr.CheckIsInit()); + SAPI_ASSERT_OK(lr.OpenFile()); + SAPI_ASSERT_OK(lr.Unpack()); + + libraw_data_t lr_data = lr.GetImgData(); + + ASSERT_EQ(lr_data.sizes.raw_height, tv.raw_height); + ASSERT_EQ(lr_data.sizes.raw_width, tv.raw_width); +} + +TEST_P(LibRawTestFiles, TestCameraList) { + const TestVariant& tv = GetParam(); + std::string test_file_path = GetTestFilePath(tv.filename); + + LibRawSapiSandbox sandbox(test_file_path); + SAPI_ASSERT_OK(sandbox.Init()); + + LibRaw lr(&sandbox, test_file_path); + SAPI_ASSERT_OK(lr.CheckIsInit()); + + SAPI_ASSERT_OK_AND_ASSIGN(std::vector camera_list, lr.GetCameraList()); + + EXPECT_FALSE(camera_list.empty()); +} + +TEST_P(LibRawTestFiles, TestColor) { + const TestVariant& tv = GetParam(); + std::string test_file_path = GetTestFilePath(tv.filename); + + LibRawSapiSandbox sandbox(test_file_path); + SAPI_ASSERT_OK(sandbox.Init()); + + LibRaw lr(&sandbox, test_file_path); + SAPI_ASSERT_OK(lr.CheckIsInit()); + SAPI_ASSERT_OK(lr.OpenFile()); + SAPI_ASSERT_OK(lr.Unpack()); + + for (int row = 0; row < 4; row++) { + for (int col = 0; col < 4; col++) { + SAPI_ASSERT_OK_AND_ASSIGN(int color, lr.COLOR(row, col)); + ASSERT_EQ(color, tv.COLOR[row][col]); + } + } +} + +TEST_P(LibRawTestFiles, TestSubtractBlack) { + const TestVariant& tv = GetParam(); + std::string test_file_path = GetTestFilePath(tv.filename); + + LibRawSapiSandbox sandbox(test_file_path); + SAPI_ASSERT_OK(sandbox.Init()); + + LibRaw lr(&sandbox, test_file_path); + SAPI_ASSERT_OK(lr.CheckIsInit()); + SAPI_ASSERT_OK(lr.OpenFile()); + SAPI_ASSERT_OK(lr.Unpack()); + SAPI_ASSERT_OK(lr.SubtractBlack()); + + libraw_data_t lr_data = lr.GetImgData(); + + SAPI_ASSERT_OK_AND_ASSIGN(std::vector rawdata, lr.RawData()); + + for (int row = 0; row < 4; row++) { + unsigned rcolors[48]; + if (lr_data.idata.colors > 1) { + for (int c = 0; c < 48; c++) { + SAPI_ASSERT_OK_AND_ASSIGN(int color, lr.COLOR(row, c)); + rcolors[c] = color; + } + } else { + memset(rcolors, 0, sizeof(rcolors)); + } + + for (int col = 0; col < 4; col++) { + int raw_idx = row * lr.GetImgData().sizes.raw_pitch / 2 + col; + unsigned black_level = lr_data.color.cblack[rcolors[col % 48]]; + int color_value = + rawdata[raw_idx] > black_level ? rawdata[raw_idx] - black_level : 0; + ASSERT_EQ(color_value, tv.color_values[row][col]); + } + } +} + +INSTANTIATE_TEST_SUITE_P(LibRawBase, LibRawTestFiles, + testing::ValuesIn(TestData)); + +} // namespace \ No newline at end of file diff --git a/contrib/libraw/utils/utils_libraw.cc b/contrib/libraw/utils/utils_libraw.cc new file mode 100644 index 0000000..b120361 --- /dev/null +++ b/contrib/libraw/utils/utils_libraw.cc @@ -0,0 +1,118 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "contrib/libraw/utils/utils_libraw.h" +#include "contrib/libraw/sandboxed.h" + + +absl::Status LibRaw::InitLibRaw() { + SAPI_ASSIGN_OR_RETURN(libraw_data_t * lr_data, api_.libraw_init(0)); + + sapi_libraw_data_t_.SetRemote(lr_data); + SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&sapi_libraw_data_t_)); + + return absl::OkStatus(); +} + +LibRaw::~LibRaw() { + if (sapi_libraw_data_t_.GetRemote() != nullptr) { + api_.libraw_close(sapi_libraw_data_t_.PtrNone()).IgnoreError(); + } +} + +absl::Status LibRaw::CheckIsInit() { return init_status_; } + +bool LibRaw::IsInit() { return CheckIsInit().ok(); } + +libraw_data_t LibRaw::GetImgData() { return sapi_libraw_data_t_.data(); } + +absl::Status LibRaw::OpenFile() { + SAPI_RETURN_IF_ERROR(CheckIsInit()); + + sapi::v::CStr file_name(file_name_.c_str()); + + SAPI_ASSIGN_OR_RETURN(int error_code, + api_.libraw_open_file(sapi_libraw_data_t_.PtrAfter(), + file_name.PtrBefore())); + + if (error_code != LIBRAW_SUCCESS) { + return absl::UnavailableError( + absl::string_view(std::to_string(error_code))); + } + + return absl::OkStatus(); +} + +absl::Status LibRaw::Unpack() { + SAPI_RETURN_IF_ERROR(CheckIsInit()); + + SAPI_ASSIGN_OR_RETURN(int error_code, + api_.libraw_unpack(sapi_libraw_data_t_.PtrAfter())); + if (error_code != LIBRAW_SUCCESS) { + return absl::UnavailableError( + absl::string_view(std::to_string(error_code))); + } + + return absl::OkStatus(); +} + +absl::Status LibRaw::SubtractBlack() { + SAPI_RETURN_IF_ERROR(CheckIsInit()); + + return api_.libraw_subtract_black(sapi_libraw_data_t_.PtrAfter()); +} + +absl::StatusOr> LibRaw::GetCameraList() { + SAPI_RETURN_IF_ERROR(CheckIsInit()); + + int size; + SAPI_ASSIGN_OR_RETURN(size, api_.libraw_cameraCount()); + + std::vector buf(size); + sapi::v::Array camera_list(buf.data(), buf.size()); + + char ** sapi_camera_list; + SAPI_ASSIGN_OR_RETURN(sapi_camera_list, api_.libraw_cameraList()); + + camera_list.SetRemote(sapi_camera_list); + SAPI_RETURN_IF_ERROR(api_.GetSandbox()->TransferFromSandboxee(&camera_list)); + + return buf; +} + +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::RawData() { + SAPI_RETURN_IF_ERROR(CheckIsInit()); + + int size = sapi_libraw_data_t_.data().sizes.raw_height * + sapi_libraw_data_t_.data().sizes.raw_width; + + std::vector buf(size); + sapi::v::Array rawdata(buf.data(), buf.size()); + + rawdata.SetRemote(sapi_libraw_data_t_.data().rawdata.raw_image); + SAPI_RETURN_IF_ERROR(api_.GetSandbox()->TransferFromSandboxee(&rawdata)); + + return buf; +} diff --git a/contrib/libraw/utils/utils_libraw.h b/contrib/libraw/utils/utils_libraw.h new file mode 100644 index 0000000..652e3b4 --- /dev/null +++ b/contrib/libraw/utils/utils_libraw.h @@ -0,0 +1,77 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CONTRIB_LIBRAW_UTILS_UTILS_LIBRAW_H_ +#define CONTRIB_LIBRAW_UTILS_UTILS_LIBRAW_H_ + +#include +#include "contrib/libraw/sandboxed.h" + +enum LibRaw_errors +{ + LIBRAW_SUCCESS = 0, + LIBRAW_UNSPECIFIED_ERROR = -1, + LIBRAW_FILE_UNSUPPORTED = -2, + LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE = -3, + LIBRAW_OUT_OF_ORDER_CALL = -4, + LIBRAW_NO_THUMBNAIL = -5, + LIBRAW_UNSUPPORTED_THUMBNAIL = -6, + LIBRAW_INPUT_CLOSED = -7, + LIBRAW_NOT_IMPLEMENTED = -8, + LIBRAW_UNSUFFICIENT_MEMORY = -100007, + LIBRAW_DATA_ERROR = -100008, + LIBRAW_IO_ERROR = -100009, + LIBRAW_CANCELLED_BY_CALLBACK = -100010, + LIBRAW_BAD_CROP = -100011, + LIBRAW_TOO_BIG = -100012, + LIBRAW_MEMPOOL_OVERFLOW = -100013 +}; + + +class LibRaw { + public: + LibRaw(LibRawSapiSandbox* sandbox, const std::string& file_name) + : sandbox_(CHECK_NOTNULL(sandbox)), + api_(sandbox_), + file_name_(file_name) { + init_status_ = InitLibRaw(); + } + + ~LibRaw(); + + absl::Status CheckIsInit(); + bool IsInit(); + + libraw_data_t GetImgData(); + absl::StatusOr> RawData(); + + absl::Status OpenFile(); + absl::Status Unpack(); + absl::Status SubtractBlack(); + absl::StatusOr> GetCameraList(); + absl::StatusOr COLOR(int row, int col); + + private: + absl::Status InitLibRaw(); + + LibRawSapiSandbox * sandbox_; + LibRawApi api_; + absl::Status init_status_; + + std::string file_name_; + + public: sapi::v::Struct sapi_libraw_data_t_; +}; + +#endif // CONTRIB_LIBRAW_UTILS_UTILS_LIBRAW_H_ \ No newline at end of file