00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SP_VIDEO_IMAGEBUFFER_CONTAINER_H__
00009 #define __SP_VIDEO_IMAGEBUFFER_CONTAINER_H__
00010
00011
00012 #include "Base/spStandard.hpp"
00013 #include "Base/spImageBuffer.hpp"
00014
00015
00016 namespace sp
00017 {
00018 namespace video
00019 {
00020
00021
00022 template <typename T, s32 DefVal> class ImageBufferContainer : public ImageBuffer
00023 {
00024
00025 public:
00026
00027 virtual ~ImageBufferContainer()
00028 {
00029 deleteBuffer();
00030 }
00031
00032
00033
00034 bool setFormat(const EPixelFormats Format)
00035 {
00036 if (Format_ == Format)
00037 return false;
00038
00039 const u32 NewFormatSize = ImageBuffer::getFormatSize(Format);
00040
00041 if (NewFormatSize == 0)
00042 return false;
00043
00044 Format_ = Format;
00045
00046
00047 if (NewFormatSize != FormatSize_ && Buffer_)
00048 {
00049 ImageConverter::convertImageFormat<T, DefVal>(
00050 Buffer_, getSize().Width, getSize().Height, getFormatSize(), NewFormatSize
00051 );
00052 FormatSize_ = NewFormatSize;
00053 }
00054
00055 return true;
00056 }
00057
00058 void setSize(const dim::size2di &Size)
00059 {
00060 if (Size.Width > 0 && Size.Height > 0 && Size_ != Size)
00061 {
00062 if (Buffer_)
00063 {
00064 ImageConverter::scaleImage<T>(
00065 Buffer_, getSize().Width, getSize().Height * getDepth(),
00066 Size.Width, Size.Height * getDepth(), getFormatSize()
00067 );
00068 }
00069 Size_ = Size;
00070 }
00071 }
00072
00073 bool setDepth(u32 Depth)
00074 {
00075 if (Depth_ == Depth)
00076 return true;
00077
00078 if (Depth >= 1 && getSize().Height % Depth == 0)
00079 {
00080 Size_.Height *= Depth_;
00081 Depth_ = Depth;
00082 Size_.Height /= Depth_;
00083 return true;
00084 }
00085
00086 #ifdef SP_DEBUGMODE
00087 io::Log::debug("ImageBufferContainer::setDepth", "Setting image buffer depth failed");
00088 #endif
00089
00090 return false;
00091 }
00092
00093 void invertColors()
00094 {
00095 ImageConverter::invertImageColors<T, DefVal>(Buffer_, getPixelCount() * getFormatSize());
00096 }
00097 void flipColors()
00098 {
00099 ImageConverter::flipImageColors<T>(Buffer_, getSize().Width, getSize().Height, getFormatSize());
00100 }
00101 void flipImageHorizontal()
00102 {
00103 ImageConverter::flipImageHorz<T>(Buffer_, getSize().Width, getSize().Height, getFormatSize());
00104 }
00105 void flipImageVertical()
00106 {
00107 ImageConverter::flipImageVert<T>(Buffer_, getSize().Width, getSize().Height, getFormatSize());
00108 }
00109 void turnImage(const EImageTurnDegrees Degree)
00110 {
00111 ImageConverter::turnImage<T>(Buffer_, getSize().Width, getSize().Height, getFormatSize(), Degree);
00112 }
00113
00114 void grayToAlpha()
00115 {
00116 setFormat(PIXELFORMAT_RGBA);
00117 ImageConverter::convertImageGrayToAlpha<T, DefVal>(Buffer_, getSize().Width, getSize().Height);
00118 }
00119
00120 u32 getDataTypeSize() const
00121 {
00122 return sizeof(T);
00123 }
00124
00125 void* getBuffer()
00126 {
00127 return Buffer_;
00128 }
00129 const void* getBuffer() const
00130 {
00131 return Buffer_;
00132 }
00133
00134 bool appendImageBuffer(const ImageBuffer* AdditionalBuffer, bool isAppendBottom = true)
00135 {
00136 if (AdditionalBuffer && AdditionalBuffer->getType() == getType() && AdditionalBuffer->getFormat() == getFormat())
00137 {
00138 const s32 w = AdditionalBuffer->getSize().Width;
00139 const s32 h = AdditionalBuffer->getSize().Height;
00140
00141 const T* AddRawBuffer = static_cast<const ImageBufferContainer<T, DefVal>*>(AdditionalBuffer)->Buffer_;
00142
00143 if (isAppendBottom)
00144 {
00145 if (ImageConverter::appendImageBufferBottom<T>(Buffer_, AddRawBuffer, getSize().Width, getSize().Height, w, h, getFormatSize()))
00146 Size_.Height += h;
00147 }
00148 else
00149 {
00150 if (ImageConverter::appendImageBufferRight<T>(Buffer_, AddRawBuffer, getSize().Width, getSize().Height, w, h, getFormatSize()))
00151 Size_.Width += w;
00152 }
00153
00154 return true;
00155 }
00156 #ifdef SP_DEBUGMODE
00157 else
00158 {
00159 io::Log::debug(
00160 "ImageBufferContainer::appendImageBuffer",
00161 "Appending image buffer with incompatible types and/or pixel formats"
00162 );
00163 }
00164 #endif
00165
00166 return false;
00167 }
00168
00169 virtual void createBuffer(const void* InitBuffer = 0)
00170 {
00171
00172 deleteBuffer();
00173 Buffer_ = MemoryManager::createBuffer<T>(getPixelCount() * getFormatSize(), "ImageBufferContainer::Buffer");
00174
00175
00176 if (InitBuffer)
00177 memcpy(Buffer_, InitBuffer, getBufferSize());
00178 else
00179 memset(Buffer_, 0, getBufferSize());
00180 }
00181
00182 virtual void deleteBuffer()
00183 {
00184 MemoryManager::deleteBuffer(Buffer_);
00185 }
00186
00187 protected:
00188
00189 ImageBufferContainer(const EImageBufferTypes Type) :
00190 ImageBuffer (Type ),
00191 Buffer_ (0 )
00192 {
00193 }
00194 ImageBufferContainer(
00195 const EImageBufferTypes Type, const EPixelFormats Format, const dim::size2di &Size, u32 Depth = 1, const void* InitBuffer = 0) :
00196 ImageBuffer (Type, Format, Size, Depth ),
00197 Buffer_ (0 )
00198 {
00199 createBuffer(InitBuffer);
00200 }
00201
00202
00203
00204 T* Buffer_;
00205
00206 };
00207
00208
00209 }
00210
00211 }
00212
00213
00214 #endif
00215
00216
00217
00218