limage - xcf/image_encode.go
1 package xcf
2
3 import (
4 "image"
5 "image/color"
6
7 "vimagination.zapto.org/limage/lcolor"
8 )
9
10 func (e *encoder) WriteImage(im image.Image, colourFunc colourBufFunc, colourChannels uint8) {
11 bounds := im.Bounds()
12
13 dx := int64(bounds.Dx())
14 dy := int64(bounds.Dy())
15
16 // Hierarchy
17
18 e.WriteUint32(uint32(dx))
19 e.WriteUint32(uint32(dy))
20 e.WriteUint32(uint32(colourChannels))
21
22 e.WriteUint32(uint32(e.pos) + 8) // currPos + this pointer (4) + zero pointer (4)
23 e.WriteUint32(0)
24
25 // Level
26
27 e.WriteUint32(uint32(dx))
28 e.WriteUint32(uint32(dy))
29
30 nx := dx >> 6 // each tile is 64 wide
31 ny := dy >> 6 // each tile is 64 high
32
33 if dx&63 > 0 { // last tile not as wide
34 nx++
35 }
36 if dy&63 > 0 { // last tile not as high
37 ny++
38 }
39
40 w := e.ReservePointerList(uint32(nx * ny))
41
42 // Tiles
43
44 for y := bounds.Min.Y; y < bounds.Max.Y; y += 64 {
45 for x := bounds.Min.X; x < bounds.Max.X; x += 64 {
46 l := uint16(0)
47 for j := y; j < y+64 && j < bounds.Max.Y; j++ {
48 for i := x; i < x+64 && i < bounds.Max.X; i++ {
49 colourFunc(e, im.At(i, j))
50 for n := uint8(0); n < colourChannels; n++ {
51 e.channelBuf[n][l] = e.colourBuf[n]
52 }
53 l++
54 }
55 }
56 w.WritePointer(uint32(e.pos))
57 for n := uint8(0); n < colourChannels; n++ {
58 e.WriteRLE(e.channelBuf[n][:l])
59 }
60 }
61 }
62 }
63
64 func (e *encoder) rgbAlphaToBuf(c color.Color) {
65 rgba := color.NRGBAModel.Convert(c).(color.NRGBA)
66 e.colourBuf[0] = rgba.R
67 e.colourBuf[1] = rgba.G
68 e.colourBuf[2] = rgba.B
69 e.colourBuf[3] = rgba.A
70 }
71
72 func (e *encoder) grayAlphaToBuf(c color.Color) {
73 ga := lcolor.GrayAlphaModel.Convert(c).(lcolor.GrayAlpha)
74 e.colourBuf[0] = ga.Y
75 e.colourBuf[1] = ga.A
76 }
77
78 func (e *encoder) grayToBuf(c color.Color) {
79 e.colourBuf[0] = color.GrayModel.Convert(c).(color.Gray).Y
80 }
81
82 func (e *encoder) paletteAlphaToBuf(c color.Color) {
83 r, g, b, a := c.RGBA()
84 i := e.colourPalette.Index(lcolor.RGB{R: uint8(r), G: uint8(g), B: uint8(b)})
85 e.colourBuf[0] = uint8(i)
86 e.colourBuf[1] = uint8(a)
87 }
88