package d2raster

import (
	
	
	
	
	
	
	

	
	
)

const imageSamplesPerAxis = 4

type preparedRasterAsset struct {
	image      image.Image
	sampleQuad rasterSampleQuadFunc
	bounds     image.Rectangle
	width      int
}

type rasterSampleQuad struct {
	c00, c10, c01, c11 [4]uint32
}

type rasterSampleQuadFunc func(source image.Image, x0, x1, y0, y1 int) rasterSampleQuad

type preparedImage struct {
	asset     *preparedRasterAsset
	box       d2scene.Box
	placement d2scene.Box
	inverse   inverseAffine
	bounds    image.Rectangle
}

// inverseAffine retains a normalized inverse of an affine transform's linear
// portion. Normalizing before the determinant avoids turning otherwise valid
// very large or very small transforms into false overflow/underflow failures.
type inverseAffine struct {
	a, b, c, d float64
	e, f       float64
}

type rasterAssetValidation struct {
	format       string
	decodedBytes int64
}

func prepareRasterAsset( context.Context,  d2scene.AssetID,  d2scene.RasterAsset,  int64) (*preparedRasterAsset, int64, error) {
	,  := validateRasterAsset(, , , )
	if  != nil {
		return nil, 0, 
	}
	,  := decodeRasterAsset(, , , )
	if  != nil {
		return nil, 0, 
	}
	return , .decodedBytes, nil
}

func validateRasterAsset( context.Context,  d2scene.AssetID,  d2scene.RasterAsset,  int64) (rasterAssetValidation, error) {
	 := fmt.Sprintf("d2raster: raster asset %q", )
	if  := .Err();  != nil {
		return rasterAssetValidation{}, 
	}
	if len(.Data) == 0 {
		return rasterAssetValidation{}, fmt.Errorf("%s has no data", )
	}
	if .PixelWidth <= 0 || .PixelHeight <= 0 {
		return rasterAssetValidation{}, fmt.Errorf("%s has invalid declared dimensions %dx%d", , .PixelWidth, .PixelHeight)
	}
	,  := rasterFormatForMIME(.MIMEType)
	if ! {
		return rasterAssetValidation{}, fmt.Errorf("%s has unsupported MIME type %q; supported raster MIME types are image/png, image/jpeg, image/gif, and image/webp", , .MIMEType)
	}
	 := rasterDataFormat(.Data)
	if  == "" {
		return rasterAssetValidation{}, fmt.Errorf("%s data has no supported raster signature", )
	}
	if  !=  {
		return rasterAssetValidation{}, fmt.Errorf("%s declares MIME type %q but data has %s signature", , .MIMEType, strings.ToUpper())
	}
	, ,  := rasterimage.Config(, .Data, )
	if  != nil {
		if  := .Err();  != nil {
			return rasterAssetValidation{}, 
		}
		return rasterAssetValidation{}, fmt.Errorf("%s has malformed %s data: %w", , strings.ToUpper(), )
	}
	if .Width != .PixelWidth || .Height != .PixelHeight {
		return rasterAssetValidation{}, fmt.Errorf(
			"%s declares dimensions %dx%d but encoded data is %dx%d",
			, .PixelWidth, .PixelHeight, .Width, .Height,
		)
	}
	,  := rasterDecodedBytes()
	if  != nil {
		return rasterAssetValidation{}, fmt.Errorf("%s: %w", , )
	}
	if .DecodedBytes != 0 {
		if .DecodedBytes <  {
			return rasterAssetValidation{}, fmt.Errorf(
				"%s declares a %d-byte decoded footprint below the required %d bytes",
				, .DecodedBytes, ,
			)
		}
		 = .DecodedBytes
	}
	if  := validateDecodedAssetBudget(, , );  != nil {
		return rasterAssetValidation{}, 
	}
	if  > platformMaxInt() {
		return rasterAssetValidation{}, fmt.Errorf("%s decoded storage exceeds the platform integer domain", )
	}
	if  := .Err();  != nil {
		return rasterAssetValidation{}, 
	}
	return rasterAssetValidation{format: , decodedBytes: }, nil
}

func validateDecodedAssetBudget( d2scene.AssetID, ,  int64) error {
	if  < 0 ||  >  {
		return fmt.Errorf(
			"d2raster: raster asset %q decoded storage requires %d bytes, exceeding the %d bytes remaining under MaxDecodedAssetBytes",
			, , maxInt64(, 0),
		)
	}
	return nil
}

func decodeRasterAsset( context.Context,  d2scene.AssetID,  d2scene.RasterAsset,  rasterAssetValidation) (*preparedRasterAsset, error) {
	 := fmt.Sprintf("d2raster: raster asset %q", )
	if  := .Err();  != nil {
		return nil, 
	}
	,  := rasterimage.DecodeFirst(, .Data, .format)
	if  != nil {
		if  := .Err();  != nil {
			return nil, 
		}
		return nil, fmt.Errorf("%s has malformed %s pixel data: %w", , strings.ToUpper(.format), )
	}
	 := .Bounds()
	if .Dx() != .PixelWidth || .Dy() != .PixelHeight {
		return nil, fmt.Errorf(
			"%s decoded pixels are %dx%d, want declared dimensions %dx%d",
			, .Dx(), .Dy(), .PixelWidth, .PixelHeight,
		)
	}
	if  := .Err();  != nil {
		return nil, 
	}
	return newPreparedRasterAsset(), nil
}

