diff --git a/.gitmodules b/.gitmodules index e7461eb..acd11e8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -15,7 +15,10 @@ url = https://github.com/OSGeo/gdal/ [submodule "oss-internship-2020/curl/curl_wrapper/curl"] path = oss-internship-2020/curl/curl_wrapper/curl - url = git@github.com:curl/curl.git + url = https://github.com/curl/curl [submodule "oss-internship-2020/libuv/libuv"] path = oss-internship-2020/libuv/libuv - url = git@github.com:libuv/libuv.git + url = https://github.com/libuv/libuv.git +[submodule "oss-internship-2020/libtiff/wrapper/libtiff"] + path = oss-internship-2020/libtiff/wrapper/libtiff + url = https://gitlab.com/libtiff/libtiff diff --git a/oss-internship-2020/libtiff/.gitignore b/oss-internship-2020/libtiff/.gitignore new file mode 100644 index 0000000..6f31401 --- /dev/null +++ b/oss-internship-2020/libtiff/.gitignore @@ -0,0 +1,2 @@ +build/ +.vscode/ diff --git a/oss-internship-2020/libtiff/CMakeLists.txt b/oss-internship-2020/libtiff/CMakeLists.txt new file mode 100644 index 0000000..9f14738 --- /dev/null +++ b/oss-internship-2020/libtiff/CMakeLists.txt @@ -0,0 +1,130 @@ +# Copyright 2020 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 +# +# http://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.10) + +project(sandboxed_libtiff CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +# Set this on the command-line +set(SAPI_ROOT "" CACHE PATH "Path to the Sandboxed API source tree") +# To obtain a full SAPI_ROOT check out its source separately: +# git clone https://github.com/google/sandboxed-api.git $HOME/sapi_root +# Then configure: +# mkdir -p build && cd build +# cmake .. -G Ninja -DSAPI_ROOT=$HOME/sapi_root + +option(TIFF_SAPI_ENABLE_EXAMPLES "" ON) +option(TIFF_SAPI_ENABLE_TESTS "" ON) + +set(SAPI_ENABLE_EXAMPLES ${TIFF_SAPI_ENABLE_EXAMPLES} CACHE BOOL "" FORCE) +set(SAPI_ENABLE_TESTS ${TIFF_SAPI_ENABLE_TESTS} CACHE BOOL "" FORCE) + +add_subdirectory(wrapper) + +add_subdirectory( + "${SAPI_ROOT}" + "${CMAKE_BINARY_DIR}/sandboxed-api-build" + # Omit this to have the full Sandboxed API in IDE + EXCLUDE_FROM_ALL +) + +add_sapi_library(tiff_sapi + # List of functions that we want to include in the + # generated sandboxed API class + FUNCTIONS TIFFOpen + TIFFClose + + TIFFGetField1 + TIFFGetField2 + TIFFGetField3 + + TIFFSetFieldUChar1 + TIFFSetFieldUChar2 + TIFFSetFieldUChar3 + TIFFSetFieldSChar1 + TIFFSetFieldSChar2 + TIFFSetFieldSChar3 + TIFFSetFieldU1 + TIFFSetFieldU2 + TIFFSetFieldU3 + TIFFSetFieldS1 + TIFFSetFieldS2 + TIFFSetFieldS3 + TIFFSetFieldUShort1 + TIFFSetFieldUShort2 + TIFFSetFieldUShort3 + TIFFSetFieldSShort1 + TIFFSetFieldSShort2 + TIFFSetFieldSShort3 + TIFFSetFieldULLong1 + TIFFSetFieldULLong2 + TIFFSetFieldULLong3 + TIFFSetFieldSLLong1 + TIFFSetFieldSLLong2 + TIFFSetFieldSLLong3 + TIFFSetFieldFloat1 + TIFFSetFieldFloat2 + TIFFSetFieldFloat3 + TIFFSetFieldDouble1 + TIFFSetFieldDouble2 + TIFFSetFieldDouble3 + + TIFFReadRGBATile + TIFFReadEncodedTile + TIFFReadEncodedStrip + TIFFReadFromUserBuffer + + TIFFTileSize + TIFFSetDirectory + TIFFFreeDirectory + TIFFCreateDirectory + + TIFFForceStrileArrayWriting + TIFFDeferStrileArrayWriting + + TIFFWriteCheck + TIFFWriteScanline + TIFFWriteDirectory + TIFFWriteEncodedTile + TIFFWriteEncodedStrip + + TIFFGetStrileOffsetWithErr + TIFFGetStrileByteCountWithErr + + TIFFCreateEXIFDirectory + TIFFWriteCustomDirectory + + INPUTS wrapper/libtiff/libtiff/tiffio.h + wrapper/func.h + # Header files or .cc files that should be parsed + LIBRARY wrapped_tiff # Library dependency from the add_library() above + LIBRARY_NAME Tiff # Name prefix for the generated header. Will be + # suffixed with "Api" and "Sandbox" as needed. + NAMESPACE "" # Optional C++ namespace to wrap the generated code +) + +target_include_directories(tiff_sapi INTERFACE + "${PROJECT_BINARY_DIR}" # To find the generated SAPI header +) + +if (TIFF_SAPI_ENABLE_EXAMPLES) + add_subdirectory(example) +endif() + +if (TIFF_SAPI_ENABLE_TESTS) + add_subdirectory(test) +endif() diff --git a/oss-internship-2020/libtiff/README.md b/oss-internship-2020/libtiff/README.md new file mode 100644 index 0000000..4e253db --- /dev/null +++ b/oss-internship-2020/libtiff/README.md @@ -0,0 +1,22 @@ +# sapi-libtiff +Copyright 2020 Google LLC. + +## Start use +You should make sure the libtiff submodule is cloned. + +`git clone --recursive https://github.com/alexelex/sapi-libtiff` + +## Usage + +#### build: +`mkdir -p build && cd build && cmake .. -DSAPI_ROOT=$HOME/sapi_root -DBUILD_SHARED_LIBS=OFF` + +`make -j 8` + +#### to run the sandboxed example: +`./example/sandboxed absolute/path/to/project/dir` + +#### to run tests: +`./test/tests` + +you also can use sandbox flags `sandbox2_danger_danger_permit_all` and `sandbox2_danger_danger_permit_all_and_log` diff --git a/oss-internship-2020/libtiff/example/CMakeLists.txt b/oss-internship-2020/libtiff/example/CMakeLists.txt new file mode 100644 index 0000000..b266071 --- /dev/null +++ b/oss-internship-2020/libtiff/example/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright 2020 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 +# +# http://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(sandboxed + main_sandboxed.cc + ../sandboxed.h +) + +target_link_libraries(sandboxed PRIVATE + tiff_sapi + sapi::sapi + sandbox2::temp_file +) diff --git a/oss-internship-2020/libtiff/example/main_sandboxed.cc b/oss-internship-2020/libtiff/example/main_sandboxed.cc new file mode 100644 index 0000000..44e71b0 --- /dev/null +++ b/oss-internship-2020/libtiff/example/main_sandboxed.cc @@ -0,0 +1,281 @@ +// Copyright 2020 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 +// +// http://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 +#include +#include + +#include "../sandboxed.h" // NOLINT(build/include) +#include "sandboxed_api/sandbox2/util/fileops.h" +#include "sandboxed_api/sandbox2/util/path.h" +#include "tiffio.h" // NOLINT(build/include) + +// sapi functions: +// TIFFTileSize +// TIFFOpen +// TIFFReadEncodedTile +// TIFFSetField +// TIFFClose +// TIFFReadRGBATile +// TIFFGetField + +namespace { + +constexpr std::array kCluster0 = {0, 0, 2, 0, 138, 139}; +constexpr std::array kCluster64 = {0, 0, 9, 6, 134, 119}; +constexpr std::array kCluster128 = {44, 40, 63, 59, 230, 95}; + +int CheckCluster(int cluster, const sapi::v::Array& buffer, + const std::vector& expected_cluster) { + uint8_t* target = buffer.GetData() + cluster * 6; + + if (!std::memcmp(target, expected_cluster.data(), 6)) { + return 0; + } + + std::cerr << "Cluster " << cluster << " did not match expected results.\n" + << "Expect: " << expected_cluster[0] << "\t" << expected_cluster[1] + << "\t" << expected_cluster[4] << "\t" << expected_cluster[5] + << "\t" << expected_cluster[2] << "\t" << expected_cluster[3] + << "\n" + << "Got: " << target[0] << "\t" << target[1] << "\t" << target[4] + << "\t" << target[5] << "\t" << target[2] << "\t" << target[3] + << '\n'; + + return 1; +} + +int CheckRgbPixel(int pixel, int min_red, int max_red, int min_green, + int max_green, int min_blue, int max_blue, + const sapi::v::Array& buffer) { + uint8_t* rgb = buffer.GetData() + 3 * pixel; + + if (rgb[0] >= min_red && rgb[0] <= max_red && rgb[1] >= min_green && + rgb[1] <= max_green && rgb[2] >= min_blue && rgb[2] <= max_blue) { + return 0; + } + + std::cerr << "Pixel " << pixel << " did not match expected results.\n" + << "Got R=" << rgb[0] << " (expected " << min_red << ".." << max_red + << "), G=" << rgb[1] << " (expected " << min_green << ".." + << max_green << "), B=" << rgb[2] << " (expected " << min_blue + << ".." << max_blue << ")\n"; + return 1; +} + +int CheckRgbaPixel(int pixel, int min_red, int max_red, int min_green, + int max_green, int min_blue, int max_blue, int min_alpha, + int max_alpha, const sapi::v::Array& buffer) { + // RGBA images are upside down - adjust for normal ordering + int adjusted_pixel = pixel % 128 + (127 - (pixel / 128)) * 128; + uint32_t rgba = buffer[adjusted_pixel]; + + if (TIFFGetR(rgba) >= static_cast(min_red) && + TIFFGetR(rgba) <= static_cast(max_red) && + TIFFGetG(rgba) >= static_cast(min_green) && + TIFFGetG(rgba) <= static_cast(max_green) && + TIFFGetB(rgba) >= static_cast(min_blue) && + TIFFGetB(rgba) <= static_cast(max_blue) && + TIFFGetA(rgba) >= static_cast(min_alpha) && + TIFFGetA(rgba) <= static_cast(max_alpha)) { + return 0; + } + + std::cerr << "Pixel " << pixel << " did not match expected results.\n" + << "Got R=" << TIFFGetR(rgba) << " (expected " << min_red << ".." + << max_red << "), G=" << TIFFGetG(rgba) << " (expected " + << min_green << ".." << max_green << "), B=" << TIFFGetB(rgba) + << " (expected " << min_blue << ".." << max_blue + << "), A=" << TIFFGetA(rgba) << " (expected " << min_alpha << ".." + << max_alpha << ")\n"; + return 1; +} +std::string GetFilePath(const std::string& dir, const std::string& filename) { + return sandbox2::file::JoinPath(dir, "test", "images", filename); +} + +std::string GetCWD() { + char cwd[PATH_MAX]; + getcwd(cwd, sizeof(cwd)); + return cwd; +} + +std::string GetFilePath(const std::string filename) { + std::string cwd = GetCWD(); + auto find = cwd.rfind("build"); + + std::string project_path; + if (find == std::string::npos) { + std::cerr << "Something went wrong: CWD don't contain build dir. " + << "Please run tests from build dir or send project dir as a " + << "parameter: ./sandboxed /absolute/path/to/project/dir \n"; + project_path = cwd; + } else { + project_path = cwd.substr(0, find); + } + + return sandbox2::file::JoinPath(project_path, "test", "images", filename); +} + +} // namespace + +int main(int argc, char** argv) { + gflags::ParseCommandLineFlags(&argc, &argv, true); + + std::string srcfile; + // "test/images/quad-tile.jpg.tiff" + std::string srcfilerel = "quad-tile.jpg.tiff"; + + if (argc < 2) { + srcfile = GetFilePath(srcfilerel); + } else { + srcfile = GetFilePath(argv[1], srcfilerel); + } + + // without addDir to sandbox. to add dir use + // sandbox(absolute_path_to_dir, srcfile) or + // sandbox(absolute_path_to_dir). file and dir should be exists. + // srcfile must also be absolute_path_to_file + TiffSapiSandbox sandbox("", srcfile); + + // initialize sapi vars after constructing TiffSapiSandbox + sapi::v::UShort h, v; + sapi::StatusOr status_or_tif; + sapi::StatusOr status_or_int; + sapi::StatusOr status_or_long; + + auto status = sandbox.Init(); + if (!status.ok()) { + fprintf(stderr, "Couldn't initialize Sandboxed API: %s\n", status); + } + + TiffApi api(&sandbox); + sapi::v::ConstCStr srcfile_var(srcfile.c_str()); + sapi::v::ConstCStr r_var("r"); + + status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore()); + if (!status_or_tif.ok()) { + std::cerr << "Could not open " << srcfile << ", TIFFError\n"; + return 1; + } + + sapi::v::RemotePtr tif(status_or_tif.value()); + if (!tif.GetValue()) { + // tif is NULL + std::cerr << "Could not open " << srcfile << "\n"; + return 1; + } + + status_or_int = api.TIFFGetField2(&tif, TIFFTAG_YCBCRSUBSAMPLING, h.PtrBoth(), + v.PtrBoth()); + if (!status_or_int.ok() || status_or_int.value() == 0 || h.GetValue() != 2 || + v.GetValue() != 2) { + std::cerr << "Could not retrieve subsampling tag\n"; + return 1; + } + + status_or_long = api.TIFFTileSize(&tif); + if (!status_or_int.ok() || status_or_long.value() != 24576) { + std::cerr << "tiles are " << status_or_long.value() << " bytes\n"; + exit(1); + } + tsize_t sz = status_or_long.value(); + + sapi::v::Array buffer_(sz); + status_or_long = api.TIFFReadEncodedTile(&tif, 9, buffer_.PtrBoth(), sz); + if (!status_or_long.ok() || status_or_long.value() != sz) { + std::cerr << "Did not get expected result code from" + << "TIFFReadEncodedTile(): (" << status_or_long.value() + << " instead of " << sz << ")\n"; + return 1; + } + + if (CheckCluster(0, buffer_, kCluster0) || + CheckCluster(64, buffer_, kCluster64) || + CheckCluster(128, buffer_, kCluster128)) { + return 1; + } + + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); + if (!status_or_int.ok() || !status_or_int.value()) { + std::cerr << "TIFFSetFieldU1 not available\n"; + } + + status_or_long = api.TIFFTileSize(&tif); + if (!status_or_long.ok() || status_or_long.value() != 128 * 128 * 3) { + std::cerr << "tiles are " << status_or_long.value() << " bytes\n"; + return 1; + } + sz = status_or_long.value(); + + sapi::v::Array buffer2_(sz); + + status_or_long = api.TIFFReadEncodedTile(&tif, 9, buffer2_.PtrBoth(), sz); + if (!status_or_long.ok() || status_or_long.value() != sz) { + std::cerr << "Did not get expected result code from " + << "TIFFReadEncodedTile(): (" << status_or_long.value() + << " instead of " << sz << ")\n"; + return 1; + } + + uint32_t pixel_status = 0; + pixel_status |= CheckRgbPixel(0, 15, 18, 0, 0, 18, 41, buffer2_); + pixel_status |= CheckRgbPixel(64, 0, 0, 0, 0, 0, 2, buffer2_); + pixel_status |= CheckRgbPixel(512, 5, 6, 34, 36, 182, 196, buffer2_); + + if (!api.TIFFClose(&tif).ok()) { + std::cerr << "TIFFClose error\n"; + } + + status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore()); + if (!status_or_tif.ok()) { + std::cerr << "Could not reopen " << srcfile << "\n"; + return 1; + } + + sapi::v::RemotePtr tif2(status_or_tif.value()); + if (!tif2.GetValue()) { // tif is NULL + std::cerr << "Could not reopen " << srcfile << "\n"; + return 1; + } + + sapi::v::Array rgba_buffer_(128 * 128); + + status_or_int = + api.TIFFReadRGBATile(&tif2, 1 * 128, 2 * 128, rgba_buffer_.PtrBoth()); + if (!status_or_int.ok() || !status_or_int.value()) { + fprintf(stderr, "TIFFReadRGBATile() returned failure code.\n"); + return 1; + } + + pixel_status |= + CheckRgbaPixel(0, 15, 18, 0, 0, 18, 41, 255, 255, rgba_buffer_); + pixel_status |= CheckRgbaPixel(64, 0, 0, 0, 0, 0, 2, 255, 255, rgba_buffer_); + pixel_status |= + CheckRgbaPixel(512, 5, 6, 34, 36, 182, 196, 255, 255, rgba_buffer_); + + if (!api.TIFFClose(&tif2).ok()) { + std::cerr << "TIFFClose erro\n"; + } + + if (pixel_status) { + std::cerr << "pixel_status is true, expected false"; + return 1; + } + + return 0; +} diff --git a/oss-internship-2020/libtiff/sandboxed.h b/oss-internship-2020/libtiff/sandboxed.h new file mode 100644 index 0000000..27f3a75 --- /dev/null +++ b/oss-internship-2020/libtiff/sandboxed.h @@ -0,0 +1,70 @@ +// Copyright 2020 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 +// +// http://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 LIBTIFF_SANDBOXED_H_ +#define LIBTIFF_SANDBOXED_H_ + +#include +#include + +#include + +#include "sandboxed_api/util/flag.h" +#include "tiff_sapi.sapi.h" // NOLINT(build/include) + +ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all); +ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all_and_log); + +class TiffSapiSandbox : public TiffSandbox { + public: + explicit TiffSapiSandbox(std::string dir = "", std::string file = "") + : dir_(std::move(dir)), file_(std::move(file)) {} + + private: + std::unique_ptr ModifyPolicy( + sandbox2::PolicyBuilder*) override { + auto builder = sandbox2::PolicyBuilder() + .AllowRead() + .AllowStaticStartup() + .AllowWrite() + .AllowOpen() + .AllowExit() + .AllowStat() + .AllowSystemMalloc() + .AllowSyscalls({ + __NR_futex, + __NR_close, + __NR_lseek, + __NR_gettid, + __NR_sysinfo, + __NR_mmap, + __NR_munmap, + }); + + if (!dir_.empty()) { + builder.AddDirectory(dir_, /*is_ro=*/false); + } + + if (!file_.empty()) { + builder.AddFile(file_, /*is_ro=*/false); + } + + return builder.BuildOrDie(); + } + + std::string dir_; + std::string file_; +}; + +#endif // LIBTIFF_SANDBOXED_H_ diff --git a/oss-internship-2020/libtiff/test/CMakeLists.txt b/oss-internship-2020/libtiff/test/CMakeLists.txt new file mode 100644 index 0000000..b36e65a --- /dev/null +++ b/oss-internship-2020/libtiff/test/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright 2020 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 +# +# http://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(tests + check_tag.h + check_tag.cc + defer_strile_writing.cc + long_tag.cc + raw_decode.cc + short_tag.cc + helper.h + helper.cc +) + +target_link_libraries(tests PRIVATE + tiff_sapi + sapi::sapi + sandbox2::temp_file + gtest + gmock + gtest_main +) + +gtest_discover_tests(tests) diff --git a/oss-internship-2020/libtiff/test/check_tag.cc b/oss-internship-2020/libtiff/test/check_tag.cc new file mode 100644 index 0000000..58fb717 --- /dev/null +++ b/oss-internship-2020/libtiff/test/check_tag.cc @@ -0,0 +1,71 @@ +// Copyright 2020 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 +// +// http://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 "check_tag.h" // NOLINT(build/include) + +using ::sapi::IsOk; +using ::testing::Eq; +using ::testing::IsFalse; +using ::testing::IsTrue; + +// sapi functions: +// TIFFGetField + +namespace { + +void CheckShortField(TiffApi& api, sapi::v::RemotePtr& tif, const ttag_t field, + const uint16_t value) { + sapi::v::UShort tmp(123); + sapi::StatusOr status_or_int; + + status_or_int = api.TIFFGetField1(&tif, field, tmp.PtrBoth()); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFGetField1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Problem fetching tag " << field; + EXPECT_THAT(tmp.GetValue(), Eq(value)) + << "Wrong SHORT value fetched for tag " << field; +} + +void CheckShortPairedField(TiffApi& api, sapi::v::RemotePtr& tif, + const ttag_t field, + const std::array& values) { + sapi::v::UShort tmp0(123); + sapi::v::UShort tmp1(456); + sapi::StatusOr status_or_int; + + status_or_int = + api.TIFFGetField2(&tif, field, tmp0.PtrBoth(), tmp1.PtrBoth()); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFGetField2 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Problem fetching tag " << field; + EXPECT_THAT(tmp0.GetValue(), Eq(values[0])) + << "Wrong SHORT PAIR[0] fetched for tag " << field; + EXPECT_THAT(tmp1.GetValue(), Eq(values[1])) + << "Wrong SHORT PAIR[1] fetched for tag " << field; +} + +void CheckLongField(TiffApi& api, sapi::v::RemotePtr& tif, const ttag_t field, + const uint32_t value) { + sapi::v::UInt tmp(123); + sapi::StatusOr status_or_int; + + status_or_int = api.TIFFGetField1(&tif, field, tmp.PtrBoth()); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFGetField1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Problem fetching tag " << field; + EXPECT_THAT(tmp.GetValue(), Eq(value)) + << "Wrong LONG value fetched for tag " << field; +} + +} // namespace diff --git a/oss-internship-2020/libtiff/test/check_tag.h b/oss-internship-2020/libtiff/test/check_tag.h new file mode 100644 index 0000000..03e02e2 --- /dev/null +++ b/oss-internship-2020/libtiff/test/check_tag.h @@ -0,0 +1,31 @@ +// Copyright 2020 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 +// +// http://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 LIBTIFF_TEST_CHECK_TAG_H_ +#define LIBTIFF_TEST_CHECK_TAG_H_ + +#include + +#include "helper.h" // NOLINT(build/include) +#include "tiffio.h" // NOLINT(build/include) + +void CheckShortField(TiffApi&, sapi::v::RemotePtr& tif, const ttag_t field, + const uint16_t value); +void CheckShortPairedField(TiffApi& api, sapi::v::RemotePtr& tif, + const ttag_t field, + const std::array& values); +void CheckLongField(TiffApi&, sapi::v::RemotePtr& tif, const ttag_t field, + const uint32_t value); + +#endif // LIBTIFF_TEST_CHECK_TAG_H_ diff --git a/oss-internship-2020/libtiff/test/defer_strile_writing.cc b/oss-internship-2020/libtiff/test/defer_strile_writing.cc new file mode 100644 index 0000000..5ae176f --- /dev/null +++ b/oss-internship-2020/libtiff/test/defer_strile_writing.cc @@ -0,0 +1,332 @@ +// Copyright 2020 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 +// +// http://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 "helper.h" // NOLINT(build/include) +#include "tiffio.h" // NOLINT(build/include) + +using ::sapi::IsOk; +using ::testing::Eq; +using ::testing::IsTrue; +using ::testing::NotNull; + +// sapi functions: +// TIFFOpen +// TIFFClose +// TIFFGetField +// TIFFSetField +// TIFFWriteCheck +// TIFFSetDirectory +// TIFFFreeDirectory +// TIFFWriteScanline +// TIFFWriteDirectory +// TIFFCreateDirectory +// TIFFReadEncodedTile +// TIFFReadEncodedStrip +// TIFFWriteEncodedTile +// TIFFWriteEncodedStrip +// TIFFDeferStrileArrayWriting +// TIFFForceStrileArrayWriting + +namespace { + +constexpr int kTileBufferSize = 256; +constexpr int kWidth = 1; +constexpr int kBps = 8; +constexpr int kRowsPerStrip = 1; +constexpr int kSamplePerPixel = 1; + +void TestWriting(const char* mode, int tiled, int height) { + sapi::StatusOr status_or_path = + sandbox2::CreateNamedTempFileAndClose("defer_strile_writing.tif"); + ASSERT_THAT(status_or_path, IsOk()) << "Could not create temp file"; + + std::string srcfile = sandbox2::file::JoinPath( + sandbox2::file_util::fileops::GetCWD(), status_or_path.value()); + + sapi::StatusOr status_or_int; + sapi::StatusOr status_or_long; + sapi::StatusOr status_or_tif; + + TiffSapiSandbox sandbox("", srcfile); + ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API"; + + TiffApi api(&sandbox); + sapi::v::ConstCStr srcfile_var(srcfile.c_str()); + sapi::v::ConstCStr mode_var(mode); + + status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), mode_var.PtrBefore()); + ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile; + + sapi::v::RemotePtr tif(status_or_tif.value()); + ASSERT_THAT(tif.GetValue(), NotNull()) + << "Can't create test TIFF file " << srcfile; + + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set CompressionNone tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_IMAGEWIDTH, kWidth); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageWidth tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_IMAGELENGTH, height); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageLenght tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_BITSPERSAMPLE, kBps); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set BitsPerSample tag"; + + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_SAMPLESPERPIXEL, kSamplePerPixel); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set SamplesPerPixel tag"; + + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set PlanarConfiguration tag"; + + if (tiled) { + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_TILEWIDTH, 16); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set TileWidth tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_TILELENGTH, 16); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set TileLenght tag"; + } else { + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_ROWSPERSTRIP, kRowsPerStrip); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set RowsPerStrip tag"; + } + + status_or_int = api.TIFFDeferStrileArrayWriting(&tif); + ASSERT_THAT(status_or_int, IsOk()) + << "TIFFDeferStrileArrayWriting fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFDeferStrileArrayWriting return unexpected value"; + + sapi::v::ConstCStr test_var("test"); + status_or_int = api.TIFFWriteCheck(&tif, tiled, test_var.PtrBefore()); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFWriteCheck fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFWriteCheck return unexpected value " + << "void test(" << mode << ", " << tiled << ", " << height << ")"; + + status_or_int = api.TIFFWriteDirectory(&tif); + ASSERT_THAT(status_or_int, IsOk()) + << "TIFFDeferStrileArrayWriting fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFDeferStrileArrayWriting return unexpected value"; + + // Create other directory + ASSERT_THAT(api.TIFFFreeDirectory(&tif), IsOk()) + << "TIFFFreeDirectory fatal error"; + ASSERT_THAT(api.TIFFCreateDirectory(&tif), IsOk()) + << "TIFFCreateDirectory fatal error"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set SubFileType tag"; + + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set CompressionNone tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_IMAGEWIDTH, kWidth); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageWidth tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_IMAGELENGTH, 1); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageLenght tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_BITSPERSAMPLE, kBps); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set BitsPerSample tag"; + + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_SAMPLESPERPIXEL, kSamplePerPixel); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set SamplesPerPixel tag"; + + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set PlanarConfiguration tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_ROWSPERSTRIP, kRowsPerStrip); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set RowsPerStrip tag"; + + status_or_int = api.TIFFDeferStrileArrayWriting(&tif); + ASSERT_THAT(status_or_int, IsOk()) + << "TIFFDeferStrileArrayWriting fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFDeferStrileArrayWriting return unexpected value"; + + status_or_int = api.TIFFWriteCheck(&tif, 0, test_var.PtrBefore()); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFWriteCheck fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFWriteCheck return unexpected value"; + + status_or_int = api.TIFFWriteDirectory(&tif); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFWriteDirectory fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFWriteDirectory return unexpected value"; + + // Force writing of strile arrays + status_or_int = api.TIFFSetDirectory(&tif, 0); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetDirectory fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFSetDirectory return unexpected value"; + + status_or_int = api.TIFFForceStrileArrayWriting(&tif); + ASSERT_THAT(status_or_int, IsOk()) + << "TIFFForceStrileArrayWriting fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFForceStrileArrayWriting return unexpected value"; + + status_or_int = api.TIFFSetDirectory(&tif, 1); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetDirectory fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFSetDirectory return unexpected value"; + + status_or_int = api.TIFFForceStrileArrayWriting(&tif); + ASSERT_THAT(status_or_int, IsOk()) + << "TIFFForceStrileArrayWriting fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFForceStrileArrayWriting return unexpected value"; + + // Now write data on frist directory + status_or_int = api.TIFFSetDirectory(&tif, 0); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetDirectory fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFSetDirectory return unexpected value"; + + if (tiled) { + for (int i = 0; i < (height + 15) / 16; ++i) { + std::array tilebuffer; + tilebuffer.fill(i); + sapi::v::Array tilebuffer_(tilebuffer.data(), kTileBufferSize); + + status_or_int = api.TIFFWriteEncodedTile(&tif, i, tilebuffer_.PtrBoth(), + kTileBufferSize); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFWriteEncodedTile fatal error"; + EXPECT_THAT(status_or_int.value(), Eq(kTileBufferSize)) + << "line " << i << ": expected 256, got " << status_or_int.value(); + } + } else { + for (int i = 0; i < height; ++i) { + sapi::v::UChar c(i); + status_or_long = api.TIFFWriteEncodedStrip(&tif, i, c.PtrBoth(), 1); + ASSERT_THAT(status_or_long, IsOk()) + << "TIFFWriteEncodedStrip fatal error"; + EXPECT_THAT(status_or_int.value(), Eq(1)) + << "line " << i << ": expected 1, got " << status_or_int.value(); + + if (i == 1 && height > 100000) { + i = height - 2; + } + } + } + + ASSERT_THAT(api.TIFFClose(&tif), IsOk()) << "TIFFClose fatal error"; + + sapi::v::ConstCStr r_var("r"); + status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore()); + ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile; + + sapi::v::RemotePtr tif2(status_or_tif.value()); + ASSERT_THAT(tif2.GetValue(), NotNull()) << "can't open " << srcfile; + + if (tiled) { + for (int i = 0; i < (height + 15) / 16; ++i) { + for (int retry = 0; retry < 2; ++retry) { + std::array tilebuffer; + auto expected_c = static_cast(i); + tilebuffer.fill(0); + + sapi::v::Array tilebuffer_(tilebuffer.data(), kTileBufferSize); + status_or_long = api.TIFFReadEncodedTile( + &tif2, i, tilebuffer_.PtrBoth(), kTileBufferSize); + ASSERT_THAT(status_or_long, IsOk()) + << "TIFFReadEncodedTile fatal error"; + EXPECT_THAT(status_or_long.value(), Eq(kTileBufferSize)) + << "line " << i << ": expected 256, got " << status_or_long.value(); + + bool cmp = tilebuffer[0] != expected_c || tilebuffer[255] != expected_c; + + EXPECT_THAT(tilebuffer[0], Eq(expected_c)) + << "unexpected value at tile " << i << ": expected " << expected_c + << ", got " << tilebuffer[0]; + + EXPECT_THAT(tilebuffer[255], Eq(expected_c)) + << "unexpected value at tile " << i << ": expected " << expected_c + << ", got " << tilebuffer[255]; + if (cmp) { + ASSERT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error"; + } + } + } + } else { + for (int i = 0; i < height; ++i) { + for (int retry = 0; retry < 2; ++retry) { + sapi::v::UChar c(0); + auto expected_c = static_cast(i); + + status_or_long = api.TIFFReadEncodedStrip(&tif2, i, c.PtrBoth(), 1); + ASSERT_THAT(status_or_long, IsOk()) + << "TIFFReadEncodedStrip fatal error"; + EXPECT_THAT(status_or_long.value(), Eq(1)) + << "line " << i << ": expected 1, got " << status_or_long.value(); + EXPECT_THAT(c.GetValue(), Eq(expected_c)) + << "unexpected value at line " << i << ": expected " << expected_c + << ", got " << c.GetValue(); + + if (c.GetValue() != expected_c) { + ASSERT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error"; + } + } + } + } + + ASSERT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error"; + + unlink(srcfile.c_str()); +} + +TEST(SandboxTest, DeferStrileWriting) { + for (int tiled = 0; tiled <= 1; ++tiled) { + TestWriting("w", tiled, 1); + TestWriting("w", tiled, 10); + TestWriting("w8", tiled, 1); + TestWriting("wD", tiled, 1); + } +} + +} // namespace diff --git a/oss-internship-2020/libtiff/test/helper.cc b/oss-internship-2020/libtiff/test/helper.cc new file mode 100644 index 0000000..67761e1 --- /dev/null +++ b/oss-internship-2020/libtiff/test/helper.cc @@ -0,0 +1,45 @@ +// Copyright 2020 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 +// +// http://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 "helper.h" // NOLINT(build/include) + +#include + +auto* g_in_dir = new std::string(); + +std::string GetCWD() { + char cwd[PATH_MAX]; + getcwd(cwd, sizeof(cwd)); + return cwd; +} + +std::string GetImagesDir() { + std::string cwd = GetCWD(); + auto find = cwd.rfind("/build"); + if (find == std::string::npos) { + std::cerr << "Something went wrong: CWD don't contain build dir. " + << "Please run tests from build dir, path might be incorrect\n"; + + return cwd + "/test/images"; + } + + return cwd.substr(0, find) + "/test/images"; +} + +std::string GetFilePath(const std::string& filename) { + if (g_in_dir->empty()) { + *g_in_dir = GetImagesDir(); + } + return sandbox2::file::JoinPath(*g_in_dir, filename); +} diff --git a/oss-internship-2020/libtiff/test/helper.h b/oss-internship-2020/libtiff/test/helper.h new file mode 100644 index 0000000..fc8c5ef --- /dev/null +++ b/oss-internship-2020/libtiff/test/helper.h @@ -0,0 +1,29 @@ +// Copyright 2020 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 +// +// http://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 LIBTIFF_TEST_HELPER_H_ +#define LIBTIFF_TEST_HELPER_H_ + +#include + +#include "../sandboxed.h" // NOLINT(build/include) +#include "gtest/gtest.h" +#include "sandboxed_api/sandbox2/util/fileops.h" +#include "sandboxed_api/sandbox2/util/path.h" +#include "sandboxed_api/sandbox2/util/temp_file.h" +#include "sandboxed_api/util/status_matchers.h" + +std::string GetFilePath(const std::string& filename); + +#endif // LIBTIFF_TEST_HELPER_H_ diff --git a/oss-internship-2020/libtiff/test/images/quad-tile.jpg.tiff b/oss-internship-2020/libtiff/test/images/quad-tile.jpg.tiff new file mode 100644 index 0000000..99b0bc2 Binary files /dev/null and b/oss-internship-2020/libtiff/test/images/quad-tile.jpg.tiff differ diff --git a/oss-internship-2020/libtiff/test/long_tag.cc b/oss-internship-2020/libtiff/test/long_tag.cc new file mode 100644 index 0000000..08a7e68 --- /dev/null +++ b/oss-internship-2020/libtiff/test/long_tag.cc @@ -0,0 +1,143 @@ +// Copyright 2020 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 +// +// http://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 "check_tag.h" // NOLINT(build/include) +#include "tiffio.h" // NOLINT(build/include) + +using ::sapi::IsOk; +using ::testing::IsTrue; +using ::testing::Ne; +using ::testing::NotNull; + +// sapi functions: +// TIFFWriteScanline +// TIFFOpen +// TIFFClose +// TIFFGetField (from check_tag.c) +// TIFFSetField + +namespace { + +struct LongTag { + ttag_t tag; + int16_t count; + int32_t value; +}; + +constexpr std::array kLongTags = { + {TIFFTAG_SUBFILETYPE, 1, + FILETYPE_REDUCEDIMAGE | FILETYPE_PAGE | FILETYPE_MASK}}; +constexpr int kSamplesPerPixel = 3; +constexpr int kWidth = 1; +constexpr int kLength = 1; +constexpr int kBps = 8; +constexpr int kRowsPerStrip = 1; + +TEST(SandboxTest, LongTag) { + sapi::StatusOr status_or_path = + sandbox2::CreateNamedTempFileAndClose("long_test.tif"); + ASSERT_THAT(status_or_path, IsOk()) << "Could not create temp file"; + + std::string srcfile = sandbox2::file::JoinPath( + sandbox2::file_util::fileops::GetCWD(), status_or_path.value()); + + TiffSapiSandbox sandbox("", srcfile); + ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API"; + + std::array buffer = {0, 127, 255}; + sapi::v::Array buffer_(buffer.data(), SPP); + + sapi::StatusOr status_or_int; + sapi::StatusOr status_or_tif; + + TiffApi api(&sandbox); + sapi::v::ConstCStr srcfile_var(srcfile.c_str()); + sapi::v::ConstCStr w_var("w"); + + status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), w_var.PtrBefore()); + ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile; + + sapi::v::RemotePtr tif(status_or_tif.value()); + ASSERT_THAT(tif.GetValue(), NotNull()) + << "Can't create test TIFF file " << srcfile; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_IMAGEWIDTH, kWidth); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageWidth tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_IMAGELENGTH, kLength); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageLength tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_BITSPERSAMPLE, kBps); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set BitsPerSample tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_SAMPLESPERPIXEL, SPP); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set SamplesPerPixel tag"; + + status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_ROWSPERSTRIP, kRowsPerStrip); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set RowsPerStrip tag"; + + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set PlanarConfiguration tag"; + + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set PhotometricInterpretation tag"; + + for (auto& tag : kLongTags) { + status_or_int = api.TIFFSetFieldU1(&tif, tag.tag, tag.value); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldUShort1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set tag " << tag.tag; + } + + status_or_int = api.TIFFWriteScanline(&tif, buffer_.PtrBoth(), 0, 0); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFWriteScanline fatal error"; + ASSERT_THAT(status_or_int.value(), Ne(-1)) << "Can't write image data"; + + ASSERT_THAT(api.TIFFClose(&tif), IsOk()) << "TIFFClose fatal error"; + + sapi::v::ConstCStr r_var("r"); + status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore()); + ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile; + + sapi::v::RemotePtr tif2(status_or_tif.value()); + ASSERT_THAT(tif2.GetValue(), NotNull()) + << "Can't create test TIFF file " << srcfile; + + CheckLongField(api, tif2, TIFFTAG_IMAGEWIDTH, kWidth); + CheckLongField(api, tif2, TIFFTAG_IMAGELENGTH, kLength); + CheckLongField(api, tif2, TIFFTAG_ROWSPERSTRIP, kRowsPerStrip); + + for (auto& tag : kLongTags) { + CheckLongField(api, tif2, tag.tag, tag.value); + } + + ASSERT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error"; + unlink(srcfile.c_str()); +} + +} // namespace diff --git a/oss-internship-2020/libtiff/test/raw_decode.cc b/oss-internship-2020/libtiff/test/raw_decode.cc new file mode 100644 index 0000000..fbd84f7 --- /dev/null +++ b/oss-internship-2020/libtiff/test/raw_decode.cc @@ -0,0 +1,207 @@ +// Copyright 2020 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 +// +// http://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 + +#include "helper.h" // NOLINT(build/include) +#include "gtest/gtest.h" +#include "tiffio.h" // NOLINT(build/include) + +using ::sapi::IsOk; +using ::testing::Eq; +using ::testing::IsFalse; +using ::testing::IsTrue; +using ::testing::NotNull; + +// sapi functions: +// TIFFOpen +// TIFFClose +// TIFFGetField +// TIFFSetField +// TIFFTileSize +// TIFFReadRGBATile +// TIFFReadEncodedTile + +namespace { + +constexpr std::array kCluster0 = {0, 0, 2, 0, 138, 139}; +constexpr std::array kCluster64 = {0, 0, 9, 6, 134, 119}; +constexpr std::array kCluster128 = {44, 40, 63, 59, 230, 95}; + +int CheckCluster(int cluster, const sapi::v::Array &buffer, + const std::vector &expected_cluster) { + uint8_t *target = buffer.GetData() + cluster * 6; + + bool comp = !(std::memcmp(target, expected_cluster.data(), 6) == 0); + + EXPECT_THAT(comp, IsFalse()) + << "Cluster " << cluster << " did not match expected results.\n" + << "Expect: " << expected_cluster[0] << "\t" << expected_cluster[1] + << "\t" << expected_cluster[4] << "\t" << expected_cluster[5] << "\t" + << expected_cluster[2] << "\t" << expected_cluster[3] << "\n" + << "Got: " << target[0] << "\t" << target[1] << "\t" << target[4] << "\t" + << target[5] << "\t" << target[2] << "\t" << target[3]; + + return comp; +} + +int CheckRgbPixel(int pixel, int min_red, int max_red, int min_green, + int max_green, int min_blue, int max_blue, + const sapi::v::Array &buffer) { + uint8_t *rgb = buffer.GetData() + 3 * pixel; + + bool comp = + !(rgb[0] >= min_red && rgb[0] <= max_red && rgb[1] >= min_green && + rgb[1] <= max_green && rgb[2] >= min_blue && rgb[2] <= max_blue); + + EXPECT_THAT(comp, IsFalse()) + << "Pixel " << pixel << " did not match expected results.\n" + << "Got R=" << rgb[0] << " (expected " << min_red << ".." << max_red + << "), G=" << rgb[1] << " (expected " << min_green << ".." << max_green + << "), B=" << rgb[2] << " (expected " << min_blue << ".." << max_blue + << ")"; + return comp; +} + +int CheckRgbaPixel(int pixel, int min_red, int max_red, int min_green, + int max_green, int min_blue, int max_blue, int min_alpha, + int max_alpha, const sapi::v::Array &buffer) { + // RGBA images are upside down - adjust for normal ordering + int adjusted_pixel = pixel % 128 + (127 - (pixel / 128)) * 128; + unsigned rgba = buffer[adjusted_pixel]; + + bool comp = !(TIFFGetR(rgba) >= static_cast(min_red) && + TIFFGetR(rgba) <= static_cast(max_red) && + TIFFGetG(rgba) >= static_cast(min_green) && + TIFFGetG(rgba) <= static_cast(max_green) && + TIFFGetB(rgba) >= static_cast(min_blue) && + TIFFGetB(rgba) <= static_cast(max_blue) && + TIFFGetA(rgba) >= static_cast(min_alpha) && + TIFFGetA(rgba) <= static_cast(max_alpha)); + + EXPECT_THAT(comp, IsFalse()) + << "Pixel " << pixel << " did not match expected results.\n" + << "Got R=" << TIFFGetR(rgba) << " (expected " << min_red << ".." + << max_red << "), G=" << TIFFGetG(rgba) << " (expected " << min_green + << ".." << max_green << "), B=" << TIFFGetB(rgba) << " (expected " + << min_blue << ".." << max_blue << "), A=" << TIFFGetA(rgba) + << " (expected " << min_alpha << ".." << max_alpha << ")"; + return comp; +} + +TEST(SandboxTest, RawDecode) { + std::string srcfile = GetFilePath("quad-tile.jpg.tiff"); + + TiffSapiSandbox sandbox("", srcfile); + ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API"; + + tsize_t sz; + unsigned int pixel_status = 0; + sapi::v::UShort h, v; + sapi::StatusOr status_or_tif; + sapi::StatusOr status_or_int; + sapi::StatusOr status_or_long; + + TiffApi api(&sandbox); + sapi::v::ConstCStr srcfile_var(srcfile.c_str()); + sapi::v::ConstCStr r_var("r"); + + status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore()); + ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile; + + sapi::v::RemotePtr tif(status_or_tif.value()); + ASSERT_THAT(tif.GetValue(), NotNull()) + << "Could not open " << srcfile << ", TIFFOpen return NULL"; + + status_or_int = api.TIFFGetField2(&tif, TIFFTAG_YCBCRSUBSAMPLING, h.PtrBoth(), + v.PtrBoth()); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFGetField2 fatal error"; + EXPECT_THAT( + status_or_int.value() == 0 || h.GetValue() != 2 || v.GetValue() != 2, + IsFalse()) + << "Could not retrieve subsampling tag"; + + status_or_long = api.TIFFTileSize(&tif); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFTileSize fatal error"; + EXPECT_THAT(status_or_long.value(), Eq(24576)) + << "tiles are " << status_or_long.value() << " bytes"; + sz = status_or_long.value(); + + sapi::v::Array buffer_(sz); + status_or_long = api.TIFFReadEncodedTile(&tif, 9, buffer_.PtrBoth(), sz); + ASSERT_THAT(status_or_long, IsOk()) << "TIFFReadEncodedTile fatal error"; + EXPECT_THAT(status_or_long.value(), Eq(sz)) + << "Did not get expected result code from TIFFReadEncodedTile()(" + << static_cast(status_or_long.value()) << " instead of " << (int)sz + << ")"; + + ASSERT_FALSE(CheckCluster(0, buffer_, kCluster0) || + CheckCluster(64, buffer_, kCluster64) || + CheckCluster(128, buffer_, kCluster128)) + << "Clusters did not match expected results"; + + status_or_int = + api.TIFFSetFieldU1(&tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFSetFieldU1 not available"; + + status_or_long = api.TIFFTileSize(&tif); + ASSERT_THAT(status_or_long, IsOk()) << "TIFFTileSize fatal error"; + EXPECT_THAT(status_or_long.value(), Eq(128 * 128 * 3)) + << "tiles are " << status_or_long.value() << " bytes"; + sz = status_or_long.value(); + + sapi::v::Array buffer2_(sz); + status_or_long = api.TIFFReadEncodedTile(&tif, 9, buffer2_.PtrBoth(), sz); + ASSERT_THAT(status_or_long, IsOk()) << "TIFFReadEncodedTile fatal error"; + EXPECT_THAT(status_or_long.value(), Eq(sz)) + << "Did not get expected result code from TIFFReadEncodedTile()(" + << status_or_long.value() << " instead of " << sz; + + pixel_status |= CheckRgbPixel(0, 15, 18, 0, 0, 18, 41, buffer2_); + pixel_status |= CheckRgbPixel(64, 0, 0, 0, 0, 0, 2, buffer2_); + pixel_status |= CheckRgbPixel(512, 5, 6, 34, 36, 182, 196, buffer2_); + + ASSERT_THAT(api.TIFFClose(&tif), IsOk()) << "TIFFClose fatal error"; + + status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore()); + ASSERT_THAT(status_or_tif, IsOk()) << "TIFFOpen fatal error"; + + sapi::v::RemotePtr tif2(status_or_tif.value()); + ASSERT_THAT(tif2.GetValue(), NotNull()) + << "Could not open " << srcfile << ", TIFFOpen return NULL"; + + sapi::v::Array rgba_buffer_(128 * 128); + + status_or_int = + api.TIFFReadRGBATile(&tif2, 1 * 128, 2 * 128, rgba_buffer_.PtrBoth()); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFReadRGBATile fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "TIFFReadRGBATile() returned failure code"; + + pixel_status |= + CheckRgbaPixel(0, 15, 18, 0, 0, 18, 41, 255, 255, rgba_buffer_); + pixel_status |= CheckRgbaPixel(64, 0, 0, 0, 0, 0, 2, 255, 255, rgba_buffer_); + pixel_status |= + CheckRgbaPixel(512, 5, 6, 34, 36, 182, 196, 255, 255, rgba_buffer_); + + EXPECT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error"; + + EXPECT_THAT(pixel_status, IsFalse()) << "wrong encoding"; +} + +} // namespace diff --git a/oss-internship-2020/libtiff/test/short_tag.cc b/oss-internship-2020/libtiff/test/short_tag.cc new file mode 100644 index 0000000..7ddb9ed --- /dev/null +++ b/oss-internship-2020/libtiff/test/short_tag.cc @@ -0,0 +1,181 @@ +// Copyright 2020 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 +// +// http://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 + +#include "check_tag.h" // NOLINT(build/include) +#include "tiffio.h" // NOLINT(build/include) + +using ::sapi::IsOk; +using ::testing::Eq; +using ::testing::IsFalse; +using ::testing::IsTrue; +using ::testing::NotNull; + +// sapi functions: +// TIFFWriteScanline +// TIFFOpen +// TIFFClose +// TIFFGetField (from check_tag.c) +// TIFFSetField + +namespace { + +constexpr int kSamplePerPixel = 3; +constexpr int kWidth = 1; +constexpr int kLength = 1; +constexpr int kBps = 8; +constexpr int kPhotometric = PHOTOMETRIC_RGB; +constexpr int kRowsPerStrip = 1; +constexpr int kPlanarConfig = PLANARCONFIG_CONTIG; + +struct SingleTag { + const ttag_t tag; + const uint16_t value; +}; + +struct PairedTag { + const ttag_t tag; + const std::array values; +}; + +constexpr std::array kShortSingleTags = { + {TIFFTAG_COMPRESSION, COMPRESSION_NONE}, + {TIFFTAG_FILLORDER, FILLORDER_MSB2LSB}, + {TIFFTAG_ORIENTATION, ORIENTATION_BOTRIGHT}, + {TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH}, + {TIFFTAG_MINSAMPLEVALUE, 23}, + {TIFFTAG_MAXSAMPLEVALUE, 241}, + {TIFFTAG_INKSET, INKSET_MULTIINK}, + {TIFFTAG_NUMBEROFINKS, kSamplePerPixel}, + {TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT}}; + +constexpr std::array kShortPairedTags = { + {TIFFTAG_PAGENUMBER, {1, 1}}, + {TIFFTAG_HALFTONEHINTS, {0, 255}}, + {TIFFTAG_DOTRANGE, {8, 16}}, + {TIFFTAG_YCBCRSUBSAMPLING, {2, 1}}}; + +TEST(SandboxTest, ShortTag) { + sapi::StatusOr status_or_path = + sandbox2::CreateNamedTempFileAndClose("short_test.tif"); + ASSERT_THAT(status_or_path, IsOk()) << "Could not create temp file"; + + std::string srcfile = sandbox2::file::JoinPath( + sandbox2::file_util::fileops::GetCWD(), status_or_path.value()); + + TiffSapiSandbox sandbox("", srcfile); + ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API"; + + std::array buffer = {0, 127, 255}; + sapi::v::Array buffer_(buffer.data(), kSamplePerPixel); + + sapi::StatusOr status_or_int; + sapi::StatusOr status_or_tif; + + TiffApi api(&sandbox); + sapi::v::ConstCStr srcfile_var(srcfile.c_str()); + sapi::v::ConstCStr w_var("w"); + + status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), w_var.PtrBefore()); + ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile; + + sapi::v::RemotePtr tif(status_or_tif.value()); + ASSERT_THAT(tif.GetValue(), NotNull()) + << "Can't create test TIFF file " << srcfile; + + status_or_int = api.TIFFSetFieldUShort1(&tif, TIFFTAG_IMAGEWIDTH, kWidth); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldUShort1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImagekWidth tag"; + + status_or_int = api.TIFFSetFieldUShort1(&tif, TIFFTAG_IMAGELENGTH, kLength); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldUShort1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageLength tag"; + + status_or_int = api.TIFFSetFieldUShort1(&tif, TIFFTAG_BITSPERSAMPLE, kBps); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldUShort1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set BitsPerSample tag"; + + status_or_int = + api.TIFFSetFieldUShort1(&tif, TIFFTAG_SAMPLESPERPIXEL, kSamplePerPixel); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldUShort1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set SamplesPerPixel tag"; + + status_or_int = + api.TIFFSetFieldUShort1(&tif, TIFFTAG_ROWSPERSTRIP, kRowsPerStrip); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldUShort1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set RowsPerStrip tag"; + + status_or_int = + api.TIFFSetFieldUShort1(&tif, TIFFTAG_PLANARCONFIG, kPlanarConfig); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldUShort1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set PlanarConfiguration tag"; + + status_or_int = + api.TIFFSetFieldUShort1(&tif, TIFFTAG_PHOTOMETRIC, kPhotometric); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldUShort1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) + << "Can't set PhotometricInterpretation tag"; + + for (auto& tag : kShortSingleTags) { + status_or_int = api.TIFFSetFieldUShort1(&tif, tag.tag, tag.value); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldUShort1 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set tag " << tag.tag; + } + + for (auto& tag : kShortPairedTags) { + status_or_int = + api.TIFFSetFieldUShort2(&tif, tag.tag, tag.values[0], tag.values[1]); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldUShort2 fatal error"; + EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set tag " << tag.tag; + } + + status_or_int = api.TIFFWriteScanline(&tif, buffer_.PtrBoth(), 0, 0); + ASSERT_THAT(status_or_int, IsOk()) << "TIFFWriteScanline fatal error"; + ASSERT_THAT(status_or_int.value(), Ne(-1)) << "Can't write image data"; + + ASSERT_THAT(api.TIFFClose(&tif), IsOk()) << "TIFFClose fatal error"; + + sapi::v::ConstCStr r_var("r"); + status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore()); + ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile; + + sapi::v::RemotePtr tif2(status_or_tif.value()); + ASSERT_THAT(tif2.GetValue(), NotNull()) + << "Can't create test TIFF file " << srcfile; + + CheckLongField(api, tif2, TIFFTAG_IMAGEWIDTH, kWidth); + CheckLongField(api, tif2, TIFFTAG_IMAGELENGTH, kLength); + CheckShortField(api, tif2, TIFFTAG_BITSPERSAMPLE, kBps); + CheckShortField(api, tif2, TIFFTAG_PHOTOMETRIC, kPhotometric); + CheckShortField(api, tif2, TIFFTAG_SAMPLESPERPIXEL, kSamplePerPixel); + CheckLongField(api, tif2, TIFFTAG_ROWSPERSTRIP, kRowsPerStrip); + CheckShortField(api, tif2, TIFFTAG_PLANARCONFIG, kPlanarConfig); + + for (auto& tag : kShortSingleTags) { + CheckShortField(api, tif2, tag.tag, tag.value); + } + + for (auto& tag : kShortPairedTags) { + CheckShortPairedField(api, tif2, tag.tag, tag.values); + } + + ASSERT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error"; +} + +} // namespace diff --git a/oss-internship-2020/libtiff/wrapper/CMakeLists.txt b/oss-internship-2020/libtiff/wrapper/CMakeLists.txt new file mode 100644 index 0000000..c3892d7 --- /dev/null +++ b/oss-internship-2020/libtiff/wrapper/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright 2020 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 +# +# http://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_library(wrapped_tiff OBJECT + func.h + func.cc +) +set_target_properties(wrapped_tiff + PROPERTIES LINKER_LANGUAGE C +) + +add_subdirectory(libtiff) + +target_link_libraries(wrapped_tiff + sandbox2::temp_file + sapi::sapi + tiff +) diff --git a/oss-internship-2020/libtiff/wrapper/func.cc b/oss-internship-2020/libtiff/wrapper/func.cc new file mode 100644 index 0000000..5fcf6da --- /dev/null +++ b/oss-internship-2020/libtiff/wrapper/func.cc @@ -0,0 +1,163 @@ +// Copyright 2020 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 +// +// http://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 "func.h" // NOLINT(build/include) + +int TIFFGetField1(TIFF* tif, uint32_t tag, void* param) { + return TIFFGetField(tif, tag, param); +} + +int TIFFGetField2(TIFF* tif, uint32_t tag, void* param1, void* param2) { + return TIFFGetField(tif, tag, param1, param2); +} + +int TIFFGetField3(TIFF* tif, uint32_t tag, void* param1, void* param2, + void* param3) { + return TIFFGetField(tif, tag, param1, param2, param3); +} + +int TIFFSetFieldUChar1(TIFF* tif, uint32_t tag, uint8_t param) { + return TIFFSetField(tif, tag, param); +} + +int TIFFSetFieldUChar2(TIFF* tif, uint32_t tag, uint8_t param1, + uint8_t param2) { + return TIFFSetField(tif, tag, param1, param2); +} + +int TIFFSetFieldUChar3(TIFF* tif, uint32_t tag, uint8_t param1, uint8_t param2, + uint8_t param3) { + return TIFFSetField(tif, tag, param1, param2, param3); +} + +int TIFFSetFieldSChar1(TIFF* tif, uint32_t tag, int8_t param) { + return TIFFSetField(tif, tag, param); +} + +int TIFFSetFieldSChar2(TIFF* tif, uint32_t tag, int8_t param1, int8_t param2) { + return TIFFSetField(tif, tag, param1, param2); +} + +int TIFFSetFieldSChar3(TIFF* tif, uint32_t tag, int8_t param1, int8_t param2, + int8_t param3) { + return TIFFSetField(tif, tag, param1, param2, param3); +} + +int TIFFSetFieldU1(TIFF* tif, uint32_t tag, uint32_t param) { + return TIFFSetField(tif, tag, param); +} + +int TIFFSetFieldU2(TIFF* tif, uint32_t tag, uint32_t param1, uint32_t param2) { + return TIFFSetField(tif, tag, param1, param2); +} + +int TIFFSetFieldU3(TIFF* tif, uint32_t tag, uint32_t param1, uint32_t param2, + uint32_t param3) { + return TIFFSetField(tif, tag, param1, param2, param3); +} + +int TIFFSetFieldS1(TIFF* tif, uint32_t tag, int param) { + return TIFFSetField(tif, tag, param); +} + +int TIFFSetFieldS2(TIFF* tif, uint32_t tag, int param1, int param2) { + return TIFFSetField(tif, tag, param1, param2); +} + +int TIFFSetFieldS3(TIFF* tif, uint32_t tag, int param1, int param2, + int param3) { + return TIFFSetField(tif, tag, param1, param2, param3); +} + +int TIFFSetFieldUShort1(TIFF* tif, uint32_t tag, uint16_t param) { + return TIFFSetField(tif, tag, param); +} + +int TIFFSetFieldUShort2(TIFF* tif, uint32_t tag, uint16_t param1, + uint16_t param2) { + return TIFFSetField(tif, tag, param1, param2); +} + +int TIFFSetFieldUShort3(TIFF* tif, uint32_t tag, uint16_t param1, + uint16_t param2, uint16_t param3) { + return TIFFSetField(tif, tag, param1, param2, param3); +} + +int TIFFSetFieldSShort1(TIFF* tif, uint32_t tag, int16_t param) { + return TIFFSetField(tif, tag, param); +} + +int TIFFSetFieldSShort2(TIFF* tif, uint32_t tag, int16_t param1, + int16_t param2) { + return TIFFSetField(tif, tag, param1, param2); +} + +int TIFFSetFieldSShort3(TIFF* tif, uint32_t tag, int16_t param1, int16_t param2, + int16_t param3) { + return TIFFSetField(tif, tag, param1, param2, param3); +} + +int TIFFSetFieldULLong1(TIFF* tif, uint32_t tag, uint64_t param) { + return TIFFSetField(tif, tag, param); +} + +int TIFFSetFieldULLong2(TIFF* tif, uint32_t tag, uint64_t param1, + uint64_t param2) { + return TIFFSetField(tif, tag, param1, param2); +} + +int TIFFSetFieldULLong3(TIFF* tif, uint32_t tag, uint64_t param1, + uint64_t param2, uint64_t param3) { + return TIFFSetField(tif, tag, param1, param2, param3); +} + +int TIFFSetFieldSLLong1(TIFF* tif, uint32_t tag, int64_t param) { + return TIFFSetField(tif, tag, param); +} + +int TIFFSetFieldSLLong2(TIFF* tif, uint32_t tag, int64_t param1, + int64_t param2) { + return TIFFSetField(tif, tag, param1, param2); +} + +int TIFFSetFieldSLLong3(TIFF* tif, uint32_t tag, int64_t param1, int64_t param2, + int64_t param3) { + return TIFFSetField(tif, tag, param1, param2, param3); +} + +int TIFFSetFieldFloat1(TIFF* tif, uint32_t tag, float param) { + return TIFFSetField(tif, tag, param); +} + +int TIFFSetFieldFloat2(TIFF* tif, uint32_t tag, float param1, float param2) { + return TIFFSetField(tif, tag, param1, param2); +} + +int TIFFSetFieldFloat3(TIFF* tif, uint32_t tag, float param1, float param2, + float param3) { + return TIFFSetField(tif, tag, param1, param2, param3); +} + +int TIFFSetFieldDouble1(TIFF* tif, uint32_t tag, double param) { + return TIFFSetField(tif, tag, param); +} + +int TIFFSetFieldDouble2(TIFF* tif, uint32_t tag, double param1, double param2) { + return TIFFSetField(tif, tag, param1, param2); +} + +int TIFFSetFieldDouble3(TIFF* tif, uint32_t tag, double param1, double param2, + double param3) { + return TIFFSetField(tif, tag, param1, param2, param3); +} diff --git a/oss-internship-2020/libtiff/wrapper/func.h b/oss-internship-2020/libtiff/wrapper/func.h new file mode 100644 index 0000000..733d986 --- /dev/null +++ b/oss-internship-2020/libtiff/wrapper/func.h @@ -0,0 +1,88 @@ +// Copyright 2020 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 +// +// http://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 LIBTIFF_WRAPPER_FUNC_H_ +#define LIBTIFF_WRAPPER_FUNC_H_ + +#include + +#include "tiffio.h" // NOLINT(build/include) + +// s - signed +// u - uint32_t +// wrapper for variadic functions TIFFGetField and TIFFSetField + +extern "C" { + +int TIFFGetField1(TIFF* tif, uint32_t tag, void* param); +int TIFFGetField2(TIFF* tif, uint32_t tag, void* param1, void* param2); +int TIFFGetField3(TIFF* tif, uint32_t tag, void* param1, void* param2, + void* param3); + +int TIFFSetFieldUChar1(TIFF* tif, uint32_t tag, uint8_t param); +int TIFFSetFieldUChar2(TIFF* tif, uint32_t tag, uint8_t param1, uint8_t param2); +int TIFFSetFieldUChar3(TIFF* tif, uint32_t tag, uint8_t param1, uint8_t param2, + uint8_t param3); + +int TIFFSetFieldSChar1(TIFF* tif, uint32_t tag, int8_t param); +int TIFFSetFieldSChar2(TIFF* tif, uint32_t tag, int8_t param1, int8_t param2); +int TIFFSetFieldSChar3(TIFF* tif, uint32_t tag, int8_t param1, int8_t param2, + int8_t param3); + +int TIFFSetFieldU1(TIFF* tif, uint32_t tag, uint32_t param); +int TIFFSetFieldU2(TIFF* tif, uint32_t tag, uint32_t param1, uint32_t param2); +int TIFFSetFieldU3(TIFF* tif, uint32_t tag, uint32_t param1, uint32_t param2, + uint32_t param3); + +int TIFFSetFieldS1(TIFF* tif, uint32_t tag, int param); +int TIFFSetFieldS2(TIFF* tif, uint32_t tag, int param1, int param2); +int TIFFSetFieldS3(TIFF* tif, uint32_t tag, int param1, int param2, int param3); + +int TIFFSetFieldUShort1(TIFF* tif, uint32_t tag, uint16_t param); +int TIFFSetFieldUShort2(TIFF* tif, uint32_t tag, uint16_t param1, + uint16_t param2); +int TIFFSetFieldUShort3(TIFF* tif, uint32_t tag, uint16_t param1, + uint16_t param2, uint16_t param3); + +int TIFFSetFieldSShort1(TIFF* tif, uint32_t tag, int16_t param); +int TIFFSetFieldSShort2(TIFF* tif, uint32_t tag, int16_t param1, + int16_t param2); +int TIFFSetFieldSShort3(TIFF* tif, uint32_t tag, int16_t param1, int16_t param2, + int16_t param3); + +int TIFFSetFieldULLong1(TIFF* tif, uint32_t tag, uint64_t param); +int TIFFSetFieldULLong2(TIFF* tif, uint32_t tag, uint64_t param1, + uint64_t param2); +int TIFFSetFieldULLong3(TIFF* tif, uint32_t tag, uint64_t param1, + uint64_t param2, uint64_t param3); + +int TIFFSetFieldSLLong1(TIFF* tif, uint32_t tag, int64_t param); +int TIFFSetFieldSLLong2(TIFF* tif, uint32_t tag, int64_t param1, + int64_t param2); +int TIFFSetFieldSLLong3(TIFF* tif, uint32_t tag, int64_t param1, int64_t param2, + int64_t param3); + +int TIFFSetFieldFloat1(TIFF* tif, uint32_t tag, float param); +int TIFFSetFieldFloat2(TIFF* tif, uint32_t tag, float param1, float param2); +int TIFFSetFieldFloat3(TIFF* tif, uint32_t tag, float param1, float param2, + float param3); + +int TIFFSetFieldDouble1(TIFF* tif, uint32_t tag, double param); +int TIFFSetFieldDouble2(TIFF* tif, uint32_t tag, double param1, double param2); +int TIFFSetFieldDouble3(TIFF* tif, uint32_t tag, double param1, double param2, + double param3); + +} // extern "C" + +#endif // LIBTIFF_WRAPPER_FUNC_H_ diff --git a/oss-internship-2020/libtiff/wrapper/libtiff b/oss-internship-2020/libtiff/wrapper/libtiff new file mode 160000 index 0000000..c8f0a16 --- /dev/null +++ b/oss-internship-2020/libtiff/wrapper/libtiff @@ -0,0 +1 @@ +Subproject commit c8f0a16f4ad10cd5d595bd5614104e2ecf52ee92