Merge pull request #50 from Manwi23:master

PiperOrigin-RevId: 332214390
Change-Id: If9e87dc52cf1e5e2266135c38b6c4429f7f78e5f
This commit is contained in:
Copybara-Service 2020-09-17 05:28:19 -07:00
commit d4274251a6
8 changed files with 3301 additions and 1 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "oss-internship-2020/openjpeg/openjpeg"]
path = oss-internship-2020/openjpeg/openjpeg
url = https://github.com/uclouvain/openjpeg.git
[submodule "oss-internship-2020/pffft/master"]
path = oss-internship-2020/pffft/master
url = https://bitbucket.org/jpommier/pffft/src/master/

View File

@ -0,0 +1 @@
build/

View File

@ -0,0 +1,56 @@
# 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(openjpeg-sapi C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# To override lib option -- else SAPI won't work
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build OpenJPEG shared library and link executables against it." FORCE)
add_subdirectory(openjpeg)
set(SAPI_ROOT "../.." CACHE PATH "Path to the Sandboxed API source tree")
set(SAPI_ENABLE_EXAMPLES OFF CACHE BOOL "")
set(SAPI_ENABLE_TESTS OFF CACHE BOOL "")
set(EXECUTABLE_OUTPUT_PATH "" CACHE PATH "" FORCE)
add_subdirectory("${SAPI_ROOT}"
"${CMAKE_BINARY_DIR}/sandboxed-api-build"
EXCLUDE_FROM_ALL)
add_sapi_library(openjp2_sapi
FUNCTIONS opj_stream_destroy
opj_stream_create_default_file_stream
opj_create_decompress
opj_image_destroy
opj_setup_decoder
opj_destroy_codec
opj_read_header
opj_decode
opj_set_default_decoder_parameters
opj_end_decompress
INPUTS ${CMAKE_CURRENT_SOURCE_DIR}/openjpeg/src/lib/openjp2/openjpeg.h
LIBRARY openjp2
LIBRARY_NAME Openjp2
NAMESPACE ""
)
target_include_directories(openjp2_sapi INTERFACE
"${PROJECT_BINARY_DIR}"
)
add_subdirectory(examples)

View File

