~ubuntu-branches/ubuntu/trusty/enigma/trusty-proposed

« back to all changes in this revision

Viewing changes to lib-src/enigma-core/SDL_rotozoom.c

  • Committer: Package Import Robot
  • Author(s): Erich Schubert
  • Date: 2013-04-06 14:54:02 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20130406145402-jgjrtk7hac8gtvza
Tags: 1.20-dfsg.1-1
* New upstream release (Closes: #704595)
  (Repacked: dropped zipios++ source and main menu music)
* Update watch file, sf.net again.
* Fix documentation links (Closes: #653508)
* Conflict with enigma-level-previews to encourage deinstallation
  (Pregenerated level previews were only used with version 1.01)
* Use dh7 for building instead of CDBS
* Update to policy 3.9.4.0 (no changes)
* Register documentation with doc-base

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 
3
 
  SDL_rotozoom.c - rotozoomer for 32bit or 8bit surfaces
4
 
 
5
 
  LGPL (c) A. Schiffler
6
 
 
7
 
  - Better 
8
 
*/
 
2
 
 
3
 SDL_rotozoom.c - rotozoomer for 32bit or 8bit surfaces
 
4
 
 
5
 LGPL (c) A. Schiffler
 
6
 
 
7
 - Better 
 
8
 */
9
9
 
10
10
#ifdef WIN32
11
11
#include <windows.h>
26
26
#define INLINE inline
27
27
#endif
28
28
 
29
 
INLINE int clamp (int x, int xmin, int xmax)
 
29
int clamp (int x, int xmin, int xmax)
30
30
{
31
31
    if (x < xmin)
32
32
        return xmin;
35
35
    return x;
36
36
}
37
37
 
38
 
INLINE double sinc(double x)
 
38
double sinc(double x)
39
39
{
40
40
    if (x == 0)
41
41
        return 1;
43
43
    return sin(x)/x;
44
44
}
45
45
 
46
 
INLINE float lanczos2(float x)
 
46
float lanczos2(float x)
47
47
{
48
 
/*     return sinc(x); */
49
 
  if (x < -2 || x > 2)
50
 
    return 0;
51
 
  else
52
 
    return sinc(x) * sinc(x/2);
53
 
/* sinc_table [(int)((x+4)*100. )] * sinc_table[(int)((x/2+4)*100.)]; */
 
48
    if (x < -2 || x > 2)
 
49
        return 0;
 
50
    else
 
51
        return sinc(x) * sinc(x/2);
 
52
    /* sinc_table [(int)((x+4)*100. )] * sinc_table[(int)((x/2+4)*100.)]; */
54
53
}
55
54
 
56
55
INLINE float lanczos3(float x)
57
56
{
58
 
/*     return sinc(x); */
59
 
  if (x < -3 || x > 3)
60
 
    return 0;
61
 
  else
62
 
    return sinc(x) * sinc(x/3);
 
57
    if (x < -3 || x > 3)
 
58
        return 0;
 
59
    else
 
60
        return sinc(x) * sinc(x/3);
63
61
}
64
62
 
65
 
/* inline float lanczos4(float x) */
66
 
/* { */
67
 
/* /\*     return sinc(x); *\/ */
68
 
/*   if (x < -4 || x > 4) */
69
 
/*     return 0; */
70
 
/*   else */
71
 
/*     return sinc_table [(int)((x+4)*100. )] * sinc_table[(int)((x/4+4)*100.)]; */
72
 
/* } */
73
 
 
74
 
/* static void */
75
 
/* resample (Uint8 *s, int slen, int spitch, */
76
 
/*           Uint8 *d, int dlen, int dpitch) */
77
 
/* { */
78
 
/*     float f = (float) slen / dlen; */
79
 
 
80
 
/*     int i,j; */
81
 
/*     Uint8 *sp; */
82
 
/*     float r, g, b, a; */
83
 
/*     int support = 2; */
84
 
 
85
 
/*     for (i=0; i<dlen; ++i) { */
86
 
/*         float x = i*f; */
87
 
/*         float c = 0; */
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); */
97
 
/*             if (ff != 0) { */
98
 
/*                 r += ff * sp[0]; */
99
 
/*                 g += ff * sp[1]; */
100
 
/*                 b += ff * sp[2]; */
101
 
/*                 a += ff * sp[3]; */
102
 
/*                 c += ff; */
103
 
/*             } */
104
 
/*             sp += spitch; */
105
 
/*         } */
106
 
/*         r /= c; */
107
 
/*         g /= c; */
108
 
/*         b /= c; */
109
 
/*         a /= c; */
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);  */
114
 
/*         d += dpitch; */
115
 
/*     } */
116
 
/* } */
117
 
 
118
63
typedef float (*FilterFunc)(float);
119
64
 
120
65
static void
121
66
resample_horiz (SDL_Surface *src, SDL_Surface *dst, FilterFunc filter, int support)
122
67
{
123
68
    int    x, y;
124
 
    int    i,j;
 
69
    int    j;
125
70
    Uint8 *sp, *dp;
126
71
    int    r, g, b, a;
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));
130
 
 
 
75
    
131
76
    for (x=0; x<dst->w; ++x) 