func newPreparedRasterAsset( image.Image) *preparedRasterAsset {
	 := .Bounds()
	return &preparedRasterAsset{
		image: , sampleQuad: bindRasterSampleQuad(),
		bounds: , width: .Dx(),
	}
}

func rasterFormatForMIME( string) (string, bool) {
	switch  {
	case "image/png":
		return "png", true
	case "image/jpeg":
		return "jpeg", true
	case "image/gif":
		return "gif", true
	case "image/webp":
		return "webp", true
	default:
		return "", false
	}
}

func rasterDataFormat( []byte) string {
	switch {
	case len() >= 8 && bytes.Equal([:8], []byte("\x89PNG\r\n\x1a\n")):
		return "png"
	case len() >= 3 && [0] == 0xff && [1] == 0xd8 && [2] == 0xff:
		return "jpeg"
	case len() >= 6 && (bytes.Equal([:6], []byte("GIF87a")) || bytes.Equal([:6], []byte("GIF89a"))):
		return "gif"
	case len() >= 12 && bytes.Equal([:4], []byte("RIFF")) && bytes.Equal([8:12], []byte("WEBP")):
		return "webp"
	default:
		return ""
	}
}

func rasterDecodedBytes( image.Config) (int64, error) {
	if .Width <= 0 || .Height <= 0 {
		return 0, fmt.Errorf("decoded dimensions %dx%d are invalid", .Width, .Height)
	}
	if int64(.Width) > math.MaxInt64/int64(.Height) {
		return 0, fmt.Errorf("decoded pixel count overflows int64")
	}
	 := int64(.Width) * int64(.Height)
	 := int64(4)
	if .ColorModel != nil {
		 := .ColorModel.Convert(color.RGBA64{R: 0x1234, G: 0x5678, B: 0x9abc, A: 0xffff})
		switch .(type) {
		case color.RGBA64, color.NRGBA64, color.Gray16, color.Alpha16:
			 = 8
		}
	}
	if  > math.MaxInt64/ {
		return 0, fmt.Errorf("decoded byte count overflows int64")
	}
	return  * , nil
}

func ( *preflight) ( string,  d2scene.Image,  d2scene.Matrix,  animationOverrides, ,  int) (*preparedPrimitive, error) {
	if .fillColor != nil || .strokeColor != nil || .dashOffset != nil {
		return nil, fmt.Errorf("d2raster: node %q image cannot be targeted by paint or stroke animation", )
	}
	if .Asset == "" {
		return nil, fmt.Errorf("d2raster: node %q image has an empty asset ID", )
	}
	if  := validateBox(.Box);  != nil {
		return nil, fmt.Errorf("d2raster: node %q image: %w", , )
	}
	if .Aspect.Align > d2scene.AlignXMaxYMax || .Aspect.Fit > d2scene.AspectSlice {
		return nil, fmt.Errorf("d2raster: node %q image has invalid aspect-ratio policy align=%d fit=%d", , .Aspect.Align, .Aspect.Fit)
	}
	if ,  := .rasters[.Asset];  {
		return .rasterImage(, , , )
	}
	if ,  := .vectors[.Asset];  {
		return .vectorImage(, , , , , )
	}
	if ,  := .document.Assets[.Asset];  {
		return nil, fmt.Errorf("d2raster: node %q image asset %q is not a raster or vector asset (got %T)", , .Asset, )
	}
	return nil, fmt.Errorf("d2raster: node %q image references missing asset %q", , .Asset)
}

func ( *preflight) ( string,  d2scene.Image,  d2scene.Matrix,  *preparedRasterAsset) (*preparedPrimitive, error) {
	,  := imagePlacement(.Box, .width, .bounds.Dy(), .Aspect)
	if  != nil {
		return nil, fmt.Errorf("d2raster: node %q image aspect ratio: %w", , )
	}
	, ,  := makeInverseAffine()
	if  != nil {
		return nil, fmt.Errorf("d2raster: node %q image transform: %w", , )
	}
	,  := transformedImagePixelBounds(.Box, , .preparationBounds())
	if  != nil {
		return nil, fmt.Errorf("d2raster: node %q image geometry: %w", , )
	}
	if ! || .Box.Width == 0 || .Box.Height == 0 {
		 = image.Rectangle{}
	}
	 := &preparedImage{
		asset: , box: .Box, placement: , inverse: , bounds: ,
	}
	return &preparedPrimitive{image: , bounds: }, nil
}

