pdqhash-go

git clone git://archive.git.mtrnord.blog/MTRNord/pdqhash-go.git
Log | Files | Refs | LICENSE

commit fed35bf1bf1a41a79809467ba475fd5c05618cc1
parent 211b265894602ff90f99236023e8d4c3030389a5
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sun, 25 Feb 2024 14:49:29 +0100

Add more tests and some minor cleanup and a fix

Diffstat:
Mcmd/scanner.go | 13++++++++++---
Acmd/scanner_test.go | 24++++++++++++++++++++++++
Mhelpers/helpers_test.go | 6++++++
Mpdq_hasher.go | 4++--
Mpdq_hasher_test.go | 25+++++++++++++++++++++++++
Mtypes/hash256.go | 8--------
6 files changed, 67 insertions(+), 13 deletions(-)

diff --git a/cmd/scanner.go b/cmd/scanner.go @@ -15,12 +15,15 @@ import ( // This is an example. It is not meant to be run in prod. -func processFolder(filename string, detailed bool) { +func processFolder(filename string, detailed bool) error { pdqhasher := pdq.NewPDQHasher() numPDQHash := 0 var prevHash *types.Hash256 - filepath.Walk(filename, func(fullPath string, item os.FileInfo, err error) error { + err := filepath.Walk(filename, func(fullPath string, item os.FileInfo, err error) error { + if err != nil { + return err + } if !item.IsDir() { // Check if file is an image filetypeRef, err := filetype.MatchFile(fullPath) @@ -48,6 +51,7 @@ func processFolder(filename string, detailed bool) { } return nil }) + return err } func processFile(filename string, detailed bool) { @@ -100,6 +104,9 @@ func main() { if !fileInfo.IsDir() { processFile(folder, detailedOutput) } else { - processFolder(folder, detailedOutput) + err := processFolder(folder, detailedOutput) + if err != nil { + log.Fatal(err) + } } } diff --git a/cmd/scanner_test.go b/cmd/scanner_test.go @@ -0,0 +1,24 @@ +package main + +import ( + "testing" + + "github.com/davidbyttow/govips/v2/vips" + "github.com/stretchr/testify/assert" +) + +func TestProcessFolder(t *testing.T) { + vips.LoggingSettings(nil, vips.LogLevelMessage) + vips.Startup(&vips.Config{ + ConcurrencyLevel: 0, + MaxCacheFiles: 5, + MaxCacheMem: 50 * 1024 * 1024, + MaxCacheSize: 100, + ReportLeaks: false, + CacheTrace: false, + CollectStats: false, + }) + defer vips.Shutdown() + err := processFolder("../test-images", true) + assert.ErrorIs(t, err, nil) +} diff --git a/helpers/helpers_test.go b/helpers/helpers_test.go @@ -19,3 +19,9 @@ func TestTorben(t *testing.T) { assert.Equal(t, float64(1.07), Torben(m, numRows, numCols), "The Torben function should produce 1.07 for 3 rows and 8 cols") } + +func TestAbs(t *testing.T) { + assert.Equal(t, int(1), Abs(-1), "The absolute value of -1 should be 1") + assert.Equal(t, int(1), Abs(1), "The absolute value of 1 should be 1") + assert.Equal(t, int(0), Abs(0), "The absolute value of 0 should be 0") +} diff --git a/pdq_hasher.go b/pdq_hasher.go @@ -182,7 +182,7 @@ func (p *PDQHasher) pdqHash256FromFloatLuma(fullBuffer1, fullBuffer2 []float64, return HashAndQuality{hash, quality} } -func (p *PDQHasher) dihedralFromFile(filename string, dihedralFlags int) HashesAndQuality { +func (p *PDQHasher) DihedralFromFile(filename string, dihedralFlags int) HashesAndQuality { image, err := vips.NewImageFromFile(filename) if err != nil { log.Fatalf("Error opening file: %v", err) @@ -431,7 +431,7 @@ func (p *PDQHasher) dct16OriginalToFlipY(A, B *[][]float64) { func (p *PDQHasher) dct16OriginalToFlipPlus1(A, B *[][]float64) { for i := 0; i < 16; i++ { for j := 0; j < 16; j++ { - (*B)[i][j] = (*A)[i][j] + (*B)[j][i] = (*A)[i][j] } } } diff --git a/pdq_hasher_test.go b/pdq_hasher_test.go @@ -122,3 +122,28 @@ func TestPDQHasher(t *testing.T) { assert.LessOrEqualf(t, hammingDistance, hammingTolerance, "Hamming distance is too high: %s", imagePath) } } + +func TestPDQHasherDehidral(t *testing.T) { + vips.LoggingSettings(nil, vips.LogLevelMessage) + vips.Startup(&vips.Config{ + ConcurrencyLevel: 0, + MaxCacheFiles: 5, + MaxCacheMem: 50 * 1024 * 1024, + MaxCacheSize: 100, + ReportLeaks: false, + CacheTrace: false, + CollectStats: false, + }) + defer vips.Shutdown() + pdqHasher := NewPDQHasher() + hashes := pdqHasher.DihedralFromFile("./test-images/reg-test-input/labelme-subset/q0004.jpg", PDQ_DO_DIH_ALL) + + assert.Equal(t, hashes.hash.String(), "992d44af36d69e6ca6b812585928bac11def254ef5398c6d07466c9abcc65b92") + assert.Equal(t, hashes.hashRotate90.String(), "9b323dd22976484c939787013f096d1669874a21dab0d3dadef50f2560cf3e4f") + assert.Equal(t, hashes.hashRotate180.String(), "8c78ee05e38335c6f3edf8f28e7d106b48ba8fe4a06c16c71213c670e993f138") + assert.Equal(t, hashes.hashRotate270.String(), "c86783787c23e2e6c6c22dab685cc7bc3cd2608b8fe579708ba0a58f359a94e5") + assert.Equal(t, hashes.hashFlipX.String(), "d92dbb5036d62093a6b82da75928453e1defdab1f539439247469325bcc6a465") + assert.Equal(t, hashes.hashFlipY.String(), "8c3811fa6383ca39f3ed470d8e7def9448ba701ba06ce9381213398fe9930ecf") + assert.Equal(t, hashes.hashFlipPlus1.String(), "993242252966b7a3939778fe3d0982e9698735dadab02c25def4f0da60cfc1b0") + assert.Equal(t, hashes.hashFlipMinus1.String(), "ee676c877c231d19c6c2d2546a5c38433cd29f748fe5868f8ba15a70359a6b1a") +} diff --git a/types/hash256.go b/types/hash256.go @@ -15,10 +15,6 @@ type Hash256 struct { W [HASH256_NUM_SLOTS]int } -func (h *Hash256) GetNumWords() int { - return HASH256_NUM_SLOTS -} - func (h *Hash256) Clone() Hash256 { rv := Hash256{} for i := 0; i < HASH256_NUM_SLOTS; i++ { @@ -37,10 +33,6 @@ func (h *Hash256) String() string { return strings.Join(result, "") } -func (h *Hash256) ToHexString() string { - return h.String() -} - func Hash256FromHexString(s string) (*Hash256, error) { if len(s) != HASH256_HEX_NUM_NYBBLES { return nil, fmt.Errorf("incorrect hash length: %s", s)