code.witches.io/go/sdl2@v0.1.1/pixels.go (about)

     1  package sdl
     2  
     3  // #include <SDL2/SDL_pixels.h>
     4  import "C"
     5  import (
     6  	"strconv"
     7  	"unsafe"
     8  )
     9  
    10  type Color struct {
    11  	R uint8
    12  	G uint8
    13  	B uint8
    14  	A uint8
    15  }
    16  
    17  const (
    18  	AlphaOpaque      = 255
    19  	AlphaTransparent = 0
    20  )
    21  
    22  type PixelType uint8
    23  
    24  const (
    25  	PixelTypeUnknown PixelType = iota
    26  	PixelTypeIndex1
    27  	PixelTypeIndex4
    28  	PixelTypeIndex8
    29  	PixelTypePacked8
    30  	PixelTypePacked16
    31  	PixelTypePacked32
    32  	PixelTypeArrayUnsigned8
    33  	PixelTypeArrayUnsigned16
    34  	PixelTypeArrayUnsigned32
    35  	PixelTypeArrayFloat16
    36  	PixelTypeArrayFloat32
    37  )
    38  
    39  // type order layout bits bytes
    40  
    41  const (
    42  	BitmapOrderNone = iota
    43  	BitmapOrder4321
    44  	BitmapOrder1234
    45  )
    46  
    47  const (
    48  	PackedOrderNone = iota
    49  	PackedOrderXRGB
    50  	PackedOrderRGBX
    51  	PackedOrderARGB
    52  	PackedOrderRGBA
    53  	PackedOrderXBGR
    54  	PackedOrderBGRX
    55  	PackedOrderABGR
    56  	PackedOrderBGRA
    57  )
    58  
    59  const (
    60  	ArrayOrderNone = iota
    61  	ArrayOrderRGB
    62  	ArrayOrderRGBA
    63  	ArrayOrderARGB
    64  	ArrayOrderBGR
    65  	ArrayOrderBGRA
    66  	ArrayOrderABGR
    67  )
    68  
    69  const (
    70  	PackedLayoutNone = iota
    71  	PackedLayout332
    72  	PackedLayout4444
    73  	PackedLayout1555
    74  	PackedLayout5551
    75  	PackedLayout565
    76  	PackedLayout8888
    77  	PackedLayout2101010
    78  	PackedLayout1010102
    79  )
    80  
    81  const (
    82  	PixelFormatUnknown     PixelFormat = 0
    83  	PixelFormatIndex1LSB               = (1 << 28) | (PixelFormat(PixelTypeIndex1) << 24) | (BitmapOrder4321 << 20) | (PackedLayoutNone << 16) | (1 << 8) | 0
    84  	PixelFormatIndex1MSB               = (1 << 28) | (PixelFormat(PixelTypeIndex1) << 24) | (BitmapOrder1234 << 20) | (PackedLayoutNone << 16) | (1 << 8) | 0
    85  	PixelFormatIndex4LSB               = (1 << 28) | (PixelFormat(PixelTypeIndex4) << 24) | (BitmapOrder4321 << 20) | (PackedLayoutNone << 16) | (4 << 8) | 0
    86  	PixelFormatIndex4MSB               = (1 << 28) | (PixelFormat(PixelTypeIndex4) << 24) | (BitmapOrder1234 << 20) | (PackedLayoutNone << 16) | (4 << 8) | 0
    87  	PixelFormatIndex8                  = (1 << 28) | (PixelFormat(PixelTypeIndex8) << 24) | (BitmapOrderNone << 20) | (PackedLayoutNone << 16) | (8 << 8) | 1
    88  	PixelFormatRGB332                  = (1 << 28) | (PixelFormat(PixelTypePacked8) << 24) | (PackedOrderXRGB << 20) | (PackedLayout332 << 16) | (8 << 8) | 1
    89  	PixelFormatRGB444                  = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderXRGB << 20) | (PackedLayout4444 << 16) | (12 << 8) | 2
    90  	PixelFormatRGB555                  = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderXRGB << 20) | (PackedLayout1555 << 16) | (15 << 8) | 2
    91  	PixelFormatBGR555                  = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderXBGR << 20) | (PackedLayout1555 << 16) | (15 << 8) | 2
    92  	PixelFormatARGB4444                = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderARGB << 20) | (PackedLayout4444 << 16) | (16 << 8) | 2
    93  	PixelFormatRGBA4444                = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderRGBA << 20) | (PackedLayout4444 << 16) | (16 << 8) | 2
    94  	PixelFormatABGR4444                = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderABGR << 20) | (PackedLayout4444 << 16) | (16 << 8) | 2
    95  	PixelFormatBGRA4444                = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderBGRA << 20) | (PackedLayout4444 << 16) | (16 << 8) | 2
    96  	PixelFormatARGB1555                = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderARGB << 20) | (PackedLayout1555 << 16) | (16 << 8) | 2
    97  	PixelFormatRGBA5551                = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderRGBA << 20) | (PackedLayout5551 << 16) | (16 << 8) | 2
    98  	PixelFormatABGR1555                = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderABGR << 20) | (PackedLayout1555 << 16) | (16 << 8) | 2
    99  	PixelFormatBGRA5551                = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderBGRA << 20) | (PackedLayout5551 << 16) | (16 << 8) | 2
   100  	PixelFormatRGB565                  = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderXRGB << 20) | (PackedLayout565 << 16) | (16 << 8) | 2
   101  	PixelFormatBGR565                  = (1 << 28) | (PixelFormat(PixelTypePacked16) << 24) | (PackedOrderXBGR << 20) | (PackedLayout565 << 16) | (16 << 8) | 2
   102  	PixelFormatRGB24                   = (1 << 28) | (PixelFormat(PixelTypeArrayUnsigned8) << 24) | (ArrayOrderRGB << 20) | (PackedLayoutNone << 16) | (24 << 8) | 3
   103  	PixelFormatBGR24                   = (1 << 28) | (PixelFormat(PixelTypeArrayUnsigned8) << 24) | (ArrayOrderBGR << 20) | (PackedLayoutNone << 16) | (24 << 8) | 3
   104  	PixelFormatRGB888                  = (1 << 28) | (PixelFormat(PixelTypePacked32) << 24) | (PackedOrderXRGB << 20) | (PackedLayout8888 << 16) | (24 << 8) | 4
   105  	PixelFormatRGBX8888                = (1 << 28) | (PixelFormat(PixelTypePacked32) << 24) | (PackedOrderRGBX << 20) | (PackedLayout8888 << 16) | (24 << 8) | 4
   106  	PixelFormatBGR888                  = (1 << 28) | (PixelFormat(PixelTypePacked32) << 24) | (PackedOrderXBGR << 20) | (PackedLayout8888 << 16) | (24 << 8) | 4
   107  	PixelFormatBGRX8888                = (1 << 28) | (PixelFormat(PixelTypePacked32) << 24) | (PackedOrderBGRX << 20) | (PackedLayout8888 << 16) | (24 << 8) | 4
   108  	PixelFormatARGB8888                = (1 << 28) | (PixelFormat(PixelTypePacked32) << 24) | (PackedOrderARGB << 20) | (PackedLayout8888 << 16) | (32 << 8) | 4
   109  	PixelFormatRGBA8888                = (1 << 28) | (PixelFormat(PixelTypePacked32) << 24) | (PackedOrderRGBA << 20) | (PackedLayout8888 << 16) | (32 << 8) | 4
   110  	PixelFormatABGR8888                = (1 << 28) | (PixelFormat(PixelTypePacked32) << 24) | (PackedOrderABGR << 20) | (PackedLayout8888 << 16) | (32 << 8) | 4
   111  	PixelFormatBGRA8888                = (1 << 28) | (PixelFormat(PixelTypePacked32) << 24) | (PackedOrderBGRA << 20) | (PackedLayout8888 << 16) | (32 << 8) | 4
   112  	PixelFormatARGB2101010             = (1 << 28) | (PixelFormat(PixelTypePacked32) << 24) | (PackedOrderARGB << 20) | (PackedLayout2101010 << 16) | (32 << 8) | 4
   113  
   114  	// Planar mode: Y + V + U (3 planes)
   115  	PixelFormatYV12 PixelFormat = ('2' << 24) | ('1' << 16) | ('V' << 8) | 'Y'
   116  	// Planar mode: Y + U + V (3 planes)
   117  	PixelFormatIYUV PixelFormat = ('V' << 24) | ('U' << 16) | ('Y' << 8) | 'I'
   118  	// Packed mode: Y0+U0+Y1+V0 (1 plane)
   119  	PixelFormatYUY2 PixelFormat = ('2' << 24) | ('Y' << 16) | ('U' << 8) | 'Y'
   120  	// Packed mode: U0+Y0+V0+Y1 (1 plane)
   121  	PixelFormatUYVY PixelFormat = ('Y' << 24) | ('V' << 16) | ('Y' << 8) | 'U'
   122  	// Packed mode: Y0+V0+Y1+U0 (1 plane)
   123  	PixelFormatYVYU PixelFormat = ('U' << 24) | ('Y' << 16) | ('V' << 8) | 'Y'
   124  	// Planar mode: Y + U/V interleaved (2 planes)
   125  	PixelFormatNV12 PixelFormat = ('2' << 24) | ('1' << 16) | ('V' << 8) | 'N'
   126  	// Planar mode: Y + V/U interleaved (2 planes)
   127  	PixelFormatNV21 PixelFormat = ('1' << 24) | ('2' << 16) | ('V' << 8) | 'N'
   128  	// Android video texture format
   129  	PixelFormatExternalOES PixelFormat = (' ' << 24) | ('S' << 16) | ('E' << 8) | 'O'
   130  )
   131  
   132  var (
   133  	PixelFormatRGBA32 PixelFormat
   134  	PixelFormatARGB32 PixelFormat
   135  	PixelFormatBGRA32 PixelFormat
   136  	PixelFormatABGR32 PixelFormat
   137  )
   138  
   139  func init() {
   140  	switch "LittleEndian" {
   141  	case "BigEndian":
   142  		PixelFormatRGBA32 = PixelFormatRGBA8888
   143  		PixelFormatARGB32 = PixelFormatARGB8888
   144  		PixelFormatBGRA32 = PixelFormatBGRA8888
   145  		PixelFormatABGR32 = PixelFormatABGR8888
   146  	case "LittleEndian":
   147  		PixelFormatRGBA32 = PixelFormatABGR8888
   148  		PixelFormatARGB32 = PixelFormatBGRA8888
   149  		PixelFormatBGRA32 = PixelFormatARGB8888
   150  		PixelFormatABGR32 = PixelFormatRGBA8888
   151  	default:
   152  		panic("invalid endianness")
   153  	}
   154  }
   155  
   156  type PixelFormat uint32
   157  
   158  func (f PixelFormat) IsFourCC() bool {
   159  	return f != 0 && ((f>>28)&0xf) != 1
   160  }
   161  
   162  func (f PixelFormat) PixelType(format int) PixelType {
   163  	return PixelType((format >> 24) & 0xf)
   164  }
   165  
   166  var pixelFormatNames = map[PixelFormat]string{
   167  	PixelFormatIndex1LSB:   "INDEX1LSB",
   168  	PixelFormatIndex1MSB:   "INDEX1MSB",
   169  	PixelFormatIndex4LSB:   "INDEX4LSB",
   170  	PixelFormatIndex4MSB:   "INDEX4MSB",
   171  	PixelFormatIndex8:      "INDEX8",
   172  	PixelFormatRGB332:      "RGB332",
   173  	PixelFormatRGB444:      "RGB444",
   174  	PixelFormatRGB555:      "RGB555",
   175  	PixelFormatBGR555:      "BGR555",
   176  	PixelFormatARGB4444:    "ARGB4444",
   177  	PixelFormatRGBA4444:    "RGBA4444",
   178  	PixelFormatABGR4444:    "ABGR4444",
   179  	PixelFormatBGRA4444:    "BGRA4444",
   180  	PixelFormatARGB1555:    "ARGB1555",
   181  	PixelFormatRGBA5551:    "RGBA5551",
   182  	PixelFormatABGR1555:    "ABGR1555",
   183  	PixelFormatBGRA5551:    "BGRA5551",
   184  	PixelFormatRGB565:      "RGB565",
   185  	PixelFormatBGR565:      "BGR565",
   186  	PixelFormatRGB24:       "RGB24",
   187  	PixelFormatBGR24:       "BGR24",
   188  	PixelFormatRGB888:      "RGB888",
   189  	PixelFormatRGBX8888:    "RGBX8888",
   190  	PixelFormatBGR888:      "BGR888",
   191  	PixelFormatBGRX8888:    "BGRX8888",
   192  	PixelFormatARGB8888:    "ARGB8888",
   193  	PixelFormatRGBA8888:    "RGBA8888",
   194  	PixelFormatABGR8888:    "ABGR8888",
   195  	PixelFormatBGRA8888:    "BGRA8888",
   196  	PixelFormatARGB2101010: "ARGB2101010",
   197  	PixelFormatYV12:        "YV12",
   198  	PixelFormatIYUV:        "IYUV",
   199  	PixelFormatYUY2:        "YUY2",
   200  	PixelFormatUYVY:        "UYVY",
   201  	PixelFormatYVYU:        "YVYU",
   202  	PixelFormatNV12:        "NV12",
   203  	PixelFormatNV21:        "NV21",
   204  	PixelFormatExternalOES: "OES",
   205  }
   206  
   207  func (f PixelFormat) String() string {
   208  	name, ok := pixelFormatNames[f]
   209  	if !ok {
   210  		return "UNKNOWN" + "(" + strconv.Itoa(int(f)) + ")"
   211  	}
   212  	return name
   213  }
   214  
   215  func PixelOrder(format int) int {
   216  	return (format >> 20) & 0xf
   217  }
   218  
   219  func PixelLayout(format int) int {
   220  	return (format >> 16) & 0xf
   221  }
   222  
   223  func BitsPerPixel(format int) int {
   224  	return (format >> 8) & 0xf
   225  }
   226  
   227  type Palette struct {
   228  	nColors  int32
   229  	colors   *Color
   230  	version  uint32
   231  	refCount int32
   232  }
   233  
   234  type PixelFormatS struct {
   235  	format        PixelFormat
   236  	palette       *Palette
   237  	bitsPerPixel  uint8
   238  	bytesPerPixel uint8
   239  	RMask         uint32
   240  	GMask         uint32
   241  	BMask         uint32
   242  	AMask         uint32
   243  
   244  	RLoss    uint8
   245  	GLoss    uint8
   246  	BLoss    uint8
   247  	ALoss    uint8
   248  	RShift   uint8
   249  	GShift   uint8
   250  	BShift   uint8
   251  	AShift   uint8
   252  	refCount int32
   253  	next     *PixelFormatS
   254  }
   255  
   256  func AllocFormat(format PixelFormat) (*PixelFormatS, error) {
   257  	nativeFormat := C.SDL_AllocFormat(C.Uint32(format))
   258  	if nativeFormat == nil {
   259  		return nil, GetError()
   260  	}
   261  	return (*PixelFormatS)(unsafe.Pointer(nativeFormat)), nil
   262  }
   263  
   264  func (f *PixelFormatS) Free() {
   265  	C.SDL_FreeFormat((*C.struct_SDL_PixelFormat)(unsafe.Pointer(f)))
   266  }
   267  
   268  func MapRGB(format *PixelFormatS, r, g, b uint8) uint32 {
   269  	return uint32(C.SDL_MapRGB((*C.struct_SDL_PixelFormat)(unsafe.Pointer(format)), C.Uint8(r), C.Uint8(g), C.Uint8(b)))
   270  }
   271  
   272  func MapRGBA(format *PixelFormatS, r, g, b, a uint8) uint32 {
   273  	return uint32(C.SDL_MapRGBA((*C.struct_SDL_PixelFormat)(unsafe.Pointer(format)), C.Uint8(r), C.Uint8(g), C.Uint8(b), C.Uint8(a)))
   274  }
   275  
   276  func (f PixelFormatS) Format() PixelFormat {
   277  	return f.format
   278  }
   279  
   280  func (f PixelFormatS) BytesPerPixel() int {
   281  	return int(f.bytesPerPixel)
   282  }
   283  
   284  func (f PixelFormatS) Palette() []Color {
   285  	if f.palette == nil {
   286  		return nil
   287  	}
   288  	colors := make([]Color, f.palette.nColors)
   289  	copy(colors, unsafe.Slice(f.palette.colors, f.palette.nColors))
   290  	return colors
   291  }
   292  
   293  func AllocPalette(colors int) (*Palette, error) {
   294  	palette := C.SDL_AllocPalette(C.int(colors))
   295  	if palette == nil {
   296  		return nil, GetError()
   297  	}
   298  	return (*Palette)(unsafe.Pointer(palette)), nil
   299  }
   300  
   301  func FreePalette(palette *Palette) {
   302  	C.SDL_FreePalette((*C.struct_SDL_Palette)(unsafe.Pointer(palette)))
   303  }
   304  
   305  func (p *Palette) Free() {
   306  	FreePalette(p)
   307  }
   308  
   309  func SetPaletteColors(palette *Palette, offset int, colors []Color) error {
   310  	if len(colors) == 0 {
   311  		return nil
   312  	}
   313  	if C.SDL_SetPaletteColors(
   314  		(*C.struct_SDL_Palette)(unsafe.Pointer(palette)),
   315  		(*C.struct_SDL_Color)(unsafe.Pointer(&colors[0])),
   316  		C.int(offset),
   317  		C.int(len(colors)),
   318  	) != 0 {
   319  		return GetError()
   320  	}
   321  	return nil
   322  }
   323  
   324  func (p *Palette) SetColors(offset int, colors []Color) error {
   325  	return SetPaletteColors(p, offset, colors)
   326  }
   327  
   328  func SetPixelFormatPalette(format *PixelFormatS, palette *Palette) error {
   329  	if C.SDL_SetPixelFormatPalette(
   330  		(*C.struct_SDL_PixelFormat)(unsafe.Pointer(format)),
   331  		(*C.struct_SDL_Palette)(unsafe.Pointer(palette)),
   332  	) != 0 {
   333  		return GetError()
   334  	}
   335  	return nil
   336  }
   337  
   338  func (f *PixelFormatS) SetPalette(palette *Palette) error {
   339  	return SetPixelFormatPalette(f, palette)
   340  }