-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathbitmap.go
More file actions
74 lines (61 loc) · 1.85 KB
/
bitmap.go
File metadata and controls
74 lines (61 loc) · 1.85 KB
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
package spice
import (
"encoding/binary"
"errors"
"fmt"
"image"
)
func bitmapImage(data []byte) (image.Image, error) {
if len(data) < 2 {
return nil, errors.New("not enough data for bitmap image")
}
format := BitmapImageType(data[0])
flags := data[1] // 1=PAL_CACHE_ME, 2=PAL_FROM_CACHE, 4=TOP_DOWN,
var headerLen int
if flags&2 == 2 {
headerLen = 22
} else {
headerLen = 18
}
if len(data) < headerLen {
return nil, errors.New("not enough data for bitmap image")
}
width := binary.LittleEndian.Uint32(data[2:6])
height := binary.LittleEndian.Uint32(data[6:10])
stride := binary.LittleEndian.Uint32(data[10:14])
var palId uint64
var palPtr uint32
if flags&2 == 2 { // PAL_FROM_CACHE
// palette_id
palId = binary.LittleEndian.Uint64(data[14:22])
} else {
// ptr to palette
palPtr = binary.LittleEndian.Uint32(data[14:18])
}
data = data[headerLen:]
//log.Printf("bitmap image, size=%dx%d stride=%d flags=%d format=%d palId=%d palPtr=%d len=%d", width, height, stride, flags, format, palId, palPtr, len(data))
_, _ = palId, palPtr
switch format {
case BITMAP_IMAGE_TYPE_32BIT, BITMAP_IMAGE_TYPE_RGBA:
ln := int(height * stride)
if len(data) < ln {
return nil, errors.New("not enough data for image")
}
// QEMU sends bitmap data in BGRX format, need to convert to RGBA
pixData := make([]byte, ln)
for i := 0; i < ln; i += 4 {
pixData[i+0] = data[i+2] // R from B
pixData[i+1] = data[i+1] // G stays
pixData[i+2] = data[i+0] // B from R
pixData[i+3] = 0xff // A (opaque)
}
img := &image.RGBA{Pix: pixData, Stride: int(stride), Rect: image.Rect(0, 0, int(width), int(height))}
if flags&4 == 0 {
// reverse image (flip vertically)
reverseImgRGBA(img)
}
return img, nil
default:
return nil, fmt.Errorf("unsupported bitmap image format=%d size=%d,%d stride=%d", format, width, height, stride)
}
}