• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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