Exemple #1
0
func benchSpeed(b *testing.B, bt BenchType, asm bool) {
	raw := readImage(b, "testdata/lenna.jpg")
	src := image.NewYCbCr(image.Rect(0, 0, bt.win, bt.hin), image.YCbCrSubsampleRatio420)
	convert(b, src, raw, asm, bt.interlaced, bt.filter)
	dst := image.NewYCbCr(image.Rect(0, 0, bt.wout, bt.hout), image.YCbCrSubsampleRatio420)
	converter := prepare(b, dst, src, asm, bt.interlaced, bt.filter, 0)
	b.SetBytes(int64(bt.wout*bt.hout*3) >> 1)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		converter.Convert(dst, src)
	}
}
Exemple #2
0
func makeImages(r image.Rectangle) []image.Image {
	return []image.Image{
		image.NewGray(r),
		image.NewGray16(r),
		image.NewNRGBA(r),
		image.NewNRGBA64(r),
		image.NewPaletted(r, somePalette),
		image.NewRGBA(r),
		image.NewRGBA64(r),
		image.NewYCbCr(r, image.YCbCrSubsampleRatio444),
		image.NewYCbCr(r, image.YCbCrSubsampleRatio422),
		image.NewYCbCr(r, image.YCbCrSubsampleRatio420),
		image.NewYCbCr(r, image.YCbCrSubsampleRatio440),
	}
}
Exemple #3
0
func NewImageOfTypeRect(src image.Image, bounds image.Rectangle) image.Image {
	switch i := src.(type) {
	case *image.Alpha:
		return image.NewAlpha(bounds)
	case *image.Alpha16:
		return image.NewAlpha16(bounds)
	case *image.Gray:
		return image.NewGray(bounds)
	case *image.Gray16:
		return image.NewGray16(bounds)
	case *image.NRGBA:
		return image.NewNRGBA(bounds)
	case *image.NRGBA64:
		return image.NewNRGBA64(bounds)
	case *image.Paletted:
		return image.NewPaletted(bounds, i.Palette)
	case *image.RGBA:
		return image.NewRGBA(bounds)
	case *image.RGBA64:
		return image.NewRGBA64(bounds)
	case *image.YCbCr:
		return image.NewYCbCr(bounds, i.SubsampleRatio)
	}
	panic("Unknown image type")
}
Exemple #4
0
// makeImg allocates and initializes the destination image.
func (d *decoder) makeImg(h0, v0, mxx, myy int) {
	if d.jpegColorSpace == Grayscale {
		m := image.NewGray(image.Rect(0, 0, 8*mxx, 8*myy))
		d.img1 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.Gray)
		return
	} else if d.jpegColorSpace == YCbCr {
		var subsampleRatio image.YCbCrSubsampleRatio
		switch {
		case h0 == 1 && v0 == 1:
			subsampleRatio = image.YCbCrSubsampleRatio444
		case h0 == 1 && v0 == 2:
			subsampleRatio = image.YCbCrSubsampleRatio440
		case h0 == 2 && v0 == 1:
			subsampleRatio = image.YCbCrSubsampleRatio422
		case h0 == 2 && v0 == 2:
			subsampleRatio = image.YCbCrSubsampleRatio420
		default:
			panic("unreachable")
		}
		m := image.NewYCbCr(image.Rect(0, 0, 8*h0*mxx, 8*v0*myy), subsampleRatio)
		d.img3 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.YCbCr)
	} else if d.jpegColorSpace == RGBA {
		m := image.NewRGBA(image.Rect(0, 0, 8*h0*mxx, 8*v0*myy))
		d.img4 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.RGBA)
	} else {
	}
}
Exemple #5
0
func BenchmarkHalveYCrCb(b *testing.B) {
	m := image.NewYCbCr(orig, image.YCbCrSubsampleRatio422)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		halve(m)
	}
}
Exemple #6
0
func runTestCaseWith(t *testing.T, tc *TestCase, asm bool, cycles int) image.Image {
	srcRaw := readImage(t, "testdata/"+tc.file).(*image.YCbCr)
	dstRaw := image.NewYCbCr(image.Rect(0, 0, tc.dst.Max.X*2, tc.dst.Max.Y*2), srcRaw.SubsampleRatio)
	var src, dst, ref image.Image
	if tc.src.Empty() {
		tc.src = srcRaw.Bounds()
	}
	suffix := "yuv"
	if tc.rgb {
		suffix = "rgb"
		src = toRgb(srcRaw).SubImage(tc.src)
		ref = toRgb(srcRaw).SubImage(tc.src)
		dst = toRgb(dstRaw).SubImage(tc.dst)
	} else {
		src = srcRaw.SubImage(tc.src)
		refRaw := image.NewYCbCr(src.Bounds(), srcRaw.SubsampleRatio)
		err := Convert(refRaw, src, nil)
		expect(t, err, nil)
		ref = refRaw.SubImage(tc.src)
		dst = dstRaw.SubImage(tc.dst)
	}
	fwd := prepare(t, dst, src, asm, tc.interlaced, tc.filter, tc.threads)
	bwd := prepare(t, src, dst, asm, tc.interlaced, tc.filter, tc.threads)
	for i := 0; i < cycles; i++ {
		err := fwd.Convert(dst, src)
		expect(t, err, nil)
		err = bwd.Convert(src, dst)
		expect(t, err, nil)
	}
	if len(tc.psnrs) > 0 {
		checkPsnrs(t, ref, src, tc.psnrRect, tc.psnrs)
	}
	if len(tc.dump) > 0 {
		sb := src.Bounds()
		db := dst.Bounds()
		asmSuffix := "go"
		if asm {
			asmSuffix = "asm"
		}
		name := fmt.Sprintf("testdata/%v-%vx%v-%vx%v-%v-%v-%v-%v.png",
			tc.dump, sb.Dx(), sb.Dy(), db.Dx(), db.Dy(), suffix,
			toInterlacedString(tc.interlaced), asmSuffix, tc.filter.Name())
		writeImage(t, name, src)
	}
	return src
}
Exemple #7
0
func benchRescale(b *testing.B, w, h, thumbW, thumbH int) {
	// Most JPEGs are YCbCr, so bench with that.
	im := image.NewYCbCr(image.Rect(0, 0, w, h), image.YCbCrSubsampleRatio422)
	o := &DecodeOpts{MaxWidth: thumbW, MaxHeight: thumbH}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = rescale(im, o, false)
	}
}
Exemple #8
0
func testInterlacedFailWith(t *testing.T, rgb bool) {
	src := readImage(t, "testdata/lenna.jpg")
	dst := image.Image(image.NewYCbCr(image.Rect(0, 0, 640, 480), image.YCbCrSubsampleRatio420))
	if rgb {
		src = toRgb(src)
		dst = toRgb(dst)
	}
	convert(t, dst, src, false, true, NewBicubicFilter())
	convert(t, dst, src, true, true, NewBicubicFilter())
}
Exemple #9
0
// Benchmark resize of 16 MPix jpeg image to 800px width.
func jpegThumb(b *testing.B, interp InterpolationFunction) {
	input := image.NewYCbCr(image.Rect(0, 0, 4896, 3264), image.YCbCrSubsampleRatio422)

	var output image.Image
	for i := 0; i < b.N; i++ {
		output = Resize(800, 0, input, interp)
	}

	output.At(0, 0)
}
Exemple #10
0
// ensureImg ensures that d.img is large enough to hold the decoded frame.
func (d *Decoder) ensureImg() {
	if d.img != nil {
		p0, p1 := d.img.Rect.Min, d.img.Rect.Max
		if p0.X == 0 && p0.Y == 0 && p1.X >= 16*d.mbw && p1.Y >= 16*d.mbh {
			return
		}
	}
	m := image.NewYCbCr(image.Rect(0, 0, 16*d.mbw, 16*d.mbh), image.YCbCrSubsampleRatio420)
	d.img = m.SubImage(image.Rect(0, 0, d.frameHeader.Width, d.frameHeader.Height)).(*image.YCbCr)
	d.upMB = make([]mb, d.mbw)
}
Exemple #11
0
func ImageTransformByProfile(src_image image.Image, src_prof, dst_prof *Profile) (image.Image, error) {
	var dst_image image.Image
	rect := src_image.Bounds()
	width := rect.Dx()
	height := rect.Dy()
	colorModel := src_image.ColorModel()
	// 今のところ RGBA, YCbCr のみ対応
	if (colorModel != color.YCbCrModel) && (colorModel != color.RGBAModel) {
		return nil, fmt.Errorf("ImageTransformByProfile: Unsupported ColorModel(%d)", colorModel)
	}
	var src_rgba *image.RGBA
	var src_ycbcr *image.YCbCr
	if colorModel == color.YCbCrModel {
		// YCbCr の場合は RGB に変換する
		src_ycbcr = src_image.(*image.YCbCr)
		src_rgba = image.NewRGBA(rect)
		DrawYCbCr(src_rgba, rect, src_ycbcr, image.Pt(0, 0))
	} else {
		src_rgba = src_image.(*image.RGBA) // type assertions
	}
	transform := CreateTransform(src_prof, DATA_RGBA_8, dst_prof, DATA_RGBA_8)
	defer transform.DeleteTransform()
	if transform == nil {
		return nil, fmt.Errorf("ImageTransformByProfile: CreateTransform Failedl(%d)", colorModel)
	}
	dst_rgba := image.NewRGBA(rect)
	src_pix := src_rgba.Pix
	dst_pix := dst_rgba.Pix
	len_pix := len(src_pix)
	transform.DoTransform(src_pix, dst_pix, len_pix)
	// YCbCr の場合は RGB から戻す
	if colorModel == color.YCbCrModel {
		dst_ycbcr := image.NewYCbCr(rect, src_ycbcr.SubsampleRatio)
		var x int
		var y int
		for y = 0; y < height; y++ {
			for x = 0; x < width; x++ {
				r, g, b, _ := dst_rgba.At(x, y).RGBA()
				yy, cb, cr := color.RGBToYCbCr(uint8(r), uint8(g), uint8(b))
				yi := dst_ycbcr.YOffset(x, y)
				ci := dst_ycbcr.COffset(x, y)
				dst_ycbcr.Y[yi] = yy
				dst_ycbcr.Cb[ci] = cb
				dst_ycbcr.Cr[ci] = cr
			}
		}
		dst_image = image.Image(dst_ycbcr)
	} else {
		dst_image = image.Image(dst_rgba)
	}

	return dst_image, nil
}
Exemple #12
0
func convertFiles(t Tester, w, h int, input string, filter Filter, rgb bool) (image.Image, image.Image) {
	src := readImage(t, input)
	raw := image.NewYCbCr(image.Rect(0, 0, w*2, h*2), image.YCbCrSubsampleRatio420)
	dst := raw.SubImage(image.Rect(7, 7, 7+w, 7+h))
	if rgb {
		src = toRgb(src)
		dst = toRgb(dst)
	}
	err := Convert(dst, src, filter)
	expect(t, err, nil)
	return src, dst
}
func benchRescale(b *testing.B, w, h, thumbW, thumbH int) {
	// Most JPEGs are YCbCr, so bench with that.
	im := image.NewYCbCr(image.Rect(0, 0, w, h), image.YCbCrSubsampleRatio422)
	o := &DecodeOpts{MaxWidth: thumbW, MaxHeight: thumbH}
	sw, sh, needRescale := o.rescaleDimensions(im.Bounds(), false)
	if !needRescale {
		b.Fatal("opts.rescaleDimensions failed to indicate image needs rescale")
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = rescale(im, sw, sh)
	}
}
Exemple #14
0
func TestNewPixelGetter(t *testing.T) {
	var img image.Image
	var pg *pixelGetter
	img = image.NewNRGBA(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itNRGBA || pg.imgNRGBA == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter NRGBA")
	}
	img = image.NewNRGBA64(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itNRGBA64 || pg.imgNRGBA64 == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter NRGBA64")
	}
	img = image.NewRGBA(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itRGBA || pg.imgRGBA == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter RGBA")
	}
	img = image.NewRGBA64(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itRGBA64 || pg.imgRGBA64 == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter RGBA64")
	}
	img = image.NewGray(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itGray || pg.imgGray == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter Gray")
	}
	img = image.NewGray16(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itGray16 || pg.imgGray16 == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter Gray16")
	}
	img = image.NewYCbCr(image.Rect(0, 0, 1, 1), image.YCbCrSubsampleRatio422)
	pg = newPixelGetter(img)
	if pg.imgType != itYCbCr || pg.imgYCbCr == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter YCbCr")
	}
	img = image.NewUniform(color.NRGBA64{0, 0, 0, 0})
	pg = newPixelGetter(img)
	if pg.imgType != itGeneric || pg.imgGeneric == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter Generic(Uniform)")
	}
	img = image.NewAlpha(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itGeneric || pg.imgGeneric == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter Generic(Alpha)")
	}
}
Exemple #15
0
func TestEncodeYCbCrStreamGeneric(t *testing.T) {
	r := image.Rect(0, 0, 16, 16)
	img := image.NewYCbCr(r, image.YCbCrSubsampleRatio444)
	c := color.YCbCr{Y: 70, Cb: 146, Cr: 164}
	for i := range img.Y {
		img.Y[i] = c.Y
	}
	for i := range img.Cb {
		img.Cb[i] = c.Cb
	}
	for i := range img.Cr {
		img.Cr[i] = c.Cr
	}

	var buf bytes.Buffer
	encodeImageStream(&buf, img)
	expectImageBuffer(buf.Bytes(), r, c, t)
}
Exemple #16
0
func FromImage(src image.Image) *image.YCbCr {
	r := src.Bounds()
	dst := image.NewYCbCr(src.Bounds(), image.YCbCrSubsampleRatio444)
	for x := r.Min.X; x < r.Max.X; x++ {
		for y := r.Min.Y; y < r.Max.Y; y++ {
			c := src.At(x, y)
			r, g, b, _ := c.RGBA()
			yy, cb, cr := color.RGBToYCbCr(uint8(r>>8), uint8(g>>8), uint8(b>>8))

			i := dst.YOffset(x, y)
			dst.Y[i] = yy
			dst.Cb[i] = cb
			dst.Cr[i] = cr
		}
	}

	return dst
}
Exemple #17
0
func NewEncoder(codec uint32, in image.Image, out io.Writer) (*Encoder, error) {
	_codec := C.avcodec_find_encoder(codec)
	if _codec == nil {
		return nil, fmt.Errorf("could not find codec")
	}

	c := C.avcodec_alloc_context3(_codec)
	f := C.avcodec_alloc_frame()

	c.bit_rate = 400000

	// resolution must be a multiple of two
	w, h := C.int(in.Bounds().Dx()), C.int(in.Bounds().Dy())
	if w%2 == 1 || h%2 == 1 {
		return nil, fmt.Errorf("Bad image dimensions (%d, %d), must be even", w, h)
	}

	log.Printf("Encoder dimensions: %d, %d", w, h)

	c.width = w
	c.height = h
	c.time_base = C.AVRational{1, 25} // FPS
	c.gop_size = 10                   // emit one intra frame every ten frames
	c.max_b_frames = 1

	underlying_im := image.NewYCbCr(in.Bounds(), image.YCbCrSubsampleRatio420)
	c.pix_fmt = C.PIX_FMT_YUV420P
	f.data[0] = ptr(underlying_im.Y)
	f.data[1] = ptr(underlying_im.Cb)
	f.data[2] = ptr(underlying_im.Cr)
	f.linesize[0] = w
	f.linesize[1] = w / 2
	f.linesize[2] = w / 2

	if C.avcodec_open2(c, _codec, nil) < 0 {
		return nil, fmt.Errorf("could not open codec")
	}

	_swscontext := C.sws_getContext(w, h, C.PIX_FMT_RGB0, w, h, C.PIX_FMT_YUV420P,
		C.SWS_BICUBIC, nil, nil, nil)

	e := &Encoder{codec, in, underlying_im, out, _codec, c, _swscontext, f, make([]byte, 16*1024)}
	return e, nil
}
Exemple #18
0
// ResizeImage resizes the given image IF it is larger than maxWidth or maxHeight
func ResizeImage(src image.Image, maxWidth int64, maxHeight int64, square bool) (image.Image, error) {
	var dst image.Image

	// Check the original dimensions first, and bail out if this image is not larger than max dimensions
	srcSize := src.Bounds().Size()
	if int64(srcSize.X) < maxWidth && int64(srcSize.Y) < maxHeight {
		return src, nil
	}

	// Use the original image dimensions to keep it in pro
	// Distorting images is a sin of which we are never guilty
	ratio := float64(maxWidth) / float64(srcSize.X)
	yRatio := float64(maxHeight) / float64(srcSize.Y)
	if yRatio < ratio {
		ratio = yRatio
	}

	// Now adjust desired width and height according to ratio
	width := float64(srcSize.X) * ratio
	height := float64(srcSize.Y) * ratio

	// Create a new resized image with the desired dimensions and fill it with resized image data
	// We switch on input image type - is YCbCrSubsampleRatio444 correct?
	switch src.(type) {
	case *image.YCbCr:
		dst = image.NewYCbCr(image.Rect(0, 0, int(width), int(height)), image.YCbCrSubsampleRatio444)
	case *image.RGBA:
		dst = image.NewRGBA(image.Rect(0, 0, int(width), int(height)))
	default:
		dst = nil
	}

	err := rez.Convert(dst, src, rez.NewBicubicFilter())
	// IF we want thumbnails to be square/cropped we could do this
	// for now we don't need this. We may not even want it for camping?
	//   err :=  imaging.Thumbnail(srcImage, 100, 100, imaging.Lanczos)

	if err != nil {
		return nil, err
	}

	return dst, nil

}
Exemple #19
0
func testYCbCr(t *testing.T, r image.Rectangle, subsampleRatio image.YCbCrSubsampleRatio, delta image.Point) {
	// Create a YCbCr image m, whose bounds are r translated by (delta.X, delta.Y).
	r1 := r.Add(delta)
	img := image.NewYCbCr(r1, subsampleRatio)

	// Initialize img's pixels. For 422 and 420 subsampling, some of the Cb and Cr elements
	// will be set multiple times. That's OK. We just want to avoid a uniform image.
	for y := r1.Min.Y; y < r1.Max.Y; y++ {
		for x := r1.Min.X; x < r1.Max.X; x++ {
			yi := img.YOffset(x, y)
			ci := img.COffset(x, y)
			img.Y[yi] = uint8(16*y + x)
			img.Cb[ci] = uint8(y + 16*x)
			img.Cr[ci] = uint8(y + 16*x)
		}
	}

	m := imageYCbCrToYCC(img)

	// Make various sub-images of m.
	for y0 := delta.Y + 3; y0 < delta.Y+7; y0++ {
		for y1 := delta.Y + 8; y1 < delta.Y+13; y1++ {
			for x0 := delta.X + 3; x0 < delta.X+7; x0++ {
				for x1 := delta.X + 8; x1 < delta.X+13; x1++ {
					subRect := image.Rect(x0, y0, x1, y1)
					sub := m.SubImage(subRect).(*ycc)

					// For each point in the sub-image's bounds, check that m.At(x, y) equals sub.At(x, y).
					for y := sub.Rect.Min.Y; y < sub.Rect.Max.Y; y++ {
						for x := sub.Rect.Min.X; x < sub.Rect.Max.X; x++ {
							color0 := m.At(x, y).(color.YCbCr)
							color1 := sub.At(x, y).(color.YCbCr)
							if color0 != color1 {
								t.Errorf("r=%v, subsampleRatio=%v, delta=%v, x=%d, y=%d, color0=%v, color1=%v",
									r, subsampleRatio, delta, x, y, color0, color1)
								return
							}
						}
					}
				}
			}
		}
	}
}
Exemple #20
0
func benchYCbCr(b *testing.B, interp InterpolationFunction) {
	m := image.NewYCbCr(image.Rect(0, 0, benchMaxX, benchMaxY), image.YCbCrSubsampleRatio422)
	// Initialize m's pixels to create a non-uniform image.
	for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ {
		for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ {
			yi := m.YOffset(x, y)
			ci := m.COffset(x, y)
			m.Y[yi] = uint8(16*y + x)
			m.Cb[ci] = uint8(y + 16*x)
			m.Cr[ci] = uint8(y + 16*x)
		}
	}
	var out image.Image
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		out = Resize(benchWidth, benchHeight, m, interp)
	}
	out.At(0, 0)
}
Exemple #21
0
func TestIsOpaque(t *testing.T) {
	type opqt struct {
		img    image.Image
		opaque bool
	}
	var testData []opqt

	testData = append(testData, opqt{image.NewNRGBA(image.Rect(0, 0, 1, 1)), false})
	testData = append(testData, opqt{image.NewNRGBA64(image.Rect(0, 0, 1, 1)), false})
	testData = append(testData, opqt{image.NewRGBA(image.Rect(0, 0, 1, 1)), false})
	testData = append(testData, opqt{image.NewRGBA64(image.Rect(0, 0, 1, 1)), false})
	testData = append(testData, opqt{image.NewGray(image.Rect(0, 0, 1, 1)), true})
	testData = append(testData, opqt{image.NewGray16(image.Rect(0, 0, 1, 1)), true})
	testData = append(testData, opqt{image.NewYCbCr(image.Rect(0, 0, 1, 1), image.YCbCrSubsampleRatio444), true})
	testData = append(testData, opqt{image.NewAlpha(image.Rect(0, 0, 1, 1)), false})

	img1 := image.NewNRGBA(image.Rect(0, 0, 1, 1))
	img1.Set(0, 0, color.NRGBA{0x00, 0x00, 0x00, 0xff})
	testData = append(testData, opqt{img1, true})
	img2 := image.NewNRGBA64(image.Rect(0, 0, 1, 1))
	img2.Set(0, 0, color.NRGBA{0x00, 0x00, 0x00, 0xff})
	testData = append(testData, opqt{img2, true})
	img3 := image.NewRGBA(image.Rect(0, 0, 1, 1))
	img3.Set(0, 0, color.NRGBA{0x00, 0x00, 0x00, 0xff})
	testData = append(testData, opqt{img3, true})
	img4 := image.NewRGBA64(image.Rect(0, 0, 1, 1))
	img4.Set(0, 0, color.NRGBA{0x00, 0x00, 0x00, 0xff})
	testData = append(testData, opqt{img4, true})
	imgp1 := image.NewPaletted(image.Rect(0, 0, 1, 1), []color.Color{color.NRGBA{0x00, 0x00, 0x00, 0xff}})
	imgp1.SetColorIndex(0, 0, 0)
	testData = append(testData, opqt{imgp1, true})
	imgp2 := image.NewPaletted(image.Rect(0, 0, 1, 1), []color.Color{color.NRGBA{0x00, 0x00, 0x00, 0xfe}})
	imgp2.SetColorIndex(0, 0, 0)
	testData = append(testData, opqt{imgp2, false})

	for _, d := range testData {
		isop := isOpaque(d.img)
		if isop != d.opaque {
			t.Errorf("isOpaque failed %#v, %v", d.img, isop)
		}
	}
}
// makeImg allocates and initializes the destination image.
func (d *decoder) makeImg(h0, v0, mxx, myy int) {
	if d.nComp == nGrayComponent {
		m := image.NewGray(image.Rect(0, 0, 8*mxx, 8*myy))
		d.img1 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.Gray)
		return
	}
	var subsampleRatio image.YCbCrSubsampleRatio
	switch h0 * v0 {
	case 1:
		subsampleRatio = image.YCbCrSubsampleRatio444
	case 2:
		subsampleRatio = image.YCbCrSubsampleRatio422
	case 4:
		subsampleRatio = image.YCbCrSubsampleRatio420
	default:
		panic("unreachable")
	}
	m := image.NewYCbCr(image.Rect(0, 0, 8*h0*mxx, 8*v0*myy), subsampleRatio)
	d.img3 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.YCbCr)
}
Exemple #23
0
// makeImg allocates and initializes the destination image.
func (d *decoder) makeImg(mxx, myy int) {
	if d.nComp == 1 {
		m := image.NewGray(image.Rect(0, 0, 8*mxx, 8*myy))
		d.img1 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.Gray)
		return
	}

	h0 := d.comp[0].h
	v0 := d.comp[0].v
	hRatio := h0 / d.comp[1].h
	vRatio := v0 / d.comp[1].v
	var subsampleRatio image.YCbCrSubsampleRatio
	switch hRatio<<4 | vRatio {
	case 0x11:
		subsampleRatio = image.YCbCrSubsampleRatio444
	case 0x12:
		subsampleRatio = image.YCbCrSubsampleRatio440
	case 0x21:
		subsampleRatio = image.YCbCrSubsampleRatio422
	case 0x22:
		subsampleRatio = image.YCbCrSubsampleRatio420
	case 0x41:
		subsampleRatio = image.YCbCrSubsampleRatio411
	case 0x42:
		subsampleRatio = image.YCbCrSubsampleRatio410
	default:
		panic("unreachable")
	}
	m := image.NewYCbCr(image.Rect(0, 0, 8*h0*mxx, 8*v0*myy), subsampleRatio)
	d.img3 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.YCbCr)

	if d.nComp == 4 {
		h3, v3 := d.comp[3].h, d.comp[3].v
		d.blackPix = make([]byte, 8*h3*mxx*8*v3*myy)
		d.blackStride = 8 * h3 * mxx
	}
}
func BenchmarkNewAtFuncYCbCR(b *testing.B) {
	benchmarkNewAtFunc(b, image.NewYCbCr(image.Rect(0, 0, 1, 1), image.YCbCrSubsampleRatio444))
}
Exemple #25
0
func srcYCbCr(boundsHint image.Rectangle) (image.Image, error) {
	m := image.NewYCbCr(boundsHint, image.YCbCrSubsampleRatio420)
	fillPix(rand.New(rand.NewSource(3)), m.Y, m.Cb, m.Cr)
	return m, nil
}
Exemple #26
0
func TestGetPixel(t *testing.T) {
	var pg *pixelGetter

	// RGBA, NRGBA, RGBA64, NRGBA64

	palette := []color.Color{
		color.NRGBA{0, 0, 0, 0},
		color.NRGBA{255, 255, 255, 255},
		color.NRGBA{50, 100, 150, 255},
		color.NRGBA{150, 100, 50, 200},
	}

	images1 := []draw.Image{
		image.NewRGBA(image.Rect(-1, -2, 3, 4)),
		image.NewRGBA64(image.Rect(-1, -2, 3, 4)),
		image.NewNRGBA(image.Rect(-1, -2, 3, 4)),
		image.NewNRGBA64(image.Rect(-1, -2, 3, 4)),
		image.NewPaletted(image.Rect(-1, -2, 3, 4), palette),
	}

	colors1 := []struct {
		c  color.NRGBA
		px pixel
	}{
		{color.NRGBA{0, 0, 0, 0}, pixel{0, 0, 0, 0}},
		{color.NRGBA{255, 255, 255, 255}, pixel{1, 1, 1, 1}},
		{color.NRGBA{50, 100, 150, 255}, pixel{0.196, 0.392, 0.588, 1}},
		{color.NRGBA{150, 100, 50, 200}, pixel{0.588, 0.392, 0.196, 0.784}},
	}

	for _, img := range images1 {
		pg = newPixelGetter(img)
		for _, k := range colors1 {
			for _, x := range []int{-1, 0, 2} {
				for _, y := range []int{-2, 0, 3} {
					img.Set(x, y, k.c)
					px := pg.getPixel(x, y)
					if !comparePixels(k.px, px, 0.005) {
						t.Errorf("getPixel %T %v %dx%d %v %v", img, k.c, x, y, k.px, px)
					}
				}
			}
		}
	}

	// Uniform (Generic)

	for _, k := range colors1 {
		img := image.NewUniform(k.c)
		pg = newPixelGetter(img)
		for _, x := range []int{-1, 0, 2} {
			for _, y := range []int{-2, 0, 3} {
				px := pg.getPixel(x, y)
				if !comparePixels(k.px, px, 0.005) {
					t.Errorf("getPixel %T %v %dx%d %v %v", img, k.c, x, y, k.px, px)
				}
			}
		}
	}

	// YCbCr

	colors2 := []struct {
		c  color.NRGBA
		px pixel
	}{
		{color.NRGBA{0, 0, 0, 255}, pixel{0, 0, 0, 1}},
		{color.NRGBA{255, 255, 255, 255}, pixel{1, 1, 1, 1}},
		{color.NRGBA{50, 100, 150, 255}, pixel{0.196, 0.392, 0.588, 1}},
	}

	for _, k := range colors2 {
		img := image.NewYCbCr(image.Rect(-1, -2, 3, 4), image.YCbCrSubsampleRatio444)
		pg = newPixelGetter(img)
		for _, x := range []int{-1, 0, 2} {
			for _, y := range []int{-2, 0, 3} {
				iy := img.YOffset(x, y)
				ic := img.COffset(x, y)
				img.Y[iy], img.Cb[ic], img.Cr[ic] = color.RGBToYCbCr(k.c.R, k.c.G, k.c.B)
				px := pg.getPixel(x, y)
				if !comparePixels(k.px, px, 0.005) {
					t.Errorf("getPixel %T %v %dx%d %v %v", img, k.c, x, y, k.px, px)
				}
			}
		}
	}

	// Gray, Gray16

	images2 := []draw.Image{
		image.NewGray(image.Rect(-1, -2, 3, 4)),
		image.NewGray16(image.Rect(-1, -2, 3, 4)),
	}

	colors3 := []struct {
		c  color.NRGBA
		px pixel
	}{
		{color.NRGBA{0, 0, 0, 0}, pixel{0, 0, 0, 1}},
		{color.NRGBA{255, 255, 255, 255}, pixel{1, 1, 1, 1}},
		{color.NRGBA{50, 100, 150, 255}, pixel{0.356, 0.356, 0.356, 1}},
		{color.NRGBA{150, 100, 50, 200}, pixel{0.337, 0.337, 0.337, 1}},
	}

	for _, img := range images2 {
		pg = newPixelGetter(img)
		for _, k := range colors3 {
			for _, x := range []int{-1, 0, 2} {
				for _, y := range []int{-2, 0, 3} {
					img.Set(x, y, k.c)
					px := pg.getPixel(x, y)
					if !comparePixels(k.px, px, 0.005) {
						t.Errorf("getPixel %T %v %dx%d %v %v", img, k.c, x, y, k.px, px)
					}
				}
			}
		}
	}
}
Exemple #27
0
func TestConvertYCbCr(t *testing.T) {
	testImage := []Image{
		image.NewYCbCr(image.Rect(0, 0, 50, 50), image.YCbCrSubsampleRatio420),
		image.NewYCbCr(image.Rect(0, 0, 50, 50), image.YCbCrSubsampleRatio422),
		image.NewYCbCr(image.Rect(0, 0, 50, 50), image.YCbCrSubsampleRatio440),
		image.NewYCbCr(image.Rect(0, 0, 50, 50), image.YCbCrSubsampleRatio444),
	}

	for _, img := range testImage {
		m := img.(*image.YCbCr)
		for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ {
			for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ {
				yi := m.YOffset(x, y)
				ci := m.COffset(x, y)
				m.Y[yi] = uint8(16*y + x)
				m.Cb[ci] = uint8(y + 16*x)
				m.Cr[ci] = uint8(y + 16*x)
			}
		}

		// test conversion from YCbCr to ycc
		yc := imageYCbCrToYCC(m)
		for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ {
			for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ {
				ystride := 3 * (m.Rect.Max.X - m.Rect.Min.X)
				xstride := 3
				yi := m.YOffset(x, y)
				ci := m.COffset(x, y)
				si := (y * ystride) + (x * xstride)
				if m.Y[yi] != yc.Pix[si] {
					t.Errorf("Err Y - found: %d expected: %d x: %d y: %d yi: %d si: %d",
						m.Y[yi], yc.Pix[si], x, y, yi, si)
				}
				if m.Cb[ci] != yc.Pix[si+1] {
					t.Errorf("Err Cb - found: %d expected: %d x: %d y: %d ci: %d si: %d",
						m.Cb[ci], yc.Pix[si+1], x, y, ci, si+1)
				}
				if m.Cr[ci] != yc.Pix[si+2] {
					t.Errorf("Err Cr - found: %d expected: %d x: %d y: %d ci: %d si: %d",
						m.Cr[ci], yc.Pix[si+2], x, y, ci, si+2)
				}
			}
		}

		// test conversion from ycc back to YCbCr
		ym := yc.YCbCr()
		for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ {
			for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ {
				yi := m.YOffset(x, y)
				ci := m.COffset(x, y)
				if m.Y[yi] != ym.Y[yi] {
					t.Errorf("Err Y - found: %d expected: %d x: %d y: %d yi: %d",
						m.Y[yi], ym.Y[yi], x, y, yi)
				}
				if m.Cb[ci] != ym.Cb[ci] {
					t.Errorf("Err Cb - found: %d expected: %d x: %d y: %d ci: %d",
						m.Cb[ci], ym.Cb[ci], x, y, ci)
				}
				if m.Cr[ci] != ym.Cr[ci] {
					t.Errorf("Err Cr - found: %d expected: %d x: %d y: %d ci: %d",
						m.Cr[ci], ym.Cr[ci], x, y, ci)
				}
			}
		}
	}
}
Exemple #28
0
// Copies an image to a new image of the same kind:
func CloneKind(src image.Image) image.Image {
	srcBounds := src.Bounds().Canon()
	zeroedBounds := srcBounds.Sub(srcBounds.Min)

	switch si := src.(type) {
	case *image.RGBA:
		out := image.NewRGBA(zeroedBounds)
		for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ {
			for x := srcBounds.Min.X; x < srcBounds.Max.X; x++ {
				out.SetRGBA(x-srcBounds.Min.X, y-srcBounds.Min.Y, si.At(x, y).(color.RGBA))
			}
		}
		return out
	case *image.YCbCr:
		out := image.NewYCbCr(zeroedBounds, si.SubsampleRatio)
		for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ {
			for x := srcBounds.Min.X; x < srcBounds.Max.X; x++ {
				ycbcr := si.At(x, y).(color.YCbCr)
				yoffs := out.YOffset(x-srcBounds.Min.X, y-srcBounds.Min.Y)
				coffs := out.COffset(x-srcBounds.Min.X, y-srcBounds.Min.Y)
				out.Y[yoffs] = ycbcr.Y
				out.Cb[coffs] = ycbcr.Cb
				out.Cr[coffs] = ycbcr.Cr
			}
		}
		return out
	case *image.Paletted:
		out := image.NewPaletted(zeroedBounds, si.Palette)
		for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ {
			for x := srcBounds.Min.X; x < srcBounds.Max.X; x++ {
				out.SetColorIndex(x-srcBounds.Min.X, y-srcBounds.Min.Y, si.ColorIndexAt(x, y))
			}
		}
		return out
	case *image.RGBA64:
		out := image.NewRGBA64(zeroedBounds)
		for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ {
			for x := srcBounds.Min.X; x < srcBounds.Max.X; x++ {
				out.SetRGBA64(x-srcBounds.Min.X, y-srcBounds.Min.Y, si.At(x, y).(color.RGBA64))
			}
		}
		return out
	case *image.NRGBA:
		out := image.NewNRGBA(zeroedBounds)
		for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ {
			for x := srcBounds.Min.X; x < srcBounds.Max.X; x++ {
				out.SetNRGBA(x-srcBounds.Min.X, y-srcBounds.Min.Y, si.At(x, y).(color.NRGBA))
			}
		}
		return out
	case *image.NRGBA64:
		out := image.NewNRGBA64(zeroedBounds)
		for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ {
			for x := srcBounds.Min.X; x < srcBounds.Max.X; x++ {
				out.SetNRGBA64(x-srcBounds.Min.X, y-srcBounds.Min.Y, si.At(x, y).(color.NRGBA64))
			}
		}
		return out
	case *image.Alpha:
		out := image.NewAlpha(zeroedBounds)
		for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ {
			for x := srcBounds.Min.X; x < srcBounds.Max.X; x++ {
				out.SetAlpha(x-srcBounds.Min.X, y-srcBounds.Min.Y, si.At(x, y).(color.Alpha))
			}
		}
		return out
	case *image.Alpha16:
		out := image.NewAlpha16(zeroedBounds)
		for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ {
			for x := srcBounds.Min.X; x < srcBounds.Max.X; x++ {
				out.SetAlpha16(x-srcBounds.Min.X, y-srcBounds.Min.Y, si.At(x, y).(color.Alpha16))
			}
		}
		return out
	case *image.Gray:
		out := image.NewGray(zeroedBounds)
		for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ {
			for x := srcBounds.Min.X; x < srcBounds.Max.X; x++ {
				out.SetGray(x-srcBounds.Min.X, y-srcBounds.Min.Y, si.At(x, y).(color.Gray))
			}
		}
		return out
	case *image.Gray16:
		out := image.NewGray16(zeroedBounds)
		for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ {
			for x := srcBounds.Min.X; x < srcBounds.Max.X; x++ {
				out.SetGray16(x-srcBounds.Min.X, y-srcBounds.Min.Y, si.At(x, y).(color.Gray16))
			}
		}
		return out
	default:
		panic(fmt.Errorf("Unhandled image format type: %s", reflect.TypeOf(src).Name()))
	}
}
Exemple #29
0
func TestNewDrawable(t *testing.T) {
	r := image.Rect(0, 0, 1, 1)
	for _, newImage := range []func(image.Rectangle) image.Image{
		func(r image.Rectangle) image.Image {
			return image.NewRGBA(r)
		},
		func(r image.Rectangle) image.Image {
			return image.NewRGBA64(r)
		},
		func(r image.Rectangle) image.Image {
			return image.NewNRGBA(r)
		},
		func(r image.Rectangle) image.Image {
			return image.NewNRGBA64(r)
		},
		func(r image.Rectangle) image.Image {
			return image.NewAlpha(r)
		},
		func(r image.Rectangle) image.Image {
			return image.NewAlpha16(r)
		},
		func(r image.Rectangle) image.Image {
			return image.NewGray(r)
		},
		func(r image.Rectangle) image.Image {
			return image.NewGray16(r)
		},
		func(r image.Rectangle) image.Image {
			return image.NewCMYK(r)
		},
		func(r image.Rectangle) image.Image {
			return image.NewPaletted(r, color.Palette{
				color.RGBA{0, 0, 0, 255},
				color.RGBA{255, 0, 0, 255},
				color.RGBA{0, 255, 0, 255},
				color.RGBA{0, 0, 255, 255},
				color.RGBA{255, 255, 255, 255},
			})
		},
		func(r image.Rectangle) image.Image {
			return image.NewYCbCr(r, image.YCbCrSubsampleRatio444)
		},
		func(r image.Rectangle) image.Image {
			return image.NewYCbCr(r, image.YCbCrSubsampleRatio422)
		},
		func(r image.Rectangle) image.Image {
			return image.NewYCbCr(r, image.YCbCrSubsampleRatio420)
		},
		func(r image.Rectangle) image.Image {
			return image.NewYCbCr(r, image.YCbCrSubsampleRatio440)
		},
		func(r image.Rectangle) image.Image {
			return image.NewYCbCr(r, image.YCbCrSubsampleRatio411)
		},
		func(r image.Rectangle) image.Image {
			return image.NewYCbCr(r, image.YCbCrSubsampleRatio410)
		},
		func(r image.Rectangle) image.Image {
			return image.NewNYCbCrA(r, image.YCbCrSubsampleRatio444)
		},
		func(r image.Rectangle) image.Image {
			return image.NewNYCbCrA(r, image.YCbCrSubsampleRatio422)
		},
		func(r image.Rectangle) image.Image {
			return image.NewNYCbCrA(r, image.YCbCrSubsampleRatio420)
		},
		func(r image.Rectangle) image.Image {
			return image.NewNYCbCrA(r, image.YCbCrSubsampleRatio440)
		},
		func(r image.Rectangle) image.Image {
			return image.NewNYCbCrA(r, image.YCbCrSubsampleRatio411)
		},
		func(r image.Rectangle) image.Image {
			return image.NewNYCbCrA(r, image.YCbCrSubsampleRatio410)
		},
		func(r image.Rectangle) image.Image {
			return image.NewUniform(color.RGBA{})
		},
		func(r image.Rectangle) image.Image {
			return &testImageDefault{image.NewRGBA(r)}
		},
	} {
		p := newImage(r)
		t.Run(fmt.Sprintf("%T", p), func(t *testing.T) {
			NewDrawable(p)
		})
	}
}
Exemple #30
0
// YCbCr converts ycc to a YCbCr image with the same subsample ratio
// as the YCbCr image that ycc was generated from.
func (p *ycc) YCbCr() *image.YCbCr {
	ycbcr := image.NewYCbCr(p.Rect, p.SubsampleRatio)
	var off int

	switch ycbcr.SubsampleRatio {
	case image.YCbCrSubsampleRatio422:
		for y := ycbcr.Rect.Min.Y; y < ycbcr.Rect.Max.Y; y++ {
			yy := (y - ycbcr.Rect.Min.Y) * ycbcr.YStride
			cy := (y - ycbcr.Rect.Min.Y) * ycbcr.CStride
			for x := ycbcr.Rect.Min.X; x < ycbcr.Rect.Max.X; x++ {
				xx := (x - ycbcr.Rect.Min.X)
				yi := yy + xx
				ci := cy + xx/2
				ycbcr.Y[yi] = p.Pix[off+0]
				ycbcr.Cb[ci] = p.Pix[off+1]
				ycbcr.Cr[ci] = p.Pix[off+2]
				off += 3
			}
		}
	case image.YCbCrSubsampleRatio420:
		for y := ycbcr.Rect.Min.Y; y < ycbcr.Rect.Max.Y; y++ {
			yy := (y - ycbcr.Rect.Min.Y) * ycbcr.YStride
			cy := (y/2 - ycbcr.Rect.Min.Y/2) * ycbcr.CStride
			for x := ycbcr.Rect.Min.X; x < ycbcr.Rect.Max.X; x++ {
				xx := (x - ycbcr.Rect.Min.X)
				yi := yy + xx
				ci := cy + xx/2
				ycbcr.Y[yi] = p.Pix[off+0]
				ycbcr.Cb[ci] = p.Pix[off+1]
				ycbcr.Cr[ci] = p.Pix[off+2]
				off += 3
			}
		}
	case image.YCbCrSubsampleRatio440:
		for y := ycbcr.Rect.Min.Y; y < ycbcr.Rect.Max.Y; y++ {
			yy := (y - ycbcr.Rect.Min.Y) * ycbcr.YStride
			cy := (y/2 - ycbcr.Rect.Min.Y/2) * ycbcr.CStride
			for x := ycbcr.Rect.Min.X; x < ycbcr.Rect.Max.X; x++ {
				xx := (x - ycbcr.Rect.Min.X)
				yi := yy + xx
				ci := cy + xx
				ycbcr.Y[yi] = p.Pix[off+0]
				ycbcr.Cb[ci] = p.Pix[off+1]
				ycbcr.Cr[ci] = p.Pix[off+2]
				off += 3
			}
		}
	default:
		// Default to 4:4:4 subsampling.
		for y := ycbcr.Rect.Min.Y; y < ycbcr.Rect.Max.Y; y++ {
			yy := (y - ycbcr.Rect.Min.Y) * ycbcr.YStride
			cy := (y - ycbcr.Rect.Min.Y) * ycbcr.CStride
			for x := ycbcr.Rect.Min.X; x < ycbcr.Rect.Max.X; x++ {
				xx := (x - ycbcr.Rect.Min.X)
				yi := yy + xx
				ci := cy + xx
				ycbcr.Y[yi] = p.Pix[off+0]
				ycbcr.Cb[ci] = p.Pix[off+1]
				ycbcr.Cr[ci] = p.Pix[off+2]
				off += 3
			}
		}
	}
	return ycbcr
}