src/video/SDL_blit_1.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. Blit1to1
  2. Blit1to2
  3. Blit1to3
  4. Blit1to4
  5. Blit1to1Key
  6. Blit1to2Key
  7. Blit1to3Key
  8. Blit1to4Key
  9. Blit1toNAlpha
  10. Blit1toNAlphaKey
  11. SDL_CalculateBlit1

   1 /*
   2     SDL - Simple DirectMedia Layer
   3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
   4 
   5     This library is free software; you can redistribute it and/or
   6     modify it under the terms of the GNU Library General Public
   7     License as published by the Free Software Foundation; either
   8     version 2 of the License, or (at your option) any later version.
   9 
  10     This library is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13     Library General Public License for more details.
  14 
  15     You should have received a copy of the GNU Library General Public
  16     License along with this library; if not, write to the Free
  17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 
  19     Sam Lantinga
  20     slouken@devolution.com
  21 */
  22 
  23 #ifdef SAVE_RCSID
  24 static char rcsid =
  25  "@(#) $Id: SDL_blit_1.c,v 1.3.2.6 2001/02/10 07:20:05 hercules Exp $";
  26 #endif
  27 
  28 #include <stdio.h>
  29 
  30 #include "SDL_types.h"
  31 #include "SDL_video.h"
  32 #include "SDL_blit.h"
  33 #include "SDL_sysvideo.h"
  34 #include "SDL_endian.h"
  35 
  36 /* Functions to blit from 8-bit surfaces to other surfaces */
  37 
  38 static void Blit1to1(SDL_BlitInfo *info)
     /* [<][>][^][v][top][bottom][index][help] */
  39 {
  40 #ifndef USE_DUFFS_LOOP
  41         int c;
  42 #endif
  43         int width, height;
  44         Uint8 *src, *map, *dst;
  45         int srcskip, dstskip;
  46 
  47         /* Set up some basic variables */
  48         width = info->d_width;
  49         height = info->d_height;
  50         src = info->s_pixels;
  51         srcskip = info->s_skip;
  52         dst = info->d_pixels;
  53         dstskip = info->d_skip;
  54         map = info->table;
  55 
  56         while ( height-- ) {
  57 #ifdef USE_DUFFS_LOOP
  58                 DUFFS_LOOP(
  59                         {
  60                           *dst = map[*src];
  61                         }
  62                         dst++;
  63                         src++;
  64                 , width);
  65 #else
  66                 for ( c=width; c; --c ) {
  67                         *dst = map[*src];
  68                         dst++;
  69                         src++;
  70                 }
  71 #endif
  72                 src += srcskip;
  73                 dst += dstskip;
  74         }
  75 }
  76 /* This is now endian dependent */
  77 #if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
  78 #define HI      1
  79 #define LO      0
  80 #else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
  81 #define HI      0
  82 #define LO      1
  83 #endif
  84 static void Blit1to2(SDL_BlitInfo *info)
     /* [<][>][^][v][top][bottom][index][help] */
  85 {
  86 #ifndef USE_DUFFS_LOOP
  87         int c;
  88 #endif
  89         int width, height;
  90         Uint8 *src, *dst;
  91         Uint16 *map;
  92         int srcskip, dstskip;
  93 
  94         /* Set up some basic variables */
  95         width = info->d_width;
  96         height = info->d_height;
  97         src = info->s_pixels;
  98         srcskip = info->s_skip;
  99         dst = info->d_pixels;
 100         dstskip = info->d_skip;
 101         map = (Uint16 *)info->table;
 102 
 103 #ifdef USE_DUFFS_LOOP
 104         while ( height-- ) {
 105                 DUFFS_LOOP(
 106                 {
 107                         *(Uint16 *)dst = map[*src++];
 108                         dst += 2;
 109                 },
 110                 width);
 111                 src += srcskip;
 112                 dst += dstskip;
 113         }
 114 #else
 115         /* Memory align at 4-byte boundary, if necessary */
 116         if ( (long)dst & 0x03 ) {
 117                 /* Don't do anything if width is 0 */
 118                 if ( width == 0 ) {
 119                         return;
 120                 }
 121                 --width;
 122 
 123                 while ( height-- ) {
 124                         /* Perform copy alignment */
 125                         *(Uint16 *)dst = map[*src++];
 126                         dst += 2;
 127 
 128                         /* Copy in 4 pixel chunks */
 129                         for ( c=width/4; c; --c ) {
 130                                 *(Uint32 *)dst =
 131                                         (map[src[HI]]<<16)|(map[src[LO]]);
 132                                 src += 2;
 133                                 dst += 4;
 134                                 *(Uint32 *)dst =
 135                                         (map[src[HI]]<<16)|(map[src[LO]]);
 136                                 src += 2;
 137                                 dst += 4;
 138                         }
 139                         /* Get any leftovers */
 140                         switch (width % 4) {
 141                                 case 3:
 142                                         *(Uint16 *)dst = map[*src++];
 143                                         dst += 2;
 144                                 case 2:
 145                                         *(Uint32 *)dst =
 146                                           (map[src[HI]]<<16)|(map[src[LO]]);
 147                                         src += 2;
 148                                         dst += 4;
 149                                         break;
 150                                 case 1:
 151                                         *(Uint16 *)dst = map[*src++];
 152                                         dst += 2;
 153                                         break;
 154                         }
 155                         src += srcskip;
 156                         dst += dstskip;
 157                 }
 158         } else { 
 159                 while ( height-- ) {
 160                         /* Copy in 4 pixel chunks */
 161                         for ( c=width/4; c; --c ) {
 162                                 *(Uint32 *)dst =
 163                                         (map[src[HI]]<<16)|(map[src[LO]]);
 164                                 src += 2;
 165                                 dst += 4;
 166                                 *(Uint32 *)dst =
 167                                         (map[src[HI]]<<16)|(map[src[LO]]);
 168                                 src += 2;
 169                                 dst += 4;
 170                         }
 171                         /* Get any leftovers */
 172                         switch (width % 4) {
 173                                 case 3:
 174                                         *(Uint16 *)dst = map[*src++];
 175                                         dst += 2;
 176                                 case 2:
 177                                         *(Uint32 *)dst =
 178                                           (map[src[HI]]<<16)|(map[src[LO]]);
 179                                         src += 2;
 180                                         dst += 4;
 181                                         break;
 182                                 case 1:
 183                                         *(Uint16 *)dst = map[*src++];
 184                                         dst += 2;
 185                                         break;
 186                         }
 187                         src += srcskip;
 188                         dst += dstskip;
 189                 }
 190         }
 191 #endif /* USE_DUFFS_LOOP */
 192 }
 193 static void Blit1to3(SDL_BlitInfo *info)
     /* [<][>][^][v][top][bottom][index][help] */
 194 {
 195 #ifndef USE_DUFFS_LOOP
 196         int c;
 197 #endif
 198         int o;
 199         int width, height;
 200         Uint8 *src, *map, *dst;
 201         int srcskip, dstskip;
 202 
 203         /* Set up some basic variables */
 204         width = info->d_width;
 205         height = info->d_height;
 206         src = info->s_pixels;
 207         srcskip = info->s_skip;
 208         dst = info->d_pixels;
 209         dstskip = info->d_skip;
 210         map = info->table;
 211 
 212         while ( height-- ) {
 213 #ifdef USE_DUFFS_LOOP
 214                 DUFFS_LOOP(
 215                         {
 216                                 o = *src * 4;
 217                                 dst[0] = map[o++];
 218                                 dst[1] = map[o++];
 219                                 dst[2] = map[o++];
 220                         }
 221                         src++;
 222                         dst += 3;
 223                 , width);
 224 #else
 225                 for ( c=width; c; --c ) {
 226                         o = *src * 4;
 227                         dst[0] = map[o++];
 228                         dst[1] = map[o++];
 229                         dst[2] = map[o++];
 230                         src++;
 231                         dst += 3;
 232                 }
 233 #endif /* USE_DUFFS_LOOP */
 234                 src += srcskip;
 235                 dst += dstskip;
 236         }
 237 }
 238 static void Blit1to4(SDL_BlitInfo *info)
     /* [<][>][^][v][top][bottom][index][help] */
 239 {
 240 #ifndef USE_DUFFS_LOOP
 241         int c;
 242 #endif
 243         int width, height;
 244         Uint8 *src;
 245         Uint32 *map, *dst;
 246         int srcskip, dstskip;
 247 
 248         /* Set up some basic variables */
 249         width = info->d_width;
 250         height = info->d_height;
 251         src = info->s_pixels;
 252         srcskip = info->s_skip;
 253         dst = (Uint32 *)info->d_pixels;
 254         dstskip = info->d_skip/4;
 255         map = (Uint32 *)info->table;
 256 
 257         while ( height-- ) {
 258 #ifdef USE_DUFFS_LOOP
 259                 DUFFS_LOOP(
 260                         *dst++ = map[*src++];
 261                 , width);
 262 #else
 263                 for ( c=width/4; c; --c ) {
 264                         *dst++ = map[*src++];
 265                         *dst++ = map[*src++];
 266                         *dst++ = map[*src++];
 267                         *dst++ = map[*src++];
 268                 }
 269                 switch ( width % 4 ) {
 270                         case 3:
 271                                 *dst++ = map[*src++];
 272                         case 2:
 273                                 *dst++ = map[*src++];
 274                         case 1:
 275                                 *dst++ = map[*src++];
 276                 }
 277 #endif /* USE_DUFFS_LOOP */
 278                 src += srcskip;
 279                 dst += dstskip;
 280         }
 281 }
 282 
 283 static void Blit1to1Key(SDL_BlitInfo *info)
     /* [<][>][^][v][top][bottom][index][help] */
 284 {
 285         int width = info->d_width;
 286         int height = info->d_height;
 287         Uint8 *src = info->s_pixels;
 288         int srcskip = info->s_skip;
 289         Uint8 *dst = info->d_pixels;
 290         int dstskip = info->d_skip;
 291         Uint8 *palmap = info->table;
 292         Uint32 ckey = info->src->colorkey;
 293         
 294         if ( palmap ) {
 295                 while ( height-- ) {
 296                         DUFFS_LOOP(
 297                         {
 298                                 if ( *src != ckey ) {
 299                                   *dst = palmap[*src];
 300                                 }
 301                                 dst++;
 302                                 src++;
 303                         },
 304                         width);
 305                         src += srcskip;
 306                         dst += dstskip;
 307                 }
 308         } else {
 309                 while ( height-- ) {
 310                         DUFFS_LOOP(
 311                         {
 312                                 if ( *src != ckey ) {
 313                                   *dst = *src;
 314                                 }
 315                                 dst++;
 316                                 src++;
 317                         },
 318                         width);
 319                         src += srcskip;
 320                         dst += dstskip;
 321                 }
 322         }
 323 }
 324 
 325 static void Blit1to2Key(SDL_BlitInfo *info)
     /* [<][>][^][v][top][bottom][index][help] */
 326 {
 327         int width = info->d_width;
 328         int height = info->d_height;
 329         Uint8 *src = info->s_pixels;
 330         int srcskip = info->s_skip;
 331         Uint16 *dstp = (Uint16 *)info->d_pixels;
 332         int dstskip = info->d_skip;
 333         Uint16 *palmap = (Uint16 *)info->table;
 334         Uint32 ckey = info->src->colorkey;
 335 
 336         /* Set up some basic variables */
 337         dstskip /= 2;
 338 
 339         while ( height-- ) {
 340                 DUFFS_LOOP(
 341                 {
 342                         if ( *src != ckey ) {
 343                                 *dstp=palmap[*src];
 344                         }
 345                         src++;
 346                         dstp++;
 347                 },
 348                 width);
 349                 src += srcskip;
 350                 dstp += dstskip;
 351         }
 352 }
 353 
 354 static void Blit1to3Key(SDL_BlitInfo *info)
     /* [<][>][^][v][top][bottom][index][help] */
 355 {
 356         int width = info->d_width;
 357         int height = info->d_height;
 358         Uint8 *src = info->s_pixels;
 359         int srcskip = info->s_skip;
 360         Uint8 *dst = info->d_pixels;
 361         int dstskip = info->d_skip;
 362         Uint8 *palmap = info->table;
 363         Uint32 ckey = info->src->colorkey;
 364         int o;
 365 
 366         while ( height-- ) {
 367                 DUFFS_LOOP(
 368                 {
 369                         if ( *src != ckey ) {
 370                                 o = *src * 4;
 371                                 dst[0] = palmap[o++];
 372                                 dst[1] = palmap[o++];
 373                                 dst[2] = palmap[o++];
 374                         }
 375                         src++;
 376                         dst += 3;
 377                 },
 378                 width);
 379                 src += srcskip;
 380                 dst += dstskip;
 381         }
 382 }
 383 
 384 static void Blit1to4Key(SDL_BlitInfo *info)
     /* [<][>][^][v][top][bottom][index][help] */
 385 {
 386         int width = info->d_width;
 387         int height = info->d_height;
 388         Uint8 *src = info->s_pixels;
 389         int srcskip = info->s_skip;
 390         Uint32 *dstp = (Uint32 *)info->d_pixels;
 391         int dstskip = info->d_skip;
 392         Uint32 *palmap = (Uint32 *)info->table;
 393         Uint32 ckey = info->src->colorkey;
 394 
 395         /* Set up some basic variables */
 396         dstskip /= 4;
 397 
 398         while ( height-- ) {
 399                 DUFFS_LOOP(
 400                 {
 401                         if ( *src != ckey ) {
 402                                 *dstp = palmap[*src];
 403                         }
 404                         src++;
 405                         dstp++;
 406                 },
 407                 width);
 408                 src += srcskip;
 409                 dstp += dstskip;
 410         }
 411 }
 412 
 413 static void Blit1toNAlpha(SDL_BlitInfo *info)
     /* [<][>][^][v][top][bottom][index][help] */
 414 {
 415         int width = info->d_width;
 416         int height = info->d_height;
 417         Uint8 *src = info->s_pixels;
 418         int srcskip = info->s_skip;
 419         Uint8 *dst = info->d_pixels;
 420         int dstskip = info->d_skip;
 421         SDL_PixelFormat *dstfmt = info->dst;
 422         const SDL_Color *srcpal = info->src->palette->colors;
 423         int dstbpp;
 424         const int A = info->src->alpha;
 425 
 426         /* Set up some basic variables */
 427         dstbpp = dstfmt->BytesPerPixel;
 428 
 429         while ( height-- ) {
 430                 int sR, sG, sB;
 431                 int dR, dG, dB;
 432                 DUFFS_LOOP4(
 433                         {
 434                                 Uint32 pixel;
 435                                 sR = srcpal[*src].r;
 436                                 sG = srcpal[*src].g;
 437                                 sB = srcpal[*src].b;
 438                                 DISEMBLE_RGB(dst, dstbpp, dstfmt,
 439                                              pixel, dR, dG, dB);
 440                                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
 441                                 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
 442                                 src++;
 443                                 dst += dstbpp;
 444                         },
 445                         width);
 446                 src += srcskip;
 447                 dst += dstskip;
 448         }
 449 }
 450 
 451 static void Blit1toNAlphaKey(SDL_BlitInfo *info)
     /* [<][>][^][v][top][bottom][index][help] */
 452 {
 453         int width = info->d_width;
 454         int height = info->d_height;
 455         Uint8 *src = info->s_pixels;
 456         int srcskip = info->s_skip;
 457         Uint8 *dst = info->d_pixels;
 458         int dstskip = info->d_skip;
 459         SDL_PixelFormat *srcfmt = info->src;
 460         SDL_PixelFormat *dstfmt = info->dst;
 461         const SDL_Color *srcpal = info->src->palette->colors;
 462         Uint32 ckey = srcfmt->colorkey;
 463         int dstbpp;
 464         const int A = srcfmt->alpha;
 465 
 466         /* Set up some basic variables */
 467         dstbpp = dstfmt->BytesPerPixel;
 468 
 469         while ( height-- ) {
 470                 int sR, sG, sB;
 471                 int dR, dG, dB;
 472                 DUFFS_LOOP(
 473                 {
 474                         if ( *src != ckey ) {
 475                                 Uint32 pixel;
 476                                 sR = srcpal[*src].r;
 477                                 sG = srcpal[*src].g;
 478                                 sB = srcpal[*src].b;
 479                                 DISEMBLE_RGB(dst, dstbpp, dstfmt,
 480                                                         pixel, dR, dG, dB);
 481                                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
 482                                 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
 483                         }
 484                         src++;
 485                         dst += dstbpp;
 486                 },
 487                 width);
 488                 src += srcskip;
 489                 dst += dstskip;
 490         }
 491 }
 492 
 493 static SDL_loblit one_blit[] = {
 494         NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
 495 };
 496 
 497 static SDL_loblit one_blitkey[] = {
 498         NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
 499 };
 500 
 501 SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index)
     /* [<][>][^][v][top][bottom][index][help] */
 502 {
 503         int which;
 504         SDL_PixelFormat *dstfmt;
 505 
 506         dstfmt = surface->map->dst->format;
 507         if ( dstfmt->BitsPerPixel < 8 ) {
 508                 which = 0;
 509         } else {
 510                 which = dstfmt->BytesPerPixel;
 511         }
 512         switch(blit_index) {
 513         case 0:                 /* copy */
 514             return one_blit[which];
 515 
 516         case 1:                 /* colorkey */
 517             return one_blitkey[which];
 518 
 519         case 2:                 /* alpha */
 520             /* Supporting 8bpp->8bpp alpha is doable but requires lots of
 521                tables which consume space and takes time to precompute,
 522                so is better left to the user */
 523             return which >= 2 ? Blit1toNAlpha : NULL;
 524 
 525         case 3:                 /* alpha + colorkey */
 526             return which >= 2 ? Blit1toNAlphaKey : NULL;
 527 
 528         }
 529         return NULL;
 530 }

/* [<][>][^][v][top][bottom][index][help] */