xref: /aosp_15_r20/external/sandboxed-api/contrib/turbojpeg/tests/turbojpeg_sapi_test.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #define _GNU_SOURCE 1
16 #include "../turbojpeg_sapi.h"  // NOLINT(build/include)
17 
18 #include <turbojpeg.h>
19 
20 #include <cerrno>
21 #include <cstdlib>
22 #include <fstream>
23 #include <iostream>
24 
25 #include "gmock/gmock.h"
26 #include "gtest/gtest.h"
27 #include "sandboxed_api/testing.h"
28 #include "sandboxed_api/util/fileops.h"
29 #include "sandboxed_api/util/path.h"
30 #include "sandboxed_api/util/status_matchers.h"
31 #include "turbojpeg_sapi.sapi.h"  // NOLINT(build/include)
32 
33 namespace {
34 
35 using ::sapi::IsOk;
36 using ::testing::Eq;
37 using ::testing::Gt;
38 using ::testing::Not;
39 using ::testing::NotNull;
40 using ::testing::StrEq;
41 
42 class TurboJpegSapiSandboxTest : public testing::Test {
43  protected:
SetUpTestSuite()44   static void SetUpTestSuite() {
45     ASSERT_THAT(getenv("TEST_FILES_DIR"), NotNull());
46     sandbox_ = new TurboJpegSapiSandbox();
47     ASSERT_THAT(sandbox_->Init(), IsOk());
48     api_ = new turbojpeg_sapi::TurboJPEGApi(sandbox_);
49   }
TearDownTestSuite()50   static void TearDownTestSuite() {
51     delete api_;
52     delete sandbox_;
53   }
54 
GetTurboJpegErrorStr(sapi::v::Ptr * handle)55   static std::string GetTurboJpegErrorStr(sapi::v::Ptr* handle) {
56     auto errmsg_ptr = api_->tjGetErrorStr2(handle);
57     if (!errmsg_ptr.ok()) return "Error getting error message";
58     auto errmsg =
59         sandbox_->GetCString(sapi::v::RemotePtr(errmsg_ptr.value()), 256);
60     if (!errmsg.ok()) return "Error getting error message";
61     return errmsg.value();
62   }
63   static turbojpeg_sapi::TurboJPEGApi* api_;
64   static TurboJpegSapiSandbox* sandbox_;
65 };
66 
67 turbojpeg_sapi::TurboJPEGApi* TurboJpegSapiSandboxTest::api_;
68 TurboJpegSapiSandbox* TurboJpegSapiSandboxTest::sandbox_;
69 
GetTestFilePath(const std::string & filename)70 std::string GetTestFilePath(const std::string& filename) {
71   return sapi::file::JoinPath(getenv("TEST_FILES_DIR"), filename);
72 }
73 
GetStreamSize(std::ifstream & stream)74 std::streamsize GetStreamSize(std::ifstream& stream) {
75   stream.seekg(0, std::ios_base::end);
76   std::streamsize ssize = stream.tellg();
77   stream.seekg(0, std::ios_base::beg);
78 
79   return ssize;
80 }
81 
ReadFile(const std::string & in_file,size_t expected_size=SIZE_MAX)82 absl::StatusOr<std::vector<uint8_t>> ReadFile(const std::string& in_file,
83                                               size_t expected_size = SIZE_MAX) {
84   std::ifstream f(GetTestFilePath(in_file));
85   if (!f.is_open()) {
86     return absl::UnavailableError("File could not be opened");
87   }
88   std::streamsize ssize = GetStreamSize(f);
89   if (expected_size != SIZE_MAX && ssize != expected_size) {
90     return absl::UnavailableError("Incorrect size of file");
91   }
92   std::vector<uint8_t> inbuf(ssize);
93   f.read(reinterpret_cast<char*>(inbuf.data()), ssize);
94   if (ssize != f.gcount()) {
95     return absl::UnavailableError("Premature end of file");
96   }
97   if (f.fail() || f.eof()) {
98     return absl::UnavailableError("Error reading file");
99   }
100   return inbuf;
101 }
102 
TEST_F(TurboJpegSapiSandboxTest,Compressor)103 TEST_F(TurboJpegSapiSandboxTest, Compressor) {
104   absl::StatusOr<void*> compression_handle_raw = api_->tjInitCompress();
105   ASSERT_THAT(compression_handle_raw, IsOk());
106   ASSERT_THAT(compression_handle_raw.value(), NotNull());
107   sapi::v::RemotePtr compression_handle{compression_handle_raw.value()};
108   auto result = ReadFile("sample.rgb", 12 * 67 * 3);
109   ASSERT_THAT(result, IsOk());
110   sapi::v::Array array(result->data(), result->size());
111 
112   sapi::v::GenericPtr buffer;
113   {
114     sapi::v::ULong length{0};
115     auto result = api_->tjCompress2(&compression_handle, array.PtrBefore(), 12,
116                                     36, 67, TJPF_RGB, buffer.PtrAfter(),
117                                     length.PtrBoth(), TJSAMP_444, 10, 0);
118     ASSERT_THAT(result, IsOk());
119     ASSERT_THAT(result.value(), Eq(0))
120         << "Error from sandboxee: "
121         << GetTurboJpegErrorStr(&compression_handle);
122     ASSERT_TRUE(buffer.GetValue());
123     ASSERT_TRUE(buffer.GetRemote());
124     ASSERT_THAT(length.GetValue(), Gt(0));
125   }
126   auto value = buffer.GetValue();
127 
128   auto destroy_result = api_->tjDestroy(&compression_handle);
129   ASSERT_THAT(destroy_result, IsOk());
130   ASSERT_THAT(destroy_result.value(), Eq(0));
131 }
132 
TEST_F(TurboJpegSapiSandboxTest,Decompressor)133 TEST_F(TurboJpegSapiSandboxTest, Decompressor) {
134   absl::StatusOr<void*> decompression_handle_raw = api_->tjInitDecompress();
135   ASSERT_THAT(decompression_handle_raw, IsOk());
136   ASSERT_THAT(decompression_handle_raw.value(), NotNull());
137   sapi::v::RemotePtr decompression_handle{decompression_handle_raw.value()};
138   auto result = ReadFile("sample.jpeg");
139   ASSERT_THAT(result, IsOk());
140   sapi::v::Array array(result->data(), result->size());
141 
142   sapi::v::Int width{0};
143   sapi::v::Int height{0};
144   sapi::v::Int subsamp{0};
145   sapi::v::Int colorspace{0};
146   auto decompress_result = api_->tjDecompressHeader3(
147       &decompression_handle, array.PtrBefore(), result->size(),
148       width.PtrAfter(), height.PtrAfter(), subsamp.PtrAfter(),
149       colorspace.PtrAfter());
150   ASSERT_THAT(decompress_result, IsOk());
151   ASSERT_THAT(decompress_result.value(), Eq(0))
152       << "Error from sandboxee: "
153       << GetTurboJpegErrorStr(&decompression_handle);
154 
155   ASSERT_THAT(width.GetValue(), Eq(67));
156   ASSERT_THAT(height.GetValue(), Eq(12));
157   ASSERT_THAT(subsamp.GetValue(), Eq(TJSAMP_GRAY));
158   ASSERT_THAT(colorspace.GetValue(), Eq(TJCS_GRAY));
159 
160   auto arr = sapi::v::Array<unsigned char>(12 * 67 * 3);
161   decompress_result = api_->tjDecompress2(
162       &decompression_handle, array.PtrBefore(), result->size(), arr.PtrAfter(),
163       12, 36, 67, TJCS_RGB, 0);
164   ASSERT_THAT(decompress_result, IsOk());
165   EXPECT_THAT(decompress_result.value(), Eq(0))
166       << "Error from sandboxee: "
167       << GetTurboJpegErrorStr(&decompression_handle);
168 
169   decompress_result = api_->tjDestroy(&decompression_handle);
170   ASSERT_THAT(decompress_result, IsOk());
171   ASSERT_THAT(decompress_result.value(), Eq(0));
172 }
173 }  // namespace
174