Exemplo n.º 1
0
func make_lzw(t *Transport, config map[string]interface{}) (uint64, tagfn, tagfn) {
	var wbuf bytes.Buffer
	enc := func(in, out []byte) int {
		if len(in) == 0 {
			return 0
		}
		wbuf.Reset()
		writer := lzw.NewWriter(&wbuf, lzw.LSB, 8 /*litWidth*/)
		if _, err := writer.Write(in); err != nil {
			panic(err)
		}
		writer.Close()
		return copy(out, wbuf.Bytes())
	}
	dec := func(in, out []byte) int {
		if len(in) == 0 {
			return 0
		}
		reader := lzw.NewReader(bytes.NewReader(in), lzw.LSB, 8 /*litWidth*/)
		n, err := readAll(reader, out)
		if err != nil {
			panic(err)
		}
		reader.Close()
		return n
	}
	return tagLzw, enc, dec
}
Exemplo n.º 2
0
// UpdateDeps is used to update the values of the dependencies for a template
func (d *DedupManager) UpdateDeps(t *Template, deps []dep.Dependency) error {
	// Calculate the path to write updates to
	dataPath := path.Join(d.config.Deduplicate.Prefix, t.hexMD5, "data")

	// Package up the dependency data
	td := templateData{
		Data: make(map[string]interface{}),
	}
	for _, dp := range deps {
		// Skip any dependencies that can't be shared
		if !dp.CanShare() {
			continue
		}

		// Pull the current value from the brain
		val, ok := d.brain.Recall(dp)
		if ok {
			td.Data[dp.HashCode()] = val
		}
	}

	// Encode via GOB and LZW compress
	var buf bytes.Buffer
	compress := lzw.NewWriter(&buf, lzw.LSB, 8)
	enc := gob.NewEncoder(compress)
	if err := enc.Encode(&td); err != nil {
		return fmt.Errorf("encode failed: %v", err)
	}
	compress.Close()

	// Compute MD5 of the buffer
	hash := md5.Sum(buf.Bytes())
	d.lastWriteLock.RLock()
	existing, ok := d.lastWrite[t]
	d.lastWriteLock.RUnlock()
	if ok && bytes.Equal(existing, hash[:]) {
		log.Printf("[INFO] (dedup) de-duplicate data '%s' already current",
			dataPath)
		return nil
	}

	// Write the KV update
	kvPair := consulapi.KVPair{
		Key:   dataPath,
		Value: buf.Bytes(),
		Flags: templateDataFlag,
	}
	client, err := d.clients.Consul()
	if err != nil {
		return fmt.Errorf("failed to get consul client: %v", err)
	}
	if _, err := client.KV().Put(&kvPair, nil); err != nil {
		return fmt.Errorf("failed to write '%s': %v", dataPath, err)
	}
	log.Printf("[INFO] (dedup) updated de-duplicate data '%s'", dataPath)
	d.lastWriteLock.Lock()
	d.lastWrite[t] = hash[:]
	d.lastWriteLock.Unlock()
	return nil
}
Exemplo n.º 3
0
Arquivo: main.go Projeto: sevki/Posts
func compressLZW(s []byte) []byte {
	var b bytes.Buffer
	w := lzw.NewWriter(&b, lzw.LSB, 8)
	w.Write([]byte("hello, world\n"))
	defer w.Close()
	return b.Bytes()
}
Exemplo n.º 4
0
func TestNoPalette(t *testing.T) {
	b := &bytes.Buffer{}

	// Manufacture a GIF with no palette, so any pixel at all
	// will be invalid.
	b.WriteString(header[:len(header)-3])
	b.WriteString("\x00\x00\x00") // No global palette.

	// Image descriptor: 2x1, no local palette.
	b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")

	// Encode the pixels: neither is in range, because there is no palette.
	pix := []byte{0, 128}
	enc := &bytes.Buffer{}
	w := lzw.NewWriter(enc, lzw.LSB, 2)
	w.Write(pix)
	w.Close()
	b.WriteByte(byte(len(enc.Bytes())))
	b.Write(enc.Bytes())
	b.WriteByte(0x00) // An empty block signifies the end of the image data.

	b.WriteString(trailer)

	try(t, b.Bytes(), "gif: invalid pixel value")
}
Exemplo n.º 5
0
// lzwEncode returns an LZW encoding (with 2-bit literals) of n zeroes.
func lzwEncode(n int) []byte {
	b := &bytes.Buffer{}
	w := lzw.NewWriter(b, lzw.LSB, 2)
	w.Write(make([]byte, n))
	w.Close()
	return b.Bytes()
}
Exemplo n.º 6
0
func (e *encoder) writeFrame(index int) (err error) {
	e.buildFrameHeader(index)
	_, err = e.w.Write(e.frameHeader[:])
	if err != nil {
		return
	}

	codeSize := log2(e.colorTableSize + 2)
	_, err = e.w.Write([]byte{uint8(codeSize)}) // Start of LZW with minimum code size.
	if err != nil {
		return
	}

	lzww := lzw.NewWriter(&blockWriter{e.w, 0}, lzw.LSB, codeSize)
	_, err = lzww.Write(e.g.Image[index].Pix)
	lzww.Close()
	if err != nil {
		return
	}

	_, err = e.w.Write([]byte{uint8(0x00)}) // End of LZW data.
	if err != nil {
		return
	}

	return nil
}
Exemplo n.º 7
0
func RunTestLZW(data []byte) {
	log.Printf("encoding/RunTestLZW: Testing comprssion LZW\n")

	var compressed bytes.Buffer
	w := lzw.NewWriter(&compressed, lzw.MSB, 8)
	defer w.Close()
	now := time.Now()
	w.Write(data)

	cl := compressed.Len()
	log.Printf("encoding/RunTestLZW: Compressed from %d bytes to %d bytes in %d ns\n", len(data), cl, time.Since(now).Nanoseconds())

	recovered := make([]byte, len(data))
	r := lzw.NewReader(&compressed, lzw.MSB, 8)
	defer r.Close()

	total := 0
	n := 100
	var err error = nil
	for err != io.EOF && n != 0 {
		n, err = r.Read(recovered[total:])
		total += n
	}
	log.Printf("encoding/RunTestLZW: Uncompressed from %d bytes to %d bytes in %d ns\n", cl, len(recovered), time.Since(now).Nanoseconds())
}
Exemplo n.º 8
0
/*
compressRateLzw return compression rate of `text` as

	length of compressed text / length of text
*/
func compressRateLzw(text string) (float64, error) {
	var buf bytes.Buffer
	btext := []byte(text)
	btextlen := len(btext)

	if btextlen <= 0 {
		return 0, nil
	}

	w := lzw.NewWriter(&buf, lzw.MSB, 8)

	n, e := w.Write(btext)
	if e != nil {
		fmt.Printf("error: %s, rate: %d, len: %d\n", e, n, btextlen)
		return 1, e
	}

	e = w.Close()
	if e != nil {
		fmt.Printf("error: %s, rate: %d, len: %d\n", e, n, btextlen)
		return 1, e
	}

	return float64(buf.Len()) / float64(btextlen), nil
}
Exemplo n.º 9
0
func TestPixelOutsidePaletteRange(t *testing.T) {
	for _, pval := range []byte{0, 1, 2, 3, 255} {
		b := &bytes.Buffer{}

		// Manufacture a GIF with a 2 color palette.
		b.WriteString(header)
		b.WriteString(palette)

		// Image descriptor: 2x1, no local palette.
		b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")

		// Encode the pixels; some pvals trigger the expected error.
		pix := []byte{pval, pval}
		enc := &bytes.Buffer{}
		w := lzw.NewWriter(enc, lzw.LSB, 2)
		w.Write(pix)
		w.Close()
		b.WriteByte(byte(len(enc.Bytes())))
		b.Write(enc.Bytes())
		b.WriteByte(0x00) // An empty block signifies the end of the image data.

		b.WriteString(trailer)

		// No error expected, unless the pixels are beyond the 2 color palette.
		want := ""
		if pval >= 2 {
			want = "gif: invalid pixel value"
		}
		try(t, b.Bytes(), want)
	}
}
func lzwCompress(input io.Reader, out io.Writer) error {
	writer := lzw.NewWriter(out, lzw.MSB, 8)
	_, err := io.Copy(writer, input)
	if err != nil {
		return err
	}
	writer.Close()
	return nil
}
Exemplo n.º 11
0
func (self *LzwCompressor) Compress(src []byte) ([]byte, error) {
	cdest := bytes.NewBuffer(make([]byte, 0, len(src)))
	compressor := lzw.NewWriter(cdest, self.order, self.litWidth)
	compressor.Write(src)
	err := compressor.Close()
	if err != nil {
		fmt.Println("Compress Close err:%s", err.Error())
	}
	return cdest.Bytes(), err
}
Exemplo n.º 12
0
// Compress places the canary byte in a buffer and uses the same buffer to fill
// in the compressed information of the given input. The configuration supports
// two type of compression: LZW and Gzip. When using Gzip compression format,
// if GzipCompressionLevel is not specified, the 'gzip.DefaultCompression' will
// be assumed.
func Compress(data []byte, config *CompressionConfig) ([]byte, error) {
	var buf bytes.Buffer
	var writer io.WriteCloser
	var err error

	if config == nil {
		return nil, fmt.Errorf("config is nil")
	}

	// Write the canary into the buffer and create writer to compress the
	// input data based on the configured type
	switch config.Type {
	case CompressionTypeLzw:
		buf.Write([]byte{CompressionCanaryLzw})

		writer = lzw.NewWriter(&buf, lzw.LSB, 8)
	case CompressionTypeGzip:
		buf.Write([]byte{CompressionCanaryGzip})

		switch {
		case config.GzipCompressionLevel == gzip.BestCompression,
			config.GzipCompressionLevel == gzip.BestSpeed,
			config.GzipCompressionLevel == gzip.DefaultCompression:
			// These are valid compression levels
		default:
			// If compression level is set to NoCompression or to
			// any invalid value, fallback to Defaultcompression
			config.GzipCompressionLevel = gzip.DefaultCompression
		}
		writer, err = gzip.NewWriterLevel(&buf, config.GzipCompressionLevel)
	default:
		return nil, fmt.Errorf("unsupported compression type")
	}
	if err != nil {
		return nil, fmt.Errorf("failed to create a compression writer; err: %v", err)
	}

	if writer == nil {
		return nil, fmt.Errorf("failed to create a compression writer")
	}

	// Compress the input and place it in the same buffer containing the
	// canary byte.
	if _, err = writer.Write(data); err != nil {
		return nil, fmt.Errorf("failed to compress input data; err: %v", err)
	}

	// Close the io.WriteCloser
	if err = writer.Close(); err != nil {
		return nil, err
	}

	// Return the compressed bytes with canary byte at the start
	return buf.Bytes(), nil
}
Exemplo n.º 13
0
// lzwEncode returns an LZW encoding (with 2-bit literals) of in.
func lzwEncode(in []byte) []byte {
	b := &bytes.Buffer{}
	w := lzw.NewWriter(b, lzw.LSB, 2)
	if _, err := w.Write(in); err != nil {
		panic(err)
	}
	if err := w.Close(); err != nil {
		panic(err)
	}
	return b.Bytes()
}
Exemplo n.º 14
0
func LzwMustCompress(inb []byte) (outb []byte) {
	buf := &bytes.Buffer{}
	w := lzw.NewWriter(buf, lzw.LSB, 8)
	_, err := w.Write(inb)
	if err != nil {
		w.Close()
		panic(err)
	}
	err = w.Close()
	if err != nil {
		panic(err)
	}
	return buf.Bytes()
}
Exemplo n.º 15
0
// Sérialise le réseau à l'interrieur d'un fichier
func (self *Reto) Serialize(filename string) {
	file, err := os.Create(filename)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	stream := lzw.NewWriter(file, lzw.LSB, 8)
	defer stream.Close()
	encoder := json.NewEncoder(stream)
	encoder.Encode(self)
	if err != nil {
		log.Fatal(err)
	}
}
Exemplo n.º 16
0
func newStream(filter name) *stream {
	st := new(stream)
	st.filter = filter
	switch filter {
	case streamLZWDecode:
		st.writer = lzw.NewWriter(&st.Buffer, lzw.MSB, 8)
	case streamFlateDecode:
		st.writer = zlib.NewWriter(&st.Buffer)
	default:
		// TODO: warn about bad filter names?
		st.writer = &st.Buffer
	}
	return st
}
Exemplo n.º 17
0
func (e *Engine) lzw_lsb() error {
	var buf bytes.Buffer
	var litWidth int
	var err error
	litWidth, err = e.stack.PopInt()
	if err == nil {
		w := lzw.NewWriter(&buf, lzw.LSB, litWidth)
		_, err = w.Write(e.stack.Pop())
		w.Close()
	}
	if err == nil {
		e.stack.Push(buf.Bytes())
	}
	return err
}
Exemplo n.º 18
0
func main() {
	ugo.MaxProcs()
	ufs.NewDirWalker(false, nil, func(fullPath string) bool {
		blobs = append(blobs, ufs.ReadBinaryFile(fullPath, true))
		return true
	}).Walk(dirPath)

	testComp("flate1", func(w io.Writer) (wc io.WriteCloser) {
		var err error
		if wc, err = flate.NewWriter(w, 1); err != nil {
			panic(err)
		}
		return
	}, flate.NewReader)
	testComp("flate9", func(w io.Writer) (wc io.WriteCloser) {
		var err error
		if wc, err = flate.NewWriter(w, 9); err != nil {
			panic(err)
		}
		return
	}, flate.NewReader)
	testComp("lzw\t", func(w io.Writer) io.WriteCloser {
		return lzw.NewWriter(w, lzw.MSB, 8)
	}, func(r io.Reader) io.ReadCloser {
		return lzw.NewReader(r, lzw.MSB, 8)
	})
	testComp("zlib", func(w io.Writer) io.WriteCloser {
		return zlib.NewWriter(w)
	}, func(r io.Reader) (rc io.ReadCloser) {
		var err error
		if rc, err = zlib.NewReader(r); err != nil {
			panic(err)
		}
		return
	})
	testComp("gzip", func(w io.Writer) io.WriteCloser {
		return gzip.NewWriter(w)
	}, func(r io.Reader) (rc io.ReadCloser) {
		var err error
		if rc, err = gzip.NewReader(r); err != nil {
			panic(err)
		}
		return
	})
	printStats("PACK:", packStats)
	printStats("UNPACK:", unpackStats)
}
Exemplo n.º 19
0
func Fuzz(data []byte) int {
	r := lzw.NewReader(bytes.NewReader(data), lzw.MSB, 8)
	uncomp := make([]byte, 64<<10)
	n, err := r.Read(uncomp)
	if err != nil && err != io.EOF {
		return 0
	}
	if n == len(uncomp) {
		return 0 // too large
	}
	uncomp = uncomp[:n]
	for width := 2; width <= 8; width++ {
		uncomp0 := append([]byte{}, uncomp...)
		for i, v := range uncomp0 {
			uncomp0[i] = v & (1<<uint(width) - 1)
		}
		for _, order := range []lzw.Order{lzw.MSB, lzw.LSB} {
			buf := new(bytes.Buffer)
			w := lzw.NewWriter(buf, order, width)
			n, err := w.Write(uncomp0)
			if err != nil {
				fmt.Printf("order=%v width=%v\n", order, width)
				panic(err)
			}
			if n != len(uncomp0) {
				fmt.Printf("order=%v width=%v\n", order, width)
				panic("short write")
			}
			if err := w.Close(); err != nil {
				fmt.Printf("order=%v width=%v\n", order, width)
				panic(err)
			}
			r1 := lzw.NewReader(buf, order, width)
			uncomp1, err := ioutil.ReadAll(r1)
			if err != nil {
				fmt.Printf("order=%v width=%v\n", order, width)
				panic(err)
			}
			if !bytes.Equal(uncomp0, uncomp1) {
				fmt.Printf("order=%v width=%v\n", order, width)
				panic("data differs")
			}
		}
	}
	return 1
}
Exemplo n.º 20
0
func encodeImageBlock(w io.Writer, img *image.Paletted) error {

	// start image

	litWidth := int(paletteBits(img.Palette))
	if litWidth < 2 {
		litWidth = 2
	}

	bounds := img.Bounds()

	if err := writeData(w,
		byte(0x2C),
		uint16(bounds.Min.X), uint16(bounds.Min.Y), uint16(bounds.Dx()), uint16(bounds.Dy()),
		byte(0),
		byte(litWidth),
	); err != nil {
		return err
	}

	// start compression

	blocks := &blockWriter{w: w}
	compress := lzw.NewWriter(blocks, lzw.LSB, litWidth)

	// write each scan line (might not be contiguous)

	startX := img.Rect.Min.X
	stopX := img.Rect.Max.X
	stopY := img.Rect.Max.Y
	for y := img.Rect.Min.Y; y < stopY; y++ {
		start := img.PixOffset(startX, y)
		stop := img.PixOffset(stopX, y)
		if _, err := compress.Write(img.Pix[start:stop]); err != nil {
			return err
		}
	}

	if err := compress.Close(); err != nil {
		return err
	}

	return blocks.Close()
}
Exemplo n.º 21
0
func (p *wmDecisionCore) bodyEncoder(w io.Writer) (io.Writer, os.Error) {
	var outW io.Writer
	var err os.Error
	switch p.encoding {
	default:
		outW = w
	case "identity":
		outW = w
	case "deflate":
		outW = flate.NewWriter(w, 6)
	case "gzip":
		outW, err = gzip.NewWriter(w)
	case "lzw":
		outW = lzw.NewWriter(w, lzw.LSB, 8)
	case "zlib":
		outW, err = zlib.NewWriter(w)
	}
	return outW, err
}
Exemplo n.º 22
0
func main() {
	flag.Parse()
	fname := "event.gob"
	switch *compr {
	case "gzip":
		fname = fmt.Sprintf("%s.gz", fname)
	case "zlib":
		fname = fmt.Sprintf("%s.z", fname)
	case "lzw":
		fname = fmt.Sprintf("%s.lzw", fname)
	case "none", "":
		fname = fname
	default:
		fname = fname
	}

	f, err := os.Create(fname)
	if err != nil {
		panic(err)
	}

	var ff io.WriteCloser = nil
	switch *compr {
	case "gzip":
		ff = gzip.NewWriter(f)
	case "zlib":
		ff = zlib.NewWriter(f)
	case "lzw":
		ff = lzw.NewWriter(f, lzw.MSB, 8)
		err = nil
	default:
		ff = f
	}

	if err != nil {
		panic(err)
	}

	tree0(ff)
	ff.Close()
	f.Close()
}
Exemplo n.º 23
0
// compressPayload takes an opaque input buffer, compresses it
// and wraps it in a compress{} message that is encoded.
func compressPayload(inp []byte) (*bytes.Buffer, error) {
	var buf bytes.Buffer
	compressor := lzw.NewWriter(&buf, lzw.LSB, lzwLitWidth)

	_, err := compressor.Write(inp)
	if err != nil {
		return nil, err
	}

	// Ensure we flush everything out
	if err := compressor.Close(); err != nil {
		return nil, err
	}

	// Create a compressed message
	c := compress{
		Algo: lzwAlgo,
		Buf:  buf.Bytes(),
	}
	return encode(compressMsg, &c)
}
Exemplo n.º 24
0
func getCompressor(out io.Writer) io.WriteCloser {
	switch *algorithm {
	case "bzip2":
		log.Fatalf("no compressor for bzip2. Try `bzip2 -c everything.go > everything.go.bzip2`")
	case "flate":
		compressor, err := flate.NewWriter(out, flate.BestCompression)
		if err != nil {
			log.Fatalf("failed making flate compressor: %s", err)
		}
		return compressor
	case "gzip":
		return gzip.NewWriter(out)
	case "lzw":
		// More specific uses of Order and litWidth are in the package docs
		return lzw.NewWriter(out, lzw.MSB, 8)
	case "zlib":
		return zlib.NewWriter(out)
	default:
		log.Fatalf("choose one of bzip2, flate, gzip, lzw, zlib with -algorithm")
	}
	panic("not reached")
}
Exemplo n.º 25
0
func main() {

	var (
		file    string
		pngfile string
		size    int
		dpi     int
		minset  bool
		packstr bool
	)

	flag.StringVar(&file, "f", "font.ttf", "truetype font filename")
	flag.StringVar(&pngfile, "png", "", "filename for png result")
	flag.IntVar(&size, "pt", 12, "font size")
	flag.IntVar(&dpi, "dpi", 144, "resolution")
	flag.BoolVar(&minset, "min", false, "reduced set of characters")
	flag.BoolVar(&packstr, "lzw", false, "print lzw compressed and base64 encoded string")
	flag.Parse()

	data, err := ioutil.ReadFile(file)

	if err != nil {
		log.Fatal(err)
	}

	font, err := freetype.ParseFont(data)

	if err != nil {
		log.Fatal(err)
	}

	scale := int32(dpi * size)

	fc := freetype.NewContext()
	fc.SetDPI(float64(dpi))
	fc.SetHinting(freetype.FullHinting)
	fc.SetFontSize(float64(size))
	fc.SetFont(font)

	bounds := font.Bounds(scale)
	width := int((bounds.XMax-bounds.XMin)+71) / 72
	height := int((bounds.YMax-bounds.YMin)+71) / 72
	dx := int(-bounds.XMin+71) / 72
	dy := int(bounds.YMax+71) / 72

	offset := 0
	cols, rows := 32, 8

	if minset {
		offset = 32
		cols, rows = 16, 6
	}

	dst := image.NewAlpha(image.Rect(0, 0, width*cols, height*rows))

	fc.SetDst(dst)
	fc.SetSrc(image.White)
	fc.SetClip(dst.Bounds())

	maxAdvance := int32(0)

	for y := 0; y < rows; y++ {
		for x := 0; x < cols; x++ {
			c := y*cols + x + offset
			hm := font.HMetric(scale/72, font.Index(rune(c)))
			if maxAdvance < hm.AdvanceWidth {
				maxAdvance = hm.AdvanceWidth
			}
			p := freetype.Pt(x*width+dx, y*height+dy)
			fc.DrawString(string(c), p)
		}
	}

	fmt.Printf("// %vx%v\n", dst.Rect.Dx(), dst.Rect.Dy())
	fmt.Println("//", width, "x", height, "->", maxAdvance)

	if len(pngfile) > 0 {
		dstfile, err := os.Create(pngfile)
		if err != nil {
			log.Fatal(err)
		}
		defer dstfile.Close()
		png.Encode(dstfile, dst)
	}

	if packstr {
		var b bytes.Buffer

		e := base64.NewEncoder(base64.StdEncoding, &b)
		w := lzw.NewWriter(e, lzw.MSB, 8)
		w.Write(dst.Pix)
		w.Close()
		e.Close()

		nbytes := len(b.Bytes())
		linelen := 72
		rows := nbytes / linelen

		fmt.Println("//", nbytes)

		for r := 0; r < rows; r++ {
			slice := b.Bytes()[r*linelen : (r+1)*linelen]
			fmt.Printf("\"%s\"\n", slice)
		}

		if rows*linelen < nbytes {
			fmt.Printf("\"%s\"\n", b.Bytes()[rows*linelen:])
		}
	}

	if len(pngfile) == 0 && !packstr {
		nbytes := len(dst.Pix)
		cols := 12
		rows := nbytes / cols
		for y := 0; y < rows; y++ {
			for x := 0; x < cols; x++ {
				fmt.Printf(" %#02x,", dst.Pix[y*cols+x])
			}
			fmt.Println("")
		}

		for r := rows * cols; r < nbytes; r++ {
			fmt.Printf(" %#02x,", dst.Pix[r])
		}
		fmt.Println("")
	}
}
Exemplo n.º 26
0
func (c compressor) GetWriter(w io.Writer) io.WriteCloser {
	return lzw.NewWriter(w, lzw.LSB, 8)
}
Exemplo n.º 27
0
func (e *encoder) writeImageBlock(pm *image.Paletted, delay int, disposal byte) {
	if e.err != nil {
		return
	}

	if len(pm.Palette) == 0 {
		e.err = errors.New("gif: cannot encode image block with empty palette")
		return
	}

	b := pm.Bounds()
	if b.Min.X < 0 || b.Max.X >= 1<<16 || b.Min.Y < 0 || b.Max.Y >= 1<<16 {
		e.err = errors.New("gif: image block is too large to encode")
		return
	}
	if !b.In(image.Rectangle{Max: image.Point{e.g.Config.Width, e.g.Config.Height}}) {
		e.err = errors.New("gif: image block is out of bounds")
		return
	}

	transparentIndex := -1
	for i, c := range pm.Palette {
		if _, _, _, a := c.RGBA(); a == 0 {
			transparentIndex = i
			break
		}
	}

	if delay > 0 || disposal != 0 || transparentIndex != -1 {
		e.buf[0] = sExtension  // Extension Introducer.
		e.buf[1] = gcLabel     // Graphic Control Label.
		e.buf[2] = gcBlockSize // Block Size.
		if transparentIndex != -1 {
			e.buf[3] = 0x01 | disposal<<2
		} else {
			e.buf[3] = 0x00 | disposal<<2
		}
		writeUint16(e.buf[4:6], uint16(delay)) // Delay Time (1/100ths of a second)

		// Transparent color index.
		if transparentIndex != -1 {
			e.buf[6] = uint8(transparentIndex)
		} else {
			e.buf[6] = 0x00
		}
		e.buf[7] = 0x00 // Block Terminator.
		e.write(e.buf[:8])
	}
	e.buf[0] = sImageDescriptor
	writeUint16(e.buf[1:3], uint16(b.Min.X))
	writeUint16(e.buf[3:5], uint16(b.Min.Y))
	writeUint16(e.buf[5:7], uint16(b.Dx()))
	writeUint16(e.buf[7:9], uint16(b.Dy()))
	e.write(e.buf[:9])

	paddedSize := log2(len(pm.Palette)) // Size of Local Color Table: 2^(1+n).
	ct := encodeColorTable(e.localColorTable[:], pm.Palette, paddedSize)
	if ct != e.globalCT || !bytes.Equal(e.globalColorTable[:ct], e.localColorTable[:ct]) {
		// Use a local color table.
		e.writeByte(fColorTable | uint8(paddedSize))
		e.write(e.localColorTable[:ct])
	} else {
		// Use the global color table.
		e.writeByte(0)
	}

	litWidth := paddedSize + 1
	if litWidth < 2 {
		litWidth = 2
	}
	e.writeByte(uint8(litWidth)) // LZW Minimum Code Size.

	lzww := lzw.NewWriter(blockWriter{e: e}, lzw.LSB, litWidth)
	if dx := b.Dx(); dx == pm.Stride {
		_, e.err = lzww.Write(pm.Pix)
		if e.err != nil {
			lzww.Close()
			return
		}
	} else {
		for i, y := 0, b.Min.Y; y < b.Max.Y; i, y = i+pm.Stride, y+1 {
			_, e.err = lzww.Write(pm.Pix[i : i+dx])
			if e.err != nil {
				lzww.Close()
				return
			}
		}
	}
	lzww.Close()
	e.writeByte(0x00) // Block Terminator.
}
Exemplo n.º 28
0
func compressStream(file io.WriteCloser) io.WriteCloser {
	return lzw.NewWriter(file, lzw.LSB, 8)
}
Exemplo n.º 29
0
func TestDecode(t *testing.T) {
	// lzwEncode returns an LZW encoding (with 2-bit literals) of n zeroes.
	lzwEncode := func(n int) []byte {
		b := &bytes.Buffer{}
		w := lzw.NewWriter(b, lzw.LSB, 2)
		w.Write(make([]byte, n))
		w.Close()
		return b.Bytes()
	}

	testCases := []struct {
		nPix    int  // The number of pixels in the image data.
		extra   bool // Whether to write an extra block after the LZW-encoded data.
		wantErr error
	}{
		{0, false, errNotEnough},
		{1, false, errNotEnough},
		{2, false, nil},
		{2, true, errTooMuch},
		{3, false, errTooMuch},
	}
	for _, tc := range testCases {
		b := &bytes.Buffer{}
		b.WriteString(header)
		b.WriteString(palette)
		// Write an image with bounds 2x1 but tc.nPix pixels. If tc.nPix != 2
		// then this should result in an invalid GIF image. First, write a
		// magic 0x2c (image descriptor) byte, bounds=(0,0)-(2,1), a flags
		// byte, and 2-bit LZW literals.
		b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")
		if tc.nPix > 0 {
			enc := lzwEncode(tc.nPix)
			if len(enc) > 0xff {
				t.Errorf("nPix=%d, extra=%t: compressed length %d is too large", tc.nPix, tc.extra, len(enc))
				continue
			}
			b.WriteByte(byte(len(enc)))
			b.Write(enc)
		}
		if tc.extra {
			b.WriteString("\x01\x02") // A 1-byte payload with an 0x02 byte.
		}
		b.WriteByte(0x00) // An empty block signifies the end of the image data.
		b.WriteString(trailer)

		got, err := Decode(b)
		if err != tc.wantErr {
			t.Errorf("nPix=%d, extra=%t\ngot  %v\nwant %v", tc.nPix, tc.extra, err, tc.wantErr)
		}

		if tc.wantErr != nil {
			continue
		}
		want := &image.Paletted{
			Pix:    []uint8{0, 0},
			Stride: 2,
			Rect:   image.Rect(0, 0, 2, 1),
			Palette: color.Palette{
				color.RGBA{0x10, 0x20, 0x30, 0xff},
				color.RGBA{0x40, 0x50, 0x60, 0xff},
			},
		}
		if !reflect.DeepEqual(got, want) {
			t.Errorf("nPix=%d, extra=%t\ngot  %v\nwant %v", tc.nPix, tc.extra, got, want)
		}
	}
}
Exemplo n.º 30
0
func (e *encoder) writeImageBlock(pm *image.Paletted, delay, transparentIndex int) {
	if e.err != nil {
		return
	}

	if len(pm.Palette) == 0 {
		e.err = errors.New("gif: cannot encode image block with empty palette")
		return
	}

	b := pm.Bounds()
	if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 || b.Min.X < 0 || b.Min.X >= 1<<16 || b.Min.Y < 0 || b.Min.Y >= 1<<16 {
		e.err = errors.New("gif: image block is too large to encode")
		return
	}

	// -1 means unknown transparent index; -2 means definitely no transparent index.
	if transparentIndex == -1 {
		for i, c := range pm.Palette {
			if _, _, _, a := c.RGBA(); a == 0 {
				transparentIndex = i
				break
			}
		}
		transparentIndex = -2
	}

	if delay > 0 || transparentIndex >= 0 {
		e.buf[0] = sExtension  // Extension Introducer.
		e.buf[1] = gcLabel     // Graphic Control Label.
		e.buf[2] = gcBlockSize // Block Size.
		if transparentIndex >= 0 {
			e.buf[3] = 0x01
		} else {
			e.buf[3] = 0x00
		}
		writeUint16(e.buf[4:6], uint16(delay)) // Delay Time (1/100ths of a second)

		// Transparent color index.
		if transparentIndex >= 0 {
			e.buf[6] = uint8(transparentIndex)
		} else {
			e.buf[6] = 0x00
		}
		e.buf[7] = 0x00 // Block Terminator.
		e.write(e.buf[:8])
	}
	e.buf[0] = sImageDescriptor
	writeUint16(e.buf[1:3], uint16(b.Min.X))
	writeUint16(e.buf[3:5], uint16(b.Min.Y))
	writeUint16(e.buf[5:7], uint16(b.Dx()))
	writeUint16(e.buf[7:9], uint16(b.Dy()))
	e.write(e.buf[:9])

	paddedSize := log2(len(pm.Palette)) // Size of Local Color Table: 2^(1+n).
	// Interlacing is not supported.
	e.writeByte(0x80 | uint8(paddedSize))

	// Local Color Table.
	e.writeColorTable(pm.Palette, paddedSize)

	litWidth := paddedSize + 1
	if litWidth < 2 {
		litWidth = 2
	}
	e.writeByte(uint8(litWidth)) // LZW Minimum Code Size.

	lzww := lzw.NewWriter(blockWriter{e: e}, lzw.LSB, litWidth)
	_, e.err = lzww.Write(pm.Pix)
	if e.err != nil {
		lzww.Close()
		return
	}
	lzww.Close()
	e.writeByte(0x00) // Block Terminator.
}