Skip to content

Commit c65d5fa

Browse files
authored
Merge pull request #2966 from pygame-community/ankith26-tobytes-premul
Adjust tobytes premul formula
2 parents 0547247 + 8f41130 commit c65d5fa

File tree

2 files changed

+41
-57
lines changed

2 files changed

+41
-57
lines changed

src_c/image.c

Lines changed: 38 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ tobytes_surf_32bpp(SDL_Surface *surf, int flipped, int hascolorkey,
495495
}
496496
}
497497

498+
#define PREMUL_PIXEL_ALPHA(pixel, alpha) (char)((((pixel) + 1) * (alpha)) >> 8)
499+
498500
PyObject *
499501
image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
500502
{
@@ -965,15 +967,12 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
965967
for (w = 0; w < surf->w; ++w) {
966968
color = *ptr++;
967969
alpha = ((color & Amask) >> Ashift) << Aloss;
968-
data[0] =
969-
(char)((((color & Rmask) >> Rshift) << Rloss) *
970-
alpha / 255);
971-
data[1] =
972-
(char)((((color & Gmask) >> Gshift) << Gloss) *
973-
alpha / 255);
974-
data[2] =
975-
(char)((((color & Bmask) >> Bshift) << Bloss) *
976-
alpha / 255);
970+
data[0] = PREMUL_PIXEL_ALPHA(
971+
((color & Rmask) >> Rshift) << Rloss, alpha);
972+
data[1] = PREMUL_PIXEL_ALPHA(
973+
((color & Gmask) >> Gshift) << Gloss, alpha);
974+
data[2] = PREMUL_PIXEL_ALPHA(
975+
((color & Bmask) >> Bshift) << Bloss, alpha);
977976
data[3] = (char)alpha;
978977
data += 4;
979978
}
@@ -992,15 +991,12 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
992991
#endif
993992
ptr += 3;
994993
alpha = ((color & Amask) >> Ashift) << Aloss;
995-
data[0] =
996-
(char)((((color & Rmask) >> Rshift) << Rloss) *
997-
alpha / 255);
998-
data[1] =
999-
(char)((((color & Gmask) >> Gshift) << Gloss) *
1000-
alpha / 255);
1001-
data[2] =
1002-
(char)((((color & Bmask) >> Bshift) << Bloss) *
1003-
alpha / 255);
994+
data[0] = PREMUL_PIXEL_ALPHA(
995+
((color & Rmask) >> Rshift) << Rloss, alpha);
996+
data[1] = PREMUL_PIXEL_ALPHA(
997+
((color & Gmask) >> Gshift) << Gloss, alpha);
998+
data[2] = PREMUL_PIXEL_ALPHA(
999+
((color & Bmask) >> Bshift) << Bloss, alpha);
10041000
data[3] = (char)alpha;
10051001
data += 4;
10061002
}
@@ -1018,15 +1014,12 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
10181014
data[0] = data[1] = data[2] = 0;
10191015
}
10201016
else {
1021-
data[0] =
1022-
(char)((((color & Rmask) >> Rshift) << Rloss) *
1023-
alpha / 255);
1024-
data[1] =
1025-
(char)((((color & Gmask) >> Gshift) << Gloss) *
1026-
alpha / 255);
1027-
data[2] =
1028-
(char)((((color & Bmask) >> Bshift) << Bloss) *
1029-
alpha / 255);
1017+
data[0] = PREMUL_PIXEL_ALPHA(
1018+
((color & Rmask) >> Rshift) << Rloss, alpha);
1019+
data[1] = PREMUL_PIXEL_ALPHA(
1020+
((color & Gmask) >> Gshift) << Gloss, alpha);
1021+
data[2] = PREMUL_PIXEL_ALPHA(
1022+
((color & Bmask) >> Bshift) << Bloss, alpha);
10301023
}
10311024
data[3] = (char)alpha;
10321025
data += 4;
@@ -1047,15 +1040,12 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
10471040
for (w = 0; w < surf->w; ++w) {
10481041
color = *ptr++;
10491042
alpha = ((color & Amask) >> Ashift) << Aloss;
1050-
data[1] =
1051-
(char)((((color & Rmask) >> Rshift) << Rloss) *
1052-
alpha / 255);
1053-
data[2] =
1054-
(char)((((color & Gmask) >> Gshift) << Gloss) *
1055-
alpha / 255);
1056-
data[3] =
1057-
(char)((((color & Bmask) >> Bshift) << Bloss) *
1058-
alpha / 255);
1043+
data[1] = PREMUL_PIXEL_ALPHA(
1044+
((color & Rmask) >> Rshift) << Rloss, alpha);
1045+
data[2] = PREMUL_PIXEL_ALPHA(
1046+
((color & Gmask) >> Gshift) << Gloss, alpha);
1047+
data[3] = PREMUL_PIXEL_ALPHA(
1048+
((color & Bmask) >> Bshift) << Bloss, alpha);
10591049
data[0] = (char)alpha;
10601050
data += 4;
10611051
}
@@ -1074,15 +1064,12 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
10741064
#endif
10751065
ptr += 3;
10761066
alpha = ((color & Amask) >> Ashift) << Aloss;
1077-
data[1] =
1078-
(char)((((color & Rmask) >> Rshift) << Rloss) *
1079-
alpha / 255);
1080-
data[2] =
1081-
(char)((((color & Gmask) >> Gshift) << Gloss) *
1082-
alpha / 255);
1083-
data[3] =
1084-
(char)((((color & Bmask) >> Bshift) << Bloss) *
1085-
alpha / 255);
1067+
data[1] = PREMUL_PIXEL_ALPHA(
1068+
((color & Rmask) >> Rshift) << Rloss, alpha);
1069+
data[2] = PREMUL_PIXEL_ALPHA(
1070+
((color & Gmask) >> Gshift) << Gloss, alpha);
1071+
data[3] = PREMUL_PIXEL_ALPHA(
1072+
((color & Bmask) >> Bshift) << Bloss, alpha);
10861073
data[0] = (char)alpha;
10871074
data += 4;
10881075
}
@@ -1100,15 +1087,12 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
11001087
data[1] = data[2] = data[3] = 0;
11011088
}
11021089
else {
1103-
data[1] =
1104-
(char)((((color & Rmask) >> Rshift) << Rloss) *
1105-
alpha / 255);
1106-
data[2] =
1107-
(char)((((color & Gmask) >> Gshift) << Gloss) *
1108-
alpha / 255);
1109-
data[3] =
1110-
(char)((((color & Bmask) >> Bshift) << Bloss) *
1111-
alpha / 255);
1090+
data[1] = PREMUL_PIXEL_ALPHA(
1091+
((color & Rmask) >> Rshift) << Rloss, alpha);
1092+
data[2] = PREMUL_PIXEL_ALPHA(
1093+
((color & Gmask) >> Gshift) << Gloss, alpha);
1094+
data[3] = PREMUL_PIXEL_ALPHA(
1095+
((color & Bmask) >> Bshift) << Bloss, alpha);
11121096
}
11131097
data[0] = (char)alpha;
11141098
data += 4;

test/image_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -506,9 +506,9 @@ def convertRGBAtoPremultiplied(surface_to_modify):
506506
for y in range(surface_to_modify.get_height()):
507507
color = surface_to_modify.get_at((x, y))
508508
premult_color = (
509-
color[0] * color[3] / 255,
510-
color[1] * color[3] / 255,
511-
color[2] * color[3] / 255,
509+
((color[0] + 1) * color[3]) >> 8,
510+
((color[1] + 1) * color[3]) >> 8,
511+
((color[2] + 1) * color[3]) >> 8,
512512
color[3],
513513
)
514514
surface_to_modify.set_at((x, y), premult_color)

0 commit comments

Comments
 (0)