9fans.net/go@v0.0.5/draw/memdraw/load.go (about)

     1  // #include <u.h>
     2  // #include <libc.h>
     3  // #include <draw.h>
     4  // #include <memdraw.h>
     5  
     6  package memdraw
     7  
     8  import (
     9  	"fmt"
    10  
    11  	"9fans.net/go/draw"
    12  )
    13  
    14  func loadmemimage(i *Image, r draw.Rectangle, data []uint8) (int, error) {
    15  	if !draw.RectInRect(r, i.R) {
    16  		return 0, fmt.Errorf("invalid rectangle")
    17  	}
    18  	l := draw.BytesPerLine(r, i.Depth)
    19  	if len(data) < l*r.Dy() {
    20  		return 0, fmt.Errorf("buffer too small")
    21  	}
    22  	ndata := l * r.Dy()
    23  	q := byteaddr(i, r.Min)
    24  	mx := 7 / i.Depth
    25  	lpart := (r.Min.X & mx) * i.Depth
    26  	rpart := (r.Max.X & mx) * i.Depth
    27  	m := uint8(0xFF) >> lpart
    28  	var y int
    29  	/* may need to do bit insertion on edges */
    30  	if l == 1 { /* all in one byte */
    31  		if rpart != 0 {
    32  			m ^= 0xFF >> rpart
    33  		}
    34  		for y = r.Min.Y; y < r.Max.Y; y++ {
    35  			q[0] ^= (data[0] ^ q[0]) & m
    36  			q = q[i.Width*4:]
    37  			data = data[1:]
    38  		}
    39  		return ndata, nil
    40  	}
    41  	if lpart == 0 && rpart == 0 { /* easy case */
    42  		for y = r.Min.Y; y < r.Max.Y; y++ {
    43  			copy(q[:l], data[:l])
    44  			q = q[i.Width*4:]
    45  			data = data[l:]
    46  		}
    47  		return ndata, nil
    48  	}
    49  	mr := uint8(0xFF) ^ (0xFF >> rpart)
    50  	if lpart != 0 && rpart == 0 {
    51  		for y = r.Min.Y; y < r.Max.Y; y++ {
    52  			q[0] ^= (data[0] ^ q[0]) & m
    53  			if l > 1 {
    54  				copy(q[1:l], data[1:l])
    55  			}
    56  			q = q[i.Width*4:]
    57  			data = data[l:]
    58  		}
    59  		return ndata, nil
    60  	}
    61  	if lpart == 0 && rpart != 0 {
    62  		for y = r.Min.Y; y < r.Max.Y; y++ {
    63  			if l > 1 {
    64  				copy(q[:l-1], data[:l-1])
    65  			}
    66  			q[l-1] ^= (data[l-1] ^ q[l-1]) & mr
    67  			q = q[i.Width*4:]
    68  			data = data[l:]
    69  		}
    70  		return ndata, nil
    71  	}
    72  	for y = r.Min.Y; y < r.Max.Y; y++ {
    73  		q[0] ^= (data[0] ^ q[0]) & m
    74  		if l > 2 {
    75  			copy(q[1:l-1], data[1:l-1])
    76  		}
    77  		q[l-1] ^= (data[l-1] ^ q[l-1]) & mr
    78  		q = q[i.Width*4:]
    79  		data = data[l:]
    80  	}
    81  	return ndata, nil
    82  }