package rardecode type ppm29Decoder struct { m model // ppm model esc byte // escape character br *rarBitReader } func (d *ppm29Decoder) init(br *rarBitReader) error { maxOrder, err := br.readBits(7) if err != nil { return err } reset := maxOrder&0x20 > 0 d.br = br var maxMB int if reset { var c byte c, err = d.br.ReadByte() if err != nil { return err } maxMB = int(c) + 1 } if maxOrder&0x40 > 0 { d.esc, err = d.br.ReadByte() if err != nil { return err } } maxOrder = (maxOrder & 0x1f) + 1 if maxOrder > 16 { maxOrder = 16 + (maxOrder-16)*3 } return d.m.init(d.br, reset, maxOrder, maxMB) } func (d *ppm29Decoder) reset() { d.esc = 2 } func (d *ppm29Decoder) readFilterData() ([]byte, error) { c, err := d.m.ReadByte() if err != nil { return nil, err } n := int(c&7) + 1 if n == 7 { var b byte b, err = d.m.ReadByte() if err != nil { return nil, err } n += int(b) } else if n == 8 { var b byte b, err = d.m.ReadByte() if err != nil { return nil, err } n = int(b) << 8 b, err = d.m.ReadByte() if err != nil { return nil, err } n |= int(b) } n++ buf := make([]byte, n) buf[0] = c for i := 1; i < n; i++ { buf[i], err = d.m.ReadByte() if err != nil { return nil, err } } return buf, nil } // fill window until full, error, filter found or end of block. func (d *ppm29Decoder) fill(dr *decodeReader) ([]byte, error) { for dr.notFull() { c, err := d.m.ReadByte() if err != nil { return nil, err } if c != d.esc { dr.writeByte(c) continue } c, err = d.m.ReadByte() if err != nil { return nil, err } switch c { case 0: return nil, errEndOfBlock case 2: return nil, errEndOfBlockAndFile case 3: return d.readFilterData() case 4: offset := 0 for i := 0; i < 3; i++ { c, err = d.m.ReadByte() if err != nil { return nil, err } offset = offset<<8 | int(c) } len, err := d.m.ReadByte() if err != nil { return nil, err } dr.copyBytes(int(len)+32, offset+2) case 5: len, err := d.m.ReadByte() if err != nil { return nil, err } dr.copyBytes(int(len)+4, 1) default: dr.writeByte(d.esc) } } return nil, nil } func newPPM29Decoder() *ppm29Decoder { ppm := new(ppm29Decoder) ppm.reset() ppm.m.maxOrder = 2 ppm.m.a.init(1) return ppm }