Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Toonz core includes
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "tmeshimage.h"
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Qt includes (mutexing classes)
Toshihiro Shimizu 890ddd
#include <qmutex></qmutex>
Toshihiro Shimizu 890ddd
#include <qmutexlocker></qmutexlocker>
Toshihiro Shimizu 890ddd
#include <qreadwritelock></qreadwritelock>
Toshihiro Shimizu 890ddd
#include <qreadlocker></qreadlocker>
Toshihiro Shimizu 890ddd
#include <qwritelocker></qwritelocker>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/imagemanager.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/* EXPLANATION (by Daniele):
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Images / Image Infos retrieval is quite a frequent task throughout Toonz - in
Shinya Kitaoka 120a6e
  particular,
Shinya Kitaoka 120a6e
  as Render operations tend to be multithreaded, it is important to ensure that
Shinya Kitaoka 120a6e
  the
Toshihiro Shimizu 890ddd
  ImageManager treats these operations efficiently.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Most of the image manager's job is that of caching hard-built image data so
Shinya Kitaoka 120a6e
  that successive
Toshihiro Shimizu 890ddd
  queries avoid rebuilding the same images again.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  In a multithreaded environment, we must make sure that multiple threads block
Shinya Kitaoka 120a6e
  each other out
Toshihiro Shimizu 890ddd
  as little as possible.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  Here are the main performance and threading notes:
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    - Image infos are completely cached, while image cachability is
Shinya Kitaoka 120a6e
  user-specified.
Toshihiro Shimizu 890ddd
      This is needed as some images must be loaded only temporarily.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    - One mutex will be used to protect the bindings table. It is the outermost
Shinya Kitaoka 120a6e
  mutex.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    - One mutex (read/write lock) will be used to protect access to EACH
Shinya Kitaoka 120a6e
  individual image.
Shinya Kitaoka 120a6e
      Testing should be required. If file access is found to be too strictly
Shinya Kitaoka 120a6e
  sequential,
Toshihiro Shimizu 890ddd
      perhaps a single mutex could suffice.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    - Having different mutexes to protect images and image infos is currently
Shinya Kitaoka 120a6e
  not implemented,
Toshihiro Shimizu 890ddd
      but could be. Testing required.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
  TODO: TXshSimpleLevel::setFrame(...) usa aggiunte/rimozioni manuali di
Shinya Kitaoka 120a6e
  immagini associate
Shinya Kitaoka 120a6e
  a binding nell'ImageManager - aspettandosi che poiche' l'immagine e' presente
Shinya Kitaoka 120a6e
  in cache,
Toshihiro Shimizu 890ddd
  verra' beccata...
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Image Builder implementation
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DEFINE_CLASS_CODE(ImageBuilder, 100)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ImageBuilder::ImageBuilder()
Shinya Kitaoka 120a6e
    : TSmartObject(m_classCode)
Shinya Kitaoka 120a6e
    , m_imageBuildingLock(QReadWriteLock::Recursive)
Shinya Kitaoka 120a6e
    , m_cached(false)
Shinya Kitaoka 120a6e
    , m_modified(false)
