-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpalette.go
73 lines (61 loc) · 1.75 KB
/
palette.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
package main
import (
"errors"
"fmt"
"goldutil/sprite"
"image"
"os"
)
/* GoldSrc uses the last color of a palette to indicate what to use as the
* transparent color for masked transparency. If the palette is shorter than the
* maximum the last color of the palette needs to be moved to the last spot and
* all corresponding pixels also need to be updated to this new palette index. */
func remapLastColor(img *image.Paletted, remapIndex uint8) {
for i, v := range img.Pix {
if v == remapIndex {
img.Pix[i] = 0xFF
}
}
}
func openPalettedImage(path string) (*image.Paletted, error) {
f, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("unable to open file at '%s': %w", path, err)
}
defer f.Close()
mysteryImg, _, err := image.Decode(f)
if err != nil {
return nil, fmt.Errorf("unable to decode image: %w", err)
}
img, ok := mysteryImg.(*image.Paletted)
if !ok {
return nil, errors.New("image is not paletted")
}
return img, nil
}
// Returns the final palette, the last index in the input palette, and true if
// this index must be remapped to 0xFF.
func imagePalette(path string) (sprite.Palette, uint8, bool, error) {
var palette sprite.Palette
img, err := openPalettedImage(path)
if err != nil {
return palette, 0, false, fmt.Errorf("unable to open image: %w", err)
}
if len(img.Palette) > 256 {
return palette, 0, false, fmt.Errorf("expected at most 256 colors palette, got %d", len(palette))
}
for i, v := range img.Palette {
r, g, b, _ := v.RGBA()
palette[i] = sprite.RGB{
R: uint8(r),
G: uint8(g),
B: uint8(b),
}
}
lastIndex := len(img.Palette) - 1
if lastIndex != 255 {
palette[255] = palette[lastIndex]
return palette, uint8(lastIndex), true, nil
}
return palette, uint8(lastIndex), false, nil
}