File:  [Qemu by Fabrice Bellard] / qemu / sdl_zoom_template.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:20:33 2018 UTC (2 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu0125, qemu0124, qemu0123, qemu0122, qemu0121, qemu0120, qemu0111, qemu0110, HEAD
qemu 0.11.0

    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