Shinya Kitaoka 120a6e
    , m_imFlags(ImageManager::none) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ImageBuilder::~ImageBuilder() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageBuilder::areInfosCompatible(int imFlags, void *extData) {
Shinya Kitaoka 120a6e
  return m_info.m_valid;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageBuilder::isImageCompatible(int imFlags, void *extData) {
Shinya Kitaoka 120a6e
  return m_info.m_valid;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageBuilder::setImageInfo(TImageInfo &info, const TDimension &size) {
Shinya Kitaoka 120a6e
  info         = TImageInfo();
Shinya Kitaoka 120a6e
  info.m_lx    = size.lx;
Shinya Kitaoka 120a6e
  info.m_ly    = size.ly;
Shinya Kitaoka 120a6e
  info.m_x0    = 0;
Shinya Kitaoka 120a6e
  info.m_y0    = 0;
Shinya Kitaoka 120a6e
  info.m_x1    = size.lx - 1;
Shinya Kitaoka 120a6e
  info.m_y1    = size.ly - 1;
Shinya Kitaoka 120a6e
  info.m_valid = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageBuilder::setImageInfo(TImageInfo &info, TImage *img) {
Shinya Kitaoka 120a6e
  info = TImageInfo();
Shinya Kitaoka 120a6e
  if (TRasterImageP ri = TRasterImageP(img)) {
Shinya Kitaoka 120a6e
    TRasterP ras = ri->getRaster();
Shinya Kitaoka 120a6e
    info.m_lx    = ras->getLx();
Shinya Kitaoka 120a6e
    info.m_ly    = ras->getLy();
Shinya Kitaoka 120a6e
    ri->getDpi(info.m_dpix, info.m_dpiy);
Shinya Kitaoka 120a6e
    TRect savebox = ri->getSavebox();
Shinya Kitaoka 120a6e
    info.m_x0     = savebox.x0;
Shinya Kitaoka 120a6e
    info.m_y0     = savebox.y0;
Shinya Kitaoka 120a6e
    info.m_x1     = savebox.x1;
Shinya Kitaoka 120a6e
    info.m_y1     = savebox.y1;
Shinya Kitaoka 120a6e
  } else if (TToonzImageP ti = TToonzImageP(img)) {
Shinya Kitaoka 120a6e
    TRasterP ras = ti->getRaster();
Shinya Kitaoka 120a6e
    info.m_lx    = ras->getLx();
Shinya Kitaoka 120a6e
    info.m_ly    = ras->getLy();
Shinya Kitaoka 120a6e
    ti->getDpi(info.m_dpix, info.m_dpiy);
Shinya Kitaoka 120a6e
    TRect savebox = ti->getSavebox();
Shinya Kitaoka 120a6e
    info.m_x0     = savebox.x0;
Shinya Kitaoka 120a6e
    info.m_y0     = savebox.y0;
Shinya Kitaoka 120a6e
    info.m_x1     = savebox.x1;
Shinya Kitaoka 120a6e
    info.m_y1     = savebox.y1;
Shinya Kitaoka 120a6e
  } else if (TMeshImageP mi = TMeshImageP(img)) {
Shinya Kitaoka 120a6e
    mi->getDpi(info.m_dpix, info.m_dpiy);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  info.m_valid = true;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageBuilder::setImageInfo(TImageInfo &info, TImageReader *ir) {
Shinya Kitaoka 120a6e
  info = TImageInfo();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const TImageInfo *tmp = ir->getImageInfo();
Shinya Kitaoka 120a6e
  if (tmp) {
Shinya Kitaoka 120a6e
    info = *tmp;
Shinya Kitaoka 120a6e
    if (info.m_x1 < info.m_x0 || info.m_y1 < info.m_y0) {
Shinya Kitaoka 120a6e
      info.m_x0 = info.m_y0 = 0;
Shinya Kitaoka 120a6e
      info.m_x1             = info.m_lx - 1;
Shinya Kitaoka 120a6e
      info.m_y1             = info.m_ly - 1;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    info.m_valid = true;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Image Manager Privates implementation
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct ImageManager::Imp {
Shinya Kitaoka 120a6e
  QReadWriteLock m_tableLock;  //!< Lock for the builders table
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp=""></std::string,>
Shinya Kitaoka 120a6e
      m_builders;  //!< identifier -> ImageBuilder table
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Imp() : m_tableLock(QReadWriteLock::Recursive) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void clear() { m_builders.clear(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Image Manager implementation
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ImageManager::ImageManager() : m_imp(new Imp) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ImageManager::~ImageManager() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ImageManager *ImageManager::instance() {
Shinya Kitaoka 120a6e
  // Re-introdotto possibile baco: voglio controllare se esiste ancora
Shinya Kitaoka 120a6e
  static ImageManager theInstance;
Shinya Kitaoka 120a6e
  return &theInstance;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ImageManager::bind(const std::string &id, ImageBuilder *builderPtr) {
Shinya Kitaoka 120a6e
  if (!builderPtr) {
Shinya Kitaoka 120a6e
    unbind(id);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QWriteLocker locker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ImageBuilderP &builderP = m_imp->m_builders[id];
Shinya Kitaoka 120a6e
  if (builderP && builderP->m_cached) TImageCache::instance()->remove(id);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  builderP = builderPtr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageManager::unbind(const std::string &id) {
Shinya Kitaoka 120a6e
  QWriteLocker locker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_builders.find(id);
Shinya Kitaoka 120a6e
  if (it == m_imp->m_builders.end()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ImageBuilderP &builderP = it->second;
Shinya Kitaoka 120a6e
  if (builderP && builderP->m_cached) TImageCache::instance()->remove(id);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_builders.erase(it);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageManager::isBound(const std::string &id) const {
Shinya Kitaoka 120a6e
  QReadLocker locker(&m_imp->m_tableLock);
Shinya Kitaoka 120a6e
  return m_imp->m_builders.find(id) != m_imp->m_builders.end();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageManager::rebind(const std::string &srcId, const std::string &dstId) {
Shinya Kitaoka 120a6e
  QWriteLocker locker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp="">::iterator st =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_builders.find(srcId);
Shinya Kitaoka 120a6e
  if (st == m_imp->m_builders.end()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ImageBuilderP builder = st->second;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_builders.erase(st);
Shinya Kitaoka 120a6e
  m_imp->m_builders[dstId] = builder;
Toshihiro Shimizu 890ddd
manongjohn 88ffb4
  m_imp->m_builders[dstId]->m_cached   = true;
manongjohn 88ffb4
  m_imp->m_builders[dstId]->m_modified = true;
manongjohn 88ffb4
Shinya Kitaoka 120a6e
  TImageCache::instance()->remap(dstId, srcId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
manongjohn 88ffb4
bool ImageManager::renumber(const std::string &srcId, const TFrameId &fid) {
manongjohn 88ffb4
  std::map<std::string, imagebuilderp="">::iterator st =</std::string,>
manongjohn 88ffb4
      m_imp->m_builders.find(srcId);
manongjohn 88ffb4
  if (st == m_imp->m_builders.end()) return false;
manongjohn 88ffb4
manongjohn 88ffb4
  m_imp->m_builders[srcId]->setFid(fid);
manongjohn 88ffb4
manongjohn 88ffb4
  return true;
manongjohn 88ffb4
}
manongjohn 88ffb4
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ImageManager::clear() {
Shinya Kitaoka 120a6e
  QWriteLocker locker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageCache::instance()->clearSceneImages();
Shinya Kitaoka 120a6e
  m_imp->clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageInfo *ImageManager::getInfo(const std::string &id, int imFlags,
Shinya Kitaoka 120a6e
                                  void *extData) {
Shinya Kitaoka 120a6e
  // Lock for table read and try to find data in the cache
Shinya Kitaoka 120a6e
  QReadLocker tableLocker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_builders.find(id);
Shinya Kitaoka 120a6e
  if (it == m_imp->m_builders.end()) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ImageBuilderP &builder = it->second;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(!((imFlags & ImageManager::toBeModified) && !builder->m_modified));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Check cached data
Shinya Kitaoka 120a6e
  if (builder->areInfosCompatible(imFlags, extData)) return &builder->m_info;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QWriteLocker imageBuildingLocker(&builder->m_imageBuildingLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Re-check as waiting may have changed the situation
Shinya Kitaoka 120a6e
  if (builder->areInfosCompatible(imFlags, extData)) return &builder->m_info;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageInfo info;
Shinya Kitaoka 120a6e
  if (builder->getInfo(info, imFlags, extData)) {
Shinya Kitaoka 120a6e
    builder->m_info = info;
Shinya Kitaoka 120a6e
    return &builder->m_info;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP ImageManager::getImage(const std::string &id, int imFlags,
Shinya Kitaoka 120a6e
                               void *extData) {
Shinya Kitaoka 120a6e
  assert(!((imFlags & ImageManager::toBeModified) &&
Shinya Kitaoka 120a6e
           (imFlags & ImageManager::dontPutInCache)));
Shinya Kitaoka 120a6e
  assert(!((imFlags & ImageManager::toBeModified) &&
Shinya Kitaoka 120a6e
           (imFlags & ImageManager::toBeSaved)));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Lock for table read and try to find data in the cache
Shinya Kitaoka 120a6e
  QReadLocker tableLocker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_builders.find(id);
Shinya Kitaoka 120a6e
  if (it == m_imp->m_builders.end()) return TImageP();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ImageBuilderP &builder = it->second;
Shinya Kitaoka 120a6e
  bool modified          = builder->m_modified;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Analyze imFlags
Shinya Kitaoka 120a6e
  bool _putInCache =
Shinya Kitaoka 120a6e
      TImageCache::instance()->isEnabled() && !(bool)(imFlags & dontPutInCache);
Shinya Kitaoka 120a6e
  bool _toBeModified = (imFlags & toBeModified);
Shinya Kitaoka 120a6e
  bool _toBeSaved    = (imFlags & toBeSaved);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Update the modified flag according to the specified flags
Shinya Kitaoka 120a6e
  if (_toBeModified)
Shinya Kitaoka 120a6e
    builder->m_modified = true;
Shinya Kitaoka 120a6e
  else if (_toBeSaved)
Shinya Kitaoka 120a6e
    builder->m_modified = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Now, fetch the image.
Shinya Kitaoka 120a6e
  TImageP img;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (builder->m_cached) {
Shinya Kitaoka 120a6e
    if (modified || builder->isImageCompatible(imFlags, extData)) {
Shinya Kitaoka 120a6e
      img = TImageCache::instance()->get(id, _toBeModified);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      assert(img);
Shinya Kitaoka 120a6e
      if (img) return img;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Lock for image building
Shinya Kitaoka 120a6e
  QWriteLocker imageBuildingLocker(&builder->m_imageBuildingLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // As multiple threads may block on filesLocker, re-check if the image is now
Shinya Kitaoka 120a6e
  // available
Shinya Kitaoka 120a6e
  if (builder->m_cached) {
Shinya Kitaoka 120a6e
    if (modified || builder->isImageCompatible(imFlags, extData)) {
Shinya Kitaoka 120a6e
      img = TImageCache::instance()->get(id, _toBeModified);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      assert(img);
Shinya Kitaoka 120a6e
      if (img) return img;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // The image was either not available or not conforming to the required
Shinya Kitaoka 120a6e
  // specifications.
Shinya Kitaoka 120a6e
  // We have to build it now, then.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Build the image
Shinya Kitaoka 120a6e
  img = builder->build(imFlags, extData);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (img && _putInCache) {
Shinya Kitaoka 120a6e
    builder->m_cached   = true;
Shinya Kitaoka 120a6e
    builder->m_modified = _toBeModified;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TImageCache::instance()->add(id, img, true);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return img;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
// load icon (and image) data of all frames into cache
Shinya Kitaoka 120a6e
void ImageManager::loadAllTlvIconsAndPutInCache(
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level, std::vector<tframeid> fids,</tframeid>
Shinya Kitaoka 120a6e
    std::vector<std::string> iconIds, bool cacheImagesAsWell) {</std::string>
Shinya Kitaoka 120a6e
  if (fids.empty() || iconIds.empty()) return;
Shinya Kitaoka 120a6e
  // number of fid and iconId should be the same
Shinya Kitaoka 120a6e
  if ((int)fids.size() != (int)iconIds.size()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // obtain ImageLoader with the first fId
Shinya Kitaoka 120a6e
  TImageInfo info;
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_builders.find(level->getImageId(fids[0]));
Shinya Kitaoka 120a6e
  if (it != m_imp->m_builders.end()) {
Shinya Kitaoka 120a6e
    const ImageBuilderP &builder = it->second;
Shinya Kitaoka 120a6e
    assert(builder);
Shinya Kitaoka 120a6e
    assert(builder->getRefCount() > 0);
Shinya Kitaoka 120a6e
luz paz 6454c4
    // this function in reimplemented only in ImageLoader
Shinya Kitaoka 120a6e
    builder->buildAllIconsAndPutInCache(level, fids, iconIds,
Shinya Kitaoka 120a6e
                                        cacheImagesAsWell);
Shinya Kitaoka 120a6e
    builder->getInfo(info, ImageManager::none, 0);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (cacheImagesAsWell) {
Shinya Kitaoka 120a6e
    // reset the savebox
Shinya Kitaoka 120a6e
    info.m_x0 = info.m_y0 = 0;
Shinya Kitaoka 120a6e
    info.m_x1             = info.m_lx - 1;
Shinya Kitaoka 120a6e
    info.m_y1             = info.m_ly - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // put flags to all builders
Shinya Kitaoka 120a6e
    for (int f = 0; f < fids.size(); f++) {
Shinya Kitaoka 120a6e
      std::map<std::string, imagebuilderp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
          m_imp->m_builders.find(level->getImageId(fids[f]));
Shinya Kitaoka 120a6e
      if (it != m_imp->m_builders.end()) {
Shinya Kitaoka 120a6e
        const ImageBuilderP &builder = it->second;
shun-iwasawa 652f5a
        builder->setImageCached();
Shinya Kitaoka 120a6e
        builder->m_info = info;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageManager::invalidate(const std::string &id) {
Shinya Kitaoka 120a6e
  QWriteLocker locker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_builders.find(id);
Shinya Kitaoka 120a6e
  if (it == m_imp->m_builders.end()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ImageBuilderP &builder = it->second;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  builder->invalidate();
Shinya Kitaoka 120a6e
  builder->m_cached = builder->m_modified = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageCache::instance()->remove(id);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageManager::setImage(const std::string &id, const TImageP &img) {
Shinya Kitaoka 120a6e
  if (!img) return invalidate(id);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QWriteLocker locker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_builders.find(id);
Shinya Kitaoka 120a6e
  if (it == m_imp->m_builders.end()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ImageBuilderP &builder = it->second;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  builder->invalidate();  // WARNING: Not all infos are correctly restored
Shinya Kitaoka 120a6e
  ImageBuilder::setImageInfo(
Shinya Kitaoka 120a6e
      builder->m_info,
Shinya Kitaoka 120a6e
      img.getPointer());  // from supplied image - must investigate further...
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageCache::instance()->add(id, img, true);
Shinya Kitaoka 120a6e
  builder->m_cached = builder->m_modified = true;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ImageBuilder *ImageManager::getBuilder(const std::string &id) {
Shinya Kitaoka 120a6e
  QWriteLocker locker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_builders.find(id);
Shinya Kitaoka 120a6e
  return (it == m_imp->m_builders.end()) ? (ImageBuilder *)0
Shinya Kitaoka 120a6e
                                         : it->second.getPointer();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageManager::isCached(const std::string &id) {
Shinya Kitaoka 120a6e
  QWriteLocker locker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_builders.find(id);
Shinya Kitaoka 120a6e
  return (it == m_imp->m_builders.end()) ? false : it->second->m_cached;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ImageManager::isModified(const std::string &id) {
Shinya Kitaoka 120a6e
  QWriteLocker locker(&m_imp->m_tableLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, imagebuilderp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_builders.find(id);
Shinya Kitaoka 120a6e
  return (it == m_imp->m_builders.end()) ? false : it->second->m_modified;
Toshihiro Shimizu 890ddd
}