| /* | |
| * Copyright 2020 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #include <ImageHashManager.h> | |
| #include <android-base/file.h> | |
| #include <gtest/gtest.h> | |
| #include <pHash/phash_fingerprinter.h> | |
| namespace android { | |
| class ImageHashManagerTest : public ::testing::Test {}; | |
| namespace { | |
| static std::array<uint8_t, kImageSize * 4> convert1ByteBufferTo4Bytes(const uint8_t* buffer) { | |
| std::array<uint8_t, kImageSize * 4> newBuffer; | |
| for (int i = 0; i < kImageSize; i++) { | |
| const uint8_t* p = buffer + i; | |
| size_t index = i * 4; | |
| newBuffer[index] = *p; | |
| newBuffer[index + 1] = *p; | |
| newBuffer[index + 2] = *p; | |
| newBuffer[index + 3] = 0xFF; | |
| } | |
| return newBuffer; | |
| } | |
| std::string GetTestDataPath(const std::string& fn) { | |
| static std::string exec_dir = android::base::GetExecutableDirectory(); | |
| return exec_dir + "/test_data/" + fn; | |
| } | |
| std::string NewFrameFromJpeg(const char* filename) { | |
| // Read the jpeg file | |
| const std::string full_filename = GetTestDataPath(filename); | |
| std::string raw_data; | |
| EXPECT_TRUE(base::ReadFileToString(full_filename, &raw_data)); | |
| return raw_data; | |
| } | |
| int64_t GetFingerprint(const char* filename) { | |
| const auto frame = NewFrameFromJpeg(filename); | |
| PhashFingerprinter fingerprinter; | |
| return fingerprinter.GenerateFingerprint(reinterpret_cast<const uint8_t*>(frame.c_str())); | |
| } | |
| TEST(ImageHashManagerTest, ShouldGenerateFingerprintCorrectly) { | |
| ASSERT_EQ(5241969330366601001LL, GetFingerprint("120.jpg.raw")); | |
| ASSERT_EQ(6191181876346691487LL, GetFingerprint("124.jpg.raw")); | |
| ASSERT_EQ(5902951508784914335LL, GetFingerprint("125.jpg.raw")); | |
| ASSERT_EQ(5015741588639023054LL, GetFingerprint("126.jpg.raw")); | |
| } | |
| int64_t CreatePHash(const char* filename) { | |
| const auto frame = NewFrameFromJpeg(filename); | |
| std::array<uint8_t, 8> outImageHash; | |
| const auto buffer = reinterpret_cast<const uint8_t*>(frame.c_str()); | |
| const auto expandedBuffer = convert1ByteBufferTo4Bytes(buffer); | |
| int32_t status = ImageHashManager::generatePHash(expandedBuffer.data(), 2, 2, 2, &outImageHash); | |
| EXPECT_EQ(-EINVAL, status); // should fail due to wrong size | |
| status = ImageHashManager::generatePHash(expandedBuffer.data(), 32, 32, 32, &outImageHash); | |
| EXPECT_EQ(0, status); // should success | |
| return *reinterpret_cast<const int64_t*>(outImageHash.data()); | |
| } | |
| TEST(ImageHashManagerTest, ShouldCreatePHashCorrectly) { | |
| ASSERT_EQ(5241969330366601001LL, CreatePHash("120.jpg.raw")); | |
| ASSERT_EQ(6191181876346691487LL, CreatePHash("124.jpg.raw")); | |
| ASSERT_EQ(5902951508784914335LL, CreatePHash("125.jpg.raw")); | |
| ASSERT_EQ(5015741588639023054LL, CreatePHash("126.jpg.raw")); | |
| } | |
| TEST(ImageHashManagerTest, TestGenerateHashWithPhash) { | |
| const auto frame = NewFrameFromJpeg("120.jpg.raw"); | |
| std::array<uint8_t, 8> outImageHash; | |
| const auto buffer = reinterpret_cast<const uint8_t*>(frame.c_str()); | |
| auto expandedBuffer = convert1ByteBufferTo4Bytes(buffer); | |
| AHardwareBuffer_Desc desc = { | |
| .width = 32, | |
| .height = 32, | |
| .layers = 1, | |
| .format = AHARDWAREBUFFER_FORMAT_BLOB, | |
| .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, | |
| }; | |
| int32_t status = | |
| ImageHashManager::generateHash("phash", expandedBuffer.data(), desc, &outImageHash); | |
| EXPECT_EQ(0, status); // should succeed | |
| ASSERT_EQ(5241969330366601001LL, *reinterpret_cast<const int64_t*>(outImageHash.data())); | |
| } | |
| TEST(ImageHashManagerTest, TestGenerateHashWithInvalidHash) { | |
| const auto frame = NewFrameFromJpeg("120.jpg.raw"); | |
| std::array<uint8_t, 8> outImageHash; | |
| const auto buffer = reinterpret_cast<const uint8_t*>(frame.c_str()); | |
| auto expandedBuffer = convert1ByteBufferTo4Bytes(buffer); | |
| AHardwareBuffer_Desc desc = { | |
| .width = 32, | |
| .height = 32, | |
| .layers = 1, | |
| .format = AHARDWAREBUFFER_FORMAT_BLOB, | |
| .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, | |
| }; | |
| int32_t status = | |
| ImageHashManager::generateHash("fakeHash", expandedBuffer.data(), desc, &outImageHash); | |
| EXPECT_EQ(-EINVAL, status); // should fail | |
| } | |
| } // namespace | |
| } // namespace android |