// ParseGitBinary parses raw as a Git binary patch. func ParseGitBinary(raw []byte) (Diff, os.Error) { var oldSHA1, newSHA1 []byte var sawBinary bool for { var first []byte first, raw, _ = getLine(raw, 1) first = bytes.TrimSpace(first) if s, ok := skip(first, "index "); ok { oldSHA1, s = getHex(s) if s, ok = skip(s, ".."); !ok { continue } newSHA1, s = getHex(s) continue } if _, ok := skip(first, "GIT binary patch"); ok { sawBinary = true continue } if n, _, ok := atoi(first, "literal ", 10); ok && sawBinary { data := make([]byte, n) d := git85.NewDecoder(bytes.NewBuffer(raw)) z, err := zlib.NewInflater(d) if err != nil { return nil, err } defer z.Close() if _, err = io.ReadFull(z, data); err != nil { if err == os.EOF { err = io.ErrUnexpectedEOF } return nil, err } var buf [1]byte m, err := z.Read(&buf) if m != 0 || err != os.EOF { return nil, os.NewError("Git binary literal longer than expected") } if sum := gitSHA1(data); !bytes.HasPrefix(sum, newSHA1) { return nil, os.NewError("Git binary literal SHA1 mismatch") } return &GitBinaryLiteral{oldSHA1, data}, nil } if !sawBinary { return nil, os.NewError("unexpected Git patch header: " + string(first)) } } panic("unreachable") }
// pd.DecodedStream() returns decoded contents of a stream. func (pd *PdfReaderT) DecodedStream(reference []byte) (DictionaryT, []byte) { dic, data := pd.Stream(reference) if f, ok := dic["/Filter"]; ok { filter := pd.ForcedArray(f) var decos [][]byte if d, ok := dic["/DecodeParams"]; ok { decos = pd.ForcedArray(d) } else { decos = make([][]byte, len(filter)) } for ff := range filter { deco := pd.Dic(decos[ff]) switch string(filter[ff]) { case "/FlateDecode": data = fancy.ReadAndClose(zlib.NewInflater(fancy.SliceReader(data))) case "/LZWDecode": early := true if deco != nil { if s, ok := deco["/EarlyChange"]; ok { early = pd.Num(s) == 1 } } data = lzw.Decode(data, early) case "/ASCII85Decode": ds := data for len(ds) > 1 && ds[len(ds)-1] < 33 { ds = ds[0 : len(ds)-1] } if len(ds) >= 2 && ds[len(ds)-1] == '>' && ds[len(ds)-2] == '~' { ds = ds[0 : len(ds)-2] } data = fancy.ReadAll(ascii85.NewDecoder(fancy.SliceReader(ds))) case "/ASCIIHexDecode": data = hex.Decode(string(data)) default: data = []byte{} } } } return dic, data }
func (d *decoder) idatReader(idat io.Reader) os.Error { r, err := zlib.NewInflater(idat) if err != nil { return err } defer r.Close() bpp := 0 // Bytes per pixel. maxPalette := uint8(0) var ( rgba *image.RGBA nrgba *image.NRGBA paletted *image.Paletted ) switch d.colorType { case ctTrueColor: bpp = 3 rgba = d.image.(*image.RGBA) case ctPaletted: bpp = 1 paletted = d.image.(*image.Paletted) maxPalette = uint8(len(paletted.Palette) - 1) case ctTrueColorAlpha: bpp = 4 nrgba = d.image.(*image.NRGBA) } // cr and pr are the bytes for the current and previous row. // The +1 is for the per-row filter type, which is at cr[0]. cr := make([]uint8, 1+bpp*d.width) pr := make([]uint8, 1+bpp*d.width) for y := 0; y < d.height; y++ { // Read the decompressed bytes. _, err := io.ReadFull(r, cr) if err != nil { return err } // Apply the filter. cdat := cr[1:] pdat := pr[1:] switch cr[0] { case ftNone: // No-op. case ftSub: for i := bpp; i < len(cdat); i++ { cdat[i] += cdat[i-bpp] } case ftUp: for i := 0; i < len(cdat); i++ { cdat[i] += pdat[i] } case ftAverage: for i := 0; i < bpp; i++ { cdat[i] += pdat[i] / 2 } for i := bpp; i < len(cdat); i++ { cdat[i] += uint8((int(cdat[i-bpp]) + int(pdat[i])) / 2) } case ftPaeth: for i := 0; i < bpp; i++ { cdat[i] += paeth(0, pdat[i], 0) } for i := bpp; i < len(cdat); i++ { cdat[i] += paeth(cdat[i-bpp], pdat[i], pdat[i-bpp]) } default: return FormatError("bad filter type") } // Convert from bytes to colors. switch d.colorType { case ctTrueColor: for x := 0; x < d.width; x++ { rgba.Set(x, y, image.RGBAColor{cdat[3*x+0], cdat[3*x+1], cdat[3*x+2], 0xff}) } case ctPaletted: for x := 0; x < d.width; x++ { if cdat[x] > maxPalette { return FormatError("palette index out of range") } paletted.SetColorIndex(x, y, cdat[x]) } case ctTrueColorAlpha: for x := 0; x < d.width; x++ { nrgba.Set(x, y, image.NRGBAColor{cdat[4*x+0], cdat[4*x+1], cdat[4*x+2], cdat[4*x+3]}) } } // The current row for y is the previous row for y+1. pr, cr = cr, pr } return nil }