Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

PixelTool.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  */
00009 #include "PixelTool.h"
00010 
00011 #include "LogicException.h"
00012 
00013 #include <assert.h>
00014 
00015 //-----------------------------------------------------------------
00016 /**
00017  * Compare colors.
00018  * NOTE: aplha values are ignored
00019  */
00020 bool
00021 PixelTool::colorEquals(const SDL_Color &color1, const SDL_Color &color2)
00022 {
00023     return color1.r == color2.r
00024         && color1.g == color2.g
00025         && color1.b == color2.b;
00026 }
00027 //-----------------------------------------------------------------
00028 Uint32
00029 PixelTool::convertColor(SDL_PixelFormat *format, const SDL_Color &color)
00030 {
00031     return SDL_MapRGB(format, color.r, color.g, color.b);
00032 }
00033 //-----------------------------------------------------------------
00034 /**
00035  * Get color at x, y.
00036  * Surface must be locked.
00037  * @return color
00038  */
00039 SDL_Color
00040 PixelTool::getColor(SDL_Surface *surface, int x, int y)
00041 {
00042     SDL_Color color;
00043     SDL_GetRGBA(getPixel(surface, x, y), surface->format,
00044             &color.r, &color.g, &color.b, &color.unused);
00045     return color;
00046 }
00047 //-----------------------------------------------------------------
00048 /**
00049  * Put color at x, y.
00050  * Surface must be locked.
00051  * TODO: support alpha values
00052  */
00053 void
00054 PixelTool::putColor(SDL_Surface *surface, int x, int y,
00055         const SDL_Color &color)
00056 {
00057     Uint32 pixel = SDL_MapRGBA(surface->format,
00058             color.r, color.g, color.b, color.unused);
00059     putPixel(surface, x, y, pixel);
00060 }
00061 //-----------------------------------------------------------------
00062 /**
00063  * Get pixel at x, y.
00064  * Surface must be locked.
00065  * @return pixel
00066  */
00067     Uint32
00068 PixelTool::getPixel(SDL_Surface *surface, int x, int y)
00069 {
00070     assert((0 <= x && x < surface->w) && (0 <= y && y < surface->h));
00071 
00072     int bpp = surface->format->BytesPerPixel;
00073     Uint8 *p = static_cast<Uint8*>(surface->pixels) + y * surface->pitch
00074         + x * bpp;
00075 
00076     return unpackPixel(bpp, p);
00077 }
00078 //-----------------------------------------------------------------
00079 /**
00080  * Put pixel at x, y.
00081  * Surface must be locked.
00082  */
00083     void
00084 PixelTool::putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
00085 {
00086     if ((0 <= x && x < surface->w) && (0 <= y && y < surface->h)) {
00087         int bpp = surface->format->BytesPerPixel;
00088         Uint8 *p = static_cast<Uint8*>(surface->pixels) + y * surface->pitch
00089             + x * bpp;
00090 
00091         packPixel(bpp, p, pixel);
00092     }
00093 }
00094 //-----------------------------------------------------------------
00095 /**
00096  * Decodes pixel from memory.
00097  * @param bpp color depth (8, 16, 24, 32)
00098  * @param p pointer to the memory
00099  * @return pixel in bpp color depth 
00100  * @throws LogicException for unknown color depth
00101  */
00102     Uint32
00103 PixelTool::unpackPixel(Uint8 bpp, Uint8 *p)
00104 {
00105     switch(bpp) {
00106         case 1: // 8bit
00107             return *p;
00108         case 2: // 16bit 
00109             return *reinterpret_cast<Uint16*>(p);
00110         case 3: // 24bit 
00111             if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00112                 return p[0] << 16 | p[1] << 8 | p[2];
00113             }
00114             else {
00115                 return p[0] | p[1] << 8 | p[2] << 16;
00116             }
00117         case 4: // 32 bit
00118             return *reinterpret_cast<Uint32*>(p);
00119         default:
00120             throw LogicException(ExInfo("unknown color depth")
00121                     .addInfo("bpp", bpp));
00122     }
00123 }
00124 //-----------------------------------------------------------------
00125 /**
00126  * Encodes pixel to memory.
00127  * @param bpp color depth (8, 16, 24, 32)
00128  * @param p pointer to the memory
00129  * @param pixel prepared pixel in bpp color depth
00130  * @throws LogicException for unknown color depth
00131  */
00132     void
00133 PixelTool::packPixel(Uint8 bpp, Uint8 *p, Uint32 pixel)
00134 {
00135     assert(p != NULL);
00136 
00137     switch(bpp) {
00138         case 1:
00139             *p = pixel;
00140             break;
00141         case 2:
00142             *reinterpret_cast<Uint16*>(p) = pixel;
00143             break;
00144         case 3:
00145             if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00146                 p[0] = (pixel >> 16) & 0xff;
00147                 p[1] = (pixel >> 8) & 0xff;
00148                 p[2] = pixel & 0xff;
00149             } else {
00150                 p[0] = pixel & 0xff;
00151                 p[1] = (pixel >> 8) & 0xff;
00152                 p[2] = (pixel >> 16) & 0xff;
00153             }
00154             break;
00155         case 4:
00156             *reinterpret_cast<Uint32*>(p) = pixel;
00157             break;
00158         default:
00159             throw LogicException(ExInfo("unknown color depth")
00160                     .addInfo("bpp", bpp));
00161     }
00162 }
00163 

Generated on Wed Jun 1 09:54:31 2005 for Fish Fillets - Next Generation by  doxygen 1.4.2