xref: /aosp_15_r20/external/sandboxed-api/contrib/libtiff/test/defer_strile_writing.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2020 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 <cstdint>
16 
17 #include "helper.h"  // NOLINT(build/include)
18 #include "tiffio.h"  // NOLINT(build/include)
19 
20 using ::sapi::IsOk;
21 using ::testing::Eq;
22 using ::testing::IsTrue;
23 using ::testing::NotNull;
24 
25 // sapi functions:
26 // TIFFOpen
27 // TIFFClose
28 // TIFFGetField
29 // TIFFSetField
30 // TIFFWriteCheck
31 // TIFFSetDirectory
32 // TIFFFreeDirectory
33 // TIFFWriteScanline
34 // TIFFWriteDirectory
35 // TIFFCreateDirectory
36 // TIFFReadEncodedTile
37 // TIFFReadEncodedStrip
38 // TIFFWriteEncodedTile
39 // TIFFWriteEncodedStrip
40 // TIFFDeferStrileArrayWriting
41 // TIFFForceStrileArrayWriting
42 
43 namespace {
44 
45 constexpr int kTileBufferSize = 256;
46 constexpr int kWidth = 1;
47 constexpr int kBps = 8;
48 constexpr int kRowsPerStrip = 1;
49 constexpr int kSamplePerPixel = 1;
50 
TestWriting(const char * mode,int tiled,int height)51 void TestWriting(const char* mode, int tiled, int height) {
52   absl::StatusOr<std::string> status_or_path =
53       sapi::CreateNamedTempFileAndClose("defer_strile_writing.tif");
54   ASSERT_THAT(status_or_path, IsOk()) << "Could not create temp file";
55 
56   std::string srcfile = sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(),
57                                              status_or_path.value());
58 
59   absl::StatusOr<int> status_or_int;
60   absl::StatusOr<int64_t> status_or_long;
61   absl::StatusOr<TIFF*> status_or_tif;
62 
63   TiffSapiSandbox sandbox("", srcfile);
64   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
65 
66   TiffApi api(&sandbox);
67   sapi::v::ConstCStr srcfile_var(srcfile.c_str());
68   sapi::v::ConstCStr mode_var(mode);
69 
70   status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), mode_var.PtrBefore());
71   ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile;
72 
73   sapi::v::RemotePtr tif(status_or_tif.value());
74   ASSERT_THAT(tif.GetValue(), NotNull())
75       << "Can't create test TIFF file " << srcfile;
76 
77   status_or_int =
78       api.TIFFSetFieldU1(&tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
79   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
80   EXPECT_THAT(status_or_int.value(), IsTrue())
81       << "Can't set CompressionNone tag";
82 
83   status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_IMAGEWIDTH, kWidth);
84   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
85   EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageWidth tag";
86 
87   status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_IMAGELENGTH, height);
88   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
89   EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageLenght tag";
90 
91   status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_BITSPERSAMPLE, kBps);
92   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
93   EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set BitsPerSample tag";
94 
95   status_or_int =
96       api.TIFFSetFieldU1(&tif, TIFFTAG_SAMPLESPERPIXEL, kSamplePerPixel);
97   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
98   EXPECT_THAT(status_or_int.value(), IsTrue())
99       << "Can't set SamplesPerPixel tag";
100 
101   status_or_int =
102       api.TIFFSetFieldU1(&tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
103   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
104   EXPECT_THAT(status_or_int.value(), IsTrue())
105       << "Can't set PlanarConfiguration tag";
106 
107   if (tiled) {
108     status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_TILEWIDTH, 16);
109     ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
110     EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set TileWidth tag";
111 
112     status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_TILELENGTH, 16);
113     ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
114     EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set TileLenght tag";
115   } else {
116     status_or_int =
117         api.TIFFSetFieldU1(&tif, TIFFTAG_ROWSPERSTRIP, kRowsPerStrip);
118     ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
119     EXPECT_THAT(status_or_int.value(), IsTrue())
120         << "Can't set RowsPerStrip tag";
121   }
122 
123   status_or_int = api.TIFFDeferStrileArrayWriting(&tif);
124   ASSERT_THAT(status_or_int, IsOk())
125       << "TIFFDeferStrileArrayWriting fatal error";
126   EXPECT_THAT(status_or_int.value(), IsTrue())
127       << "TIFFDeferStrileArrayWriting return unexpected value";
128 
129   sapi::v::ConstCStr test_var("test");
130   status_or_int = api.TIFFWriteCheck(&tif, tiled, test_var.PtrBefore());
131   ASSERT_THAT(status_or_int, IsOk()) << "TIFFWriteCheck fatal error";
132   EXPECT_THAT(status_or_int.value(), IsTrue())
133       << "TIFFWriteCheck return unexpected value "
134       << "void test(" << mode << ", " << tiled << ", " << height << ")";
135 
136   status_or_int = api.TIFFWriteDirectory(&tif);
137   ASSERT_THAT(status_or_int, IsOk())
138       << "TIFFDeferStrileArrayWriting fatal error";
139   EXPECT_THAT(status_or_int.value(), IsTrue())
140       << "TIFFDeferStrileArrayWriting return unexpected value";
141 
142   // Create other directory
143   ASSERT_THAT(api.TIFFFreeDirectory(&tif), IsOk())
144       << "TIFFFreeDirectory fatal error";
145   ASSERT_THAT(api.TIFFCreateDirectory(&tif), IsOk())
146       << "TIFFCreateDirectory fatal error";
147 
148   status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
149   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
150   EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set SubFileType tag";
151 
152   status_or_int =
153       api.TIFFSetFieldU1(&tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
154   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
155   EXPECT_THAT(status_or_int.value(), IsTrue())
156       << "Can't set CompressionNone tag";
157 
158   status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_IMAGEWIDTH, kWidth);
159   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
160   EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageWidth tag";
161 
162   status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_IMAGELENGTH, 1);
163   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
164   EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set ImageLenght tag";
165 
166   status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_BITSPERSAMPLE, kBps);
167   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
168   EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set BitsPerSample tag";
169 
170   status_or_int =
171       api.TIFFSetFieldU1(&tif, TIFFTAG_SAMPLESPERPIXEL, kSamplePerPixel);
172   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
173   EXPECT_THAT(status_or_int.value(), IsTrue())
174       << "Can't set SamplesPerPixel tag";
175 
176   status_or_int =
177       api.TIFFSetFieldU1(&tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
178   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
179   EXPECT_THAT(status_or_int.value(), IsTrue())
180       << "Can't set PlanarConfiguration tag";
181 
182   status_or_int = api.TIFFSetFieldU1(&tif, TIFFTAG_ROWSPERSTRIP, kRowsPerStrip);
183   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
184   EXPECT_THAT(status_or_int.value(), IsTrue()) << "Can't set RowsPerStrip tag";
185 
186   status_or_int = api.TIFFDeferStrileArrayWriting(&tif);
187   ASSERT_THAT(status_or_int, IsOk())
188       << "TIFFDeferStrileArrayWriting fatal error";
189   EXPECT_THAT(status_or_int.value(), IsTrue())
190       << "TIFFDeferStrileArrayWriting return unexpected value";
191 
192   status_or_int = api.TIFFWriteCheck(&tif, 0, test_var.PtrBefore());
193   ASSERT_THAT(status_or_int, IsOk()) << "TIFFWriteCheck fatal error";
194   EXPECT_THAT(status_or_int.value(), IsTrue())
195       << "TIFFWriteCheck return unexpected value";
196 
197   status_or_int = api.TIFFWriteDirectory(&tif);
198   ASSERT_THAT(status_or_int, IsOk()) << "TIFFWriteDirectory fatal error";
199   EXPECT_THAT(status_or_int.value(), IsTrue())
200       << "TIFFWriteDirectory return unexpected value";
201 
202   // Force writing of strile arrays
203   status_or_int = api.TIFFSetDirectory(&tif, 0);
204   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetDirectory fatal error";
205   EXPECT_THAT(status_or_int.value(), IsTrue())
206       << "TIFFSetDirectory return unexpected value";
207 
208   status_or_int = api.TIFFForceStrileArrayWriting(&tif);
209   ASSERT_THAT(status_or_int, IsOk())
210       << "TIFFForceStrileArrayWriting fatal error";
211   EXPECT_THAT(status_or_int.value(), IsTrue())
212       << "TIFFForceStrileArrayWriting return unexpected value";
213 
214   status_or_int = api.TIFFSetDirectory(&tif, 1);
215   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetDirectory fatal error";
216   EXPECT_THAT(status_or_int.value(), IsTrue())
217       << "TIFFSetDirectory return unexpected value";
218 
219   status_or_int = api.TIFFForceStrileArrayWriting(&tif);
220   ASSERT_THAT(status_or_int, IsOk())
221       << "TIFFForceStrileArrayWriting fatal error";
222   EXPECT_THAT(status_or_int.value(), IsTrue())
223       << "TIFFForceStrileArrayWriting return unexpected value";
224 
225   // Now write data on frist directory
226   status_or_int = api.TIFFSetDirectory(&tif, 0);
227   ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetDirectory fatal error";
228   EXPECT_THAT(status_or_int.value(), IsTrue())
229       << "TIFFSetDirectory return unexpected value";
230 
231   if (tiled) {
232     for (int i = 0; i < (height + 15) / 16; ++i) {
233       std::array<uint8_t, kTileBufferSize> tilebuffer;
234       tilebuffer.fill(i);
235       sapi::v::Array<uint8_t> tilebuffer_(tilebuffer.data(), kTileBufferSize);
236 
237       status_or_int = api.TIFFWriteEncodedTile(&tif, i, tilebuffer_.PtrBoth(),
238                                                kTileBufferSize);
239       ASSERT_THAT(status_or_int, IsOk()) << "TIFFWriteEncodedTile fatal error";
240       EXPECT_THAT(status_or_int.value(), Eq(kTileBufferSize))
241           << "line " << i << ": expected 256, got " << status_or_int.value();
242     }
243   } else {
244     for (int i = 0; i < height; ++i) {
245       sapi::v::UChar c(i);
246       status_or_long = api.TIFFWriteEncodedStrip(&tif, i, c.PtrBoth(), 1);
247       ASSERT_THAT(status_or_long, IsOk())
248           << "TIFFWriteEncodedStrip fatal error";
249       EXPECT_THAT(status_or_int.value(), Eq(1))
250           << "line " << i << ": expected 1, got " << status_or_int.value();
251 
252       if (i == 1 && height > 100000) {
253         i = height - 2;
254       }
255     }
256   }
257 
258   ASSERT_THAT(api.TIFFClose(&tif), IsOk()) << "TIFFClose fatal error";
259 
260   sapi::v::ConstCStr r_var("r");
261   status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore());
262   ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile;
263 
264   sapi::v::RemotePtr tif2(status_or_tif.value());
265   ASSERT_THAT(tif2.GetValue(), NotNull()) << "can't open " << srcfile;
266 
267   if (tiled) {
268     for (int i = 0; i < (height + 15) / 16; ++i) {
269       for (int retry = 0; retry < 2; ++retry) {
270         std::array<uint8_t, kTileBufferSize> tilebuffer;
271         auto expected_c = static_cast<uint8_t>(i);
272         tilebuffer.fill(0);
273 
274         sapi::v::Array<uint8_t> tilebuffer_(tilebuffer.data(), kTileBufferSize);
275         status_or_long = api.TIFFReadEncodedTile(
276             &tif2, i, tilebuffer_.PtrBoth(), kTileBufferSize);
277         ASSERT_THAT(status_or_long, IsOk())
278             << "TIFFReadEncodedTile fatal error";
279         EXPECT_THAT(status_or_long.value(), Eq(kTileBufferSize))
280             << "line " << i << ": expected 256, got " << status_or_long.value();
281 
282         bool cmp = tilebuffer[0] != expected_c || tilebuffer[255] != expected_c;
283 
284         EXPECT_THAT(tilebuffer[0], Eq(expected_c))
285             << "unexpected value at tile " << i << ": expected " << expected_c
286             << ", got " << tilebuffer[0];
287 
288         EXPECT_THAT(tilebuffer[255], Eq(expected_c))
289             << "unexpected value at tile " << i << ": expected " << expected_c
290             << ", got " << tilebuffer[255];
291         if (cmp) {
292           ASSERT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error";
293         }
294       }
295     }
296   } else {
297     for (int i = 0; i < height; ++i) {
298       for (int retry = 0; retry < 2; ++retry) {
299         sapi::v::UChar c(0);
300         auto expected_c = static_cast<uint8_t>(i);
301 
302         status_or_long = api.TIFFReadEncodedStrip(&tif2, i, c.PtrBoth(), 1);
303         ASSERT_THAT(status_or_long, IsOk())
304             << "TIFFReadEncodedStrip fatal error";
305         EXPECT_THAT(status_or_long.value(), Eq(1))
306             << "line " << i << ": expected 1, got " << status_or_long.value();
307         EXPECT_THAT(c.GetValue(), Eq(expected_c))
308             << "unexpected value at line " << i << ": expected " << expected_c
309             << ", got " << c.GetValue();
310 
311         if (c.GetValue() != expected_c) {
312           ASSERT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error";
313         }
314       }
315     }
316   }
317 
318   ASSERT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error";
319 
320   unlink(srcfile.c_str());
321 }
322 
TEST(SandboxTest,DeferStrileWriting)323 TEST(SandboxTest, DeferStrileWriting) {
324   for (int tiled = 0; tiled <= 1; ++tiled) {
325     TestWriting("w", tiled, 1);
326     TestWriting("w", tiled, 10);
327     TestWriting("w8", tiled, 1);
328     TestWriting("wD", tiled, 1);
329   }
330 }
331 
332 }  // namespace
333