Skip to content

Commit 27c7bbc

Browse files
committed
image/jpeg: prepare for new FDCT/IDCT implementations
Preparation for a new unencumbered implementation of fdct.go and idct.go. - Change benchmark not to allocate O(b.N) storage. - Make tests point out where differences are. - Parameterize differ tolerance. Change-Id: Id5dfee40f86de894bad72dd6178ba61ec81ea2da Reviewed-on: https://go-review.googlesource.com/c/go/+/705516 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent f15cd63 commit 27c7bbc

File tree

1 file changed

+21
-28
lines changed

1 file changed

+21
-28
lines changed

src/image/jpeg/dct_test.go

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,11 @@ import (
1313
)
1414

1515
func benchmarkDCT(b *testing.B, f func(*block)) {
16-
b.StopTimer()
17-
blocks := make([]block, 0, b.N*len(testBlocks))
18-
for i := 0; i < b.N; i++ {
19-
blocks = append(blocks, testBlocks[:]...)
20-
}
21-
b.StartTimer()
22-
for i := range blocks {
23-
f(&blocks[i])
16+
var blk block // avoid potential allocation in loop
17+
for b.Loop() {
18+
for _, blk = range testBlocks {
19+
f(&blk)
20+
}
2421
}
2522
}
2623

@@ -52,16 +49,13 @@ func TestDCT(t *testing.T) {
5249
// floats to ints.
5350
for i, b := range blocks {
5451
got, want := b, b
55-
for j := range got {
56-
got[j] = (got[j] - 128) * 8
57-
}
5852
slowFDCT(&got)
5953
slowIDCT(&got)
6054
for j := range got {
6155
got[j] = got[j]/8 + 128
6256
}
63-
if differ(&got, &want) {
64-
t.Errorf("i=%d: IDCT(FDCT)\nsrc\n%s\ngot\n%s\nwant\n%s\n", i, &b, &got, &want)
57+
if d := differ(&got, &want, 2); d >= 0 {
58+
t.Errorf("i=%d: IDCT(FDCT) (diff at %d,%d)\nsrc\n%s\ngot\n%s\nwant\n%s\n", i, d/8, d%8, &b, &got, &want)
6559
}
6660
}
6761

@@ -70,12 +64,9 @@ func TestDCT(t *testing.T) {
7064
for i, b := range blocks {
7165
got, want := b, b
7266
fdct(&got)
73-
for j := range want {
74-
want[j] = (want[j] - 128) * 8
75-
}
7667
slowFDCT(&want)
77-
if differ(&got, &want) {
78-
t.Errorf("i=%d: FDCT\nsrc\n%s\ngot\n%s\nwant\n%s\n", i, &b, &got, &want)
68+
if d := differ(&got, &want, 2); d >= 0 {
69+
t.Errorf("i=%d: FDCT (diff at %d,%d)\nsrc\n%s\ngot\n%s\nwant\n%s\n", i, d/8, d%8, &b, &got, &want)
7970
}
8071
}
8172

@@ -84,24 +75,26 @@ func TestDCT(t *testing.T) {
8475
got, want := b, b
8576
idct(&got)
8677
slowIDCT(&want)
87-
if differ(&got, &want) {
88-
t.Errorf("i=%d: IDCT\nsrc\n%s\ngot\n%s\nwant\n%s\n", i, &b, &got, &want)
78+
if d := differ(&got, &want, 2); d >= 0 {
79+
t.Errorf("i=%d: IDCT (diff at %d,%d)\nsrc\n%s\ngot\n%s\nwant\n%s\n", i, d/8, d%8, &b, &got, &want)
8980
}
9081
}
9182
}
9283

93-
// differ reports whether any pair-wise elements in b0 and b1 differ by 2 or
94-
// more. That tolerance is because there isn't a single definitive decoding of
84+
// differ reports whether any pair-wise elements in b0 and b1 differ by more than 'ok'.
85+
// That tolerance is because there isn't a single definitive decoding of
9586
// a given JPEG image, even before the YCbCr to RGB conversion; implementations
9687
// can have different IDCT rounding errors.
97-
func differ(b0, b1 *block) bool {
88+
// If there is a difference, differ returns the index of the first difference.
89+
// Otherwise it returns -1.
90+
func differ(b0, b1 *block, ok int32) int {
9891
for i := range b0 {
9992
delta := b0[i] - b1[i]
100-
if delta < -2 || +2 < delta {
101-
return true
93+
if delta < -ok || ok < delta {
94+
return i
10295
}
10396
}
104-
return false
97+
return -1
10598
}
10699

107100
// alpha returns 1 if i is 0 and returns √2 otherwise.
@@ -166,12 +159,12 @@ func slowFDCT(b *block) {
166159
sum := 0.0
167160
for y := 0; y < 8; y++ {
168161
for x := 0; x < 8; x++ {
169-
sum += alpha(u) * alpha(v) * float64(b[8*y+x]) *
162+
sum += alpha(u) * alpha(v) * float64(b[8*y+x]-128) *
170163
cosines[((2*x+1)*u)%32] *
171164
cosines[((2*y+1)*v)%32]
172165
}
173166
}
174-
dst[8*v+u] = sum / 8
167+
dst[8*v+u] = sum
175168
}
176169
}
177170
// Convert from float64 to int32.

0 commit comments

Comments
 (0)