00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include "SDL_gfxBlitFunc.h"
00010 
00018 static unsigned int GFX_ALPHA_ADJUST_ARRAY[256] = {
00019         0,  
00020         15,  
00021         22,  
00022         27,  
00023         31,  
00024         35,  
00025         39,  
00026         42,  
00027         45,  
00028         47,  
00029         50,  
00030         52,  
00031         55,  
00032         57,  
00033         59,  
00034         61,  
00035         63,  
00036         65,  
00037         67,  
00038         69,  
00039         71,  
00040         73,  
00041         74,  
00042         76,  
00043         78,  
00044         79,  
00045         81,  
00046         82,  
00047         84,  
00048         85,  
00049         87,  
00050         88,  
00051         90,  
00052         91,  
00053         93,  
00054         94,  
00055         95,  
00056         97,  
00057         98,  
00058         99,  
00059         100,  
00060         102,  
00061         103,  
00062         104,  
00063         105,  
00064         107,  
00065         108,  
00066         109,  
00067         110,  
00068         111,  
00069         112,  
00070         114,  
00071         115,  
00072         116,  
00073         117,  
00074         118,  
00075         119,  
00076         120,  
00077         121,  
00078         122,  
00079         123,  
00080         124,  
00081         125,  
00082         126,  
00083         127,  
00084         128,  
00085         129,  
00086         130,  
00087         131,  
00088         132,  
00089         133,  
00090         134,  
00091         135,  
00092         136,  
00093         137,  
00094         138,  
00095         139,  
00096         140,  
00097         141,  
00098         141,  
00099         142,  
00100         143,  
00101         144,  
00102         145,  
00103         146,  
00104         147,  
00105         148,  
00106         148,  
00107         149,  
00108         150,  
00109         151,  
00110         152,  
00111         153,  
00112         153,  
00113         154,  
00114         155,  
00115         156,  
00116         157,  
00117         158,  
00118         158,  
00119         159,  
00120         160,  
00121         161,  
00122         162,  
00123         162,  
00124         163,  
00125         164,  
00126         165,  
00127         165,  
00128         166,  
00129         167,  
00130         168,  
00131         168,  
00132         169,  
00133         170,  
00134         171,  
00135         171,  
00136         172,  
00137         173,  
00138         174,  
00139         174,  
00140         175,  
00141         176,  
00142         177,  
00143         177,  
00144         178,  
00145         179,  
00146         179,  
00147         180,  
00148         181,  
00149         182,  
00150         182,  
00151         183,  
00152         184,  
00153         184,  
00154         185,  
00155         186,  
00156         186,  
00157         187,  
00158         188,  
00159         188,  
00160         189,  
00161         190,  
00162         190,  
00163         191,  
00164         192,  
00165         192,  
00166         193,  
00167         194,  
00168         194,  
00169         195,  
00170         196,  
00171         196,  
00172         197,  
00173         198,  
00174         198,  
00175         199,  
00176         200,  
00177         200,  
00178         201,  
00179         201,  
00180         202,  
00181         203,  
00182         203,  
00183         204,  
00184         205,  
00185         205,  
00186         206,  
00187         206,  
00188         207,  
00189         208,  
00190         208,  
00191         209,  
00192         210,  
00193         210,  
00194         211,  
00195         211,  
00196         212,  
00197         213,  
00198         213,  
00199         214,  
00200         214,  
00201         215,  
00202         216,  
00203         216,  
00204         217,  
00205         217,  
00206         218,  
00207         218,  
00208         219,  
00209         220,  
00210         220,  
00211         221,  
00212         221,  
00213         222,  
00214         222,  
00215         223,  
00216         224,  
00217         224,  
00218         225,  
00219         225,  
00220         226,  
00221         226,  
00222         227,  
00223         228,  
00224         228,  
00225         229,  
00226         229,  
00227         230,  
00228         230,  
00229         231,  
00230         231,  
00231         232,  
00232         233,  
00233         233,  
00234         234,  
00235         234,  
00236         235,  
00237         235,  
00238         236,  
00239         236,  
00240         237,  
00241         237,  
00242         238,  
00243         238,  
00244         239,  
00245         240,  
00246         240,  
00247         241,  
00248         241,  
00249         242,  
00250         242,  
00251         243,  
00252         243,  
00253         244,  
00254         244,  
00255         245,  
00256         245,  
00257         246,  
00258         246,  
00259         247,  
00260         247,  
00261         248,  
00262         248,  
00263         249,  
00264         249,  
00265         250,  
00266         250,  
00267         251,  
00268         251,  
00269         252,  
00270         252,  
00271         253,  
00272         253,  
00273         254,  
00274         255   
00275 };
00276 
00285 void _SDL_gfxBlitBlitterRGBA(SDL_gfxBlitInfo * info)
00286 {
00287         int       width = info->d_width;
00288         int       height = info->d_height;
00289         Uint8    *src = info->s_pixels;
00290         int       srcskip = info->s_skip;
00291         Uint8    *dst = info->d_pixels;
00292         int       dstskip = info->d_skip;
00293         SDL_PixelFormat *srcfmt = info->src;
00294         SDL_PixelFormat *dstfmt = info->dst;
00295         Uint8       srcbpp = srcfmt->BytesPerPixel;
00296         Uint8       dstbpp = dstfmt->BytesPerPixel;
00297 
00298         while (height--) {
00299                 GFX_DUFFS_LOOP4( {
00300                         Uint32 pixel;
00301                         unsigned sR;
00302                         unsigned sG;
00303                         unsigned sB;
00304                         unsigned sA;
00305                         unsigned dR;
00306                         unsigned dG;
00307                         unsigned dB;
00308                         unsigned dA;
00309                         unsigned sAA;
00310                         GFX_DISASSEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA);
00311                         GFX_DISASSEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
00312                         sAA=GFX_ALPHA_ADJUST_ARRAY[sA & 255];
00313                         GFX_ALPHA_BLEND(sR, sG, sB, sAA, dR, dG, dB);
00314                         dA |= sAA;
00315                         GFX_ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
00316                         src += srcbpp; dst += dstbpp;
00317                 }, width);
00318                 src += srcskip;
00319                 dst += dstskip;
00320         }
00321 }
00322 
00335 int _SDL_gfxBlitRGBACall(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect)
00336 {
00337         
00338 
00339 
00340         if (srcrect->w && srcrect->h) {
00341                 SDL_gfxBlitInfo info;
00342 
00343                 
00344 
00345 
00346 #if (SDL_MINOR_VERSION == 3)
00347                 info.s_pixels = (Uint8 *) src->pixels               + (Uint16) srcrect->y * src->pitch + (Uint16) srcrect->x * src->format->BytesPerPixel;
00348 #else
00349                 info.s_pixels = (Uint8 *) src->pixels + src->offset + (Uint16) srcrect->y * src->pitch + (Uint16) srcrect->x * src->format->BytesPerPixel;
00350 #endif
00351                 info.s_width = srcrect->w;
00352                 info.s_height = srcrect->h;
00353                 info.s_skip = (int)(src->pitch - info.s_width * src->format->BytesPerPixel);
00354 #if (SDL_MINOR_VERSION == 3)
00355                 info.d_pixels = (Uint8 *) dst->pixels               + (Uint16) dstrect->y * dst->pitch + (Uint16) dstrect->x * dst->format->BytesPerPixel;
00356 #else
00357                 info.d_pixels = (Uint8 *) dst->pixels + dst->offset + (Uint16) dstrect->y * dst->pitch + (Uint16) dstrect->x * dst->format->BytesPerPixel;
00358 #endif
00359                 info.d_width = dstrect->w;
00360                 info.d_height = dstrect->h;
00361                 info.d_skip = (int)(dst->pitch - info.d_width * dst->format->BytesPerPixel);
00362                 info.aux_data = NULL;
00363                 info.src = src->format;
00364                 info.table = NULL;
00365                 info.dst = dst->format;
00366 
00367                 
00368 
00369 
00370                 _SDL_gfxBlitBlitterRGBA(&info);
00371                 return 1;
00372         }
00373 
00374         return (0);
00375 }
00376 
00390 int SDL_gfxBlitRGBA(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect)
00391 {
00392         SDL_Rect  sr, dr;
00393         int       srcx, srcy, w, h;
00394 
00395         
00396 
00397 
00398         if (!src || !dst) {
00399                 SDL_SetError("SDL_UpperBlit: passed a NULL surface");
00400                 return (-1);
00401         }
00402         if ((src->locked) || (dst->locked)) {
00403                 SDL_SetError("Surfaces must not be locked during blit");
00404                 return (-1);
00405         }
00406 
00407         
00408 
00409 
00410         if (dstrect == NULL) {
00411                 dr.x = dr.y = 0;
00412                 dr.w = dst->w;
00413                 dr.h = dst->h;
00414         } else {
00415                 dr = *dstrect;
00416         }
00417 
00418         
00419 
00420 
00421         if (srcrect) {
00422                 int       maxw, maxh;
00423 
00424                 srcx = srcrect->x;
00425                 w = srcrect->w;
00426                 if (srcx < 0) {
00427                         w += srcx;
00428                         dr.x -= srcx;
00429                         srcx = 0;
00430                 }
00431                 maxw = src->w - srcx;
00432                 if (maxw < w)
00433                         w = maxw;
00434 
00435                 srcy = srcrect->y;
00436                 h = srcrect->h;
00437                 if (srcy < 0) {
00438                         h += srcy;
00439                         dr.y -= srcy;
00440                         srcy = 0;
00441                 }
00442                 maxh = src->h - srcy;
00443                 if (maxh < h)
00444                         h = maxh;
00445 
00446         } else {
00447                 srcx = srcy = 0;
00448                 w = src->w;
00449                 h = src->h;
00450         }
00451 
00452         
00453 
00454 
00455         {
00456                 SDL_Rect *clip = &dst->clip_rect;
00457                 int       dx, dy;
00458 
00459                 dx = clip->x - dr.x;
00460                 if (dx > 0) {
00461                         w -= dx;
00462                         dr.x += dx;
00463                         srcx += dx;
00464                 }
00465                 dx = dr.x + w - clip->x - clip->w;
00466                 if (dx > 0)
00467                         w -= dx;
00468 
00469                 dy = clip->y - dr.y;
00470                 if (dy > 0) {
00471                         h -= dy;
00472                         dr.y += dy;
00473                         srcy += dy;
00474                 }
00475                 dy = dr.y + h - clip->y - clip->h;
00476                 if (dy > 0)
00477                         h -= dy;
00478         }
00479 
00480         if (w > 0 && h > 0) {
00481                 sr.x = srcx;
00482                 sr.y = srcy;
00483                 sr.w = dr.w = w;
00484                 sr.h = dr.h = h;
00485                 return (_SDL_gfxBlitRGBACall(src, &sr, dst, &dr));
00486         }
00487 
00488         return 0;
00489 }
00490 
00503 int SDL_gfxSetAlpha(SDL_Surface *src, Uint8 a)
00504 {
00505 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00506         const int alpha_offset = 0;
00507 #else
00508         const int alpha_offset = 3;
00509 #endif
00510         int i, j, row_skip;
00511         Uint8 *pixels;
00512         
00513         
00514         if ( (src==NULL) || 
00515              (src->format==NULL) || 
00516              (src->format->BytesPerPixel!=4) ) {
00517           SDL_SetError("SDL_gfxSetAlpha: Invalid input surface.");
00518           return -1;
00519         }
00520 
00521         
00522 
00523 
00524         if (SDL_MUSTLOCK(src)) {
00525                 if (SDL_LockSurface(src) < 0) {
00526                         return (-1);
00527                 }
00528         }
00529         
00530         
00531         pixels = (Uint8 *)src->pixels;
00532         row_skip = (src->pitch - (4*src->w));
00533         pixels += alpha_offset;
00534         for ( i=0; i<src->h; i++ ) {
00535           for ( j=0; j<src->w; j++  ) {
00536             *pixels = a; 
00537             pixels += 4;
00538           }
00539           pixels += row_skip;
00540         }
00541 
00542         
00543 
00544 
00545         if (SDL_MUSTLOCK(src)) {
00546                 SDL_UnlockSurface(src);
00547         }
00548         
00549         return 1; 
00550 }
00551 
00566 int SDL_gfxMultiplyAlpha(SDL_Surface *src, Uint8 a)
00567 {
00568 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00569         const int alpha_offset = 0;
00570 #else
00571         const int alpha_offset = 3;
00572 #endif
00573         int i, j, row_skip;
00574         Uint8 *pixels;
00575         
00576         
00577         if ( (src==NULL) || 
00578              (src->format==NULL) || 
00579              (src->format->BytesPerPixel!=4) ) {
00580           SDL_SetError("SDL_gfxMultiplyAlpha: Invalid input surface.");
00581           return -1;
00582         }
00583         
00584         
00585         if (a==255) {
00586           return 0;
00587         }
00588 
00589         
00590 
00591 
00592         if (SDL_MUSTLOCK(src)) {
00593                 if (SDL_LockSurface(src) < 0) {
00594                         return (-1);
00595                 }
00596         }
00597         
00598         
00599         pixels = (Uint8 *)src->pixels;
00600         row_skip = (src->pitch - (4*src->w));
00601         pixels += alpha_offset;
00602         for ( i=0; i<src->h; i++ ) {
00603           for ( j=0; j<src->w; j++  ) {
00604             *pixels = (Uint8)(((int)(*pixels)*a)>>8);
00605             pixels += 4;
00606           }
00607           pixels += row_skip;
00608         }
00609 
00610         
00611 
00612 
00613         if (SDL_MUSTLOCK(src)) {
00614                 SDL_UnlockSurface(src);
00615         }
00616                 
00617         return 1;
00618 }