mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
init libpng
This commit is contained in:
parent
ea379ef4d6
commit
bcecc9e74a
112
oss-internship-2020/libpng/CMakeLists.txt
Normal file
112
oss-internship-2020/libpng/CMakeLists.txt
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
# 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.12)
|
||||||
|
|
||||||
|
project(sandboxed_libpng 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 /path/to/sapi_root
|
||||||
|
# Then configure:
|
||||||
|
# mkdir -p build && cd build
|
||||||
|
# cmake .. -G Ninja -DSAPI_ROOT=/path/to/sapi_root
|
||||||
|
|
||||||
|
option(LIBPNG_SAPI_ENABLE_EXAMPLES "" OFF)
|
||||||
|
option(LIBPNG_SAPI_ENABLE_TESTS "" OFF)
|
||||||
|
|
||||||
|
set(SAPI_ENABLE_EXAMPLES ${LIBPNG_SAPI_ENABLE_EXAMPLES} CACHE BOOL "" FORCE)
|
||||||
|
set(SAPI_ENABLE_TESTS ${LIBPNG_SAPI_ENABLE_TESTS} CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
set (CMAKE_FIND_LIBRARY_SUFFIXES .a $ {CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||||
|
find_package(PNG REQUIRED)
|
||||||
|
list(GET PNG_INCLUDE_DIRS 0 PNG_INCLUDE_DIR)
|
||||||
|
|
||||||
|
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(libpng_sapi
|
||||||
|
# List of functions that we want to include in the
|
||||||
|
# generated sandboxed API class
|
||||||
|
|
||||||
|
FUNCTIONS png_image_free
|
||||||
|
png_image_finish_read
|
||||||
|
png_image_write_to_file
|
||||||
|
png_image_begin_read_from_file
|
||||||
|
|
||||||
|
png_get_rowbytes
|
||||||
|
png_get_bit_depth
|
||||||
|
png_get_color_type
|
||||||
|
png_get_image_width
|
||||||
|
png_get_image_height
|
||||||
|
|
||||||
|
png_set_IHDR
|
||||||
|
png_set_sig_bytes
|
||||||
|
png_set_interlace_handling
|
||||||
|
|
||||||
|
png_read_info
|
||||||
|
png_read_image_wrapper
|
||||||
|
png_read_update_info
|
||||||
|
|
||||||
|
png_write_end
|
||||||
|
png_write_info
|
||||||
|
png_write_image_wrapper
|
||||||
|
|
||||||
|
png_create_info_struct
|
||||||
|
png_create_read_struct_wrapper
|
||||||
|
png_create_write_struct_wrapper
|
||||||
|
|
||||||
|
png_init_io_wrapper
|
||||||
|
|
||||||
|
png_sig_cmp
|
||||||
|
|
||||||
|
png_fread
|
||||||
|
png_fdopen
|
||||||
|
png_rewind
|
||||||
|
png_fclose
|
||||||
|
|
||||||
|
png_setjmp
|
||||||
|
|
||||||
|
INPUTS "${PNG_INCLUDE_DIR}/png.h"
|
||||||
|
wrapper/func.h
|
||||||
|
# Header files or .cc files that should be parsed
|
||||||
|
LIBRARY wrapper
|
||||||
|
# Library dependency from the add_library() above
|
||||||
|
LIBRARY_NAME LibPNG # 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(libpng_sapi INTERFACE
|
||||||
|
"${PROJECT_BINARY_DIR}" # To find the generated SAPI header
|
||||||
|
)
|
||||||
|
|
||||||
|
if (LIBPNG_SAPI_ENABLE_EXAMPLES)
|
||||||
|
add_subdirectory(examples)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (LIBPNG_SAPI_ENABLE_TESTS)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif()
|
||||||
|
|
0
oss-internship-2020/libpng/README.md
Normal file
0
oss-internship-2020/libpng/README.md
Normal file
51
oss-internship-2020/libpng/examples/CMakeLists.txt
Normal file
51
oss-internship-2020/libpng/examples/CMakeLists.txt
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# 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(pngtopng
|
||||||
|
example1.cc
|
||||||
|
../tests/libpng.h
|
||||||
|
../sandboxed.h
|
||||||
|
)
|
||||||
|
|
||||||
|
find_package(PNG REQUIRED)
|
||||||
|
|
||||||
|
target_link_libraries(pngtopng PRIVATE
|
||||||
|
sapi::sapi
|
||||||
|
sandbox2::temp_file
|
||||||
|
libpng_sapi
|
||||||
|
"${PNG_LIBRARY}"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(pngtopng INTERFACE
|
||||||
|
"${PNG_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(rgbtobgr
|
||||||
|
example2.cc
|
||||||
|
../tests/libpng.h
|
||||||
|
../sandboxed.h
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(rgbtobgr PRIVATE
|
||||||
|
sapi::sapi
|
||||||
|
sandbox2::temp_file
|
||||||
|
libpng_sapi
|
||||||
|
"${PNG_LIBRARY}"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(rgbtobgr INTERFACE
|
||||||
|
"${PNG_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
|
90
oss-internship-2020/libpng/examples/example1.cc
Normal file
90
oss-internship-2020/libpng/examples/example1.cc
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
// 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 <string>
|
||||||
|
|
||||||
|
#include "../sandboxed.h" // NOLINT(build/include)
|
||||||
|
#include "../tests/libpng.h" // NOLINT(build/include)
|
||||||
|
#include "sandboxed_api/vars.h"
|
||||||
|
|
||||||
|
absl::Status LibPNGMain(const std::string& infile, const std::string& outfile) {
|
||||||
|
LibPNGSapiSandbox sandbox;
|
||||||
|
sandbox.AddFile(infile);
|
||||||
|
sandbox.AddFile(outfile);
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(sandbox.Init());
|
||||||
|
LibPNGApi api(&sandbox);
|
||||||
|
|
||||||
|
sapi::v::Struct<png_image> image;
|
||||||
|
sapi::v::ConstCStr infile_var(infile.c_str());
|
||||||
|
sapi::v::ConstCStr outfile_var(outfile.c_str());
|
||||||
|
|
||||||
|
image.mutable_data()->version = PNG_IMAGE_VERSION;
|
||||||
|
|
||||||
|
SAPI_ASSIGN_OR_RETURN(
|
||||||
|
int result, api.png_image_begin_read_from_file(image.PtrBoth(),
|
||||||
|
infile_var.PtrBefore()));
|
||||||
|
if (!result) {
|
||||||
|
return absl::InternalError(
|
||||||
|
absl::StrCat("begin read error: ", image.mutable_data()->message));
|
||||||
|
}
|
||||||
|
|
||||||
|
image.mutable_data()->format = PNG_FORMAT_RGBA;
|
||||||
|
|
||||||
|
auto buffer = malloc(PNG_IMAGE_SIZE(*image.mutable_data()));
|
||||||
|
if (!buffer) {
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_image_free(image.PtrBoth()));
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
sapi::v::Array<uint8_t> buffer_(PNG_IMAGE_SIZE(*image.mutable_data()));
|
||||||
|
|
||||||
|
SAPI_ASSIGN_OR_RETURN(
|
||||||
|
result, api.png_image_finish_read(
|
||||||
|
image.PtrBoth(), sapi::v::NullPtr().PtrBoth(),
|
||||||
|
buffer_.PtrBoth(), 0, sapi::v::NullPtr().PtrBoth()));
|
||||||
|
if (!result) {
|
||||||
|
return absl::InternalError(
|
||||||
|
absl::StrCat("finish read error: ", image.mutable_data()->message));
|
||||||
|
}
|
||||||
|
|
||||||
|
SAPI_ASSIGN_OR_RETURN(
|
||||||
|
result, api.png_image_write_to_file(
|
||||||
|
image.PtrBoth(), outfile_var.PtrBefore(), 0,
|
||||||
|
buffer_.PtrBoth(), 0, sapi::v::NullPtr().PtrBoth()));
|
||||||
|
if (!result) {
|
||||||
|
return absl::InternalError(
|
||||||
|
absl::StrCat("write error: ", image.mutable_data()->message));
|
||||||
|
}
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char** argv) {
|
||||||
|
if (argc != 3) {
|
||||||
|
LOG(ERROR) << "usage: example input-file output-file";
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto status = LibPNGMain(argv[1], argv[2]);
|
||||||
|
if (!status.ok()) {
|
||||||
|
LOG(ERROR) << "LibPNGMain failed with error:\n"
|
||||||
|
<< status.ToString() << '\n';
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
239
oss-internship-2020/libpng/examples/example2.cc
Normal file
239
oss-internship-2020/libpng/examples/example2.cc
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
// 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 <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "../sandboxed.h" // NOLINT(build/include)
|
||||||
|
#include "../tests/libpng.h" // NOLINT(build/include)
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
Data() {}
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
uint8_t color_type;
|
||||||
|
uint8_t bit_depth;
|
||||||
|
int number_of_passes;
|
||||||
|
size_t rowbytes;
|
||||||
|
std::unique_ptr<sapi::v::Array<uint8_t>> row_pointers;
|
||||||
|
};
|
||||||
|
|
||||||
|
absl::Status ReadPng(LibPNGApi& api, LibPNGSapiSandbox& sandbox,
|
||||||
|
absl::string_view infile, Data& d) {
|
||||||
|
sapi::v::Fd fd(open(infile.data(), O_RDONLY));
|
||||||
|
|
||||||
|
if (fd.GetValue() < 0) {
|
||||||
|
return absl::InternalError("Error opening input file");
|
||||||
|
}
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(sandbox.TransferToSandboxee(&fd));
|
||||||
|
if (fd.GetRemoteFd() < 0) {
|
||||||
|
return absl::InternalError("Error receiving remote FD");
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<void*> status_or_file;
|
||||||
|
sapi::v::ConstCStr rb_var("rb");
|
||||||
|
SAPI_ASSIGN_OR_RETURN(status_or_file,
|
||||||
|
api.png_fdopen(fd.GetRemoteFd(), rb_var.PtrBefore()));
|
||||||
|
|
||||||
|
sapi::v::RemotePtr file(status_or_file.value());
|
||||||
|
if (!file.GetValue()) {
|
||||||
|
return absl::InternalError(absl::StrCat("Could not open ", infile));
|
||||||
|
}
|
||||||
|
|
||||||
|
sapi::v::Array<char> header(8);
|
||||||
|
SAPI_RETURN_IF_ERROR(
|
||||||
|
api.png_fread(header.PtrBoth(), 1, header.GetSize(), &file));
|
||||||
|
|
||||||
|
SAPI_ASSIGN_OR_RETURN(int return_value,
|
||||||
|
api.png_sig_cmp(header.PtrBoth(), 0, header.GetSize()));
|
||||||
|
if (return_value != 0) {
|
||||||
|
return absl::InternalError(absl::StrCat(infile, " is not a PNG file"));
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<png_structp> status_or_png_structp;
|
||||||
|
sapi::v::ConstCStr ver_string_var(PNG_LIBPNG_VER_STRING);
|
||||||
|
SAPI_ASSIGN_OR_RETURN(
|
||||||
|
status_or_png_structp,
|
||||||
|
api.png_create_read_struct_wrapper(ver_string_var.PtrBefore(),
|
||||||
|
sapi::v::NullPtr().PtrBoth()));
|
||||||
|
|
||||||
|
sapi::v::RemotePtr struct_ptr(status_or_png_structp.value());
|
||||||
|
if (!struct_ptr.GetValue()) {
|
||||||
|
return absl::InternalError("png_create_read_struct_wrapper failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<png_infop> status_or_png_infop;
|
||||||
|
SAPI_ASSIGN_OR_RETURN(status_or_png_infop,
|
||||||
|
api.png_create_info_struct(&struct_ptr));
|
||||||
|
|
||||||
|
sapi::v::RemotePtr info_ptr(status_or_png_infop.value());
|
||||||
|
if (!info_ptr.GetValue()) {
|
||||||
|
return absl::InternalError("png_create_info_struct failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_setjmp(&struct_ptr));
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_init_io_wrapper(&struct_ptr, &file));
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_set_sig_bytes(&struct_ptr, header.GetSize()));
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_read_info(&struct_ptr, &info_ptr));
|
||||||
|
|
||||||
|
SAPI_ASSIGN_OR_RETURN(d.width,
|
||||||
|
api.png_get_image_width(&struct_ptr, &info_ptr));
|
||||||
|
|
||||||
|
SAPI_ASSIGN_OR_RETURN(d.height,
|
||||||
|
api.png_get_image_height(&struct_ptr, &info_ptr));
|
||||||
|
|
||||||
|
SAPI_ASSIGN_OR_RETURN(d.color_type,
|
||||||
|
api.png_get_color_type(&struct_ptr, &info_ptr));
|
||||||
|
|
||||||
|
SAPI_ASSIGN_OR_RETURN(d.bit_depth,
|
||||||
|
api.png_get_bit_depth(&struct_ptr, &info_ptr));
|
||||||
|
|
||||||
|
SAPI_ASSIGN_OR_RETURN(d.number_of_passes,
|
||||||
|
api.png_set_interlace_handling(&struct_ptr));
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_read_update_info(&struct_ptr, &info_ptr));
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_setjmp(&struct_ptr));
|
||||||
|
|
||||||
|
SAPI_ASSIGN_OR_RETURN(d.rowbytes,
|
||||||
|
api.png_get_rowbytes(&struct_ptr, &info_ptr));
|
||||||
|
d.row_pointers =
|
||||||
|
std::make_unique<sapi::v::Array<uint8_t>>(d.height * d.rowbytes);
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_read_image_wrapper(
|
||||||
|
&struct_ptr, d.row_pointers->PtrAfter(), d.height, d.rowbytes));
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_fclose(&file));
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status WritePng(LibPNGApi& api, LibPNGSapiSandbox& sandbox,
|
||||||
|
absl::string_view outfile, Data& d) {
|
||||||
|
sapi::v::Fd fd(open(outfile.data(), O_WRONLY));
|
||||||
|
if (fd.GetValue() < 0) {
|
||||||
|
return absl::InternalError("Error opening output file");
|
||||||
|
}
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(sandbox.TransferToSandboxee(&fd));
|
||||||
|
if (fd.GetRemoteFd() < 0) {
|
||||||
|
return absl::InternalError("Error receiving remote FD");
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<void*> status_or_file;
|
||||||
|
sapi::v::ConstCStr wb_var("wb");
|
||||||
|
SAPI_ASSIGN_OR_RETURN(status_or_file,
|
||||||
|
api.png_fdopen(fd.GetRemoteFd(), wb_var.PtrBefore()));
|
||||||
|
|
||||||
|
sapi::v::RemotePtr file(status_or_file.value());
|
||||||
|
if (!file.GetValue()) {
|
||||||
|
return absl::InternalError(absl::StrCat("Could not open ", outfile));
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<png_structp> status_or_png_structp;
|
||||||
|
sapi::v::ConstCStr ver_string_var(PNG_LIBPNG_VER_STRING);
|
||||||
|
SAPI_ASSIGN_OR_RETURN(
|
||||||
|
status_or_png_structp,
|
||||||
|
api.png_create_write_struct_wrapper(ver_string_var.PtrBefore(),
|
||||||
|
sapi::v::NullPtr().PtrBoth()));
|
||||||
|
|
||||||
|
sapi::v::RemotePtr struct_ptr(status_or_png_structp.value());
|
||||||
|
if (!struct_ptr.GetValue()) {
|
||||||
|
return absl::InternalError("png_create_write_struct_wrapper failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<png_infop> status_or_png_infop;
|
||||||
|
SAPI_ASSIGN_OR_RETURN(status_or_png_infop,
|
||||||
|
api.png_create_info_struct(&struct_ptr));
|
||||||
|
|
||||||
|
sapi::v::RemotePtr info_ptr(status_or_png_infop.value());
|
||||||
|
if (!info_ptr.GetValue()) {
|
||||||
|
return absl::InternalError("png_create_info_struct failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_setjmp(&struct_ptr));
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_init_io_wrapper(&struct_ptr, &file));
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_setjmp(&struct_ptr));
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_set_IHDR(
|
||||||
|
&struct_ptr, &info_ptr, d.width, d.height, d.bit_depth, d.color_type,
|
||||||
|
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE));
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_write_info(&struct_ptr, &info_ptr));
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_setjmp(&struct_ptr));
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_write_image_wrapper(
|
||||||
|
&struct_ptr, d.row_pointers->PtrBefore(), d.height, d.rowbytes));
|
||||||
|
|
||||||
|
auto null = sapi::v::NullPtr();
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_setjmp(&struct_ptr));
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_write_end(&struct_ptr, &null));
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(api.png_fclose(&file));
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status LibPNGMain(const std::string& infile, const std::string& outfile) {
|
||||||
|
LibPNGSapiSandbox sandbox;
|
||||||
|
sandbox.AddFile(infile);
|
||||||
|
sandbox.AddFile(outfile);
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(sandbox.Init());
|
||||||
|
LibPNGApi api(&sandbox);
|
||||||
|
|
||||||
|
Data d;
|
||||||
|
SAPI_RETURN_IF_ERROR(ReadPng(api, sandbox, infile, d));
|
||||||
|
|
||||||
|
if (d.color_type != PNG_COLOR_TYPE_RGBA &&
|
||||||
|
d.color_type != PNG_COLOR_TYPE_RGB) {
|
||||||
|
return absl::InternalError(absl::StrCat(
|
||||||
|
infile, " has unexpected color type. Expected RGB or RGBA"));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t channel_count = 3;
|
||||||
|
if (d.color_type == PNG_COLOR_TYPE_RGBA) {
|
||||||
|
channel_count = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RGB to BGR
|
||||||
|
for (size_t i = 0; i != d.height; ++i) {
|
||||||
|
for (size_t j = 0; j != d.width; ++j) {
|
||||||
|
uint8_t r = (*d.row_pointers)[i * d.rowbytes + j * channel_count];
|
||||||
|
uint8_t g = (*d.row_pointers)[i * d.rowbytes + j * channel_count + 1];
|
||||||
|
uint8_t b = (*d.row_pointers)[i * d.rowbytes + j * channel_count + 2];
|
||||||
|
(*d.row_pointers)[i * d.rowbytes + j * channel_count] = b;
|
||||||
|
(*d.row_pointers)[i * d.rowbytes + j * channel_count + 2] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SAPI_RETURN_IF_ERROR(WritePng(api, sandbox, outfile, d));
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char** argv) {
|
||||||
|
if (argc != 3) {
|
||||||
|
LOG(ERROR) << "Usage: example5 infile outfile";
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto status = LibPNGMain(argv[1], argv[2]);
|
||||||
|
if (!status.ok()) {
|
||||||
|
LOG(ERROR) << "LibPNGMain failed with error:\n"
|
||||||
|
<< status.ToString() << '\n';
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
BIN
oss-internship-2020/libpng/images/pngtest.png
Normal file
BIN
oss-internship-2020/libpng/images/pngtest.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
BIN
oss-internship-2020/libpng/images/pngtopng_pngtest.png
Normal file
BIN
oss-internship-2020/libpng/images/pngtopng_pngtest.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
BIN
oss-internship-2020/libpng/images/red_ball.png
Normal file
BIN
oss-internship-2020/libpng/images/red_ball.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
BIN
oss-internship-2020/libpng/images/rgbtobgr_red_ball.png
Normal file
BIN
oss-internship-2020/libpng/images/rgbtobgr_red_ball.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
BIN
oss-internship-2020/libpng/images/test_output.png
Normal file
BIN
oss-internship-2020/libpng/images/test_output.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
64
oss-internship-2020/libpng/sandboxed.h
Normal file
64
oss-internship-2020/libpng/sandboxed.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// 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 <linux/futex.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "libpng_sapi.sapi.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class LibPNGSapiSandbox : public LibPNGSandbox {
|
||||||
|
public:
|
||||||
|
void AddFile(const std::string& file) { files_.push_back(file); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||||
|
sandbox2::PolicyBuilder*) override {
|
||||||
|
auto builder = std::make_unique<sandbox2::PolicyBuilder>();
|
||||||
|
(*builder)
|
||||||
|
.AllowRead()
|
||||||
|
.AllowStaticStartup()
|
||||||
|
.AllowWrite()
|
||||||
|
.AllowOpen()
|
||||||
|
.AllowExit()
|
||||||
|
.AllowStat()
|
||||||
|
.AllowMmap()
|
||||||
|
.AllowSystemMalloc()
|
||||||
|
.AllowSyscalls({
|
||||||
|
__NR_futex,
|
||||||
|
__NR_close,
|
||||||
|
__NR_lseek,
|
||||||
|
__NR_gettid,
|
||||||
|
__NR_sysinfo,
|
||||||
|
__NR_munmap,
|
||||||
|
__NR_recvmsg,
|
||||||
|
__NR_fcntl,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const auto& file : files_) {
|
||||||
|
builder->AddFile(file, /*is_ro=*/false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.get()->BuildOrDie();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> files_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
36
oss-internship-2020/libpng/tests/CMakeLists.txt
Normal file
36
oss-internship-2020/libpng/tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# 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)
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
add_executable(tests
|
||||||
|
basic_test.cc
|
||||||
|
extended_test.cc
|
||||||
|
helper.h
|
||||||
|
helper.cc
|
||||||
|
libpng.h
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(tests PRIVATE
|
||||||
|
gmock
|
||||||
|
gtest
|
||||||
|
gtest_main
|
||||||
|
sandbox2::temp_file
|
||||||
|
sapi::sapi
|
||||||
|
libpng_sapi
|
||||||
|
)
|
||||||
|
|
||||||
|
gtest_discover_tests(tests)
|
||||||
|
|
91
oss-internship-2020/libpng/tests/basic_test.cc
Normal file
91
oss-internship-2020/libpng/tests/basic_test.cc
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
// 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 "../sandboxed.h" // NOLINT(build/include)
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "helper.h" // NOLINT(build/include)
|
||||||
|
#include "libpng.h" // NOLINT(build/include)
|
||||||
|
#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"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using ::sapi::IsOk;
|
||||||
|
using ::testing::Eq;
|
||||||
|
using ::testing::IsTrue;
|
||||||
|
|
||||||
|
TEST(SandboxTest, ReadWrite) {
|
||||||
|
std::string infile = GetTestFilePath("pngtest.png");
|
||||||
|
|
||||||
|
absl::StatusOr<std::string> status_or_path =
|
||||||
|
sandbox2::CreateNamedTempFileAndClose("output.png");
|
||||||
|
ASSERT_THAT(status_or_path, IsOk()) << "Could not create temp output file";
|
||||||
|
|
||||||
|
std::string outfile = sandbox2::file::JoinPath(
|
||||||
|
sandbox2::file_util::fileops::GetCWD(), status_or_path.value());
|
||||||
|
|
||||||
|
LibPNGSapiSandbox sandbox;
|
||||||
|
sandbox.AddFile(infile);
|
||||||
|
sandbox.AddFile(outfile);
|
||||||
|
|
||||||
|
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||||
|
|
||||||
|
LibPNGApi api(&sandbox);
|
||||||
|
|
||||||
|
sapi::v::Struct<png_image> image;
|
||||||
|
sapi::v::ConstCStr infile_var(infile.c_str());
|
||||||
|
sapi::v::ConstCStr outfile_var(outfile.c_str());
|
||||||
|
|
||||||
|
image.mutable_data()->version = PNG_IMAGE_VERSION;
|
||||||
|
|
||||||
|
absl::StatusOr<int> status_or_int = api.png_image_begin_read_from_file(
|
||||||
|
image.PtrBoth(), infile_var.PtrBefore());
|
||||||
|
ASSERT_THAT(status_or_int, IsOk())
|
||||||
|
<< "png_image_begin_read_from_file fatal error";
|
||||||
|
ASSERT_THAT(status_or_int.value(), IsTrue())
|
||||||
|
<< "png_image_begin_read_from_file failed: "
|
||||||
|
<< image.mutable_data()->message;
|
||||||
|
|
||||||
|
image.mutable_data()->format = PNG_FORMAT_RGBA;
|
||||||
|
ASSERT_THAT(image.mutable_data()->version, Eq(PNG_IMAGE_VERSION))
|
||||||
|
<< "image version changed";
|
||||||
|
|
||||||
|
sapi::v::Array<uint8_t> buffer_(PNG_IMAGE_SIZE(*image.mutable_data()));
|
||||||
|
status_or_int = api.png_image_finish_read(
|
||||||
|
image.PtrBoth(), sapi::v::NullPtr().PtrBoth(), buffer_.PtrBoth(), 0,
|
||||||
|
sapi::v::NullPtr().PtrBoth());
|
||||||
|
ASSERT_THAT(status_or_int, IsOk()) << "png_image_finish_read fatal error";
|
||||||
|
ASSERT_THAT(status_or_int.value(), IsTrue())
|
||||||
|
<< "png_image_finish_read failed: " << image.mutable_data()->message;
|
||||||
|
ASSERT_THAT(image.mutable_data()->version, Eq(PNG_IMAGE_VERSION))
|
||||||
|
<< "image version changed";
|
||||||
|
ASSERT_THAT(image.mutable_data()->format, Eq(PNG_FORMAT_RGBA))
|
||||||
|
<< "image format changed";
|
||||||
|
|
||||||
|
status_or_int = api.png_image_write_to_file(
|
||||||
|
image.PtrBoth(), outfile_var.PtrBefore(), 0, buffer_.PtrBoth(), 0,
|
||||||
|
sapi::v::NullPtr().PtrBoth());
|
||||||
|
ASSERT_THAT(status_or_int, IsOk()) << "png_image_write_to_file fatal error";
|
||||||
|
ASSERT_THAT(status_or_int.value(), IsTrue())
|
||||||
|
<< "png_image_finish_read failed: " << image.mutable_data()->message;
|
||||||
|
ASSERT_THAT(image.mutable_data()->version, Eq(PNG_IMAGE_VERSION))
|
||||||
|
<< "image version changed";
|
||||||
|
ASSERT_THAT(image.mutable_data()->format, Eq(PNG_FORMAT_RGBA))
|
||||||
|
<< "image format changed";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
248
oss-internship-2020/libpng/tests/extended_test.cc
Normal file
248
oss-internship-2020/libpng/tests/extended_test.cc
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
// 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 <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "../sandboxed.h" // NOLINT(build/include)
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "helper.h" // NOLINT(build/include)
|
||||||
|
#include "libpng.h" // NOLINT(build/include)
|
||||||
|
#include "sandboxed_api/util/status_matchers.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using ::sapi::IsOk;
|
||||||
|
using ::testing::ContainerEq;
|
||||||
|
using ::testing::Eq;
|
||||||
|
using ::testing::Ge;
|
||||||
|
using ::testing::Gt;
|
||||||
|
using ::testing::IsTrue;
|
||||||
|
using ::testing::NotNull;
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
Data() {}
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
uint8_t color_type;
|
||||||
|
uint8_t bit_depth;
|
||||||
|
int number_of_passes;
|
||||||
|
size_t rowbytes;
|
||||||
|
std::unique_ptr<sapi::v::Array<uint8_t>> row_pointers;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ReadPng(LibPNGApi& api, LibPNGSapiSandbox& sandbox,
|
||||||
|
absl::string_view infile, Data& data) {
|
||||||
|
sapi::v::Fd fd(open(infile.data(), O_RDONLY));
|
||||||
|
|
||||||
|
ASSERT_THAT(fd.GetValue(), Ge(0)) << "Error opening input file";
|
||||||
|
ASSERT_THAT(sandbox.TransferToSandboxee(&fd), IsOk());
|
||||||
|
ASSERT_THAT(fd.GetRemoteFd(), Ge(0)) << "Error receiving remote FD";
|
||||||
|
|
||||||
|
sapi::v::ConstCStr rb_var("rb");
|
||||||
|
absl::StatusOr<void*> status_or_file =
|
||||||
|
api.png_fdopen(fd.GetRemoteFd(), rb_var.PtrBefore());
|
||||||
|
ASSERT_THAT(status_or_file, IsOk());
|
||||||
|
|
||||||
|
sapi::v::RemotePtr file(status_or_file.value());
|
||||||
|
ASSERT_THAT(file.GetValue(), NotNull()) << "Could not open " << infile;
|
||||||
|
|
||||||
|
sapi::v::Array<char> header(8);
|
||||||
|
ASSERT_THAT(api.png_fread(header.PtrBoth(), 1, header.GetSize(), &file),
|
||||||
|
IsOk());
|
||||||
|
|
||||||
|
absl::StatusOr<int> status_or_int =
|
||||||
|
api.png_sig_cmp(header.PtrBoth(), 0, header.GetSize());
|
||||||
|
ASSERT_THAT(status_or_int, IsOk());
|
||||||
|
ASSERT_THAT(status_or_int.value(), Eq(0)) << infile << " is not a PNG file";
|
||||||
|
|
||||||
|
sapi::v::ConstCStr ver_string_var(PNG_LIBPNG_VER_STRING);
|
||||||
|
absl::StatusOr<png_structp> status_or_png_structp =
|
||||||
|
api.png_create_read_struct_wrapper(ver_string_var.PtrBefore(),
|
||||||
|
sapi::v::NullPtr().PtrBoth());
|
||||||
|
|
||||||
|
ASSERT_THAT(status_or_png_structp, IsOk());
|
||||||
|
sapi::v::RemotePtr struct_ptr(status_or_png_structp.value());
|
||||||
|
ASSERT_THAT(struct_ptr.GetValue(), NotNull())
|
||||||
|
<< "png_create_read_struct_wrapper failed";
|
||||||
|
|
||||||
|
absl::StatusOr<png_infop> status_or_png_infop =
|
||||||
|
api.png_create_info_struct(&struct_ptr);
|
||||||
|
|
||||||
|
ASSERT_THAT(status_or_png_infop, IsOk());
|
||||||
|
sapi::v::RemotePtr info_ptr(status_or_png_infop.value());
|
||||||
|
ASSERT_THAT(info_ptr.GetValue(), NotNull())
|
||||||
|
<< "png_create_info_struct failed";
|
||||||
|
|
||||||
|
ASSERT_THAT(api.png_setjmp(&struct_ptr), IsOk());
|
||||||
|
ASSERT_THAT(api.png_init_io_wrapper(&struct_ptr, &file), IsOk());
|
||||||
|
ASSERT_THAT(api.png_set_sig_bytes(&struct_ptr, header.GetSize()), IsOk());
|
||||||
|
ASSERT_THAT(api.png_read_info(&struct_ptr, &info_ptr), IsOk());
|
||||||
|
|
||||||
|
status_or_int = api.png_get_image_width(&struct_ptr, &info_ptr);
|
||||||
|
ASSERT_THAT(status_or_int, IsOk());
|
||||||
|
data.width = status_or_int.value();
|
||||||
|
EXPECT_THAT(data.width, Gt(0));
|
||||||
|
|
||||||
|
status_or_int = api.png_get_image_height(&struct_ptr, &info_ptr);
|
||||||
|
ASSERT_THAT(status_or_int, IsOk());
|
||||||
|
data.height = status_or_int.value();
|
||||||
|
EXPECT_THAT(data.height, Gt(0));
|
||||||
|
|
||||||
|
absl::StatusOr<uint8_t> status_or_uchar =
|
||||||
|
api.png_get_color_type(&struct_ptr, &info_ptr);
|
||||||
|
ASSERT_THAT(status_or_uchar, IsOk());
|
||||||
|
data.color_type = status_or_uchar.value();
|
||||||
|
|
||||||
|
status_or_uchar = api.png_get_bit_depth(&struct_ptr, &info_ptr);
|
||||||
|
ASSERT_THAT(status_or_uchar, IsOk());
|
||||||
|
data.bit_depth = status_or_uchar.value();
|
||||||
|
|
||||||
|
status_or_int = api.png_set_interlace_handling(&struct_ptr);
|
||||||
|
ASSERT_THAT(status_or_int, IsOk());
|
||||||
|
data.number_of_passes = status_or_int.value();
|
||||||
|
|
||||||
|
ASSERT_THAT(api.png_read_update_info(&struct_ptr, &info_ptr), IsOk());
|
||||||
|
ASSERT_THAT(api.png_setjmp(&struct_ptr), IsOk());
|
||||||
|
|
||||||
|
absl::StatusOr<uint32_t> status_or_uint =
|
||||||
|
api.png_get_rowbytes(&struct_ptr, &info_ptr);
|
||||||
|
ASSERT_THAT(status_or_uint, IsOk());
|
||||||
|
data.rowbytes = status_or_uint.value();
|
||||||
|
EXPECT_THAT(data.rowbytes, Ge(data.width));
|
||||||
|
|
||||||
|
data.row_pointers =
|
||||||
|
std::make_unique<sapi::v::Array<uint8_t>>(data.height * data.rowbytes);
|
||||||
|
|
||||||
|
ASSERT_THAT(
|
||||||
|
api.png_read_image_wrapper(&struct_ptr, data.row_pointers->PtrAfter(),
|
||||||
|
data.height, data.rowbytes),
|
||||||
|
IsOk());
|
||||||
|
|
||||||
|
ASSERT_THAT(api.png_fclose(&file), IsOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WritePng(LibPNGApi& api, LibPNGSapiSandbox& sandbox,
|
||||||
|
absl::string_view outfile, Data& data) {
|
||||||
|
sapi::v::Fd fd(open(outfile.data(), O_WRONLY));
|
||||||
|
|
||||||
|
ASSERT_THAT(fd.GetValue(), Ge(0)) << "Error opening output file";
|
||||||
|
ASSERT_THAT(sandbox.TransferToSandboxee(&fd), IsOk());
|
||||||
|
ASSERT_THAT(fd.GetRemoteFd(), Ge(0)) << "Error receiving remote FD";
|
||||||
|
|
||||||
|
sapi::v::ConstCStr wb_var("wb");
|
||||||
|
absl::StatusOr<void*> status_or_file =
|
||||||
|
api.png_fdopen(fd.GetRemoteFd(), wb_var.PtrBefore());
|
||||||
|
ASSERT_THAT(status_or_file, IsOk());
|
||||||
|
|
||||||
|
sapi::v::RemotePtr file(status_or_file.value());
|
||||||
|
ASSERT_THAT(file.GetValue(), NotNull()) << "Could not open " << outfile;
|
||||||
|
|
||||||
|
sapi::v::ConstCStr ver_string_var(PNG_LIBPNG_VER_STRING);
|
||||||
|
absl::StatusOr<png_structp> status_or_png_structp =
|
||||||
|
api.png_create_write_struct_wrapper(ver_string_var.PtrBefore(),
|
||||||
|
sapi::v::NullPtr().PtrBoth());
|
||||||
|
ASSERT_THAT(status_or_png_structp, IsOk());
|
||||||
|
|
||||||
|
sapi::v::RemotePtr struct_ptr(status_or_png_structp.value());
|
||||||
|
ASSERT_THAT(struct_ptr.GetValue(), NotNull())
|
||||||
|
<< "png_create_write_struct_wrapper failed";
|
||||||
|
|
||||||
|
absl::StatusOr<png_infop> status_or_png_infop =
|
||||||
|
api.png_create_info_struct(&struct_ptr);
|
||||||
|
ASSERT_THAT(status_or_png_infop, IsOk());
|
||||||
|
|
||||||
|
sapi::v::RemotePtr info_ptr(status_or_png_infop.value());
|
||||||
|
ASSERT_THAT(info_ptr.GetValue(), NotNull())
|
||||||
|
<< "png_create_info_struct failed";
|
||||||
|
|
||||||
|
ASSERT_THAT(api.png_setjmp(&struct_ptr), IsOk());
|
||||||
|
ASSERT_THAT(api.png_init_io_wrapper(&struct_ptr, &file), IsOk());
|
||||||
|
|
||||||
|
ASSERT_THAT(api.png_setjmp(&struct_ptr), IsOk());
|
||||||
|
ASSERT_THAT(
|
||||||
|
api.png_set_IHDR(&struct_ptr, &info_ptr, data.width, data.height,
|
||||||
|
data.bit_depth, data.color_type, PNG_INTERLACE_NONE,
|
||||||
|
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE),
|
||||||
|
IsOk());
|
||||||
|
|
||||||
|
ASSERT_THAT(api.png_write_info(&struct_ptr, &info_ptr), IsOk());
|
||||||
|
|
||||||
|
ASSERT_THAT(api.png_setjmp(&struct_ptr), IsOk());
|
||||||
|
ASSERT_THAT(
|
||||||
|
api.png_write_image_wrapper(&struct_ptr, data.row_pointers->PtrBefore(),
|
||||||
|
data.height, data.rowbytes),
|
||||||
|
IsOk());
|
||||||
|
|
||||||
|
auto null = sapi::v::NullPtr();
|
||||||
|
ASSERT_THAT(api.png_setjmp(&struct_ptr), IsOk());
|
||||||
|
ASSERT_THAT(api.png_write_end(&struct_ptr, &null), IsOk());
|
||||||
|
|
||||||
|
ASSERT_THAT(api.png_fclose(&file), IsOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SandboxTest, ReadModifyWrite) {
|
||||||
|
std::string infile = GetTestFilePath("red_ball.png");
|
||||||
|
std::string outfile = GetTestFilePath("test_output.png");
|
||||||
|
|
||||||
|
LibPNGSapiSandbox sandbox;
|
||||||
|
ASSERT_THAT(sandbox.Init(), IsOk());
|
||||||
|
LibPNGApi api(&sandbox);
|
||||||
|
|
||||||
|
Data data;
|
||||||
|
ReadPng(api, sandbox, infile, data);
|
||||||
|
|
||||||
|
ASSERT_THAT(data.color_type == PNG_COLOR_TYPE_RGBA ||
|
||||||
|
data.color_type == PNG_COLOR_TYPE_RGB,
|
||||||
|
IsTrue())
|
||||||
|
<< infile << " has unexpected color type. Expected RGB or RGBA";
|
||||||
|
|
||||||
|
size_t channel_count = 3;
|
||||||
|
if (data.color_type == PNG_COLOR_TYPE_RGBA) {
|
||||||
|
channel_count = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_THAT(channel_count * data.width, Eq(data.rowbytes));
|
||||||
|
|
||||||
|
// RGB to BGR
|
||||||
|
for (size_t i = 0; i != data.height; ++i) {
|
||||||
|
for (size_t j = 0; j != data.width; ++j) {
|
||||||
|
uint8_t r = (*data.row_pointers)[i * data.rowbytes + j * channel_count];
|
||||||
|
uint8_t b =
|
||||||
|
(*data.row_pointers)[i * data.rowbytes + j * channel_count + 2];
|
||||||
|
(*data.row_pointers)[i * data.rowbytes + j * channel_count] = b;
|
||||||
|
(*data.row_pointers)[i * data.rowbytes + j * channel_count + 2] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WritePng(api, sandbox, outfile, data);
|
||||||
|
|
||||||
|
Data result;
|
||||||
|
ReadPng(api, sandbox, outfile, result);
|
||||||
|
|
||||||
|
EXPECT_THAT(result.height, Eq(data.height));
|
||||||
|
EXPECT_THAT(result.width, Eq(data.width));
|
||||||
|
EXPECT_THAT(result.color_type, Eq(data.color_type));
|
||||||
|
EXPECT_THAT(result.rowbytes, Eq(data.rowbytes));
|
||||||
|
EXPECT_THAT(result.bit_depth, Eq(data.bit_depth));
|
||||||
|
EXPECT_THAT(result.number_of_passes, Eq(data.number_of_passes));
|
||||||
|
EXPECT_THAT(absl::MakeSpan(result.row_pointers->GetData(),
|
||||||
|
result.row_pointers->GetSize()),
|
||||||
|
ContainerEq(absl::MakeSpan(data.row_pointers->GetData(),
|
||||||
|
data.row_pointers->GetSize())));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
40
oss-internship-2020/libpng/tests/helper.cc
Normal file
40
oss-internship-2020/libpng/tests/helper.cc
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// 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 "../sandboxed.h" // NOLINT(build/include)
|
||||||
|
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||||
|
#include "sandboxed_api/sandbox2/util/path.h"
|
||||||
|
|
||||||
|
std::string GetImagesFolder() {
|
||||||
|
std::string cwd = sandbox2::file_util::fileops::GetCWD();
|
||||||
|
auto find = cwd.rfind("/build");
|
||||||
|
if (find == std::string::npos) {
|
||||||
|
LOG(ERROR) << "Something went wrong: CWD don't contain build dir. "
|
||||||
|
<< "Please run tests from build dir, path might be incorrect\n";
|
||||||
|
|
||||||
|
return sandbox2::file::JoinPath(cwd, "images");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sandbox2::file::JoinPath(cwd.substr(0, find), "images");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetTestFilePath(const std::string& filename) {
|
||||||
|
static std::string* images_folder_path = nullptr;
|
||||||
|
if (!images_folder_path) {
|
||||||
|
images_folder_path = new std::string(GetImagesFolder());
|
||||||
|
}
|
||||||
|
return sandbox2::file::JoinPath(*images_folder_path, filename);
|
||||||
|
}
|
||||||
|
|
18
oss-internship-2020/libpng/tests/helper.h
Normal file
18
oss-internship-2020/libpng/tests/helper.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// 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 <string>
|
||||||
|
|
||||||
|
std::string GetTestFilePath(const std::string& filename);
|
||||||
|
|
92
oss-internship-2020/libpng/tests/libpng.h
Normal file
92
oss-internship-2020/libpng/tests/libpng.h
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// Defines from libpng library. The problem is that the build throws the error
|
||||||
|
// "Duplicate functions" if #include <png.h> was added.
|
||||||
|
|
||||||
|
#define PNG_FORMAT_FLAG_ALPHA 0x01U
|
||||||
|
#define PNG_FORMAT_FLAG_COLOR 0x02U
|
||||||
|
#define PNG_FORMAT_FLAG_LINEAR 0x04U
|
||||||
|
#define PNG_FORMAT_FLAG_COLORMAP 0x08U
|
||||||
|
|
||||||
|
#ifdef PNG_FORMAT_BGR_SUPPORTED
|
||||||
|
#define PNG_FORMAT_FLAG_BGR 0x10U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PNG_FORMAT_AFIRST_SUPPORTED
|
||||||
|
#define PNG_FORMAT_FLAG_AFIRST 0x20U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U
|
||||||
|
|
||||||
|
#define PNG_FORMAT_GRAY 0
|
||||||
|
#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA
|
||||||
|
#define PNG_FORMAT_AG (PNG_FORMAT_GA | PNG_FORMAT_FLAG_AFIRST)
|
||||||
|
#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR
|
||||||
|
#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_BGR)
|
||||||
|
#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB | PNG_FORMAT_FLAG_ALPHA)
|
||||||
|
#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA | PNG_FORMAT_FLAG_AFIRST)
|
||||||
|
#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR | PNG_FORMAT_FLAG_ALPHA)
|
||||||
|
#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA | PNG_FORMAT_FLAG_AFIRST)
|
||||||
|
|
||||||
|
#define PNG_IMAGE_VERSION 1
|
||||||
|
|
||||||
|
#define PNG_IMAGE_PIXEL_(test, fmt) \
|
||||||
|
(((fmt)&PNG_FORMAT_FLAG_COLORMAP) ? 1 : test(fmt))
|
||||||
|
|
||||||
|
#define PNG_IMAGE_SAMPLE_CHANNELS(fmt) \
|
||||||
|
(((fmt) & (PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_ALPHA)) + 1)
|
||||||
|
|
||||||
|
#define PNG_IMAGE_PIXEL_CHANNELS(fmt) \
|
||||||
|
PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS, fmt)
|
||||||
|
|
||||||
|
#define PNG_IMAGE_ROW_STRIDE(image) \
|
||||||
|
(PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width)
|
||||||
|
|
||||||
|
#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt) \
|
||||||
|
((((fmt)&PNG_FORMAT_FLAG_LINEAR) >> 2) + 1)
|
||||||
|
|
||||||
|
#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt) \
|
||||||
|
PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE, fmt)
|
||||||
|
|
||||||
|
#define PNG_IMAGE_BUFFER_SIZE(image, row_stride) \
|
||||||
|
(PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format) * (image).height * \
|
||||||
|
(row_stride))
|
||||||
|
|
||||||
|
#define PNG_IMAGE_SIZE(image) \
|
||||||
|
PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image))
|
||||||
|
|
||||||
|
typedef uint8_t *png_bytep;
|
||||||
|
|
||||||
|
#if UINT_MAX == 65535
|
||||||
|
typedef unsigned int png_uint_16;
|
||||||
|
#elif USHRT_MAX == 65535
|
||||||
|
typedef unsigned short png_uint_16;
|
||||||
|
#else
|
||||||
|
#error "libpng requires an unsigned 16-bit type"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PNG_LIBPNG_VER_STRING "1.6.38.git"
|
||||||
|
|
||||||
|
#define PNG_COLOR_MASK_COLOR 2
|
||||||
|
#define PNG_COLOR_MASK_ALPHA 4
|
||||||
|
|
||||||
|
#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
|
||||||
|
#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
|
||||||
|
#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
|
||||||
|
|
||||||
|
#define PNG_FILTER_TYPE_BASE 0
|
||||||
|
#define PNG_COMPRESSION_TYPE_BASE 0
|
||||||
|
#define PNG_INTERLACE_NONE 0
|
||||||
|
|
28
oss-internship-2020/libpng/wrapper/CMakeLists.txt
Normal file
28
oss-internship-2020/libpng/wrapper/CMakeLists.txt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# 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(wrapper OBJECT
|
||||||
|
func.h
|
||||||
|
func.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(wrapper
|
||||||
|
PROPERTIES LINKER_LANGUAGE C
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(wrapper
|
||||||
|
sandbox2::temp_file
|
||||||
|
sapi::sapi
|
||||||
|
PNG::PNG
|
||||||
|
)
|
57
oss-internship-2020/libpng/wrapper/func.cc
Normal file
57
oss-internship-2020/libpng/wrapper/func.cc
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#include "func.h" // NOLINT(build/include)
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void png_setjmp(png_structrp ptr) { setjmp(png_jmpbuf(ptr)); }
|
||||||
|
|
||||||
|
void* png_fdopen(int fd, const char* mode) {
|
||||||
|
FILE* f = fdopen(fd, mode);
|
||||||
|
return static_cast<void*>(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void png_rewind(void* f) { rewind(static_cast<FILE*>(f)); }
|
||||||
|
|
||||||
|
void png_fread(void* buffer, size_t size, size_t count, void* stream) {
|
||||||
|
fread(buffer, size, count, static_cast<FILE*>(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
void png_fclose(void* f) { fclose(static_cast<FILE*>(f)); }
|
||||||
|
|
||||||
|
void png_init_io_wrapper(png_structrp png_ptr, void* f) {
|
||||||
|
png_init_io(png_ptr, static_cast<FILE*>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
png_structp png_create_read_struct_wrapper(png_const_charp user_png_ver,
|
||||||
|
png_voidp error_ptr) {
|
||||||
|
return png_create_read_struct(user_png_ver, error_ptr, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
png_structp png_create_write_struct_wrapper(png_const_charp user_png_ver,
|
||||||
|
png_voidp error_ptr) {
|
||||||
|
return png_create_write_struct(user_png_ver, error_ptr, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void png_read_image_wrapper(png_structrp png_ptr, png_bytep image,
|
||||||
|
size_t height, size_t rowbytes) {
|
||||||
|
png_bytep* ptrs = (png_bytep*)malloc(height * sizeof(png_bytep));
|
||||||
|
for (size_t i = 0; i != height; ++i) {
|
||||||
|
ptrs[i] = image + (i * rowbytes);
|
||||||
|
}
|
||||||
|
png_read_image(png_ptr, ptrs);
|
||||||
|
free(ptrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void png_write_image_wrapper(png_structrp png_ptr, png_bytep image,
|
||||||
|
size_t height, size_t rowbytes) {
|
||||||
|
png_bytep* ptrs = (png_bytep*)malloc(height * sizeof(png_bytep));
|
||||||
|
for (size_t i = 0; i != height; ++i) {
|
||||||
|
ptrs[i] = image + (i * rowbytes);
|
||||||
|
}
|
||||||
|
png_write_image(png_ptr, ptrs);
|
||||||
|
free(ptrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void png_write_end_wrapper(png_structrp png_ptr) {
|
||||||
|
png_write_end(png_ptr, NULL);
|
||||||
|
}
|
||||||
|
|
24
oss-internship-2020/libpng/wrapper/func.h
Normal file
24
oss-internship-2020/libpng/wrapper/func.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef LIBPNG_WRAPPER_FUNC_H
|
||||||
|
#define LIBPNG_WRAPPER_FUNC_H
|
||||||
|
|
||||||
|
#include "png.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void* png_fdopen(int fd, const char* mode);
|
||||||
|
void png_rewind(void* f);
|
||||||
|
void png_fread(void* buffer, size_t size, size_t count, void* stream);
|
||||||
|
void png_fclose(void* f);
|
||||||
|
void png_setjmp(png_structrp ptr);
|
||||||
|
png_structp png_create_read_struct_wrapper(png_const_charp user_png_ver,
|
||||||
|
png_voidp error_ptr);
|
||||||
|
png_structp png_create_write_struct_wrapper(png_const_charp user_png_ver,
|
||||||
|
png_voidp error_ptr);
|
||||||
|
void png_init_io_wrapper(png_structrp png_ptr, void* f);
|
||||||
|
void png_read_image_wrapper(png_structrp png_ptr, png_bytep image,
|
||||||
|
size_t height, size_t rowbytes);
|
||||||
|
void png_write_image_wrapper(png_structrp png_ptr, png_bytep image,
|
||||||
|
size_t height, size_t rowbytes);
|
||||||
|
void png_write_end_wrapper(png_structrp png_ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user