~shabbyrobe/imgx

8f339096952096f9a8c5b8d6c5b09601751c928d — Blake Williams 5 months ago 7f0c394
Use unsafe.Slice for cast
4 files changed, 6 insertions(+), 17 deletions(-)

M README.md
M rgba/convert.go
M rgba/convert_fast.go
M rgba/index.go
M README.md => README.md +1 -2
@@ 18,8 18,7 @@ in this repo. If you require stability, it is _strongly_ recommended that you
copy and paste the required modules into your project's `internal` folder. They
should be small and discrete enough, with minimal interdependencies.

Individual modules are separately licensed and documented (reflecting my
preference to use separate repositories), but if there is no LICENSE file
Individual modules are separately licensed, but if there is no LICENSE file
contained therein, the code is licensed under the LICENSE at the top-level.



M rgba/convert.go => rgba/convert.go +2 -1
@@ 26,7 26,7 @@ func CastToBytes(colors []color.RGBA) ([]byte, error) {
	return castToBytes(colors)
}

// Convert an image.Image into an *image.RGBA.
// Convert an image.Image into an *rgba.Image
//
// This will attempt to cast the image first, and if that succeeds, 'copied' will be
// false. If you require a copy of the image, call CloneDeep() on the output:


@@ 44,6 44,7 @@ func CastToBytes(colors []color.RGBA) ([]byte, error) {
// one does not exist it should be added. If a fast path is unavailable, there are slow
// paths that attempt to use image.RGBAAt(), then finally image.At().
//
// .
func Convert(img image.Image) (out *Image, copied bool) {
	switch img := img.(type) {
	case *Image:

M rgba/convert_fast.go => rgba/convert_fast.go +3 -12
@@ 1,4 1,4 @@
//+build !purego
//go:build !purego

package rgba



@@ 6,7 6,6 @@ import (
	"fmt"
	"image"
	"image/color"
	"reflect"
	"unsafe"
)



@@ 14,19 13,11 @@ func castFromBytes(data []byte) ([]color.RGBA, error) {
	if len(data)%4 != 0 {
		return nil, fmt.Errorf("rgba: raw RGBA data must be a multiple of 4")
	}
	// EVIL:
	header := *(*reflect.SliceHeader)(unsafe.Pointer(&data))
	header.Len /= 4
	header.Cap /= 4
	return *(*[]color.RGBA)(unsafe.Pointer(&header)), nil
	return unsafe.Slice((*color.RGBA)(unsafe.Pointer(&data[0])), len(data)/4), nil
}

func castToBytes(colors []color.RGBA) (data []byte, err error) {
	// EVIL:
	header := *(*reflect.SliceHeader)(unsafe.Pointer(&colors))
	header.Len *= 4
	header.Cap *= 4
	return *(*[]byte)(unsafe.Pointer(&header)), nil
	return unsafe.Slice((*byte)(unsafe.Pointer(&colors[0])), len(colors)*4), nil
}

var colorVal color.RGBA

M rgba/index.go => rgba/index.go +0 -2
@@ 33,7 33,6 @@ type Index interface {
// go.mod updates).
//
// See RGBPrecacheIndexer.
//
type IndexUnmarshaler interface {
	UnmarshalIndex(b []byte) (Index, error)
}


@@ 42,7 41,6 @@ type IndexUnmarshaler interface {
// representation for faster Unmarshaling later.
//
// See RGBPrecacheIndex.
//
type IndexMarshaler interface {
	MarshalIndex() []byte
}