1// +build wasm,js
2
3package psd
4
5import (
6	"io"
7)
8
9func decodePackBits(dest []byte, r io.Reader, width int, lines int, large bool) (read int, err error) {
10	buf := make([]byte, lines*(get4or8(large)>>1))
11	var l int
12	if l, err = io.ReadFull(r, buf); err != nil {
13		return
14	}
15	read += l
16
17	total := 0
18	lens := make([]int, lines)
19	offsets := make([]int, lines)
20	ofs := 0
21	if large {
22		for i := range lens {
23			l = int(readUint32(buf, ofs))
24			lens[i] = l
25			offsets[i] = total
26			total += l
27			ofs += 4
28		}
29	} else {
30		for i := range lens {
31			l = int(readUint16(buf, ofs))
32			lens[i] = l
33			offsets[i] = total
34			total += l
35			ofs += 2
36		}
37	}
38
39	buf = make([]byte, total)
40	if l, err = io.ReadFull(r, buf); err != nil {
41		return
42	}
43	read += l
44
45	err = decodePackBitsPerLine(dest, buf, lens)
46	return
47}
48
49func decodePackBitsPerLine(dest []byte, buf []byte, lens []int) error {
50	var l int
51	for _, ln := range lens {
52		for i := 0; i < ln; {
53			if buf[i] <= 0x7f {
54				l = int(buf[i]) + 1
55				if len(dest) < l || ln-i-1 < l {
56					return errBrokenPackBits
57				}
58				copy(dest[:l], buf[i+1:])
59				dest = dest[l:]
60				i += l + 1
61				continue
62			}
63			if buf[i] == 0x80 {
64				i++
65				continue
66			}
67			l = int(-buf[i]) + 1
68			if len(dest) < l || i+1 >= ln {
69				return errBrokenPackBits
70			}
71			for j, c := 0, buf[i+1]; j < l; j++ {
72				dest[j] = c
73			}
74			dest = dest[l:]
75			i += 2
76		}
77		buf = buf[ln:]
78	}
79	return nil
80}
81