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

     1  package draw
     2  
     3  import "fmt"
     4  
     5  // Unload reads a rectangle of pixels from image i into data,
     6  // returning the number of bytes copied to data.
     7  // It is an error if data does not contain pixels for the entire rectangle.
     8  //
     9  // See the Load method's documentation for details about the data format.
    10  func (i *Image) Unload(r Rectangle, data []byte) (n int, err error) {
    11  	i.Display.mu.Lock()
    12  	defer i.Display.mu.Unlock()
    13  	return i.unload(r, data)
    14  }
    15  
    16  func (src *Image) unload(r Rectangle, data []byte) (n int, err error) {
    17  	i := src
    18  	if !r.In(i.R) {
    19  		return 0, fmt.Errorf("image.Unload: bad rectangle")
    20  	}
    21  	bpl := BytesPerLine(r, i.Depth)
    22  	if len(data) < bpl*r.Dy() {
    23  		return 0, fmt.Errorf("image.Unload: buffer too small")
    24  	}
    25  
    26  	d := i.Display
    27  	d.flush(false) // make sure next flush is only us
    28  	ntot := 0
    29  	for r.Min.Y < r.Max.Y {
    30  		a := d.bufimage(1 + 4 + 4*4)
    31  		dy := 8000 / bpl
    32  		if dy <= 0 {
    33  			return 0, fmt.Errorf("unloadimage: image too wide")
    34  		}
    35  		if dy > r.Dy() {
    36  			dy = r.Dy()
    37  		}
    38  		a[0] = 'r'
    39  		bplong(a[1:], uint32(i.id))
    40  		bplong(a[5:], uint32(r.Min.X))
    41  		bplong(a[9:], uint32(r.Min.Y))
    42  		bplong(a[13:], uint32(r.Max.X))
    43  		bplong(a[17:], uint32(r.Min.Y+dy))
    44  		if err := d.flush(false); err != nil {
    45  			return ntot, err
    46  		}
    47  		n, err := d.conn.ReadDraw(data[ntot:])
    48  		ntot += n
    49  		if err != nil {
    50  			return ntot, err
    51  		}
    52  		r.Min.Y += dy
    53  	}
    54  	return ntot, nil
    55  }