func ( *preflight) ( string,  d2scene.Image,  d2scene.Matrix,  d2scene.VectorAsset, ,  int) (*preparedPrimitive, error) {
	 :=  + 1
	if  > .options.MaxImportDepth {
		return nil, fmt.Errorf(
			"d2raster: node %q vector asset %q import depth %d exceeds limit %d",
			, .Asset, , .options.MaxImportDepth,
		)
	}
	if .activeAssets[.Asset] {
		return nil, fmt.Errorf("d2raster: node %q has cyclic vector asset reference at %q", , .Asset)
	}
	 := .Box.Width == 0 || .Box.Height == 0 || !finiteLinearTransformInvertible()
	 := .Box
	 := .Aspect
	// An empty destination paints no pixels, but the referenced scene still
	// needs structural validation and per-instance budget accounting. Prepare
	// it in a canonical viewport so large intrinsic coordinates and the
	// necessarily singular real viewport do not become device-domain errors.
	// The empty outer clip discards all prepared bounds and resource work.
	if  {
		// Keep each canonical scale in (0,1]. A fixed 1x1 target would make
		// 1/source overflow for a valid subnormal ViewBox dimension.
		 = d2scene.Box{
			Width: math.Min(.ViewBox.Width, 1), Height: math.Min(.ViewBox.Height, 1),
		}
		 = d2scene.AspectRatio{Align: d2scene.AlignNone}
	}
	,  := d2scene.AspectRatioMatrix(.ViewBox, , )
	if  != nil {
		return nil, fmt.Errorf("d2raster: node %q vector asset %q aspect ratio: %w", , .Asset, )
	}
	if ! && !finiteLinearTransformInvertible() {
		return nil, fmt.Errorf("d2raster: node %q vector asset %q aspect ratio: mapping is singular in the finite numeric domain", , .Asset)
	}
	 := .Mul()
	if  {
		// The actual ancestor transform cannot affect an empty viewport. Avoid
		// letting a finite but device-sized ancestor influence accounting-only
		// preparation of the imported definition.
		 = 
	}
	if !.IsFinite() {
		return nil, fmt.Errorf("d2raster: node %q vector asset %q has a non-finite composed transform", , .Asset)
	}

	if .activeAssets == nil {
		.activeAssets = make(map[d2scene.AssetID]bool)
	}
	.activeAssets[.Asset] = true
	defer delete(.activeAssets, .Asset)
	,  := .node(.Root, , +1, )
	if  != nil {
		return nil, fmt.Errorf("d2raster: node %q vector asset %q: %w", , .Asset, )
	}
	 := &preparedClip{}
	if ! {
		,  = .imageBoxClip(, .Asset, .Box, )
		if  != nil {
			return nil, 
		}
	}
	 := &preparedNode{
		opacity:  1,
		blend:    d2scene.BlendNormal,
		children: []*preparedNode{},
		clip:     ,
	}
	if  != nil {
		.bounds = .bounds.Intersect(.bounds)
	}
	return &preparedPrimitive{vector: , bounds: .bounds}, nil
}

// imageBoxClip constructs the implicit image viewport in device space. It is
// renderer-generated geometry, so its four edges intentionally do not consume
// MaxPathCommands; that limit counts instantiated scene work.
func ( *preflight) ( string,  d2scene.AssetID,  d2scene.Box,  d2scene.Matrix) (*preparedClip, error) {
	 := [...]d2scene.Point{
		{X: .X, Y: .Y},
		{X: .X + .Width, Y: .Y},
		{X: .X + .Width, Y: .Y + .Height},
		{X: .X, Y: .Y + .Height},
	}
	 := make([]d2scene.Point, len())
	for ,  := range  {
		[] = .Point()
		if  := validateRasterPoint([]);  != nil {
			return nil, fmt.Errorf("d2raster: node %q vector asset %q viewport geometry: %w", , , )
		}
	}
	,  := transformedImagePixelBounds(, , .preparationBounds())
	if  != nil {
		return nil, fmt.Errorf("d2raster: node %q vector asset %q viewport geometry: %w", , , )
	}
	 := finiteLinearTransformInvertible()
	if ! || .Width == 0 || .Height == 0 {
		 = image.Rectangle{}
	}
	return &preparedClip{
		subpaths: []subpath{{points: , closed: true}},
		fillRule: d2scene.NonZero,
		bounds:   ,
		edges:    4,
	}, nil
}

func imagePlacement( d2scene.Box, ,  int,  d2scene.AspectRatio) (d2scene.Box, error) {
	if .Align == d2scene.AlignNone || .Width == 0 || .Height == 0 {
		return , nil
	}
	 := .Width / float64()
	 := .Height / float64()
	 := math.Min(, )
	if .Fit == d2scene.AspectSlice {
		 = math.Max(, )
	}
	 := float64() * 
	 := float64() * 
	if !finite() || !finite() || !finite() ||  <= 0 {
		return d2scene.Box{}, fmt.Errorf("placement is outside the finite positive domain")
	}
	, ,  := aspectAlignmentFactors(.Align)
	if ! {
		return d2scene.Box{}, fmt.Errorf("unsupported alignment %d", .Align)
	}
	return d2scene.Box{
		X:      .X + (.Width-)*,
		Y:      .Y + (.Height-)*,
		Width:  ,
		Height: ,
	}, validateImagePlacement(, , , , )
}

func validateImagePlacement( d2scene.Box, , , ,  float64) error {
	 := .X + (.Width-)*
	 := .Y + (.Height-)*
	if !finite() || !finite() {
		return fmt.Errorf("placement origin is outside the finite numeric domain")
	}
	return nil
}

