xref: /aosp_15_r20/external/sandboxed-api/contrib/zopfli/utils/utils_zopfli.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 #include "contrib/zopfli/utils/utils_zopfli.h"
16 
17 #include <unistd.h>
18 
19 #include <fstream>
20 
Compress(ZopfliApi & api,std::ifstream & instream,std::ofstream & outstream,ZopfliFormat format)21 absl::Status Compress(ZopfliApi& api, std::ifstream& instream,
22                       std::ofstream& outstream, ZopfliFormat format) {
23   // Get size of Stream
24   instream.seekg(0, std::ios_base::end);
25   std::streamsize ssize = instream.tellg();
26   instream.seekg(0, std::ios_base::beg);
27 
28   // Read data
29   sapi::v::Array<uint8_t> inbuf(ssize);
30   instream.read(reinterpret_cast<char*>(inbuf.GetData()), ssize);
31   if (instream.gcount() != ssize) {
32     return absl::UnavailableError("Unable to read file");
33   }
34 
35   // Compress
36   sapi::v::Struct<ZopfliOptions> options;
37   SAPI_RETURN_IF_ERROR(api.ZopfliInitOptions(options.PtrAfter()));
38 
39   sapi::v::GenericPtr outptr;
40   sapi::v::IntBase<size_t> outsize(0);
41 
42   SAPI_RETURN_IF_ERROR(
43       api.ZopfliCompress(options.PtrBefore(), format, inbuf.PtrBefore(), ssize,
44                          outptr.PtrAfter(), outsize.PtrBoth()));
45 
46   // Get and save data
47   sapi::v::Array<int8_t> outbuf(outsize.GetValue());
48   outbuf.SetRemote(reinterpret_cast<void*>(outptr.GetValue()));
49   SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferFromSandboxee(&outbuf));
50 
51   outstream.write(reinterpret_cast<char*>(outbuf.GetData()), outbuf.GetSize());
52   if (!outstream.good()) {
53     return absl::UnavailableError("Unable to write file");
54   }
55   return absl::OkStatus();
56 }
57 
CompressFD(ZopfliApi & api,sapi::v::Fd & infd,sapi::v::Fd & outfd,ZopfliFormat format)58 absl::Status CompressFD(ZopfliApi& api, sapi::v::Fd& infd, sapi::v::Fd& outfd,
59                         ZopfliFormat format) {
60   SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferToSandboxee(&infd));
61   SAPI_RETURN_IF_ERROR(api.GetSandbox()->TransferToSandboxee(&outfd));
62 
63   sapi::v::Struct<ZopfliOptions> options;
64   SAPI_RETURN_IF_ERROR(api.ZopfliInitOptions(options.PtrAfter()));
65 
66   SAPI_ASSIGN_OR_RETURN(
67       int ret, api.ZopfliCompressFD(options.PtrBefore(), format,
68                                     infd.GetRemoteFd(), outfd.GetRemoteFd()));
69 
70   infd.CloseRemoteFd(api.GetSandbox()->rpc_channel()).IgnoreError();
71   outfd.CloseRemoteFd(api.GetSandbox()->rpc_channel()).IgnoreError();
72 
73   if (ret == -1) {
74     return absl::UnavailableError("Unable to compress file");
75   }
76 
77   return absl::OkStatus();
78 }
79