mirror of
https://github.com/unidoc/unipdf.git
synced 2025-05-02 22:17:06 +08:00

* Prepared skeleton and basic component implementations for the jbig2 encoding. * Added Bitset. Implemented Bitmap. * Decoder with old Arithmetic Decoder * Partly working arithmetic * Working arithmetic decoder. * MMR patched. * rebuild to apache. * Working generic * Working generic * Decoded full document * Update Jenkinsfile go version [master] (#398) * Update Jenkinsfile go version * Decoded AnnexH document * Minor issues fixed. * Update README.md * Fixed generic region errors. Added benchmark. Added bitmap unpadder. Added Bitmap toImage method. * Fixed endofpage error * Added integration test. * Decoded all test files without errors. Implemented JBIG2Global. * Merged with v3 version * Fixed the EOF in the globals issue * Fixed the JBIG2 ChocolateData Decode * JBIG2 Added license information * Minor fix in jbig2 encoding. * Applied the logging convention * Cleaned unnecessary imports * Go modules clear unused imports * checked out the README.md * Moved trace to Debug. Fixed the build integrate tag in the document_decode_test.go * Initial encoder skeleton * Applied UniPDF Developer Guide. Fixed lint issues. * Cleared documentation, fixed style issues. * Added jbig2 doc.go files. Applied unipdf guide style. * Minor code style changes. * Minor naming and style issues fixes. * Minor naming changes. Style issues fixed. * Review r11 fixes. * Added JBIG2 Encoder skeleton. * Moved Document and Page to jbig2/document package. Created decoder package responsible for decoding jbig2 stream. * Implemented raster functions. * Added raster uni low test funcitons. * Added raster low test functions * untracked files on jbig2-encoder: c869089 Added raster low test functions * index on jbig2-encoder: c869089 Added raster low test functions * Added morph files. * implemented jbig2 encoder basics * JBIG2 Encoder - Generic method * Added jbig2 image encode ttests, black/white image tests * cleaned and tested jbig2 package * unfinished jbig2 classified encoder * jbig2 minor style changes * minor jbig2 encoder changes * prepared JBIG2 Encoder * Style and lint fixes * Minor changes and lints * Fixed shift unsinged value build errors * Minor naming change * Added jbig2 encode, image gondels. Fixed jbig2 decode bug. * Provided jbig2 core.DecodeGlobals function. * Fixed JBIG2Encoder `r6` revision issues. * Removed public JBIG2Encoder document. * Minor style changes * added NewJBIG2Encoder function. * fixed JBIG2Encoder 'r9' revision issues. * Cleared 'r9' commented code. * Updated ACKNOWLEDGEMENETS. Fixed JBIG2Encoder 'r10' revision issues. Co-authored-by: Gunnsteinn Hall <gunnsteinn.hall@gmail.com>
1396 lines
46 KiB
Go
1396 lines
46 KiB
Go
/*
|
|
* This file is subject to the terms and conditions defined in
|
|
* file 'LICENSE.md', which is part of this source code package.
|
|
*/
|
|
|
|
package bitmap
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/unidoc/unipdf/v3/common"
|
|
)
|
|
|
|
// BenchmarkGetComponents benchmarks the get components methods.
|
|
func BenchmarkGetComponents(b *testing.B) {
|
|
// Having a bitmap 50x22 with few different components like letters.
|
|
//
|
|
// 1 2 3 4 5 6 7
|
|
//
|
|
// 111111 11112222 22222233 33333333 44444444 44
|
|
// 01234567 89012345 67890123 45678901 23456789 01234567 89
|
|
//
|
|
// 0 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 2 00111110 01111000 00100111 11000010 00100111 10010001 00000000
|
|
// 3 00100010 01001000 00100001 00000011 00100100 10010001 00000000
|
|
// 4 00100010 01001000 00100001 00000010 10100100 10010101 00000000
|
|
// 5 00100010 01001000 00100001 00000010 01100100 10011011 00000000
|
|
// 6 00111100 01111000 00100001 00000010 00100111 10010001 00000000
|
|
// 7 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 8 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 9 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 10 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 11 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 12 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 13 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 14 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 15 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 16 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 17 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 18 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 19 00000000 00000000 00010101 01010000 00000000 00000000 00000000
|
|
// 20 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 21 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
//
|
|
//
|
|
data := []byte{
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x3E, 0x78, 0x27, 0xC2, 0x27, 0x91, 0x00,
|
|
0x22, 0x48, 0x21, 0x03, 0x24, 0x91, 0x00,
|
|
0x22, 0x48, 0x21, 0x02, 0xA4, 0x95, 0x00,
|
|
0x22, 0x48, 0x21, 0x02, 0x64, 0x9B, 0x00,
|
|
0x3C, 0x78, 0x21, 0x02, 0x27, 0x91, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x15, 0x50, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
}
|
|
bm, err := NewWithData(50, 22, data)
|
|
require.NoError(b, err)
|
|
|
|
type bmSizes struct {
|
|
name string
|
|
bm *Bitmap
|
|
size int
|
|
}
|
|
|
|
bm2, err := expandBinaryPower2(bm, 2)
|
|
require.NoError(b, err)
|
|
|
|
bm4, err := expandBinaryPower2(bm, 4)
|
|
require.NoError(b, err)
|
|
|
|
bm8, err := expandBinaryPower2(bm, 8)
|
|
require.NoError(b, err)
|
|
|
|
sizes := []*bmSizes{
|
|
{"One", bm, 1},
|
|
{"Two", bm2, 2},
|
|
{"Four", bm4, 4},
|
|
{"Eight", bm8, 8},
|
|
}
|
|
|
|
b.Run("ComponentConn", func(b *testing.B) {
|
|
w, h := 12, 8
|
|
for _, size := range sizes {
|
|
b.Run(size.name, func(b *testing.B) {
|
|
var bmB *Bitmap
|
|
maxW, maxH := w*size.size, h*size.size
|
|
for i := 0; i < b.N; i++ {
|
|
b.StopTimer()
|
|
bmB, err = copyBitmap(nil, size.bm)
|
|
require.NoError(b, err)
|
|
b.StartTimer()
|
|
|
|
_, _, err = bmB.GetComponents(ComponentConn, maxW, maxH)
|
|
assert.NoError(b, err)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
b.Run("ComponentCharacters", func(b *testing.B) {
|
|
w, h := 12, 8
|
|
for _, size := range sizes {
|
|
b.Run(size.name, func(b *testing.B) {
|
|
var bmB *Bitmap
|
|
maxW, maxH := w*size.size, h*size.size
|
|
for i := 0; i < b.N; i++ {
|
|
b.StopTimer()
|
|
bmB, err = copyBitmap(nil, size.bm)
|
|
require.NoError(b, err)
|
|
b.StartTimer()
|
|
|
|
_, _, err = bmB.GetComponents(ComponentCharacters, maxW, maxH)
|
|
assert.NoError(b, err)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
b.Run("ComponentWords", func(b *testing.B) {
|
|
w, h := 20, 8
|
|
for _, size := range sizes {
|
|
b.Run(size.name, func(b *testing.B) {
|
|
var bmB *Bitmap
|
|
maxW, maxH := w*size.size, h*size.size
|
|
for i := 0; i < b.N; i++ {
|
|
b.StopTimer()
|
|
bmB, err = copyBitmap(nil, size.bm)
|
|
require.NoError(b, err)
|
|
b.StartTimer()
|
|
|
|
_, _, err = bmB.GetComponents(ComponentWords, maxW, maxH)
|
|
assert.NoError(b, err)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// TestConnComponents is the function that tests the connectivity components methods.
|
|
func TestConnComponents(t *testing.T) {
|
|
// Having a bitmap 50x18 with few different components like letters
|
|
//
|
|
// 1 2 3 4 5 6 7
|
|
//
|
|
// 111111 11112222 22222233 33333333 44444444 44
|
|
// 01234567 89012345 67890123 45678901 23456789 01234567 89
|
|
//
|
|
// 0 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 2 00111110 01111000 00100111 11000010 00100111 10010001 00000000
|
|
// 3 00100010 01001000 00100001 00000011 00100100 10010001 00000000
|
|
// 4 00100010 01001000 00100001 00000010 10100100 10010101 00000000
|
|
// 5 00100010 01001000 00100001 00000010 01100100 10011011 00000000
|
|
// 6 00111100 01111000 00100001 00000010 00100111 10010001 00000000
|
|
// 7 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 8 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 9 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 10 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 11 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 12 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 13 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 14 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 15 00000000 00000000 00010101 01010000 00000000 00000000 00000000
|
|
// 16 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 17 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
//
|
|
//
|
|
data := []byte{
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x3E, 0x78, 0x27, 0xC2, 0x27, 0x91, 0x00,
|
|
0x22, 0x48, 0x21, 0x03, 0x24, 0x91, 0x00,
|
|
0x22, 0x48, 0x21, 0x02, 0xA4, 0x95, 0x00,
|
|
0x22, 0x48, 0x21, 0x02, 0x64, 0x9B, 0x00,
|
|
0x3C, 0x78, 0x21, 0x02, 0x27, 0x91, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x15, 0x50, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
}
|
|
bm, err := NewWithData(50, 18, data)
|
|
require.NoError(t, err)
|
|
|
|
common.SetLogger(common.NewConsoleLogger(common.LogLevelDebug))
|
|
|
|
t.Run("Connectivity8", func(t *testing.T) {
|
|
// for connectivity 8 there should be 8 components:
|
|
// letters: d, o, i, t, n, o, w
|
|
// and a skull image.
|
|
t.Run("WithBitmaps", func(t *testing.T) {
|
|
bitmaps := &Bitmaps{}
|
|
|
|
bm, err := copyBitmap(nil, bm)
|
|
require.NoError(t, err)
|
|
|
|
boxes, err := bm.ConnComponents(bitmaps, 8)
|
|
require.NoError(t, err)
|
|
|
|
if assert.Len(t, bitmaps.Values, 8) && assert.Len(t, *boxes, 8) {
|
|
for i, bm := range bitmaps.Values {
|
|
box := bitmaps.Boxes[i]
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'D' - expected data:
|
|
//
|
|
// 11111000 0xF8
|
|
// 10001000 0x88
|
|
// 10001000 0x88
|
|
// 10001000 0x88
|
|
// 11110000 0xF0
|
|
assert.Equal(t, []byte{0xF8, 0x88, 0x88, 0x88, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 2)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 6+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 1:
|
|
assert.Equal(t, 4, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'O' - expected data:
|
|
//
|
|
// 11110000 - 0xF0
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 11110000 - 0xF0
|
|
assert.Equal(t, []byte{0xF0, 0x90, 0x90, 0x90, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 9)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 12+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 2:
|
|
assert.Equal(t, 1, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'I' - expected data:
|
|
//
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
assert.Equal(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 18)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 18+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 3:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Width)
|
|
// Letter 'T' - expected data:
|
|
//
|
|
// 11111000 - 0xF8
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
assert.Equal(t, []byte{0xF8, 0x20, 0x20, 0x20, 0x20}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 21)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 25+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 4:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'N' - expected data:
|
|
//
|
|
// 10001000 - 0x88
|
|
// 11001000 - 0xC8
|
|
// 10101000 - 0xA8
|
|
// 10011000 - 0x98
|
|
// 10001000 - 0x88
|
|
assert.Equal(t, []byte{0x88, 0xC8, 0xA8, 0x98, 0x88}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 30)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 34+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 5:
|
|
assert.Equal(t, 4, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'O' - expected data:
|
|
//
|
|
// 11110000 - 0xF0
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 11110000 - 0xF0
|
|
assert.Equal(t, []byte{0xF0, 0x90, 0x90, 0x90, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 37)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 40+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 6:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'W' - expected data:
|
|
//
|
|
// 10001000 - 0x88
|
|
// 10001000 - 0x88
|
|
// 10101000 - 0xA8
|
|
// 11011000 - 0xD8
|
|
// 10001000 - 0x88
|
|
assert.Equal(t, []byte{0x88, 0x88, 0xA8, 0xD8, 0x88}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 43)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 47+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 7:
|
|
// the last one is the the image
|
|
//
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 00101010 10100000 - 0x2A, 0xA0
|
|
assert.Equal(t, 12, bm.Width)
|
|
assert.Equal(t, 7, bm.Height)
|
|
assert.Equal(t, []byte{0xFF, 0xF0, 0xFF, 0xF0, 0xC6, 0x30, 0xC6, 0x30, 0xC6, 0x30, 0xFF, 0xF0, 0x2A, 0xA0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 17)
|
|
assert.Equal(t, box.Min.Y, 9)
|
|
assert.Equal(t, box.Max.X, 28+1)
|
|
assert.Equal(t, box.Max.Y, 15+1)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("OnlyBoxes", func(t *testing.T) {
|
|
bm, err := copyBitmap(nil, bm)
|
|
require.NoError(t, err)
|
|
|
|
boxes, err := bm.ConnComponents(nil, 8)
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, *boxes, 8)
|
|
for i, box := range *boxes {
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, box.Min.X, 2)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 6+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 1:
|
|
assert.Equal(t, box.Min.X, 9)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 12+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 2:
|
|
assert.Equal(t, box.Min.X, 18)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 18+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 3:
|
|
assert.Equal(t, box.Min.X, 21)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 25+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 4:
|
|
assert.Equal(t, box.Min.X, 30)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 34+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 5:
|
|
assert.Equal(t, box.Min.X, 37)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 40+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 6:
|
|
assert.Equal(t, box.Min.X, 43)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 47+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 7:
|
|
assert.Equal(t, box.Min.X, 17)
|
|
assert.Equal(t, box.Min.Y, 9)
|
|
assert.Equal(t, box.Max.X, 28+1)
|
|
assert.Equal(t, box.Max.Y, 15+1)
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("Connectivity4", func(t *testing.T) {
|
|
// Having the connectivity of '4' the letters that
|
|
// are connected using their corners are not treated
|
|
// as single letter.
|
|
// Thus when there were '8' symbols in '8' connectivity
|
|
// the letter 'N' and 'W' both disassembles into 3 copmonents.
|
|
// This gives us 8-2+3+3 = 12 classes.
|
|
t.Run("WithBitmaps", func(t *testing.T) {
|
|
bitmaps := &Bitmaps{}
|
|
|
|
bm, err := copyBitmap(nil, bm)
|
|
require.NoError(t, err)
|
|
|
|
boxes, err := bm.ConnComponents(bitmaps, 4)
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, boxes)
|
|
|
|
cond := assert.Len(t, bitmaps.Values, 12) && assert.Len(t, *boxes, 12) && assert.Len(t, bitmaps.Boxes, 12)
|
|
require.True(t, cond)
|
|
|
|
for i, bm := range bitmaps.Values {
|
|
// The box in bitmaps must be equal to box as an output.
|
|
box := bitmaps.Boxes[i]
|
|
assert.Equal(t, box, (*boxes)[i])
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'D' - expected data:
|
|
//
|
|
// 11111000 0xF8
|
|
// 10001000 0x88
|
|
// 10001000 0x88
|
|
// 10001000 0x88
|
|
// 11110000 0xF0
|
|
assert.Equal(t, []byte{0xF8, 0x88, 0x88, 0x88, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 2)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 6+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 1:
|
|
assert.Equal(t, 4, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'O' - expected data:
|
|
//
|
|
// 11110000 - 0xF0
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 11110000 - 0xF0
|
|
assert.Equal(t, []byte{0xF0, 0x90, 0x90, 0x90, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 9)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 12+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 2:
|
|
assert.Equal(t, 1, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'I' - expected data:
|
|
//
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
assert.Equal(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 18)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 18+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 3:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Width)
|
|
// Letter 'T' - expected data:
|
|
//
|
|
// 11111000 - 0xF8
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
assert.Equal(t, []byte{0xF8, 0x20, 0x20, 0x20, 0x20}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 21)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 25+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 4:
|
|
assert.Equal(t, 2, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Left part of letter 'N' - expected data:
|
|
//
|
|
// 10000000 - 0x80
|
|
// 11000000 - 0xC0
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
assert.Equal(t, []byte{0x80, 0xC0, 0x80, 0x80, 0x80}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 30)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 31+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 5:
|
|
// A right side of the letter 'N' - expected data:
|
|
//
|
|
// 01000000 - 0x40
|
|
// 01000000 - 0x40
|
|
// 01000000 - 0x40
|
|
// 11000000 - 0xC0
|
|
// 01000000 - 0x40
|
|
assert.Equal(t, 2, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
assert.Equal(t, []byte{0x40, 0x40, 0x40, 0xC0, 0x40}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 33)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 34+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 6:
|
|
assert.Equal(t, 4, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'O' - expected data:
|
|
//
|
|
// 11110000 - 0xF0
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 11110000 - 0xF0
|
|
assert.Equal(t, []byte{0xF0, 0x90, 0x90, 0x90, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 37)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 40+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 7:
|
|
// Left part of the letter 'W' - expected data:
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 11000000 - 0xC0
|
|
// 10000000 - 0x80
|
|
assert.Equal(t, 2, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
assert.Equal(t, []byte{0x80, 0x80, 0x80, 0xC0, 0x80}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 43)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 44+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 8:
|
|
// The right part of the letter 'W' - expected data:
|
|
//
|
|
// 01000000 - 0x40
|
|
// 01000000 - 0x40
|
|
// 01000000 - 0x40
|
|
// 11000000 - 0xC0
|
|
// 01000000 - 0x40
|
|
assert.Equal(t, 2, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
assert.Equal(t, []byte{0x40, 0x40, 0x40, 0xC0, 0x40}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 46)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 47+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 9:
|
|
// A single dot in the middle of 'N' letter - expected data:
|
|
// 10000000 - 0x80
|
|
assert.Equal(t, 1, bm.Width, bm)
|
|
assert.Equal(t, 1, bm.Height)
|
|
assert.Equal(t, []byte{0x80}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 32)
|
|
assert.Equal(t, box.Min.Y, 4)
|
|
assert.Equal(t, box.Max.X, 32+1)
|
|
assert.Equal(t, box.Max.Y, 4+1)
|
|
case 10:
|
|
// The dot in the middle of the 'W' letter
|
|
// 100000000 - 0x80
|
|
assert.Equal(t, 1, bm.Width)
|
|
assert.Equal(t, 1, bm.Height)
|
|
assert.Equal(t, []byte{0x80}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 45)
|
|
assert.Equal(t, box.Min.Y, 4)
|
|
assert.Equal(t, box.Max.X, 45+1)
|
|
assert.Equal(t, box.Max.Y, 4+1)
|
|
case 11:
|
|
// the last one is the the image
|
|
//
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 00101010 10100000 - 0x2A, 0xA0
|
|
assert.Equal(t, 12, bm.Width)
|
|
assert.Equal(t, 7, bm.Height)
|
|
assert.Equal(t, []byte{0xFF, 0xF0, 0xFF, 0xF0, 0xC6, 0x30, 0xC6, 0x30, 0xC6, 0x30, 0xFF, 0xF0, 0x2A, 0xA0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 17)
|
|
assert.Equal(t, box.Min.Y, 9)
|
|
assert.Equal(t, box.Max.X, 28+1)
|
|
assert.Equal(t, box.Max.Y, 15+1)
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("OnlyBoxes", func(t *testing.T) {
|
|
bm, err := copyBitmap(nil, bm)
|
|
require.NoError(t, err)
|
|
|
|
boxes, err := bm.ConnComponents(nil, 4)
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, *boxes, 12)
|
|
for i, box := range *boxes {
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, box.Min.X, 2)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 6+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 1:
|
|
assert.Equal(t, box.Min.X, 9)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 12+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 2:
|
|
assert.Equal(t, box.Min.X, 18)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 18+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 3:
|
|
assert.Equal(t, box.Min.X, 21)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 25+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 4:
|
|
assert.Equal(t, box.Min.X, 30)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 31+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 5:
|
|
assert.Equal(t, box.Min.X, 33)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 34+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 6:
|
|
assert.Equal(t, box.Min.X, 37)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 40+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 7:
|
|
assert.Equal(t, box.Min.X, 43)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 44+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 8:
|
|
assert.Equal(t, box.Min.X, 46)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 47+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 9:
|
|
assert.Equal(t, box.Min.X, 32)
|
|
assert.Equal(t, box.Min.Y, 4)
|
|
assert.Equal(t, box.Max.X, 32+1)
|
|
assert.Equal(t, box.Max.Y, 4+1)
|
|
case 10:
|
|
assert.Equal(t, box.Min.X, 45)
|
|
assert.Equal(t, box.Min.Y, 4)
|
|
assert.Equal(t, box.Max.X, 45+1)
|
|
assert.Equal(t, box.Max.Y, 4+1)
|
|
case 11:
|
|
assert.Equal(t, box.Min.X, 17)
|
|
assert.Equal(t, box.Min.Y, 9)
|
|
assert.Equal(t, box.Max.X, 28+1)
|
|
assert.Equal(t, box.Max.Y, 15+1)
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("Invalid", func(t *testing.T) {
|
|
t.Run("NoBitmap", func(t *testing.T) {
|
|
var bm *Bitmap
|
|
_, err := bm.ConnComponents(nil, 8)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("Connectivity", func(t *testing.T) {
|
|
// having any bitmap with some connectivity different
|
|
// then '4' and '8' - i.e. '2' should return error.
|
|
bm := New(10, 10)
|
|
_, err := bm.ConnComponents(nil, 2)
|
|
require.Error(t, err)
|
|
})
|
|
})
|
|
}
|
|
|
|
// TestGetComponents tests the GetComponents function.
|
|
func TestGetComponents(t *testing.T) {
|
|
// Having a bitmap 50x22 with few different components like letters.
|
|
//
|
|
// 1 2 3 4 5 6 7
|
|
//
|
|
// 111111 11112222 22222233 33333333 44444444 44
|
|
// 01234567 89012345 67890123 45678901 23456789 01234567 89
|
|
//
|
|
// 0 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 2 00111110 01111000 00100111 11000010 00100111 10010001 00000000
|
|
// 3 00100010 01001000 00100001 00000011 00100100 10010001 00000000
|
|
// 4 00100010 01001000 00100001 00000010 10100100 10010101 00000000
|
|
// 5 00100010 01001000 00100001 00000010 01100100 10011011 00000000
|
|
// 6 00111100 01111000 00100001 00000010 00100111 10010001 00000000
|
|
// 7 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 8 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 9 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 10 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 11 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 12 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 13 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 14 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 15 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 16 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 17 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 18 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 19 00000000 00000000 00010101 01010000 00000000 00000000 00000000
|
|
// 20 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 21 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
//
|
|
//
|
|
data := []byte{
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x3E, 0x78, 0x27, 0xC2, 0x27, 0x91, 0x00,
|
|
0x22, 0x48, 0x21, 0x03, 0x24, 0x91, 0x00,
|
|
0x22, 0x48, 0x21, 0x02, 0xA4, 0x95, 0x00,
|
|
0x22, 0x48, 0x21, 0x02, 0x64, 0x9B, 0x00,
|
|
0x3C, 0x78, 0x21, 0x02, 0x27, 0x91, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x15, 0x50, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
}
|
|
bm, err := NewWithData(50, 22, data)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("ComponentConn", func(t *testing.T) {
|
|
t.Run("Max12-8", func(t *testing.T) {
|
|
// the highest component is 12 bits wide and 8bits tall.
|
|
// this should get all possible components out of the given input bitmap.
|
|
bm, err = copyBitmap(nil, bm)
|
|
require.NoError(t, err)
|
|
|
|
bitmaps, boxes, err := bm.GetComponents(ComponentConn, 12, 8)
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, bitmaps)
|
|
require.NotNil(t, boxes)
|
|
|
|
if assert.Len(t, bitmaps.Values, 8) && assert.Len(t, *boxes, 8) {
|
|
for i, bm := range bitmaps.Values {
|
|
box := bitmaps.Boxes[i]
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'D' - expected data:
|
|
//
|
|
// 11111000 0xF8
|
|
// 10001000 0x88
|
|
// 10001000 0x88
|
|
// 10001000 0x88
|
|
// 11110000 0xF0
|
|
assert.Equal(t, []byte{0xF8, 0x88, 0x88, 0x88, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 2)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 6+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 1:
|
|
assert.Equal(t, 4, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'O' - expected data:
|
|
//
|
|
// 11110000 - 0xF0
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 11110000 - 0xF0
|
|
assert.Equal(t, []byte{0xF0, 0x90, 0x90, 0x90, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 9)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 12+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 2:
|
|
assert.Equal(t, 1, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'I' - expected data:
|
|
//
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
assert.Equal(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 18)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 18+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 3:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Width)
|
|
// Letter 'T' - expected data:
|
|
//
|
|
// 11111000 - 0xF8
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
assert.Equal(t, []byte{0xF8, 0x20, 0x20, 0x20, 0x20}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 21)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 25+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 4:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'N' - expected data:
|
|
//
|
|
// 10001000 - 0x88
|
|
// 11001000 - 0xC8
|
|
// 10101000 - 0xA8
|
|
// 10011000 - 0x98
|
|
// 10001000 - 0x88
|
|
assert.Equal(t, []byte{0x88, 0xC8, 0xA8, 0x98, 0x88}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 30)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 34+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 5:
|
|
assert.Equal(t, 4, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'O' - expected data:
|
|
//
|
|
// 11110000 - 0xF0
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 11110000 - 0xF0
|
|
assert.Equal(t, []byte{0xF0, 0x90, 0x90, 0x90, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 37)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 40+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 6:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'W' - expected data:
|
|
//
|
|
// 10001000 - 0x88
|
|
// 10001000 - 0x88
|
|
// 10101000 - 0xA8
|
|
// 11011000 - 0xD8
|
|
// 10001000 - 0x88
|
|
assert.Equal(t, []byte{0x88, 0x88, 0xA8, 0xD8, 0x88}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 43)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 47+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 7:
|
|
// the last one is the the image
|
|
//
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 00101010 10100000 - 0x2A, 0xA0
|
|
assert.Equal(t, 12, bm.Width)
|
|
assert.Equal(t, 7, bm.Height)
|
|
assert.Equal(t, []byte{0xFF, 0xF0, 0xFF, 0xF0, 0xC6, 0x30, 0xC6, 0x30, 0xC6, 0x30, 0xFF, 0xF0, 0x2A, 0xA0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 17)
|
|
assert.Equal(t, box.Min.Y, 13)
|
|
assert.Equal(t, box.Max.X, 28+1)
|
|
assert.Equal(t, box.Max.Y, 19+1)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("Max10-6", func(t *testing.T) {
|
|
bm, err := copyBitmap(nil, bm)
|
|
require.NoError(t, err)
|
|
|
|
bitmaps, boxes, err := bm.GetComponents(ComponentConn, 10, 6)
|
|
require.NoError(t, err)
|
|
|
|
if assert.Len(t, bitmaps.Values, 7) && assert.Len(t, *boxes, 7) {
|
|
for i, bm := range bitmaps.Values {
|
|
box := bitmaps.Boxes[i]
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'D' - expected data:
|
|
//
|
|
// 11111000 0xF8
|
|
// 10001000 0x88
|
|
// 10001000 0x88
|
|
// 10001000 0x88
|
|
// 11110000 0xF0
|
|
assert.Equal(t, []byte{0xF8, 0x88, 0x88, 0x88, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 2)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 6+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 1:
|
|
assert.Equal(t, 4, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'O' - expected data:
|
|
//
|
|
// 11110000 - 0xF0
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 11110000 - 0xF0
|
|
assert.Equal(t, []byte{0xF0, 0x90, 0x90, 0x90, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 9)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 12+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 2:
|
|
assert.Equal(t, 1, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'I' - expected data:
|
|
//
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
assert.Equal(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 18)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 18+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 3:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Width)
|
|
// Letter 'T' - expected data:
|
|
//
|
|
// 11111000 - 0xF8
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
assert.Equal(t, []byte{0xF8, 0x20, 0x20, 0x20, 0x20}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 21)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 25+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 4:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'N' - expected data:
|
|
//
|
|
// 10001000 - 0x88
|
|
// 11001000 - 0xC8
|
|
// 10101000 - 0xA8
|
|
// 10011000 - 0x98
|
|
// 10001000 - 0x88
|
|
assert.Equal(t, []byte{0x88, 0xC8, 0xA8, 0x98, 0x88}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 30)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 34+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 5:
|
|
assert.Equal(t, 4, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'O' - expected data:
|
|
//
|
|
// 11110000 - 0xF0
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 11110000 - 0xF0
|
|
assert.Equal(t, []byte{0xF0, 0x90, 0x90, 0x90, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 37)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 40+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 6:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'W' - expected data:
|
|
//
|
|
// 10001000 - 0x88
|
|
// 10001000 - 0x88
|
|
// 10101000 - 0xA8
|
|
// 11011000 - 0xD8
|
|
// 10001000 - 0x88
|
|
assert.Equal(t, []byte{0x88, 0x88, 0xA8, 0xD8, 0x88}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 43)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 47+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("Char", func(t *testing.T) {
|
|
// the highest component is 12 bits wide and 8bits tall.
|
|
// this should get all possible components out of the given input bitmap.
|
|
bm, err = copyBitmap(nil, bm)
|
|
require.NoError(t, err)
|
|
|
|
bitmaps, boxes, err := bm.GetComponents(ComponentCharacters, 12, 8)
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, bitmaps)
|
|
require.NotNil(t, boxes)
|
|
|
|
if assert.Len(t, bitmaps.Values, 8) && assert.Len(t, *boxes, 8) {
|
|
for i, bm := range bitmaps.Values {
|
|
box := bitmaps.Boxes[i]
|
|
switch i {
|
|
case 0:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'D' - expected data:
|
|
//
|
|
// 11111000 0xF8
|
|
// 10001000 0x88
|
|
// 10001000 0x88
|
|
// 10001000 0x88
|
|
// 11110000 0xF0
|
|
assert.Equal(t, []byte{0xF8, 0x88, 0x88, 0x88, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 2)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 6+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 1:
|
|
assert.Equal(t, 4, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'O' - expected data:
|
|
//
|
|
// 11110000 - 0xF0
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 11110000 - 0xF0
|
|
assert.Equal(t, []byte{0xF0, 0x90, 0x90, 0x90, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 9)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 12+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 2:
|
|
assert.Equal(t, 1, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'I' - expected data:
|
|
//
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
// 10000000 - 0x80
|
|
assert.Equal(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 18)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 18+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 3:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Width)
|
|
// Letter 'T' - expected data:
|
|
//
|
|
// 11111000 - 0xF8
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
// 00100000 - 0x20
|
|
assert.Equal(t, []byte{0xF8, 0x20, 0x20, 0x20, 0x20}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 21)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 25+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 4:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'N' - expected data:
|
|
//
|
|
// 10001000 - 0x88
|
|
// 11001000 - 0xC8
|
|
// 10101000 - 0xA8
|
|
// 10011000 - 0x98
|
|
// 10001000 - 0x88
|
|
assert.Equal(t, []byte{0x88, 0xC8, 0xA8, 0x98, 0x88}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 30)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 34+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 5:
|
|
assert.Equal(t, 4, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'O' - expected data:
|
|
//
|
|
// 11110000 - 0xF0
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 10010000 - 0x90
|
|
// 11110000 - 0xF0
|
|
assert.Equal(t, []byte{0xF0, 0x90, 0x90, 0x90, 0xF0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 37)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 40+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 6:
|
|
assert.Equal(t, 5, bm.Width)
|
|
assert.Equal(t, 5, bm.Height)
|
|
// Letter 'W' - expected data:
|
|
//
|
|
// 10001000 - 0x88
|
|
// 10001000 - 0x88
|
|
// 10101000 - 0xA8
|
|
// 11011000 - 0xD8
|
|
// 10001000 - 0x88
|
|
assert.Equal(t, []byte{0x88, 0x88, 0xA8, 0xD8, 0x88}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 43)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 47+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 7:
|
|
// the last one is the the image
|
|
//
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 00101010 10100000 - 0x2A, 0xA0
|
|
assert.Equal(t, 12, bm.Width)
|
|
assert.Equal(t, 7, bm.Height)
|
|
assert.Equal(t, []byte{0xFF, 0xF0, 0xFF, 0xF0, 0xC6, 0x30, 0xC6, 0x30, 0xC6, 0x30, 0xFF, 0xF0, 0x2A, 0xA0}, bm.Data)
|
|
assert.Equal(t, box.Min.X, 17)
|
|
assert.Equal(t, box.Min.Y, 13)
|
|
assert.Equal(t, box.Max.X, 28+1)
|
|
assert.Equal(t, box.Max.Y, 19+1)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("Word", func(t *testing.T) {
|
|
// the highest component is 20 bits wide and 8bits tall.
|
|
bm, err = copyBitmap(nil, bm)
|
|
require.NoError(t, err)
|
|
|
|
bitmaps, boxes, err := bm.GetComponents(ComponentWords, 20, 8)
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, bitmaps)
|
|
require.NotNil(t, boxes)
|
|
|
|
// this should result in a three words and a image components:
|
|
if assert.Len(t, bitmaps.Values, 4) && assert.Len(t, *boxes, 4) {
|
|
for i, word := range bitmaps.Values {
|
|
box := (*boxes)[i]
|
|
switch i {
|
|
case 0:
|
|
// the first word should look like 'DO'.
|
|
//
|
|
// 11111001 11100000 - 0xF9, 0xE0
|
|
// 10001001 00100000 - 0x89, 0x20
|
|
// 10001001 00100000 - 0x89, 0x20
|
|
// 10001001 00100000 - 0x89, 0x20
|
|
// 11110001 11100000 - 0xF1, 0xE0
|
|
data := []byte{0xF9, 0xE0, 0x89, 0x20, 0x89, 0x20, 0x89, 0x20, 0xF1, 0xE0}
|
|
assert.Equal(t, data, word.Data)
|
|
assert.Equal(t, box.Min.X, 2)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 12+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 1:
|
|
// the second word should be like 'IT'
|
|
//
|
|
// 10011111 - 0x9F
|
|
// 10000100 - 0x84
|
|
// 10000100 - 0x84
|
|
// 10000100 - 0x84
|
|
// 10000100 - 0x84
|
|
data := []byte{0x9F, 0x84, 0x84, 0x84, 0x84}
|
|
assert.Equal(t, data, word.Data)
|
|
assert.Equal(t, box.Min.X, 18)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 25+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 2:
|
|
// the third word should look like 'NOW'
|
|
//
|
|
// 10001001 11100100 01000000 - 0x89, 0xE4, 0x40
|
|
// 11001001 00100100 01000000 - 0xC9, 0x24, 0x40
|
|
// 10101001 00100101 01000000 - 0xA9, 0x25, 0x40
|
|
// 10011001 00100110 11000000 - 0x99, 0x26, 0xC0
|
|
// 10001001 11100100 01000000 - 0x89, 0xE4, 0x40
|
|
data := []byte{
|
|
0x89, 0xE4, 0x40,
|
|
0xC9, 0x24, 0x40,
|
|
0xA9, 0x25, 0x40,
|
|
0x99, 0x26, 0xC0,
|
|
0x89, 0xE4, 0x40,
|
|
}
|
|
assert.Equal(t, data, word.Data)
|
|
assert.Equal(t, box.Min.X, 30)
|
|
assert.Equal(t, box.Min.Y, 2)
|
|
assert.Equal(t, box.Max.X, 47+1)
|
|
assert.Equal(t, box.Max.Y, 6+1)
|
|
case 3:
|
|
// the last component is the image of the 'skull'i
|
|
//
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11000110 00110000 - 0xC6, 0x30
|
|
// 11111111 11110000 - 0xFF, 0xF0
|
|
// 00101010 10100000 - 0x2A, 0xA0
|
|
data := []byte{
|
|
0xFF, 0xF0,
|
|
0xFF, 0xF0,
|
|
0xC6, 0x30,
|
|
0xC6, 0x30,
|
|
0xC6, 0x30,
|
|
0xFF, 0xF0,
|
|
0x2A, 0xA0,
|
|
}
|
|
|
|
assert.Equal(t, 12, word.Width)
|
|
assert.Equal(t, 7, word.Height)
|
|
assert.Equal(t, data, word.Data, word.String())
|
|
assert.Equal(t, box.Min.X, 17)
|
|
assert.Equal(t, box.Min.Y, 13)
|
|
assert.Equal(t, box.Max.X, 28+1)
|
|
assert.Equal(t, box.Max.Y, 19+1)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("Zero", func(t *testing.T) {
|
|
// Create a zero like bitmap - it should not create any component.
|
|
bm := New(bm.Width, bm.Height)
|
|
|
|
bitmaps, boxes, err := bm.GetComponents(ComponentConn, 12, 8)
|
|
require.NoError(t, err)
|
|
|
|
if assert.NotNil(t, bitmaps) {
|
|
assert.Empty(t, bitmaps.Values)
|
|
}
|
|
|
|
if assert.NotNil(t, boxes) {
|
|
assert.Empty(t, *boxes)
|
|
}
|
|
})
|
|
|
|
t.Run("EmptyBitmap", func(t *testing.T) {
|
|
var b *Bitmap
|
|
_, _, err := b.GetComponents(ComponentConn, 12, 8)
|
|
assert.Error(t, err)
|
|
})
|
|
}
|
|
|
|
// TestWordMaskByDilation tests the WordMaskByDilation function.
|
|
func TestWordMaskByDilation(t *testing.T) {
|
|
// Having a bitmap 50x18 with few different components like letters
|
|
//
|
|
// 1 2 3 4 5 6 7
|
|
//
|
|
// 111111 11112222 22222233 33333333 44444444 44
|
|
// 01234567 89012345 67890123 45678901 23456789 01234567 89
|
|
//
|
|
// 0 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 2 00111110 01111000 00100111 11000010 00100111 10010001 00000000
|
|
// 3 00100010 01001000 00100001 00000011 00100100 10010001 00000000
|
|
// 4 00100010 01001000 00100001 00000010 10100100 10010101 00000000
|
|
// 5 00100010 01001000 00100001 00000010 01100100 10011011 00000000
|
|
// 6 00111100 01111000 00100001 00000010 00100111 10010001 00000000
|
|
// 7 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 8 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 9 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 10 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 11 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 12 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 13 00000000 00000000 01100011 00011000 00000000 00000000 00000000
|
|
// 14 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 15 00000000 00000000 00010101 01010000 00000000 00000000 00000000
|
|
// 16 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 17 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
//
|
|
//
|
|
data := []byte{
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x3E, 0x78, 0x27, 0xC2, 0x27, 0x91, 0x00,
|
|
0x22, 0x48, 0x21, 0x03, 0x24, 0x91, 0x00,
|
|
0x22, 0x48, 0x21, 0x02, 0xA4, 0x95, 0x00,
|
|
0x22, 0x48, 0x21, 0x02, 0x64, 0x9B, 0x00,
|
|
0x3C, 0x78, 0x21, 0x02, 0x27, 0x91, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x63, 0x18, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x15, 0x50, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
}
|
|
bm, err := NewWithData(50, 18, data)
|
|
require.NoError(t, err)
|
|
|
|
masks, _, err := wordMaskByDilation(bm)
|
|
require.NoError(t, err)
|
|
|
|
// the function wordMaskByDilation should create a mask bitmap that
|
|
// would set all the box areas for each copmonent of the input
|
|
// with all 'ONE' by using dilation.
|
|
//
|
|
// 1 2 3 4 5 6 7
|
|
//
|
|
// 111111 11112222 22222233 33333333 44444444 44
|
|
// 01234567 89012345 67890123 45678901 23456789 01234567 89
|
|
//
|
|
// 0 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 2 00111111 11111000 00111111 11000011 11111111 11111111 00000000
|
|
// 3 00111111 11111000 00100001 00000011 11111111 11111111 00000000
|
|
// 4 00111111 11111000 00100001 00000011 11111111 11111111 00000000
|
|
// 5 00111111 11111000 00100001 00000011 11111111 11111111 00000000
|
|
// 6 00111111 11111000 00100001 00000011 11111111 11111111 00000000
|
|
// 7 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 8 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 9 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 10 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 11 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 12 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 13 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 14 00000000 00000000 01111111 11111000 00000000 00000000 00000000
|
|
// 15 00000000 00000000 00011111 11110000 00000000 00000000 00000000
|
|
// 16 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
// 17 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
|
//
|
|
result := []byte{
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x3F, 0xF8, 0x3F, 0xC3, 0xFF, 0xFF, 0x00,
|
|
0x3F, 0xF8, 0x21, 0x03, 0xFF, 0xFF, 0x00,
|
|
0x3F, 0xF8, 0x21, 0x03, 0xFF, 0xFF, 0x00,
|
|
0x3F, 0xF8, 0x21, 0x03, 0xFF, 0xFF, 0x00,
|
|
0x3F, 0xF8, 0x21, 0x03, 0xFF, 0xFF, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
}
|
|
assert.Equal(t, result, masks.Data)
|
|
}
|