func aspectAlignmentFactors( d2scene.AspectAlign) (,  float64,  bool) {
	switch  {
	case d2scene.AlignXMinYMin:
		return 0, 0, true
	case d2scene.AlignXMidYMin:
		return .5, 0, true
	case d2scene.AlignXMaxYMin:
		return 1, 0, true
	case d2scene.AlignXMinYMid:
		return 0, .5, true
	case d2scene.AlignXMidYMid:
		return .5, .5, true
	case d2scene.AlignXMaxYMid:
		return 1, .5, true
	case d2scene.AlignXMinYMax:
		return 0, 1, true
	case d2scene.AlignXMidYMax:
		return .5, 1, true
	case d2scene.AlignXMaxYMax:
		return 1, 1, true
	default:
		return 0, 0, false
	}
}

func makeInverseAffine( d2scene.Matrix) (inverseAffine, bool, error) {
	 := math.Max(
		math.Max(math.Abs(.A), math.Abs(.B)),
		math.Max(math.Abs(.C), math.Abs(.D)),
	)
	if !finite() {
		return inverseAffine{}, false, fmt.Errorf("linear coefficients are non-finite")
	}
	if  == 0 {
		return inverseAffine{}, false, nil
	}
	 := .A / 
	 := .B / 
	 := .C / 
	 := .D / 
	 := * - *
	if  == 0 {
		return inverseAffine{}, false, nil
	}
	 := inverseAffine{
		a: ( / ) / ,
		b: (- / ) / ,
		c: (- / ) / ,
		d: ( / ) / ,
		e: .E,
		f: .F,
	}
	if !finite(.a) || !finite(.b) || !finite(.c) || !finite(.d) {
		return inverseAffine{}, false, fmt.Errorf("inverse is outside the finite numeric domain")
	}
	return , true, nil
}

func ( inverseAffine) ( d2scene.Point) (d2scene.Point, bool) {
	 := .X - .e
	 := .Y - .f
	 := d2scene.Point{
		X: math.FMA(.a, , .c*),
		Y: math.FMA(.b, , .d*),
	}
	return , finitePoint()
}

func transformedImagePixelBounds( d2scene.Box,  d2scene.Matrix,  image.Rectangle) (image.Rectangle, error) {
	 := [...]d2scene.Point{
		.Point(d2scene.Point{X: .X, Y: .Y}),
		.Point(d2scene.Point{X: .X + .Width, Y: .Y}),
		.Point(d2scene.Point{X: .X + .Width, Y: .Y + .Height}),
		.Point(d2scene.Point{X: .X, Y: .Y + .Height}),
	}
	,  := math.Inf(1), math.Inf(1)
	,  := math.Inf(-1), math.Inf(-1)
	for ,  := range  {
		if  := validateRasterPoint();  != nil {
			return image.Rectangle{}, 
		}
		 = math.Min(, .X)
		 = math.Min(, .Y)
		 = math.Max(, .X)
		 = math.Max(, .Y)
	}
	if  <= float64(.Min.X) ||  <= float64(.Min.Y) ||  >= float64(.Max.X) ||  >= float64(.Max.Y) {
		return image.Rectangle{}, nil
	}
	 = math.Max(, float64(.Min.X))
	 = math.Max(, float64(.Min.Y))
	 = math.Min(, float64(.Max.X))
	 = math.Min(, float64(.Max.Y))
	return image.Rect(
		int(math.Floor()), int(math.Floor()),
		int(math.Ceil()), int(math.Ceil()),
	).Intersect(), nil
}

func drawPreparedImage( context.Context,  *image.RGBA,  *preparedImage) error {
	if  == nil || .asset == nil {
		return fmt.Errorf("d2raster: internal image primitive is missing its decoded asset")
	}
	 := .bounds.Intersect(.Bounds())
	if .Empty() {
		return .Err()
	}
	if ,  := nativeRasterImageOrigin();  {
		return drawNativeSizePreparedImage(, , .asset, , )
	}
	return drawSampledPreparedImage(, , , )
}

func nativeRasterImageOrigin( *preparedImage) (image.Point, bool) {
	if .inverse.a <= 0 || .inverse.d <= 0 || .inverse.b != 0 || .inverse.c != 0 ||
		.placement != .box ||
		.box.Width != .inverse.a*float64(.asset.width) ||
		.box.Height != .inverse.d*float64(.asset.bounds.Dy()) ||
		!powerOfTwo(.inverse.a) || !powerOfTwo(.inverse.d) {
		return image.Point{}, false
	}
	// The general path evaluates sample locations at eighth-pixel offsets. Keep
	// the shortcut inside the exact integer domain for those offsets, including
	// when a large local origin and translation nearly cancel in device space.
	const  = float64(uint64(1) << 47)
	 := .box.X / .inverse.a
	 := .box.Y / .inverse.d
	for ,  := range [...]float64{, , .inverse.e, .inverse.f} {
		if  != math.Trunc() || math.Abs() >  {
			return image.Point{}, false
		}
	}
	 :=  + .inverse.e
	 :=  + .inverse.f
	 := float64(platformMaxInt())
	 := - - 1
	if  != math.Trunc() ||  != math.Trunc() ||  <  ||  >  ||  <  ||  >  {
		return image.Point{}, false
	}
	return image.Pt(int(), int()), true
}

