Copybara import of the project:
--pull/171/head656cd15cb6
by Piotr Bartman <prbartman@gmail.com>: LibRaw --a505222184
by Piotr Bartman <prbartman@gmail.com>: CMake cleanup --7fc66b2026
by Piotr Bartman <prbartman@gmail.com>: cleanup + img.raw --1b1c085cfe
by Piotr Bartman <prbartman@gmail.com>: libraw: data checking --7e76425c37
by Piotr Bartman <prbartman@gmail.com>: libraw: CR @cblichmann PiperOrigin-RevId: 453859071 Change-Id: Ib9e1887f97d48ecbebda05c5c6df01e3642bbfba
parent
de836031d4
commit
0e7abb70fe
|
@ -11,7 +11,7 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04]
|
os: [ubuntu-20.04]
|
||||||
contrib: [jsonnet, libtiff, pffft]
|
contrib: [jsonnet, libraw, libtiff, pffft]
|
||||||
ignore-errors: [true]
|
ignore-errors: [true]
|
||||||
include:
|
include:
|
||||||
- compiler: clang
|
- compiler: clang
|
||||||
|
|
|
@ -18,15 +18,16 @@ set(SAPI_CONTRIB_SANDBOXES
|
||||||
hunspell
|
hunspell
|
||||||
jsonnet
|
jsonnet
|
||||||
libidn2
|
libidn2
|
||||||
|
libraw
|
||||||
libtiff
|
libtiff
|
||||||
libxls
|
libxls
|
||||||
libzip
|
libzip
|
||||||
pffft
|
pffft
|
||||||
turbojpeg
|
turbojpeg
|
||||||
uriparser
|
uriparser
|
||||||
|
woff2
|
||||||
zopfli
|
zopfli
|
||||||
zstd
|
zstd
|
||||||
woff2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(_contrib IN LISTS SAPI_CONTRIB_SANDBOXES)
|
foreach(_contrib IN LISTS SAPI_CONTRIB_SANDBOXES)
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.13..3.22)
|
||||||
|
|
||||||
|
project(sapi_libraw CXX)
|
||||||
|
include(CTest)
|
||||||
|
include(GoogleTest)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
|
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 a077aac05190530f22af4254a1e31745876d007f # 2022-06-03
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(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 # 2021-11-18
|
||||||
|
)
|
||||||
|
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_cameraList
|
||||||
|
libraw_cameraCount
|
||||||
|
|
||||||
|
libraw_COLOR
|
||||||
|
libraw_get_raw_height
|
||||||
|
libraw_get_raw_width
|
||||||
|
|
||||||
|
INPUTS "${CMAKE_BINARY_DIR}/raw.gen.h"
|
||||||
|
|
||||||
|
LIBRARY raw
|
||||||
|
LIBRARY_NAME LibRaw
|
||||||
|
NAMESPACE ""
|
||||||
|
)
|
||||||
|
add_library(sapi_contrib::libraw ALIAS sapi_libraw)
|
||||||
|
target_include_directories(sapi_libraw INTERFACE
|
||||||
|
"${PROJECT_BINARY_DIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(SAPI_BUILD_EXAMPLES)
|
||||||
|
add_subdirectory(example)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_TESTING AND SAPI_BUILD_TESTING)
|
||||||
|
add_subdirectory(test)
|
||||||
|
endif()
|
|
@ -0,0 +1,23 @@
|
||||||
|
# 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::logging
|
||||||
|
sapi::sapi
|
||||||
|
)
|
|
@ -0,0 +1,163 @@
|
||||||
|
// Copyright 2022 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may !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 <cstring>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
|
#include "contrib/libraw/sandboxed.h"
|
||||||
|
#include "contrib/libraw/utils/utils_libraw.h"
|
||||||
|
#include "sandboxed_api/util/logging.h"
|
||||||
|
|
||||||
|
void PrintUsage(const char* name) {
|
||||||
|
std::cout << "Dump (small) selecton of RAW file as tab-separated text file\n"
|
||||||
|
<< "Usage: " << name
|
||||||
|
<< " 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";
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t SubtractBlack(uint16_t val, unsigned int bl) {
|
||||||
|
return val > bl ? val - bl : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
sapi::InitLogging(argv[0]);
|
||||||
|
if (argc < 4) {
|
||||||
|
PrintUsage(argv[0]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int colstart = atoi(argv[2]); // NOLINT(runtime/deprecated_fn)
|
||||||
|
int rowstart = atoi(argv[3]); // NOLINT(runtime/deprecated_fn)
|
||||||
|
int channel = 0;
|
||||||
|
if (argc > 4) {
|
||||||
|
channel = atoi(argv[4]); // NOLINT(runtime/deprecated_fn)
|
||||||
|
}
|
||||||
|
int width = 16;
|
||||||
|
if (argc > 5) {
|
||||||
|
width = atoi(argv[5]); // NOLINT(runtime/deprecated_fn)
|
||||||
|
}
|
||||||
|
int height = 4;
|
||||||
|
if (argc > 6) {
|
||||||
|
height = atoi(argv[6]); // NOLINT(runtime/deprecated_fn)
|
||||||
|
}
|
||||||
|
if (width < 1 || height < 1) {
|
||||||
|
PrintUsage(argv[0]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sapi::v::ConstCStr file_name(argv[1]);
|
||||||
|
absl::Status status;
|
||||||
|
LibRawSapiSandbox sandbox(file_name.GetData());
|
||||||
|
|
||||||
|
status = sandbox.Init();
|
||||||
|
if (!status.ok()) {
|
||||||
|
std::cerr << "Unable to start sandbox: " << status.message() << "\n";
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LibRaw lr(&sandbox, argv[1]);
|
||||||
|
if (!lr.CheckIsInit().ok()) {
|
||||||
|
std::cerr << "Unable init LibRaw: " << lr.CheckIsInit().message();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = lr.OpenFile();
|
||||||
|
if (!status.ok()) {
|
||||||
|
std::cerr << "Unable to open file " << argv[1] << ": " << status.message();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((lr.GetColorCount() == 1 && channel > 0) || (channel > 3)) {
|
||||||
|
std::cerr << "Incorrect CHANNEL specified: " << channel << "\n";
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = lr.Unpack();
|
||||||
|
if (!status.ok()) {
|
||||||
|
std::cerr << "Unable to unpack file " << argv[1] << status.message();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = lr.SubtractBlack();
|
||||||
|
if (!status.ok()) {
|
||||||
|
std::cerr << "Unable to subtract black level: " << status.message();
|
||||||
|
// ok, but different output
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<std::vector<uint16_t>> rawdata = lr.RawData();
|
||||||
|
if (!rawdata.ok()) {
|
||||||
|
std::cerr << "Unable to get raw data: " << rawdata.status().message();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<ushort> raw_height = lr.GetRawHeight();
|
||||||
|
absl::StatusOr<ushort> raw_width = lr.GetRawWidth();
|
||||||
|
if (!raw_height.ok() || !raw_width.ok()) {
|
||||||
|
std::cerr << "Unable to get raw image sizes";
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// header
|
||||||
|
std::cout << argv[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 && col < *raw_width; col++) {
|
||||||
|
std::cout << std::setw(6) << col;
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
|
||||||
|
// dump raw to output
|
||||||
|
for (int row = rowstart; row < rowstart + height && row < *raw_height;
|
||||||
|
++row) {
|
||||||
|
int rcolors[48];
|
||||||
|
if (lr.GetColorCount() > 1) {
|
||||||
|
absl::StatusOr<int> 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 col = colstart; col < colstart + width && col < *raw_width;
|
||||||
|
++col) {
|
||||||
|
int idx = row * lr.GetImgData().sizes.raw_pitch / 2 + col;
|
||||||
|
|
||||||
|
if (rcolors[col % 48] == channel) {
|
||||||
|
absl::StatusOr<unsigned int> cblack = lr.GetCBlack(channel);
|
||||||
|
if (!cblack.ok()) {
|
||||||
|
std::cerr << "Unable to get cblack for channel " << channel << ": "
|
||||||
|
<< cblack.status().message();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
std::cout << std::setw(6) << SubtractBlack((*rawdata).at(idx), *cblack);
|
||||||
|
} else {
|
||||||
|
std::cout << " -";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,25 @@
|
||||||
|
// 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_RAW_GEN_H
|
||||||
|
#define CONTRIB_LIBRAW_RAW_GEN_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define __time_t uint64_t
|
||||||
|
#define time_t uint64_t
|
||||||
|
|
||||||
|
#include "${libraw_SOURCE_DIR}/libraw/libraw.h"
|
||||||
|
|
||||||
|
#endif // CONTRIB_LIBRAW_RAW_GEN_H
|
|
@ -0,0 +1,49 @@
|
||||||
|
// 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 <libgen.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#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<sandbox2::Policy> ModifyPolicy(
|
||||||
|
sandbox2::PolicyBuilder*) override {
|
||||||
|
return sandbox2::PolicyBuilder()
|
||||||
|
.AllowDynamicStartup()
|
||||||
|
.AllowOpen()
|
||||||
|
.AllowRead()
|
||||||
|
.AllowWrite()
|
||||||
|
.AllowSystemMalloc()
|
||||||
|
.AllowExit()
|
||||||
|
.AllowSyscalls({__NR_recvmsg})
|
||||||
|
.AddFile(file_name_, /*is_ro=*/true)
|
||||||
|
.BuildOrDie();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string file_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CONTRIB_LIBRAW_SANDBOXED_H_
|
|
@ -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_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"
|
||||||
|
)
|
|
@ -0,0 +1,187 @@
|
||||||
|
// 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];
|
||||||
|
} kTestData[] = {{.filename = "img.raw",
|
||||||
|
.raw_height = 540,
|
||||||
|
.raw_width = 960,
|
||||||
|
.COLOR =
|
||||||
|
{
|
||||||
|
{0, 1, 0, 1},
|
||||||
|
{3, 2, 3, 2},
|
||||||
|
{0, 1, 0, 1},
|
||||||
|
{3, 2, 3, 2},
|
||||||
|
},
|
||||||
|
.color_values = {
|
||||||
|
{548, 1285, 554, 1253},
|
||||||
|
{1290, 789, 1279, 788},
|
||||||
|
{551, 1303, 549, 1253},
|
||||||
|
{1265, 809, 1257, 779},
|
||||||
|
}}};
|
||||||
|
|
||||||
|
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<TestVariant> {};
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
SAPI_ASSERT_OK_AND_ASSIGN(ushort raw_height, lr.GetRawHeight());
|
||||||
|
SAPI_ASSERT_OK_AND_ASSIGN(ushort raw_width, lr.GetRawWidth());
|
||||||
|
|
||||||
|
EXPECT_EQ(raw_height, tv.raw_height);
|
||||||
|
EXPECT_EQ(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<char*> 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));
|
||||||
|
EXPECT_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<uint16_t> 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;
|
||||||
|
EXPECT_EQ(color_value, tv.color_values[row][col]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(LibRawBase, LibRawTestFiles,
|
||||||
|
testing::ValuesIn(kTestData));
|
||||||
|
|
||||||
|
} // namespace
|
|
@ -0,0 +1,159 @@
|
||||||
|
// 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<std::vector<char*>> LibRaw::GetCameraList() {
|
||||||
|
SAPI_RETURN_IF_ERROR(CheckIsInit());
|
||||||
|
|
||||||
|
int size;
|
||||||
|
SAPI_ASSIGN_OR_RETURN(size, api_.libraw_cameraCount());
|
||||||
|
|
||||||
|
std::vector<char*> buf(size);
|
||||||
|
sapi::v::Array<char*> 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(sandbox_->TransferFromSandboxee(&camera_list));
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<int> 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<int> 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<int> 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<unsigned int> LibRaw::GetCBlack(int channel) {
|
||||||
|
SAPI_RETURN_IF_ERROR(CheckIsInit());
|
||||||
|
|
||||||
|
if (channel < 0 || >= 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<std::vector<uint16_t>> LibRaw::RawData() {
|
||||||
|
SAPI_RETURN_IF_ERROR(CheckIsInit());
|
||||||
|
|
||||||
|
int raw_height;
|
||||||
|
int raw_width;
|
||||||
|
SAPI_ASSIGN_OR_RETURN(raw_height, GetRawHeight());
|
||||||
|
SAPI_ASSIGN_OR_RETURN(raw_width, GetRawWidth());
|
||||||
|
int size = raw_height * raw_width;
|
||||||
|
std::vector<uint16_t> buf(size);
|
||||||
|
sapi::v::Array<uint16_t> rawdata(buf.data(), buf.size());
|
||||||
|
|
||||||
|
rawdata.SetRemote(sapi_libraw_data_t_.data().rawdata.raw_image);
|
||||||
|
SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&rawdata));
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
// 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 <vector>
|
||||||
|
|
||||||
|
#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<std::vector<uint16_t>> RawData();
|
||||||
|
|
||||||
|
absl::Status OpenFile();
|
||||||
|
absl::Status Unpack();
|
||||||
|
absl::Status SubtractBlack();
|
||||||
|
absl::StatusOr<std::vector<char*>> GetCameraList();
|
||||||
|
absl::StatusOr<int> COLOR(int row, int col);
|
||||||
|
absl::StatusOr<int> GetRawHeight();
|
||||||
|
absl::StatusOr<int> GetRawWidth();
|
||||||
|
absl::StatusOr<unsigned int> GetCBlack(int channel);
|
||||||
|
int GetColorCount();
|
||||||
|
|
||||||
|
private:
|
||||||
|
absl::Status InitLibRaw();
|
||||||
|
|
||||||
|
LibRawSapiSandbox* sandbox_;
|
||||||
|
LibRawApi api_;
|
||||||
|
absl::Status init_status_;
|
||||||
|
|
||||||
|
std::string file_name_;
|
||||||
|
|
||||||
|
sapi::v::Struct<libraw_data_t> sapi_libraw_data_t_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CONTRIB_LIBRAW_UTILS_UTILS_LIBRAW_H_
|
Loading…
Reference in New Issue