@ -0,0 +1,29 @@
# OpenJPEG Sandboxed API
This library provides sandboxed version of the [OpenJPEG](https://github.com/uclouvain/openjpeg) library.
## Examples
The examples are sandboxed and simplified version of the main tools provided by the OpenJPEG library, namely (for now) `opj_decompress` from [here](https://github.com/uclouvain/openjpeg/blob/master/src/bin/jp2/opj_decompress.c).
In `decompress_example.cc` the library's sandboxed API is used to convert the _.jp2_ to _.pnm_ image format.
## Build
To build this example, after cloning the whole Sandbox API project, you also need to run
```
git submodule update --init --recursive
```
anywhere in the project tree in order to clone the `openjpeg` submodule.
Then in the `sandboxed-api/oss-internship-2020/openjpeg` run
```
mkdir build && cd build
cmake -G Ninja
ninja
```
To run `decompress_sandboxed`:
```
cd examples
./decompress_sandboxed absolute/path/to/the/file.jp2 absolute/path/to/the/file.pnm
```

View File

@ -0,0 +1,48 @@
# 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.
# we need to use modified versions of some of the library tools
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/gen_files")
file(COPY "${PROJECT_SOURCE_DIR}/openjpeg/src/bin/jp2/convert.c" DESTINATION "${PROJECT_BINARY_DIR}/gen_files/")
file(COPY "${PROJECT_SOURCE_DIR}/openjpeg/src/bin/jp2/convert.h" DESTINATION "${PROJECT_BINARY_DIR}/gen_files/")
file(COPY "${PROJECT_SOURCE_DIR}/examples/convert.patch" DESTINATION "${PROJECT_BINARY_DIR}/gen_files/")
file(COPY "${PROJECT_SOURCE_DIR}/examples/convert_h.patch" DESTINATION "${PROJECT_BINARY_DIR}/gen_files/")
add_custom_command(
OUTPUT ${PROJECT_BINARY_DIR}/gen_files/convert.cc ${PROJECT_BINARY_DIR}/gen_files/convert.h
COMMAND cd ${PROJECT_BINARY_DIR}/gen_files && patch < ${PROJECT_SOURCE_DIR}/examples/convert.patch > /dev/null
COMMAND cd ${PROJECT_BINARY_DIR}/gen_files && patch < ${PROJECT_SOURCE_DIR}/examples/convert_h.patch > /dev/null
COMMAND mv ${PROJECT_BINARY_DIR}/gen_files/convert.c ${PROJECT_BINARY_DIR}/gen_files/convert.cc
)
add_library(convert_helper STATIC
${PROJECT_BINARY_DIR}/gen_files/convert.cc
${PROJECT_BINARY_DIR}/gen_files/convert.h
)
add_executable(decompress_sandboxed
decompress_example.cc
)
target_link_libraries(decompress_sandboxed PRIVATE
convert_helper
openjp2_sapi
sapi::sapi
)
target_link_libraries(convert_helper PRIVATE
openjp2_sapi
sapi::sapi
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,135 @@
--- convert.h 2020-08-27 15:46:45.028628305 +0000
+++ convert_helper.h 2020-08-27 14:26:02.155455250 +0000
@@ -1,126 +1,8 @@
-/*
- * The copyright in this software is being made available under the 2-clauses
- * BSD License, included below. This software may be subject to other third
- * party and contributor rights, including patent rights, and no such rights
- * are granted under this license.
- *
- * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2014, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux
- * Copyright (c) 2003-2014, Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __J2K_CONVERT_H
-#define __J2K_CONVERT_H
+// imagetopnm and the two functions it calls internaly are patched
+// versions of the library's tools; from openjpeg/src/bin/jp2/convert.c
-/**@name RAW component encoding parameters */
-/*@{*/
-typedef struct raw_comp_cparameters {
- /** subsampling in X direction */
- int dx;
- /** subsampling in Y direction */
- int dy;
- /*@}*/
-} raw_comp_cparameters_t;
-
-/**@name RAW image encoding parameters */
-/*@{*/
-typedef struct raw_cparameters {
- /** width of the raw image */
- int rawWidth;
- /** height of the raw image */
- int rawHeight;
- /** number of components of the raw image */
- int rawComp;
- /** bit depth of the raw image */
- int rawBitDepth;
- /** signed/unsigned raw image */
- OPJ_BOOL rawSigned;
- /** raw components parameters */
- raw_comp_cparameters_t *rawComps;
- /*@}*/
-} raw_cparameters_t;
-
-/* Component precision clipping */
-void clip_component(opj_image_comp_t* component, OPJ_UINT32 precision);
-/* Component precision scaling */
-void scale_component(opj_image_comp_t* component, OPJ_UINT32 precision);
-
-/* planar / interleaved conversions */
-typedef void (* convert_32s_CXPX)(const OPJ_INT32* pSrc, OPJ_INT32* const* pDst,
- OPJ_SIZE_T length);
-extern const convert_32s_CXPX convert_32s_CXPX_LUT[5];
-typedef void (* convert_32s_PXCX)(OPJ_INT32 const* const* pSrc, OPJ_INT32* pDst,
- OPJ_SIZE_T length, OPJ_INT32 adjust);
-extern const convert_32s_PXCX convert_32s_PXCX_LUT[5];
-/* bit depth conversions */
-typedef void (* convert_XXx32s_C1R)(const OPJ_BYTE* pSrc, OPJ_INT32* pDst,
- OPJ_SIZE_T length);
-extern const convert_XXx32s_C1R convert_XXu32s_C1R_LUT[9]; /* up to 8bpp */
-typedef void (* convert_32sXXx_C1R)(const OPJ_INT32* pSrc, OPJ_BYTE* pDst,
- OPJ_SIZE_T length);
-extern const convert_32sXXx_C1R convert_32sXXu_C1R_LUT[9]; /* up to 8bpp */
-
-
-/* TGA conversion */
-opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters);
-int imagetotga(opj_image_t * image, const char *outfile);
-
-/* BMP conversion */
-opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters);
-int imagetobmp(opj_image_t *image, const char *outfile);
-
-/* TIFF conversion*/
-opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters);
-int imagetotif(opj_image_t *image, const char *outfile);
-/**
-Load a single image component encoded in PGX file format
-@param filename Name of the PGX file to load
-@param parameters *List ?*
-@return Returns a greyscale image if successful, returns NULL otherwise
-*/
-opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters);
-int imagetopgx(opj_image_t *image, const char *outfile);
-
-opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters);
-int imagetopnm(opj_image_t *image, const char *outfile, int force_split);
-
-/* RAW conversion */
-int imagetoraw(opj_image_t * image, const char *outfile);
-int imagetorawl(opj_image_t * image, const char *outfile);
-opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters,
- raw_cparameters_t *raw_cp);
-opj_image_t* rawltoimage(const char *filename, opj_cparameters_t *parameters,
- raw_cparameters_t *raw_cp);
-
-/* PNG conversion*/
-extern int imagetopng(opj_image_t *image, const char *write_idf);
-extern opj_image_t* pngtoimage(const char *filename,
- opj_cparameters_t *parameters);
-
-#endif /* __J2K_CONVERT_H */
+#include "openjp2_sapi.sapi.h"
+const char* opj_version(void);
+static int are_comps_similar(opj_image_t* image);
+int imagetopnm(opj_image_t* image, const char* outfile, int force_split);

View File

