| |
| |
|
|
| #include "tconvert.h" |
| |
| |
| #include "timage_io.h" |
| |
| |
| #include "timagecache.h" |
| |
| |
| #include "ttile.h" |
| |
| |
| #include "trop.h" |
| |
| |
| |
| |
| |
| #include <QRegion> |
| #include <QByteArray> |
| |
| |
| #include "tcacheresourcepool.h" |
| |
| #include "tcacheresource.h" |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| namespace |
| { |
| |
| const int latticeStep = 512; |
| |
| static unsigned long cacheId = 0; |
| |
| |
| |
| inline int getRasterType(const TRasterP &ras) |
| { |
| if ((TRaster32P)ras) |
| return TCacheResource::RGBM32; |
| else if ((TRaster64P)ras) |
| return TCacheResource::RGBM64; |
| else if ((TRasterCM32P)ras) |
| return TCacheResource::CM32; |
| |
| return TCacheResource::NONE; |
| } |
| |
| |
| |
| inline TRasterP getRaster(const TImageP &img) |
| { |
| TRasterImageP rimg(img); |
| if (rimg) |
| return rimg->getRaster(); |
| TToonzImageP timg(img); |
| if (timg) |
| return timg->getRaster(); |
| |
| assert(!"Wrong image type!"); |
| return 0; |
| } |
| |
| |
| |
| inline bool isEmpty(const TRect &rect) { return rect.x0 > rect.x1 || rect.y0 > rect.y1; } |
| |
| |
| |
| inline QRect toQRect(const TRect &r) { return QRect(r.x0, r.y0, r.getLx(), r.getLy()); } |
| inline TRect toTRect(const QRect &r) { return TRect(r.left(), r.top(), r.right(), r.bottom()); } |
| inline QPoint toQPoint(const TPoint &p) { return QPoint(p.x, p.y); } |
| |
| |
| |
| inline TRect getTileRect(const TTile &tile) |
| { |
| return TRect( |
| TPoint(tfloor(tile.m_pos.x), tfloor(tile.m_pos.y)), |
| tile.getRaster()->getSize()); |
| } |
| |
| |
| |
| |
| inline bool contains(const QRegion ®ion, const TRect &rect) |
| { |
| return QRegion(toQRect(rect)).subtracted(region).isEmpty(); |
| } |
| |
| |
| |
| inline void saveCompressed(const TFilePath &fp, const TRasterP &ras) |
| { |
| assert(ras->getLx() == latticeStep && ras->getLy() == latticeStep); |
| unsigned int size = sq(latticeStep) * ras->getPixelSize(); |
| |
| ras->lock(); |
| QByteArray data = qCompress((const char *)ras->getRawData(), size); |
| ras->unlock(); |
| |
| Tofstream oss(fp); |
| oss.write((const char *)&size, sizeof(unsigned int)); |
| oss.write(data.constData(), data.size()); |
| assert(!oss.fail()); |
| } |
| |
| |
| |
| inline void loadCompressed(const TFilePath &fp, TRasterP &ras, TCacheResource::Type rasType) |
| { |
| Tifstream is(fp); |
| |
| if (rasType == TCacheResource::CM32) |
| ras = TRasterCM32P(latticeStep, latticeStep); |
| else if (rasType == TCacheResource::RGBM32) |
| ras = TRaster32P(latticeStep, latticeStep); |
| else if (rasType == TCacheResource::RGBM64) |
| ras = TRaster64P(latticeStep, latticeStep); |
| else |
| assert(false); |
| |
| ras->lock(); |
| |
| char *rawData = (char *)ras->getRawData(); |
| unsigned int dataSize; |
| is.read((char *)&dataSize, sizeof(unsigned int)); |
| is.read(rawData, dataSize); |
| |
| |
| QByteArray data(QByteArray::fromRawData(rawData, dataSize)); |
| data = qUncompress(data); |
| memcpy(rawData, data.constData(), data.size()); |
| |
| ras->unlock(); |
| } |
| } |
| |
| |
| |
| |
| |
| TCacheResourceP::TCacheResourceP(const std::string &imageName, bool createIfNone) |
| : m_pointer(TCacheResourcePool::instance()->getResource(imageName, createIfNone)) |
| { |
| if (m_pointer) |
| m_pointer->addRef(); |
| } |
| |
| |
| |
| TCacheResourceP::~TCacheResourceP() |
| { |
| if (m_pointer) { |
| m_pointer->release(); |
| m_pointer = 0; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| TCacheResource::TCacheResource() |
| : m_id(cacheId++), m_tileType(NONE), m_cellsCount(0), m_locksCount(0), m_backEnabled(false), m_invalidated(false) |
| { |
| } |
| |
| |
| |
| TCacheResource::~TCacheResource() |
| { |
| clear(); |
| } |
| |
| |
| |
| void TCacheResource::release() |
| { |
| if ((--m_refCount) <= 0) { |
| |
| TCacheResourcePool::instance()->releaseResource(this); |
| } |
| } |
| |
| |
| |
| inline TCacheResource::PointLess TCacheResource::getCellIndex(const TPoint &pos) const |
| { |
| return PointLess( |
| tfloor(pos.x / (double)latticeStep), |
| tfloor(pos.y / (double)latticeStep)); |
| } |
| |
| |
| |
| inline TPoint TCacheResource::getCellPos(const PointLess &cellIndex) const |
| { |
| return TPoint(cellIndex.x * latticeStep, cellIndex.y * latticeStep); |
| } |
| |
| |
| |
| |
| inline TPoint TCacheResource::getCellPos(const TPoint &pos) const |
| { |
| TPoint cellIndex( |
| tfloor(pos.x / (double)latticeStep), |
| tfloor(pos.y / (double)latticeStep)); |
| return TPoint(cellIndex.x * latticeStep, cellIndex.y * latticeStep); |
| } |
| |
| |
| |
| |
| inline TPoint TCacheResource::getCellPos(const TPointD &pos) const |
| { |
| TPoint cellIndex( |
| tfloor(pos.x / (double)latticeStep), |
| tfloor(pos.y / (double)latticeStep)); |
| return TPoint(cellIndex.x * latticeStep, cellIndex.y * latticeStep); |
| } |
| |
| |
| |
| |
| |
| bool TCacheResource::checkRasterType(const TRasterP &ras, int &rasType) const |
| { |
| rasType = ::getRasterType(ras); |
| if (rasType == NONE) { |
| assert(!"The passed raster has unkown type!"); |
| return false; |
| } |
| if (m_tileType != NONE && m_tileType != rasType) { |
| assert(!"The passed raster has not the same type of the cache resource!"); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| |
| |
| TRasterP TCacheResource::buildCompatibleRaster(const TDimension &size) |
| { |
| TRasterP result; |
| if (m_tileType == RGBM32) |
| result = TRaster32P(size); |
| else if (m_tileType == RGBM64) |
| result = TRaster64P(size); |
| else if (m_tileType == CM32) |
| result = TRasterCM32P(size); |
| |
| return result; |
| } |
| |
| |
| |
| bool TCacheResource::checkTile(const TTile &tile) const |
| { |
| |
| TPointD tileFracPos(tile.m_pos.x - tfloor(tile.m_pos.x), tile.m_pos.y - tfloor(tile.m_pos.y)); |
| if (tileFracPos.x != 0.0 || tileFracPos.y != 0.0) { |
| assert(!"The passed tile must have integer geometry!"); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| |
| |
| inline std::string TCacheResource::getCellName(int idxX, int idxY) const |
| { |
| return "cell" + toString(idxX) + "," + toString(idxY); |
| } |
| |
| |
| |
| inline std::string TCacheResource::getCellCacheId(int idxX, int idxY) const |
| { |
| return "TCacheResource" + toString(m_id) + getCellName(idxX, idxY); |
| } |
| |
| |
| |
| inline std::string TCacheResource::getCellCacheId(const TPoint &cellPos) const |
| { |
| return getCellCacheId(tfloor(cellPos.x / (double)latticeStep), |
| tfloor(cellPos.y / (double)latticeStep)); |
| } |
| |
| |
| |
| inline TRasterP TCacheResource::createCellRaster(int rasterType, const std::string &cacheId) |
| { |
| TRasterP result; |
| |
| if (rasterType == TCacheResource::NONE) { |
| assert(!"Unknown raster type!"); |
| return result; |
| } |
| |
| TImageP img; |
| if (rasterType == TCacheResource::RGBM32) { |
| result = TRaster32P(latticeStep, latticeStep); |
| img = TRasterImageP(result); |
| } else if (rasterType == TCacheResource::RGBM64) { |
| result = TRaster64P(latticeStep, latticeStep); |
| img = TRasterImageP(result); |
| } else if (rasterType == TCacheResource::CM32) { |
| result = TRasterCM32P(latticeStep, latticeStep); |
| img = TToonzImageP(result, result->getBounds()); |
| } |
| |
| TImageCache::instance()->add(cacheId, img); |
| ++m_cellsCount; |
| |
| |
| |
| return result; |
| } |
| |
| |
| |
| bool TCacheResource::canDownloadSome(const TRect &rect) const |
| { |
| return m_region.intersects(toQRect(rect)); |
| } |
| |
| |
| |
| bool TCacheResource::canDownloadAll(const TRect &rect) const |
| { |
| return contains(m_region, rect); |
| } |
| |
| |
| |
| bool TCacheResource::canUpload(const TTile &tile) const |
| { |
| int tileType; |
| return checkTile(tile) && checkRasterType(tile.getRaster(), tileType); |
| } |
| |
| |
| |
| |
| |
| bool TCacheResource::canDownloadSome(const TTile &tile) const |
| { |
| return checkTile(tile) && m_region.intersects(toQRect(getTileRect(tile))); |
| } |
| |
| |
| |
| |
| |
| bool TCacheResource::canDownloadAll(const TTile &tile) const |
| { |
| return checkTile(tile) && contains(m_region, getTileRect(tile)); |
| } |
| |
| |
| |
| |
| |
| |
| bool TCacheResource::upload(const TPoint &pos, TRasterP ras) |
| { |
| int tileType; |
| if (!checkRasterType(ras, tileType)) |
| return false; |
| |
| if (m_tileType == NONE) |
| m_tileType = tileType; |
| |
| |
| |
| TRect tileRect(ras->getBounds() + pos); |
| TPoint initialPos(getCellPos(tileRect.getP00())); |
| |
| |
| |
| |
| TPoint currPos; |
| for (currPos.x = initialPos.x; currPos.x <= tileRect.x1; currPos.x += latticeStep) |
| for (currPos.y = initialPos.y; currPos.y <= tileRect.y1; currPos.y += latticeStep) { |
| |
| TRect cellRect(currPos, TDimension(latticeStep, latticeStep)); |
| |
| TRect overlapRect(tileRect * cellRect); |
| assert(!overlapRect.isEmpty()); |
| |
| PointLess cellIndex(getCellIndex(currPos)); |
| std::pair<TRasterP, CellData *> cellInfos(touch(cellIndex)); |
| TRasterP cellRas(cellInfos.first); |
| |
| TRect temp(overlapRect - currPos); |
| TRasterP overlappingCellRas(cellRas->extract(temp)); |
| temp = TRect(overlapRect - tileRect.getP00()); |
| TRasterP overlappingTileRas(ras->extract(temp)); |
| |
| assert(overlappingCellRas->getBounds() == overlappingTileRas->getBounds()); |
| TRop::copy(overlappingCellRas, overlappingTileRas); |
| |
| cellInfos.second->m_modified = true; |
| } |
| |
| |
| m_region += toQRect(tileRect); |
| |
| return true; |
| } |
| |
| |
| |
| bool TCacheResource::upload(const TTile &tile) |
| { |
| if (!checkTile(tile)) |
| return false; |
| |
| return upload(TPoint(tile.m_pos.x, tile.m_pos.y), tile.getRaster()); |
| } |
| |
| |
| |
| |
| |
| |
| QRegion TCacheResource::download(const TPoint &pos, TRasterP ras) |
| { |
| int tileType; |
| if (!checkRasterType(ras, tileType)) |
| return QRegion(); |
| |
| |
| TRect tileRect(ras->getBounds() + pos); |
| |
| if (!m_region.intersects(toQRect(tileRect))) |
| return QRegion(); |
| |
| |
| |
| TPoint initialPos(getCellPos(tileRect.getP00())); |
| |
| TPoint currPos; |
| for (currPos.x = initialPos.x; currPos.x <= tileRect.x1; currPos.x += latticeStep) |
| for (currPos.y = initialPos.y; currPos.y <= tileRect.y1; currPos.y += latticeStep) { |
| TRect cellRect(currPos, TDimension(latticeStep, latticeStep)); |
| |
| TRect overlapRect(tileRect * cellRect); |
| assert(!overlapRect.isEmpty()); |
| QRect overlapQRect(toQRect(overlapRect)); |
| |
| if (m_region.intersects(overlapQRect)) { |
| |
| std::pair<TRasterP, CellData *> cellInfos(touch(getCellIndex(currPos))); |
| TRasterP cellRas(cellInfos.first); |
| |
| TRect temp(overlapRect - currPos); |
| TRasterP overlappingCellRas(cellRas->extract(temp)); |
| temp = TRect(overlapRect - tileRect.getP00()); |
| TRasterP overlappingTileRas(ras->extract(temp)); |
| |
| TRop::copy(overlappingTileRas, overlappingCellRas); |
| } |
| } |
| |
| return m_region.intersected(QRegion(toQRect(tileRect))); |
| } |
| |
| |
| |
| QRegion TCacheResource::download(TTile &tile) |
| { |
| if (!checkTile(tile)) |
| return QRegion(); |
| |
| return download(TPoint(tile.m_pos.x, tile.m_pos.y), tile.getRaster()); |
| } |
| |
| |
| |
| bool TCacheResource::downloadAll(const TPoint &pos, TRasterP ras) |
| { |
| int tileType; |
| if (!checkRasterType(ras, tileType)) |
| return false; |
| |
| |
| TRect tileRect(ras->getBounds() + pos); |
| |
| if (!contains(m_region, tileRect)) |
| return false; |
| |
| |
| |
| |
| |
| |
| TPoint initialPos(getCellPos(tileRect.getP00())); |
| |
| TPoint currPos; |
| for (currPos.x = initialPos.x; currPos.x <= tileRect.x1; currPos.x += latticeStep) |
| for (currPos.y = initialPos.y; currPos.y <= tileRect.y1; currPos.y += latticeStep) { |
| TRect cellRect(currPos, TDimension(latticeStep, latticeStep)); |
| |
| TRect overlapRect(tileRect * cellRect); |
| assert(!overlapRect.isEmpty()); |
| QRect overlapQRect(toQRect(overlapRect)); |
| |
| if (m_region.intersects(overlapQRect)) { |
| |
| std::pair<TRasterP, CellData *> cellInfos(touch(getCellIndex(currPos))); |
| TRasterP cellRas(cellInfos.first); |
| |
| TRect temp(overlapRect - currPos); |
| TRasterP overlappingCellRas(cellRas->extract(temp)); |
| temp = TRect(overlapRect - tileRect.getP00()); |
| TRasterP overlappingTileRas(ras->extract(temp)); |
| |
| TRop::copy(overlappingTileRas, overlappingCellRas); |
| } |
| } |
| |
| return true; |
| } |
| |
| |
| |
| bool TCacheResource::downloadAll(TTile &tile) |
| { |
| if (!checkTile(tile)) |
| return false; |
| |
| return downloadAll(TPoint(tile.m_pos.x, tile.m_pos.y), tile.getRaster()); |
| } |
| |
| |
| |
| |
| |
| |
| void TCacheResource::clear(QRegion region) |
| { |
| if (!m_region.intersects(region)) |
| return; |
| |
| |
| TRect bbox(toTRect(region.boundingRect())); |
| |
| |
| TPoint initialPos(getCellPos(bbox.getP00())); |
| TPoint pos; |
| for (pos.x = initialPos.x; pos.x <= bbox.x1; pos.x += latticeStep) |
| for (pos.y = initialPos.y; pos.y <= bbox.y1; pos.y += latticeStep) { |
| QRect cellQRect(toQRect(TRect(pos, TDimension(latticeStep, latticeStep)))); |
| |
| if (region.intersects(cellQRect) && m_region.intersects(cellQRect)) { |
| |
| TImageCache::instance()->remove(getCellCacheId(pos)); |
| m_region -= cellQRect; |
| |
| --m_cellsCount; |
| |
| |
| |
| |
| m_cellDatas[getCellIndex(pos)].m_modified = true; |
| } |
| } |
| |
| if (m_region.isEmpty()) { |
| m_tileType = NONE; |
| m_locksCount = 0; |
| } |
| } |
| |
| |
| |
| |
| |
| bool TCacheResource::uploadPalette(TPaletteP palette) |
| { |
| if (m_tileType == NONE) |
| m_tileType = CM32; |
| |
| if (m_tileType != CM32) { |
| assert(!"The resource already holds a non-colormap content!"); |
| return false; |
| } |
| |
| m_palette = palette; |
| return true; |
| } |
| |
| |
| |
| void TCacheResource::downloadPalette(TPaletteP &palette) |
| { |
| palette = m_palette; |
| } |
| |
| |
| |
| |
| |
| void TCacheResource::addRef2(const TRect &rect) |
| { |
| |
| |
| |
| |
| TPoint initialPos(getCellPos(rect.getP00())); |
| TPoint pos; |
| for (pos.x = initialPos.x; pos.x <= rect.x1; pos.x += latticeStep) |
| for (pos.y = initialPos.y; pos.y <= rect.y1; pos.y += latticeStep) { |
| PointLess cellIndex(getCellIndex(pos)); |
| CellData &cellData = m_cellDatas[cellIndex]; |
| cellData.m_referenced = true; |
| cellData.m_refsCount++; |
| } |
| } |
| |
| |
| |
| void TCacheResource::release2(const TRect &rect) |
| { |
| |
| |
| |
| if (m_locksCount > 0) |
| return; |
| |
| std::map<PointLess, CellData>::iterator it; |
| for (it = m_cellDatas.begin(); it != m_cellDatas.end();) { |
| if (!it->second.m_referenced) { |
| ++it; |
| continue; |
| } |
| |
| TPoint cellPos(getCellPos(it->first)); |
| TRect cellRect(cellPos, TDimension(latticeStep, latticeStep)); |
| |
| if (isEmpty(cellRect * rect)) { |
| ++it; |
| continue; |
| } |
| |
| QRect cellQRect(toQRect(cellRect)); |
| if (--it->second.m_refsCount <= 0) { |
| releaseCell(cellQRect, it->first, it->second.m_modified); |
| std::map<PointLess, CellData>::iterator jt = it++; |
| m_cellDatas.erase(jt); |
| } else |
| ++it; |
| } |
| } |
| |
| |
| |
| void TCacheResource::addLock() |
| { |
| |
| |
| |
| ++m_locksCount; |
| } |
| |
| |
| |
| void TCacheResource::releaseLock() |
| { |
| |
| |
| |
| m_locksCount = tmax(m_locksCount - 1, 0); |
| |
| if (m_locksCount > 0) |
| return; |
| |
| |
| std::map<PointLess, CellData>::iterator it; |
| for (it = m_cellDatas.begin(); it != m_cellDatas.end();) |
| if (it->second.m_referenced) { |
| TPoint cellPos(getCellPos(it->first)); |
| QRect cellQRect(cellPos.x, cellPos.y, latticeStep, latticeStep); |
| |
| releaseCell(cellQRect, it->first, it->second.m_modified); |
| std::map<PointLess, CellData>::iterator jt = it++; |
| m_cellDatas.erase(jt); |
| } else |
| ++it; |
| } |
| |
| |
| |
| void TCacheResource::releaseCell(const QRect &cellQRect, const PointLess &cellIndex, bool doSave) |
| { |
| if (m_region.intersects(cellQRect)) { |
| std::string cellCacheId(getCellCacheId(cellIndex.x, cellIndex.y)); |
| |
| if (!(doSave && save(cellIndex))) |
| m_region -= cellQRect; |
| |
| TImageCache::instance()->remove(cellCacheId); |
| --m_cellsCount; |
| |
| |
| } |
| } |
| |
| |
| |
| |
| int TCacheResource::size() const |
| { |
| |
| |
| |
| return m_tileType == NONE ? 0 : m_tileType == RGBM64 ? (m_cellsCount << 11) : (m_cellsCount << 10); |
| } |
| |
| |
| |
| |
| |
| void TCacheResource::enableBackup() |
| { |
| if (m_backEnabled) |
| return; |
| TCacheResourcePool::instance()->startBacking(this); |
| } |
| |
| |
| |
| void TCacheResource::invalidate() |
| { |
| m_invalidated = true; |
| } |
| |
| |
| |
| void TCacheResource::setPath(const TFilePath &path) |
| { |
| m_path = path; |
| } |
| |
| |
| |
| const TFilePath &TCacheResource::getPath() const |
| { |
| return m_path; |
| } |
| |
| |
| |
| bool TCacheResource::save(const PointLess &cellIndex, TRasterP cellRas) const |
| { |
| if (!m_backEnabled || m_invalidated) |
| return false; |
| |
| assert(!m_path.isEmpty()); |
| |
| if (!cellRas) |
| cellRas = getRaster(TImageCache::instance()->get( |
| getCellCacheId(cellIndex.x, cellIndex.y), false)); |
| |
| assert(m_tileType != NONE); |
| |
| TFilePath fp(TCacheResourcePool::instance()->getPath() + m_path + getCellName(cellIndex.x, cellIndex.y)); |
| |
| if (m_tileType == CM32) { |
| ::saveCompressed(fp, cellRas); |
| } else { |
| TImageWriter::save(fp.withType(".tif"), cellRas); |
| } |
| |
| return true; |
| } |
| |
| |
| |
| TRasterP TCacheResource::load(const PointLess &cellPos) |
| { |
| if (m_path.isEmpty()) |
| return 0; |
| |
| TFilePath cellPath(TCacheResourcePool::instance()->getPath() + m_path + TFilePath(getCellName(cellPos.x, cellPos.y))); |
| TRasterP ras; |
| if (m_tileType == CM32) { |
| ::loadCompressed(cellPath, ras, CM32); |
| } else { |
| TImageReader::load(cellPath.withType(".tif"), ras); |
| } |
| |
| return ras; |
| } |
| |
| |
| |
| std::pair<TRasterP, TCacheResource::CellData *> TCacheResource::touch(const PointLess &cellIndex) |
| { |
| std::string cellId(getCellCacheId(cellIndex.x, cellIndex.y)); |
| |
| std::map<PointLess, CellData>::iterator it = m_cellDatas.find(cellIndex); |
| if (it != m_cellDatas.end()) { |
| |
| TImageP img(TImageCache::instance()->get(cellId, true)); |
| if (img) |
| return std::make_pair(getRaster(img), &it->second); |
| } |
| |
| it = m_cellDatas.insert(std::make_pair(cellIndex, CellData())).first; |
| |
| |
| TRasterP ras(load(cellIndex)); |
| if (ras) { |
| TImageCache::instance()->add(cellId, TRasterImageP(ras)); |
| return std::make_pair(ras, &it->second); |
| } |
| |
| |
| return std::make_pair( |
| createCellRaster(m_tileType, cellId), |
| &it->second); |
| } |
| |
| |
| |
| void TCacheResource::save() |
| { |
| if (m_backEnabled && !m_invalidated) { |
| assert(!m_path.isEmpty()); |
| |
| |
| std::map<PointLess, CellData>::iterator it; |
| for (it = m_cellDatas.begin(); it != m_cellDatas.end(); ++it) { |
| if (it->second.m_modified) |
| save(it->first); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| } |
| |
| |
| |
| void TCacheResource::save(const TFilePath &fp) |
| { |
| assert(!fp.isEmpty()); |
| |
| std::map<PointLess, CellData>::iterator it; |
| for (it = m_cellDatas.begin(); it != m_cellDatas.end(); ++it) { |
| TRasterP cellRas = getRaster(TImageCache::instance()->get( |
| getCellCacheId(it->first.x, it->first.y), false)); |
| |
| assert(m_tileType != NONE); |
| |
| TFilePath cellFp(fp + TFilePath(getCellName(it->first.x, it->first.y))); |
| |
| if (m_tileType == CM32) |
| ::saveCompressed(cellFp, cellRas); |
| else |
| TImageWriter::save(cellFp.withType(".tif"), cellRas); |
| } |
| } |
| |
| |
| |
| void TCacheResource::clear() |
| { |
| std::map<PointLess, CellData>::iterator it; |
| for (it = m_cellDatas.begin(); it != m_cellDatas.end(); ++it) { |
| std::string cellCacheId(getCellCacheId(it->first.x, it->first.y)); |
| TImageCache::instance()->remove(cellCacheId); |
| } |
| |
| m_cellDatas.clear(); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |