Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made SDL_ReadSurfacePixel a public function #8863

Merged
merged 1 commit into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions include/SDL3/SDL_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,31 @@ extern DECLSPEC int SDLCALL SDL_BlitSurfaceUncheckedScaled(SDL_Surface *src,
const SDL_Rect *dstrect,
SDL_ScaleMode scaleMode);

/**
* Retrieves a single pixel from 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_GetRGBA, 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 read
* \param x the horizontal coordinate, 0 <= x < width
* \param y the vertical coordinate, 0 <= y < height
* \param r a pointer filled in with the red channel, 0-255, or NULL to ignore this channel
* \param g a pointer filled in with the green channel, 0-255, or NULL to ignore this channel
* \param b a pointer filled in with the blue channel, 0-255, or NULL to ignore this channel
* \param a a pointer filled in with the alpha channel, 0-255, or NULL to ignore this channel
* \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 DECLSPEC int SDLCALL SDL_ReadSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a);


/**
* Set the YUV conversion mode
*
Expand Down
21 changes: 0 additions & 21 deletions include/SDL3/SDL_test_compare.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,6 @@
extern "C" {
#endif

/**
* Retrieves a single pixel from 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_GetRGBA, 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
* \param x Horizontal coordinate, 0 <= x < width
* \param y Vertical coordinate, 0 <= y < height
* \param r Pointer to location to store red channel, 0-255
* \param g Pointer to location to store green channel, 0-255
* \param b Pointer to location to store blue channel, 0-255
* \param a Pointer to location to store alpha channel, 0-255
* \returns 0 if the surface is valid and the coordinates are in-bounds
*/
int SDLTest_ReadSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a);

/**
* Compares a surface and with reference image data for equality
*
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -963,6 +963,7 @@ SDL3_0.0.0 {
SDL_GetHapticFromInstanceID;
SDL_GetHapticInstanceID;
SDL_GetHapticName;
SDL_ReadSurfacePixel;
# extra symbols go here (don't modify this line)
local: *;
};
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -988,3 +988,4 @@
#define SDL_GetHapticFromInstanceID SDL_GetHapticFromInstanceID_REAL
#define SDL_GetHapticInstanceID SDL_GetHapticInstanceID_REAL
#define SDL_GetHapticName SDL_GetHapticName_REAL
#define SDL_ReadSurfacePixel SDL_ReadSurfacePixel_REAL
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1013,3 +1013,4 @@ SDL_DYNAPI_PROC(const char*,SDL_GetHapticInstanceName,(SDL_HapticID a),(a),retur
SDL_DYNAPI_PROC(SDL_Haptic*,SDL_GetHapticFromInstanceID,(SDL_HapticID a),(a),return)
SDL_DYNAPI_PROC(SDL_HapticID,SDL_GetHapticInstanceID,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_GetHapticName,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_ReadSurfacePixel,(SDL_Surface *a, int b, int c, Uint8 *d, Uint8 *e, Uint8 *f, Uint8 *g),(a,b,c,d,e,f,g),return)
12 changes: 2 additions & 10 deletions src/test/SDL_test_compare.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,11 @@
*/
#include <SDL3/SDL_test.h>

#include "../video/SDL_surface_pixel_impl.h"

#define FILENAME_SIZE 128

/* Counter for _CompareSurface calls; used for filename creation when comparisons fail */
static int _CompareSurfaceCount = 0;

int
SDLTest_ReadSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
{
return SDL_ReadSurfacePixel_impl(surface, x, y, r, g, b, a);
}

static void
LogErrorFormat(const char *name, const SDL_PixelFormat *format)
{
Expand Down Expand Up @@ -96,14 +88,14 @@ int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface,
for (i = 0; i < surface->w; i++) {
int temp;

temp = SDLTest_ReadSurfacePixel(surface, i, j, &R, &G, &B, &A);
temp = SDL_ReadSurfacePixel(surface, i, j, &R, &G, &B, &A);
if (temp != 0) {
SDLTest_LogError("Failed to retrieve pixel (%d,%d): %s", i, j, SDL_GetError());
ret++;
continue;
}

temp = SDLTest_ReadSurfacePixel(referenceSurface, i, j, &Rd, &Gd, &Bd, &Ad);
temp = SDL_ReadSurfacePixel(referenceSurface, i, j, &Rd, &Gd, &Bd, &Ad);
if (temp != 0) {
SDLTest_LogError("Failed to retrieve reference pixel (%d,%d): %s", i, j, SDL_GetError());
ret++;
Expand Down
68 changes: 62 additions & 6 deletions src/video/SDL_surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "SDL_video_c.h"
#include "SDL_blit.h"
#include "SDL_RLEaccel_c.h"
#include "SDL_surface_pixel_impl.h"
#include "SDL_pixels_c.h"
#include "SDL_yuv_c.h"
#include "../render/SDL_sysrender.h"
Expand All @@ -36,11 +35,6 @@ SDL_COMPILE_TIME_ASSERT(surface_size_assumptions,

SDL_COMPILE_TIME_ASSERT(can_indicate_overflow, SDL_SIZE_MAX > SDL_MAX_SINT32);

int SDL_ReadSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
{
return SDL_ReadSurfacePixel_impl(surface, x, y, r, g, b, a);
}

/* Public routines */

/*
Expand Down Expand Up @@ -1560,6 +1554,68 @@ int SDL_PremultiplyAlpha(int width, int height,
return 0;
}

/* This function Copyright 2023 Collabora Ltd., contributed to SDL under the ZLib license */
int SDL_ReadSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
{
Uint32 pixel = 0;
size_t bytes_per_pixel;
Uint8 unused;
Uint8 *p;

if (!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 (!r) {
r = &unused;
}

if (!g) {
g = &unused;
}

if (!b) {
b = &unused;
}

if (!a) {
a = &unused;
}

bytes_per_pixel = surface->format->BytesPerPixel;

if (bytes_per_pixel > sizeof(pixel)) {
return SDL_InvalidParamError("surface->format->BytesPerPixel");
}

if (SDL_MUSTLOCK(surface)) {
SDL_LockSurface(surface);
}

p = (Uint8 *)surface->pixels + y * surface->pitch + x * bytes_per_pixel;
/* Fill the appropriate number of least-significant bytes of pixel,
* leaving the most-significant bytes set to zero */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
SDL_memcpy(((Uint8 *) &pixel) + (sizeof(pixel) - bytes_per_pixel), p, bytes_per_pixel);
#else
SDL_memcpy(&pixel, p, bytes_per_pixel);
#endif
SDL_GetRGBA(pixel, surface->format, r, g, b, a);

if (SDL_MUSTLOCK(surface)) {
SDL_UnlockSurface(surface);
}
return 0;
}

/*
* Free a surface created by the above function.
*/
Expand Down
80 changes: 0 additions & 80 deletions src/video/SDL_surface_pixel_impl.h

This file was deleted.

2 changes: 1 addition & 1 deletion test/testshape.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode, SDL_Surface *shap
bitmap_scanline = bitmap + y * bytes_per_scanline;
for (x = 0; x < shape->w; x++) {
alpha = 0;
if (SDLTest_ReadSurfacePixel(shape, x, y, &r, &g, &b, &alpha) != 0) {
if (SDL_ReadSurfacePixel(shape, x, y, &r, &g, &b, &alpha) != 0) {
continue;
}

Expand Down