Example #1
0
func testEncodeAll(t *testing.T, go1Dot5Fields bool, useGlobalColorModel bool) {
	const width, height = 150, 103

	g0 := &GIF{
		Image:     make([]*image.Paletted, len(frames)),
		Delay:     make([]int, len(frames)),
		LoopCount: 5,
	}
	for i, f := range frames {
		g, err := readGIF(f)
		if err != nil {
			t.Fatal(f, err)
		}
		m := g.Image[0]
		if m.Bounds().Dx() != width || m.Bounds().Dy() != height {
			t.Fatalf("frame %d had unexpected bounds: got %v, want width/height = %d/%d",
				i, m.Bounds(), width, height)
		}
		g0.Image[i] = m
	}
	// The GIF.Disposal, GIF.Config and GIF.BackgroundIndex fields were added
	// in Go 1.5. Valid Go 1.4 or earlier code should still produce valid GIFs.
	//
	// On the following line, color.Model is an interface type, and
	// color.Palette is a concrete (slice) type.
	globalColorModel, backgroundIndex := color.Model(color.Palette(nil)), uint8(0)
	if useGlobalColorModel {
		globalColorModel, backgroundIndex = color.Palette(palette.WebSafe), uint8(1)
	}
	if go1Dot5Fields {
		g0.Disposal = make([]byte, len(g0.Image))
		for i := range g0.Disposal {
			g0.Disposal[i] = DisposalNone
		}
		g0.Config = image.Config{
			ColorModel: globalColorModel,
			Width:      width,
			Height:     height,
		}
		g0.BackgroundIndex = backgroundIndex
	}

	var buf bytes.Buffer
	if err := EncodeAll(&buf, g0); err != nil {
		t.Fatal("EncodeAll:", err)
	}
	encoded := buf.Bytes()
	config, err := DecodeConfig(bytes.NewReader(encoded))
	if err != nil {
		t.Fatal("DecodeConfig:", err)
	}
	g1, err := DecodeAll(bytes.NewReader(encoded))
	if err != nil {
		t.Fatal("DecodeAll:", err)
	}

	if !reflect.DeepEqual(config, g1.Config) {
		t.Errorf("DecodeConfig inconsistent with DecodeAll")
	}
	if !palettesEqual(g1.Config.ColorModel.(color.Palette), globalColorModel.(color.Palette)) {
		t.Errorf("unexpected global color model")
	}
	if w, h := g1.Config.Width, g1.Config.Height; w != width || h != height {
		t.Errorf("got config width * height = %d * %d, want %d * %d", w, h, width, height)
	}

	if g0.LoopCount != g1.LoopCount {
		t.Errorf("loop counts differ: %d and %d", g0.LoopCount, g1.LoopCount)
	}
	if backgroundIndex != g1.BackgroundIndex {
		t.Errorf("background indexes differ: %d and %d", backgroundIndex, g1.BackgroundIndex)
	}
	if len(g0.Image) != len(g1.Image) {
		t.Fatalf("image lengths differ: %d and %d", len(g0.Image), len(g1.Image))
	}
	if len(g1.Image) != len(g1.Delay) {
		t.Fatalf("image and delay lengths differ: %d and %d", len(g1.Image), len(g1.Delay))
	}
	if len(g1.Image) != len(g1.Disposal) {
		t.Fatalf("image and disposal lengths differ: %d and %d", len(g1.Image), len(g1.Disposal))
	}

	for i := range g0.Image {
		m0, m1 := g0.Image[i], g1.Image[i]
		if m0.Bounds() != m1.Bounds() {
			t.Errorf("frame %d: bounds differ: %v and %v", i, m0.Bounds(), m1.Bounds())
		}
		d0, d1 := g0.Delay[i], g1.Delay[i]
		if d0 != d1 {
			t.Errorf("frame %d: delay values differ: %d and %d", i, d0, d1)
		}
		p0, p1 := uint8(0), g1.Disposal[i]
		if go1Dot5Fields {
			p0 = DisposalNone
		}
		if p0 != p1 {
			t.Errorf("frame %d: disposal values differ: %d and %d", i, p0, p1)
		}
	}
}
Example #2
0
	for i, r := range chars {
		y := uint32(i * value)
		y |= y << 8
		c := TextColor{r, y}
		pal[i] = &c
	}

	return pal
}

// slice of *TextColor -> color.Palette
func NewPalette(p []*TextColor) color.Palette {
	pal := make([]color.Color, len(p))
	for i, r := range p {
		pal[i] = color.Color(r)
	}
	return pal
}

// default Palette
var (
	DefaultSet      = MakeTextColors([]rune(" .:oO8@")...)
	AlternateSet    = MakeTextColors([]rune(" .:;+=xX$&")...)
	SciSet          = MakeTextColors([]rune("  .,-+=:;/XHM%@#$$")...)
	UnicodeBoxSet   = MakeTextColors([]rune(" ▏▎▍▌▋▊")...)
	UnicodeShadeSet = MakeTextColors([]rune(" .░▒▓■")...)
)

// The color model for ASCII images
var TextModel color.Model = color.Model(NewPalette(DefaultSet))