132
77
    {
133
78
        float c      = 0;
135
80
        int   start  = (int) MAX(0, center-support + 0.5);
136
81
        int   stop   = (int) MIN(src->w, center+support+0.5);
137
82
        int   n      = stop-start;
138
 
 
 
83
        
139
84
        for (j=0; j<n; ++j) {
140
85
            F[j] = filter((j+start-center+0.5)/dx);
141
86
            c += F[j];
169
114
resample_vert (SDL_Surface *src, SDL_Surface *dst, FilterFunc filter, int support)
170
115
{
171
116
    int    x, y;
172
 
    int    i,j;
 
117
    int    j;
173
118
    Uint8 *sp, *dp;
174
119
    int    r, g, b, a;
175
120
    float  factor  = (float) src->h / dst->h;
176
121
    float  dx      = MAX(factor, 1.0);
177
122
    float *F       = (float*) malloc(sizeof(float)*(2*support+1));
178
 
 
 
123
    
179
124
    for (y=0; y<dst->h; ++y)
180
125
    {
181
126
        float c      = 0;
183
128
        int   start  = (int) MAX(0, center-support + 0.5);
184
129
        int   stop   = (int) MIN(src->h, center+support+0.5);
185
130
        int   n      = stop-start;
186
 
 
 
131
        
187
132
        for (j=0; j<n; ++j) {
188
133
            F[j] = filter((j+start-center+0.5)/dx);
189
134
            c += F[j];
209
154
            dp[2] = (Uint8) clamp (b, 0, 255); 
210
155
            dp[3] = (Uint8) clamp (a, 0, 255); 
211
156
            dp += 4;
212
 
/*            dp += src->pitch; */
 
157
            /*            dp += src->pitch; */
213
158
        }
214
159
    }
215
160
    free(F);
219
164
 
220
165
static void zoomLanczos (SDL_Surface *src, SDL_Surface *dst)
221
166
{
222
 
#if 1
223
167
    resample_horiz(src, dst, lanczos2, 2);
224
168
    resample_vert(src, dst, lanczos2, 2);
225
 
#else
226
 
    resample_horiz(src, dst, lanczos3, 3);
227
 
    resample_vert(src, dst, lanczos3, 3);
228
 
#endif
229
169
}
230
170
 
231
171
/*
232
 
 
 
172
 
233
173
 32bit Zoomer with optional anti-aliasing by bilinear interpolation.
234
 
 
 
174
 
235
175
 Zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface.
236
 
 
237
 
*/
 
176
 
 
177
 */
238
178
 
239
179
int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int smooth)
240
180
{
241
181
    if (!smooth) {
242
 
        int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey;
 
182
        int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy;
243
183
        tColorRGBA *sp, *csp, *dp;
244
 
        int sgap, dgap;
 
184
        int dgap;
245
185
        sx = (int) (65536.0 * (float) src->w / (float) dst->w);
246
186
            sy = (int) (65536.0 * (float) src->h / (float) dst->h);
247
 
 
 
187
        
248
188
        /*
249
189
         * Allocate memory for row increments
250
190
         */
255
195
            free(sax);
256
196
            return (-1);
257
197
        }
258
 
 
 
198
        
259
199
        /*
260
200
         * Precalculate row increments
261
201
         */
277
217
            if ((csy >> 16) >= src->h)
278
218
                csy -= sy;
279
219
        }
280
 
 
 
220
        
281
221
        /*
282
222
         * Pointer setup
283
223
         */
284
 
        sp = csp = (tColorRGBA *) src->pixels;
 
224
        csp = (tColorRGBA *) src->pixels;
285
225
        dp = (tColorRGBA *) dst->pixels;
286
 
        sgap = src->pitch - src->w * 4;
 
226
        //        sgap = src->pitch - src->w * 4;
287
227
        dgap = dst->pitch - dst->w * 4;
288
 
    
 
228
        
289
229
        /*
290
230
         * Switch between interpolating and non-interpolating code
291
231
         */
302
242
                csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
303
243
                dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
304
244
            }
305
 
 
 
245
        
306
246
        free(sax);
307
247
        free(say);
308
248
        return (0);
314
254
    {
315
255
        int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep;
316
256
        tColorRGBA *sp, *csp, *dp;
317
 
        int sgap, dgap;
318
 
 
 
257
        int dgap;
 
258
        
319
259
        /*
320
260
         * Variable setup
321
261
         */
327
267
            smooth = 1;
328
268
            if (src->w > dst->w) // if the image gets shrinked -> use stronger blur :
329
269
                smooth = (int)((double)(src->w)/dst->w+0.5);
330
 
 
 
270
            
331
271
            sx = (int) (65536.0 * (float) (src->w) / (float) dst->w);
332
272
            sy = (int) (65536.0 * (float) (src->h) / (float) dst->h);
333
273
        } else {
334
274
            sx = (int) (65536.0 * (float) src->w / (float) dst->w);
335
275
            sy = (int) (65536.0 * (float) src->h / (float) dst->h);
336
276
        }
337
 
 
 
277
        
338
278
        /*
339
279
         * Allocate memory for row increments
340
280
         */
345
285
            free(sax);
346
286
            return (-1);
347
287
        }
348
 
 
 
288
        
349
289
        /*
350
290
         * Precalculate row increments
351
291
         */
371
311
            if ((sum >> 16) >= src->h - smooth)
372
312
                csy -= sy;
373
313
        }
374
 
 
 
314
        
375
315
        /*
376
316
         * Pointer setup
377
317
         */
378
 
        sp = csp = (tColorRGBA *) src->pixels;
 
318
        csp = (tColorRGBA *) src->pixels;
379
319
        dp = (tColorRGBA *) dst->pixels;
380
 
        sgap = src->pitch - src->w * 4;
381
320
        dgap = dst->pitch - dst->w * 4;
382
 
    
 
321
        
383
322
        /*
384
323
         * Switch between interpolating and non-interpolating code
385
324
         */
