diff options
Diffstat (limited to 'src/graphics/Bitmap.h')
-rw-r--r-- | src/graphics/Bitmap.h | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/src/graphics/Bitmap.h b/src/graphics/Bitmap.h new file mode 100644 index 0000000..8a46a99 --- /dev/null +++ b/src/graphics/Bitmap.h @@ -0,0 +1,186 @@ +// +// libavg - Media Playback Engine. +// Copyright (C) 2003-2014 Ulrich von Zadow +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Current versions can be found at www.libavg.de +// + +#ifndef _Bitmap_H_ +#define _Bitmap_H_ + +#include "../api.h" +#include "Pixel32.h" +#include "PixelFormat.h" + +#include "../base/Rect.h" +#include "../base/GLMHelper.h" +#include "../base/UTF8String.h" + +#include <boost/shared_ptr.hpp> + +#if defined(__SSE__) || defined(_WIN32) +#include <xmmintrin.h> +#endif + +#include <stdlib.h> +#include <string> +#include <vector> +#include <algorithm> +#include <iostream> + +namespace avg { + +typedef std::vector<int> Histogram; +typedef boost::shared_ptr<Histogram> HistogramPtr; + +class Bitmap; +typedef boost::shared_ptr<Bitmap> BitmapPtr; + +class AVG_API Bitmap +{ +public: + Bitmap(glm::vec2 size, PixelFormat pf, const UTF8String& sName="", int stride=0); + Bitmap(IntPoint size, PixelFormat pf, const UTF8String& sName="", int stride=0); + Bitmap(IntPoint size, PixelFormat pf, unsigned char * pBits, + int stride, bool bCopyBits, const UTF8String& sName=""); + Bitmap(const Bitmap& origBmp); + Bitmap(const Bitmap& origBmp, bool bOwnsBits); + Bitmap(Bitmap& origBmp, const IntRect& rect); + virtual ~Bitmap(); + + Bitmap &operator =(const Bitmap & origBmp); + + // Does pixel format conversion if nessesary. + void copyPixels(const Bitmap& origBmp); + void copyYUVPixels(const Bitmap& yBmp, const Bitmap& uBmp, const Bitmap& vBmp, + bool bJPEG); + void save(const UTF8String& sName); + + IntPoint getSize() const; + int getStride() const; + PixelFormat getPixelFormat() const; + void setPixelFormat(PixelFormat pf); + unsigned char* getPixels(); + const unsigned char* getPixels() const; + std::string getPixelsAsString() const; + void setPixels(const unsigned char* pPixels); + void setPixelsFromString(const std::string& sPixels); + bool ownsBits() const; + const std::string& getName() const; + int getBytesPerPixel() const; + int getLineLen() const; + int getMemNeeded() const; + bool hasAlpha() const; + HistogramPtr getHistogram(int stride = 1) const; + void getMinMax(int stride, int& min, int& max) const; + void setAlpha(const Bitmap& alphaBmp); + + Pixel32 getPythonPixel(const glm::vec2& pos); + template<class PIXEL> + void setPixel(const IntPoint& p, PIXEL color); + template<class PIXEL> + void drawLine(IntPoint p0, IntPoint p1, PIXEL color); + + BitmapPtr subtract(const Bitmap& pOtherBmp); + void blt(const Bitmap& otherBmp, const IntPoint& pos); + float getAvg() const; + float getChannelAvg(int channel) const; + float getStdDev() const; + + bool operator ==(const Bitmap& otherBmp); + void dump(bool bDumpPixels=false) const; + + static int getPreferredStride(int width, PixelFormat pf); + +private: + void initWithData(unsigned char* pBits, int stride, bool bCopyBits); + void allocBits(int stride=0); + void YCbCrtoBGR(const Bitmap& origBmp); + void YCbCrtoI8(const Bitmap& origBmp); + void I8toI16(const Bitmap& origBmp); + void I8toRGB(const Bitmap& origBmp); + void I16toI8(const Bitmap& origBmp); + void BGRtoB5G6R5(const Bitmap& origBmp); + void ByteRGBAtoFloatRGBA(const Bitmap& origBmp); + void FloatRGBAtoByteRGBA(const Bitmap& origBmp); + void BY8toRGBNearest(const Bitmap& origBmp); + void BY8toRGBBilinear(const Bitmap& origBmp); + + IntPoint m_Size; + int m_Stride; + PixelFormat m_PF; + unsigned char* m_pBits; + bool m_bOwnsBits; + UTF8String m_sName; + + static bool s_bMagickInitialized; + static bool s_bGTKInitialized; +}; + +BitmapPtr YCbCr2RGBBitmap(BitmapPtr pYBmp, BitmapPtr pUBmp, BitmapPtr pVBmp); + +template<class PIXEL> +void Bitmap::setPixel(const IntPoint& p, PIXEL color) +{ + *(PIXEL*)(&(m_pBits[p.y*m_Stride+p.x*getBytesPerPixel()])) = color; +} + +// TODO: This is slow, and it clips incorrectly. Replace with external lib? +template<class PIXEL> +void Bitmap::drawLine(IntPoint p0, IntPoint p1, PIXEL color) +{ + IntRect BmpRect(IntPoint(0,0), m_Size); + p0 = BmpRect.cropPoint(p0); + p1 = BmpRect.cropPoint(p1); + + bool bSteep = abs(p1.y - p0.y) > abs(p1.x - p0.x); + if (bSteep) { + std::swap(p0.x, p0.y); + std::swap(p1.x, p1.y); + } + if (p0.x > p1.x) { + std::swap(p0, p1); + } + int deltax = p1.x - p0.x; + int deltay = abs(p1.y - p0.y); + int error = -deltax/2; + int ystep; + int y = p0.y; + if (p0.y < p1.y) { + ystep = 1; + } else { + ystep = -1; + } + for (int x = p0.x; x <= p1.x; x++) { + if (bSteep) { + setPixel(IntPoint(y, x), color); + } else { + setPixel(IntPoint(x, y), color); + } + error += deltay; + if (error > 0) { + y += ystep; + error -= deltax; + } + } +} +#if defined(__SSE__) || defined(_WIN32) +std::ostream& operator<<(std::ostream& os, const __m64 &val); +#endif + +} +#endif |