mirror of https://github.com/libsdl-org/SDL
Added SDL_WriteSurfacePixel() and SDL_WriteSurfacePixelFloat()
This commit is contained in:
parent
12e50d17a2
commit
9294476788
|
@ -1211,6 +1211,49 @@ extern SDL_DECLSPEC int SDLCALL SDL_ReadSurfacePixel(SDL_Surface *surface, int x
|
|||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_ReadSurfacePixelFloat(SDL_Surface *surface, int x, int y, float *r, float *g, float *b, float *a);
|
||||
|
||||
/**
|
||||
* Writes a single pixel to a surface.
|
||||
*
|
||||
* This function prioritizes correctness over speed: it is suitable for unit
|
||||
* tests, but is not intended for use in a game engine.
|
||||
*
|
||||
* Like SDL_MapRGBA, this uses the entire 0..255 range when converting color
|
||||
* components from pixel formats with less than 8 bits per RGB component.
|
||||
*
|
||||
* \param surface the surface to write.
|
||||
* \param x the horizontal coordinate, 0 <= x < width.
|
||||
* \param y the vertical coordinate, 0 <= y < height.
|
||||
* \param r the red channel value, 0-255.
|
||||
* \param g the green channel value, 0-255.
|
||||
* \param b the blue channel value, 0-255.
|
||||
* \param a the alpha channel value, 0-255.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_WriteSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||
|
||||
/**
|
||||
* Writes a single pixel to a surface.
|
||||
*
|
||||
* This function prioritizes correctness over speed: it is suitable for unit
|
||||
* tests, but is not intended for use in a game engine.
|
||||
*
|
||||
* \param surface the surface to write.
|
||||
* \param x the horizontal coordinate, 0 <= x < width.
|
||||
* \param y the vertical coordinate, 0 <= y < height.
|
||||
* \param r the red channel value, normally in the range 0-1.
|
||||
* \param g the green channel value, normally in the range 0-1.
|
||||
* \param b the blue channel value, normally in the range 0-1.
|
||||
* \param a the alpha channel value, normally in the range 0-1.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_WriteSurfacePixelFloat(SDL_Surface *surface, int x, int y, float r, float g, float b, float a);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -875,6 +875,8 @@ SDL3_0.0.0 {
|
|||
SDL_WriteS64LE;
|
||||
SDL_WriteS8;
|
||||
SDL_WriteStorageFile;
|
||||
SDL_WriteSurfacePixel;
|
||||
SDL_WriteSurfacePixelFloat;
|
||||
SDL_WriteU16BE;
|
||||
SDL_WriteU16LE;
|
||||
SDL_WriteU32BE;
|
||||
|
|
|
@ -900,6 +900,8 @@
|
|||
#define SDL_WriteS64LE SDL_WriteS64LE_REAL
|
||||
#define SDL_WriteS8 SDL_WriteS8_REAL
|
||||
#define SDL_WriteStorageFile SDL_WriteStorageFile_REAL
|
||||
#define SDL_WriteSurfacePixel SDL_WriteSurfacePixel_REAL
|
||||
#define SDL_WriteSurfacePixelFloat SDL_WriteSurfacePixelFloat_REAL
|
||||
#define SDL_WriteU16BE SDL_WriteU16BE_REAL
|
||||
#define SDL_WriteU16LE SDL_WriteU16LE_REAL
|
||||
#define SDL_WriteU32BE SDL_WriteU32BE_REAL
|
||||
|
|
|
@ -910,6 +910,8 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS64BE,(SDL_IOStream *a, Sint64 b),(a,b),return
|
|||
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS64LE,(SDL_IOStream *a, Sint64 b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS8,(SDL_IOStream *a, Sint8 b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_WriteStorageFile,(SDL_Storage *a, const char *b, const void *c, Uint64 d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_WriteSurfacePixel,(SDL_Surface *a, int b, int c, Uint8 d, Uint8 e, Uint8 f, Uint8 g),(a,b,c,d,e,f,g),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_WriteSurfacePixelFloat,(SDL_Surface *a, int b, int c, float d, float e, float f, float g),(a,b,c,d,e,f,g),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU16BE,(SDL_IOStream *a, Uint16 b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU16LE,(SDL_IOStream *a, Uint16 b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU32BE,(SDL_IOStream *a, Uint32 b),(a,b),return)
|
||||
|
|
|
@ -2459,6 +2459,126 @@ int SDL_ReadSurfacePixelFloat(SDL_Surface *surface, int x, int y, float *r, floa
|
|||
return result;
|
||||
}
|
||||
|
||||
int SDL_WriteSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
Uint32 pixel = 0;
|
||||
size_t bytes_per_pixel;
|
||||
Uint8 *p;
|
||||
int result = -1;
|
||||
|
||||
if (!SDL_SurfaceValid(surface) || !surface->format || !surface->pixels) {
|
||||
return SDL_InvalidParamError("surface");
|
||||
}
|
||||
|
||||
if (x < 0 || x >= surface->w) {
|
||||
return SDL_InvalidParamError("x");
|
||||
}
|
||||
|
||||
if (y < 0 || y >= surface->h) {
|
||||
return SDL_InvalidParamError("y");
|
||||
}
|
||||
|
||||
bytes_per_pixel = SDL_BYTESPERPIXEL(surface->format);
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
if (SDL_LockSurface(surface) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
p = (Uint8 *)surface->pixels + y * surface->pitch + x * bytes_per_pixel;
|
||||
|
||||
if (bytes_per_pixel <= sizeof(pixel) && !SDL_ISPIXELFORMAT_FOURCC(surface->format)) {
|
||||
pixel = SDL_MapRGBA(surface->internal->format, surface->internal->palette, r, g, b, a);
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
SDL_memcpy(p, ((Uint8 *)&pixel) + (sizeof(pixel) - bytes_per_pixel), bytes_per_pixel);
|
||||
#else
|
||||
SDL_memcpy(p, &pixel, bytes_per_pixel);
|
||||
#endif
|
||||
result = 0;
|
||||
} else if (SDL_ISPIXELFORMAT_FOURCC(surface->format)) {
|
||||
result = SDL_Unsupported();
|
||||
} else {
|
||||
/* This is really slow, but it gets the job done */
|
||||
Uint8 rgba[4];
|
||||
SDL_Colorspace colorspace = SDL_GetSurfaceColorspace(surface);
|
||||
|
||||
rgba[0] = r;
|
||||
rgba[1] = g;
|
||||
rgba[2] = b;
|
||||
rgba[3] = a;
|
||||
result = SDL_ConvertPixelsAndColorspace(1, 1, SDL_PIXELFORMAT_RGBA32, SDL_COLORSPACE_SRGB, 0, rgba, sizeof(rgba), surface->format, colorspace, surface->internal->props, p, surface->pitch);
|
||||
}
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int SDL_WriteSurfacePixelFloat(SDL_Surface *surface, int x, int y, float r, float g, float b, float a)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (!SDL_SurfaceValid(surface) || !surface->format || !surface->pixels) {
|
||||
return SDL_InvalidParamError("surface");
|
||||
}
|
||||
|
||||
if (x < 0 || x >= surface->w) {
|
||||
return SDL_InvalidParamError("x");
|
||||
}
|
||||
|
||||
if (y < 0 || y >= surface->h) {
|
||||
return SDL_InvalidParamError("y");
|
||||
}
|
||||
|
||||
if (SDL_BYTESPERPIXEL(surface->format) <= sizeof(Uint32) && !SDL_ISPIXELFORMAT_FOURCC(surface->format)) {
|
||||
Uint8 r8, g8, b8, a8;
|
||||
|
||||
r8 = (Uint8)SDL_round(SDL_clamp(r, 0.0f, 1.0f) * 255.0f);
|
||||
g8 = (Uint8)SDL_round(SDL_clamp(g, 0.0f, 1.0f) * 255.0f);
|
||||
b8 = (Uint8)SDL_round(SDL_clamp(b, 0.0f, 1.0f) * 255.0f);
|
||||
a8 = (Uint8)SDL_round(SDL_clamp(a, 0.0f, 1.0f) * 255.0f);
|
||||
if (SDL_WriteSurfacePixel(surface, x, y, r8, g8, b8, a8) == 0) {
|
||||
result = 0;
|
||||
}
|
||||
} else if (SDL_ISPIXELFORMAT_FOURCC(surface->format)) {
|
||||
result = SDL_Unsupported();
|
||||
} else {
|
||||
/* This is really slow, but it gets the job done */
|
||||
float rgba[4];
|
||||
Uint8 *p;
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
if (SDL_LockSurface(surface) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
p = (Uint8 *)surface->pixels + y * surface->pitch + x * SDL_BYTESPERPIXEL(surface->format);
|
||||
|
||||
rgba[0] = r;
|
||||
rgba[1] = g;
|
||||
rgba[2] = b;
|
||||
rgba[3] = a;
|
||||
|
||||
if (surface->format == SDL_PIXELFORMAT_RGBA128_FLOAT) {
|
||||
SDL_memcpy(p, rgba, sizeof(rgba));
|
||||
result = 0;
|
||||
} else {
|
||||
SDL_Colorspace dst_colorspace = SDL_GetSurfaceColorspace(surface);
|
||||
SDL_Colorspace src_colorspace = (dst_colorspace == SDL_COLORSPACE_SRGB_LINEAR ? SDL_COLORSPACE_SRGB_LINEAR : SDL_COLORSPACE_SRGB);
|
||||
|
||||
result = SDL_ConvertPixelsAndColorspace(1, 1, SDL_PIXELFORMAT_RGBA128_FLOAT, src_colorspace, 0, rgba, sizeof(rgba), surface->format, dst_colorspace, surface->internal->props, p, surface->pitch);
|
||||
}
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free a surface created by the above function.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue