package sdl // #include "sdl_wrapper.h" // // #if !(SDL_VERSION_ATLEAST(2,0,5)) // // enum // { // #if SDL_BYTEORDER == SDL_BIG_ENDIAN // SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888, // SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888, // SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888, // SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888 // #else // SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888, // SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888, // SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888, // SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888 // #endif // }; // // #endif // // int bytesPerPixel(Uint32 format) { // return SDL_BYTESPERPIXEL(format); // } // // int bitsPerPixel(Uint32 format) { // return SDL_BITSPERPIXEL(format); // } import "C" import ( "image/color" "unsafe" ) // PixelFormat contains pixel format information. // (https://wiki.libsdl.org/SDL_PixelFormat) type PixelFormat struct { Format uint32 // one of the PIXELFORMAT values (https://wiki.libsdl.org/SDL_PixelFormatEnum) Palette *Palette // palette structure associated with this pixel format, or nil if the format doesn't have a palette (https://wiki.libsdl.org/SDL_Palette) BitsPerPixel uint8 // the number of significant bits in a pixel value, eg: 8, 15, 16, 24, 32 BytesPerPixel uint8 // the number of bytes required to hold a pixel value, eg: 1, 2, 3, 4 _ [2]uint8 // padding Rmask uint32 // a mask representing the location of the red component of the pixel Gmask uint32 // a mask representing the location of the green component of the pixel Bmask uint32 // a mask representing the location of the blue component of the pixel Amask uint32 // a mask representing the location of the alpha component of the pixel or 0 if the pixel format doesn't have any alpha information rLoss uint8 // (internal use) gLoss uint8 // (internal use) bLoss uint8 // (internal use) aLoss uint8 // (internal use) rShift uint8 // (internal use) gShift uint8 // (internal use) bShift uint8 // (internal use) aShift uint8 // (internal use) refCount int32 // (internal use) next *PixelFormat // (internal use) } type cPixelFormat C.SDL_PixelFormat // Palette contains palette information. // (https://wiki.libsdl.org/SDL_Palette) type Palette struct { Ncolors int32 // the number of colors in the palette Colors *Color // an array of Color structures representing the palette (https://wiki.libsdl.org/SDL_Color) version uint32 // incrementally tracks changes to the palette (internal use) refCount int32 // reference count (internal use) } type cPalette C.SDL_Palette // Color represents a color. This implements image/color.Color interface. // (https://wiki.libsdl.org/SDL_Color) type Color color.NRGBA // Uint32 return uint32 representation of RGBA color. func (c Color) Uint32() uint32 { var v uint32 v |= uint32(c.R) << 24 v |= uint32(c.G) << 16 v |= uint32(c.B) << 8 v |= uint32(c.A) return v } // Pixel types. const ( PIXELTYPE_UNKNOWN = C.SDL_PIXELTYPE_UNKNOWN PIXELTYPE_INDEX1 = C.SDL_PIXELTYPE_INDEX1 PIXELTYPE_INDEX4 = C.SDL_PIXELTYPE_INDEX4 PIXELTYPE_INDEX8 = C.SDL_PIXELTYPE_INDEX8 PIXELTYPE_PACKED8 = C.SDL_PIXELTYPE_PACKED8 PIXELTYPE_PACKED16 = C.SDL_PIXELTYPE_PACKED16 PIXELTYPE_PACKED32 = C.SDL_PIXELTYPE_PACKED32 PIXELTYPE_ARRAYU8 = C.SDL_PIXELTYPE_ARRAYU8 PIXELTYPE_ARRAYU16 = C.SDL_PIXELTYPE_ARRAYU16 PIXELTYPE_ARRAYU32 = C.SDL_PIXELTYPE_ARRAYU32 PIXELTYPE_ARRAYF16 = C.SDL_PIXELTYPE_ARRAYF16 PIXELTYPE_ARRAYF32 = C.SDL_PIXELTYPE_ARRAYF32 ) // Bitmap pixel order high bit -> low bit. const ( BITMAPORDER_NONE = C.SDL_BITMAPORDER_NONE BITMAPORDER_4321 = C.SDL_BITMAPORDER_4321 BITMAPORDER_1234 = C.SDL_BITMAPORDER_1234 ) // Packed component order high bit -> low bit. const ( PACKEDORDER_NONE = C.SDL_PACKEDORDER_NONE PACKEDORDER_XRGB = C.SDL_PACKEDORDER_XRGB PACKEDORDER_RGBX = C.SDL_PACKEDORDER_RGBX PACKEDORDER_ARGB = C.SDL_PACKEDORDER_ARGB PACKEDORDER_RGBA = C.SDL_PACKEDORDER_RGBA PACKEDORDER_XBGR = C.SDL_PACKEDORDER_XBGR PACKEDORDER_BGRX = C.SDL_PACKEDORDER_BGRX PACKEDORDER_ABGR = C.SDL_PACKEDORDER_ABGR PACKEDORDER_BGRA = C.SDL_PACKEDORDER_BGRA ) // Array component order low byte -> high byte. const ( ARRAYORDER_NONE = C.SDL_ARRAYORDER_NONE ARRAYORDER_RGB = C.SDL_ARRAYORDER_RGB ARRAYORDER_RGBA = C.SDL_ARRAYORDER_RGBA ARRAYORDER_ARGB = C.SDL_ARRAYORDER_ARGB ARRAYORDER_BGR = C.SDL_ARRAYORDER_BGR ARRAYORDER_BGRA = C.SDL_ARRAYORDER_BGRA ARRAYORDER_ABGR = C.SDL_ARRAYORDER_ABGR ) // Packed component layout. const ( PACKEDLAYOUT_NONE = C.SDL_PACKEDLAYOUT_NONE PACKEDLAYOUT_332 = C.SDL_PACKEDLAYOUT_332 PACKEDLAYOUT_4444 = C.SDL_PACKEDLAYOUT_4444 PACKEDLAYOUT_1555 = C.SDL_PACKEDLAYOUT_1555 PACKEDLAYOUT_5551 = C.SDL_PACKEDLAYOUT_5551 PACKEDLAYOUT_565 = C.SDL_PACKEDLAYOUT_565 PACKEDLAYOUT_8888 = C.SDL_PACKEDLAYOUT_8888 PACKEDLAYOUT_2101010 = C.SDL_PACKEDLAYOUT_2101010 PACKEDLAYOUT_1010102 = C.SDL_PACKEDLAYOUT_1010102 ) // Pixel format values. const ( PIXELFORMAT_UNKNOWN = C.SDL_PIXELFORMAT_UNKNOWN PIXELFORMAT_INDEX1LSB = C.SDL_PIXELFORMAT_INDEX1LSB PIXELFORMAT_INDEX1MSB = C.SDL_PIXELFORMAT_INDEX1MSB PIXELFORMAT_INDEX4LSB = C.SDL_PIXELFORMAT_INDEX4LSB PIXELFORMAT_INDEX4MSB = C.SDL_PIXELFORMAT_INDEX4MSB PIXELFORMAT_INDEX8 = C.SDL_PIXELFORMAT_INDEX8 PIXELFORMAT_RGB332 = C.SDL_PIXELFORMAT_RGB332 PIXELFORMAT_RGB444 = C.SDL_PIXELFORMAT_RGB444 PIXELFORMAT_RGB555 = C.SDL_PIXELFORMAT_RGB555 PIXELFORMAT_BGR555 = C.SDL_PIXELFORMAT_BGR555 PIXELFORMAT_ARGB4444 = C.SDL_PIXELFORMAT_ARGB4444 PIXELFORMAT_RGBA4444 = C.SDL_PIXELFORMAT_RGBA4444 PIXELFORMAT_ABGR4444 = C.SDL_PIXELFORMAT_ABGR4444 PIXELFORMAT_BGRA4444 = C.SDL_PIXELFORMAT_BGRA4444 PIXELFORMAT_ARGB1555 = C.SDL_PIXELFORMAT_ARGB1555 PIXELFORMAT_RGBA5551 = C.SDL_PIXELFORMAT_RGBA5551 PIXELFORMAT_ABGR1555 = C.SDL_PIXELFORMAT_ABGR1555 PIXELFORMAT_BGRA5551 = C.SDL_PIXELFORMAT_BGRA5551 PIXELFORMAT_RGB565 = C.SDL_PIXELFORMAT_RGB565 PIXELFORMAT_BGR565 = C.SDL_PIXELFORMAT_BGR565 PIXELFORMAT_RGB24 = C.SDL_PIXELFORMAT_RGB24 PIXELFORMAT_BGR24 = C.SDL_PIXELFORMAT_BGR24 PIXELFORMAT_RGB888 = C.SDL_PIXELFORMAT_RGB888 PIXELFORMAT_RGBX8888 = C.SDL_PIXELFORMAT_RGBX8888 PIXELFORMAT_BGR888 = C.SDL_PIXELFORMAT_BGR888 PIXELFORMAT_BGRX8888 = C.SDL_PIXELFORMAT_BGRX8888 PIXELFORMAT_ARGB8888 = C.SDL_PIXELFORMAT_ARGB8888 PIXELFORMAT_RGBA8888 = C.SDL_PIXELFORMAT_RGBA8888 PIXELFORMAT_ABGR8888 = C.SDL_PIXELFORMAT_ABGR8888 PIXELFORMAT_BGRA8888 = C.SDL_PIXELFORMAT_BGRA8888 PIXELFORMAT_ARGB2101010 = C.SDL_PIXELFORMAT_ARGB2101010 PIXELFORMAT_YV12 = C.SDL_PIXELFORMAT_YV12 PIXELFORMAT_IYUV = C.SDL_PIXELFORMAT_IYUV PIXELFORMAT_YUY2 = C.SDL_PIXELFORMAT_YUY2 PIXELFORMAT_UYVY = C.SDL_PIXELFORMAT_UYVY PIXELFORMAT_YVYU = C.SDL_PIXELFORMAT_YVYU ) // Pixel format variables. var ( PIXELFORMAT_RGBA32 = C.SDL_PIXELFORMAT_RGBA32 PIXELFORMAT_ARGB32 = C.SDL_PIXELFORMAT_ARGB32 PIXELFORMAT_BGRA32 = C.SDL_PIXELFORMAT_BGRA32 PIXELFORMAT_ABGR32 = C.SDL_PIXELFORMAT_ABGR32 ) // These define alpha as the opacity of a surface. const ( ALPHA_OPAQUE = C.SDL_ALPHA_OPAQUE ALPHA_TRANSPARENT = C.SDL_ALPHA_TRANSPARENT ) func (format *PixelFormat) cptr() *C.SDL_PixelFormat { return (*C.SDL_PixelFormat)(unsafe.Pointer(format)) } func (palette *Palette) cptr() *C.SDL_Palette { return (*C.SDL_Palette)(unsafe.Pointer(palette)) } /* * the following code is modified version of the code from bitbucket.org/dooots/go-sdl2 */ // GetPixelFormatName returns the human readable name of a pixel format. // (https://wiki.libsdl.org/SDL_GetPixelFormatName) func GetPixelFormatName(format uint) string { return C.GoString(C.SDL_GetPixelFormatName(C.Uint32(format))) } // PixelFormatEnumToMasks converts one of the enumerated pixel formats to a bpp value and RGBA masks. // (https://wiki.libsdl.org/SDL_PixelFormatEnumToMasks) func PixelFormatEnumToMasks(format uint) (bpp int, rmask, gmask, bmask, amask uint32, err error) { result := C.SDL_PixelFormatEnumToMasks(C.Uint32(format), (*C.int)(unsafe.Pointer(&bpp)), (*C.Uint32)(&rmask), (*C.Uint32)(&gmask), (*C.Uint32)(&bmask), (*C.Uint32)(&amask)) if result == C.SDL_FALSE { err = GetError() } return } // MasksToPixelFormatEnum converts a bpp value and RGBA masks to an enumerated pixel format. // (https://wiki.libsdl.org/SDL_MasksToPixelFormatEnum) func MasksToPixelFormatEnum(bpp int, rmask, gmask, bmask, amask uint32) uint { return uint(C.SDL_MasksToPixelFormatEnum(C.int(bpp), C.Uint32(rmask), C.Uint32(gmask), C.Uint32(bmask), C.Uint32(amask))) } // AllocFormat creates a PixelFormat structure corresponding to a pixel format. // (https://wiki.libsdl.org/SDL_AllocFormat) func AllocFormat(format uint) (*PixelFormat, error) { r := (*PixelFormat)(unsafe.Pointer(C.SDL_AllocFormat(C.Uint32(format)))) if r == nil { return nil, GetError() } return r, nil } // Free frees the PixelFormat structure allocated by AllocFormat(). // (https://wiki.libsdl.org/SDL_FreeFormat) func (format *PixelFormat) Free() { C.SDL_FreeFormat((*C.SDL_PixelFormat)(unsafe.Pointer(format))) } // AllocPalette creates a palette structure with the specified number of color entries. // (https://wiki.libsdl.org/SDL_AllocPalette) func AllocPalette(ncolors int) (*Palette, error) { r := (*Palette)(unsafe.Pointer(C.SDL_AllocPalette(C.int(ncolors)))) if r == nil { return nil, GetError() } return r, nil } // SetPalette sets the palette for the pixel format structure. // (https://wiki.libsdl.org/SDL_SetPixelFormatPalette) func (format *PixelFormat) SetPalette(palette *Palette) error { r := C.SDL_SetPixelFormatPalette((*C.SDL_PixelFormat)(unsafe.Pointer(format)), (*C.SDL_Palette)(unsafe.Pointer(palette))) if r != 0 { return GetError() } return nil } // SetColors sets a range of colors in the palette. // (https://wiki.libsdl.org/SDL_SetPaletteColors) func (palette *Palette) SetColors(colors []Color) error { if colors == nil { return nil } var ptr *C.SDL_Color if len(colors) > 0 { ptr = (*C.SDL_Color)(unsafe.Pointer(&colors[0])) } r := C.SDL_SetPaletteColors((*C.SDL_Palette)(unsafe.Pointer(palette)), ptr, 0, C.int(len(colors))) if r != 0 { return GetError() } return nil } // Free frees the palette created with AllocPalette(). // (https://wiki.libsdl.org/SDL_FreePalette) func (palette *Palette) Free() { C.SDL_FreePalette((*C.SDL_Palette)(unsafe.Pointer(palette))) } // MapRGB maps an RGB triple to an opaque pixel value for a given pixel format. // (https://wiki.libsdl.org/SDL_MapRGB) func MapRGB(format *PixelFormat, r, g, b uint8) uint32 { return uint32(C.SDL_MapRGB((*C.SDL_PixelFormat)(unsafe.Pointer(format)), C.Uint8(r), C.Uint8(g), C.Uint8(b))) } // MapRGBA maps an RGBA quadruple to a pixel value for a given pixel format. // (https://wiki.libsdl.org/SDL_MapRGBA) func MapRGBA(format *PixelFormat, r, g, b, a uint8) uint32 { return uint32(C.SDL_MapRGBA((*C.SDL_PixelFormat)(unsafe.Pointer(format)), C.Uint8(r), C.Uint8(g), C.Uint8(b), C.Uint8(a))) } // GetRGB returns RGB values from a pixel in the specified format. // (https://wiki.libsdl.org/SDL_GetRGB) func GetRGB(pixel uint32, format *PixelFormat) (r, g, b uint8) { C.SDL_GetRGB(C.Uint32(pixel), (*C.SDL_PixelFormat)(unsafe.Pointer(format)), (*C.Uint8)(&r), (*C.Uint8)(&g), (*C.Uint8)(&b)) return } // GetRGBA returns RGBA values from a pixel in the specified format. // (https://wiki.libsdl.org/SDL_GetRGBA) func GetRGBA(pixel uint32, format *PixelFormat) (r, g, b, a uint8) { C.SDL_GetRGBA(C.Uint32(pixel), (*C.SDL_PixelFormat)(unsafe.Pointer(format)), (*C.Uint8)(&r), (*C.Uint8)(&g), (*C.Uint8)(&b), (*C.Uint8)(&a)) return } // CalculateGammaRamp calculates a 256 entry gamma ramp for a gamma value. // (https://wiki.libsdl.org/SDL_CalculateGammaRamp) func CalculateGammaRamp(gamma float32, ramp *[256]uint16) { C.SDL_CalculateGammaRamp(C.float(gamma), (*C.Uint16)(unsafe.Pointer(&ramp[0]))) } // BytesPerPixel returns the number of bytes per pixel for the given format func BytesPerPixel(format uint32) int { return int(C.bytesPerPixel(C.Uint32(format))) } // BitsPerPixel returns the number of bits per pixel for the given format func BitsPerPixel(format uint32) int { return int(C.bitsPerPixel(C.Uint32(format))) } var ( RGB444Model color.Model = color.ModelFunc(rgb444Model) RGB332Model color.Model = color.ModelFunc(rgb332Model) RGB565Model color.Model = color.ModelFunc(rgb565Model) RGB555Model color.Model = color.ModelFunc(rgb555Model) BGR565Model color.Model = color.ModelFunc(bgr565Model) BGR555Model color.Model = color.ModelFunc(bgr555Model) ARGB4444Model color.Model = color.ModelFunc(argb4444Model) ABGR4444Model color.Model = color.ModelFunc(abgr4444Model) RGBA4444Model color.Model = color.ModelFunc(rgba4444Model) BGRA4444Model color.Model = color.ModelFunc(bgra4444Model) ARGB1555Model color.Model = color.ModelFunc(argb1555Model) RGBA5551Model color.Model = color.ModelFunc(rgba5551Model) ABGR1555Model color.Model = color.ModelFunc(abgr1555Model) BGRA5551Model color.Model = color.ModelFunc(bgra5551Model) RGBA8888Model color.Model = color.ModelFunc(rgba8888Model) BGRA8888Model color.Model = color.ModelFunc(bgra8888Model) ) type RGB444 struct { R, G, B byte } func (c RGB444) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale4to8bit(c.R), G: upscale4to8bit(c.G), B: upscale4to8bit(c.B), A: 0xFF, } return nrgba.RGBA() } func rgb444Model(c color.Color) color.Color { if _, ok := c.(RGB444); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return RGB444{ R: downscale8to4bit(nrgba.R), G: downscale8to4bit(nrgba.G), B: downscale8to4bit(nrgba.B), } } type RGB332 struct { R, G, B byte } func (c RGB332) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale3to8bit(c.R), G: upscale3to8bit(c.G), B: upscale2to8bit(c.B), A: 0xFF, } return nrgba.RGBA() } func rgb332Model(c color.Color) color.Color { if _, ok := c.(RGB332); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return RGB332{ R: downscale8to3bit(nrgba.R), G: downscale8to3bit(nrgba.G), B: downscale8to2bit(nrgba.B), } } type RGB565 struct { R, G, B byte } func (c RGB565) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale5to8bit(c.R), G: upscale6to8bit(c.G), B: upscale5to8bit(c.B), A: 0xFF, } return nrgba.RGBA() } func rgb565Model(c color.Color) color.Color { if _, ok := c.(RGB565); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return RGB565{ R: downscale8to5bit(nrgba.R), G: downscale8to6bit(nrgba.G), B: downscale8to5bit(nrgba.B), } } type RGB555 struct { R, G, B byte } func (c RGB555) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale5to8bit(c.R), G: upscale5to8bit(c.G), B: upscale5to8bit(c.B), A: 0xFF, } return nrgba.RGBA() } func rgb555Model(c color.Color) color.Color { if _, ok := c.(RGB555); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return RGB555{ R: downscale8to5bit(nrgba.R), G: downscale8to5bit(nrgba.G), B: downscale8to5bit(nrgba.B), } } type BGR565 struct { B, G, R byte } func (c BGR565) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale5to8bit(c.R), G: upscale6to8bit(c.G), B: upscale5to8bit(c.B), A: 0xFF, } return nrgba.RGBA() } func bgr565Model(c color.Color) color.Color { if _, ok := c.(BGR565); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return BGR565{ B: downscale8to5bit(nrgba.B), G: downscale8to6bit(nrgba.G), R: downscale8to5bit(nrgba.R), } } type BGR555 struct { B, G, R byte } func (c BGR555) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale5to8bit(c.R), G: upscale5to8bit(c.G), B: upscale5to8bit(c.B), A: 0xFF, } return nrgba.RGBA() } func bgr555Model(c color.Color) color.Color { if _, ok := c.(BGR555); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return BGR555{ B: downscale8to5bit(nrgba.B), G: downscale8to5bit(nrgba.G), R: downscale8to5bit(nrgba.R), } } type RGB888 struct { R, G, B byte } func (c RGB888) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: c.R, G: c.G, B: c.B, A: 0xFF, } return nrgba.RGBA() } func rgb888Model(c color.Color) color.Color { if _, ok := c.(RGB888); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return RGB888{ R: nrgba.R, G: nrgba.G, B: nrgba.B, } } type BGR888 struct { B, G, R byte } func (c BGR888) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: c.R, G: c.G, B: c.B, A: 0xFF, } return nrgba.RGBA() } func bgr888Model(c color.Color) color.Color { if _, ok := c.(BGR888); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return BGR888{ B: nrgba.B, G: nrgba.G, R: nrgba.R, } } type ARGB4444 struct { A, R, G, B byte } func (c ARGB4444) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale4to8bit(c.R), G: upscale4to8bit(c.G), B: upscale4to8bit(c.B), A: upscale4to8bit(c.A), } return nrgba.RGBA() } func argb4444Model(c color.Color) color.Color { if _, ok := c.(ARGB4444); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return ARGB4444{ A: downscale8to4bit(nrgba.A), R: downscale8to4bit(nrgba.R), G: downscale8to4bit(nrgba.G), B: downscale8to4bit(nrgba.B), } } type ABGR4444 struct { A, B, G, R byte } func (c ABGR4444) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale4to8bit(c.R), G: upscale4to8bit(c.G), B: upscale4to8bit(c.B), A: upscale4to8bit(c.A), } return nrgba.RGBA() } func abgr4444Model(c color.Color) color.Color { if _, ok := c.(ABGR4444); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return ABGR4444{ A: downscale8to4bit(nrgba.A), B: downscale8to4bit(nrgba.B), G: downscale8to4bit(nrgba.G), R: downscale8to4bit(nrgba.R), } } type RGBA4444 struct { R, G, B, A byte } func (c RGBA4444) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale4to8bit(c.R), G: upscale4to8bit(c.G), B: upscale4to8bit(c.B), A: upscale4to8bit(c.A), } return nrgba.RGBA() } func rgba4444Model(c color.Color) color.Color { if _, ok := c.(RGBA4444); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return RGBA4444{ R: downscale8to4bit(nrgba.R), G: downscale8to4bit(nrgba.G), B: downscale8to4bit(nrgba.B), A: downscale8to4bit(nrgba.A), } } type BGRA4444 struct { B, G, R, A byte } func (c BGRA4444) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale4to8bit(c.R), G: upscale4to8bit(c.G), B: upscale4to8bit(c.B), A: upscale4to8bit(c.A), } return nrgba.RGBA() } func bgra4444Model(c color.Color) color.Color { if _, ok := c.(BGRA4444); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return BGRA4444{ B: downscale8to4bit(nrgba.B), G: downscale8to4bit(nrgba.G), R: downscale8to4bit(nrgba.R), A: downscale8to4bit(nrgba.A), } } type ARGB1555 struct { A, R, G, B byte } func (c ARGB1555) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale5to8bit(c.R), G: upscale5to8bit(c.G), B: upscale5to8bit(c.B), A: upscale1to8bit(c.A), } return nrgba.RGBA() } func argb1555Model(c color.Color) color.Color { if _, ok := c.(ARGB1555); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return ARGB1555{ A: downscale8to1bit(nrgba.A), R: downscale8to5bit(nrgba.R), G: downscale8to5bit(nrgba.G), B: downscale8to5bit(nrgba.B), } } type RGBA5551 struct { R, G, B, A byte } func (c RGBA5551) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale5to8bit(c.R), G: upscale5to8bit(c.G), B: upscale5to8bit(c.B), A: upscale1to8bit(c.A), } return nrgba.RGBA() } func rgba5551Model(c color.Color) color.Color { if _, ok := c.(RGBA5551); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return RGBA5551{ R: downscale8to5bit(nrgba.R), G: downscale8to5bit(nrgba.G), B: downscale8to5bit(nrgba.B), A: downscale8to1bit(nrgba.A), } } type ABGR1555 struct { A, R, G, B byte } func (c ABGR1555) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale5to8bit(c.R), G: upscale5to8bit(c.G), B: upscale5to8bit(c.B), A: upscale1to8bit(c.A), } return nrgba.RGBA() } func abgr1555Model(c color.Color) color.Color { if _, ok := c.(ABGR1555); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return ABGR1555{ A: downscale8to1bit(nrgba.A), R: downscale8to5bit(nrgba.R), G: downscale8to5bit(nrgba.G), B: downscale8to5bit(nrgba.B), } } type BGRA5551 struct { B, G, R, A byte } func (c BGRA5551) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: upscale5to8bit(c.R), G: upscale5to8bit(c.G), B: upscale5to8bit(c.B), A: upscale1to8bit(c.A), } return nrgba.RGBA() } func bgra5551Model(c color.Color) color.Color { if _, ok := c.(BGRA5551); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return BGRA5551{ B: downscale8to5bit(nrgba.B), G: downscale8to5bit(nrgba.G), R: downscale8to5bit(nrgba.R), A: downscale8to1bit(nrgba.A), } } type RGBA8888 struct { R, G, B, A byte } func (c RGBA8888) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: c.R, G: c.G, B: c.B, A: c.A, } return nrgba.RGBA() } func rgba8888Model(c color.Color) color.Color { if _, ok := c.(RGBA8888); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return RGBA8888{ R: nrgba.R, G: nrgba.G, B: nrgba.B, A: nrgba.A, } } type BGRA8888 struct { B, G, R, A byte } func (c BGRA8888) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: c.R, G: c.G, B: c.B, A: c.A, } return nrgba.RGBA() } func bgra8888Model(c color.Color) color.Color { if _, ok := c.(BGRA8888); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return BGRA8888{ B: nrgba.B, G: nrgba.G, R: nrgba.R, A: nrgba.A, } } type ARGB8888 struct { A, R, G, B byte } func (c ARGB8888) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: c.R, G: c.G, B: c.B, A: c.A, } return nrgba.RGBA() } func argb8888Model(c color.Color) color.Color { if _, ok := c.(ARGB8888); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return ARGB8888{ A: nrgba.A, R: nrgba.R, G: nrgba.G, B: nrgba.B, } } type ABGR8888 struct { A, B, G, R byte } func (c ABGR8888) RGBA() (r, g, b, a uint32) { nrgba := color.NRGBA{ R: c.R, G: c.G, B: c.B, A: c.A, } return nrgba.RGBA() } func abgr8888Model(c color.Color) color.Color { if _, ok := c.(ABGR8888); ok { return c } nrgba := color.NRGBAModel.Convert(c).(color.NRGBA) return ABGR8888{ A: nrgba.A, B: nrgba.B, G: nrgba.G, R: nrgba.R, } } func downscale8to1bit(alpha byte) byte { if alpha == 0 { return 0 } return 1 } func downscale8to2bit(in byte) byte { return in >> 6 } func downscale8to3bit(in byte) byte { return in >> 5 } func downscale8to4bit(in byte) byte { return in >> 4 } func downscale8to5bit(in byte) byte { return in >> 3 } func downscale8to6bit(in byte) byte { return in >> 2 } func upscale1to8bit(alphaBit byte) byte { if alphaBit == 0 { return 0 } return 0xFF } func upscale2to8bit(in byte) byte { return in<<6 | in<<4 | in<<2 | in } func upscale3to8bit(in byte) byte { return in<<5 | in<<2 | (in>>1)&0b11 } func upscale4to8bit(in byte) byte { return in<<4 | in } func upscale5to8bit(in byte) byte { return in<<3 | (in>>2)&0b111 } func upscale6to8bit(in byte) byte { return in<<2 | (in>>4)&0b11 }