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 }