9fans.net/go@v0.0.5/draw/memdraw/alloc.go (about) 1 // #include <u.h> 2 // #include <libc.h> 3 // #include <draw.h> 4 // #include <memdraw.h> 5 6 // #define poolalloc(a, b) malloc(b) 7 // #define poolfree(a, b) free(b) 8 9 package memdraw 10 11 import ( 12 "fmt" 13 14 "9fans.net/go/draw" 15 ) 16 17 func allocmemimaged(r draw.Rectangle, chan_ draw.Pix, md *_Memdata, X interface{}) (*Image, error) { 18 if r.Dx() <= 0 || r.Dy() <= 0 { 19 return nil, fmt.Errorf("bad rectangle %v", r) 20 } 21 d := chan_.Depth() 22 if d == 0 { 23 return nil, fmt.Errorf("bad channel descriptor %.8x", chan_) 24 } 25 26 l := draw.WordsPerLine(r, d) 27 i := new(Image) 28 29 i.X = X 30 i.Data = md 31 i.zero = 4 * l * r.Min.Y 32 33 if r.Min.X >= 0 { 34 i.zero += (r.Min.X * d) / 8 35 } else { 36 i.zero -= (-r.Min.X*d + 7) / 8 37 } 38 i.zero = -i.zero 39 i.Width = uint32(l) 40 i.R = r 41 i.Clipr = r 42 i.Flags = 0 43 i.Layer = nil 44 i.cmap = memdefcmap 45 if err := memsetchan(i, chan_); err != nil { 46 return nil, err 47 } 48 return i, nil 49 } 50 51 func AllocImage(r draw.Rectangle, chan_ draw.Pix) (*Image, error) { 52 d := chan_.Depth() 53 if d == 0 { 54 return nil, fmt.Errorf("bad channel descriptor %.8x", chan_) 55 } 56 57 l := draw.WordsPerLine(r, d) 58 nw := l * r.Dy() 59 md := new(_Memdata) 60 md.ref = 1 61 md.Bdata = make([]byte, (1+nw)*4) 62 63 i, err := allocmemimaged(r, chan_, md, nil) 64 if err != nil { 65 return nil, err 66 } 67 md.imref = i 68 return i, nil 69 } 70 71 func byteaddr(i *Image, p draw.Point) []uint8 { 72 return i.BytesAt(p) 73 } 74 75 func (i *Image) BytesAt(p draw.Point) []uint8 { 76 /* careful to sign-extend negative p.y for 64-bits */ 77 a := i.zero + 4*p.Y*int(i.Width) 78 79 if i.Depth < 8 { 80 np := 8 / i.Depth 81 if p.X < 0 { 82 a += (p.X - np + 1) / np 83 } else { 84 a += p.X / np 85 } 86 } else { 87 a += p.X * (i.Depth / 8) 88 } 89 return i.Data.Bdata[a:] 90 } 91 92 func memsetchan(i *Image, chan_ draw.Pix) error { 93 d := chan_.Depth() 94 if d == 0 { 95 return fmt.Errorf("bad channel descriptor") 96 } 97 98 i.Depth = d 99 i.Pix = chan_ 100 i.Flags &^= Fgrey | Falpha | Fcmap | Fbytes 101 bytes := 1 102 cc := chan_ 103 j := uint(0) 104 k := 0 105 for ; cc != 0; func() { j += _NBITS(cc); cc >>= 8; k++ }() { 106 t := _TYPE(cc) 107 if t < 0 || t >= draw.NChan { 108 return fmt.Errorf("bad channel string") 109 } 110 if t == draw.CGrey { 111 i.Flags |= Fgrey 112 } 113 if t == draw.CAlpha { 114 i.Flags |= Falpha 115 } 116 if t == draw.CMap && i.cmap == nil { 117 i.cmap = memdefcmap 118 i.Flags |= Fcmap 119 } 120 121 i.shift[t] = j 122 i.mask[t] = (1 << _NBITS(cc)) - 1 123 i.nbits[t] = _NBITS(cc) 124 if _NBITS(cc) != 8 { 125 bytes = 0 126 } 127 } 128 i.nchan = k 129 if bytes != 0 { 130 i.Flags |= Fbytes 131 } 132 return nil 133 } 134 135 func Free(i *Image) { 136 }