389
328
            for (y = 0; y < dst->h; y++) {
390
329
                /* Setup color source pointers */
391
330
                tColorRGBA *c00, *c01, *c10, *c11;
392
 
 
 
331
                
393
332
                c00  = csp;
394
333
                c01  = csp+1;
395
334
                c10  = (tColorRGBA *) ((Uint8 *) csp + src->pitch);
396
335
                c11  = c10+1;
397
336
                csax = sax;
398
337
                for (x = 0; x < dst->w; x++, dp++) {
399
 
 
 
338
                    
400
339
                    /* Interpolate colors */
401
340
                    ex = *csax & 0xffff;
402
341
                    ey = *csay & 0xffff;
412
351
                    t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
413
352
                    t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
414
353
                    dp->a = (((t2 - t1) * ey) >> 16) + t1;
415
 
 
 
354
                    
416
355
                    /* Advance source pointers */
417
356
                    csax++;
418
357
                    sstep = (*csax >> 16);
432
371
                tColorRGBA *c       = csp;
433
372
                int         smooth2 = smooth*smooth;
434
373
                csax                = sax;
435
 
 
 
374
                
436
375
                for (x = 0; x < dst->w; x++, dp++) {
437
376
                    int         xo, yo;
438
377
                    tColorRGBA *co    = c;
439
378
                    int         r     = 0, g = 0, b = 0, a = 0;
440
 
 
 
379
                    
441
380
                    for (yo = 0; yo<smooth; ++yo) {
442
381
                        for (xo = 0; xo<smooth; ++xo) {
443
382
                            assert(co >= csp);
450
389
                        co  = (tColorRGBA *) ((Uint8 *) co + src->pitch);
451
390
                        co -= smooth;
452
391
                    }
453
 
 
 
392
                    
454
393
                    dp->r = r/smooth2;
455
394
                    dp->g = g/smooth2;
456
395
                    dp->b = b/smooth2;
457
396
                    dp->a = a/smooth2;
458
 
 
 
397
                    
459
398
                    csax++;
460
399
                    sstep  = (*csax >> 16);
461
400
                    c   += sstep;
478
417
                csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
479
418
                dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
480
419
            }
481
 
 
 
420
            
482
421
        }
483
 
 
 
422
        
484
423
        free(sax);
485
424
        free(say);
486
425
        return (0);
489
428
}
490
429
 
491
430
/*
492
 
 
 
431
 
493
432
 8bit Zoomer without smoothing.
494
 
 
 
433
 
495
434
 Zoomes 8bit palette/Y 'src' surface to 'dst' surface.
496
 
 
497
 
*/
 
435
 
 
436
 */
498
437
 
499
438
int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
500
439
{
501
440
    Uint32 x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy;
502
441
    Uint8 *sp, *dp, *csp;
503
442
    int dgap;
504
 
 
 
443
    
505
444
    /*
506
445
     * Variable setup
507
446
     */
508
447
    sx = (Uint32) (65536.0 * (float) src->w / (float) dst->w);
509
448
    sy = (Uint32) (65536.0 * (float) src->h / (float) dst->h);
510
 
 
 
449
    
511
450
    /*
512
451
     * Allocate memory for row increments
513
452
     */
520
459
            }
521
460
            return (-1);
522
461
    }
523
 
 
 
462
    
524
463
    /*
525
464
     * Precalculate row increments
526
465
     */
540
479
            csy &= 0xffff;
541
480
            csay++;
542
481
    }
543
 
 
 
482
    
544
483
    csx = 0;
545
484
    csax = sax;
546
485
    for (x = 0; x < dst->w; x++) {
553
492
            csy += (*csay);
554
493
            csay++;
555
494
    }
556
 
 
 
495
    
557
496
    /*
558
497
     * Pointer setup
559
498
     */
560
 
    sp = csp = (Uint8 *) src->pixels;
 
499
    csp = (Uint8 *) src->pixels;
561
500
    dp = (Uint8 *) dst->pixels;
562
501
    dgap = dst->pitch - dst->w;
563
 
 
 
502
    
564
503
    /*
565
504
     * Draw
566
505
     */
570
509
            sp = csp;
571
510
            for (x = 0; x < dst->w; x++) {
572
511
                /*
573
 
                * Draw
574
 
                */
 
512
             * Draw
 
513
             */
575
514
                *dp = *sp;
576
515
                /*
577
 
                * Advance source pointers
578
 
                */
 
516
             * Advance source pointers
 
517
             */
579
518
                sp += (*csax);
580
519
                csax++;
581
520
                /*
582
 
                * Advance destination pointer
583
 
                */
 
521
             * Advance destination pointer
 
522
             */
584
523
                dp++;
585
524
            }
586
525
            /*
587
 
            * Advance source pointer (for row)
588
 
            */
 
526
         * Advance source pointer (for row)
 
527
         */
589
528
            csp += ((*csay) * src->pitch);
590
529
            csay++;
591
530
            /*
592
 
            * Advance destination pointers
593
 
            */
 
531
         * Advance destination pointers
 
532
         */
594
533
            dp += dgap;
595
534
    }
596
 
 
 
535
    
597
536
    /*
598
537
     * Remove temp arrays
599
538
     */
600
539
    free(sax);
601
540
    free(say);
602
 
 
 
541
    
603
542
    return (0);
604
543
}
605
544
 
606
545
/*
607
 
 
 
546
 
608
547
 32bit Rotozoomer with optional anti-aliasing by bilinear interpolation.
609
 
 
 
548
 
610
549
 Rotates and zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface.
611
 
 
612
 
*/
 
550
 
 
551
 */
613
552
 
