From dd22bd15f6ed3e5eb5c77ab427029be50fe20148 Mon Sep 17 00:00:00 2001 From: Dimitri John Ledkov Date: Tue, 24 Jun 2014 20:05:13 +0100 Subject: libavg (1.8.1-1) unstable; urgency=medium * New upstream release (Closes: #739664) * Mark libdc1394-22-dev as linux-any build-dependency. * Add libvdpau-dev build-dependency. * Add libavresample-dev build-dependency. # imported from the archive --- src/player/Image.cpp | 399 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 399 insertions(+) create mode 100644 src/player/Image.cpp (limited to 'src/player/Image.cpp') diff --git a/src/player/Image.cpp b/src/player/Image.cpp new file mode 100644 index 0000000..5ac5fb9 --- /dev/null +++ b/src/player/Image.cpp @@ -0,0 +1,399 @@ +// +// 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 "Image.h" + +#include "../base/Logger.h" +#include "../base/Exception.h" +#include "../base/ObjectCounter.h" + +#include "../graphics/Filterfliprgb.h" +#include "../graphics/TextureMover.h" +#include "../graphics/BitmapLoader.h" + +#include "OGLSurface.h" +#include "OffscreenCanvas.h" + +#include +#include + +using namespace std; + +namespace avg { + +Image::Image(OGLSurface * pSurface, const MaterialInfo& material) + : m_sFilename(""), + m_pSurface(pSurface), + m_State(CPU), + m_Source(NONE), + m_Material(material) +{ + ObjectCounter::get()->incRef(&typeid(*this)); + assertValid(); +} + +Image::~Image() +{ + if (m_State == GPU && m_Source != NONE) { + m_pSurface->destroy(); + } + ObjectCounter::get()->decRef(&typeid(*this)); +} + +void Image::moveToGPU() +{ + assertValid(); + if (m_State == CPU) { + switch (m_Source) { + case FILE: + case BITMAP: + setupSurface(); + break; + case SCENE: + m_pSurface->create(B8G8R8X8, m_pCanvas->getTex()); + break; + case NONE: + break; + default: + AVG_ASSERT(false); + } + m_State = GPU; + } + assertValid(); +} + +void Image::moveToCPU() +{ + assertValid(); + if (m_State == GPU) { + switch (m_Source) { + case FILE: + case BITMAP: + m_pBmp = m_pSurface->getTex()->moveTextureToBmp(); + break; + case SCENE: + break; + case NONE: + break; + default: + AVG_ASSERT(false); + return; + } + m_State = CPU; + m_pSurface->destroy(); + } + assertValid(); +} + +void Image::discard() +{ + assertValid(); + setEmpty(); + m_State = CPU; + assertValid(); +} + +void Image::setEmpty() +{ + assertValid(); + if (m_State == GPU) { + m_pSurface->destroy(); + } + changeSource(NONE); + assertValid(); +} + +void Image::setFilename(const std::string& sFilename, TextureCompression comp) +{ + assertValid(); + AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO, "Loading " << sFilename); + BitmapPtr pBmp = loadBitmap(sFilename); + if (comp == TEXTURECOMPRESSION_B5G6R5 && pBmp->hasAlpha()) { + throw Exception(AVG_ERR_UNSUPPORTED, + "B5G6R5-compressed textures with an alpha channel are not supported."); + } + changeSource(FILE); + m_pBmp = pBmp; + + m_sFilename = sFilename; + + switch (comp) { + case TEXTURECOMPRESSION_B5G6R5: + m_pBmp = BitmapPtr(new Bitmap(pBmp->getSize(), B5G6R5, sFilename)); + if (!BitmapLoader::get()->isBlueFirst()) { + FilterFlipRGB().applyInPlace(pBmp); + } + m_pBmp->copyPixels(*pBmp); + break; + case TEXTURECOMPRESSION_NONE: + break; + default: + assert(false); + } + + if (m_State == GPU) { + m_pSurface->destroy(); + setupSurface(); + } + assertValid(); +} + +void Image::setBitmap(BitmapPtr pBmp, TextureCompression comp) +{ + assertValid(); + if (!pBmp) { + throw Exception(AVG_ERR_UNSUPPORTED, "setBitmap(): bitmap must not be None!"); + } + if (comp == TEXTURECOMPRESSION_B5G6R5 && pBmp->hasAlpha()) { + throw Exception(AVG_ERR_UNSUPPORTED, + "B5G6R5-compressed textures with an alpha channel are not supported."); + } + bool bSourceChanged = changeSource(BITMAP); + PixelFormat pf; + switch (comp) { + case TEXTURECOMPRESSION_NONE: + pf = pBmp->getPixelFormat(); + break; + case TEXTURECOMPRESSION_B5G6R5: + pf = B5G6R5; + if (!BitmapLoader::get()->isBlueFirst()) { + FilterFlipRGB().applyInPlace(pBmp); + } + break; + default: + assert(false); + } + if (m_State == GPU) { + GLTexturePtr pTex = m_pSurface->getTex(); + if (bSourceChanged || m_pSurface->getSize() != pBmp->getSize() || + m_pSurface->getPixelFormat() != pf) + { + pTex = GLTexturePtr(new GLTexture(pBmp->getSize(), pf, + m_Material.getUseMipmaps(), 0, m_Material.getWrapSMode(), + m_Material.getWrapTMode())); + m_pSurface->create(pf, pTex); + } + TextureMoverPtr pMover = TextureMover::create(pBmp->getSize(), pf, + GL_STATIC_DRAW); + BitmapPtr pMoverBmp = pMover->lock(); + pMoverBmp->copyPixels(*pBmp); + pMover->unlock(); + pMover->moveToTexture(*pTex); + m_pBmp = BitmapPtr(); + } else { + m_pBmp = BitmapPtr(new Bitmap(pBmp->getSize(), pf, "")); + m_pBmp->copyPixels(*pBmp); + } + assertValid(); +} + +void Image::setCanvas(OffscreenCanvasPtr pCanvas) +{ + assertValid(); + if (m_Source == SCENE && pCanvas == m_pCanvas) { + return; + } + changeSource(SCENE); + m_pCanvas = pCanvas; + if (m_State == GPU) { + m_pSurface->create(B8G8R8X8, m_pCanvas->getTex()); + } + assertValid(); +} + +OffscreenCanvasPtr Image::getCanvas() const +{ + return m_pCanvas; +} + +const string& Image::getFilename() const +{ + return m_sFilename; +} + +BitmapPtr Image::getBitmap() +{ + if (m_Source == NONE) { + return BitmapPtr(); + } else { + switch (m_State) { + case CPU: + if (m_Source == SCENE) { + return BitmapPtr(); + } else { + return BitmapPtr(new Bitmap(*m_pBmp)); + } + case GPU: + return m_pSurface->getTex()->moveTextureToBmp(); + default: + AVG_ASSERT(false); + return BitmapPtr(); + } + } +} + +IntPoint Image::getSize() +{ + if (m_Source == NONE) { + return IntPoint(0,0); + } else { + switch (m_State) { + case CPU: + if (m_Source == SCENE) { + return m_pCanvas->getSize(); + } else { + return m_pBmp->getSize(); + } + case GPU: + return m_pSurface->getSize(); + default: + AVG_ASSERT(false); + return IntPoint(0,0); + } + } +} + +PixelFormat Image::getPixelFormat() +{ + PixelFormat pf; + if (BitmapLoader::get()->isBlueFirst()) { + pf = B8G8R8X8; + } else { + pf = R8G8B8X8; + } + if (m_Source != NONE) { + switch (m_State) { + case CPU: + if (m_Source != SCENE) { + pf = m_pBmp->getPixelFormat(); + } + case GPU: + pf = m_pSurface->getPixelFormat(); + default: + AVG_ASSERT(false); + } + } + return pf; +} + +OGLSurface* Image::getSurface() +{ + AVG_ASSERT(m_State == GPU); + return m_pSurface; +} + +Image::State Image::getState() +{ + return m_State; +} + +Image::Source Image::getSource() +{ + return m_Source; +} + +Image::TextureCompression Image::string2compression(const string& s) +{ + if (s == "none") { + return Image::TEXTURECOMPRESSION_NONE; + } else if (s == "B5G6R5") { + return Image::TEXTURECOMPRESSION_B5G6R5; + } else { + throw(Exception(AVG_ERR_UNSUPPORTED, + "Image compression "+s+" not supported.")); + } +} + +string Image::compression2String(TextureCompression compression) +{ + switch(compression) { + case Image::TEXTURECOMPRESSION_NONE: + return "none"; + case Image::TEXTURECOMPRESSION_B5G6R5: + return "B5G6R5"; + default: + AVG_ASSERT(false); + return 0; + } +} + +void Image::setupSurface() +{ + PixelFormat pf = m_pBmp->getPixelFormat(); +// cerr << "setupSurface: " << pf << endl; + GLTexturePtr pTex(new GLTexture(m_pBmp->getSize(), pf, m_Material.getUseMipmaps(), + 0, m_Material.getWrapSMode(), m_Material.getWrapTMode())); + m_pSurface->create(pf, pTex); + TextureMoverPtr pMover = TextureMover::create(m_pBmp->getSize(), pf, GL_STATIC_DRAW); + pMover->moveBmpToTexture(m_pBmp, *pTex); + m_pBmp = BitmapPtr(); +} + +bool Image::changeSource(Source newSource) +{ + if (newSource != m_Source) { + switch (m_Source) { + case NONE: + break; + case FILE: + case BITMAP: + if (m_State == CPU) { + m_pBmp = BitmapPtr(); + } + m_sFilename = ""; + break; + case SCENE: + m_pCanvas = OffscreenCanvasPtr(); + break; + default: + AVG_ASSERT(false); + } + m_Source = newSource; + return true; + } else { + return false; + } +} + +void Image::assertValid() const +{ + AVG_ASSERT(m_pSurface); + AVG_ASSERT((m_Source == FILE) == (m_sFilename != "")); + AVG_ASSERT((m_Source == SCENE) == bool(m_pCanvas)); + switch (m_State) { + case CPU: + AVG_ASSERT((m_Source == FILE || m_Source == BITMAP) == bool(m_pBmp)); + AVG_ASSERT(!(m_pSurface->isCreated())); + break; + case GPU: + AVG_ASSERT(!m_pBmp); + if (m_Source != NONE) { + AVG_ASSERT(m_pSurface->isCreated()); + } else { + AVG_ASSERT(!m_pSurface->isCreated()); + } + break; + default: + AVG_ASSERT(false); + } +} + +} -- cgit v1.2.3