Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

# 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
    00044     //-----------------------------------------------------------------------
    00045     CImage::CImage(const TVector2I& Size, TPixelFormat Format, const uchar* pPixels) :
    00046     m_Size  (Size),
    00047     m_Format(Format),
    00048     m_Pixels(pPixels, pPixels + Size.x * Size.y * GetBytesPerPixel(Format))
    00049     {
    00050
    00051     }
    00052
    00053     //-----------------------------------------------------------------------
    00054     const TVector2I& CImage::GetSize() const
    00055     {
    00056         return m_Size;
    00057     }
    00058
    00059     //-----------------------------------------------------------------------
    00060     TPixelFormat CImage::GetFormat() const
    00061     {
    00062         return m_Format;
    00063     }
    00064
    00065     //-----------------------------------------------------------------------
    00066     const uchar* CImage::GetData() const
    00067     {
    00068         return &m_Pixels[0];
    00069     }
    00070
    00071     //-----------------------------------------------------------------------
    00072     void CImage::Fill(const CColor& Color)
    00073     {
    00074         SetPixel(0, 0, Color);
    00075
    00076         uint Bpp = GetBytesPerPixel(m_Format);
    00077         std::vector<uchar>::iterator Begin = m_Pixels.begin();
    00078         for (std::vector<uchar>::iterator i = Begin + Bpp; i != m_Pixels.end(); i += Bpp)
    00079             std::copy(Begin, Begin + Bpp, i);
    00080     }
    00081
    00082     //-----------------------------------------------------------------------
    00083     void CImage::SetPixel(int x, int y, const uchar* pPix)
    00084     {
    00085         std::copy(pPix, pPix + GetBytesPerPixel(m_Format), &m_Pixels[(x + y * m_Size.x) * GetBytesPerPixel(m_Format)]);
    00086     }
    00087
    00088     //-----------------------------------------------------------------------
    00089     void CImage::SetPixel(int x, int y, const CColor& Color)
    00090     {
    00091         uchar* pPix = &m_Pixels[(x + y * m_Size.x) * GetBytesPerPixel(m_Format)];
    00092
    00093         uchar Components[4] = {Color.GetBlue(), Color.GetGreen(), Color.GetRed(), Color.GetAlpha()};
    00094         ConvertPixel(PXF_A8R8G8B8, Components, m_Format, pPix);
    00095     }
    00096
    00097     //-----------------------------------------------------------------------
    00098     void CImage::GetPixel(int x, int y, uchar* pPix) const
    00099     {
    00100         const uchar* pBegin = &m_Pixels[(x + y * m_Size.x) * GetBytesPerPixel(m_Format)];
    00101         std::copy(pBegin, pBegin + GetBytesPerPixel(m_Format), pPix);
    00102     }
    00103
    00104     //-----------------------------------------------------------------------
    00105     CColor CImage::GetPixel(int x, int y) const
    00106     {
    00107         uchar Components[4];
    00108         const uchar* pPix = &m_Pixels[(x + y * m_Size.x) * GetBytesPerPixel(m_Format)];
    00109         ConvertPixel(m_Format, pPix, PXF_A8R8G8B8, Components);
    00110
    00111         return CColor(Components[2], Components[1], Components[0], Components[3]);
    00112     }
    00113
    00114     //-----------------------------------------------------------------------
    00115     void CImage::CopyImage(const CImage& Src)
    00116     {
    00117         // If the dimensions are not the same we make a filtering, otherwise we make a simple copy
    00118         if (m_Size == Src.m_Size)
    00119         {
    00120             // If the sizes are the same we copy simply pixels, otherwise we make a conversion
    00121             if (m_Format == Src.m_Format)
    00122             {
    00123                 m_Pixels = Src.m_Pixels;
    00124             }
    00125             else
    00126             {
    00127                 // Recovery of the parameters for the copy (pointer on pixels and bpps)
    00128                 const uchar* pSrcPix  = &Src.m_Pixels[0];
    00129                 uchar*       pDestPix = &m_Pixels[0];
    00130                 uint         SrcBpp  = GetBytesPerPixel(Src.m_Format);
    00131                 uint         DestBpp = GetBytesPerPixel(m_Format);
    00132
    00133                 // For each pixels of the image source, conversion / copy in the current image
    00134                 for (int i = 0; i < m_Size.x; ++i)
    00135                     for (int j = 0; j < m_Size.y; ++j)
    00136                     {
    00137                         ConvertPixel(Src.m_Format, pSrcPix, m_Format, pDestPix);
    00138                         pSrcPix  += SrcBpp;
    00139                         pDestPix += DestBpp;
    00140                     }
    00141             }
    00142         }
    00143         else
    00144         {
    00145             // Calculation of the step of progress in the image source
    00146             TVector2F Step(static_cast<float>(Src.m_Size.x) / m_Size.x, static_cast<float>(Src.m_Size.y) / m_Size.y);
    00147
    00148             // If the formats are the same we copy simply pixels, otherwise we make a conversion
    00149             if (m_Format == Src.m_Format)
    00150             {
    00151                 // Copy of the pixels
    00152                 uchar Pixel[16];
    00153                 for (int i = 0; i < m_Size.x; ++i)
    00154                     for (int j = 0; j < m_Size.y; ++j)
    00155                     {
    00156                         Src.GetPixel(static_cast<int>(i * Step.x), static_cast<int>(j * Step.y), Pixel);
    00157                         SetPixel(i, j, Pixel);
    00158                     }
    00159             }
    00160             else
    00161             {
    00162                 // For each pixels of the image source, conversion / copy in the current image
    00163                 uchar SrcPix[16], DestPix[16];
    00164                 for (int i = 0; i < m_Size.x; ++i)
    00165                     for (int j = 0; j < m_Size.y; ++j)
    00166                     {
    00167                         Src.GetPixel(static_cast<int>(i * Step.x), static_cast<int>(j * Step.y), SrcPix);
    00168                         ConvertPixel(Src.m_Format, SrcPix, m_Format, DestPix);
    00169                         SetPixel(i, j, DestPix);
    00170                     }
    00171             }
    00172         }
    00173     }
    00174
    00175     //-----------------------------------------------------------------------
    00176     CImage CImage::SubImage(const CRectangle& Rect) const
    00177     {
    00178         Assert(CRectangle(0, 0, m_Size.x, m_Size.y).Intersects(Rect) == INT_IN);
    00179
    00180         CImage Img(TVector2I(Rect.Width(), Rect.Height()), m_Format);
    00181
    00182         const uchar* pSrc       = &m_Pixels[(Rect.Left() + Rect.Top() * m_Size.x) * GetBytesPerPixel(m_Format)];
    00183         uchar*       pDest      = &Img.m_Pixels[0];
    00184         const uint   SrcPitch  = m_Size.x * GetBytesPerPixel(m_Format);
    00185         const uint   DestPitch = Img.m_Size.x * GetBytesPerPixel(Img.m_Format);
    00186
    00187         for (int i = Rect.Left(); i < Rect.Right(); ++i)
    00188         {
    00189             std::copy(pSrc, pSrc + DestPitch, pDest);
    00190             pSrc  += SrcPitch;
    00191             pDest += DestPitch;
    00192         }
    00193
    00194         return Img;
    00195     }
    00196
    00197     //-----------------------------------------------------------------------
    00198     void CImage::Flip()
    00199     {
    00200         int Bpp = GetBytesPerPixel(m_Format);
    00201
    00202         for (int j = 0; j < m_Size.y / 2; ++j)
    00203         {
    00204             std::swap_ranges(&m_Pixels[j * m_Size.x * Bpp],
    00205                             &m_Pixels[(j + 1) * m_Size.x * Bpp - 1],
    00206                             &m_Pixels[(m_Size.y - j - 1) * m_Size.x * Bpp]);
    00207         }
    00208     }
    00209
    00210     //-----------------------------------------------------------------------
    00211     void CImage::Mirror()
    00212     {
    00213         int Bpp = GetBytesPerPixel(m_Format);
    00214
    00215         for (int i = 0; i < m_Size.x / 2; ++i)
    00216             for (int j = 0; j < m_Size.y; ++j)
    00217             {
    00218                 std::swap_ranges(&m_Pixels[(i + j * m_Size.x) * Bpp],
    00219                                 &m_Pixels[(i + j * m_Size.x + 1) * Bpp],
    00220                                 &m_Pixels[(m_Size.x - i - 1 + j * m_Size.x) * Bpp]);
    00221             }
    00222     }
    00223
    00224 } // namespace Keos