614
553
void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int smooth)
615
554
{
616
555
    int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
617
556
    tColorRGBA c00, c01, c10, c11;
618
 
    tColorRGBA *pc, *sp, *spb;
 
557
    tColorRGBA *pc, *sp;
619
558
    int gap;
620
 
 
 
559
    
621
560
    /*
622
561
     * Variable setup
623
562
     */
629
568
    sh = src->h - 1;
630
569
    pc = dst->pixels;
631
570
    gap = dst->pitch - dst->w * 4;
632
 
 
 
571
    
633
572
    /*
634
573
     * Switch between interpolating and non-interpolating code
635
574
     */
636
575
    if (smooth) {
637
 
        for (y = 0; y < dst->h; y++) {
638
 
            dy = cy - y;
639
 
            sdx = (ax + (isin * dy)) + xd;
640
 
            sdy = (ay - (icos * dy)) + yd;
641
 
            for (x = 0; x < dst->w; x++) {
642
 
                dx = (sdx >> 16);
643
 
                dy = (sdy >> 16);
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);
647
 
                        sp += dx;
648
 
                        c00 = *sp;
649
 
                        sp += 1;
650
 
                        c01 = *sp;
651
 
                        sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
652
 
                        sp -= 1;
653
 
                        c10 = *sp;
654
 
                        sp += 1;
655
 
                        c11 = *sp;
656
 
                    } else if ((dx == sw) && (dy == sh)) {
657
 
                        sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
658
 
                        sp += dx;
659
 
                        c00 = *sp;
660
 
                        c01 = *sp;
661
 
                        c10 = *sp;
662
 
                        c11 = *sp;
663
 
                    } else if ((dx == -1) && (dy == -1)) {
664
 
                        sp = (tColorRGBA *) (src->pixels);
665
 
                        c00 = *sp;
666
 
                        c01 = *sp;
667
 
                        c10 = *sp;
668
 
                        c11 = *sp;
669
 
                    } else if ((dx == -1) && (dy == sh)) {
670
 
                        sp = (tColorRGBA *) (src->pixels);
671
 
                        sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
672
 
                        c00 = *sp;
673
 
                        c01 = *sp;
674
 
                        c10 = *sp;
675
 
                        c11 = *sp;
676
 
                    } else if ((dx == sw) && (dy == -1)) {
677
 
                        sp = (tColorRGBA *) (src->pixels);
678
 
                        sp += dx;
679
 
                        c00 = *sp;
680
 
                        c01 = *sp;
681
 
                        c10 = *sp;
682
 
                        c11 = *sp;
683
 
                    } else if (dx == -1) {
684
 
                        sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
685
 
                        c00 = *sp;
686
 
                        c01 = *sp;
687
 
                        c10 = *sp;
688
 
                        sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
689
 
                        c11 = *sp;
690
 
                    } else if (dy == -1) {
691
 
                        sp = (tColorRGBA *) (src->pixels);
692
 
                        sp += dx;
693
 
                        c00 = *sp;
694
 
                        c01 = *sp;
695
 
                        c10 = *sp;
696
 
                        sp += 1;
697
 
                        c11 = *sp;
698
 
                    } else if (dx == sw) {
699
 
                        sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
700
 
                        sp += dx;
701
 
                        c00 = *sp;
702
 
                        c01 = *sp;
703
 
                        sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
704
 
                        c10 = *sp;
705
 
                        c11 = *sp;
706
 
                    } else if (dy == sh) {
707
 
                        sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
708
 
                        sp += dx;
709
 
                        c00 = *sp;
710
 
                        sp += 1;
711
 
                        c01 = *sp;
712
 
                        c10 = *sp;
713
 
                        c11 = *sp;
714
 
                    }
715
 
                    /*
716
 
                     * Interpolate colors
717
 
                     */
718
 
                    ex = (sdx & 0xffff);
719
 
                    ey = (sdy & 0xffff);
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;
732
 
                }
733
 
                sdx += icos;
734
 
                sdy += isin;
735
 
                pc++;
736
 
            }
737
 
            pc = (tColorRGBA *) ((Uint8 *) pc + gap);
738
 
        }
 
576
        for (y = 0; y < dst->h; y++) {
 
577
            dy = cy - y;
 
578
            sdx = (ax + (isin * dy)) + xd;
 
579
            sdy = (ay - (icos * dy)) + yd;
 
580
            for (x = 0; x < dst->w; x++) {
 
581
                dx = (sdx >> 16);
 
582
                dy = (sdy >> 16);
 
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);
 
586
                        sp += dx;
 
587
                        c00 = *sp;
 
588
                        sp += 1;
 
589
                        c01 = *sp;
 
590
                        sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
 
591
                        sp -= 1;
 
592
                        c10 = *sp;
 
593
                        sp += 1;
 
594
                        c11 = *sp;
 
595
                    } else if ((dx == sw) && (dy == sh)) {
 
596
                        sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
 
597
                        sp += dx;
 
598
                        c00 = *sp;
 
599
                        c01 = *sp;
 
600
                        c10 = *sp;
 
601
                        c11 = *sp;
 
602
                    } else if ((dx == -1) && (dy == -1)) {
 
603
                        sp = (tColorRGBA *) (src->pixels);
 
604
                        c00 = *sp;
 
605
                        c01 = *sp;
 
606
                        c10 = *sp;
 
607
                        c11 = *sp;
 
608
                    } else if ((dx == -1) && (dy == sh)) {
 
609
                        sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
 
610
                        c00 = *sp;
 
611
                        c01 = *sp;
 
612
                        c10 = *sp;
 
613
                        c11 = *sp;
 
614
                    } else if ((dx == sw) && (dy == -1)) {
 
615
                        sp = (tColorRGBA *) (src->pixels);
 
616
                        sp += dx;
 
617
                        c00 = *sp;
 
618
                        c01 = *sp;
 
619
                        c10 = *sp;
 
620
                        c11 = *sp;
 
621
                    } else if (dx == -1) {
 
622
                        sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
 
623
                        c00 = *sp;
 
624
                        c01 = *sp;
 
625
                        c10 = *sp;
 
626
                        sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
 
627
                        c11 = *sp;
 
628
                    } else if (dy == -1) {
 
629
                        sp = (tColorRGBA *) (src->pixels);
 
630
                        sp += dx;
 
631
                        c00 = *sp;
 
632
                        c01 = *sp;
 
633
                        c10 = *sp;
 
634
                        sp += 1;
 
635
                        c11 = *sp;
 
636
                    } else if (dx == sw) {
 
637
                        sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
 
638
                        sp += dx;
 
639
                        c00 = *sp;
 
640
                        c01 = *sp;
 
641
                        sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
 
642
                        c10 = *sp;
 
643
                        c11 = *sp;
 
644
                    } else if (dy == sh) {
 
645
                        sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
 
646
                        sp += dx;
 
647
                        c00 = *sp;
 
648
                        sp += 1;
 
649
                        c01 = *sp;
 
650
                        c10 = *sp;
 
651
                        c11 = *sp;
 
652
                    }
 
