KeosImage.cpp

Go to the documentation of this file.
00001 /*
00002  * This source file is part of KEOS (Free 3D Engine)
00003  * For the latest info, see http://www.keosengine.org/
00004  * E-mails : thierry.vouriot@keosengine.org, yeri@keosengine.org
00005  *
00006  * This program is free software; you can redistribute it and/or modify it under
00007  * the terms of the GNU Lesser General Public License as published by the Free Software
00008  * Foundation; either version 2 of the License, or (at your option) any later
00009  * version.
00010  *
00011  * This program is distributed in the hope that it will be useful, but WITHOUT
00012  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public License along with
00016  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00017  * Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00018  * http://www.gnu.org/copyleft/lesser.txt.
00019  *
00020  */
00021 
00022 #include "KeosImage.h"
00023 #include "KeosPixelUtils.h"
00024 #include "KeosException.h"
00025 #include "KeosColor.h"
00026 #include "KeosRectangle.h"
00027 
00028 namespace Keos
00029 {
00030 
00031   //=======================================================================
00032   // CImage implementation
00033   //=======================================================================
00034 
00035   //-----------------------------------------------------------------------
00036   CImage::CImage(const TVector2I& Size, TPixelFormat Format) :
00037       m_Size  (Size),
00038       m_Format(Format),
00039       m_Pixels(Size.x * Size.y * GetBytesPerPixel(Format), 0x00)
00040   {}
00041 
00042   //-----------------------------------------------------------------------
00043   CImage::CImage(const TVector2I& Size, TPixelFormat Format, const uchar* pPixels) :
00044       m_Size  (Size),
00045       m_Format(Format),
00046       m_Pixels(pPixels, pPixels + Size.x * Size.y * GetBytesPerPixel(Format))
00047   {}
00048 
00049   //-----------------------------------------------------------------------
00050   const TVector2I& CImage::GetSize() const
00051   {
00052     return m_Size;
00053   }
00054 
00055   //-----------------------------------------------------------------------
00056   TPixelFormat CImage::GetFormat() const
00057   {
00058     return m_Format;
00059   }
00060 
00061   //-----------------------------------------------------------------------
00062   const uchar* CImage::GetData() const
00063   {
00064     return &m_Pixels[0];
00065   }
00066 
00067   //-----------------------------------------------------------------------
00068   void CImage::Fill(const CColor& Color)
00069   {
00070     SetPixel(0, 0, Color);
00071 
00072     uint Bpp = GetBytesPerPixel(m_Format);
00073     std::vector<uchar>::iterator Begin = m_Pixels.begin();
00074     for (std::vector<uchar>::iterator i = Begin + Bpp; i != m_Pixels.end(); i += Bpp)
00075       std::copy(Begin, Begin + Bpp, i);
00076   }
00077 
00078   //-----------------------------------------------------------------------
00079   void CImage::SetPixel(int x, int y, const uchar* pPix)
00080   {
00081     std::copy(pPix, pPix + GetBytesPerPixel(m_Format), &m_Pixels[(x + y * m_Size.x) * GetBytesPerPixel(m_Format)]);
00082   }
00083 
00084   //-----------------------------------------------------------------------
00085   void CImage::SetPixel(int x, int y, const CColor& Color)
00086   {
00087     uchar* pPix = &m_Pixels[(x + y * m_Size.x) * GetBytesPerPixel(m_Format)];
00088 
00089     uchar Components[4] = {Color.GetBlue(), Color.GetGreen(), Color.GetRed(), Color.GetAlpha()};
00090     ConvertPixel(PXF_A8R8G8B8, Components, m_Format, pPix);
00091   }
00092 
00093   //-----------------------------------------------------------------------
00094   void CImage::GetPixel(int x, int y, uchar* pPix) const
00095   {
00096     const uchar* pBegin = &m_Pixels[(x + y * m_Size.x) * GetBytesPerPixel(m_Format)];
00097     std::copy(pBegin, pBegin + GetBytesPerPixel(m_Format), pPix);
00098   }
00099 
00100   //-----------------------------------------------------------------------
00101   CColor CImage::GetPixel(int x, int y) const
00102   {
00103     uchar Components[4];
00104     const uchar* pPix = &m_Pixels[(x + y * m_Size.x) * GetBytesPerPixel(m_Format)];
00105     ConvertPixel(m_Format, pPix, PXF_A8R8G8B8, Components);
00106 
00107     return CColor(Components[2], Components[1], Components[0], Components[3]);
00108   }
00109 
00110   //-----------------------------------------------------------------------
00111   void CImage::CopyImage(const CImage& Src)
00112   {
00113     // If the dimensions are not the same we make a filtering, otherwise we make a simple copy
00114     if (m_Size == Src.m_Size)
00115     {
00116       // If the sizes are the same we copy simply pixels, otherwise we make a conversion
00117       if (m_Format == Src.m_Format)
00118       {
00119         m_Pixels = Src.m_Pixels;
00120       }
00121       else
00122       {
00123         // Recovery of the parameters for the copy (pointer on pixels and bpps)
00124         const uchar* pSrcPix  = &Src.m_Pixels[0];
00125         uchar*       pDestPix = &m_Pixels[0];
00126         uint         SrcBpp  = GetBytesPerPixel(Src.m_Format);
00127         uint         DestBpp = GetBytesPerPixel(m_Format);
00128 
00129         // For each pixels of the image source, conversion / copy in the current image
00130         for (int i = 0; i < m_Size.x; ++i)
00131           for (int j = 0; j < m_Size.y; ++j)
00132           {
00133             ConvertPixel(Src.m_Format, pSrcPix, m_Format, pDestPix);
00134             pSrcPix  += SrcBpp;
00135             pDestPix += DestBpp;
00136           }
00137       }
00138     }
00139     else
00140     {
00141       // Calculation of the step of progress in the image source
00142       TVector2F Step(static_cast<float>(Src.m_Size.x) / m_Size.x, static_cast<float>(Src.m_Size.y) / m_Size.y);
00143 
00144       // If the formats are the same we copy simply pixels, otherwise we make a conversion
00145       if (m_Format == Src.m_Format)
00146       {
00147         // Copy of the pixels
00148         uchar Pixel[16];
00149         for (int i = 0; i < m_Size.x; ++i)
00150           for (int j = 0; j < m_Size.y; ++j)
00151           {
00152             Src.GetPixel(static_cast<int>(i * Step.x), static_cast<int>(j * Step.y), Pixel);
00153             SetPixel(i, j, Pixel);
00154           }
00155       }
00156       else
00157       {
00158         // For each pixels of the image source, conversion / copy in the current image
00159         uchar SrcPix[16], DestPix[16];
00160         for (int i = 0; i < m_Size.x; ++i)
00161           for (int j = 0; j < m_Size.y; ++j)
00162           {
00163             Src.GetPixel(static_cast<int>(i * Step.x), static_cast<int>(j * Step.y), SrcPix);
00164             ConvertPixel(Src.m_Format, SrcPix, m_Format, DestPix);
00165             SetPixel(i, j, DestPix);
00166           }
00167       }
00168     }
00169   }
00170 
00171   //-----------------------------------------------------------------------
00172   CImage CImage::SubImage(const CRectangle& Rect) const
00173   {
00174     Assert(CRectangle(0, 0, m_Size.x, m_Size.y).Intersects(Rect) == INT_IN);
00175 
00176     CImage Img(TVector2I(Rect.Width(), Rect.Height()), m_Format);
00177 
00178     const uchar* pSrc       = &m_Pixels[(Rect.Left() + Rect.Top() * m_Size.x) * GetBytesPerPixel(m_Format)];
00179     uchar*       pDest      = &Img.m_Pixels[0];
00180     const uint   SrcPitch  = m_Size.x * GetBytesPerPixel(m_Format);
00181     const uint   DestPitch = Img.m_Size.x * GetBytesPerPixel(Img.m_Format);
00182 
00183     for (int i = Rect.Left(); i < Rect.Right(); ++i)
00184     {
00185       std::copy(pSrc, pSrc + DestPitch, pDest);
00186       pSrc  += SrcPitch;
00187       pDest += DestPitch;
00188     }
00189 
00190     return Img;
00191   }
00192 
00193   //-----------------------------------------------------------------------
00194   void CImage::Flip()
00195   {
00196     int Bpp = GetBytesPerPixel(m_Format);
00197 
00198     for (int j = 0; j < m_Size.y / 2; ++j)
00199     {
00200       std::swap_ranges(&m_Pixels[j * m_Size.x * Bpp],
00201                        &m_Pixels[(j + 1) * m_Size.x * Bpp - 1],
00202                        &m_Pixels[(m_Size.y - j - 1) * m_Size.x * Bpp]);
00203     }
00204   }
00205 
00206   //-----------------------------------------------------------------------
00207   void CImage::Mirror()
00208   {
00209     int Bpp = GetBytesPerPixel(m_Format);
00210 
00211     for (int i = 0; i < m_Size.x / 2; ++i)
00212       for (int j = 0; j < m_Size.y; ++j)
00213       {
00214         std::swap_ranges(&m_Pixels[(i + j * m_Size.x) * Bpp],
00215                          &m_Pixels[(i + j * m_Size.x + 1) * Bpp],
00216                          &m_Pixels[(m_Size.x - i - 1 + j * m_Size.x) * Bpp]);
00217       }
00218   }
00219 
00220 } // namespace Keos

Generated on Fri Mar 9 14:29:02 2007 for Keos by  doxygen 1.5.1-p1