mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
rewtite pixels and clusters check for clarify. sapi::StatusOr -> absl::StatusOr (building problems). resolved review issues
This commit is contained in:
parent
6497a40bff
commit
b6abae3356
@ -23,22 +23,46 @@
|
||||
#include "sandboxed_api/vars.h"
|
||||
#include "tiffio.h" // NOLINT(build/include)
|
||||
|
||||
constexpr std::array<uint8_t, 6> kCluster0 = {0, 0, 2, 0, 138, 139};
|
||||
constexpr std::array<uint8_t, 6> kCluster64 = {0, 0, 9, 6, 134, 119};
|
||||
constexpr std::array<uint8_t, 6> kCluster128 = {44, 40, 63, 59, 230, 95};
|
||||
|
||||
constexpr unsigned kRawTileNumber = 9;
|
||||
|
||||
namespace {
|
||||
|
||||
absl::Status CheckCluster(int cluster, const sapi::v::Array<uint8_t>& buffer,
|
||||
const std::array<uint8_t, 6>& expected_cluster) {
|
||||
if (buffer.GetSize() <= cluster * 6) {
|
||||
struct ChannelLimits {
|
||||
uint8_t min_red;
|
||||
uint8_t max_red;
|
||||
uint8_t min_green;
|
||||
uint8_t max_green;
|
||||
uint8_t min_blue;
|
||||
uint8_t max_blue;
|
||||
uint8_t min_alpha;
|
||||
uint8_t max_alpha;
|
||||
};
|
||||
|
||||
constexpr unsigned kRawTileNumber = 9;
|
||||
constexpr unsigned kClusterSize = 6;
|
||||
constexpr unsigned kChannelsInPixel = 3;
|
||||
constexpr unsigned kTestCount = 3;
|
||||
constexpr unsigned kImageSize = 128 * 128;
|
||||
constexpr unsigned kClusterImageSize = 64 * 64;
|
||||
using ClusterData = std::array<uint8_t, kClusterSize>;
|
||||
|
||||
constexpr std::array<std::pair<unsigned, ClusterData>, kTestCount> kClusters = {
|
||||
{{0, {0, 0, 2, 0, 138, 139}},
|
||||
{64, {0, 0, 9, 6, 134, 119}},
|
||||
{128, {44, 40, 63, 59, 230, 95}}}};
|
||||
|
||||
constexpr std::array<std::pair<unsigned, ChannelLimits>, kTestCount> kLimits = {
|
||||
{{0, {15, 18, 0, 0, 18, 41, 255, 255}},
|
||||
{64, {0, 0, 0, 0, 0, 2, 255, 255}},
|
||||
{512, {5, 6, 34, 36, 182, 196, 255, 255}}}};
|
||||
|
||||
absl::Status CheckCluster(unsigned cluster,
|
||||
const sapi::v::Array<uint8_t>& buffer,
|
||||
const ClusterData& expected_cluster) {
|
||||
if (buffer.GetSize() <= cluster * kClusterSize) {
|
||||
return absl::InternalError("Buffer overrun\n");
|
||||
}
|
||||
uint8_t* target = buffer.GetData() + cluster * 6;
|
||||
auto target = buffer.GetData() + cluster * kClusterSize;
|
||||
|
||||
if (!std::memcmp(target, expected_cluster.data(), 6)) {
|
||||
if (!std::memcmp(target, expected_cluster.data(), kClusterSize)) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
@ -51,55 +75,54 @@ absl::Status CheckCluster(int cluster, const sapi::v::Array<uint8_t>& buffer,
|
||||
target[2], "\t", target[3], "\t", target[4], "\t", target[5], "\n"));
|
||||
}
|
||||
|
||||
absl::Status CheckRgbPixel(int pixel, int min_red, int max_red, int min_green,
|
||||
int max_green, int min_blue, int max_blue,
|
||||
absl::Status CheckRgbPixel(unsigned pixel, const ChannelLimits& limits,
|
||||
const sapi::v::Array<uint8_t>& buffer) {
|
||||
if (buffer.GetSize() <= pixel * 3) {
|
||||
if (buffer.GetSize() <= pixel * kChannelsInPixel) {
|
||||
return absl::InternalError("Buffer overrun\n");
|
||||
}
|
||||
uint8_t* rgb = buffer.GetData() + 3 * pixel;
|
||||
auto rgb = buffer.GetData() + kChannelsInPixel * pixel;
|
||||
|
||||
if (rgb[0] >= min_red && rgb[0] <= max_red && rgb[1] >= min_green &&
|
||||
rgb[1] <= max_green && rgb[2] >= min_blue && rgb[2] <= max_blue) {
|
||||
if (rgb[0] >= limits.min_red && rgb[0] <= limits.max_red &&
|
||||
rgb[1] >= limits.min_green && rgb[1] <= limits.max_green &&
|
||||
rgb[2] >= limits.min_blue && rgb[2] <= limits.max_blue) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
return absl::InternalError(absl::StrCat(
|
||||
"Pixel ", pixel, " did not match expected results.\n", "Got R=", rgb[0],
|
||||
" (expected ", min_red, "..=", max_red, "), G=", rgb[1], " (expected ",
|
||||
min_green, "..=", max_green, "), B=", rgb[2], " (expected ", min_blue,
|
||||
"..=", max_blue, ")\n"));
|
||||
" (expected ", limits.min_red, "..=", limits.max_red, "), G=", rgb[1],
|
||||
" (expected ", limits.min_green, "..=", limits.max_green, "), B=", rgb[2],
|
||||
" (expected ", limits.min_blue, "..=", limits.max_blue, ")\n"));
|
||||
}
|
||||
|
||||
absl::Status CheckRgbaPixel(int pixel, int min_red, int max_red, int min_green,
|
||||
int max_green, int min_blue, int max_blue,
|
||||
int min_alpha, int max_alpha,
|
||||
absl::Status CheckRgbaPixel(unsigned pixel, const ChannelLimits& limits,
|
||||
const sapi::v::Array<unsigned>& buffer) {
|
||||
// RGBA images are upside down - adjust for normal ordering
|
||||
int adjusted_pixel = pixel % 128 + (127 - (pixel / 128)) * 128;
|
||||
unsigned adjusted_pixel = pixel % 128 + (127 - (pixel / 128)) * 128;
|
||||
|
||||
if (buffer.GetSize() <= adjusted_pixel) {
|
||||
return absl::InternalError("Buffer overrun\n");
|
||||
}
|
||||
uint32 rgba = buffer[adjusted_pixel];
|
||||
|
||||
if (TIFFGetR(rgba) >= (uint32)min_red && TIFFGetR(rgba) <= (uint32)max_red &&
|
||||
TIFFGetG(rgba) >= (uint32)min_green &&
|
||||
TIFFGetG(rgba) <= (uint32)max_green &&
|
||||
TIFFGetB(rgba) >= (uint32)min_blue &&
|
||||
TIFFGetB(rgba) <= (uint32)max_blue &&
|
||||
TIFFGetA(rgba) >= (uint32)min_alpha &&
|
||||
TIFFGetA(rgba) <= (uint32)max_alpha) {
|
||||
auto rgba = buffer[adjusted_pixel];
|
||||
if (TIFFGetR(rgba) >= static_cast<unsigned>(limits.min_red) &&
|
||||
TIFFGetR(rgba) <= static_cast<unsigned>(limits.max_red) &&
|
||||
TIFFGetG(rgba) >= static_cast<unsigned>(limits.min_green) &&
|
||||
TIFFGetG(rgba) <= static_cast<unsigned>(limits.max_green) &&
|
||||
TIFFGetB(rgba) >= static_cast<unsigned>(limits.min_blue) &&
|
||||
TIFFGetB(rgba) <= static_cast<unsigned>(limits.max_blue) &&
|
||||
TIFFGetA(rgba) >= static_cast<unsigned>(limits.min_alpha) &&
|
||||
TIFFGetA(rgba) <= static_cast<unsigned>(limits.max_alpha)) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
return absl::InternalError(absl::StrCat(
|
||||
"Pixel ", pixel, " did not match expected results.\n",
|
||||
"Got R=", TIFFGetR(rgba), " (expected ", min_red, "..=", max_red,
|
||||
"), G=", TIFFGetG(rgba), " (expected ", min_green, "..=", max_green,
|
||||
"), B=", TIFFGetB(rgba), " (expected ", min_blue, "..=", max_blue,
|
||||
"), A=", TIFFGetA(rgba), " (expected ", min_alpha, "..=", max_alpha,
|
||||
")\n"));
|
||||
"Pixel ", pixel, " did not match expected results.\n", "Got R=",
|
||||
TIFFGetR(rgba), " (expected ", limits.min_red, "..=", limits.max_red,
|
||||
"), G=", TIFFGetG(rgba), " (expected ", limits.min_green,
|
||||
"..=", limits.max_green, "), B=", TIFFGetB(rgba), " (expected ",
|
||||
limits.min_blue, "..=", limits.max_blue, "), A=", TIFFGetA(rgba),
|
||||
" (expected ", limits.min_alpha, "..=", limits.max_alpha, ")\n"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -128,17 +151,22 @@ std::string GetFilePath(const std::string filename) {
|
||||
}
|
||||
|
||||
absl::Status LibTIFFMain(const std::string& srcfile) {
|
||||
// without addDir to sandbox. to add dir use
|
||||
// sandbox(absolute_path_to_dir, srcfile) or
|
||||
// sandbox(absolute_path_to_dir). file and dir should be exists.
|
||||
// srcfile must also be absolute_path_to_file
|
||||
// to use dir and file inside sapi-libtiff, use
|
||||
// sandbox(file) – file only -- or
|
||||
// sandbox(file, dir) -- file and dir -- or
|
||||
// sandbox(nullopt, dir) -- dir only.
|
||||
// file and directory must exist.
|
||||
// all paths must be absolute.
|
||||
|
||||
TiffSapiSandbox sandbox(srcfile);
|
||||
|
||||
bool pixel_status = true;
|
||||
bool cluster_status = true;
|
||||
// initialize sapi vars after constructing TiffSapiSandbox
|
||||
sapi::v::UShort h, v;
|
||||
sapi::StatusOr<TIFF*> status_or_tif;
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
sapi::StatusOr<tmsize_t> status_or_long;
|
||||
absl::StatusOr<TIFF*> status_or_tif;
|
||||
absl::StatusOr<int> status_or_int;
|
||||
absl::StatusOr<tmsize_t> status_or_long;
|
||||
absl::Status status;
|
||||
|
||||
status = sandbox.Init();
|
||||
@ -154,7 +182,6 @@ absl::Status LibTIFFMain(const std::string& srcfile) {
|
||||
|
||||
sapi::v::RemotePtr tif(status_or_tif.value());
|
||||
if (!tif.GetValue()) {
|
||||
// tif is NULL
|
||||
return absl::InternalError(absl::StrCat("Could not open ", srcfile));
|
||||
}
|
||||
|
||||
@ -166,8 +193,10 @@ absl::Status LibTIFFMain(const std::string& srcfile) {
|
||||
}
|
||||
|
||||
SAPI_ASSIGN_OR_RETURN(tsize_t sz, api.TIFFTileSize(&tif));
|
||||
if (sz != 24576) {
|
||||
return absl::InternalError(absl::StrCat("tiles are ", sz, " bytes\n"));
|
||||
if (sz != kClusterSize * kClusterImageSize) {
|
||||
return absl::InternalError(
|
||||
absl::StrCat("Unexpected TileSize ", sz, ". Expected ",
|
||||
kClusterSize * kClusterImageSize, " bytes\n"));
|
||||
}
|
||||
|
||||
sapi::v::Array<uint8_t> buffer_(sz);
|
||||
@ -181,36 +210,29 @@ absl::Status LibTIFFMain(const std::string& srcfile) {
|
||||
status_or_long.value(), " instead of ", sz));
|
||||
}
|
||||
|
||||
bool pixel_status = true;
|
||||
if (status = CheckCluster(0, buffer_, kCluster0); !status.ok()) {
|
||||
LOG(ERROR) << "CheckCluster failed:\n" << status.ToString();
|
||||
for (const auto& [id, data] : kClusters) {
|
||||
if (status = CheckCluster(id, buffer_, data); !status.ok()) {
|
||||
LOG(ERROR) << "CheckCluster failed:\n" << status.ToString();
|
||||
}
|
||||
cluster_status &= status.ok();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
|
||||
if (status = CheckCluster(64, buffer_, kCluster64); !status.ok()) {
|
||||
LOG(ERROR) << "CheckCluster failed:\n" << status.ToString();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
|
||||
if (status = CheckCluster(128, buffer_, kCluster128); !status.ok()) {
|
||||
LOG(ERROR) << "CheckCluster failed:\n" << status.ToString();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
|
||||
if (!pixel_status) {
|
||||
return absl::InternalError("unexpected pixel_status value");
|
||||
if (!cluster_status) {
|
||||
return absl::InternalError("One or more clusters failed the check");
|
||||
}
|
||||
|
||||
SAPI_ASSIGN_OR_RETURN(
|
||||
status_or_int,
|
||||
return_value,
|
||||
api.TIFFSetFieldU1(&tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB));
|
||||
if (return_value == 0) {
|
||||
return absl::InternalError("TIFFSetFieldU1 not available");
|
||||
return absl::InternalError("The JPEGCOLORMODE tag cannot be changed");
|
||||
}
|
||||
|
||||
SAPI_ASSIGN_OR_RETURN(sz, api.TIFFTileSize(&tif));
|
||||
if (sz != 128 * 128 * 3) {
|
||||
return absl::InternalError(absl::StrCat("tiles are ", sz, " bytes"));
|
||||
if (sz != kChannelsInPixel * kImageSize) {
|
||||
return absl::InternalError(
|
||||
absl::StrCat("Unexpected TileSize ", sz, ". Expected ",
|
||||
kChannelsInPixel * kImageSize, " bytes\n"));
|
||||
}
|
||||
|
||||
sapi::v::Array<uint8_t> buffer2_(sz);
|
||||
@ -224,23 +246,12 @@ absl::Status LibTIFFMain(const std::string& srcfile) {
|
||||
" instead of ", sz));
|
||||
}
|
||||
|
||||
pixel_status = true;
|
||||
// Checking specific pixels from the test data, 0th, 64th and 512th
|
||||
if (status = CheckRgbPixel(0, 15, 18, 0, 0, 18, 41, buffer2_); !status.ok()) {
|
||||
LOG(ERROR) << "CheckRgbPixel failed:\n" << status.ToString();
|
||||
for (const auto& [id, data] : kLimits) {
|
||||
if (status = CheckRgbPixel(id, data, buffer2_); !status.ok()) {
|
||||
LOG(ERROR) << "CheckRgbPixel failed:\n" << status.ToString();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
|
||||
if (status = CheckRgbPixel(64, 0, 0, 0, 0, 0, 2, buffer2_); !status.ok()) {
|
||||
LOG(ERROR) << "CheckRgbPixel failed:\n" << status.ToString();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
|
||||
if (status = CheckRgbPixel(512, 5, 6, 34, 36, 182, 196, buffer2_);
|
||||
!status.ok()) {
|
||||
LOG(ERROR) << "CheckRgbPixel failed:\n" << status.ToString();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
|
||||
SAPI_RETURN_IF_ERROR(api.TIFFClose(&tif));
|
||||
|
||||
@ -252,7 +263,7 @@ absl::Status LibTIFFMain(const std::string& srcfile) {
|
||||
return absl::InternalError(absl::StrCat("Could not reopen ", srcfile));
|
||||
}
|
||||
|
||||
sapi::v::Array<uint32> rgba_buffer_(128 * 128);
|
||||
sapi::v::Array<unsigned> rgba_buffer_(kImageSize);
|
||||
|
||||
// read as rgba
|
||||
SAPI_ASSIGN_OR_RETURN(
|
||||
@ -263,29 +274,17 @@ absl::Status LibTIFFMain(const std::string& srcfile) {
|
||||
}
|
||||
|
||||
// Checking specific pixels from the test data, 0th, 64th and 512th
|
||||
if (status = CheckRgbaPixel(0, 15, 18, 0, 0, 18, 41, 255, 255, rgba_buffer_);
|
||||
!status.ok()) {
|
||||
LOG(ERROR) << "CheckRgbaPixel failed:\n" << status.ToString();
|
||||
for (const auto& [id, data] : kLimits) {
|
||||
if (status = CheckRgbaPixel(id, data, rgba_buffer_); !status.ok()) {
|
||||
LOG(ERROR) << "CheckRgbaPixel failed:\n" << status.ToString();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
|
||||
if (status = CheckRgbaPixel(64, 0, 0, 0, 0, 0, 2, 255, 255, rgba_buffer_);
|
||||
!status.ok()) {
|
||||
LOG(ERROR) << "CheckRgbaPixel failed:\n" << status.ToString();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
|
||||
if (status =
|
||||
CheckRgbaPixel(512, 5, 6, 34, 36, 182, 196, 255, 255, rgba_buffer_);
|
||||
!status.ok()) {
|
||||
LOG(ERROR) << "CheckRgbaPixel failed:\n" << status.ToString();
|
||||
}
|
||||
pixel_status &= status.ok();
|
||||
|
||||
SAPI_RETURN_IF_ERROR(api.TIFFClose(&tif2));
|
||||
|
||||
if (!pixel_status) {
|
||||
return absl::InternalError("unexpected pixel_status value");
|
||||
return absl::InternalError("wrong encoding");
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
|
@ -18,12 +18,8 @@
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include "sandboxed_api/util/flag.h"
|
||||
#include "tiff_sapi.sapi.h"
|
||||
|
||||
ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all);
|
||||
ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all_and_log);
|
||||
|
||||
namespace {
|
||||
|
||||
class TiffSapiSandbox : public TiffSandbox {
|
||||
|
@ -17,7 +17,7 @@
|
||||
void CheckShortField(TiffApi& api, sapi::v::RemotePtr& tif, const ttag_t field,
|
||||
const uint16_t value) {
|
||||
sapi::v::UShort tmp(123);
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
absl::StatusOr<int> status_or_int;
|
||||
|
||||
status_or_int = api.TIFFGetField1(&tif, field, tmp.PtrBoth());
|
||||
ASSERT_THAT(status_or_int, IsOk()) << "TIFFGetField1 fatal error";
|
||||
@ -32,7 +32,7 @@ void CheckShortPairedField(TiffApi& api, sapi::v::RemotePtr& tif,
|
||||
const std::array<uint16_t, 2>& values) {
|
||||
sapi::v::UShort tmp0(123);
|
||||
sapi::v::UShort tmp1(456);
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
absl::StatusOr<int> status_or_int;
|
||||
|
||||
status_or_int =
|
||||
api.TIFFGetField2(&tif, field, tmp0.PtrBoth(), tmp1.PtrBoth());
|
||||
@ -48,7 +48,7 @@ void CheckShortPairedField(TiffApi& api, sapi::v::RemotePtr& tif,
|
||||
void CheckLongField(TiffApi& api, sapi::v::RemotePtr& tif, const ttag_t field,
|
||||
const unsigned value) {
|
||||
sapi::v::UInt tmp(123);
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
absl::StatusOr<int> status_or_int;
|
||||
|
||||
status_or_int = api.TIFFGetField1(&tif, field, tmp.PtrBoth());
|
||||
ASSERT_THAT(status_or_int, IsOk()) << "TIFFGetField1 fatal error";
|
||||
|
@ -26,16 +26,16 @@ constexpr uint16_t kRowsPerStrip = 1;
|
||||
constexpr uint16_t kSamplePerPixel = 1;
|
||||
|
||||
void TestWriting(const char* mode, int tiled, int height) {
|
||||
sapi::StatusOr<std::string> status_or_path =
|
||||
absl::StatusOr<std::string> status_or_path =
|
||||
sandbox2::CreateNamedTempFileAndClose("defer_strile_writing.tif");
|
||||
ASSERT_THAT(status_or_path, IsOk()) << "Could not create temp file";
|
||||
|
||||
std::string srcfile = sandbox2::file::JoinPath(
|
||||
sandbox2::file_util::fileops::GetCWD(), status_or_path.value());
|
||||
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
sapi::StatusOr<signed long> status_or_long;
|
||||
sapi::StatusOr<TIFF*> status_or_tif;
|
||||
absl::StatusOr<int> status_or_int;
|
||||
absl::StatusOr<signed long> status_or_long;
|
||||
absl::StatusOr<TIFF*> status_or_tif;
|
||||
|
||||
TiffSapiSandbox sandbox(srcfile);
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||
|
@ -14,8 +14,6 @@
|
||||
|
||||
#include "helper.h"
|
||||
|
||||
static std::string* g_in_dir = nullptr;
|
||||
|
||||
std::string GetImagesDir() {
|
||||
std::string cwd = sandbox2::file_util::fileops::GetCWD();
|
||||
auto find = cwd.rfind("/build");
|
||||
@ -30,6 +28,7 @@ std::string GetImagesDir() {
|
||||
}
|
||||
|
||||
std::string GetFilePath(const std::string& filename) {
|
||||
static std::string* g_in_dir = nullptr;
|
||||
if (!g_in_dir) {
|
||||
g_in_dir = new std::string(GetImagesDir());
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ constexpr unsigned kBps = 8;
|
||||
constexpr unsigned kRowsPerStrip = 1;
|
||||
|
||||
TEST(SandboxTest, LongTag) {
|
||||
sapi::StatusOr<std::string> status_or_path =
|
||||
absl::StatusOr<std::string> status_or_path =
|
||||
sandbox2::CreateNamedTempFileAndClose("long_test.tif");
|
||||
ASSERT_THAT(status_or_path, IsOk()) << "Could not create temp file";
|
||||
|
||||
@ -48,8 +48,8 @@ TEST(SandboxTest, LongTag) {
|
||||
std::array<uint8_t, kSamplePerPixel> buffer = {0, 127, 255};
|
||||
sapi::v::Array<uint8_t> buffer_(buffer.data(), kSamplePerPixel);
|
||||
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
sapi::StatusOr<TIFF*> status_or_tif;
|
||||
absl::StatusOr<int> status_or_int;
|
||||
absl::StatusOr<TIFF*> status_or_tif;
|
||||
|
||||
TiffApi api(&sandbox);
|
||||
sapi::v::ConstCStr srcfile_var(srcfile.c_str());
|
||||
|
@ -21,24 +21,47 @@
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr std::array<uint8_t, 6> kCluster0 = {0, 0, 2, 0, 138, 139};
|
||||
constexpr std::array<uint8_t, 6> kCluster64 = {0, 0, 9, 6, 134, 119};
|
||||
constexpr std::array<uint8_t, 6> kCluster128 = {44, 40, 63, 59, 230, 95};
|
||||
struct ChannelLimits {
|
||||
uint8_t min_red;
|
||||
uint8_t max_red;
|
||||
uint8_t min_green;
|
||||
uint8_t max_green;
|
||||
uint8_t min_blue;
|
||||
uint8_t max_blue;
|
||||
uint8_t min_alpha;
|
||||
uint8_t max_alpha;
|
||||
};
|
||||
|
||||
constexpr unsigned kRawTileNumber = 9;
|
||||
constexpr unsigned kClusterSize = 6;
|
||||
constexpr unsigned kChannelsInPixel = 3;
|
||||
constexpr unsigned kTestCount = 3;
|
||||
constexpr unsigned kImageSize = 128 * 128;
|
||||
constexpr unsigned kClusterImageSize = 64 * 64;
|
||||
using ClusterData = std::array<uint8_t, kClusterSize>;
|
||||
|
||||
bool CheckCluster(int cluster, const sapi::v::Array<uint8_t>& buffer,
|
||||
const std::array<uint8_t, 6>& expected_cluster) {
|
||||
bool is_overrun = (buffer.GetSize() <= cluster * 6);
|
||||
constexpr std::array<std::pair<unsigned, ClusterData>, kTestCount> kClusters = {
|
||||
{{0, {0, 0, 2, 0, 138, 139}},
|
||||
{64, {0, 0, 9, 6, 134, 119}},
|
||||
{128, {44, 40, 63, 59, 230, 95}}}};
|
||||
|
||||
constexpr std::array<std::pair<unsigned, ChannelLimits>, kTestCount> kLimits = {
|
||||
{{0, {15, 18, 0, 0, 18, 41, 255, 255}},
|
||||
{64, {0, 0, 0, 0, 0, 2, 255, 255}},
|
||||
{512, {5, 6, 34, 36, 182, 196, 255, 255}}}};
|
||||
|
||||
bool CheckCluster(unsigned cluster, const sapi::v::Array<uint8_t>& buffer,
|
||||
const ClusterData& expected_cluster) {
|
||||
bool is_overrun = (buffer.GetSize() <= cluster * kClusterSize);
|
||||
EXPECT_THAT(is_overrun, IsFalse()) << "Overrun";
|
||||
|
||||
if (is_overrun) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t* target = buffer.GetData() + cluster * 6;
|
||||
|
||||
bool comp = !(std::memcmp(target, expected_cluster.data(), 6) == 0);
|
||||
auto target = buffer.GetData() + cluster * kClusterSize;
|
||||
bool comp =
|
||||
!(std::memcmp(target, expected_cluster.data(), kClusterSize) == 0);
|
||||
|
||||
// the image is split on 6-bit clusters because it has YCbCr color format
|
||||
EXPECT_THAT(comp, IsFalse())
|
||||
@ -52,36 +75,33 @@ bool CheckCluster(int cluster, const sapi::v::Array<uint8_t>& buffer,
|
||||
return comp;
|
||||
}
|
||||
|
||||
bool CheckRgbPixel(int pixel, int min_red, int max_red, int min_green,
|
||||
int max_green, int min_blue, int max_blue,
|
||||
bool CheckRgbPixel(unsigned pixel, const ChannelLimits& limits,
|
||||
const sapi::v::Array<uint8_t>& buffer) {
|
||||
bool is_overrun = (buffer.GetSize() <= pixel * 3);
|
||||
bool is_overrun = (buffer.GetSize() <= pixel * kChannelsInPixel);
|
||||
EXPECT_THAT(is_overrun, IsFalse()) << "Overrun";
|
||||
|
||||
if (is_overrun) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t* rgb = buffer.GetData() + pixel * 3;
|
||||
|
||||
bool comp =
|
||||
!(rgb[0] >= min_red && rgb[0] <= max_red && rgb[1] >= min_green &&
|
||||
rgb[1] <= max_green && rgb[2] >= min_blue && rgb[2] <= max_blue);
|
||||
auto rgb = buffer.GetData() + pixel * kChannelsInPixel;
|
||||
bool comp = !(rgb[0] >= limits.min_red && rgb[0] <= limits.max_red &&
|
||||
rgb[1] >= limits.min_green && rgb[1] <= limits.max_green &&
|
||||
rgb[2] >= limits.min_blue && rgb[2] <= limits.max_blue);
|
||||
|
||||
EXPECT_THAT(comp, IsFalse())
|
||||
<< "Pixel " << pixel << " did not match expected results.\n"
|
||||
<< "Got R=" << rgb[0] << " (expected " << min_red << "..=" << max_red
|
||||
<< "), G=" << rgb[1] << " (expected " << min_green << "..=" << max_green
|
||||
<< "), B=" << rgb[2] << " (expected " << min_blue << "..=" << max_blue
|
||||
<< ")";
|
||||
<< "Got R=" << rgb[0] << " (expected " << limits.min_red
|
||||
<< "..=" << limits.max_red << "), G=" << rgb[1] << " (expected "
|
||||
<< limits.min_green << "..=" << limits.max_green << "), B=" << rgb[2]
|
||||
<< " (expected " << limits.min_blue << "..=" << limits.max_blue << ")";
|
||||
return comp;
|
||||
}
|
||||
|
||||
bool CheckRgbaPixel(int pixel, int min_red, int max_red, int min_green,
|
||||
int max_green, int min_blue, int max_blue, int min_alpha,
|
||||
int max_alpha, const sapi::v::Array<unsigned>& buffer) {
|
||||
bool CheckRgbaPixel(unsigned pixel, const ChannelLimits& limits,
|
||||
const sapi::v::Array<unsigned>& buffer) {
|
||||
// RGBA images are upside down - adjust for normal ordering
|
||||
int adjusted_pixel = pixel % 128 + (127 - (pixel / 128)) * 128;
|
||||
unsigned adjusted_pixel = pixel % 128 + (127 - (pixel / 128)) * 128;
|
||||
|
||||
bool is_overrun = (buffer.GetSize() <= adjusted_pixel);
|
||||
EXPECT_THAT(is_overrun, IsFalse()) << "Overrun";
|
||||
@ -90,40 +110,40 @@ bool CheckRgbaPixel(int pixel, int min_red, int max_red, int min_green,
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned rgba = buffer[adjusted_pixel];
|
||||
|
||||
bool comp = !(TIFFGetR(rgba) >= (unsigned)min_red &&
|
||||
TIFFGetR(rgba) <= (unsigned)max_red &&
|
||||
TIFFGetG(rgba) >= (unsigned)min_green &&
|
||||
TIFFGetG(rgba) <= (unsigned)max_green &&
|
||||
TIFFGetB(rgba) >= (unsigned)min_blue &&
|
||||
TIFFGetB(rgba) <= (unsigned)max_blue &&
|
||||
TIFFGetA(rgba) >= (unsigned)min_alpha &&
|
||||
TIFFGetA(rgba) <= (unsigned)max_alpha);
|
||||
auto rgba = buffer[adjusted_pixel];
|
||||
bool comp = !(TIFFGetR(rgba) >= static_cast<unsigned>(limits.min_red) &&
|
||||
TIFFGetR(rgba) <= static_cast<unsigned>(limits.max_red) &&
|
||||
TIFFGetG(rgba) >= static_cast<unsigned>(limits.min_green) &&
|
||||
TIFFGetG(rgba) <= static_cast<unsigned>(limits.max_green) &&
|
||||
TIFFGetB(rgba) >= static_cast<unsigned>(limits.min_blue) &&
|
||||
TIFFGetB(rgba) <= static_cast<unsigned>(limits.max_blue) &&
|
||||
TIFFGetA(rgba) >= static_cast<unsigned>(limits.min_alpha) &&
|
||||
TIFFGetA(rgba) <= static_cast<unsigned>(limits.max_alpha));
|
||||
|
||||
EXPECT_THAT(comp, IsFalse())
|
||||
<< "Pixel " << pixel << " did not match expected results.\n"
|
||||
<< "Got R=" << TIFFGetR(rgba) << " (expected " << min_red
|
||||
<< "..=" << max_red << "), G=" << TIFFGetG(rgba) << " (expected "
|
||||
<< min_green << "..=" << max_green << "), B=" << TIFFGetB(rgba)
|
||||
<< " (expected " << min_blue << "..=" << max_blue
|
||||
<< "), A=" << TIFFGetA(rgba) << " (expected " << min_alpha
|
||||
<< "..=" << max_alpha << ")";
|
||||
<< "Got R=" << TIFFGetR(rgba) << " (expected " << limits.min_red
|
||||
<< "..=" << limits.max_red << "), G=" << TIFFGetG(rgba) << " (expected "
|
||||
<< limits.min_green << "..=" << limits.max_green
|
||||
<< "), B=" << TIFFGetB(rgba) << " (expected " << limits.min_blue
|
||||
<< "..=" << limits.max_blue << "), A=" << TIFFGetA(rgba) << " (expected "
|
||||
<< limits.min_alpha << "..=" << limits.max_alpha << ")";
|
||||
return comp;
|
||||
}
|
||||
|
||||
TEST(SandboxTest, RawDecode) {
|
||||
tsize_t sz;
|
||||
bool pixel_status = false;
|
||||
bool cluster_status = false;
|
||||
std::string srcfile = GetFilePath("quad-tile.jpg.tiff");
|
||||
|
||||
TiffSapiSandbox sandbox(srcfile);
|
||||
ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
|
||||
|
||||
tsize_t sz;
|
||||
bool pixel_status = false;
|
||||
sapi::v::UShort h, v;
|
||||
sapi::StatusOr<TIFF*> status_or_tif;
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
sapi::StatusOr<tmsize_t> status_or_long;
|
||||
absl::StatusOr<TIFF*> status_or_tif;
|
||||
absl::StatusOr<int> status_or_int;
|
||||
absl::StatusOr<tmsize_t> status_or_long;
|
||||
|
||||
TiffApi api(&sandbox);
|
||||
sapi::v::ConstCStr srcfile_var(srcfile.c_str());
|
||||
@ -146,8 +166,9 @@ TEST(SandboxTest, RawDecode) {
|
||||
|
||||
status_or_long = api.TIFFTileSize(&tif);
|
||||
ASSERT_THAT(status_or_int, IsOk()) << "TIFFTileSize fatal error";
|
||||
EXPECT_THAT(status_or_long.value(), Eq(24576))
|
||||
<< "tiles are " << status_or_long.value() << " bytes";
|
||||
EXPECT_THAT(status_or_long.value(), Eq(kClusterImageSize * kClusterSize))
|
||||
<< "Unexpected TileSize " << status_or_long.value() << ". Expected "
|
||||
<< kClusterImageSize * kClusterSize << " bytes\n";
|
||||
sz = status_or_long.value();
|
||||
|
||||
sapi::v::Array<uint8_t> buffer_(sz);
|
||||
@ -159,21 +180,22 @@ TEST(SandboxTest, RawDecode) {
|
||||
<< "Did not get expected result code from TIFFReadEncodedTile()("
|
||||
<< (int)status_or_long.value() << " instead of " << (int)sz << ")";
|
||||
|
||||
ASSERT_FALSE(CheckCluster(0, buffer_, kCluster0) ||
|
||||
CheckCluster(64, buffer_, kCluster64) ||
|
||||
CheckCluster(128, buffer_, kCluster128))
|
||||
<< "Clusters did not match expected results";
|
||||
for (const auto& [id, data] : kClusters) {
|
||||
cluster_status |= CheckCluster(id, buffer_, data);
|
||||
}
|
||||
ASSERT_FALSE(cluster_status) << "Clusters did not match expected results";
|
||||
|
||||
status_or_int =
|
||||
api.TIFFSetFieldU1(&tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
|
||||
ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
|
||||
EXPECT_THAT(status_or_int.value(), IsTrue())
|
||||
<< "TIFFSetFieldU1 not available";
|
||||
<< "The JPEGCOLORMODE tag cannot be changed";
|
||||
|
||||
status_or_long = api.TIFFTileSize(&tif);
|
||||
ASSERT_THAT(status_or_long, IsOk()) << "TIFFTileSize fatal error";
|
||||
EXPECT_THAT(status_or_long.value(), Eq(128 * 128 * 3))
|
||||
<< "tiles are " << status_or_long.value() << " bytes";
|
||||
EXPECT_THAT(status_or_long.value(), Eq(kImageSize * kChannelsInPixel))
|
||||
<< "Unexpected TileSize " << status_or_long.value() << ". Expected "
|
||||
<< kImageSize * kChannelsInPixel << " bytes\n";
|
||||
sz = status_or_long.value();
|
||||
|
||||
sapi::v::Array<uint8_t> buffer2_(sz);
|
||||
@ -184,9 +206,9 @@ TEST(SandboxTest, RawDecode) {
|
||||
<< "Did not get expected result code from TIFFReadEncodedTile()("
|
||||
<< status_or_long.value() << " instead of " << sz;
|
||||
|
||||
pixel_status |= CheckRgbPixel(0, 15, 18, 0, 0, 18, 41, buffer2_);
|
||||
pixel_status |= CheckRgbPixel(64, 0, 0, 0, 0, 0, 2, buffer2_);
|
||||
pixel_status |= CheckRgbPixel(512, 5, 6, 34, 36, 182, 196, buffer2_);
|
||||
for (const auto& [id, data] : kLimits) {
|
||||
pixel_status |= CheckRgbPixel(id, data, buffer2_);
|
||||
}
|
||||
|
||||
ASSERT_THAT(api.TIFFClose(&tif), IsOk()) << "TIFFClose fatal error";
|
||||
|
||||
@ -197,7 +219,7 @@ TEST(SandboxTest, RawDecode) {
|
||||
ASSERT_THAT(tif2.GetValue(), NotNull())
|
||||
<< "Could not open " << srcfile << ", TIFFOpen return NULL";
|
||||
|
||||
sapi::v::Array<unsigned> rgba_buffer_(128 * 128);
|
||||
sapi::v::Array<unsigned> rgba_buffer_(kImageSize);
|
||||
|
||||
status_or_int =
|
||||
api.TIFFReadRGBATile(&tif2, 1 * 128, 2 * 128, rgba_buffer_.PtrBoth());
|
||||
@ -205,14 +227,11 @@ TEST(SandboxTest, RawDecode) {
|
||||
EXPECT_THAT(status_or_int.value(), IsTrue())
|
||||
<< "TIFFReadRGBATile() returned failure code";
|
||||
|
||||
pixel_status |=
|
||||
CheckRgbaPixel(0, 15, 18, 0, 0, 18, 41, 255, 255, rgba_buffer_);
|
||||
pixel_status |= CheckRgbaPixel(64, 0, 0, 0, 0, 0, 2, 255, 255, rgba_buffer_);
|
||||
pixel_status |=
|
||||
CheckRgbaPixel(512, 5, 6, 34, 36, 182, 196, 255, 255, rgba_buffer_);
|
||||
for (const auto& [id, data] : kLimits) {
|
||||
pixel_status |= CheckRgbaPixel(id, data, rgba_buffer_);
|
||||
}
|
||||
|
||||
EXPECT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error";
|
||||
|
||||
EXPECT_THAT(pixel_status, IsFalse()) << "wrong encoding";
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ constexpr std::array<PairedTag, 4> kShortPairedTags = {
|
||||
{TIFFTAG_YCBCRSUBSAMPLING, {2, 1}}}};
|
||||
|
||||
TEST(SandboxTest, ShortTag) {
|
||||
sapi::StatusOr<std::string> status_or_path =
|
||||
absl::StatusOr<std::string> status_or_path =
|
||||
sandbox2::CreateNamedTempFileAndClose("short_test.tif");
|
||||
ASSERT_THAT(status_or_path, IsOk()) << "Could not create temp file";
|
||||
|
||||
@ -69,8 +69,8 @@ TEST(SandboxTest, ShortTag) {
|
||||
std::array<uint8_t, kSamplePerPixel> buffer = {0, 127, 255};
|
||||
sapi::v::Array<uint8_t> buffer_(buffer.data(), kSamplePerPixel);
|
||||
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
sapi::StatusOr<TIFF*> status_or_tif;
|
||||
absl::StatusOr<int> status_or_int;
|
||||
absl::StatusOr<TIFF*> status_or_tif;
|
||||
|
||||
TiffApi api(&sandbox);
|
||||
sapi::v::ConstCStr srcfile_var(srcfile.c_str());
|
||||
|
Loading…
x
Reference in New Issue
Block a user