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

     1  package draw
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"strings"
     7  )
     8  
     9  var ldepthToPix = []Pix{
    10  	GREY1,
    11  	GREY2,
    12  	GREY4,
    13  	CMAP8,
    14  }
    15  
    16  func (d *Display) creadimage(rd io.Reader) (*Image, error) {
    17  	fd := rd
    18  	hdr := make([]byte, 5*12)
    19  
    20  	_, err := io.ReadFull(fd, hdr)
    21  	if err != nil {
    22  		return nil, fmt.Errorf("reading image header: %v", err)
    23  	}
    24  
    25  	/*
    26  	 * distinguish new channel descriptor from old ldepth.
    27  	 * channel descriptors have letters as well as numbers,
    28  	 * while ldepths are a single digit formatted as %-11d.
    29  	 */
    30  	new := false
    31  	for m := 0; m < 10; m++ {
    32  		if hdr[m] != ' ' {
    33  			new = true
    34  			break
    35  		}
    36  	}
    37  	if hdr[11] != ' ' {
    38  		return nil, fmt.Errorf("creadimage: bad format")
    39  	}
    40  	var pix Pix
    41  	if new {
    42  		pix, err = ParsePix(strings.TrimSpace(string(hdr[:12])))
    43  		if err != nil {
    44  			return nil, fmt.Errorf("creadimage: %v", err)
    45  		}
    46  	} else {
    47  		ldepth := int(hdr[10]) - '0'
    48  		if ldepth < 0 || ldepth > 3 {
    49  			return nil, fmt.Errorf("creadimage: bad ldepth %d", ldepth)
    50  		}
    51  		pix = ldepthToPix[ldepth]
    52  	}
    53  	r := ator(hdr[1*12:])
    54  	if r.Min.X > r.Max.X || r.Min.Y > r.Max.Y {
    55  		return nil, fmt.Errorf("creadimage: bad rectangle")
    56  	}
    57  
    58  	var i *Image
    59  	if d != nil {
    60  		i, err = d.allocImage(r, pix, false, 0)
    61  		if err != nil {
    62  			return nil, err
    63  		}
    64  	} else {
    65  		i = &Image{R: r, Pix: pix, Depth: pix.Depth()}
    66  	}
    67  
    68  	ncblock := compblocksize(r, pix.Depth())
    69  	buf := make([]byte, ncblock)
    70  	miny := r.Min.Y
    71  	for miny != r.Max.Y {
    72  		if _, err = io.ReadFull(fd, hdr[:2*12]); err != nil {
    73  			goto Errout
    74  		}
    75  		maxy := atoi(hdr[0*12:])
    76  		nb := atoi(hdr[1*12:])
    77  		if maxy <= miny || r.Max.Y < maxy {
    78  			err = fmt.Errorf("creadimage: bad maxy %d", maxy)
    79  			goto Errout
    80  		}
    81  		if nb <= 0 || ncblock < nb {
    82  			err = fmt.Errorf("creadimage: bad count %d", nb)
    83  			goto Errout
    84  		}
    85  		if _, err = io.ReadFull(fd, buf[:nb]); err != nil {
    86  			goto Errout
    87  		}
    88  		if d != nil {
    89  			a := d.bufimage(21 + nb)
    90  			// XXX err
    91  			if err != nil {
    92  				goto Errout
    93  			}
    94  			a[0] = 'Y'
    95  			bplong(a[1:], i.id)
    96  			bplong(a[5:], uint32(r.Min.X))
    97  			bplong(a[9:], uint32(miny))
    98  			bplong(a[13:], uint32(r.Max.X))
    99  			bplong(a[17:], uint32(maxy))
   100  			if !new { // old image: flip the data bits
   101  				twiddlecompressed(buf[:nb])
   102  			}
   103  			copy(a[21:], buf)
   104  		}
   105  		miny = maxy
   106  	}
   107  	return i, nil
   108  
   109  Errout:
   110  	if d != nil {
   111  		i.free()
   112  	}
   113  	return nil, err
   114  }