653
                    /*
 
654
                     * Interpolate colors
 
655
                     */
 
656
                    ex = (sdx & 0xffff);
 
657
                    ey = (sdy & 0xffff);
 
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;
 
670
                }
 
671
                sdx += icos;
 
672
                sdy += isin;
 
673
                pc++;
 
674
            }
 
675
            pc = (tColorRGBA *) ((Uint8 *) pc + gap);
 
676
        }
739
677
    } else {
740
 
        for (y = 0; y < dst->h; y++) {
741
 
            dy = cy - 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);
749
 
                    sp += dx;
750
 
                    *pc = *sp;
751
 
                }
752
 
                sdx += icos;
753
 
                sdy += isin;
754
 
                pc++;
755
 
            }
756
 
            pc = (tColorRGBA *) ((Uint8 *) pc + gap);
757
 
        }
 
678
        for (y = 0; y < dst->h; y++) {
 
679
            dy = cy - 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);
 
687
                    sp += dx;
 
688
                    *pc = *sp;
 
689
                }
 
690
                sdx += icos;
 
691
                sdy += isin;
 
692
                pc++;
 
693
            }
 
694
            pc = (tColorRGBA *) ((Uint8 *) pc + gap);
 
695
        }
758
696
    }
759
697
}
760
698
 
761
699
/*
762
 
 
 
700
 
763
701
 8bit Rotozoomer without smoothing
764
 
 
 
702
 
765
703
 Rotates and zoomes 8bit palette/Y 'src' surface to 'dst' surface.
766
 
 
767
 
*/
 
704
 
 
705
 */
768
706
 
769
707
void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos)
770
708
{
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;
773
711
    int gap;
774
 
 
 
712
    
775
713
    /*
776
714
     * Variable setup
777
715
     */
779
717
    yd = ((src->h - dst->h) << 15);
780
718
    ax = (cx << 16) - (icos * cx);
781
719
    ay = (cy << 16) - (isin * cx);
782
 
    sw = src->w - 1;
783
 
    sh = src->h - 1;
784
720
    pc = dst->pixels;
785
721
    gap = dst->pitch - dst->w;
786
722
    /*
791
727
     * Iterate through destination surface
792
728
     */
793
729
    for (y = 0; y < dst->h; y++) {
794
 
        dy = cy - y;
795
 
        sdx = (ax + (isin * dy)) + xd;
796
 
        sdy = (ay - (icos * dy)) + yd;
797
 
        for (x = 0; x < dst->w; x++) {
798
 
            dx = (short) (sdx >> 16);
799
 
            dy = (short) (sdy >> 16);
800
 
            if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
801
 
                sp = (tColorY *) (src->pixels);
802
 
                sp += (src->pitch * dy + dx);
803
 
                *pc = *sp;
804
 
            }
805
 
            sdx += icos;
806
 
            sdy += isin;
807
 
            pc++;
808
 
        }
809
 
        pc += gap;
 
730
        dy = cy - y;
 
731
        sdx = (ax + (isin * dy)) + xd;
 
732
        sdy = (ay - (icos * dy)) + yd;
 
733
        for (x = 0; x < dst->w; x++) {
 
734
            dx = (short) (sdx >> 16);
 
735
            dy = (short) (sdy >> 16);
 
736
            if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
 
737
                sp = (tColorY *) (src->pixels);
 
738
                sp += (src->pitch * dy + dx);
 
739
                *pc = *sp;
 
740
            }
 
741
            sdx += icos;
 
742
            sdy += isin;
 
743
            pc++;
 
744
        }
 
745
        pc += gap;
810
746
    }
811
747
}
812
748
 
813
749
/*
814
 
 
 
750
 
815
751
 rotozoomSurface()
816
 
 
 
752
 
817
753
 Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
818
754
 'angle' is the rotation in degrees. 'zoom' a scaling factor. If 'smooth' is 1
819
755
 then the destination 32bit surface is anti-aliased. If the surface is not 8bit
820
756
 or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
821
 
 
822
 
*/
 
757
 
 
758
 */
823
759
 
824
760
#define VALUE_LIMIT     0.001
825
761
 
827
763
/* Local rotozoom-size function with trig result return */
828
764
 
829
765
void rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight,
830
 
                             double *canglezoom, double *sanglezoom)
 
766
                             double *canglezoom, double *sanglezoom)
831
767
{
832
768
    double x, y, cx, cy, sx, sy;
833
769
    double radangle;
834
770
    int dstwidthhalf, dstheighthalf;
835
 
 
 
771
    
836
772
    /*
837
773
     * Determine destination width and height by rotating a centered source box
838
774
     */
848
784
    sx = *sanglezoom * x;
849
785
    sy = *sanglezoom * y;
850
786
    dstwidthhalf = MAX((int)
851
 
                       ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1);
 
787
                       ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1);
852
788
    dstheighthalf = MAX((int)
853
 
                        ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1);
 
789
                        ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1);
854
790
    *dstwidth = 2 * dstwidthhalf;
855
791
    *dstheight = 2 * dstheighthalf;