func powerOfTwo( float64) bool {
	,  := math.Frexp()
	return  == .5
}

func drawNativeSizePreparedImage( context.Context,  *image.RGBA,  *preparedRasterAsset,  image.Rectangle,  image.Point) error {
	switch source := .image.(type) {
	case *image.RGBA:
		return drawNativeSizeRGBA(, , , , )
	case *image.NRGBA:
		return drawNativeSizeNRGBA(, , , , )
	case *image.YCbCr:
		return drawNativeSizeYCbCr(, , , , )
	case *image.Paletted:
		return drawNativeSizePaletted(, , , , )
	case *image.Gray:
		return drawNativeSizeGray(, , , , )
	case *image.Alpha:
		return drawNativeSizeAlpha(, , , , )
	case *image.RGBA64:
		return drawNativeSizeRGBA64(, , , , )
	case *image.NRGBA64:
		return drawNativeSizeNRGBA64(, , , , )
	case *image.Gray16:
		return drawNativeSizeGray16(, , , , )
	case *image.Alpha16:
		return drawNativeSizeAlpha16(, , , , )
	case *image.CMYK:
		return drawNativeSizeCMYK(, , , , )
	case *image.NYCbCrA:
		return drawNativeSizeNYCbCrA(, , , , )
	}
	return drawNativeSizeGeneric(, , , , )
}

func drawNativeSizeRGBA( context.Context, ,  *image.RGBA,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .PixOffset(.Rect.Min.X+.Min.X-.X, .Rect.Min.Y+-.Y)
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*4]
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			compositeNativeRGBA([*4:*4], [*4:*4])
		}
	}
	return .Err()
}

func drawNativeSizeNRGBA( context.Context,  *image.RGBA,  *image.NRGBA,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .PixOffset(.Rect.Min.X+.Min.X-.X, .Rect.Min.Y+-.Y)
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*4]
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			compositeNativeNRGBA([*4:*4], [*4:*4])
		}
	}
	return .Err()
}

func drawNativeSizeYCbCr( context.Context,  *image.RGBA,  *image.YCbCr,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .Rect.Min.X + .Min.X - .X
		 := .Rect.Min.Y +  - .Y
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			for  := ;  < ; ++ {
				 := .YOffset(+, )
				 := .COffset(+, )
				, , ,  := (color.YCbCr{
					Y: .Y[], Cb: .Cb[], Cr: .Cr[],
				}).RGBA()
				 :=  * 4
				[] = byte(( + 128) / 257)
				[+1] = byte(( + 128) / 257)
				[+2] = byte(( + 128) / 257)
				[+3] = 0xff
			}
		}
	}
	return .Err()
}

func drawNativeSizePaletted( context.Context,  *image.RGBA,  *image.Paletted,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .PixOffset(.Rect.Min.X+.Min.X-.X, .Rect.Min.Y+-.Y)
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			for  := ;  < ; ++ {
				 := rgba64(.Palette[.Pix[+]])
				if [3] == 0 {
					continue
				}
				 :=  * 4
				compositePremultipliedRGBA64([:+4], )
			}
		}
	}
	return .Err()
}

func drawNativeSizeGray( context.Context,  *image.RGBA,  *image.Gray,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .PixOffset(.Rect.Min.X+.Min.X-.X, .Rect.Min.Y+-.Y)
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			for  := ;  < ; ++ {
				 := .Pix[+]
				 :=  * 4
				[] = 
				[+1] = 
				[+2] = 
				[+3] = 0xff
			}
		}
	}
	return .Err()
}

func drawNativeSizeAlpha( context.Context,  *image.RGBA,  *image.Alpha,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .PixOffset(.Rect.Min.X+.Min.X-.X, .Rect.Min.Y+-.Y)
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			for  := ;  < ; ++ {
				 := .Pix[+]
				if  == 0 {
					continue
				}
				 :=  * 4
				if  == 0xff {
					[] = 0xff
					[+1] = 0xff
					[+2] = 0xff
					[+3] = 0xff
					continue
				}
				compositePremultipliedRGBA8([:+4], , , , )
			}
		}
	}
	return .Err()
}

func drawNativeSizeRGBA64( context.Context,  *image.RGBA,  *image.RGBA64,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .PixOffset(.Rect.Min.X+.Min.X-.X, .Rect.Min.Y+-.Y)
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*8]
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			for  := ;  < ; ++ {
				 :=  * 8
				 := readBigEndianUint16([+6:])
				if  == 0 {
					continue
				}
				 :=  * 4
				compositePremultipliedRGBA64([:+4], [4]uint32{
					readBigEndianUint16([:]),
					readBigEndianUint16([+2:]),
					readBigEndianUint16([+4:]),
					,
				})
			}
		}
	}
	return .Err()
}

func drawNativeSizeNRGBA64( context.Context,  *image.RGBA,  *image.NRGBA64,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .PixOffset(.Rect.Min.X+.Min.X-.X, .Rect.Min.Y+-.Y)
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*8]
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			for  := ;  < ; ++ {
				 :=  * 8
				 := readBigEndianUint16([+6:])
				if  == 0 {
					continue
				}
				 := func( uint32) uint32 { return  *  / 0xffff }
				 :=  * 4
				compositePremultipliedRGBA64([:+4], [4]uint32{
					(readBigEndianUint16([:])),
					(readBigEndianUint16([+2:])),
					(readBigEndianUint16([+4:])),
					,
				})
			}
		}
	}
	return .Err()
}

func drawNativeSizeGray16( context.Context,  *image.RGBA,  *image.Gray16,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .PixOffset(.Rect.Min.X+.Min.X-.X, .Rect.Min.Y+-.Y)
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*2]
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			for  := ;  < ; ++ {
				 := byte((readBigEndianUint16([*2:]) + 128) / 257)
				 :=  * 4
				[] = 
				[+1] = 
				[+2] = 
				[+3] = 0xff
			}
		}
	}
	return .Err()
}

func drawNativeSizeAlpha16( context.Context,  *image.RGBA,  *image.Alpha16,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .PixOffset(.Rect.Min.X+.Min.X-.X, .Rect.Min.Y+-.Y)
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*2]
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			for  := ;  < ; ++ {
				 := byte((readBigEndianUint16([*2:]) + 128) / 257)
				if  == 0 {
					continue
				}
				 :=  * 4
				compositePremultipliedRGBA8([:+4], , , , )
			}
		}
	}
	return .Err()
}

func readBigEndianUint16( []byte) uint32 {
	return uint32([0])<<8 | uint32([1])
}

func drawNativeSizeCMYK( context.Context,  *image.RGBA,  *image.CMYK,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .PixOffset(.Rect.Min.X+.Min.X-.X, .Rect.Min.Y+-.Y)
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*4]
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			for  := ;  < ; ++ {
				 :=  * 4
				, , ,  := (color.CMYK{
					C: [], M: [+1], Y: [+2], K: [+3],
				}).RGBA()
				[] = byte(( + 128) / 257)
				[+1] = byte(( + 128) / 257)
				[+2] = byte(( + 128) / 257)
				[+3] = 0xff
			}
		}
	}
	return .Err()
}

func drawNativeSizeNYCbCrA( context.Context,  *image.RGBA,  *image.NYCbCrA,  image.Rectangle,  image.Point) error {
	 := .Dx()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		 := .Rect.Min.X + .Min.X - .X
		 := .Rect.Min.Y +  - .Y
		 := .PixOffset(.Min.X, )
		 := .Pix[ : +*4]
		for  := 0;  < ;  += 256 {
			if  := .Err();  != nil {
				return 
			}
			 := min(+256, )
			for  := ;  < ; ++ {
				 := .YOffset(+, )
				 := .COffset(+, )
				 := .AOffset(+, )
				, , ,  := (color.NYCbCrA{
					YCbCr: color.YCbCr{Y: .Y[], Cb: .Cb[], Cr: .Cr[]},
					A:     .A[],
				}).RGBA()
				if  == 0 {
					continue
				}
				 :=  * 4
				compositePremultipliedRGBA64([:+4], [4]uint32{, , , })
			}
		}
	}
	return .Err()
}

func compositeNativeRGBA(,  []byte) {
	for  := 0;  < len(); {
		 := [+3]
		if  == 0xff {
			 :=  + 4
			for  < len() && [+3] == 0xff {
				 += 4
			}
			copy([:], [:])
			 = 
			continue
		}
		if  != 0 {
			compositePremultipliedRGBA8([:+4], [], [+1], [+2], )
		}
		 += 4
	}
}

func compositeNativeNRGBA(,  []byte) {
	for  := 0;  < len(); {
		 := [+3]
		if  == 0xff {
			 :=  + 4
			for  < len() && [+3] == 0xff {
				 += 4
			}
			copy([:], [:])
			 = 
			continue
		}
		if  != 0 {
			 := uint32()
			 := func( byte) byte {
				return byte((uint32()* + 127) / 255)
			}
			compositePremultipliedRGBA8([:+4],
				([]), ([+1]), ([+2]), )
		}
		 += 4
	}
}

func compositePremultipliedRGBA8( []byte, , , ,  byte) {
	 := uint32()
	 := 255 - 
	 := func( byte) uint32 { return (uint32()* + 127) / 255 }
	[0] = byte(min(uint32(), ) + ([0]))
	[1] = byte(min(uint32(), ) + ([1]))
	[2] = byte(min(uint32(), ) + ([2]))
	[3] = byte( + ([3]))
}

func drawNativeSizeGeneric( context.Context,  *image.RGBA,  *preparedRasterAsset,  image.Rectangle,  image.Point) error {
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		for  := .Min.X;  < .Max.X; ++ {
			if (-.Min.X)&255 == 0 {
				if  := .Err();  != nil {
					return 
				}
			}
			 := .bounds.Min.X +  - .X
			 := .bounds.Min.Y +  - .Y
			var  [4]uint32
			if .sampleQuad == nil {
				 = rgba64(.image.At(, ))
			} else {
				 = .sampleQuad(.image, , , , ).c00
			}
			if [3] == 0 {
				continue
			}
			 := .PixOffset(, )
			compositePremultipliedRGBA64(.Pix[:+4], )
		}
	}
	return .Err()
}

