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 }