46
INLINE float lanczos2(float x)
46
float lanczos2(float x)
52
return sinc(x) * sinc(x/2);
53
/* sinc_table [(int)((x+4)*100. )] * sinc_table[(int)((x/2+4)*100.)]; */
51
return sinc(x) * sinc(x/2);
52
/* sinc_table [(int)((x+4)*100. )] * sinc_table[(int)((x/2+4)*100.)]; */
56
55
INLINE float lanczos3(float x)
62
return sinc(x) * sinc(x/3);
60
return sinc(x) * sinc(x/3);
65
/* inline float lanczos4(float x) */
67
/* /\* return sinc(x); *\/ */
68
/* if (x < -4 || x > 4) */
71
/* return sinc_table [(int)((x+4)*100. )] * sinc_table[(int)((x/4+4)*100.)]; */
75
/* resample (Uint8 *s, int slen, int spitch, */
76
/* Uint8 *d, int dlen, int dpitch) */
78
/* float f = (float) slen / dlen; */
82
/* float r, g, b, a; */
83
/* int support = 2; */
85
/* for (i=0; i<dlen; ++i) { */
88
/* float dx = MAX(f, 1.0); */
89
/* float center = (i+0.5)*f; /\* kernel center in the source image *\/ */
90
/* int start = (int) MAX(0, center-support + 0.5); */
91
/* int stop = (int) MIN(slen, center+support+0.5); */
92
/* int n = stop-start; */
93
/* r = g = b = a = 0; */
94
/* sp = s + start*spitch; */
95
/* for (j=0; j<n; ++j) { */
96
/* float ff = lanczos2((j+start-center+0.5)/dx); */
98
/* r += ff * sp[0]; */
99
/* g += ff * sp[1]; */
100
/* b += ff * sp[2]; */
101
/* a += ff * sp[3]; */
110
/* d[0] = (Uint8) clamp (r, 0, 255); */
111
/* d[1] = (Uint8) clamp (g, 0, 255); */
112
/* d[2] = (Uint8) clamp (b, 0, 255); */
113
/* d[3] = (Uint8) clamp (a, 0, 255); */
118
63
typedef float (*FilterFunc)(float);
121
66
resample_horiz (SDL_Surface *src, SDL_Surface *dst, FilterFunc filter, int support)
127
72
float factor = (float) src->w / dst->w;
128
73
float dx = MAX(factor, 1.0);
129
74
float *F = (float*) malloc(sizeof(float)*(2*support+1));
131
76
for (x=0; x<dst->w; ++x)
630
569
pc = dst->pixels;
631
570
gap = dst->pitch - dst->w * 4;
634
573
* Switch between interpolating and non-interpolating code
637
for (y = 0; y < dst->h; y++) {
639
sdx = (ax + (isin * dy)) + xd;
640
sdy = (ay - (icos * dy)) + yd;
641
for (x = 0; x < dst->w; x++) {
644
if ((dx >= -1) && (dy >= -1) && (dx < src->w) && (dy < src->h)) {
645
if ((dx >= 0) && (dy >= 0) && (dx < sw) && (dy < sh)) {
646
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
651
sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
656
} else if ((dx == sw) && (dy == sh)) {
657
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
663
} else if ((dx == -1) && (dy == -1)) {
664
sp = (tColorRGBA *) (src->pixels);
669
} else if ((dx == -1) && (dy == sh)) {
670
sp = (tColorRGBA *) (src->pixels);
671
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
676
} else if ((dx == sw) && (dy == -1)) {
677
sp = (tColorRGBA *) (src->pixels);
683
} else if (dx == -1) {
684
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
688
sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
690
} else if (dy == -1) {
691
sp = (tColorRGBA *) (src->pixels);
698
} else if (dx == sw) {
699
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
703
sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
706
} else if (dy == sh) {
707
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
720
t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
721
t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
722
pc->r = (((t2 - t1) * ey) >> 16) + t1;
723
t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
724
t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
725
pc->g = (((t2 - t1) * ey) >> 16) + t1;
726
t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
727
t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
728
pc->b = (((t2 - t1) * ey) >> 16) + t1;
729
t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
730
t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
731
pc->a = (((t2 - t1) * ey) >> 16) + t1;
737
pc = (tColorRGBA *) ((Uint8 *) pc + gap);
576
for (y = 0; y < dst->h; y++) {
578
sdx = (ax + (isin * dy)) + xd;
579
sdy = (ay - (icos * dy)) + yd;
580
for (x = 0; x < dst->w; x++) {
583
if ((dx >= -1) && (dy >= -1) && (dx < src->w) && (dy < src->h)) {
584
if ((dx >= 0) && (dy >= 0) && (dx < sw) && (dy < sh)) {
585
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
590
sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
595
} else if ((dx == sw) && (dy == sh)) {
596
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
602
} else if ((dx == -1) && (dy == -1)) {
603
sp = (tColorRGBA *) (src->pixels);
608
} else if ((dx == -1) && (dy == sh)) {
609
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
614
} else if ((dx == sw) && (dy == -1)) {
615
sp = (tColorRGBA *) (src->pixels);
621
} else if (dx == -1) {
622
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
626
sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
628
} else if (dy == -1) {
629
sp = (tColorRGBA *) (src->pixels);
636
} else if (dx == sw) {
637
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
641
sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
644
} else if (dy == sh) {
645
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
658
t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
659
t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
660
pc->r = (((t2 - t1) * ey) >> 16) + t1;
661
t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
662
t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
663
pc->g = (((t2 - t1) * ey) >> 16) + t1;
664
t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
665
t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
666
pc->b = (((t2 - t1) * ey) >> 16) + t1;
667
t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
668
t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
669
pc->a = (((t2 - t1) * ey) >> 16) + t1;
675
pc = (tColorRGBA *) ((Uint8 *) pc + gap);
740
for (y = 0; y < dst->h; y++) {
742
sdx = (ax + (isin * dy)) + xd;
743
sdy = (ay - (icos * dy)) + yd;
744
for (x = 0; x < dst->w; x++) {
745
dx = (short) (sdx >> 16);
746
dy = (short) (sdy >> 16);
747
if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
748
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
756
pc = (tColorRGBA *) ((Uint8 *) pc + gap);
678
for (y = 0; y < dst->h; y++) {
680
sdx = (ax + (isin * dy)) + xd;
681
sdy = (ay - (icos * dy)) + yd;
682
for (x = 0; x < dst->w; x++) {
683
dx = (short) (sdx >> 16);
684
dy = (short) (sdy >> 16);
685
if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
686
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
694
pc = (tColorRGBA *) ((Uint8 *) pc + gap);
763
701
8bit Rotozoomer without smoothing
765
703
Rotates and zoomes 8bit palette/Y 'src' surface to 'dst' surface.
769
707
void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos)
771
int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh;
709
int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay;
772
710
tColorY *pc, *sp;
876
812
double sanglezoom, canglezoom, sanglezoominv, canglezoominv;
877
813
int dstwidthhalf, dstwidth, dstheighthalf, dstheight;
880
815
int i, src_converted;
889
824
* Determine if source surface is 32bit or 8bit
891
826
is32bit = (src->format->BitsPerPixel == 32);
892
827
if ((is32bit) || (src->format->BitsPerPixel == 8)) {
894
* Use source surface 'as is'
829
* Use source surface 'as is'
900
* New source surface is 32bit with a defined RGBA ordering
835
* New source surface is 32bit with a defined RGBA ordering
903
838
SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
904
SDL_BlitSurface(src, NULL, rz_src, NULL);
839
SDL_BlitSurface(src, NULL, rz_src, NULL);
910
845
* Sanity check zoom factor
912
847
if (zoom < VALUE_LIMIT) {
915
850
zoominv = 65536.0 / (zoom * zoom);
918
853
* Check if we have a rotozoom or just a zoom
920
855
if (fabs(angle) > VALUE_LIMIT) {
923
* Angle!=0: full rotozoom
926
* -----------------------
929
/* Determine target size */
930
rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoom, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
933
* Calculate target factors from sin/cos and zoom
935
sanglezoominv = sanglezoom;
936
canglezoominv = canglezoom;
937
sanglezoominv *= zoominv;
938
canglezoominv *= zoominv;
940
/* Calculate half size */
941
dstwidthhalf = dstwidth / 2;
942
dstheighthalf = dstheight / 2;
945
* Alloc space to completely contain the rotated surface
950
* Target surface is 32bit with source RGBA/ABGR ordering
953
SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32,
954
rz_src->format->Rmask, rz_src->format->Gmask,
955
rz_src->format->Bmask, rz_src->format->Amask);
958
* Target surface is 8bit
960
rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
964
* Lock source surface
966
SDL_LockSurface(rz_src);
968
* Check which kind of surface we have
972
* Call the 32bit transformation routine to do the rotation (using alpha)
974
transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
975
(int) (sanglezoominv), (int) (canglezoominv), smooth);
977
* Turn on source-alpha support
979
SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
982
* Copy palette and colorkey info
984
for (i = 0; i < rz_src->format->palette->ncolors; i++) {
985
rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
987
rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
989
* Call the 8bit transformation routine to do the rotation
991
transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
992
(int) (sanglezoominv), (int) (canglezoominv));
993
SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
996
* Unlock source surface
998
SDL_UnlockSurface(rz_src);
858
* Angle!=0: full rotozoom
861
* -----------------------
864
/* Determine target size */
865
rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoom, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
868
* Calculate target factors from sin/cos and zoom
870
sanglezoominv = sanglezoom;
871
canglezoominv = canglezoom;
872
sanglezoominv *= zoominv;
873
canglezoominv *= zoominv;
875
/* Calculate half size */
876
dstwidthhalf = dstwidth / 2;
877
dstheighthalf = dstheight / 2;
880
* Alloc space to completely contain the rotated surface
885
* Target surface is 32bit with source RGBA/ABGR ordering
888
SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32,
889
rz_src->format->Rmask, rz_src->format->Gmask,
890
rz_src->format->Bmask, rz_src->format->Amask);
893
* Target surface is 8bit
895
rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
899
* Lock source surface
901
SDL_LockSurface(rz_src);
903
* Check which kind of surface we have
907
* Call the 32bit transformation routine to do the rotation (using alpha)
909
transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
910
(int) (sanglezoominv), (int) (canglezoominv), smooth);
912
* Turn on source-alpha support
914
SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
917
* Copy palette and colorkey info
919
for (i = 0; i < rz_src->format->palette->ncolors; i++) {
920
rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
922
rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
924
* Call the 8bit transformation routine to do the rotation
926
transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
927
(int) (sanglezoominv), (int) (canglezoominv));
928
SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
931
* Unlock source surface
933
SDL_UnlockSurface(rz_src);
1003
* Angle=0: Just a zoom
1006
* --------------------
1010
* Calculate target size
1012
zoomSurfaceSize(rz_src->w, rz_src->h, zoom, zoom, &dstwidth, &dstheight);
1015
* Alloc space to completely contain the zoomed surface
1020
* Target surface is 32bit with source RGBA/ABGR ordering
1023
SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32,
1024
rz_src->format->Rmask, rz_src->format->Gmask,
1025
rz_src->format->Bmask, rz_src->format->Amask);
1028
* Target surface is 8bit
1030
rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
1034
* Lock source surface
1036
SDL_LockSurface(rz_src);
1038
* Check which kind of surface we have
1042
* Call the 32bit transformation routine to do the zooming (using alpha)
1044
zoomSurfaceRGBA(rz_src, rz_dst, smooth);
1046
* Turn on source-alpha support
1048
SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
1051
* Copy palette and colorkey info
1053
for (i = 0; i < rz_src->format->palette->ncolors; i++) {
1054
rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
1056
rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
1058
* Call the 8bit transformation routine to do the zooming
1060
zoomSurfaceY(rz_src, rz_dst);
1061
SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
1064
* Unlock source surface
1066
SDL_UnlockSurface(rz_src);
938
* Angle=0: Just a zoom
941
* --------------------
945
* Calculate target size
947
zoomSurfaceSize(rz_src->w, rz_src->h, zoom, zoom, &dstwidth, &dstheight);
950
* Alloc space to completely contain the zoomed surface
955
* Target surface is 32bit with source RGBA/ABGR ordering
958
SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32,
959
rz_src->format->Rmask, rz_src->format->Gmask,
960
rz_src->format->Bmask, rz_src->format->Amask);
963
* Target surface is 8bit
965
rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
969
* Lock source surface
971
SDL_LockSurface(rz_src);
973
* Check which kind of surface we have
977
* Call the 32bit transformation routine to do the zooming (using alpha)
979
zoomSurfaceRGBA(rz_src, rz_dst, smooth);
981
* Turn on source-alpha support
983
SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
986
* Copy palette and colorkey info
988
for (i = 0; i < rz_src->format->palette->ncolors; i++) {
989
rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
991
rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
993
* Call the 8bit transformation routine to do the zooming
995
zoomSurfaceY(rz_src, rz_dst);
996
SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
999
* Unlock source surface
1001
SDL_UnlockSurface(rz_src);
1070
1005
* Cleanup temp surface
1072
1007
if (src_converted) {
1073
SDL_FreeSurface(rz_src);
1008
SDL_FreeSurface(rz_src);
1077
1012
* Return destination surface
1124
1059
int dstwidth, dstheight;
1126
1061
int i, src_converted;
1131
1066
if (src == NULL)
1135
1070
* Determine if source surface is 32bit or 8bit
1137
1072
is32bit = (src->format->BitsPerPixel == 32);
1138
1073
if ((is32bit) || (src->format->BitsPerPixel == 8)) {
1140
* Use source surface 'as is'
1075
* Use source surface 'as is'
1146
* New source surface is 32bit with a defined RGBA ordering
1081
* New source surface is 32bit with a defined RGBA ordering
1149
1084
SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
1150
SDL_BlitSurface(src, NULL, rz_src, NULL);
1085
SDL_BlitSurface(src, NULL, rz_src, NULL);
1155
1090
/* Get size if target */
1156
1091
zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
1159
1094
* Alloc space to completely contain the zoomed surface
1164
* Target surface is 32bit with source RGBA/ABGR ordering
1099
* Target surface is 32bit with source RGBA/ABGR ordering
1167
1102
SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32,
1168
rz_src->format->Rmask, rz_src->format->Gmask,
1169
rz_src->format->Bmask, rz_src->format->Amask);
1103
rz_src->format->Rmask, rz_src->format->Gmask,
1104
rz_src->format->Bmask, rz_src->format->Amask);
1172
* Target surface is 8bit
1174
rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
1107
* Target surface is 8bit
1109
rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
1178
1113
* Lock source surface