856
792
}
861
797
void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight)
862
798
{
863
799
    double dummy_sanglezoom, dummy_canglezoom;
864
 
 
 
800
    
865
801
    rotozoomSurfaceSizeTrig(width, height, angle, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
866
802
}
867
803
 
875
811
    double zoominv;
876
812
    double sanglezoom, canglezoom, sanglezoominv, canglezoominv;
877
813
    int dstwidthhalf, dstwidth, dstheighthalf, dstheight;
878
 
    double x, y, cx, cy;
879
814
    int is32bit;
880
815
    int i, src_converted;
881
 
 
 
816
    
882
817
    /*
883
818
     * Sanity check
884
819
     */
885
820
    if (src == NULL)
886
 
        return (NULL);
887
 
 
 
821
        return (NULL);
 
822
    
888
823
    /*
889
824
     * Determine if source surface is 32bit or 8bit
890
825
     */
891
826
    is32bit = (src->format->BitsPerPixel == 32);
892
827
    if ((is32bit) || (src->format->BitsPerPixel == 8)) {
893
 
        /*
894
 
         * Use source surface 'as is'
895
 
         */
896
 
        rz_src = src;
897
 
        src_converted = 0;
 
828
        /*
 
829
         * Use source surface 'as is'
 
830
         */
 
831
        rz_src = src;
 
832
        src_converted = 0;
898
833
    } else {
899
 
        /*
900
 
         * New source surface is 32bit with a defined RGBA ordering
901
 
         */
902
 
        rz_src =
 
834
        /*
 
835
         * New source surface is 32bit with a defined RGBA ordering
 
836
         */
 
837
        rz_src =
903
838
            SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
904
 
        SDL_BlitSurface(src, NULL, rz_src, NULL);
905
 
        src_converted = 1;
906
 
        is32bit = 1;
 
839
        SDL_BlitSurface(src, NULL, rz_src, NULL);
 
840
        src_converted = 1;
 
841
        is32bit = 1;
907
842
    }
908
 
 
 
843
    
909
844
    /*
910
845
     * Sanity check zoom factor
911
846
     */
912
847
    if (zoom < VALUE_LIMIT) {
913
 
        zoom = VALUE_LIMIT;
 
848
        zoom = VALUE_LIMIT;
914
849
    }
915
850
    zoominv = 65536.0 / (zoom * zoom);
916
 
 
 
851
    
917
852
    /*
918
853
     * Check if we have a rotozoom or just a zoom
919
854
     */
920
855
    if (fabs(angle) > VALUE_LIMIT) {
921
 
 
922
 
        /*
923
 
         * Angle!=0: full rotozoom
924
 
         */
925
 
        /*
926
 
         * -----------------------
927
 
         */
928
 
 
929
 
        /* Determine target size */
930
 
        rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoom, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
931
 
 
932
 
        /*
933
 
         * Calculate target factors from sin/cos and zoom
934
 
         */
935
 
        sanglezoominv = sanglezoom;
936
 
        canglezoominv = canglezoom;
937
 
        sanglezoominv *= zoominv;
938
 
        canglezoominv *= zoominv;
939
 
 
940
 
        /* Calculate half size */
941
 
        dstwidthhalf = dstwidth / 2;
942
 
        dstheighthalf = dstheight / 2;
943
 
 
944
 
        /*
945
 
         * Alloc space to completely contain the rotated surface
946
 
         */
947
 
        rz_dst = NULL;
948
 
        if (is32bit) {
949
 
            /*
950
 
             * Target surface is 32bit with source RGBA/ABGR ordering
951
 
             */
952
 
            rz_dst =
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);
956
 
        } else {
957
 
            /*
958
 
             * Target surface is 8bit
959
 
             */
960
 
            rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
961
 
        }
962
 
 
963
 
        /*
964
 
         * Lock source surface
965
 
         */
966
 
        SDL_LockSurface(rz_src);
967
 
        /*
968
 
         * Check which kind of surface we have
969
 
         */
970
 
        if (is32bit) {
971
 
            /*
972
 
             * Call the 32bit transformation routine to do the rotation (using alpha)
973
 
             */
974
 
            transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
975
 
                                 (int) (sanglezoominv), (int) (canglezoominv), smooth);
976
 
            /*
977
 
             * Turn on source-alpha support
978
 
             */
979
 
            SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
980
 
        } else {
981
 
            /*
982
 
             * Copy palette and colorkey info
983
 
             */
984
 
            for (i = 0; i < rz_src->format->palette->ncolors; i++) {
985
 
                rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
986
 
            }
987
 
            rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
988
 
            /*
989
 
             * Call the 8bit transformation routine to do the rotation
990
 
             */
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);
994
 
        }
995
 
        /*
996
 
         * Unlock source surface
997
 
         */
998
 
        SDL_UnlockSurface(rz_src);
999
 
 
 
856
        
 
857
        /*
 
858
         * Angle!=0: full rotozoom
 
859
         */
 
860
        /*
 
861
         * -----------------------
 
862
         */
 
863
        
 
864
        /* Determine target size */
 
865
        rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoom, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
 
866
        
 
867
        /*
 
868
         * Calculate target factors from sin/cos and zoom
 
869
         */
 
870
        sanglezoominv = sanglezoom;
 
871
        canglezoominv = canglezoom;
 
872
        sanglezoominv *= zoominv;
 
873
        canglezoominv *= zoominv;
 
874
        
 
875
        /* Calculate half size */
 
876
        dstwidthhalf = dstwidth / 2;
 
877
        dstheighthalf = dstheight / 2;
 
878
        
 
879
        /*
 
880
         * Alloc space to completely contain the rotated surface
 
881
         */
 
882
        rz_dst = NULL;
 
883
        if (is32bit) {
 
884
            /*
 
885
             * Target surface is 32bit with source RGBA/ABGR ordering
 
886
             */
 
887
            rz_dst =
 
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);
 
891
        } else {
 
892
            /*
 
893
             * Target surface is 8bit
 
894
             */
 
895
            rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
 
896
        }
 
897
        
 
898
        /*
 
899
         * Lock source surface
 
900
         */
 
901
        SDL_LockSurface(rz_src);
 
902
        /*
 
903
         * Check which kind of surface we have
 
904
         */
 
905
        if (is32bit) {
 
906
            /*
 
907
             * Call the 32bit transformation routine to do the rotation (using alpha)
 
908
             */
 
909
            transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
 
910
                                 (int) (sanglezoominv), (int) (canglezoominv), smooth);
 
