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