func drawSampledPreparedImage( context.Context,  *image.RGBA,  *preparedImage,  image.Rectangle) error {
	const  = imageSamplesPerAxis * imageSamplesPerAxis
	 := .asset.width
	 := .asset.bounds.Dy()
	for  := .Min.Y;  < .Max.Y; ++ {
		if  := .Err();  != nil {
			return 
		}
		for  := .Min.X;  < .Max.X; ++ {
			if (-.Min.X)&255 == 0 {
				if  := .Err();  != nil {
					return 
				}
			}
			 := 0
			,  := 0.0, 0.0
			for  := 0;  < imageSamplesPerAxis; ++ {
				for  := 0;  < imageSamplesPerAxis; ++ {
					 := d2scene.Point{
						X: float64() + (float64()+.5)/imageSamplesPerAxis,
						Y: float64() + (float64()+.5)/imageSamplesPerAxis,
					}
					,  := .inverse.point()
					if ! || !pointInImageBox(, .box) {
						continue
					}
					 := (.X - .placement.X) / .placement.Width * float64()
					 := (.Y - .placement.Y) / .placement.Height * float64()
					if !finite() || !finite() ||  < 0 ||  < 0 ||  >= float64() ||  >= float64() {
						continue
					}
					++
					 += 
					 += 
				}
			}
			if  == 0 {
				continue
			}
			// Affine source coordinates average to the pixel center for fully
			// covered pixels, preserving exact 1:1 texels. At transformed or
			// clipped edges, average only covered samples and apply their
			// coverage after interpolation.
			 := bilinearPremultiplied(
				.asset,
				/float64(),
				/float64(),
			)
			var  [4]uint32
			for  := range  {
				[] = uint32((uint64([])*uint64() + /2) / )
			}
			if [3] == 0 {
				continue
			}
			 := .PixOffset(, )
			compositePremultipliedRGBA64(.Pix[:+4], )
		}
	}
	return .Err()
}

func pointInImageBox( d2scene.Point,  d2scene.Box) bool {
	return .X >= .X && .Y >= .Y &&
		.X < .X+.Width && .Y < .Y+.Height
}

func bilinearPremultiplied( *preparedRasterAsset, ,  float64) [4]uint32 {
	 := .bounds.Dy()
	 :=  - .5
	 :=  - .5
	 := int(math.Floor())
	 := int(math.Floor())
	 :=  - float64()
	 :=  - float64()
	,  := +1, +1
	 = clampInt(, 0, .width-1)
	 = clampInt(, 0, .width-1)
	 = clampInt(, 0, -1)
	 = clampInt(, 0, -1)
	// A zero interpolation weight makes the second texel irrelevant. Mark it
	// as shared so the bound sampler can avoid reading the same source pixel up
	// to four times. Exact pixel-center sampling is common for unscaled images.
	if  == 0 {
		 = 
	}
	if  == 0 {
		 = 
	}
	 += .bounds.Min.X
	 += .bounds.Min.X
	 += .bounds.Min.Y
	 += .bounds.Min.Y
	var  rasterSampleQuad
	if .sampleQuad == nil {
		.c00 = rgba64(.image.At(, ))
		if  ==  {
			.c10 = .c00
		} else {
			.c10 = rgba64(.image.At(, ))
		}
		if  ==  {
			.c01, .c11 = .c00, .c10
		} else {
			.c01 = rgba64(.image.At(, ))
			if  ==  {
				.c11 = .c01
			} else {
				.c11 = rgba64(.image.At(, ))
			}
		}
	} else {
		 = .sampleQuad(.image, , , , )
	}
	if  ==  &&  ==  {
		return .c00
	}
	var  [4]uint32
	if  ==  {
		for  := range  {
			 := float64(.c00[]) + (float64(.c01[])-float64(.c00[]))*
			[] = uint32(math.Round(math.Max(0, math.Min(65535, ))))
		}
		return 
	}
	if  ==  {
		for  := range  {
			 := float64(.c00[]) + (float64(.c10[])-float64(.c00[]))*
			[] = uint32(math.Round(math.Max(0, math.Min(65535, ))))
		}
		return 
	}
	for  := range  {
		 := float64(.c00[]) + (float64(.c10[])-float64(.c00[]))*
		 := float64(.c01[]) + (float64(.c11[])-float64(.c01[]))*
		 :=  + (-)*
		[] = uint32(math.Round(math.Max(0, math.Min(65535, ))))
	}
	return 
}

func bindRasterSampleQuad( image.Image) rasterSampleQuadFunc {
	// Bind the decoded image's concrete access path once. Calling Image.At
	// through image.Image makes several common concrete color values escape on
	// every texel read; an image is sampled four times for every painted pixel.
	switch .(type) {
	case *image.NRGBA:
		return sampleNRGBAQuad
	case *image.RGBA:
		return sampleRGBAQuad
	case *image.YCbCr:
		return sampleYCbCrQuad
	case *image.Paletted:
		// Palette colors are already interface values, so binding RGBA64At does
		// not eliminate allocations and is slower for four-texel interpolation.
		// The generic path still avoids duplicate reads at pixel centers/edges.
		return nil
	case *image.RGBA64:
		return sampleStandardRGBA64Quad
	case *image.NRGBA64:
		return sampleStandardRGBA64Quad
	case *image.Alpha:
		return nil
	case *image.Alpha16:
		return sampleStandardRGBA64Quad
	case *image.Gray:
		return nil
	case *image.Gray16:
		return sampleStandardRGBA64Quad
	case *image.CMYK:
		return sampleStandardRGBA64Quad
	case *image.NYCbCrA:
		return sampleStandardRGBA64Quad
	default:
		return nil
	}
}

