00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00114 if (m_Size == Src.m_Size)
00115 {
00116
00117 if (m_Format == Src.m_Format)
00118 {
00119 m_Pixels = Src.m_Pixels;
00120 }
00121 else
00122 {
00123
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
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
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
00145 if (m_Format == Src.m_Format)
00146 {
00147
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
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 }