911
            /*
 
912
             * Turn on source-alpha support
 
913
             */
 
914
            SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
 
915
        } else {
 
916
            /*
 
917
             * Copy palette and colorkey info
 
918
             */
 
919
            for (i = 0; i < rz_src->format->palette->ncolors; i++) {
 
920
                rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
 
921
            }
 
922
            rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
 
923
            /*
 
924
             * Call the 8bit transformation routine to do the rotation
 
925
             */
 
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);
 
929
        }
 
930
        /*
 
931
         * Unlock source surface
 
932
         */
 
933
        SDL_UnlockSurface(rz_src);
 
934
        
1000
935
    } else {
1001
 
 
1002
 
        /*
1003
 
         * Angle=0: Just a zoom
1004
 
         */
1005
 
        /*
1006
 
         * --------------------
1007
 
         */
1008
 
 
1009
 
        /*
1010
 
         * Calculate target size
1011
 
         */
1012
 
        zoomSurfaceSize(rz_src->w, rz_src->h, zoom, zoom, &dstwidth, &dstheight);
1013
 
 
1014
 
        /*
1015
 
         * Alloc space to completely contain the zoomed surface
1016
 
         */
1017
 
        rz_dst = NULL;
1018
 
        if (is32bit) {
1019
 
            /*
1020
 
             * Target surface is 32bit with source RGBA/ABGR ordering
1021
 
             */
1022
 
            rz_dst =
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);
1026
 
        } else {
1027
 
            /*
1028
 
             * Target surface is 8bit
1029
 
             */
1030
 
            rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
1031
 
        }
1032
 
 
1033
 
        /*
1034
 
         * Lock source surface
1035
 
         */
1036
 
        SDL_LockSurface(rz_src);
1037
 
        /*
1038
 
         * Check which kind of surface we have
1039
 
         */
1040
 
        if (is32bit) {
1041
 
            /*
1042
 
             * Call the 32bit transformation routine to do the zooming (using alpha)
1043
 
             */
1044
 
            zoomSurfaceRGBA(rz_src, rz_dst, smooth);
1045
 
            /*
1046
 
             * Turn on source-alpha support
1047
 
             */
1048
 
            SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
1049
 
        } else {
1050
 
            /*
1051
 
             * Copy palette and colorkey info
1052
 
             */
1053
 
            for (i = 0; i < rz_src->format->palette->ncolors; i++) {
1054
 
                rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
1055
 
            }
1056
 
            rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
1057
 
            /*
1058
 
             * Call the 8bit transformation routine to do the zooming
1059
 
             */
1060
 
            zoomSurfaceY(rz_src, rz_dst);
1061
 
            SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
1062
 
        }
1063
 
        /*
1064
 
         * Unlock source surface
1065
 
         */
1066
 
        SDL_UnlockSurface(rz_src);
 
936
        
 
937
        /*
 
938
         * Angle=0: Just a zoom
 
939
         */
 
940
        /*
 
941
         * --------------------
 
942
         */
 
943
        
 
944
        /*
 
945
         * Calculate target size
 
946
         */
 
947
        zoomSurfaceSize(rz_src->w, rz_src->h, zoom, zoom, &dstwidth, &dstheight);
 
948
        
 
949
        /*
 
950
         * Alloc space to completely contain the zoomed surface
 
951
         */
 
952
        rz_dst = NULL;
 
953
        if (is32bit) {
 
954
            /*
 
955
             * Target surface is 32bit with source RGBA/ABGR ordering
 
956
             */
 
957
            rz_dst =
 
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);
 
961
        } else {
 
962
            /*
 
963
             * Target surface is 8bit
 
964
             */
 
965
            rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
 
966
        }
 
967
        
 
968
        /*
 
969
         * Lock source surface
 
970
         */
 
971
        SDL_LockSurface(rz_src);
 
972
        /*
 
973
         * Check which kind of surface we have
 
974
         */
 
975
        if (is32bit) {
 
976
            /*
 
977
             * Call the 32bit transformation routine to do the zooming (using alpha)
 
978
             */
 
979
            zoomSurfaceRGBA(rz_src, rz_dst, smooth);
 
980
            /*
 
981
             * Turn on source-alpha support
 
982
             */
 
983
            SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
 
984
        } else {
 
985
            /*
 
986
             * Copy palette and colorkey info
 
987
             */
 
988
            for (i = 0; i < rz_src->format->palette->ncolors; i++) {
 
989
                rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
 
990
            }
 
991
            rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
 
992
            /*
 
993
             * Call the 8bit transformation routine to do the zooming
 
994
             */
 
995
            zoomSurfaceY(rz_src, rz_dst);
 
996
            SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
 
997
        }
 
998
        /*
 
999
         * Unlock source surface
 
1000
         */
 
1001
        SDL_UnlockSurface(rz_src);
1067
1002
    }
1068
 
 
 
1003
    
1069
1004
    /*
1070
1005
     * Cleanup temp surface
1071
1006
     */
1072
1007
    if (src_converted) {
1073
 
        SDL_FreeSurface(rz_src);
 
1008
        SDL_FreeSurface(rz_src);
1074
1009
    }
1075
 
 
 
1010
    
1076
1011
    /*
1077
1012
     * Return destination surface
1078
1013
     */
1080
1015
}
1081
1016
 
1082
1017
/*
1083
 
 
 
1018
 
1084
1019
 zoomSurface()
1085
 
 
 
1020
 
1086
1021
 Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
1087
1022
 'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1
1088
1023
 then the destination 32bit surface is anti-aliased. If the surface is not 8bit
1089
1024
 or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
1090
 
 
1091
 
*/
 
1025
 
 
1026
 */
1092
1027
 
1093
1028
#define VALUE_LIMIT     0.001
1094
1029
 
1098
1033
     * Sanity check zoom factors
1099
1034
     */