func sampleNRGBAQuad( image.Image, , , ,  int) rasterSampleQuad {
	 := .(*image.NRGBA)
	 := rasterSampleQuad{c00: sampleNRGBAAt(, , )}
	if  ==  {
		.c10 = .c00
	} else {
		.c10 = sampleNRGBAAt(, , )
	}
	if  ==  {
		.c01, .c11 = .c00, .c10
	} else {
		.c01 = sampleNRGBAAt(, , )
		if  ==  {
			.c11 = .c01
		} else {
			.c11 = sampleNRGBAAt(, , )
		}
	}
	return 
}

func sampleRGBAQuad( image.Image, , , ,  int) rasterSampleQuad {
	 := .(*image.RGBA)
	 := rasterSampleQuad{c00: sampleRGBAAt(, , )}
	if  ==  {
		.c10 = .c00
	} else {
		.c10 = sampleRGBAAt(, , )
	}
	if  ==  {
		.c01, .c11 = .c00, .c10
	} else {
		.c01 = sampleRGBAAt(, , )
		if  ==  {
			.c11 = .c01
		} else {
			.c11 = sampleRGBAAt(, , )
		}
	}
	return 
}

func sampleYCbCrQuad( image.Image, , , ,  int) rasterSampleQuad {
	 := .(*image.YCbCr)
	 := rasterSampleQuad{c00: rgba64Value(.RGBA64At(, ))}
	if  ==  {
		.c10 = .c00
	} else {
		.c10 = rgba64Value(.RGBA64At(, ))
	}
	if  ==  {
		.c01, .c11 = .c00, .c10
	} else {
		.c01 = rgba64Value(.RGBA64At(, ))
		if  ==  {
			.c11 = .c01
		} else {
			.c11 = rgba64Value(.RGBA64At(, ))
		}
	}
	return 
}

func sampleNRGBAAt( *image.NRGBA, ,  int) [4]uint32 {
	 := (-.Rect.Min.Y)*.Stride + (-.Rect.Min.X)*4
	 := .Pix[ : +4 : +4]
	 := uint32([3])
	return [4]uint32{
		uint32([0]) * 0x101 *  / 0xff,
		uint32([1]) * 0x101 *  / 0xff,
		uint32([2]) * 0x101 *  / 0xff,
		 * 0x101,
	}
}

func sampleRGBAAt( *image.RGBA, ,  int) [4]uint32 {
	 := (-.Rect.Min.Y)*.Stride + (-.Rect.Min.X)*4
	 := .Pix[ : +4 : +4]
	return [4]uint32{
		uint32([0]) * 0x101,
		uint32([1]) * 0x101,
		uint32([2]) * 0x101,
		uint32([3]) * 0x101,
	}
}

func sampleStandardRGBA64Quad( image.Image, , , ,  int) rasterSampleQuad {
	return sampleBoundRGBA64Quad(.(image.RGBA64Image).RGBA64At, , , , )
}

func sampleBoundRGBA64Quad( func(,  int) color.RGBA64, , , ,  int) rasterSampleQuad {
	 := rasterSampleQuad{c00: rgba64Value((, ))}
	if  ==  {
		.c10 = .c00
	} else {
		.c10 = rgba64Value((, ))
	}
	if  ==  {
		.c01, .c11 = .c00, .c10
	} else {
		.c01 = rgba64Value((, ))
		if  ==  {
			.c11 = .c01
		} else {
			.c11 = rgba64Value((, ))
		}
	}
	return 
}

func rgba64Value( color.RGBA64) [4]uint32 {
	return [4]uint32{uint32(.R), uint32(.G), uint32(.B), uint32(.A)}
}

func rgba64( color.Color) [4]uint32 {
	, , ,  := .RGBA()
	return [4]uint32{, , , }
}

func clampInt(, ,  int) int {
	if  <  {
		return 
	}
	if  >  {
		return 
	}
	return 
}

func compositePremultipliedRGBA64( []byte,  [4]uint32) {
	 := func( uint32) uint32 { return ( + 128) / 257 }
	if [3] == 0xffff {
		[0] = uint8(([0]))
		[1] = uint8(([1]))
		[2] = uint8(([2]))
		[3] = 0xff
		return
	}
	 := ([3])
	if  == 0 {
		return
	}
	 := 255 - 
	 := func(,  uint32) uint32 { return (* + 127) / 255 }
	 := func( uint32,  byte) byte {
		 = ()
		if  >  {
			 = 
		}
		 :=  + (uint32(), )
		if  > 255 {
			 = 255
		}
		return byte()
	}
	[0] = ([0], [0])
	[1] = ([1], [1])
	[2] = ([2], [2])
	 :=  + (uint32([3]), )
	if  > 255 {
		 = 255
	}
	[3] = uint8()
}