30 #include <boost/circular_buffer.hpp>
31 #include <boost/math/constants/constants.hpp>
34 #define ERR_DP LOG_STREAM(err, log_display)
38 SDL_version sdl_version;
39 SDL_GetVersion(&sdl_version);
40 return version_info(sdl_version.major, sdl_version.minor, sdl_version.patch);
47 if(ver.major < major)
return false;
48 if(ver.major > major)
return true;
50 if(ver.minor < minor)
return false;
51 if(ver.minor > minor)
return true;
53 if(ver.patch < patch)
return false;
79 if(
surf ==
nullptr ||
dst ==
nullptr) {
80 PLAIN_LOG <<
"Could not create surface to scale onto";
108 if (
w == 0 ||
h ==0) {
113 if(
surf ==
nullptr ||
dst ==
nullptr) {
114 PLAIN_LOG <<
"Could not create surface to scale onto";
122 const uint32_t*
const src_pixels = src_lock.
pixels();
123 uint32_t*
const dst_pixels = dst_lock.
pixels();
129 for(
int ydst = 0; ydst !=
h; ++ydst, ysrc += yratio) {
131 for(
int xdst = 0; xdst !=
w; ++xdst, xsrc += xratio) {
135 const uint32_t*
const src_word = src_pixels + ysrcint*
surf->w + xsrcint;
136 uint32_t*
const dst_word = dst_pixels + ydst*
dst->w + xdst;
137 const int dx = (xsrcint + 1 <
surf->w) ? 1 : 0;
138 const int dy = (ysrcint + 1 <
surf->h) ?
surf->w : 0;
141 uint32_t rr,gg,bb,aa, temp;
143 uint32_t pix[4], bilin[4];
166 const int32_t
e = 0x000000FF & xsrc;
167 const int32_t
s = 0x000000FF & ysrc;
168 const int32_t
n = 0xFF -
s;
171 const int32_t we = 0xFF -
e;
174 pix[1] = *(src_word + dx);
175 pix[2] = *(src_word + dy);
176 pix[3] = *(src_word + dx + dy);
184 rr = bb = gg = aa = 0;
185 for (loc=0; loc<4; loc++) {
197 temp = (a * bilin[loc]);
213 *dst_word = (a << 24) + (r << 16) + (
g << 8) +
b;
234 if(
surf ==
nullptr ||
dst ==
nullptr) {
235 PLAIN_LOG <<
"Could not create surface to scale onto";
243 const uint32_t*
const src_pixels = src_lock.
pixels();
244 uint32_t*
const dst_pixels = dst_lock.
pixels();
250 for(
int ydst = 0; ydst !=
h; ++ydst, ysrc += yratio) {
252 for(
int xdst = 0; xdst !=
w; ++xdst, xsrc += xratio) {
256 const uint32_t*
const src_word = src_pixels + ysrcint*
surf->w + xsrcint;
257 uint32_t*
const dst_word = dst_pixels + ydst*
dst->w + xdst;
258 const int dx = (xsrcint + 1 <
surf->w) ? 1 : 0;
259 const int dy = (ysrcint + 1 <
surf->h) ?
surf->w : 0;
262 uint32_t rr,gg,bb,aa;
263 uint16_t avg_r, avg_g, avg_b;
264 uint32_t pix[4], bilin[4];
278 const int32_t east = 0x000000FF & xsrc;
279 const int32_t south = 0x000000FF & ysrc;
280 const int32_t north = 0xFF - south;
281 const int32_t west = 0xFF - east;
284 pix[1] = *(src_word + dx);
285 pix[2] = *(src_word + dy);
286 pix[3] = *(src_word + dx + dy);
288 bilin[0] = north*west;
289 bilin[1] = north*east;
290 bilin[2] = south*west;
291 bilin[3] = south*east;
297 avg_r = avg_g = avg_b = 0;
299 for (loc=0; loc<4; loc++) {
326 rr = gg = bb = aa = 0;
327 for (loc=0; loc<4; loc++) {
333 r =
static_cast<uint8_t
>(avg_r);
334 g =
static_cast<uint8_t
>(avg_g);
335 b =
static_cast<uint8_t
>(avg_b);
337 rr += r * bilin[loc];
338 gg +=
g * bilin[loc];
339 bb +=
b * bilin[loc];
340 aa += a * bilin[loc];
346 *dst_word = (a << 24) + (r << 16) + (
g << 8) +
b;
356 if(
surf ==
nullptr) {
367 PLAIN_LOG <<
"Could not create surface to scale onto";
371 if(
w == 0 ||
h == 0) {
380 const uint32_t*
const src_pixels = src_lock.
pixels();
381 uint32_t*
const dst_pixels = dst_lock.
pixels();
383 const int src_w =
surf->w;
384 const int src_h =
surf->h;
386 const float xratio =
static_cast<float>(src_w) /
static_cast<float>(
w);
387 const float yratio =
static_cast<float>(src_h) /
static_cast<float>(
h);
388 for(
int ydst = 0; ydst !=
h; ++ydst) {
389 for(
int xdst = 0; xdst !=
w; ++xdst) {
391 const int xsrc = std::floor(
static_cast<float>(xdst) * xratio);
392 const int ysrc = std::floor(
static_cast<float>(ydst) * yratio);
393 dst_pixels[ydst *
dst->w + xdst] = src_pixels[ysrc * src_w + xsrc];
405 uint32_t* beg = lock.
pixels();
406 uint32_t* end = beg + nsurf.
area();
409 uint8_t alpha = (*beg) >> 24;
417 r = std::clamp(
static_cast<int>(r) +
red, 0, 255);
418 g = std::clamp(
static_cast<int>(
g) +
green, 0, 255);
419 b = std::clamp(
static_cast<int>(
b) +
blue, 0, 255);
421 *beg = (alpha << 24) + (r << 16) + (
g << 8) +
b;
433 uint32_t* beg = lock.
pixels();
434 uint32_t* end = beg + nsurf.
area();
437 uint8_t alpha = (*beg) >> 24;
450 const uint8_t avg =
static_cast<uint8_t
>((
451 77 *
static_cast<uint16_t
>(r) +
452 150 *
static_cast<uint16_t
>(
g) +
453 29 *
static_cast<uint16_t
>(
b) ) / 256);
455 *beg = (alpha << 24) | (avg << 16) | (avg << 8) | avg;
467 uint32_t* beg = lock.
pixels();
468 uint32_t* end = beg + nsurf.
area();
471 uint8_t alpha = (*beg) >> 24;
474 uint8_t r,
g,
b, result;
482 result =
static_cast<uint8_t
>(0.299 * r + 0.587 *
g + 0.114 *
b) > threshold ? 255 : 0;
484 *beg = (alpha << 24) | (result << 16) | (result << 8) | result;
496 uint32_t* beg = lock.
pixels();
497 uint32_t* end = beg + nsurf.
area();
500 uint8_t alpha = (*beg) >> 24;
511 uint8_t outRed = std::min(255,
static_cast<int>((r * 0.393) + (
g * 0.769) + (
b * 0.189)));
512 uint8_t outGreen = std::min(255,
static_cast<int>((r * 0.349) + (
g * 0.686) + (
b * 0.168)));
513 uint8_t outBlue = std::min(255,
static_cast<int>((r * 0.272) + (
g * 0.534) + (
b * 0.131)));
515 *beg = (alpha << 24) | (outRed << 16) | (outGreen << 8) | (outBlue);
527 uint32_t* beg = lock.
pixels();
528 uint32_t* end = beg + nsurf.
area();
531 uint8_t alpha = (*beg) >> 24;
534 uint8_t r,
g,
b, newR, newG, newB;
543 newR = r > thresholdR ? 255 - r : r;
544 newG =
g > thresholdG ? 255 -
g :
g;
545 newB =
b > thresholdB ? 255 -
b :
b;
547 *beg = (alpha << 24) | (newR << 16) | (newG << 8) | (newB);
559 uint32_t* beg = lock.
pixels();
560 uint32_t* end = beg + nsurf.
area();
563 uint8_t alpha = (*beg) >> 24;
565 *beg = (0xff << 24) | (alpha << 16) | (alpha << 8) | alpha;
576 uint32_t* beg = lock.
pixels();
577 uint32_t* end = beg + nsurf.
area();
581 *beg = 0xff000000 | *beg;
599 uint32_t* beg = lock.
pixels();
600 uint32_t* end = beg +
surf->w*
surf->h;
603 uint8_t alpha = (*beg) >> 24;
609 *beg = (alpha*4) << 24;
623 uint32_t* beg = lock.
pixels();
624 uint32_t* end = beg + nsurf.
area();
627 uint8_t alpha = (*beg) >> 24;
630 uint8_t
red,
green,
blue, newRed, newGreen, newBlue, newAlpha;
703 *beg = (newAlpha << 24) | (newRed << 16) | (newGreen << 8) | newBlue;
716 if(map_rgb.empty()) {
721 uint32_t* beg = lock.
pixels();
722 uint32_t* end = beg + nsurf.
area();
725 uint8_t alpha = (*beg) >> 24;
730 uint32_t oldrgb = (*beg) | 0xFF000000;
733 if(
i != map_rgb.end()) {
734 *beg = (alpha << 24) | (
i->second.to_argb_bytes() & 0x00FFFFFF);
746 uint32_t* beg = lock.
pixels();
747 uint32_t* end = beg + nsurf.
area();
749 if (amount < 0) amount = 0;
751 uint8_t alpha = (*beg) >> 24;
763 *beg = (alpha << 24) + (r << 16) + (
g << 8) +
b;
773 if(
surf ==
nullptr) {
777 SDL_SetSurfaceAlphaMod(
surf, alpha_mod);
784 uint32_t* beg = lock.
pixels();
785 uint32_t* end = beg + nsurf.
area();
788 uint8_t alpha = (*beg) >> 24;
796 alpha = uint8_t(std::clamp(
static_cast<int>(alpha) + amount, 0, 255));
797 *beg = (alpha << 24) + (r << 16) + (
g << 8) +
b;
807 if(nsurf ==
nullptr) {
808 *empty_result =
true;
811 if(nmask ==
nullptr) {
815 if (nsurf->w != nmask->w) {
820 std::stringstream ss;
821 ss <<
"Detected an image with bad dimensions: ";
823 ss << nsurf->w <<
"x" << nsurf->h;
825 PLAIN_LOG <<
"It will not be masked, please use: "<< nmask->w <<
"x" << nmask->h;
834 uint32_t* beg = lock.
pixels();
835 uint32_t* end = beg + nsurf.
area();
836 const uint32_t* mbeg = mlock.
pixels();
837 const uint32_t* mend = mbeg + nmask->w*nmask->h;
839 while(beg != end && mbeg != mend) {
840 uint8_t alpha = (*beg) >> 24;
848 uint8_t malpha = (*mbeg) >> 24;
849 if (alpha > malpha) {
855 *beg = (alpha << 24) + (r << 16) + (
g << 8) +
b;
863 *empty_result = empty;
868 if(nsurf ==
nullptr) {
871 if(nmask ==
nullptr){
875 if (nsurf->w != nmask->w || nsurf->h != nmask->h ) {
884 const uint32_t* mbeg = mlock.
pixels();
885 const uint32_t* mend = mbeg + nmask->w*nmask->h;
886 const uint32_t* beg = lock.
pixels();
889 while(mbeg != mend) {
890 uint8_t malpha = (*mbeg) >> 24;
892 uint8_t alpha = (*beg) >> 24;
906 if(nsurf ==
nullptr) {
909 if(lightmap ==
nullptr) {
913 if (nsurf->w != lightmap->w) {
918 PLAIN_LOG <<
"Detected an image with bad dimensions: " << nsurf->w <<
"x" << nsurf->h;
919 PLAIN_LOG <<
"It will not be lighted, please use: "<< lightmap->w <<
"x" << lightmap->h;
926 uint32_t* beg = lock.
pixels();
927 uint32_t* end = beg + nsurf.
area();
928 const uint32_t* lbeg = llock.
pixels();
929 const uint32_t* lend = lbeg + lightmap.
area();
931 while(beg != end && lbeg != lend) {
932 uint8_t alpha = (*beg) >> 24;
945 int dr = (
static_cast<int>(lr) - 128) * 2;
946 int dg = (
static_cast<int>(
lg) - 128) * 2;
947 int db = (
static_cast<int>(lb) - 128) * 2;
949 r = std::clamp(r + dr, 0, 255);
950 g = std::clamp(
g + dg, 0, 255);
951 b = std::clamp(
b + db, 0, 255);
953 *beg = (alpha << 24) + (r << 16) + (
g << 8) +
b;
963 if(
surf ==
nullptr) {
967 const int max_blur = 256;
968 if(depth > max_blur) {
972 uint32_t queue[max_blur];
973 const uint32_t* end_queue = queue + max_blur;
975 const uint32_t ff = 0xff;
977 const unsigned pixel_offset =
rect.y *
surf->w +
rect.x;
980 for(
int y = 0; y <
rect.h; ++y) {
981 const uint32_t* front = &queue[0];
982 uint32_t* back = &queue[0];
984 uint32_t*
p = lock.
pixels() + pixel_offset + y *
surf->w;
985 for(
int x = 0; x <= depth && x <
rect.w; ++x, ++
p) {
986 red += ((*p) >> 16)&0xFF;
987 green += ((*p) >> 8)&0xFF;
991 if(back == end_queue) {
997 for(
int x = 0; x <
rect.w; ++x, ++
p) {
999 | (std::min(
red/avg,ff) << 16)
1000 | (std::min(
green/avg,ff) << 8)
1001 | std::min(
blue/avg,ff);
1004 red -= ((*front) >> 16)&0xFF;
1005 green -= ((*front) >> 8)&0xFF;
1006 blue -= *front&0xFF;
1009 if(front == end_queue) {
1014 if(x + depth+1 <
rect.w) {
1015 uint32_t* q =
p + depth+1;
1016 red += ((*q) >> 16)&0xFF;
1017 green += ((*q) >> 8)&0xFF;
1021 if(back == end_queue) {
1028 for(
int x = 0; x <
rect.w; ++x) {
1029 const uint32_t* front = &queue[0];
1030 uint32_t* back = &queue[0];
1032 uint32_t*
p = lock.
pixels() + pixel_offset + x;
1033 for(
int y = 0; y <= depth && y <
rect.h; ++y,
p +=
surf->w) {
1034 red += ((*p) >> 16)&0xFF;
1035 green += ((*p) >> 8)&0xFF;
1039 if(back == end_queue) {
1044 p = lock.
pixels() + pixel_offset + x;
1045 for(
int y = 0; y <
rect.h; ++y,
p +=
surf->w) {
1047 | (std::min(
red/avg,ff) << 16)
1048 | (std::min(
green/avg,ff) << 8)
1049 | std::min(
blue/avg,ff);
1052 red -= ((*front) >> 16)&0xFF;
1053 green -= ((*front) >> 8)&0xFF;
1054 blue -= *front&0xFF;
1057 if(front == end_queue) {
1062 if(y + depth+1 <
rect.h) {
1063 uint32_t* q =
p + (depth+1)*
surf->w;
1064 red += ((*q) >> 16)&0xFF;
1065 green += ((*q) >> 8)&0xFF;
1069 if(back == end_queue) {
1079 if(res ==
nullptr) {
1083 const int max_blur = 256;
1084 if(depth > max_blur) {
1094 : alpha(((*
p) >> 24)&0xFF)
1095 ,
red(((*
p) >> 16)&0xFF)
1096 ,
green(((*
p) >> 8)&0xFF)
1097 ,
blue((*
p)&0xFF) {}
1106 Average& operator+=(
const Pixel& pix){
1107 red += pix.alpha * pix.red;
1108 green += pix.alpha * pix.green;
1109 blue += pix.alpha * pix.blue;
1113 Average& operator-=(
const Pixel& pix){
1114 red -= pix.alpha * pix.red;
1115 green -= pix.alpha * pix.green;
1116 blue -= pix.alpha * pix.blue;
1120 uint32_t operator()(
unsigned num){
1121 const uint32_t ff = 0xff;
1125 return (std::min(alpha/num,ff) << 24)
1126 | (std::min(
red/alpha,ff) << 16)
1127 | (std::min(
green/alpha,ff) << 8)
1128 | std::min(
blue/alpha,ff);
1132 boost::circular_buffer<Pixel> queue(depth*2+1);
1137 for(y = 0; y < res->h; ++y) {
1142 uint32_t*
p = lock.
pixels() + y*res->w;
1143 for(x = 0; x <= depth && x < res->w; ++x, ++
p) {
1144 assert(!queue.full());
1145 queue.push_back(Pixel{
p});
1146 avg += queue.back();
1151 for(x = 0; x < res->w; ++x, ++
p) {
1153 const uint32_t num = queue.size();
1158 avg -= queue.front();
1159 assert(!queue.empty());
1164 if(x + depth+1 < res->w) {
1165 uint32_t* q =
p + depth+1;
1166 assert(!queue.full());
1167 queue.push_back(Pixel{q});
1168 avg += queue.back();
1171 assert(
static_cast<int>(queue.size()) == std::min(depth, res->w));
1176 for(x = 0; x < res->w; ++x) {
1181 uint32_t*
p = lock.
pixels() + x;
1182 for(y = 0; y <= depth && y < res->h; ++y,
p += res->w) {
1183 assert(!queue.full());
1184 queue.push_back(Pixel{
p});
1185 avg += queue.back();
1190 for(y = 0; y < res->h; ++y,
p += res->w) {
1192 const uint32_t num = queue.size();
1197 avg -= queue.front();
1198 assert(!queue.empty());
1203 if(y + depth+1 < res->h) {
1204 uint32_t* q =
p + (depth+1)*res->w;
1205 assert(!queue.full());
1206 queue.push_back(Pixel{q});
1207 avg += queue.back();
1210 assert(
static_cast<int>(queue.size()) == std::min(depth, res->h));
1222 if(res ==
nullptr) {
1223 PLAIN_LOG <<
"Could not create a new surface in cut_surface()";
1227 std::size_t sbpp =
surf->format->BytesPerPixel;
1228 std::size_t spitch =
surf->pitch;
1229 std::size_t rbpp = res->format->BytesPerPixel;
1230 std::size_t rpitch = res->pitch;
1233 SDL_Rect src_rect = r;
1234 SDL_Rect dst_rect { 0, 0, r.w, r.h };
1236 if (src_rect.x < 0) {
1237 if (src_rect.x + src_rect.w <= 0)
1239 dst_rect.x -= src_rect.x;
1240 dst_rect.w += src_rect.x;
1241 src_rect.w += src_rect.x;
1244 if (src_rect.y < 0) {
1245 if (src_rect.y + src_rect.h <= 0)
1247 dst_rect.y -= src_rect.y;
1248 dst_rect.h += src_rect.y;
1249 src_rect.h += src_rect.y;
1253 if(src_rect.x >=
surf->w || src_rect.y >=
surf->h)
1259 const uint8_t*
src =
reinterpret_cast<const uint8_t *
>(slock.
pixels());
1260 uint8_t* dest =
reinterpret_cast<uint8_t *
>(rlock.
pixels());
1262 for(
int y = 0; y < src_rect.h && (src_rect.y + y) <
surf->h; ++y) {
1263 const uint8_t* line_src =
src + (src_rect.y + y) * spitch + src_rect.x * sbpp;
1264 uint8_t* line_dest = dest + (dst_rect.y + y) * rpitch + dst_rect.x * rbpp;
1265 std::size_t
size = src_rect.w + src_rect.x <=
surf->w ? src_rect.w :
surf->w - src_rect.x;
1267 assert(rpitch >= src_rect.w * rbpp);
1268 memcpy(line_dest, line_src,
size * rbpp);
1278 uint32_t* beg = lock.
pixels();
1279 uint32_t* end = beg + nsurf.
area();
1281 uint16_t ratio = amount * 256;
1282 const uint16_t
red = ratio * color.r;
1283 const uint16_t
green = ratio * color.g;
1284 const uint16_t
blue = ratio * color.b;
1285 ratio = 256 - ratio;
1288 uint8_t a =
static_cast<uint8_t
>(*beg >> 24);
1289 uint8_t r = (ratio *
static_cast<uint8_t
>(*beg >> 16) +
red) >> 8;
1290 uint8_t
g = (ratio *
static_cast<uint8_t
>(*beg >> 8) +
green) >> 8;
1291 uint8_t
b = (ratio *
static_cast<uint8_t
>(*beg) +
blue) >> 8;
1293 *beg = (a << 24) | (r << 16) | (
g << 8) |
b;
1307 int src_w, src_h, dst_w, dst_h;
1308 float min_x, min_y, sine, cosine;
1312 const float radians = angle * boost::math::constants::pi<float>() / 180;
1313 cosine = std::cos(radians);
1314 sine = std::sin(radians);
1316 src_w =
surf->w * zoom;
1317 src_h =
surf->h * zoom;
1319 const float point_1x = src_h * -sine;
1320 const float point_1y = src_h * cosine;
1321 const float point_2x = src_w * cosine - src_h * sine;
1322 const float point_2y = src_h * cosine + src_w * sine;
1323 const float point_3x = src_w * cosine;
1324 const float point_3y = src_w * sine;
1328 min_x = std::min(0.0F, std::min(point_1x, std::min(point_2x, point_3x)));
1329 min_y = std::min(0.0F, std::min(point_1y, std::min(point_2y, point_3y)));
1330 max_x = (angle > 90 && angle < 180) ? 0 : std::max(point_1x, std::max(point_2x, point_3x));
1331 max_y = (angle > 180 && angle < 270) ? 0 : std::max(point_1y, std::max(point_2y, point_3y));
1332 dst_w =
static_cast<int>(ceil(std::abs(max_x) - min_x)) / zoom;
1333 dst_h =
static_cast<int>(ceil(std::abs(max_y) - min_y)) / zoom;
1338 uint32_t*
const dst_pixels = dst_lock.
pixels();
1342 const uint32_t*
const src_pixels = src_lock.
pixels();
1344 const float scale = 1.f / zoom;
1345 const int max_x = dst_w * zoom;
1346 const int max_y = dst_h * zoom;
1349 for (
int x = 0; x < max_x; x += offset)
1350 for (
int y = 0; y < max_y; y += offset) {
1352 const float source_x = (x + min_x)*cosine + (y + min_y)*sine;
1353 const float source_y = (y + min_y)*cosine - (x + min_x)*sine;
1355 if (source_x >= 0 && source_x < src_w && source_y >= 0 && source_y < src_h) {
1358 src_pixels[int(source_y) *
src->w + int(source_x)];
1369 if (
surf ==
nullptr )
1374 if ( nsurf ==
nullptr ) {
1375 PLAIN_LOG <<
"could not make neutral surface...";
1381 uint32_t*
const pixels = lock.
pixels();
1385 for (
int y=0; y != nsurf->h/2; ++y) {
1386 for(
int x=0; x != nsurf->w; ++x) {
1387 const int index1 = y*nsurf->w + x;
1388 const int index2 = (nsurf->h-y)*nsurf->w - x - 1;
1389 std::swap(pixels[index1],pixels[index2]);
1393 if (
is_odd(nsurf->h) ) {
1395 for (
int x=0; x != nsurf->w/2; ++x) {
1396 const int index1 = (nsurf->h/2)*nsurf->w + x;
1397 const int index2 = (nsurf->h/2)*nsurf->w + (nsurf->w - x - 1);
1398 std::swap(pixels[index1],pixels[index2]);
1414 if (
surf ==
nullptr ||
dst ==
nullptr ) {
1415 PLAIN_LOG <<
"could not make neutral surface...";
1423 const uint32_t*
const src_pixels = src_lock.
pixels();
1424 uint32_t*
const dst_pixels = dst_lock.
pixels();
1427 for(
int y = 0; y !=
surf->h; ++y) {
1428 for (
int x = 0; x !=
surf->w; ++x ) {
1429 const int src_index = y*
surf->w + x;
1430 const int dst_index = clockwise ?
1431 x*
dst->w + (
dst->w-1-y) :
1433 dst_pixels[dst_index] = src_pixels[src_index];
1445 uint32_t*
const pixels = lock.
pixels();
1447 for(
int y = 0; y != nsurf->h; ++y) {
1448 for(
int x = 0; x != nsurf->w/2; ++x) {
1449 const int index1 = y*nsurf->w + x;
1450 const int index2 = (y+1)*nsurf->w - x - 1;
1451 std::swap(pixels[index1],pixels[index2]);
1461 uint32_t*
const pixels = lock.
pixels();
1463 for(
int x = 0; x != nsurf->w; ++x) {
1464 for(
int y = 0; y != nsurf->h/2; ++y) {
1465 const int index1 = y*nsurf->w + x;
1466 const int index2 = (nsurf->h-y-1)*nsurf->w + x;
1467 std::swap(pixels[index1],pixels[index2]);
1475 if (
src ==
nullptr) {
1480 if(area.x >=
src->w || area.y >=
src->h || area.x + area.w < 0 || area.y + area.h < 0) {
1484 if(area.x + area.w >
src->w) {
1485 area.w =
src->w - area.x;
1487 if(area.y + area.h >
src->h) {
1488 area.h =
src->h - area.y;
1494 if(
dst ==
nullptr) {
1495 PLAIN_LOG <<
"Could not create a new surface in get_surface_portion()";
1500 SDL_BlendMode src_blend;
1501 SDL_GetSurfaceBlendMode(
src, &src_blend);
1502 SDL_SetSurfaceBlendMode(
src, SDL_BLENDMODE_NONE);
1503 SDL_BlitSurface(
src, &area,
dst,
nullptr);
1504 SDL_SetSurfaceBlendMode(
src, src_blend);
1511 constexpr
bool not_alpha(uint32_t pixel)
1513 return (pixel >> 24) != 0x00;
1522 const uint32_t*
const pixels = lock.
pixels();
1525 for(
n = 0;
n != nsurf->h; ++
n) {
1526 const uint32_t*
const start_row = pixels +
n*nsurf->w;
1527 const uint32_t*
const end_row = start_row + nsurf->w;
1529 if(std::find_if(start_row,end_row,not_alpha) != end_row)
1535 for(
n = 0;
n != nsurf->h-res.y; ++
n) {
1536 const uint32_t*
const start_row = pixels + (nsurf->h-
n-1)*nsurf->w;
1537 const uint32_t*
const end_row = start_row + nsurf->w;
1539 if(std::find_if(start_row,end_row,not_alpha) != end_row)
1546 res.h = nsurf->h - res.y -
n;
1548 for(
n = 0;
n != nsurf->w; ++
n) {
1550 for(y = 0; y != nsurf->h; ++y) {
1551 const uint32_t pixel = pixels[y*nsurf->w +
n];
1552 if(not_alpha(pixel))
1562 for(
n = 0;
n != nsurf->w-res.x; ++
n) {
1564 for(y = 0; y != nsurf->h; ++y) {
1565 const uint32_t pixel = pixels[y*nsurf->w + nsurf->w -
n - 1];
1566 if(not_alpha(pixel))
1574 res.w = nsurf->w - res.x -
n;
Helper class for pinning SDL surfaces into memory.
surface clone() const
Makes a copy of this surface.
int area() const
Total area of the surface in square pixels.
Represents version numbers.
std::unordered_map< color_t, color_t > color_range_map
void swap(config &lhs, config &rhs)
Implement non-member swap function for std::swap (calls config::swap).
Standard logging facilities (interface).
constexpr int fixed_point_to_int(int32_t n)
If positive, just bit shift.
constexpr bool is_odd(T num)
constexpr unsigned fixed_point_multiply(int32_t n1, int32_t n2)
constexpr int32_t fixed_point_divide(int n1, int n2)
version_info get_version()
Returns the runtime SDL version.
bool runtime_at_least(uint8_t major, uint8_t minor=0, uint8_t patch=0)
Returns true if the runtime SDL version is at or greater than the specified version,...
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
void scale(size_t factor, const uint32_t *src, uint32_t *trg, int srcWidth, int srcHeight, ColorFormat colFmt, const ScalerCfg &cfg=ScalerCfg(), int yFirst=0, int yLast=std::numeric_limits< int >::max())
const int SCALE_FACTOR_MAX
rect dst
Location on the final composed sheet.
rect src
Non-transparent portion of the surface to compose.
std::string filename
Filename.
The basic class for representing 8-bit RGB or RGBA colour values.
static constexpr color_t from_argb_bytes(uint32_t c)
Creates a new color_t object from a uint32_t variable.
An abstract description of a rectangle with integer coordinates.
static map_location::direction n
static map_location::direction s
void mask_surface(surface &nsurf, const surface &nmask, bool *empty_result, const std::string &filename)
Applies a mask on a surface.
rect get_non_transparent_portion(const surface &nsurf)
void alpha_to_greyscale(surface &nsurf)
surface scale_surface_legacy(const surface &surf, int w, int h)
Scale a surface using simple bilinear filtering (discarding rgb from source pixels with 0 alpha)
void recolor_image(surface &nsurf, const color_range_map &map_rgb)
Recolors a surface using a map with source and converted palette values.
void wipe_alpha(surface &nsurf)
void brighten_image(surface &nsurf, int32_t amount)
void adjust_surface_alpha(surface &surf, uint8_t alpha_mod)
void sepia_image(surface &nsurf)
void adjust_surface_alpha_add(surface &nsurf, int amount)
void blend_surface(surface &nsurf, const double amount, const color_t color)
Blends a surface with a color.
void swap_channels_image(surface &nsurf, channel r, channel g, channel b, channel a)
void adjust_surface_color(surface &nsurf, int red, int green, int blue)
surface cut_surface(const surface &surf, const SDL_Rect &r)
Cuts a rectangle from a surface.
void negative_image(surface &nsurf, const int thresholdR, const int thresholdG, const int thresholdB)
void shadow_image(surface &surf, int scale)
create an heavy shadow of the image, by blurring, increasing alpha and darkening
static lg::log_domain log_display("display")
void light_surface(surface &nsurf, const surface &lightmap)
Light surf using lightmap.
surface get_surface_portion(const surface &src, SDL_Rect &area)
Get a portion of the screen.
surface scale_surface_xbrz(const surface &surf, std::size_t z)
Scale a surface using xBRZ algorithm.
bool in_mask_surface(const surface &nsurf, const surface &nmask)
Check if a surface fit into a mask.
surface scale_surface_sharp(const surface &surf, int w, int h)
Scale a surface using modified nearest neighbour algorithm.
void blur_alpha_surface(surface &res, int depth)
Cross-fades a surface with alpha channel.
void greyscale_image(surface &nsurf)
void flop_surface(surface &nsurf)
surface rotate_90_surface(const surface &surf, bool clockwise)
Rotates a surface 90 degrees.
surface rotate_180_surface(const surface &surf)
Rotates a surface 180 degrees.
void flip_surface(surface &nsurf)
surface scale_surface(const surface &surf, int w, int h)
Scale a surface using alpha-weighted modified bilinear filtering Note: causes artifacts with alpha gr...
surface rotate_any_surface(const surface &surf, float angle, int zoom, int offset)
Rotates a surface by any degrees.
void monochrome_image(surface &nsurf, const int threshold)
void blur_surface(surface &surf, SDL_Rect rect, int depth)
Cross-fades a surface in place.