1100
1035
    if (zoomx < VALUE_LIMIT) {
1101
 
        zoomx = VALUE_LIMIT;
 
1036
        zoomx = VALUE_LIMIT;
1102
1037
    }
1103
1038
    if (zoomy < VALUE_LIMIT) {
1104
 
        zoomy = VALUE_LIMIT;
 
1039
        zoomy = VALUE_LIMIT;
1105
1040
    }
1106
 
 
 
1041
    
1107
1042
    /*
1108
1043
     * Calculate target size
1109
1044
     */
1110
1045
    *dstwidth = (int) ((double) width * zoomx);
1111
1046
    *dstheight = (int) ((double) height * zoomy);
1112
1047
    if (*dstwidth < 1) {
1113
 
        *dstwidth = 1;
 
1048
        *dstwidth = 1;
1114
1049
    }
1115
1050
    if (*dstheight < 1) {
1116
 
        *dstheight = 1;
 
1051
        *dstheight = 1;
1117
1052
    }
1118
1053
}
1119
1054
 
1124
1059
    int dstwidth, dstheight;
1125
1060
    int is32bit;
1126
1061
    int i, src_converted;
1127
 
 
 
1062
    
1128
1063
    /*
1129
1064
     * Sanity check
1130
1065
     */
1131
1066
    if (src == NULL)
1132
 
        return (NULL);
1133
 
 
 
1067
        return (NULL);
 
1068
    
1134
1069
    /*
1135
1070
     * Determine if source surface is 32bit or 8bit
1136
1071
     */
1137
1072
    is32bit = (src->format->BitsPerPixel == 32);
1138
1073
    if ((is32bit) || (src->format->BitsPerPixel == 8)) {
1139
 
        /*
1140
 
         * Use source surface 'as is'
1141
 
         */
1142
 
        rz_src = src;
1143
 
        src_converted = 0;
 
1074
        /*
 
1075
         * Use source surface 'as is'
 
1076
         */
 
1077
        rz_src = src;
 
1078
        src_converted = 0;
1144
1079
    } else {
1145
 
        /*
1146
 
         * New source surface is 32bit with a defined RGBA ordering
1147
 
         */
1148
 
        rz_src =
 
1080
        /*
 
1081
         * New source surface is 32bit with a defined RGBA ordering
 
1082
         */
 
1083
        rz_src =
1149
1084
            SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
1150
 
        SDL_BlitSurface(src, NULL, rz_src, NULL);
1151
 
        src_converted = 1;
1152
 
        is32bit = 1;
 
1085
        SDL_BlitSurface(src, NULL, rz_src, NULL);
 
1086
        src_converted = 1;
 
1087
        is32bit = 1;
1153
1088
    }
1154
 
 
 
1089
    
1155
1090
    /* Get size if target */
1156
1091
    zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
1157
 
 
 
1092
    
1158
1093
    /*
1159
1094
     * Alloc space to completely contain the zoomed surface
1160
1095
     */
1161
1096
    rz_dst = NULL;
1162
1097
    if (is32bit) {
1163
 
        /*
1164
 
         * Target surface is 32bit with source RGBA/ABGR ordering
1165
 
         */
1166
 
        rz_dst =
 
1098
        /*
 
1099
         * Target surface is 32bit with source RGBA/ABGR ordering
 
1100
         */
 
1101
        rz_dst =
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);
1170
1105
    } else {
1171
 
        /*
1172
 
         * Target surface is 8bit
1173
 
         */
1174
 
        rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
 
1106
        /*
 
1107
         * Target surface is 8bit
 
1108
         */
 
1109
        rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
1175
1110
    }
1176
 
 
 
1111
    
1177
1112
    /*
1178
1113
     * Lock source surface
1179
1114
     */
1182
1117
     * Check which kind of surface we have
1183
1118
     */
1184
1119
    if (is32bit) {
1185
 
        /*
1186
 
         * Call the 32bit transformation routine to do the zooming (using alpha)
1187
 
         */
1188
 
        zoomSurfaceRGBA(rz_src, rz_dst, smooth);
1189
 
        /*
1190
 
         * Turn on source-alpha support
1191
 
         */
1192
 
        SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
 
1120
        /*
 
1121
         * Call the 32bit transformation routine to do the zooming (using alpha)
 
1122
         */
 
1123
        zoomSurfaceRGBA(rz_src, rz_dst, smooth);
 
1124
        /*
 
1125
         * Turn on source-alpha support
 
1126
         */
 
1127
        SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
1193
1128
    } else {
1194
 
        /*
1195
 
         * Copy palette and colorkey info
1196
 
         */
1197
 
        for (i = 0; i < rz_src->format->palette->ncolors; i++) {
1198
 
            rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
1199
 
        }
1200
 
        rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
1201
 
        /*
1202
 
         * Call the 8bit transformation routine to do the zooming
1203
 
         */
1204
 
        zoomSurfaceY(rz_src, rz_dst);
1205
 
        SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
 
1129
        /*
 
1130
         * Copy palette and colorkey info
 
1131
         */
 
1132
        for (i = 0; i < rz_src->format->palette->ncolors; i++) {
 
1133
            rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
 
1134
        }
 
1135
        rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
 
1136
        /*
 
1137
         * Call the 8bit transformation routine to do the zooming
 
1138
         */
 
1139
        zoomSurfaceY(rz_src, rz_dst);
 
1140
        SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
1206
1141
    }
1207
1142
    /*
1208
1143
     * Unlock source surface
1209
1144
     */
1210
1145
    SDL_UnlockSurface(rz_src);
1211
 
 
 
1146
    
1212
1147
    /*
1213
1148
     * Cleanup temp surface
1214
1149
     */
1215
1150
    if (src_converted) {
1216
 
        SDL_FreeSurface(rz_src);
 
1151
        SDL_FreeSurface(rz_src);
1217
1152
    }
1218
 
 
 
1153
    
1219
1154
    /*
1220
1155
     * Return destination surface
1221
1156
     */