예제 #1
0
// 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")
}
예제 #2
0
// 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
}
예제 #3
0
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
}