Annotation of qemu/sdl_zoom_template.h, revision 1.1.1.1

1.1       root        1: /*
                      2:  * SDL_zoom_template - surface scaling
                      3:  * 
                      4:  * Copyright (c) 2009 Citrix Systems, Inc.
                      5:  *
                      6:  * Derived from: SDL_rotozoom,  LGPL (c) A. Schiffler from the SDL_gfx library.
                      7:  * Modifications by Stefano Stabellini.
                      8:  *
                      9:  * This work is licensed under the terms of the GNU GPL version 2.
                     10:  * See the COPYING file in the top-level directory.
                     11:  *
                     12:  */
                     13: 
                     14: #if BPP == 16
                     15: #define SDL_TYPE Uint16
                     16: #elif BPP == 32
                     17: #define SDL_TYPE Uint32
                     18: #else
                     19: #error unsupport depth
                     20: #endif
                     21: 
                     22: /*  
                     23:  *  Simple helper functions to make the code looks nicer
                     24:  *
                     25:  *  Assume spf = source SDL_PixelFormat
                     26:  *         dpf = dest SDL_PixelFormat
                     27:  *
                     28:  */
                     29: #define getRed(color)   (((color) & spf->Rmask) >> spf->Rshift)
                     30: #define getGreen(color) (((color) & spf->Gmask) >> spf->Gshift)
                     31: #define getBlue(color)  (((color) & spf->Bmask) >> spf->Bshift)
                     32: #define getAlpha(color) (((color) & spf->Amask) >> spf->Ashift)
                     33: 
                     34: #define setRed(r, pcolor) do { \
                     35:     *pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
                     36:               (((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
                     37: } while (0);
                     38: 
                     39: #define setGreen(g, pcolor) do { \
                     40:     *pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
                     41:               (((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
                     42: } while (0);
                     43: 
                     44: #define setBlue(b, pcolor) do { \
                     45:     *pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
                     46:               (((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
                     47: } while (0);
                     48: 
                     49: #define setAlpha(a, pcolor) do { \
                     50:     *pcolor = ((*pcolor) & (~(dpf->Amask))) + \
                     51:               (((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
                     52: } while (0);
                     53: 
                     54: static int glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth,
                     55:                                    SDL_Rect *dst_rect)
                     56: {
                     57:     int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, sstep_jump;
                     58:     SDL_TYPE *c00, *c01, *c10, *c11, *sp, *csp, *dp;
                     59:     int d_gap;
                     60:     SDL_PixelFormat *spf = src->format;
                     61:     SDL_PixelFormat *dpf = dst->format;
                     62: 
                     63:     if (smooth) { 
                     64:         /* For interpolation: assume source dimension is one pixel.
                     65:          * Smaller here to avoid overflow on right and bottom edge.
                     66:          */
                     67:         sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w);
                     68:         sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h);
                     69:     } else {
                     70:         sx = (int) (65536.0 * (float) src->w / (float) dst->w);
                     71:         sy = (int) (65536.0 * (float) src->h / (float) dst->h);
                     72:     }
                     73: 
                     74:     if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
                     75:         return (-1);
                     76:     }
                     77:     if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
                     78:         free(sax);
                     79:         return (-1);
                     80:     }
                     81: 
                     82:     sp = csp = (SDL_TYPE *) src->pixels;
                     83:     dp = (SDL_TYPE *) (dst->pixels + dst_rect->y * dst->pitch +
                     84:                        dst_rect->x * dst->format->BytesPerPixel);
                     85: 
                     86:     csx = 0;
                     87:     csax = sax;
                     88:     for (x = 0; x <= dst->w; x++) {
                     89:         *csax = csx;
                     90:         csax++;
                     91:         csx &= 0xffff;
                     92:         csx += sx;
                     93:     }
                     94:     csy = 0;
                     95:     csay = say;
                     96:     for (y = 0; y <= dst->h; y++) {
                     97:         *csay = csy;
                     98:         csay++;
                     99:         csy &= 0xffff;
                    100:         csy += sy;
                    101:     }
                    102: 
                    103:     d_gap = dst->pitch - dst_rect->w * dst->format->BytesPerPixel;
                    104: 
                    105:     if (smooth) {
                    106:         csay = say;
                    107:         for (y = 0; y < dst_rect->y; y++) {
                    108:             csay++;
                    109:             sstep = (*csay >> 16) * src->pitch;
                    110:             csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
                    111:         }
                    112: 
                    113:         /* Calculate sstep_jump */
                    114:         csax = sax; 
                    115:         sstep_jump = 0;
                    116:         for (x = 0; x < dst_rect->x; x++) {
                    117:             csax++; 
                    118:             sstep = (*csax >> 16);
                    119:             sstep_jump += sstep;
                    120:         }
                    121: 
                    122:         for (y = 0; y < dst_rect->h ; y++) {
                    123:             /* Setup colour source pointers */
                    124:             c00 = csp + sstep_jump;
                    125:             c01 = c00 + 1;
                    126:             c10 = (SDL_TYPE *) ((Uint8 *) csp + src->pitch) + sstep_jump;
                    127:             c11 = c10 + 1;
                    128:             csax = sax + dst_rect->x; 
                    129: 
                    130:             for (x = 0; x < dst_rect->w; x++) {
                    131: 
                    132:                 /* Interpolate colours */
                    133:                 ex = (*csax & 0xffff);
                    134:                 ey = (*csay & 0xffff);
                    135:                 t1 = ((((getRed(*c01) - getRed(*c00)) * ex) >> 16) +
                    136:                      getRed(*c00)) & (dpf->Rmask >> dpf->Rshift);
                    137:                 t2 = ((((getRed(*c11) - getRed(*c10)) * ex) >> 16) +
                    138:                      getRed(*c10)) & (dpf->Rmask >> dpf->Rshift);
                    139:                 setRed((((t2 - t1) * ey) >> 16) + t1, dp);
                    140:                 t1 = ((((getGreen(*c01) - getGreen(*c00)) * ex) >> 16) +
                    141:                      getGreen(*c00)) & (dpf->Gmask >> dpf->Gshift);
                    142:                 t2 = ((((getGreen(*c11) - getGreen(*c10)) * ex) >> 16) +
                    143:                      getGreen(*c10)) & (dpf->Gmask >> dpf->Gshift);
                    144:                 setGreen((((t2 - t1) * ey) >> 16) + t1, dp);
                    145:                 t1 = ((((getBlue(*c01) - getBlue(*c00)) * ex) >> 16) +
                    146:                      getBlue(*c00)) & (dpf->Bmask >> dpf->Bshift);
                    147:                 t2 = ((((getBlue(*c11) - getBlue(*c10)) * ex) >> 16) +
                    148:                      getBlue(*c10)) & (dpf->Bmask >> dpf->Bshift);
                    149:                 setBlue((((t2 - t1) * ey) >> 16) + t1, dp);
                    150:                 t1 = ((((getAlpha(*c01) - getAlpha(*c00)) * ex) >> 16) +
                    151:                      getAlpha(*c00)) & (dpf->Amask >> dpf->Ashift);
                    152:                 t2 = ((((getAlpha(*c11) - getAlpha(*c10)) * ex) >> 16) +
                    153:                      getAlpha(*c10)) & (dpf->Amask >> dpf->Ashift);
                    154:                 setAlpha((((t2 - t1) * ey) >> 16) + t1, dp); 
                    155: 
                    156:                 /* Advance source pointers */
                    157:                 csax++; 
                    158:                 sstep = (*csax >> 16);
                    159:                 c00 += sstep;
                    160:                 c01 += sstep;
                    161:                 c10 += sstep;
                    162:                 c11 += sstep;
                    163:                 /* Advance destination pointer */
                    164:                 dp++;
                    165:             }
                    166:             /* Advance source pointer */
                    167:             csay++;
                    168:             csp = (SDL_TYPE *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
                    169:             /* Advance destination pointers */
                    170:             dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
                    171:         }
                    172: 
                    173: 
                    174:     } else {
                    175:         csay = say;
                    176: 
                    177:         for (y = 0; y < dst_rect->y; y++) {
                    178:             csay++;
                    179:             sstep = (*csay >> 16) * src->pitch;
                    180:             csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
                    181:         }
                    182: 
                    183:         /* Calculate sstep_jump */
                    184:         csax = sax; 
                    185:         sstep_jump = 0;
                    186:         for (x = 0; x < dst_rect->x; x++) {
                    187:             csax++; 
                    188:             sstep = (*csax >> 16);
                    189:             sstep_jump += sstep;
                    190:         }
                    191: 
                    192:         for (y = 0 ; y < dst_rect->h ; y++) {
                    193:             sp = csp + sstep_jump;
                    194:             csax = sax + dst_rect->x;
                    195: 
                    196:             for (x = 0; x < dst_rect->w; x++) {
                    197: 
                    198:                 /* Draw */
                    199:                 *dp = *sp;
                    200: 
                    201:                 /* Advance source pointers */
                    202:                 csax++;
                    203:                 sstep = (*csax >> 16);
                    204:                 sp += sstep;
                    205: 
                    206:                 /* Advance destination pointer */
                    207:                 dp++;
                    208:             }
                    209:             /* Advance source pointers */
                    210:             csay++;
                    211:             sstep = (*csay >> 16) * src->pitch;
                    212:             csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
                    213: 
                    214:             /* Advance destination pointer */
                    215:             dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
                    216:         }
                    217:     }
                    218: 
                    219:     free(sax);
                    220:     free(say);
                    221:     return (0);
                    222: }
                    223: 
                    224: #undef SDL_TYPE
                    225: 

unix.superglobalmegacorp.com