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  }