@ -0,0 +1,157 @@
// 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.
// Perform decompression from *.jp2 to *.pnm format
#include <libgen.h>
#include <syscall.h>
#include <cstdlib>
#include <iostream>
#include <vector>
#include "gen_files/convert.h" // NOLINT(build/include)
#include "openjp2_sapi.sapi.h" // NOLINT(build/include)
class Openjp2SapiSandbox : public Openjp2Sandbox {
public:
explicit Openjp2SapiSandbox(std::string in_file)
: in_file_(std::move(in_file)) {}
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
sandbox2::PolicyBuilder*) override {
return sandbox2::PolicyBuilder()
.AllowStaticStartup()
.AllowOpen()
.AllowRead()
.AllowWrite()
.AllowStat()
.AllowSystemMalloc()
.AllowExit()
.AllowSyscalls({
__NR_futex,
__NR_close,
__NR_lseek,
})
.AddFile(in_file_)
.BuildOrDie();
}
private:
std::string in_file_;
};
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
if (argc != 3) {
std::cerr << "Usage: " << basename(argv[0]) << " absolute/path/to/INPUT.jp2"
<< " absolute/path/to/OUTPUT.pnm\n";
return EXIT_FAILURE;
}
std::string in_file(argv[1]);
// Initialize sandbox.
Openjp2SapiSandbox sandbox(in_file);
absl::Status status = sandbox.Init();
CHECK(status.ok()) << "Sandbox initialization failed " << status;
Openjp2Api api(&sandbox);
sapi::v::ConstCStr in_file_v(in_file.c_str());
// Initialize library's main data-holders.
sapi::StatusOr<opj_stream_t*> stream =
api.opj_stream_create_default_file_stream(in_file_v.PtrBefore(), 1);
CHECK(stream.ok()) << "Stream initialization failed: " << stream.status();
sapi::v::RemotePtr stream_pointer(stream.value());
sapi::StatusOr<opj_codec_t*> codec = api.opj_create_decompress(OPJ_CODEC_JP2);
CHECK(codec.ok()) << "Codec initialization failed: " << stream.status();
sapi::v::RemotePtr codec_pointer(codec.value());
sapi::v::Struct<opj_dparameters_t> parameters;
status = api.opj_set_default_decoder_parameters(parameters.PtrBoth());
CHECK(status.ok()) << "Parameters initialization failed " << status;
sapi::StatusOr<OPJ_BOOL> bool_status =
api.opj_setup_decoder(&codec_pointer, parameters.PtrBefore());
CHECK(bool_status.ok() && bool_status.value()) << "Decoder setup failed";
// Start reading image from the input file.
sapi::v::GenericPtr image_pointer;
bool_status = api.opj_read_header(&stream_pointer, &codec_pointer,
image_pointer.PtrAfter());
CHECK(bool_status.ok() && bool_status.value())
<< "Reading image header failed";
sapi::v::Struct<opj_image_t> image;
image.SetRemote(reinterpret_cast<void*>(image_pointer.GetValue()));
CHECK(sandbox.TransferFromSandboxee(&image).ok())
<< "Transfer from sandboxee failed";
bool_status =
api.opj_decode(&codec_pointer, &stream_pointer, image.PtrAfter());
CHECK(bool_status.ok() && bool_status.value()) << "Decoding failed";
bool_status = api.opj_end_decompress(&codec_pointer, &stream_pointer);
CHECK(bool_status.ok() && bool_status.value()) << "Ending decompress failed";
int components = image.data().numcomps;
// Transfer the read data to the main process.
sapi::v::Array<opj_image_comp_t> image_components(components);
image_components.SetRemote(image.data().comps);
CHECK(sandbox.TransferFromSandboxee(&image_components).ok())
<< "Transfer from sandboxee failed";
image.mutable_data()->comps =
static_cast<opj_image_comp_t*>(image_components.GetLocal());
unsigned int width = static_cast<unsigned int>(image.data().comps[0].w);
unsigned int height = static_cast<unsigned int>(image.data().comps[0].h);
std::vector<std::vector<OPJ_INT32>> data(components);
sapi::v::Array<OPJ_INT32> image_components_data(width * height);
for (int i = 0; i < components; ++i) {
image_components_data.SetRemote(image.data().comps[i].data);
CHECK(sandbox.TransferFromSandboxee(&image_components_data).ok())
<< "Transfer from sandboxee failed";
std::vector<OPJ_INT32> component_data(
image_components_data.GetData(),
image_components_data.GetData() + (width * height));
data[i] = std::move(component_data);
image_components[i].data = &data[i][0];
}
// Convert the image to the desired format and save it to the file.
int error =
imagetopnm(static_cast<opj_image_t*>(image.GetLocal()), argv[2], 0);
CHECK(!error) << "Image convert failed";
// Clean up.
status = api.opj_image_destroy(image.PtrNone());
CHECK(status.ok()) << "Image destroy failed " << status;
status = api.opj_stream_destroy(&stream_pointer);
CHECK(status.ok()) << "Stream destroy failed " << status;
status = api.opj_destroy_codec(&codec_pointer);
CHECK(status.ok()) << "Codec destroy failed " << status;
return EXIT_SUCCESS;
}