1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <ImageHashManager.h>
18 #include <android-base/file.h>
19 #include <gtest/gtest.h>
20 #include <pHash/phash_fingerprinter.h>
21
22 namespace android {
23 class ImageHashManagerTest : public ::testing::Test {};
24
25 namespace {
26
convert1ByteBufferTo4Bytes(const uint8_t * buffer)27 static std::array<uint8_t, kImageSize * 4> convert1ByteBufferTo4Bytes(const uint8_t* buffer) {
28 std::array<uint8_t, kImageSize * 4> newBuffer;
29 for (int i = 0; i < kImageSize; i++) {
30 const uint8_t* p = buffer + i;
31 size_t index = i * 4;
32 newBuffer[index] = *p;
33 newBuffer[index + 1] = *p;
34 newBuffer[index + 2] = *p;
35 newBuffer[index + 3] = 0xFF;
36 }
37 return newBuffer;
38 }
39
GetTestDataPath(const std::string & fn)40 std::string GetTestDataPath(const std::string& fn) {
41 static std::string exec_dir = android::base::GetExecutableDirectory();
42 return exec_dir + "/test_data/" + fn;
43 }
44
NewFrameFromJpeg(const char * filename)45 std::string NewFrameFromJpeg(const char* filename) {
46 // Read the jpeg file
47 const std::string full_filename = GetTestDataPath(filename);
48 std::string raw_data;
49 EXPECT_TRUE(base::ReadFileToString(full_filename, &raw_data));
50 return raw_data;
51 }
52
GetFingerprint(const char * filename)53 int64_t GetFingerprint(const char* filename) {
54 const auto frame = NewFrameFromJpeg(filename);
55 PhashFingerprinter fingerprinter;
56 return fingerprinter.GenerateFingerprint(reinterpret_cast<const uint8_t*>(frame.c_str()));
57 }
58
TEST(ImageHashManagerTest,ShouldGenerateFingerprintCorrectly)59 TEST(ImageHashManagerTest, ShouldGenerateFingerprintCorrectly) {
60 ASSERT_EQ(5241969330366601001LL, GetFingerprint("120.jpg.raw"));
61 ASSERT_EQ(6191181876346691487LL, GetFingerprint("124.jpg.raw"));
62 ASSERT_EQ(5902951508784914335LL, GetFingerprint("125.jpg.raw"));
63 ASSERT_EQ(5015741588639023054LL, GetFingerprint("126.jpg.raw"));
64 }
65
CreatePHash(const char * filename)66 int64_t CreatePHash(const char* filename) {
67 const auto frame = NewFrameFromJpeg(filename);
68 std::array<uint8_t, 8> outImageHash;
69 const auto buffer = reinterpret_cast<const uint8_t*>(frame.c_str());
70 const auto expandedBuffer = convert1ByteBufferTo4Bytes(buffer);
71
72 int32_t status = ImageHashManager::generatePHash(expandedBuffer.data(), 2, 2, 2, &outImageHash);
73 EXPECT_EQ(-EINVAL, status); // should fail due to wrong size
74
75 status = ImageHashManager::generatePHash(expandedBuffer.data(), 32, 32, 32, &outImageHash);
76 EXPECT_EQ(0, status); // should success
77 return *reinterpret_cast<const int64_t*>(outImageHash.data());
78 }
79
TEST(ImageHashManagerTest,ShouldCreatePHashCorrectly)80 TEST(ImageHashManagerTest, ShouldCreatePHashCorrectly) {
81 ASSERT_EQ(5241969330366601001LL, CreatePHash("120.jpg.raw"));
82 ASSERT_EQ(6191181876346691487LL, CreatePHash("124.jpg.raw"));
83 ASSERT_EQ(5902951508784914335LL, CreatePHash("125.jpg.raw"));
84 ASSERT_EQ(5015741588639023054LL, CreatePHash("126.jpg.raw"));
85 }
86
TEST(ImageHashManagerTest,TestGenerateHashWithPhash)87 TEST(ImageHashManagerTest, TestGenerateHashWithPhash) {
88 const auto frame = NewFrameFromJpeg("120.jpg.raw");
89 std::array<uint8_t, 8> outImageHash;
90 const auto buffer = reinterpret_cast<const uint8_t*>(frame.c_str());
91 auto expandedBuffer = convert1ByteBufferTo4Bytes(buffer);
92
93 AHardwareBuffer_Desc desc = {
94 .width = 32,
95 .height = 32,
96 .layers = 1,
97 .format = AHARDWAREBUFFER_FORMAT_BLOB,
98 .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
99 };
100
101 int32_t status =
102 ImageHashManager::generateHash("phash", expandedBuffer.data(), desc, &outImageHash);
103 EXPECT_EQ(0, status); // should succeed
104
105 ASSERT_EQ(5241969330366601001LL, *reinterpret_cast<const int64_t*>(outImageHash.data()));
106 }
107
TEST(ImageHashManagerTest,TestGenerateHashWithInvalidHash)108 TEST(ImageHashManagerTest, TestGenerateHashWithInvalidHash) {
109 const auto frame = NewFrameFromJpeg("120.jpg.raw");
110 std::array<uint8_t, 8> outImageHash;
111 const auto buffer = reinterpret_cast<const uint8_t*>(frame.c_str());
112 auto expandedBuffer = convert1ByteBufferTo4Bytes(buffer);
113
114 AHardwareBuffer_Desc desc = {
115 .width = 32,
116 .height = 32,
117 .layers = 1,
118 .format = AHARDWAREBUFFER_FORMAT_BLOB,
119 .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
120 };
121
122 int32_t status =
123 ImageHashManager::generateHash("fakeHash", expandedBuffer.data(), desc, &outImageHash);
124 EXPECT_EQ(-EINVAL, status); // should fail
125 }
126
127 } // namespace
128
129 } // namespace android
130