9fans.net/go@v0.0.5/draw/memdraw/cload.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 // Compressed image file parameters. 15 const ( 16 _NMATCH = 3 /* shortest match possible */ 17 _NRUN = (_NMATCH + 31) /* longest match possible */ 18 _NMEM = 1024 /* window size */ 19 _NDUMP = 128 /* maximum length of dump */ 20 _NCBLOCK = 6000 /* size of compressed blocks */ 21 ) 22 23 func cloadmemimage(i *Image, r draw.Rectangle, data []uint8) (int, error) { 24 if !draw.RectInRect(r, i.R) { 25 return 0, fmt.Errorf("invalid rectangle") 26 } 27 bpl := draw.BytesPerLine(r, i.Depth) 28 u := data 29 var mem [_NMEM]byte 30 memp := mem[:] 31 y := r.Min.Y 32 linep := byteaddr(i, draw.Pt(r.Min.X, y)) 33 linep = linep[:bpl] 34 for { 35 if len(linep) == 0 { 36 y++ 37 if y == r.Max.Y { 38 break 39 } 40 linep = byteaddr(i, draw.Pt(r.Min.X, y)) 41 linep = linep[:bpl] 42 } 43 if len(u) == 0 { /* buffer too small */ 44 return len(data) - len(u), fmt.Errorf("buffer too small") 45 } 46 c := u[0] 47 u = u[1:] 48 if c >= 128 { 49 for cnt := c - 128 + 1; cnt != 0; cnt-- { 50 if len(u) == 0 { /* buffer too small */ 51 return len(data) - len(u), fmt.Errorf("buffer too small") 52 } 53 if len(linep) == 0 { /* phase error */ 54 return len(data) - len(u), fmt.Errorf("phase error") 55 } 56 linep[0] = u[0] 57 linep = linep[1:] 58 memp[0] = u[0] 59 memp = memp[1:] 60 u = u[1:] 61 if len(memp) == 0 { 62 memp = mem[:] 63 } 64 } 65 } else { 66 if len(u) == 0 { /* short buffer */ 67 return len(data) - len(u), fmt.Errorf("buffer too small") 68 } 69 offs := int(u[0]) + (int(c&3) << 8) + 1 70 u = u[1:] 71 var omemp []byte 72 if δ := len(mem) - len(memp); δ < offs { 73 omemp = mem[δ+(_NMEM-offs):] 74 } else { 75 omemp = mem[δ-offs:] 76 } 77 for cnt := (c >> 2) + _NMATCH; cnt != 0; cnt-- { 78 if len(linep) == 0 { /* phase error */ 79 return len(data) - len(u), fmt.Errorf("phase error") 80 } 81 linep[0] = omemp[0] 82 linep = linep[1:] 83 memp[0] = omemp[0] 84 memp = memp[1:] 85 omemp = omemp[1:] 86 if len(omemp) == 0 { 87 omemp = mem[:] 88 } 89 if len(memp) == 0 { 90 memp = mem[:] 91 } 92 } 93 } 94 } 95 return len(data) - len(u), nil 96 }