-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
133 lines (110 loc) · 2.33 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package go_qoi
import (
"bufio"
"encoding/binary"
"image"
"image/color"
"image/png"
"io"
"os"
)
const (
QOI_OP_INDEX = 0x00
QOI_OP_DIFF = 0x40
QOI_OP_LUMA = 0x80
QOI_OP_RUN = 0xC0
QOI_OP_RGB = 0xFE
QOI_OP_RGBA = 0xFF
QOI_OP_MASK2 = 0xC0
QOI_MAGIC = "qoif"
QOI_END_PADDING_SIZE = 8
QOI_HEADER_SIZE = 14
)
var QOI_END_PADDING = [8]byte{0, 0, 0, 0, 0, 0, 0, 1}
func readUint32(reader *bufio.Reader) (uint32, error) {
bytes := make([]byte, 4)
_, err := reader.Read(bytes)
if err != nil {
return 0, err
}
value := binary.BigEndian.Uint32(bytes)
return value, nil
}
func writeUint32(writer io.Writer, value uint32) error {
bytes := make([]byte, 4)
binary.BigEndian.PutUint32(bytes, value)
_, err := writer.Write(bytes)
if err != nil {
return err
}
return nil
}
func colorToNRGBA(c color.Color) color.NRGBA {
return color.NRGBAModel.Convert(c).(color.NRGBA)
}
func colorEquals(c, o color.Color) bool {
c1 := colorToNRGBA(c)
o1 := colorToNRGBA(o)
return c1 == o1
}
func indexPositionHash(px color.NRGBA) uint8 {
return (px.R*3 + px.G*5 + px.B*7 + px.A*11) % 64
}
// Calculate the maximum (worst case) number of bytes necessary to convert the image.
func MaxQoiSize(img image.Image) int {
channels := 4
b := img.Bounds().Max
return b.X*b.Y*(channels+1) +
QOI_HEADER_SIZE +
QOI_END_PADDING_SIZE
}
func ReadPngFile(filename string) (image.Image, error) {
i, err := os.Open(filename)
if err != nil {
return nil, err
}
defer i.Close()
img, err := png.Decode(i)
if err != nil {
return nil, err
}
return img, nil
}
func ReadQoiFile(filename string) (image.Image, error) {
i, err := os.Open(filename)
if err != nil {
return nil, err
}
defer i.Close()
img, err := Decode(i)
if err != nil {
return nil, err
}
return img, nil
}
func SaveImageToPngFile(img *image.Image, filename string) error {
f, err := os.Create(filename)
if err != nil {
return err
}
if err := png.Encode(f, *img); err != nil {
f.Close()
return err
}
if err := f.Close(); err != nil {
return err
}
return nil
}
func ReadPngAndSaveImageToQoi(input, output string) error {
o, err := os.Create(output)
if err != nil {
return err
}
defer o.Close()
img, err := ReadPngFile(input)
if err := Encode(o, img); err != nil {
return err
}
return nil
}