Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef _DEBUG
Toshihiro Shimizu 890ddd
#undef _STLP_DEBUG
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define _STLP_DEBUG 1
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
#ifdef _DEBUGTOONZ
Toshihiro Shimizu 890ddd
#undef _DEBUGTOONZ
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Toshihiro Shimizu 890ddd
#define _DEBUGTOONZ _DEBUG
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "trastercm.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcodec.h"
Toshihiro Shimizu 890ddd
#include "tfilepath_io.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "traster.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
#include "tbigmemorymanager.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
#include <deque></deque>
Toshihiro Shimizu 890ddd
#include <numeric></numeric>
Toshihiro Shimizu 890ddd
#include <sstream></sstream>
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#include <crtdbg.h></crtdbg.h>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qthreadstorage></qthreadstorage>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef DVAPI
Toshihiro Shimizu 890ddd
#undef DVVAR
Toshihiro Shimizu 890ddd
#ifdef TSYSTEM_EXPORTS
Toshihiro Shimizu 890ddd
#define DVAPI DV_EXPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_EXPORT_VAR
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define DVAPI DV_IMPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_IMPORT_VAR
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class ImageBuilder;
Toshihiro Shimizu 890ddd
class ImageInfo;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// std::ofstream os("C:\\cache.txt");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TUINT32 HistoryCount = 0;
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class TheCodec final : public TRasterCodecLz4 {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static TheCodec *instance() {
Shinya Kitaoka 120a6e
    if (!_instance) _instance = new TheCodec();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    return _instance;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void reset() {
Shinya Kitaoka 120a6e
    if (_instance) _instance->TRasterCodecLz4::reset();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  static TheCodec *_instance;
Shinya Kitaoka 120a6e
  TheCodec() : TRasterCodecLz4("Lz4_Codec", false) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TheCodec *TheCodec::_instance = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class CacheItem : public TSmartObject {
Shinya Kitaoka 120a6e
  DECLARE_CLASS_CODE
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CacheItem()
Shinya Kitaoka 120a6e
      : m_cantCompress(false)
Shinya Kitaoka 120a6e
      , m_builder(0)
Shinya Kitaoka 120a6e
      , m_imageInfo(0)
Shinya Kitaoka 120a6e
      , m_modified(false) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CacheItem(ImageBuilder *builder, ImageInfo *imageInfo)
Shinya Kitaoka 120a6e
      : m_cantCompress(false)
Shinya Kitaoka 120a6e
      , m_builder(builder)
Shinya Kitaoka 120a6e
      , m_imageInfo(imageInfo)
Shinya Kitaoka 120a6e
      , m_historyCount(0)
Shinya Kitaoka 120a6e
      , m_modified(false) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  virtual ~CacheItem() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  virtual TUINT32 getSize() const = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // getImage restituisce un'immagine non compressa
Shinya Kitaoka 120a6e
  virtual TImageP getImage() const = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool m_cantCompress;
Shinya Kitaoka 120a6e
  ImageBuilder *m_builder;
Shinya Kitaoka 120a6e
  ImageInfo *m_imageInfo;
Shinya Kitaoka 120a6e
  std::string m_id;
Shinya Kitaoka 120a6e
  TUINT32 m_historyCount;
Shinya Kitaoka 120a6e
  bool m_modified;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DVAPI TSmartPointerT<cacheitem>;</cacheitem>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
typedef TSmartPointerT<cacheitem> CacheItemP;</cacheitem>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DEFINE_CLASS_CODE(CacheItem, 101)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class ImageInfo {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TDimension m_size;
Shinya Kitaoka 120a6e
  ImageInfo(const TDimension &size) : m_size(size) {}
Shinya Kitaoka 120a6e
  virtual ~ImageInfo() {}
Shinya Kitaoka 120a6e
  virtual ImageInfo *clone() = 0;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class ImageBuilder {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  virtual ~ImageBuilder() {}
Shinya Kitaoka 120a6e
  virtual ImageBuilder *clone() = 0;
Shinya Kitaoka 120a6e
  virtual TImageP build(ImageInfo *info, const TRasterP &ras) = 0;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RasterImageInfo final : public ImageInfo {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RasterImageInfo(const TRasterImageP &ri);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void setInfo(const TRasterImageP &ri);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  ImageInfo *clone() override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double m_dpix, m_dpiy;
Shinya Kitaoka 120a6e
  std::string m_name;
Shinya Kitaoka 120a6e
  TRect m_savebox;
Shinya Kitaoka 120a6e
  bool m_isOpaque;
Shinya Kitaoka 120a6e
  TPoint m_offset;
Shinya Kitaoka 120a6e
  int m_subs;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
RasterImageInfo::RasterImageInfo(const TRasterImageP &ri)
Shinya Kitaoka 120a6e
    : ImageInfo(ri->getRaster()->getSize()) {
Shinya Kitaoka 120a6e
  ri->getDpi(m_dpix, m_dpiy);
Shinya Kitaoka 120a6e
  m_name     = ri->getName();
Shinya Kitaoka 120a6e
  m_savebox  = ri->getSavebox();
Shinya Kitaoka 120a6e
  m_isOpaque = ri->isOpaque();
Shinya Kitaoka 120a6e
  m_offset   = ri->getOffset();
Shinya Kitaoka 120a6e
  m_subs     = ri->getSubsampling();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RasterImageInfo::setInfo(const TRasterImageP &ri) {
Shinya Kitaoka 120a6e
  ri->setDpi(m_dpix, m_dpiy);
Shinya Kitaoka 120a6e
  ri->setName(m_name);
Shinya Kitaoka 120a6e
  ri->setSavebox(m_savebox);
Shinya Kitaoka 120a6e
  ri->setOpaqueFlag(m_isOpaque);
Shinya Kitaoka 120a6e
  ri->setOffset(m_offset);
Shinya Kitaoka 120a6e
  ri->setSubsampling(m_subs);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ImageInfo *RasterImageInfo::clone() { return new RasterImageInfo(*this); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class ToonzImageInfo final : public ImageInfo {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ToonzImageInfo(const TToonzImageP &ti);
Shinya Kitaoka 120a6e
  ~ToonzImageInfo() {
Shinya Kitaoka 120a6e
    if (m_palette) m_palette->release();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  ImageInfo *clone() override {
Shinya Kitaoka 120a6e
    ToonzImageInfo *ret = new ToonzImageInfo(*this);
Shinya Kitaoka 120a6e
    if (ret->m_palette) ret->m_palette->addRef();
Shinya Kitaoka 120a6e
    return ret;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setInfo(const TToonzImageP &ti);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double m_dpix, m_dpiy;
Shinya Kitaoka 120a6e
  std::string m_name;
Shinya Kitaoka 120a6e
  TRect m_savebox;
Shinya Kitaoka 120a6e
  TPoint m_offset;
Shinya Kitaoka 120a6e
  int m_subs;
Shinya Kitaoka 120a6e
  TPalette *m_palette;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToonzImageInfo::ToonzImageInfo(const TToonzImageP &ti)
Shinya Kitaoka 120a6e
    : ImageInfo(ti->getSize()) {
Shinya Kitaoka 120a6e
  m_palette = ti->getPalette();
Shinya Kitaoka 120a6e
  if (m_palette) m_palette->addRef();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ti->getDpi(m_dpix, m_dpiy);
Shinya Kitaoka 120a6e
  m_savebox = ti->getSavebox();
Shinya Kitaoka 120a6e
  m_offset  = ti->getOffset();
Shinya Kitaoka 120a6e
  m_subs    = ti->getSubsampling();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToonzImageInfo::setInfo(const TToonzImageP &ti) {
Shinya Kitaoka 120a6e
  ti->setPalette(m_palette);
Shinya Kitaoka 120a6e
  ti->setDpi(m_dpix, m_dpiy);
Shinya Kitaoka 120a6e
  ti->setOffset(m_offset);
Shinya Kitaoka 120a6e
  ti->setSubsampling(m_subs);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RasterImageBuilder final : public ImageBuilder {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 473e70
  ImageBuilder *clone() override { return new RasterImageBuilder(*this); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  TImageP build(ImageInfo *info, const TRasterP &ras) override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP RasterImageBuilder::build(ImageInfo *info, const TRasterP &ras) {
Shinya Kitaoka 120a6e
  RasterImageInfo *riInfo = dynamic_cast<rasterimageinfo *="">(info);</rasterimageinfo>
Shinya Kitaoka 120a6e
  assert(riInfo);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int rcount       = ras->getRefCount();
Shinya Kitaoka 120a6e
  TRasterImageP ri = new TRasterImage();
Toshihiro Shimizu 890ddd
#ifdef _DEBUGTOONZ
Shinya Kitaoka 120a6e
  ras->m_cashed = true;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  ri->setRaster(ras);
Shinya Kitaoka 120a6e
  riInfo->setInfo(ri);
Shinya Kitaoka 120a6e
  assert(ras->getRefCount() > rcount);
Shinya Kitaoka 120a6e
  return ri;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class ToonzImageBuilder final : public ImageBuilder {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 473e70
  ImageBuilder *clone() override { return new ToonzImageBuilder(*this); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  TImageP build(ImageInfo *info, const TRasterP &ras) override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP ToonzImageBuilder::build(ImageInfo *info, const TRasterP &ras) {
Shinya Kitaoka 120a6e
  ToonzImageInfo *tiInfo = dynamic_cast<toonzimageinfo *="">(info);</toonzimageinfo>
Shinya Kitaoka 120a6e
  assert(tiInfo);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P rasCM32 = ras;
Shinya Kitaoka 120a6e
  assert(rasCM32);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P imgRasCM32;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(TRect(tiInfo->m_size).contains(tiInfo->m_savebox));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ras->getSize() != tiInfo->m_size) {
Shinya Kitaoka 120a6e
    TRasterCM32P fullRas(tiInfo->m_size);
Shinya Kitaoka 120a6e
    TRect rectToExtract(tiInfo->m_savebox);
Shinya Kitaoka 120a6e
    TPixelCM32 bgColor;
Shinya Kitaoka 120a6e
    fullRas->fillOutside(tiInfo->m_savebox, bgColor);
Shinya Kitaoka 120a6e
    fullRas->extractT(rectToExtract)->copy(ras);
Shinya Kitaoka 120a6e
    assert(rectToExtract == tiInfo->m_savebox);
Shinya Kitaoka 120a6e
    imgRasCM32 = fullRas;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    imgRasCM32 = rasCM32;
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  imgRasCM32->m_cashed = true;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  TToonzImageP ti = new TToonzImage(imgRasCM32, tiInfo->m_savebox);
Shinya Kitaoka 120a6e
  tiInfo->setInfo(ti);
Shinya Kitaoka 120a6e
  return ti;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class UncompressedOnMemoryCacheItem final : public CacheItem {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  UncompressedOnMemoryCacheItem(const TImageP &image) : m_image(image) {
Shinya Kitaoka 120a6e
    TRasterImageP ri = m_image;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (ri) m_imageInfo = new RasterImageInfo(ri);
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      TToonzImageP ti = m_image;
Shinya Kitaoka 120a6e
      if (ti)
Shinya Kitaoka 120a6e
        m_imageInfo = new ToonzImageInfo(ti);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        m_imageInfo = 0;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_imageInfo = 0;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~UncompressedOnMemoryCacheItem() {
Shinya Kitaoka 120a6e
    if (m_imageInfo) delete m_imageInfo;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  TUINT32 getSize() const override;
Shinya Kitaoka 473e70
  TImageP getImage() const override { return m_image; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageP m_image;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DVAPI TSmartPointerT<uncompressedonmemorycacheitem>;</uncompressedonmemorycacheitem>
Shinya Kitaoka 120a6e
template class DVAPI
Shinya Kitaoka 120a6e
    TDerivedSmartPointerT<uncompressedonmemorycacheitem, cacheitem="">;</uncompressedonmemorycacheitem,>
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
typedef TDerivedSmartPointerT<uncompressedonmemorycacheitem, cacheitem=""></uncompressedonmemorycacheitem,>
Shinya Kitaoka 120a6e
    UncompressedOnMemoryCacheItemP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TUINT32 UncompressedOnMemoryCacheItem::getSize() const {
Shinya Kitaoka 120a6e
  TRasterImageP ri = m_image;
Shinya Kitaoka 120a6e
  if (ri) {
Shinya Kitaoka 120a6e
    TRasterP ras = ri->getRaster();
Shinya Kitaoka 120a6e
    if (ras)
Shinya Kitaoka 120a6e
      return ras->getLy() * ras->getRowSize();
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return 0;
Shinya Kitaoka 120a6e
  } else {
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
    TToonzImageP ti = m_image;
Shinya Kitaoka 120a6e
    if (ti) {
Shinya Kitaoka 120a6e
      TDimension size = ti->getSize();
Shinya Kitaoka 120a6e
      return size.lx * size.ly * sizeof(TPixelCM32);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
#endif
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 d1f6c4
class CompressedOnMemoryCacheItem final : public CacheItem {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CompressedOnMemoryCacheItem(const TImageP &img);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  CompressedOnMemoryCacheItem(const TRasterP &compressedRas,
Shinya Kitaoka 120a6e
                              ImageBuilder *builder, ImageInfo *info);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~CompressedOnMemoryCacheItem();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  TUINT32 getSize() const override;
Shinya Kitaoka 473e70
  TImageP getImage() const override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterP m_compressedRas;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DVAPI TSmartPointerT<compressedonmemorycacheitem>;</compressedonmemorycacheitem>
Shinya Kitaoka 120a6e
template class DVAPI
Shinya Kitaoka 120a6e
    TDerivedSmartPointerT<compressedonmemorycacheitem, cacheitem="">;</compressedonmemorycacheitem,>
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
typedef TDerivedSmartPointerT<compressedonmemorycacheitem, cacheitem=""></compressedonmemorycacheitem,>
Shinya Kitaoka 120a6e
    CompressedOnMemoryCacheItemP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CompressedOnMemoryCacheItem::CompressedOnMemoryCacheItem(const TImageP &img)
Shinya Kitaoka 120a6e
    : m_compressedRas() {
Shinya Kitaoka 120a6e
  TRasterImageP ri = img;
Shinya Kitaoka 120a6e
  if (ri) {
Shinya Kitaoka 120a6e
    m_imageInfo     = new RasterImageInfo(ri);
Shinya Kitaoka 120a6e
    m_builder       = new RasterImageBuilder();
Shinya Kitaoka 120a6e
    TINT32 buffSize = 0;
Shinya Kitaoka 120a6e
    m_compressedRas =
Shinya Kitaoka 120a6e
        TheCodec::instance()->compress(ri->getRaster(), 1, buffSize);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TToonzImageP ti = img;
Shinya Kitaoka 120a6e
    if (ti) {
Shinya Kitaoka 120a6e
      m_imageInfo          = new ToonzImageInfo(ti);
Shinya Kitaoka 120a6e
      m_builder            = new ToonzImageBuilder();
Shinya Kitaoka 120a6e
      TRasterCM32P rasCM32 = ti->getRaster();
Shinya Kitaoka 120a6e
      TINT32 buffSize      = 0;
Shinya Kitaoka 120a6e
      m_compressedRas = TheCodec::instance()->compress(rasCM32, 1, buffSize);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    assert(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CompressedOnMemoryCacheItem::CompressedOnMemoryCacheItem(const TRasterP &ras,
Shinya Kitaoka 120a6e
                                                         ImageBuilder *builder,
Shinya Kitaoka 120a6e
                                                         ImageInfo *info)
Shinya Kitaoka 120a6e
    : CacheItem(builder, info), m_compressedRas(ras) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
CompressedOnMemoryCacheItem::~CompressedOnMemoryCacheItem() {
Shinya Kitaoka 120a6e
  delete m_imageInfo;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TUINT32 CompressedOnMemoryCacheItem::getSize() const {
Shinya Kitaoka 120a6e
  if (m_compressedRas)
Shinya Kitaoka 120a6e
    return m_compressedRas->getLx();
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP CompressedOnMemoryCacheItem::getImage() const {
Shinya Kitaoka 120a6e
  assert(m_compressedRas);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // PER IL MOMENTO DISCRIMINO: DA ELIMINARE
Shinya Kitaoka 120a6e
  TRasterP ras;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TheCodec::instance()->decompress(m_compressedRas, ras);
Toshihiro Shimizu 890ddd
#ifdef _DEBUGTOONZ
Shinya Kitaoka 120a6e
  ras->m_cashed = true;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  ToonzImageBuilder *tibuilder = dynamic_cast<toonzimagebuilder *="">(m_builder);</toonzimagebuilder>
Shinya Kitaoka 120a6e
  if (tibuilder)
Shinya Kitaoka 120a6e
    return tibuilder->build(m_imageInfo, ras);
Shinya Kitaoka 120a6e
  else
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    return m_builder->build(m_imageInfo, ras);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class CompressedOnDiskCacheItem final : public CacheItem {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CompressedOnDiskCacheItem(const TFilePath &fp, const TRasterP &compressedRas,
Shinya Kitaoka 120a6e
                            ImageBuilder *builder, ImageInfo *info);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~CompressedOnDiskCacheItem();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  TUINT32 getSize() const override { return 0; }
Shinya Kitaoka 473e70
  TImageP getImage() const override;
Shinya Kitaoka 120a6e
  TFilePath m_fp;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DVAPI TSmartPointerT<compressedondiskcacheitem>;</compressedondiskcacheitem>
Shinya Kitaoka 120a6e
template class DVAPI
Shinya Kitaoka 120a6e
    TDerivedSmartPointerT<compressedondiskcacheitem, cacheitem="">;</compressedondiskcacheitem,>
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
typedef TDerivedSmartPointerT<compressedondiskcacheitem, cacheitem=""></compressedondiskcacheitem,>
Shinya Kitaoka 120a6e
    CompressedOnDiskCacheItemP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
CompressedOnDiskCacheItem::CompressedOnDiskCacheItem(
Shinya Kitaoka 120a6e
    const TFilePath &fp, const TRasterP &compressedRas, ImageBuilder *builder,
Shinya Kitaoka 120a6e
    ImageInfo *info)
Shinya Kitaoka 120a6e
    : CacheItem(builder, info), m_fp(fp) {
Shinya Kitaoka 120a6e
  compressedRas->lock();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Tofstream oss(m_fp);
Shinya Kitaoka 120a6e
  assert(compressedRas->getLy() == 1 && compressedRas->getPixelSize() == 1);
Shinya Kitaoka 120a6e
  TUINT32 size = compressedRas->getLx();
Shinya Kitaoka 120a6e
  oss.write((char *)&size, sizeof(TUINT32));
Shinya Kitaoka 120a6e
  oss.write((char *)compressedRas->getRawData(), size);
Shinya Kitaoka 120a6e
  assert(!oss.fail());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  compressedRas->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
CompressedOnDiskCacheItem::~CompressedOnDiskCacheItem() {
Shinya Kitaoka 120a6e
  delete m_imageInfo;
Shinya Kitaoka 120a6e
  TSystem::deleteFile(m_fp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP CompressedOnDiskCacheItem::getImage() const {
Shinya Kitaoka 120a6e
  Tifstream is(m_fp);
Shinya Kitaoka 120a6e
  TUINT32 dataSize;
Shinya Kitaoka 120a6e
  is.read((char *)&dataSize, sizeof(TUINT32));
Shinya Kitaoka 120a6e
  TRasterGR8P ras(dataSize, 1);
Shinya Kitaoka 120a6e
  ras->lock();
Shinya Kitaoka 120a6e
  UCHAR *data = ras->getRawData();
Shinya Kitaoka 120a6e
  is.read((char *)data, dataSize);
Shinya Kitaoka 120a6e
  assert(!is.fail());
Shinya Kitaoka 120a6e
  ras->unlock();
Shinya Kitaoka 120a6e
  CompressedOnMemoryCacheItem item(ras, m_builder->clone(),
Shinya Kitaoka 120a6e
                                   m_imageInfo->clone());
Shinya Kitaoka 120a6e
  return item.getImage();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class UncompressedOnDiskCacheItem final : public CacheItem {
Shinya Kitaoka 120a6e
  int m_pixelsize;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  UncompressedOnDiskCacheItem(const TFilePath &fp, const TImageP &img);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~UncompressedOnDiskCacheItem();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  TUINT32 getSize() const override { return 0; }
Shinya Kitaoka 473e70
  TImageP getImage() const override;
Shinya Kitaoka 120a6e
  // TRaster32P getRaster32() const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFilePath m_fp;
Toshihiro Shimizu 890ddd
};
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DVAPI TSmartPointerT<uncompressedondiskcacheitem>;</uncompressedondiskcacheitem>
Shinya Kitaoka 120a6e
template class DVAPI
Shinya Kitaoka 120a6e
    TDerivedSmartPointerT<uncompressedondiskcacheitem, cacheitem="">;</uncompressedondiskcacheitem,>
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
typedef TDerivedSmartPointerT<uncompressedondiskcacheitem, cacheitem=""></uncompressedondiskcacheitem,>
Shinya Kitaoka 120a6e
    UncompressedOnDiskCacheItemP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UncompressedOnDiskCacheItem::UncompressedOnDiskCacheItem(const TFilePath &fp,
Shinya Kitaoka 120a6e
                                                         const TImageP &image)
Shinya Kitaoka 120a6e
    : CacheItem(0, 0), m_fp(fp) {
Shinya Kitaoka 120a6e
  TRasterImageP ri = image;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterP ras;
Shinya Kitaoka 120a6e
  if (ri) {
Shinya Kitaoka 120a6e
    m_imageInfo = new RasterImageInfo(ri);
Shinya Kitaoka 120a6e
    ras         = ri->getRaster();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TToonzImageP ti = image;
Shinya Kitaoka 120a6e
    if (ti) {
Shinya Kitaoka 120a6e
      m_imageInfo = new ToonzImageInfo(ti);
Shinya Kitaoka 120a6e
      ras         = ti->getRaster();
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    assert(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_builder = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int dataSize = ras->getLx() * ras->getLy() * ras->getPixelSize();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int lx      = ras->getLx();
Shinya Kitaoka 120a6e
  int ly      = ras->getLy();
Shinya Kitaoka 120a6e
  int wrap    = ras->getWrap();
Shinya Kitaoka 120a6e
  m_pixelsize = ras->getPixelSize();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Tofstream oss(m_fp);
Shinya Kitaoka 120a6e
  // oss.write((char*)&dataSize, sizeof(TUINT32));
Shinya Kitaoka 120a6e
  // assert(!oss.fail());
Shinya Kitaoka 120a6e
  ras->lock();
Shinya Kitaoka 120a6e
  if (lx == wrap) {
Shinya Kitaoka 120a6e
    oss.write((char *)ras->getRawData(), dataSize);
Shinya Kitaoka 120a6e
    assert(!oss.fail());
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    char *buf = (char *)ras->getRawData();
Shinya Kitaoka 120a6e
    for (int i = 0; i < ly; i++, buf += wrap) {
Shinya Kitaoka 120a6e
      oss.write(buf, lx * m_pixelsize);
Shinya Kitaoka 120a6e
      assert(!oss.fail());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UncompressedOnDiskCacheItem::~UncompressedOnDiskCacheItem() {
Shinya Kitaoka 120a6e
  delete m_imageInfo;
Shinya Kitaoka 120a6e
  TSystem::deleteFile(m_fp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP UncompressedOnDiskCacheItem::getImage() const {
Shinya Kitaoka 120a6e
  Tifstream is(m_fp);
Shinya Kitaoka 120a6e
  TUINT32 dataSize =
Shinya Kitaoka 120a6e
      m_imageInfo->m_size.lx * m_imageInfo->m_size.ly * m_pixelsize;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // is.read((char*)&dataSize, sizeof(TUINT32));
Shinya Kitaoka 120a6e
  // assert(unsigned(m_lx*m_ly*m_pixelsize)==dataSize);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterP ras;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  RasterImageInfo *rii = dynamic_cast<rasterimageinfo *="">(m_imageInfo);</rasterimageinfo>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (rii) {
Shinya Kitaoka 120a6e
    if (m_pixelsize == 4)
Shinya Kitaoka 120a6e
      ras = (TRasterP)(TRaster32P(rii->m_size));
Shinya Kitaoka 120a6e
    else if (m_pixelsize == 8)
Shinya Kitaoka 120a6e
      ras = (TRasterP)(TRaster64P(rii->m_size));
Shinya Kitaoka 120a6e
    else if (m_pixelsize == 1)
Shinya Kitaoka 120a6e
      ras = (TRasterP)(TRasterGR8P(rii->m_size));
Shinya Kitaoka 120a6e
    else if (m_pixelsize == 2)
Shinya Kitaoka 120a6e
      ras = (TRasterP)(TRasterGR16P(rii->m_size));
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
    ras->lock();
Shinya Kitaoka 120a6e
    char *data = (char *)ras->getRawData();
Shinya Kitaoka 120a6e
    is.read(data, dataSize);
Shinya Kitaoka 120a6e
    ras->unlock();
Toshihiro Shimizu 890ddd
#ifdef _DEBUGTOONZ
Shinya Kitaoka 120a6e
    ras->m_cashed = true;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    return RasterImageBuilder().build(m_imageInfo, ras);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    ToonzImageInfo *tii = dynamic_cast<toonzimageinfo *="">(m_imageInfo);</toonzimageinfo>
Shinya Kitaoka 120a6e
    if (tii) {
Shinya Kitaoka 120a6e
      ras = (TRasterP)(TRasterCM32P(tii->m_size));
Shinya Kitaoka 120a6e
      ras->lock();
Shinya Kitaoka 120a6e
      char *data = (char *)ras->getRawData();
Shinya Kitaoka 120a6e
      is.read(data, dataSize);
Shinya Kitaoka 120a6e
      ras->unlock();
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
      ras->m_cashed = true;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return ToonzImageBuilder().build(m_imageInfo, ras);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
      return 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::string TImageCache::getUniqueId(void) {
Shinya Kitaoka 120a6e
  static TAtomicVar count;
Shinya Kitaoka 120a6e
  std::stringstream ss;
Shinya Kitaoka 120a6e
  ss << ++count;
Shinya Kitaoka 120a6e
  return "IMAGECACHEUNIQUEID" + ss.str();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TImageCache::Imp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Imp() : m_rootDir() {
Shinya Kitaoka 120a6e
    // ATTENZIONE: e' molto piu' veloce se si usa memoria fisica
Shinya Kitaoka 120a6e
    // invece che virtuale: la virtuale e' tanta, non c'e' quindi bisogno
Shinya Kitaoka 120a6e
    // di comprimere le immagini, che grandi come sono vengono swappate su disco
Shinya Kitaoka 120a6e
    if (TBigMemoryManager::instance()->isActive()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_reservedMemory = (TINT64)(TSystem::getMemorySize(true) * 0.10);
Shinya Kitaoka 120a6e
    if (m_reservedMemory < 64 * 1024) m_reservedMemory = 64 * 1024;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~Imp() {
Shinya Kitaoka 120a6e
    if (m_rootDir != TFilePath()) TSystem::rmDirTree(m_rootDir);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool inline notEnoughMemory() {
Shinya Kitaoka 120a6e
    if (TBigMemoryManager::instance()->isActive())
Shinya Kitaoka 120a6e
      return TBigMemoryManager::instance()->getAvailableMemoryinKb() <
Shinya Kitaoka 120a6e
             50 * 1024;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return TSystem::memoryShortage();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void doCompress();
Shinya Kitaoka 120a6e
  void doCompress(std::string id);
Shinya Kitaoka 120a6e
  UCHAR *compressAndMalloc(TUINT32 requestedSize);  // compress in the cache
Shinya Kitaoka 120a6e
                                                    // till it can nallocate the
Shinya Kitaoka 120a6e
                                                    // requested memory
Shinya Kitaoka 120a6e
  void outputMap(UINT chunkRequested, std::string filename);
Shinya Kitaoka 120a6e
  void remove(const std::string &id);
Shinya Kitaoka 120a6e
  void remap(const std::string &dstId, const std::string &srcId);
Shinya Kitaoka 120a6e
  TImageP get(const std::string &id, bool toBeModified);
Shinya Kitaoka 120a6e
  void add(const std::string &id, const TImageP &img, bool overwrite);
Shinya Kitaoka 120a6e
  TFilePath m_rootDir;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  QThreadStorage<bool *=""> m_isEnabled;</bool>
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  bool m_isEnabled;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp=""> m_uncompressedItems;</std::string,>
Shinya Kitaoka 120a6e
  std::map<tuint32, std::string=""> m_itemHistory;</tuint32,>
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp=""> m_compressedItems;</std::string,>
Shinya Kitaoka 120a6e
  std::map<void *,="" std::string=""></void>
Shinya Kitaoka 120a6e
      m_itemsByImagePointer;  // items ordered by ImageP.getPointer()
Shinya Kitaoka 120a6e
  std::map<std::string, std::string=""> m_duplicatedItems;  // for duplicated items</std::string,>
Shinya Kitaoka 120a6e
                                                         // (when id1!=id2 but
Shinya Kitaoka 120a6e
                                                         // image1==image2) in
Shinya Kitaoka 120a6e
                                                         // the map: key is dup
Shinya Kitaoka 120a6e
                                                         // id, value is main id
Shinya Kitaoka 120a6e
  // memoria fisica totale della macchina che non puo' essere utilizzata;
Shinya Kitaoka 120a6e
  TINT64 m_reservedMemory;
Shinya Kitaoka 120a6e
  TThread::Mutex m_mutex;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  static int m_fileid;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TImageCache::Imp::m_fileid;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
inline void *getPointer(const TImageP &img) {
Shinya Kitaoka 120a6e
  TRasterImageP rimg = img;
Shinya Kitaoka 120a6e
  if (rimg) return rimg->getRaster().getPointer();
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  TToonzImageP timg = img;
Shinya Kitaoka 120a6e
  if (timg) return timg->getRaster().getPointer();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return img.getPointer();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Returns true or false whether the image or its eventual raster are
Toshihiro Shimizu 890ddd
// referenced by someone other than Toonz cache.
Shinya Kitaoka 120a6e
inline TINT32 hasExternalReferences(const TImageP &img) {
Shinya Kitaoka 120a6e
  int refCount;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TRasterImageP rimg = img;
Shinya Kitaoka 120a6e
    if (rimg) refCount = rimg->getRaster()->getRefCount();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TToonzImageP timg = img;
Shinya Kitaoka 120a6e
    if (timg)
Shinya Kitaoka 120a6e
      refCount = timg->getRaster()->getRefCount() -
Shinya Kitaoka 120a6e
                 1;  //!!! the TToonzImage::getRaster method increments raster
Shinya Kitaoka 38fd86
                     //! refCount!(the TRasterImage::getRaster don't)
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return std::max(refCount, img->getRefCount()) > 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::Imp::doCompress() {
Shinya Kitaoka 120a6e
  // se la memoria usata per mantenere le immagini decompresse e' superiore
Shinya Kitaoka 120a6e
  // a un dato valore, comprimo alcune immagini non compresse non checked-out
Shinya Kitaoka 120a6e
  // in modo da liberare memoria
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // per il momento scorre tutte le immagini alla ricerca di immagini
Shinya Kitaoka 120a6e
  // non compresse non checked-out
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_mutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<tuint32, std::string="">::iterator itu = m_itemHistory.begin();</tuint32,>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (; itu != m_itemHistory.end() && notEnoughMemory();) {
Shinya Kitaoka 120a6e
    std::map<std::string, cacheitemp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
        m_uncompressedItems.find(itu->second);
Shinya Kitaoka 120a6e
    assert(it != m_uncompressedItems.end());
Shinya Kitaoka 120a6e
    CacheItemP item = it->second;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    UncompressedOnMemoryCacheItemP uitem = item;
Shinya Kitaoka 120a6e
    if (item->m_cantCompress ||
Shinya Kitaoka 120a6e
        (uitem && (!uitem->m_image || hasExternalReferences(uitem->m_image)))) {
Shinya Kitaoka 120a6e
      ++itu;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    std::string id = it->first;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
    assert(itu->first == it->second->m_historyCount);
Shinya Kitaoka 120a6e
    itu = m_itemHistory.erase(itu);
Shinya Kitaoka 120a6e
    m_itemsByImagePointer.erase(getPointer(item->getImage()));
Shinya Kitaoka 120a6e
    m_uncompressedItems.erase(it);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    std::map<tuint32, std::string="">::iterator itu2 = itu;</tuint32,>
Shinya Kitaoka 120a6e
    itu++;
Shinya Kitaoka 120a6e
    m_itemHistory.erase(itu2);
Shinya Kitaoka 120a6e
    m_itemsByImagePointer.erase(item->getImage().getPointer());
Shinya Kitaoka 120a6e
    m_uncompressedItems.erase(it);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (m_compressedItems.find(id) == m_compressedItems.end()) {
Shinya Kitaoka 120a6e
      assert(uitem);
Shinya Kitaoka 120a6e
      item->m_cantCompress = true;
Shinya Kitaoka 120a6e
      CacheItemP newItem   = new CompressedOnMemoryCacheItem(
Shinya Kitaoka 120a6e
          item->getImage());  // WARNING the codec buffer  allocation can CHANGE
Shinya Kitaoka 120a6e
                              // the cache.
Shinya Kitaoka 120a6e
      item->m_cantCompress = false;
Shinya Kitaoka 120a6e
      if (newItem->getSize() ==
Shinya Kitaoka 120a6e
          0)  /// non c'era memoria sufficiente per il buffer compresso....
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        assert(m_rootDir != TFilePath());
Shinya Kitaoka 120a6e
        TFilePath fp =
Shinya Kitaoka 120a6e
            m_rootDir + TFilePath(std::to_string(TImageCache::Imp::m_fileid++));
Shinya Kitaoka 120a6e
        newItem = new UncompressedOnDiskCacheItem(fp, item->getImage());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      m_compressedItems[id] = newItem;
Shinya Kitaoka 120a6e
      item                  = CacheItemP();
Shinya Kitaoka 120a6e
      uitem                 = UncompressedOnMemoryCacheItemP();
Shinya Kitaoka 120a6e
      // doCompress();//restart, since interators can have been changed (see
Shinya Kitaoka 120a6e
      // comment above)
Shinya Kitaoka 120a6e
      // return;
Shinya Kitaoka 120a6e
      itu = m_itemHistory.begin();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // se il quantitativo di memoria utilizzata e' superiore a un dato valore,
Shinya Kitaoka 120a6e
  // sposto
Shinya Kitaoka 120a6e
  // su disco alcune immagini compresse in modo da liberare memoria
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (itu != m_itemHistory.end())  // memory is enough!
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itc = m_compressedItems.begin();</std::string,>
Shinya Kitaoka 120a6e
  for (; itc != m_compressedItems.end() && notEnoughMemory(); ++itc) {
Shinya Kitaoka 120a6e
    CacheItemP item = itc->second;
Shinya Kitaoka 120a6e
    if (item->m_cantCompress) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    CompressedOnMemoryCacheItemP citem = itc->second;
Shinya Kitaoka 120a6e
    if (citem) {
Shinya Kitaoka 120a6e
      assert(m_rootDir != TFilePath());
Shinya Kitaoka 120a6e
      TFilePath fp =
Shinya Kitaoka 120a6e
          m_rootDir + TFilePath(std::to_string(TImageCache::Imp::m_fileid++));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      CacheItemP newItem = new CompressedOnDiskCacheItem(
Shinya Kitaoka 120a6e
          fp, citem->m_compressedRas, citem->m_builder->clone(),
Shinya Kitaoka 120a6e
          citem->m_imageInfo->clone());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      itc->second                   = 0;
Shinya Kitaoka 120a6e
      m_compressedItems[itc->first] = newItem;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::Imp::doCompress(std::string id) {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_mutex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // search id in m_uncompressedItems
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it = m_uncompressedItems.find(id);</std::string,>
Shinya Kitaoka 120a6e
  if (it == m_uncompressedItems.end()) return;  // id not found: return
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // is item suitable for compression ?
Shinya Kitaoka 120a6e
  CacheItemP item                      = it->second;
Shinya Kitaoka 120a6e
  UncompressedOnMemoryCacheItemP uitem = item;
Shinya Kitaoka 120a6e
  if (item->m_cantCompress ||
Shinya Kitaoka 120a6e
      (uitem && (!uitem->m_image || hasExternalReferences(uitem->m_image))))
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // search id in m_itemHistory
Shinya Kitaoka 120a6e
  std::map<tuint32, std::string="">::iterator itu = m_itemHistory.begin();</tuint32,>
Shinya Kitaoka 120a6e
  while (itu != m_itemHistory.end() && itu->second != id) ++itu;
Shinya Kitaoka 120a6e
  if (itu == m_itemHistory.end()) return;  // id not found: return
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// delete itu from m_itemHistory
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  assert(itu->first == it->second->m_historyCount);
Shinya Kitaoka 120a6e
  itu = m_itemHistory.erase(itu);
Shinya Kitaoka 120a6e
  m_itemsByImagePointer.erase(getPointer(item->getImage()));
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  std::map<tuint32, std::string="">::iterator itu2 = itu;</tuint32,>
Shinya Kitaoka 120a6e
  itu++;
Shinya Kitaoka 120a6e
  m_itemHistory.erase(itu2);
Shinya Kitaoka 120a6e
  m_itemsByImagePointer.erase(item->getImage().getPointer());
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // delete item from m_uncompressedItems
Shinya Kitaoka 120a6e
  m_uncompressedItems.erase(it);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // check if item has been already compressed. this should never happen
Shinya Kitaoka 120a6e
  if (m_compressedItems.find(id) != m_compressedItems.end()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(uitem);
Shinya Kitaoka 120a6e
  item->m_cantCompress = true;  // ??
Shinya Kitaoka 120a6e
  CacheItemP newItem   = new CompressedOnMemoryCacheItem(
Shinya Kitaoka 120a6e
      item->getImage());  // WARNING the codec buffer  allocation can CHANGE the
Shinya Kitaoka 120a6e
                          // cache.
Shinya Kitaoka 120a6e
  item->m_cantCompress = false;  // ??
Shinya Kitaoka 120a6e
  if (newItem->getSize() ==
Shinya Kitaoka 120a6e
      0)  /// non c'era memoria sufficiente per il buffer compresso....
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    assert(m_rootDir != TFilePath());
Shinya Kitaoka 120a6e
    TFilePath fp =
Shinya Kitaoka 120a6e
        m_rootDir + TFilePath(std::to_string(TImageCache::Imp::m_fileid++));
Shinya Kitaoka 120a6e
    newItem = new UncompressedOnDiskCacheItem(fp, item->getImage());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_compressedItems[id] = newItem;
Shinya Kitaoka 120a6e
  item                  = CacheItemP();
Shinya Kitaoka 120a6e
  uitem                 = UncompressedOnMemoryCacheItemP();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
  // se il quantitativo di memoria utilizzata e' superiore a un dato valore,
Shinya Kitaoka 120a6e
  sposto
Toshihiro Shimizu 890ddd
  // su disco alcune immagini compresse in modo da liberare memoria
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  if (itu != m_itemHistory.end()) //memory is enough!
Toshihiro Shimizu 890ddd
    return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 3bfa54
  std::map<std::string, cacheitemp="">::iterator itc = m_compressedItems.begin();</std::string,>
Toshihiro Shimizu 890ddd
  for ( ; itc != m_compressedItems.end() && notEnoughMemory(); ++itc)
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          CacheItemP item = itc->second;
Shinya Kitaoka 120a6e
          if (item->m_cantCompress)
Shinya Kitaoka 120a6e
                  continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          CompressedOnMemoryCacheItemP citem = itc->second;
Shinya Kitaoka 120a6e
          if (citem)
Shinya Kitaoka 120a6e
                {
Shinya Kitaoka 120a6e
                  assert(m_rootDir!=TFilePath());
Shinya Kitaoka 120a6e
                  TFilePath fp = m_rootDir +
Shinya Kitaoka 120a6e
  TFilePath(toString(TImageCache::Imp::m_fileid++));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                  CacheItemP newItem = new CompressedOnDiskCacheItem(fp,
Shinya Kitaoka 120a6e
  citem->m_compressedRas,
Shinya Kitaoka 120a6e
                                                                                                                                                                                                                           citem->m_builder->clone(), citem->m_imageInfo->clone());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                  itc->second = 0;
Shinya Kitaoka 120a6e
                  m_compressedItems[itc->first] = newItem;
Shinya Kitaoka 120a6e
                }
Shinya Kitaoka 120a6e
        }
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UCHAR *TImageCache::Imp::compressAndMalloc(TUINT32 size) {
Shinya Kitaoka 120a6e
  UCHAR *buf = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_mutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TheCodec::instance()->reset();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // if (size!=0)
Shinya Kitaoka 120a6e
  //  size = size>>10;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // assert(size==0 || TBigMemoryManager::instance()->isActive());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<tuint32, std::string="">::iterator itu = m_itemHistory.begin();</tuint32,>
Shinya Kitaoka 120a6e
  while (
Shinya Kitaoka 120a6e
      (buf = TBigMemoryManager::instance()->getBuffer(size)) == 0 &&
Shinya Kitaoka 120a6e
      itu !=
Shinya Kitaoka 120a6e
          m_itemHistory
Shinya Kitaoka 120a6e
              .end())  //>TBigMemoryManager::instance()->getAvailableMemoryinKb()))
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    std::map<std::string, cacheitemp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
        m_uncompressedItems.find(itu->second);
Shinya Kitaoka 120a6e
    assert(it != m_uncompressedItems.end());
Shinya Kitaoka 120a6e
    CacheItemP item = it->second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    UncompressedOnMemoryCacheItemP uitem = item;
Shinya Kitaoka 120a6e
    if (item->m_cantCompress ||
Shinya Kitaoka 120a6e
        (uitem && (!uitem->m_image || hasExternalReferences(uitem->m_image)))) {
Shinya Kitaoka 120a6e
      ++itu;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_compressedItems.find(it->first) == m_compressedItems.end()) {
Shinya Kitaoka 120a6e
      assert(uitem);
Shinya Kitaoka 120a6e
      CacheItemP newItem;
Shinya Kitaoka 120a6e
      // newItem = new CompressedOnMemoryCacheItem(item->getImage());
Shinya Kitaoka 120a6e
      // if (newItem->getSize()==0)
Shinya Kitaoka 120a6e
      //  {
Shinya Kitaoka 120a6e
      assert(m_rootDir != TFilePath());
Shinya Kitaoka 120a6e
      TFilePath fp =
Shinya Kitaoka 120a6e
          m_rootDir + TFilePath(std::to_string(TImageCache::Imp::m_fileid++));
Shinya Kitaoka 120a6e
      newItem = new UncompressedOnDiskCacheItem(fp, item->getImage());
Shinya Kitaoka 120a6e
      //  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      m_compressedItems[it->first] = newItem;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
    assert(itu->first == it->second->m_historyCount);
Shinya Kitaoka 120a6e
    itu = m_itemHistory.erase(itu);
Shinya Kitaoka 120a6e
    m_itemsByImagePointer.erase(getPointer(item->getImage()));
Shinya Kitaoka 120a6e
    m_uncompressedItems.erase(it);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    std::map<tuint32, std::string="">::iterator itu2 = itu;</tuint32,>
Shinya Kitaoka 120a6e
    itu++;
Shinya Kitaoka 120a6e
    m_itemHistory.erase(itu2);
Shinya Kitaoka 120a6e
    m_itemsByImagePointer.erase(item->getImage().getPointer());
Shinya Kitaoka 120a6e
    m_uncompressedItems.erase(it);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (buf != 0) return buf;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itc = m_compressedItems.begin();</std::string,>
Shinya Kitaoka 120a6e
  for (; itc != m_compressedItems.end() &&
Shinya Kitaoka 120a6e
         (buf = TBigMemoryManager::instance()->getBuffer(size)) == 0;
Shinya Kitaoka 120a6e
       ++itc) {
Shinya Kitaoka 120a6e
    CacheItemP item = itc->second;
Shinya Kitaoka 120a6e
    if (item->m_cantCompress) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    CompressedOnMemoryCacheItemP citem = itc->second;
Shinya Kitaoka 120a6e
    if (citem) {
Shinya Kitaoka 120a6e
      assert(m_rootDir != TFilePath());
Shinya Kitaoka 120a6e
      TFilePath fp =
Shinya Kitaoka 120a6e
          m_rootDir + TFilePath(std::to_string(TImageCache::Imp::m_fileid++));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      CacheItemP newItem = new CompressedOnDiskCacheItem(
Shinya Kitaoka 120a6e
          fp, citem->m_compressedRas, citem->m_builder->clone(),
Shinya Kitaoka 120a6e
          citem->m_imageInfo->clone());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      itc->second                   = 0;
Shinya Kitaoka 120a6e
      m_compressedItems[itc->first] = newItem;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return buf;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int check       = 0;
Toshihiro Shimizu 890ddd
const int magic = 123456;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static TImageCache *CacheInstance = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageCache *TImageCache::instance() {
Shinya Kitaoka 120a6e
  if (CacheInstance == 0) CacheInstance = new TImageCache();
Shinya Kitaoka 120a6e
  return CacheInstance;
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
if (!ImageCache::m_instance)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
ImageCache::m_instance = new ImageCache;
Shinya Kitaoka 120a6e
ImageCache::m_destroyer.m_imageCache = ImageCache::m_instance;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
return ImageCache::m_instance;
Shinya Kitaoka 120a6e
  */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageCache::TImageCache() : m_imp(new Imp()) {
Shinya Kitaoka 120a6e
  assert(check == 0);
Shinya Kitaoka 120a6e
  check = magic;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageCache::~TImageCache() {
Shinya Kitaoka 120a6e
  assert(check == magic);
Shinya Kitaoka 120a6e
  check         = -1;
Shinya Kitaoka 120a6e
  CacheInstance = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::setEnabled(bool isEnabled) {
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  QThreadStorage<bool *=""> &storage = m_imp->m_isEnabled;</bool>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (storage.hasLocalData() && *(storage.localData()) == isEnabled) return;
Shinya Kitaoka 120a6e
  if (!storage.hasLocalData())
Shinya Kitaoka 120a6e
    storage.setLocalData(new bool(isEnabled));
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    *(storage.localData()) = isEnabled;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  m_imp->m_isEnabled = isEnabled;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TImageCache::isEnabled() {
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  QThreadStorage<bool *=""> &storage = m_imp->m_isEnabled;</bool>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!storage.hasLocalData()) return true;
Shinya Kitaoka 120a6e
  return *(storage.localData());
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  return m_isEnabled;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::setRootDir(const TFilePath &cacheDir) {
Shinya Kitaoka 120a6e
  if (m_imp->m_rootDir != TFilePath()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_rootDir =
Shinya Kitaoka 120a6e
      cacheDir + TFilePath(std::to_string(TSystem::getProcessId()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  TFileStatus fs1(m_imp->m_rootDir);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!fs1.doesExist()) TSystem::mkDir(m_imp->m_rootDir);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
TFilePath TImageCache::getRootDir() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
return m_imp->m_rootDir;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UCHAR *TImageCache::compressAndMalloc(TUINT32 requestedSize) {
Shinya Kitaoka 120a6e
  return m_imp->compressAndMalloc(requestedSize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::add(const std::string &id, const TImageP &img,
Shinya Kitaoka 120a6e
                      bool overwrite) {
Shinya Kitaoka 120a6e
  if (!isEnabled()) return;
Shinya Kitaoka 120a6e
  m_imp->add(id, img, overwrite);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::Imp::add(const std::string &id, const TImageP &img,
Shinya Kitaoka 120a6e
                           bool overwrite) {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef LEVO
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it1 = m_uncompressedItems.begin();</std::string,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; it1 != m_uncompressedItems.end(); ++it1) {
Shinya Kitaoka 120a6e
    UncompressedOnMemoryCacheItemP item =
Shinya Kitaoka 120a6e
        (UncompressedOnMemoryCacheItemP)it1->second;
Shinya Kitaoka 120a6e
    // m_memUsage -= item->getSize();
Shinya Kitaoka 120a6e
    assert(item);
Shinya Kitaoka 120a6e
    TImageP refImg = item->getImage();
Shinya Kitaoka 120a6e
    if (refImg.getPointer() == img.getPointer() && it1->first != id)
Shinya Kitaoka 120a6e
      assert(!"opps gia' esiste in cache!");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itUncompr =</std::string,>
Shinya Kitaoka 120a6e
      m_uncompressedItems.find(id);
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itCompr =</std::string,>
Shinya Kitaoka 120a6e
      m_compressedItems.find(id);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUGTOONZ
Shinya Kitaoka 120a6e
  TRasterImageP rimg = (TRasterImageP)img;
Shinya Kitaoka 120a6e
  TToonzImageP timg  = (TToonzImageP)img;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (itUncompr != m_uncompressedItems.end() ||
Shinya Kitaoka 120a6e
      itCompr !=
Shinya Kitaoka 120a6e
          m_compressedItems.end())  // already present in cache with same id...
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (overwrite) {
Toshihiro Shimizu 890ddd
#ifdef _DEBUGTOONZ
Shinya Kitaoka 120a6e
      if (rimg)
Shinya Kitaoka 120a6e
        rimg->getRaster()->m_cashed = true;
Shinya Kitaoka 120a6e
      else if (timg)
Shinya Kitaoka 120a6e
        timg->getRaster()->m_cashed = true;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
      std::map<std::string, cacheitemp="">::iterator it;</std::string,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (itUncompr != m_uncompressedItems.end()) {
Shinya Kitaoka 120a6e
        assert(m_itemHistory.find(itUncompr->second->m_historyCount) !=
Shinya Kitaoka 120a6e
               m_itemHistory.end());
Shinya Kitaoka 120a6e
        m_itemHistory.erase(itUncompr->second->m_historyCount);
Shinya Kitaoka 120a6e
        m_itemsByImagePointer.erase(getPointer(itUncompr->second->getImage()));
Shinya Kitaoka 120a6e
        m_uncompressedItems.erase(itUncompr);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (itCompr != m_compressedItems.end()) m_compressedItems.erase(id);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    std::map<std::string, std::string="">::iterator dt =</std::string,>
Shinya Kitaoka 120a6e
        m_duplicatedItems.find(id);
Shinya Kitaoka 120a6e
    if ((dt != m_duplicatedItems.end()) && !overwrite) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::map<void *,="" std::string="">::iterator it;</void>
Shinya Kitaoka 120a6e
    if ((it = m_itemsByImagePointer.find(getPointer(img))) !=
Shinya Kitaoka 120a6e
        m_itemsByImagePointer
Shinya Kitaoka 120a6e
            .end())  // already present in cache with another id...
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      m_duplicatedItems[id] = it->second;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (dt != m_duplicatedItems.end()) m_duplicatedItems.erase(dt);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CacheItemP item;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUGTOONZ
Shinya Kitaoka 120a6e
  if (rimg)
Shinya Kitaoka 120a6e
    rimg->getRaster()->m_cashed = true;
Shinya Kitaoka 120a6e
  else if (timg)
Shinya Kitaoka 120a6e
    timg->getRaster()->m_cashed = true;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  item = new UncompressedOnMemoryCacheItem(img);
Toshihiro Shimizu 890ddd
#ifdef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  item->m_cantCompress = false;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  item->m_cantCompress = (TVectorImageP(img) ? true : false);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  item->m_id                             = id;
Shinya Kitaoka 120a6e
  m_uncompressedItems[id]                = item;
Shinya Kitaoka 120a6e
  m_itemsByImagePointer[getPointer(img)] = id;
Shinya Kitaoka 120a6e
  item->m_historyCount                   = HistoryCount;
Shinya Kitaoka 120a6e
  m_itemHistory[HistoryCount]            = id;
Shinya Kitaoka 120a6e
  HistoryCount++;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  doCompress();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUGTOONZ
Shinya Kitaoka 120a6e
// int itemCount =
Shinya Kitaoka 120a6e
// m_imp->m_uncompressedItems.size()+m_imp->m_compressedItems.size();
Shinya Kitaoka 120a6e
// m_imp->outputDebug();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::remove(const std::string &id) { m_imp->remove(id); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::Imp::remove(const std::string &id) {
Shinya Kitaoka 120a6e
  if (CacheInstance == 0)
Shinya Kitaoka 120a6e
    return;  // the remove can be called when exiting from toonz...after the
Shinya Kitaoka 120a6e
             // imagecache was already freed!
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(check == magic);
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_mutex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, std::string="">::iterator it1;</std::string,>
Shinya Kitaoka 120a6e
  if ((it1 = m_duplicatedItems.find(id)) !=
Shinya Kitaoka 120a6e
      m_duplicatedItems.end())  // it's a duplicated id...
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    m_duplicatedItems.erase(it1);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it1 = m_duplicatedItems.begin(); it1 != m_duplicatedItems.end(); ++it1)
Shinya Kitaoka 120a6e
    if (it1->second == id) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (it1 != m_duplicatedItems.end())  // it has duplicated, so cannot erase it;
Shinya Kitaoka 120a6e
                                       // I erase the duplicate, and assign its
Shinya Kitaoka 120a6e
                                       // id has the main id
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    std::string sonId = it1->first;
Shinya Kitaoka 120a6e
    m_duplicatedItems.erase(it1);
Shinya Kitaoka 120a6e
    remap(sonId, id);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it = m_uncompressedItems.find(id);</std::string,>
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itc = m_compressedItems.find(id);</std::string,>
Shinya Kitaoka 120a6e
  if (it != m_uncompressedItems.end()) {
Shinya Kitaoka 120a6e
    const CacheItemP &item = it->second;
Shinya Kitaoka 120a6e
    assert((UncompressedOnMemoryCacheItemP)item);
Shinya Kitaoka 120a6e
    assert(m_itemHistory.find(it->second->m_historyCount) !=
Shinya Kitaoka 120a6e
           m_itemHistory.end());
Shinya Kitaoka 120a6e
    m_itemHistory.erase(it->second->m_historyCount);
Shinya Kitaoka 120a6e
    m_itemsByImagePointer.erase(getPointer(it->second->getImage()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUGTOONZ
Shinya Kitaoka 120a6e
    if ((TRasterImageP)it->second->getImage())
Shinya Kitaoka 120a6e
      ((TRasterImageP)it->second->getImage())->getRaster()->m_cashed = false;
Shinya Kitaoka 120a6e
    else if ((TToonzImageP)it->second->getImage())
Shinya Kitaoka 120a6e
      ((TToonzImageP)it->second->getImage())->getRaster()->m_cashed = false;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_uncompressedItems.erase(it);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (itc != m_compressedItems.end()) m_compressedItems.erase(itc);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::remap(const std::string &dstId, const std::string &srcId) {
Shinya Kitaoka 120a6e
  m_imp->remap(dstId, srcId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::Imp::remap(const std::string &dstId,
Shinya Kitaoka 120a6e
                             const std::string &srcId) {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_mutex);
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_uncompressedItems.find(srcId);
Shinya Kitaoka 120a6e
  if (it != m_uncompressedItems.end()) {
Shinya Kitaoka 120a6e
    CacheItemP citem = it->second;
Shinya Kitaoka 120a6e
    assert(m_itemHistory.find(citem->m_historyCount) != m_itemHistory.end());
Shinya Kitaoka 120a6e
    m_itemHistory.erase(citem->m_historyCount);
Shinya Kitaoka 120a6e
    m_itemsByImagePointer.erase(getPointer(citem->getImage()));
Shinya Kitaoka 120a6e
    m_uncompressedItems.erase(it);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_uncompressedItems[dstId]                           = citem;
Shinya Kitaoka 120a6e
    m_itemHistory[citem->m_historyCount]                 = dstId;
Shinya Kitaoka 120a6e
    m_itemsByImagePointer[getPointer(citem->getImage())] = dstId;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  it = m_compressedItems.find(srcId);
Shinya Kitaoka 120a6e
  if (it != m_compressedItems.end()) {
Shinya Kitaoka 120a6e
    CacheItemP citem = it->second;
Shinya Kitaoka 120a6e
    m_compressedItems.erase(it);
Shinya Kitaoka 120a6e
    m_compressedItems[dstId] = citem;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::map<std::string, std::string="">::iterator it2 =</std::string,>
Shinya Kitaoka 120a6e
      m_duplicatedItems.find(srcId);
Shinya Kitaoka 120a6e
  if (it2 != m_duplicatedItems.end()) {
Shinya Kitaoka 120a6e
    std::string id = it2->second;
Shinya Kitaoka 120a6e
    m_duplicatedItems.erase(it2);
Shinya Kitaoka 120a6e
    m_duplicatedItems[dstId] = id;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (it2 = m_duplicatedItems.begin(); it2 != m_duplicatedItems.end(); ++it2)
Shinya Kitaoka 120a6e
    if (it2->second == srcId) it2->second = dstId;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::remapIcons(const std::string &dstId,
Shinya Kitaoka 120a6e
                             const std::string &srcId) {
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it;</std::string,>
Shinya Kitaoka 120a6e
  std::map<std::string, std::string=""> table;</std::string,>
Shinya Kitaoka 120a6e
  std::string prefix = srcId + ":";
Shinya Kitaoka 120a6e
  int j              = (int)prefix.length();
Shinya Kitaoka 120a6e
  for (it = m_imp->m_uncompressedItems.begin();
Shinya Kitaoka 120a6e
       it != m_imp->m_uncompressedItems.end(); ++it) {
Shinya Kitaoka 120a6e
    std::string id                      = it->first;
Shinya Kitaoka 120a6e
    if (id.find(prefix) == 0) table[id] = dstId + ":" + id.substr(j);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (std::map<std::string, std::string="">::iterator it2 = table.begin();</std::string,>
Shinya Kitaoka 120a6e
       it2 != table.end(); ++it2) {
Shinya Kitaoka 120a6e
    remap(it2->second, it2->first);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::clear(bool deleteFolder) {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_imp->m_mutex);
Shinya Kitaoka 120a6e
  m_imp->m_uncompressedItems.clear();
Shinya Kitaoka 120a6e
  m_imp->m_itemHistory.clear();
Shinya Kitaoka 120a6e
  m_imp->m_compressedItems.clear();
Shinya Kitaoka 120a6e
  m_imp->m_duplicatedItems.clear();
Shinya Kitaoka 120a6e
  m_imp->m_itemsByImagePointer.clear();
Shinya Kitaoka 120a6e
  if (deleteFolder && m_imp->m_rootDir != TFilePath())
Shinya Kitaoka 120a6e
    TSystem::rmDirTree(m_imp->m_rootDir);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::clearSceneImages() {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_imp->m_mutex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // note the ';' - which follows ':' in the ascii table
Shinya Kitaoka 120a6e
  m_imp->m_uncompressedItems.erase(
Shinya Kitaoka 120a6e
      m_imp->m_uncompressedItems.begin(),
Shinya Kitaoka 120a6e
      m_imp->m_uncompressedItems.lower_bound("$:"));
Shinya Kitaoka 120a6e
  m_imp->m_uncompressedItems.erase(m_imp->m_uncompressedItems.lower_bound("$;"),
Shinya Kitaoka 120a6e
                                   m_imp->m_uncompressedItems.end());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_imp->m_compressedItems.erase(m_imp->m_compressedItems.begin(),
Shinya Kitaoka 120a6e
                                 m_imp->m_compressedItems.lower_bound("$:"));
Shinya Kitaoka 120a6e
  m_imp->m_compressedItems.erase(m_imp->m_compressedItems.lower_bound("$;"),
Shinya Kitaoka 120a6e
                                 m_imp->m_compressedItems.end());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_imp->m_duplicatedItems.erase(m_imp->m_duplicatedItems.begin(),
Shinya Kitaoka 120a6e
                                 m_imp->m_duplicatedItems.lower_bound("$:"));
Shinya Kitaoka 120a6e
  m_imp->m_duplicatedItems.erase(m_imp->m_duplicatedItems.lower_bound("$;"),
Shinya Kitaoka 120a6e
                                 m_imp->m_duplicatedItems.end());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Clear maps whose id is on the second of map pairs.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<tuint32, std::string="">::iterator it;</tuint32,>
Shinya Kitaoka 120a6e
  for (it = m_imp->m_itemHistory.begin(); it != m_imp->m_itemHistory.end();) {
Shinya Kitaoka 120a6e
    if (it->second.size() >= 2 && it->second[0] == '$' && it->second[1] == ':')
Shinya Kitaoka 120a6e
      ++it;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      std::map<tuint32, std::string="">::iterator app = it;</tuint32,>
Shinya Kitaoka 120a6e
      app++;
Shinya Kitaoka 120a6e
      m_imp->m_itemHistory.erase(it);
Shinya Kitaoka 120a6e
      it = app;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<void *,="" std::string="">::iterator jt;</void>
Shinya Kitaoka 120a6e
  for (jt = m_imp->m_itemsByImagePointer.begin();
Shinya Kitaoka 120a6e
       jt != m_imp->m_itemsByImagePointer.end();) {
Shinya Kitaoka 120a6e
    if (jt->second.size() >= 2 && jt->second[0] == '$' && jt->second[1] == ':')
Shinya Kitaoka 120a6e
      ++jt;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      std::map<void *,="" std::string="">::iterator app = jt;</void>
Shinya Kitaoka 120a6e
      app++;
Shinya Kitaoka 120a6e
      m_imp->m_itemsByImagePointer.erase(jt);
Shinya Kitaoka 120a6e
      jt = app;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TImageCache::isCached(const std::string &id) const {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_imp->m_mutex);
Shinya Kitaoka 120a6e
  return (m_imp->m_uncompressedItems.find(id) !=
Shinya Kitaoka 120a6e
              m_imp->m_uncompressedItems.end() ||
Shinya Kitaoka 120a6e
          m_imp->m_compressedItems.find(id) != m_imp->m_compressedItems.end() ||
Shinya Kitaoka 120a6e
          m_imp->m_duplicatedItems.find(id) != m_imp->m_duplicatedItems.end());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifdef LEVO
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TImageCache::getSize(const std::string &id, TDimension &size) const {
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_imp->m_mutex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_uncompressedItems.find(id);
Shinya Kitaoka 120a6e
  if (it != m_imp->m_uncompressedItems.end()) {
Shinya Kitaoka 120a6e
    UncompressedOnMemoryCacheItemP uncompressed = it->second;
Shinya Kitaoka 120a6e
    assert(uncompressed);
Shinya Kitaoka 120a6e
    TToonzImageP ti = uncompressed->getImage();
Shinya Kitaoka 120a6e
    if (ti) {
Shinya Kitaoka 120a6e
      size = ti->getSize();
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRasterImageP ri = uncompressed->getImage();
Shinya Kitaoka 120a6e
    if (ri && ri->getRaster()) {
Shinya Kitaoka 120a6e
      size = ri->getRaster()->getSize();
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itc =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_compressedItems.find(id);
Shinya Kitaoka 120a6e
  if (itc == m_imp->m_compressedItems.end()) return false;
Shinya Kitaoka 120a6e
  CacheItemP cacheItem = itc->second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (cacheItem->m_imageInfo) {
Shinya Kitaoka 120a6e
    RasterImageInfo *rimageInfo =
Shinya Kitaoka 120a6e
        dynamic_cast<rasterimageinfo *="">(cacheItem->m_imageInfo);</rasterimageinfo>
Shinya Kitaoka 120a6e
    if (rimageInfo) {
Shinya Kitaoka 120a6e
      size = rimageInfo->m_size;
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ToonzImageInfo *timageInfo =
Shinya Kitaoka 120a6e
        dynamic_cast<toonzimageinfo *="">(cacheItem->m_imageInfo);</toonzimageinfo>
Shinya Kitaoka 120a6e
    if (timageInfo) {
Shinya Kitaoka 120a6e
      size = timageInfo->m_size;
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TImageCache::getSavebox(const std::string &id, TRect &savebox) const {
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_imp->m_mutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_uncompressedItems.find(id);
Shinya Kitaoka 120a6e
  if (it != m_imp->m_uncompressedItems.end()) {
Shinya Kitaoka 120a6e
    UncompressedOnMemoryCacheItemP uncompressed = it->second;
Shinya Kitaoka 120a6e
    assert(uncompressed);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TToonzImageP ti = uncompressed->getImage();
Shinya Kitaoka 120a6e
    if (ti) {
Shinya Kitaoka 120a6e
      savebox = ti->getSavebox();
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TRasterImageP ri = uncompressed->getImage();
Shinya Kitaoka 120a6e
    if (ri) {
Shinya Kitaoka 120a6e
      savebox = ri->getSavebox();
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itc =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_compressedItems.find(id);
Shinya Kitaoka 120a6e
  if (itc == m_imp->m_compressedItems.end()) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CacheItemP cacheItem = itc->second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(cacheItem->m_imageInfo);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  RasterImageInfo *rimageInfo =
Shinya Kitaoka 120a6e
      dynamic_cast<rasterimageinfo *="">(cacheItem->m_imageInfo);</rasterimageinfo>
Shinya Kitaoka 120a6e
  if (rimageInfo) {
Shinya Kitaoka 120a6e
    savebox = rimageInfo->m_savebox;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  ToonzImageInfo *timageInfo =
Shinya Kitaoka 120a6e
      dynamic_cast<toonzimageinfo *="">(cacheItem->m_imageInfo);</toonzimageinfo>
Shinya Kitaoka 120a6e
  if (timageInfo) {
Shinya Kitaoka 120a6e
    savebox = timageInfo->m_savebox;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
#endif
Shinya Kitaoka 120a6e
  return false;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool TImageCache::getDpi(const std::string &id, double &dpiX,
Shinya Kitaoka 120a6e
                         double &dpiY) const {
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_imp->m_mutex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_uncompressedItems.find(id);
Shinya Kitaoka 120a6e
  if (it != m_imp->m_uncompressedItems.end()) {
Shinya Kitaoka 120a6e
    UncompressedOnMemoryCacheItemP uncompressed = it->second;
Shinya Kitaoka 120a6e
    assert(uncompressed);
Shinya Kitaoka 120a6e
    TToonzImageP ti = uncompressed->getImage();
Shinya Kitaoka 120a6e
    if (ti) {
Shinya Kitaoka 120a6e
      ti->getDpi(dpiX, dpiY);
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TRasterImageP ri = uncompressed->getImage();
Shinya Kitaoka 120a6e
    if (ri) {
Shinya Kitaoka 120a6e
      ri->getDpi(dpiX, dpiY);
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itc =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_compressedItems.find(id);
Shinya Kitaoka 120a6e
  if (itc == m_imp->m_compressedItems.end()) return false;
Shinya Kitaoka 120a6e
  CacheItemP cacheItem = itc->second;
Shinya Kitaoka 120a6e
  assert(cacheItem->m_imageInfo);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  RasterImageInfo *rimageInfo =
Shinya Kitaoka 120a6e
      dynamic_cast<rasterimageinfo *="">(cacheItem->m_imageInfo);</rasterimageinfo>
Shinya Kitaoka 120a6e
  if (rimageInfo) {
Shinya Kitaoka 120a6e
    dpiX = rimageInfo->m_dpix;
Shinya Kitaoka 120a6e
    dpiY = rimageInfo->m_dpiy;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  ToonzImageInfo *timageInfo =
Shinya Kitaoka 120a6e
      dynamic_cast<toonzimageinfo *="">(cacheItem->m_imageInfo);</toonzimageinfo>
Shinya Kitaoka 120a6e
  if (timageInfo) {
Shinya Kitaoka 120a6e
    dpiX = timageInfo->m_dpix;
Shinya Kitaoka 120a6e
    dpiY = timageInfo->m_dpiy;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TImageCache::getSubsampling(const std::string &id, int &subs) const {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_imp->m_mutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, std::string="">::iterator it1;</std::string,>
Shinya Kitaoka 120a6e
  if ((it1 = m_imp->m_duplicatedItems.find(id)) !=
Shinya Kitaoka 120a6e
      m_imp->m_duplicatedItems.end()) {
Shinya Kitaoka 120a6e
    assert(m_imp->m_duplicatedItems.find(it1->second) ==
Shinya Kitaoka 120a6e
           m_imp->m_duplicatedItems.end());
Shinya Kitaoka 120a6e
    return getSubsampling(it1->second, subs);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_uncompressedItems.find(id);
Shinya Kitaoka 120a6e
  if (it != m_imp->m_uncompressedItems.end()) {
Shinya Kitaoka 120a6e
    UncompressedOnMemoryCacheItemP uncompressed = it->second;
Shinya Kitaoka 120a6e
    assert(uncompressed);
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
    if (TToonzImageP ti = uncompressed->getImage()) {
Shinya Kitaoka 120a6e
      subs = ti->getSubsampling();
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    else
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
        if (TRasterImageP ri = uncompressed->getImage()) {
Shinya Kitaoka 120a6e
      subs = ri->getSubsampling();
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itc =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_compressedItems.find(id);
Shinya Kitaoka 120a6e
  if (itc == m_imp->m_compressedItems.end()) return false;
Shinya Kitaoka 120a6e
  CacheItemP cacheItem = itc->second;
Shinya Kitaoka 120a6e
  assert(cacheItem->m_imageInfo);
Shinya Kitaoka 120a6e
  if (RasterImageInfo *rimageInfo =
Shinya Kitaoka 120a6e
          dynamic_cast<rasterimageinfo *="">(cacheItem->m_imageInfo)) {</rasterimageinfo>
Shinya Kitaoka 120a6e
    subs = rimageInfo->m_subs;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
  else if (ToonzImageInfo *timageInfo =
Shinya Kitaoka 120a6e
               dynamic_cast<toonzimageinfo *="">(cacheItem->m_imageInfo)) {</toonzimageinfo>
Shinya Kitaoka 120a6e
    subs = timageInfo->m_subs;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TImageCache::hasBeenModified(const std::string &id, bool reset) const {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_imp->m_mutex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, std::string="">::iterator it;</std::string,>
Shinya Kitaoka 120a6e
  if ((it = m_imp->m_duplicatedItems.find(id)) !=
Shinya Kitaoka 120a6e
      m_imp->m_duplicatedItems.end()) {
Shinya Kitaoka 120a6e
    assert(m_imp->m_duplicatedItems.find(it->second) ==
Shinya Kitaoka 120a6e
           m_imp->m_duplicatedItems.end());
Shinya Kitaoka 120a6e
    return hasBeenModified(it->second, reset);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TImageP img;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itu =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_uncompressedItems.find(id);
Shinya Kitaoka 120a6e
  if (itu != m_imp->m_uncompressedItems.end()) {
Shinya Kitaoka 120a6e
    if (reset && itu->second->m_modified) {
Shinya Kitaoka 120a6e
      itu->second->m_modified = false;
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      return itu->second->m_modified;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;  // not present in cache==modified (for particle purposes...)
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP TImageCache::get(const std::string &id, bool toBeModified) const {
Shinya Kitaoka 120a6e
  return m_imp->get(id, toBeModified);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP TImageCache::Imp::get(const std::string &id, bool toBeModified) {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_mutex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, std::string="">::const_iterator it;</std::string,>
Shinya Kitaoka 120a6e
  if ((it = m_duplicatedItems.find(id)) != m_duplicatedItems.end()) {
Shinya Kitaoka 120a6e
    assert(m_duplicatedItems.find(it->second) == m_duplicatedItems.end());
Shinya Kitaoka 120a6e
    return get(it->second, toBeModified);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TImageP img;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itu =</std::string,>
Shinya Kitaoka 120a6e
      m_uncompressedItems.find(id);
Shinya Kitaoka 120a6e
  if (itu != m_uncompressedItems.end()) {
Shinya Kitaoka 120a6e
    img = itu->second->getImage();
Shinya Kitaoka 120a6e
    if (itu->second->m_historyCount !=
Shinya Kitaoka 120a6e
        HistoryCount - 1)  // significa che l'ultimo get non era sulla stessa
Shinya Kitaoka 120a6e
                           // immagine, quindi  serve aggiornare l'history!
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      assert(m_itemHistory.find(itu->second->m_historyCount) !=
Shinya Kitaoka 120a6e
             m_itemHistory.end());
Shinya Kitaoka 120a6e
      m_itemHistory.erase(itu->second->m_historyCount);
Shinya Kitaoka 120a6e
      m_itemHistory[HistoryCount] = id;
Shinya Kitaoka 120a6e
      itu->second->m_historyCount = HistoryCount;
Shinya Kitaoka 120a6e
      HistoryCount++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (toBeModified) {
Shinya Kitaoka 120a6e
      itu->second->m_modified = true;
Shinya Kitaoka 120a6e
      std::map<std::string, cacheitemp="">::iterator itc =</std::string,>
Shinya Kitaoka 120a6e
          m_compressedItems.find(id);
Shinya Kitaoka 120a6e
      if (itc != m_compressedItems.end()) m_compressedItems.erase(itc);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return img;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itc = m_compressedItems.find(id);</std::string,>
Shinya Kitaoka 120a6e
  if (itc == m_compressedItems.end()) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CacheItemP cacheItem = itc->second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  img = cacheItem->getImage();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CacheItemP uncompressed;
Shinya Kitaoka 120a6e
  uncompressed                    = new UncompressedOnMemoryCacheItem(img);
Shinya Kitaoka 120a6e
  m_uncompressedItems[itc->first] = uncompressed;
Shinya Kitaoka 120a6e
  m_itemsByImagePointer[getPointer(img)] = itc->first;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_itemHistory[HistoryCount]  = itc->first;
Shinya Kitaoka 120a6e
  uncompressed->m_historyCount = HistoryCount;
Shinya Kitaoka 120a6e
  HistoryCount++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (CompressedOnMemoryCacheItemP(cacheItem))
Shinya Kitaoka 120a6e
  // l'immagine compressa non la tengo insieme alla
Shinya Kitaoka 120a6e
  // uncompressa se e' troppo grande
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (10 * cacheItem->getSize() > uncompressed->getSize()) {
Shinya Kitaoka 120a6e
      m_compressedItems.erase(itc);
Shinya Kitaoka 120a6e
      itc = m_compressedItems.end();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    assert((CompressedOnDiskCacheItemP)cacheItem ||
Shinya Kitaoka 120a6e
           (UncompressedOnDiskCacheItemP)cacheItem);  // deve essere compressa!
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (toBeModified && itc != m_compressedItems.end()) {
Shinya Kitaoka 120a6e
    uncompressed->m_modified = true;
Shinya Kitaoka 120a6e
    m_compressedItems.erase(itc);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  uncompressed->m_cantCompress = toBeModified;
Shinya Kitaoka 120a6e
  // se la memoria utilizzata e' superiore al massimo consentito, comprime
Shinya Kitaoka 120a6e
  doCompress();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  uncompressed->m_cantCompress = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#define DO_MEMCHECK
Toshihiro Shimizu 890ddd
#ifdef DO_MEMCHECK
Shinya Kitaoka 120a6e
  assert(_CrtCheckMemory());
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return img;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class AccumulateMemUsage {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  int operator()(int oldValue, std::pair<std::string, cacheitemp=""> item) {</std::string,>
Shinya Kitaoka 120a6e
    return oldValue + item.second->getSize();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TImageCache::getMemUsage() const {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_imp->m_mutex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int ret = std::accumulate(m_imp->m_uncompressedItems.begin(),
Shinya Kitaoka 120a6e
                            m_imp->m_uncompressedItems.end(), 0,
Shinya Kitaoka 120a6e
                            AccumulateMemUsage());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return ret + std::accumulate(m_imp->m_compressedItems.begin(),
Shinya Kitaoka 120a6e
                               m_imp->m_compressedItems.end(), 0,
Shinya Kitaoka 120a6e
                               AccumulateMemUsage());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TImageCache::getDiskUsage() const { return 0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TImageCache::getMemUsage(const std::string &id) const {
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_uncompressedItems.find(id);
Shinya Kitaoka 120a6e
  if (it != m_imp->m_uncompressedItems.end()) return it->second->getSize();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  it = m_imp->m_compressedItems.find(id);
Shinya Kitaoka 120a6e
  if (it != m_imp->m_compressedItems.end()) return it->second->getSize();
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns the uncompressed image size (in KB) of the image associated with
Toshihiro Shimizu 890ddd
//! passd id, or 0 if none was found.
Shinya Kitaoka 120a6e
UINT TImageCache::getUncompressedMemUsage(const std::string &id) const {
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_uncompressedItems.find(id);
Shinya Kitaoka 120a6e
  if (it != m_imp->m_uncompressedItems.end()) return it->second->getSize();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  it = m_imp->m_compressedItems.find(id);
Shinya Kitaoka 120a6e
  if (it != m_imp->m_compressedItems.end()) return it->second->getSize();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
int TImageCache::getItemCount() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  return m_imp->m_uncompressedItems.size()+m_imp->m_compressedItems.size();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TImageCache::getDiskUsage(const std::string &id) const { return 0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::dump(std::ostream &os) const {
Shinya Kitaoka 120a6e
  os << "mem: " << getMemUsage() << std::endl;
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
      m_imp->m_uncompressedItems.begin();
Shinya Kitaoka 120a6e
  for (; it != m_imp->m_uncompressedItems.end(); ++it) {
Shinya Kitaoka 120a6e
    os << it->first << std::endl;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::outputMap(UINT chunkRequested, std::string filename) {
Shinya Kitaoka 120a6e
  m_imp->outputMap(chunkRequested, filename);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::Imp::outputMap(UINT chunkRequested, std::string filename) {
Shinya Kitaoka 120a6e
  TThread::MutexLocker sl(&m_mutex);
Shinya Kitaoka 120a6e
  //#ifdef _DEBUG
Shinya Kitaoka 120a6e
  // static int Count = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string st = filename /*+toString(Count++)*/ + ".txt";
Shinya Kitaoka 120a6e
  TFilePath fp(st);
Shinya Kitaoka 120a6e
  Tofstream os(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int umcount1 = 0;
Shinya Kitaoka 120a6e
  int umcount2 = 0;
Shinya Kitaoka 120a6e
  int umcount3 = 0;
Shinya Kitaoka 120a6e
  int cmcount  = 0;
Shinya Kitaoka 120a6e
  int cdcount  = 0;
Shinya Kitaoka 120a6e
  int umcount  = 0;
Shinya Kitaoka 120a6e
  int udcount  = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TUINT64 umsize1 = 0;
Shinya Kitaoka 120a6e
  TUINT64 umsize2 = 0;
Shinya Kitaoka 120a6e
  TUINT64 umsize3 = 0;
Shinya Kitaoka 120a6e
  TUINT64 cmsize  = 0;
Shinya Kitaoka 120a6e
  TUINT64 cdsize  = 0;
Shinya Kitaoka 120a6e
  TUINT64 umsize  = 0;
Shinya Kitaoka 120a6e
  TUINT64 udsize  = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itu = m_uncompressedItems.begin();</std::string,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; itu != m_uncompressedItems.end(); ++itu) {
Shinya Kitaoka 120a6e
    UncompressedOnMemoryCacheItemP uitem = itu->second;
Shinya Kitaoka 120a6e
    if (uitem->m_image && hasExternalReferences(uitem->m_image)) {
Shinya Kitaoka 120a6e
      umcount1++;
Shinya Kitaoka 120a6e
      umsize1 += (TUINT64)(itu->second->getSize() / 1024.0);
Shinya Kitaoka 120a6e
    } else if (uitem->m_cantCompress) {
Shinya Kitaoka 120a6e
      umcount2++;
Shinya Kitaoka 120a6e
      umsize2 += (TUINT64)(itu->second->getSize() / 1024.0);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      umcount3++;
Shinya Kitaoka 120a6e
      umsize3 += (TUINT64)(itu->second->getSize() / 1024.0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::map<std::string, cacheitemp="">::iterator itc = m_compressedItems.begin();</std::string,>
Shinya Kitaoka 120a6e
  for (; itc != m_compressedItems.end(); ++itc) {
Shinya Kitaoka 120a6e
    CacheItemP boh                      = itc->second;
Shinya Kitaoka 120a6e
    CompressedOnMemoryCacheItemP cmitem = itc->second;
Shinya Kitaoka 120a6e
    CompressedOnDiskCacheItemP cditem   = itc->second;
Shinya Kitaoka 120a6e
    UncompressedOnDiskCacheItemP uditem = itc->second;
Shinya Kitaoka 120a6e
    if (cmitem) {
Shinya Kitaoka 120a6e
      cmcount++;
Shinya Kitaoka 120a6e
      cmsize += cmitem->getSize();
Shinya Kitaoka 120a6e
    } else if (cditem) {
Shinya Kitaoka 120a6e
      cdcount++;
Shinya Kitaoka 120a6e
      cdsize += cditem->getSize();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      assert(uditem);
Shinya Kitaoka 120a6e
      udcount++;
Shinya Kitaoka 120a6e
      udsize += uditem->getSize();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TUINT64 currPhisMemoryAvail =
Shinya Kitaoka 120a6e
      (TUINT64)(TSystem::getFreeMemorySize(true) / 1024.0);
Shinya Kitaoka 120a6e
  // TUINT64 currVirtualMemoryAvail = TSystem::getFreeMemorySize(false)/1024.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os << "************************************************************\n";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os << "***requested memory: " +
Shinya Kitaoka 120a6e
            std::to_string((int)chunkRequested / 1048576.0) + " MB\n";
Shinya Kitaoka 120a6e
  // os<<"*** memory in rasters: " +
Shinya Kitaoka 120a6e
  // std::to_string((int)TRaster::getTotalMemoryInKB()/1024.0) + " MB\n";
Shinya Kitaoka 120a6e
  // os<<"***virtualmem " + std::to_string((int)currVirtualMemoryAvail) + "
Shinya Kitaoka 120a6e
  // MB\n";
Shinya Kitaoka 120a6e
  os << "***phismem " + std::to_string((int)currPhisMemoryAvail) +
Shinya Kitaoka 120a6e
            " MB; percent of tot:" +
Shinya Kitaoka 120a6e
            std::to_string(
Shinya Kitaoka 120a6e
                (int)((currPhisMemoryAvail * 100) / m_reservedMemory)) +
Shinya Kitaoka 120a6e
            "\n";
Shinya Kitaoka 120a6e
  // os<<"***bigmem available" +
Shinya Kitaoka 120a6e
  // std::to_string((int)TBigMemoryManager::instance()->getAvailableMemoryinKb());
Shinya Kitaoka 120a6e
  os << "***uncompressed NOT compressable(refcount>1)   " +
Shinya Kitaoka 120a6e
            std::to_string(umcount1) + " " + std::to_string(umsize1 / 1024.0) +
Shinya Kitaoka 120a6e
            " MB\n";
Shinya Kitaoka 120a6e
  os << "***uncompressed NOT compressable(cantCompress)   " +
Shinya Kitaoka 120a6e
            std::to_string(umcount2) + " " + std::to_string(umsize2 / 1024.0) +
Shinya Kitaoka 120a6e
            " MB\n";
Shinya Kitaoka 120a6e
  os << "***uncompressed compressable   " + std::to_string(umcount3) + " " +
Shinya Kitaoka 120a6e
            std::to_string(umsize3 / 1024.0) + " MB\n";
Shinya Kitaoka 120a6e
  os << "***compressed on mem  " + std::to_string(cmcount) + " " +
Shinya Kitaoka 120a6e
            std::to_string((int)cmsize / 1048576.0) + " MB\n";
Shinya Kitaoka 120a6e
  os << "***compressed on disk " + std::to_string(cdcount) + " " +
Shinya Kitaoka 120a6e
            std::to_string((int)cdsize / 1048576.0) + " MB\n";
Shinya Kitaoka 120a6e
  os << "***uncompressed on disk " + std::to_string(udcount) + " " +
Shinya Kitaoka 120a6e
            std::to_string((int)udsize / 1048576.0) + " MB\n";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // TBigMemoryManager::instance()->printMap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::compress(const std::string &id) { m_imp->doCompress(id); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::add(const QString &id, const TImageP &img, bool overwrite) {
Shinya Kitaoka 120a6e
  if (!isEnabled()) return;
Shinya Kitaoka 120a6e
  m_imp->add(id.toStdString(), img, overwrite);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageCache::remove(const QString &id) { m_imp->remove(id.toStdString()); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP TImageCache::get(const QString &id, bool toBeModified) const {
Shinya Kitaoka 120a6e
  return get(id.toStdString(), toBeModified);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*************************************************************************************
Toshihiro Shimizu 890ddd
//    TCachedImage implementation
Toshihiro Shimizu 890ddd
//*************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DEFINE_CLASS_CODE(TCachedImage, 103)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TCachedImage::TCachedImage()
Shinya Kitaoka 120a6e
    : TSmartObject(m_classCode)
Shinya Kitaoka 120a6e
    , m_ref(TImageCache::instance()->getUniqueId()) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TCachedImage::TCachedImage(const TImageP &img)
Shinya Kitaoka 120a6e
    : TSmartObject(m_classCode), m_ref(TImageCache::instance()->getUniqueId()) {
Shinya Kitaoka 120a6e
  setImage(img);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TCachedImage::~TCachedImage() { TImageCache::instance()->remove(m_ref); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TCachedImage::setImage(const TImageP &img, bool overwrite) {
Shinya Kitaoka 120a6e
  TImageCache::instance()->add(m_ref, img, overwrite);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP TCachedImage::image(bool toBeModified) {
Shinya Kitaoka 120a6e
  return TImageCache::instance()->get(m_ref, toBeModified);
Toshihiro Shimizu 890ddd
}