diff options
Diffstat (limited to 'src/graphics/BitmapLoader.cpp')
-rw-r--r-- | src/graphics/BitmapLoader.cpp | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/graphics/BitmapLoader.cpp b/src/graphics/BitmapLoader.cpp new file mode 100644 index 0000000..eeaa5a4 --- /dev/null +++ b/src/graphics/BitmapLoader.cpp @@ -0,0 +1,156 @@ +// +// 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 +// + +#include "BitmapLoader.h" + +#include "PixelFormat.h" +#include "Filterfliprgb.h" + +#include "../base/Exception.h" +#include "../base/ScopeTimer.h" + +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <iostream> + +using namespace std; +using namespace boost; + +namespace avg { + +BitmapLoader * BitmapLoader::s_pBitmapLoader = 0; + +void BitmapLoader::init(bool bBlueFirst) +{ +#if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36) + g_type_init(); +#endif +// cerr << "BitmapLoader::init(" << bBlueFirst << ")" << endl; + if (s_pBitmapLoader != 0) { + delete s_pBitmapLoader; + } + s_pBitmapLoader = new BitmapLoader(bBlueFirst); +} + +BitmapLoader* BitmapLoader::get() +{ + AVG_ASSERT(s_pBitmapLoader != 0); + return s_pBitmapLoader; +} + +BitmapLoader::BitmapLoader(bool bBlueFirst) + : m_bBlueFirst(bBlueFirst) +{ +} + +BitmapLoader::~BitmapLoader() +{ +} + +bool BitmapLoader::isBlueFirst() const +{ + return m_bBlueFirst; +} + +PixelFormat BitmapLoader::getDefaultPixelFormat(bool bAlpha) +{ + if (bAlpha) { + if (m_bBlueFirst) { + return B8G8R8A8; + } else { + return R8G8B8A8; + } + } else { + if (m_bBlueFirst) { + return B8G8R8X8; + } else { + return R8G8B8X8; + } + } +} + +static ProfilingZoneID GDKPixbufProfilingZone("gdk_pixbuf load", true); +static ProfilingZoneID ConvertProfilingZone("Format conversion", true); +static ProfilingZoneID RGBFlipProfilingZone("RGB<->BGR flip", true); + +BitmapPtr BitmapLoader::load(const UTF8String& sFName, PixelFormat pf) const +{ + AVG_ASSERT(s_pBitmapLoader != 0); + GError* pError = 0; + GdkPixbuf* pPixBuf; + { + ScopeTimer timer(GDKPixbufProfilingZone); + pPixBuf = gdk_pixbuf_new_from_file(sFName.c_str(), &pError); + } + if (!pPixBuf) { + string sErr = pError->message; + g_error_free(pError); + throw Exception(AVG_ERR_FILEIO, sErr); + } + IntPoint size = IntPoint(gdk_pixbuf_get_width(pPixBuf), + gdk_pixbuf_get_height(pPixBuf)); + + PixelFormat srcPF; + if (gdk_pixbuf_get_has_alpha(pPixBuf)) { + srcPF = R8G8B8A8; + } else { + srcPF = R8G8B8; + } + if (pf == NO_PIXELFORMAT) { + if (m_bBlueFirst) { + if (srcPF == R8G8B8A8) { + pf = B8G8R8A8; + } else if (srcPF == R8G8B8) { + pf = B8G8R8X8; + } + } else { + if (srcPF == R8G8B8A8) { + pf = R8G8B8A8; + } else if (srcPF == R8G8B8) { + pf = R8G8B8X8; + } + } + } + BitmapPtr pBmp(new Bitmap(size, pf, sFName)); + { + ScopeTimer timer(ConvertProfilingZone); + + int stride = gdk_pixbuf_get_rowstride(pPixBuf); + guchar* pSrc = gdk_pixbuf_get_pixels(pPixBuf); + BitmapPtr pSrcBmp(new Bitmap(size, srcPF, pSrc, stride, false)); + { + ScopeTimer timer(RGBFlipProfilingZone); + if (pixelFormatIsBlueFirst(pf) != pixelFormatIsBlueFirst(srcPF)) { + FilterFlipRGB().applyInPlace(pSrcBmp); + } + } + pBmp->copyPixels(*pSrcBmp); + } + g_object_unref(pPixBuf); + return pBmp; +} + +BitmapPtr loadBitmap(const UTF8String& sFName, PixelFormat pf) +{ + return BitmapLoader::get()->load(sFName, pf); +} + +} + |