Pixel-doubling blitter

From GPWiki

Here is C-code for pixel-doubling blitter using SDL. Code has been tested with gcc-4.0.3, with flags -Wall -pedantic -ansi -g

 void
 pixel_doubling_blit(SDL_Surface* surface)
 {
   register int i, j;
 
   SDL_Surface* screen = SDL_GetVideoSurface();
 
   int bpp = surface->format->BytesPerPixel;
 
   assert(bpp == screen->format->BytesPerPixel);
 
   if (SDL_MUSTLOCK(screen) != 0)
   {
     if (SDL_LockSurface(screen) < 0)
     {
       fprintf(stderr, "screen locking failed\n");
       return;
     }
   }
 
   switch (bpp)
   {
     case 2:
     {
       int tpitch = screen->pitch / 2;
       int spitch = surface->pitch / 2;
        /* :COMMENT: 051223.15: pitch is always in bytes
         * However, incrementing is done in sizeof(Uint16)
         * and sizeof(Uint16) is two bytes. */
 
       Uint16* tp = (Uint16*) screen->pixels;
       Uint16* sp = (Uint16*) surface->pixels;
 
       const int wd = ((screen->w / 2) < (surface->w))
           ? (screen->w / 2) : (surface->w);
 
       const int hg = ((screen->h) < (surface->w))
           ? (screen->h) : (surface->w);
 
       for (j = 0; j < hg; ++j)
       {
         for (i = 0; i < wd; ++i)
         {
           tp[i*2] = sp[i];
           tp[i*2 + 1] = sp[i];
         }
         tp += tpitch;
         if (j % 2 != 0)  sp += spitch;
       }
 
       break;
     }
     case 3:
     {
        /* :COMMENT: 051223.18: This case has only been tested on
         *                      little-endian machine. */
 
       int tpitch = screen->pitch;
       int spitch = surface->pitch;
 
       const int wd = ((screen->w / 2) < (surface->w))
           ? (screen->w / 2) : (surface->w);
 
       const int hg = ((screen->h) < (surface->w))
           ? (screen->h) : (surface->w);
 
       Uint8* tp = (Uint8*) screen->pixels;
       Uint8* sp = (Uint8*) surface->pixels;
 
       for (j = 0; j < hg; ++j)
       {
         for (i = 0; i < 3 * wd; i += 3)
         {
           int i2 = i * 2;
           tp[i2 + 0] = sp[i];
           tp[i2 + 1] = sp[i + 1];
           tp[i2 + 2] = sp[i + 2];
           tp[i2 + 3] = sp[i];
           tp[i2 + 4] = sp[i + 1];
           tp[i2 + 5] = sp[i + 2];
         }
         tp += tpitch;
         if (j % 2 != 0)  sp += spitch;
       }
 
       break;
     }
     case 4:
     {
       int tpitch = screen->pitch / 4;
       int spitch = surface->pitch / 4;
        /* :COMMENT: 051223.15: pitch is always in bytes
         * However, incrementing is done in sizeof(Uint32)
         * and sizeof(Uint32) is four bytes. */
 
       Uint32* tp = (Uint32*) screen->pixels;
       Uint32* sp = (Uint32*) surface->pixels;
 
       const int wd = ((screen->w / 2) < (surface->w))
           ? (screen->w / 2) : (surface->w);
 
       const int hg = ((screen->h) < (surface->w))
           ? (screen->h) : (surface->w);
 
       for (j = 0; j < hg; ++j)
       {
         for (i = 0; i < wd; ++i)
         {
           tp[i*2] = sp[i];
           tp[i*2 + 1] = sp[i];
         }
         tp += tpitch;
         if (j % 2 != 0)  sp += spitch;
       }
 
       break;
     }
     default:
       /* :COMMENT: 051223.17: This should never happen. */
       fprintf(stderr, "Unknown bitdepth.\n");
       break;
   }
 
 
   if (SDL_MUSTLOCK(screen) != 0)
   {
     SDL_UnlockSurface(screen);
   }
 }