Image.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <image/Image.h>
00022 #include <image/ImageFactory.h>
00023 #include <image/ImageHandle.h>
00024 #include <common/DefinesAssert.h>
00025 #include <SDL/SDL.h>
00026 #include "string.h"
00027 
00028 Image::~Image()
00029 {
00030 
00031 }
00032 
00033 unsigned char *Image::getBitsPos(int x, int y)
00034 {
00035         DIALOG_ASSERT(x >= 0 && y >= 0 && x < getWidth() && y < getHeight());
00036         return &getBits()[(x * getComponents()) + (y * getWidth() * getComponents())];
00037 }
00038 
00039 unsigned char *Image::getBitsOffset(int offset)
00040 {
00041         DIALOG_ASSERT(offset >=0 && offset < getComponents() * getWidth() * getHeight());
00042         return &getBits()[offset];
00043 }
00044 
00045 bool Image::writeToFile(const std::string &filename)
00046 {
00047         if (!getBits() || getComponents() == 4) return false;
00048 
00049         unsigned char *brgbits = new unsigned char[getWidth() * getHeight() * 3];
00050 
00051         // Convert the returned bits from RGB to BGR
00052         // and flip the verticle scan lines
00053         unsigned char *from = (unsigned char *) getBits();
00054         for (int i=0; i<getHeight(); i ++)
00055         {
00056                 unsigned char *destRow = ((unsigned char *) brgbits) + 
00057                         ((getHeight() - i - 1) * (getWidth() * 3));
00058                 for (int j=0; j<getWidth(); j++)
00059                 {
00060                         unsigned char *dest = destRow + (j * getComponents());
00061 
00062                         dest[0] = from[0];
00063                         dest[1] = from[1];
00064                         dest[2] = from[2];
00065                         from+=getComponents();
00066                 }
00067         }
00068 
00069     /* SDL interprets each pixel as a 32-bit number, so our masks must depend
00070        on the endianness (byte order) of the machine */
00071     Uint32 rmask, gmask, bmask;
00072 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00073     rmask = 0xff000000;
00074     gmask = 0x00ff0000;
00075     bmask = 0x0000ff00;
00076 #else
00077     rmask = 0x000000ff;
00078     gmask = 0x0000ff00;
00079     bmask = 0x00ff0000;
00080 #endif
00081 
00082         SDL_Surface *image = SDL_CreateRGBSurface( 
00083                 SDL_SWSURFACE, getWidth(), getHeight(), 24, rmask, gmask, bmask, 0);
00084         memcpy(image->pixels, brgbits, getWidth() * getHeight() * 3);
00085 
00086         if (!image) return false;
00087 
00088         SDL_SaveBMP(image, filename.c_str());
00089     SDL_FreeSurface (image);
00090 
00091         delete [] brgbits;
00092         return true;
00093 }
00094 
00095 #ifndef S3D_SERVER
00096 
00097 #include <GLEXT/GLState.h>
00098 #include <common/Defines.h>
00099 
00100 ImageHandle Image::createAlphaMult(float mult)
00101 {
00102         if (getComponents() != 4) return ImageHandle();
00103         
00104         ImageHandle map = ImageFactory::createBlank(getWidth(), getHeight(), true);
00105 
00106         unsigned char *srcBits = getBits();
00107         unsigned char *destBits = map.getBits();
00108         for (int y=0; y<getHeight(); y++)
00109         {
00110                 for (int x=0; x<getWidth(); x++, srcBits += 3, destBits += 3)
00111                 {
00112                         float a = float(srcBits[3]) * mult;
00113                         a = MAX(a, 255);
00114                         a = MIN(a, 0);
00115 
00116                         destBits[0] = srcBits[0];
00117                         destBits[1] = srcBits[1];
00118                         destBits[2] = srcBits[2];
00119                         destBits[3] = (unsigned char)(a);
00120                 }
00121         }
00122 
00123         return ImageHandle(map);
00124 }
00125 
00126 ImageHandle Image::createResize(int newWidth, int newHeight)
00127 {
00128         if (!getBits()) return ImageHandle();
00129 
00130         ImageHandle map = ImageFactory::createBlank(newWidth, newHeight);
00131 
00132         // Odd hack to fix a seeming memory corruption with gluScaleImage
00133         delete [] map.getBits();
00134         map.setBits(new unsigned char[newWidth * 2 * newHeight * map.getComponents()]);
00135 
00136         if (getWidth() != newWidth || getHeight() != newHeight)
00137         {
00138                 int result = gluScaleImage(
00139                         ((getComponents()==4)?GL_RGBA:GL_RGB), 
00140                         getWidth(), getHeight(),
00141                         GL_UNSIGNED_BYTE, getBits(),
00142                         newWidth, newHeight, 
00143                         GL_UNSIGNED_BYTE, map.getBits());
00144                 if (result != 0)
00145                 {
00146                         const char *error = (const char *) gluErrorString(result);
00147                         S3D::dialogExit("gluScaleImage", error);
00148                 }
00149         }
00150         else
00151         {
00152                 memcpy(map.getBits(), getBits(), getComponents() * getWidth() * getHeight());
00153         }
00154 
00155         return ImageHandle(map);
00156 }
00157 #endif

Generated on Mon Feb 16 15:14:50 2009 for Scorched3D by  doxygen 1.5.3