|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tcodec.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trastercm.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpixel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tbigmemorymanager.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsystem.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tstopwatch.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "timagecache.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterimage.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//#include "snappy-c.h"
|
|
roentgen |
19af1b |
#if defined(LZ4_STATIC)
|
|
Toshihiro Shimizu |
890ddd |
#include "lz4frame_static.h"
|
|
roentgen |
19af1b |
#else
|
|
roentgen |
19af1b |
#include "lz4frame.h"
|
|
roentgen |
19af1b |
#endif
|
|
roentgen |
19af1b |
|
|
Toshihiro Shimizu |
890ddd |
#include <qdir></qdir>
|
|
Toshihiro Shimizu |
890ddd |
#include <qprocess></qprocess>
|
|
Toshihiro Shimizu |
890ddd |
#include <qcoreapplication></qcoreapplication>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace std;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
class Header
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
enum RasType {
|
|
Toshihiro Shimizu |
890ddd |
Raster32RGBM,
|
|
Toshihiro Shimizu |
890ddd |
Raster64RGBM,
|
|
Toshihiro Shimizu |
890ddd |
Raster32CM,
|
|
Toshihiro Shimizu |
890ddd |
RasterGR8,
|
|
Toshihiro Shimizu |
890ddd |
RasterGR16,
|
|
Toshihiro Shimizu |
890ddd |
RasterUnknown
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
Header(const TRasterP &ras);
|
|
Toshihiro Shimizu |
890ddd |
~Header() {}
|
|
Toshihiro Shimizu |
890ddd |
TRasterP createRaster() const;
|
|
Toshihiro Shimizu |
890ddd |
int getRasterSize() const;
|
|
Toshihiro Shimizu |
890ddd |
int m_lx;
|
|
Toshihiro Shimizu |
890ddd |
int m_ly;
|
|
Toshihiro Shimizu |
890ddd |
RasType m_rasType;
|
|
Toshihiro Shimizu |
890ddd |
Header(void *mem) { memcpy(this, mem, sizeof(Header)); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Toshihiro Shimizu |
890ddd |
Header(); // not implemented
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Header::Header(const TRasterP &ras)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(ras);
|
|
Toshihiro Shimizu |
890ddd |
m_lx = ras->getLx();
|
|
Toshihiro Shimizu |
890ddd |
m_ly = ras->getLy();
|
|
Toshihiro Shimizu |
890ddd |
TRaster32P ras32(ras);
|
|
Toshihiro Shimizu |
890ddd |
if (ras32)
|
|
Toshihiro Shimizu |
890ddd |
m_rasType = Raster32RGBM;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
TRasterCM32P rasCM32(ras);
|
|
Toshihiro Shimizu |
890ddd |
if (rasCM32)
|
|
Toshihiro Shimizu |
890ddd |
m_rasType = Raster32CM;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
TRaster64P ras64(ras);
|
|
Toshihiro Shimizu |
890ddd |
if (ras64)
|
|
Toshihiro Shimizu |
890ddd |
m_rasType = Raster64RGBM;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
TRasterGR8P rasGR8(ras);
|
|
Toshihiro Shimizu |
890ddd |
if (rasGR8)
|
|
Toshihiro Shimizu |
890ddd |
m_rasType = RasterGR8;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
TRasterGR16P rasGR16(ras);
|
|
Toshihiro Shimizu |
890ddd |
if (rasGR16)
|
|
Toshihiro Shimizu |
890ddd |
m_rasType = RasterGR16;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
assert(!"Unknown RasterType");
|
|
Toshihiro Shimizu |
890ddd |
m_rasType = RasterUnknown;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterP Header::createRaster() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
switch (m_rasType) {
|
|
Toshihiro Shimizu |
890ddd |
case Raster32RGBM:
|
|
Toshihiro Shimizu |
890ddd |
return TRaster32P(m_lx, m_ly);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case Raster32CM:
|
|
Toshihiro Shimizu |
890ddd |
return TRasterCM32P(m_lx, m_ly);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case Raster64RGBM:
|
|
Toshihiro Shimizu |
890ddd |
return TRaster64P(m_lx, m_ly);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case RasterGR8:
|
|
Toshihiro Shimizu |
890ddd |
return TRasterGR8P(m_lx, m_ly);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case RasterGR16:
|
|
Toshihiro Shimizu |
890ddd |
return TRasterGR16P(m_lx, m_ly);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
default:
|
|
Toshihiro Shimizu |
890ddd |
assert(0);
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int Header::getRasterSize() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
switch (m_rasType) {
|
|
Toshihiro Shimizu |
890ddd |
case Raster32RGBM:
|
|
Toshihiro Shimizu |
890ddd |
return 4 * m_lx * m_ly;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case Raster32CM:
|
|
Toshihiro Shimizu |
890ddd |
return 4 * m_lx * m_ly;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case Raster64RGBM:
|
|
Toshihiro Shimizu |
890ddd |
return 8 * m_lx * m_ly;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case RasterGR8:
|
|
Toshihiro Shimizu |
890ddd |
return m_lx * m_ly;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
default:
|
|
Toshihiro Shimizu |
890ddd |
assert(0);
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
} //anonymous namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// TRasterCodecSnappy
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
/*TRasterCodecSnappy::TRasterCodecSnappy(const std::string &name, bool useCache)
|
|
Toshihiro Shimizu |
890ddd |
: TRasterCodec(name)
|
|
Toshihiro Shimizu |
890ddd |
, m_raster()
|
|
Toshihiro Shimizu |
890ddd |
, m_useCache(useCache)
|
|
Toshihiro Shimizu |
890ddd |
, m_cacheId("")
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterCodecSnappy::~TRasterCodecSnappy()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->remove(m_cacheId);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_raster = TRasterGR8P();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT TRasterCodecSnappy::doCompress(const TRasterP &inRas, int allocUnit, TRasterGR8P& outRas)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(inRas);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(inRas->getLx() == inRas->getWrap());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t inDataSize = inRas->getLx() * inRas->getLy() * inRas->getPixelSize();
|
|
Toshihiro Shimizu |
890ddd |
size_t maxReqSize = snappy_max_compressed_length(inDataSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_cacheId=="")
|
|
Toshihiro Shimizu |
890ddd |
m_cacheId = TImageCache::instance()->getUniqueId();
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
outRas = ((TRasterImageP)TImageCache::instance()->get(m_cacheId, true))->getRaster();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
outRas = m_raster;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas || outRas->getLx()<(int)maxReqSize)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
outRas = TRasterGR8P();
|
|
Toshihiro Shimizu |
890ddd |
m_raster = TRasterGR8P();
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->remove(m_cacheId);
|
|
Toshihiro Shimizu |
890ddd |
outRas = TRasterGR8P(maxReqSize, 1);
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->add(m_cacheId, TRasterImageP(outRas), true);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_raster = outRas;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
char* buffer = (char*) outRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
if (!buffer)
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
char* inData = (char*) inRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t outSize = maxReqSize;
|
|
Toshihiro Shimizu |
890ddd |
snappy_status r = snappy_compress(inData, inDataSize, buffer, &outSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
inRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if(r != SNAPPY_OK)
|
|
Toshihiro Shimizu |
890ddd |
throw TException("compress... something goes bad");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return outSize;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterP TRasterCodecSnappy::compress(const TRasterP &inRas, int allocUnit, TINT32 &outDataSize)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TRasterGR8P rasOut;
|
|
Toshihiro Shimizu |
890ddd |
UINT outSize = doCompress(inRas, allocUnit, rasOut);
|
|
Toshihiro Shimizu |
890ddd |
if (outSize==0)
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT headerSize = sizeof(Header);
|
|
Toshihiro Shimizu |
890ddd |
if (TBigMemoryManager::instance()->isActive() &&
|
|
Toshihiro Shimizu |
890ddd |
TBigMemoryManager::instance()->getAvailableMemoryinKb()<((outSize + headerSize)>>10))
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterGR8P r8(outSize + headerSize, 1);
|
|
Toshihiro Shimizu |
890ddd |
r8->lock();
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *memoryChunk = r8->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
if (!memoryChunk)
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
Header head(inRas);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
memcpy(memoryChunk, &head, headerSize);
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *tmp = memoryChunk + headerSize;
|
|
Toshihiro Shimizu |
890ddd |
rasOut->lock();
|
|
Toshihiro Shimizu |
890ddd |
memcpy(tmp, rasOut->getRawData(), outSize);
|
|
Toshihiro Shimizu |
890ddd |
r8->unlock();
|
|
Toshihiro Shimizu |
890ddd |
rasOut->unlock();
|
|
Toshihiro Shimizu |
890ddd |
outDataSize = outSize + headerSize;
|
|
Toshihiro Shimizu |
890ddd |
return r8;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRasterCodecSnappy::decompress(const UCHAR* inData, TINT32 inDataSize, TRasterP &outRas, bool safeMode)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int headerSize = sizeof(Header);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Header *header= (Header *)inData;
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
outRas = header->createRaster();
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas)
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (outRas->getLx() != outRas->getWrap())
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int outDataSize = header->getRasterSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
char* mc = (char*) inData + headerSize;
|
|
Toshihiro Shimizu |
890ddd |
int ds = inDataSize - headerSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t outSize;
|
|
Toshihiro Shimizu |
890ddd |
snappy_uncompressed_length(mc, ds, &outSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
snappy_status rc = snappy_uncompress(mc, ds, (char*) outRas->getRawData(), &outSize);
|
|
Toshihiro Shimizu |
890ddd |
outRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (rc != SNAPPY_OK)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (safeMode)
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
throw TException("decompress... something goes bad");
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(outSize == (size_t)outDataSize);
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRasterCodecSnappy::decompress(const TRasterP & compressedRas, TRasterP &outRas)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int headerSize = sizeof(Header);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(compressedRas->getLy()==1 && compressedRas->getPixelSize()==1);
|
|
Toshihiro Shimizu |
890ddd |
UINT inDataSize = compressedRas->getLx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
compressedRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UCHAR* inData = compressedRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
Header header(inData);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
outRas = header.createRaster();
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas)
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (outRas->getLx() != outRas->getWrap())
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int outDataSize = header.getRasterSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
char* mc = (char*) inData + headerSize;
|
|
Toshihiro Shimizu |
890ddd |
int ds = inDataSize - headerSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t outSize;
|
|
Toshihiro Shimizu |
890ddd |
snappy_uncompressed_length(mc, ds, &outSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
char* outData = (char*) outRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
snappy_status rc = snappy_uncompress(mc, ds, outData, &outSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
compressedRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (rc != SNAPPY_OK)
|
|
Toshihiro Shimizu |
890ddd |
throw TException("decompress... something goes bad");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(outSize == (size_t)outDataSize);
|
|
Toshihiro Shimizu |
890ddd |
}*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// TRasterCodecLz4
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool lz4decompress(LZ4F_decompressionContext_t lz4dctx,
|
|
Toshihiro Shimizu |
890ddd |
char *out, size_t *out_len_res,
|
|
Toshihiro Shimizu |
890ddd |
const char *in, size_t in_len)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
size_t out_len = *out_len_res,
|
|
Toshihiro Shimizu |
890ddd |
in_read, out_written;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
*out_len_res = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (in_len) {
|
|
Toshihiro Shimizu |
890ddd |
out_written = out_len;
|
|
Toshihiro Shimizu |
890ddd |
in_read = in_len;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t res = LZ4F_decompress(
|
|
Toshihiro Shimizu |
890ddd |
lz4dctx, (void *)out, &out_written, (const void *)in, &in_read, NULL);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (LZ4F_isError(res))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
*out_len_res += out_written;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
out += out_written;
|
|
Toshihiro Shimizu |
890ddd |
out_len -= out_written;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
in += in_read;
|
|
Toshihiro Shimizu |
890ddd |
in_len -= in_read;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
TRasterCodecLz4::TRasterCodecLz4(const std::string &name, bool useCache)
|
|
Toshihiro Shimizu |
890ddd |
: TRasterCodec(name), m_raster(), m_useCache(useCache), m_cacheId("")
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterCodecLz4::~TRasterCodecLz4()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->remove(m_cacheId);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_raster = TRasterGR8P();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT TRasterCodecLz4::doCompress(const TRasterP &inRas, int allocUnit, TRasterGR8P &outRas)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(inRas);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(inRas->getLx() == inRas->getWrap());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t inDataSize = inRas->getLx() * inRas->getLy() * inRas->getPixelSize();
|
|
Toshihiro Shimizu |
890ddd |
size_t maxReqSize = LZ4F_compressFrameBound(inDataSize, NULL);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache) {
|
|
Toshihiro Shimizu |
890ddd |
if (m_cacheId == "")
|
|
Toshihiro Shimizu |
890ddd |
m_cacheId = TImageCache::instance()->getUniqueId();
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
outRas = ((TRasterImageP)TImageCache::instance()->get(m_cacheId, true))->getRaster();
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
outRas = m_raster;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas || outRas->getLx() < (int)maxReqSize) {
|
|
Toshihiro Shimizu |
890ddd |
outRas = TRasterGR8P();
|
|
Toshihiro Shimizu |
890ddd |
m_raster = TRasterGR8P();
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->remove(m_cacheId);
|
|
Toshihiro Shimizu |
890ddd |
outRas = TRasterGR8P(maxReqSize, 1);
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->add(m_cacheId, TRasterImageP(outRas), true);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_raster = outRas;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
void *buffer = (void *)outRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
if (!buffer)
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
const void *inData = (const void *)inRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t outSize = LZ4F_compressFrame(buffer, maxReqSize, inData, inDataSize, NULL);
|
|
Toshihiro Shimizu |
890ddd |
outRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
inRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (LZ4F_isError(outSize))
|
|
Toshihiro Shimizu |
890ddd |
throw TException("compress... something goes bad");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return outSize;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterP TRasterCodecLz4::compress(const TRasterP &inRas, int allocUnit, TINT32 &outDataSize)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TRasterGR8P rasOut;
|
|
Toshihiro Shimizu |
890ddd |
UINT outSize = doCompress(inRas, allocUnit, rasOut);
|
|
Toshihiro Shimizu |
890ddd |
if (outSize == 0)
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT headerSize = sizeof(Header);
|
|
Toshihiro Shimizu |
890ddd |
if (TBigMemoryManager::instance()->isActive() &&
|
|
Toshihiro Shimizu |
890ddd |
TBigMemoryManager::instance()->getAvailableMemoryinKb() < ((outSize + headerSize) >> 10))
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterGR8P r8(outSize + headerSize, 1);
|
|
Toshihiro Shimizu |
890ddd |
r8->lock();
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *memoryChunk = r8->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
if (!memoryChunk)
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
Header head(inRas);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
memcpy(memoryChunk, &head, headerSize);
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *tmp = memoryChunk + headerSize;
|
|
Toshihiro Shimizu |
890ddd |
rasOut->lock();
|
|
Toshihiro Shimizu |
890ddd |
memcpy(tmp, rasOut->getRawData(), outSize);
|
|
Toshihiro Shimizu |
890ddd |
r8->unlock();
|
|
Toshihiro Shimizu |
890ddd |
rasOut->unlock();
|
|
Toshihiro Shimizu |
890ddd |
outDataSize = outSize + headerSize;
|
|
Toshihiro Shimizu |
890ddd |
return r8;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRasterCodecLz4::decompress(const UCHAR *inData, TINT32 inDataSize, TRasterP &outRas, bool safeMode)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int headerSize = sizeof(Header);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Header *header = (Header *)inData;
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas) {
|
|
Toshihiro Shimizu |
890ddd |
outRas = header->createRaster();
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas)
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
if (outRas->getLx() != outRas->getWrap())
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
LZ4F_decompressionContext_t lz4dctx;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
LZ4F_errorCode_t err = LZ4F_createDecompressionContext(&lz4dctx, LZ4F_VERSION);
|
|
Toshihiro Shimizu |
890ddd |
if (LZ4F_isError(err))
|
|
Toshihiro Shimizu |
890ddd |
throw TException("compress... something goes bad");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int outDataSize = header->getRasterSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const char *mc = (const char *)(inData + headerSize);
|
|
Toshihiro Shimizu |
890ddd |
size_t ds = inDataSize - headerSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t outSize = outDataSize;
|
|
Toshihiro Shimizu |
890ddd |
char *outData = (char *)outRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
//err = LZ4F_decompress(lz4dctx, outData, &outSize, mc, &ds, NULL);
|
|
Toshihiro Shimizu |
890ddd |
bool ok = lz4decompress(lz4dctx, outData, &outSize, mc, ds);
|
|
Toshihiro Shimizu |
890ddd |
LZ4F_freeDecompressionContext(lz4dctx);
|
|
Toshihiro Shimizu |
890ddd |
outRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!ok) {
|
|
Toshihiro Shimizu |
890ddd |
if (safeMode)
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
throw TException("decompress... something goes bad");
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(outSize == (size_t)outDataSize);
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRasterCodecLz4::decompress(const TRasterP &compressedRas, TRasterP &outRas)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int headerSize = sizeof(Header);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(compressedRas->getLy() == 1 && compressedRas->getPixelSize() == 1);
|
|
Toshihiro Shimizu |
890ddd |
UINT inDataSize = compressedRas->getLx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
compressedRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *inData = compressedRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
Header header(inData);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas) {
|
|
Toshihiro Shimizu |
890ddd |
outRas = header.createRaster();
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas)
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
if (outRas->getLx() != outRas->getWrap())
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
LZ4F_decompressionContext_t lz4dctx;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
LZ4F_errorCode_t err = LZ4F_createDecompressionContext(&lz4dctx, LZ4F_VERSION);
|
|
Toshihiro Shimizu |
890ddd |
if (LZ4F_isError(err))
|
|
Toshihiro Shimizu |
890ddd |
throw TException("compress... something goes bad");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int outDataSize = header.getRasterSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const char *mc = (const char *)(inData + headerSize);
|
|
Toshihiro Shimizu |
890ddd |
size_t ds = inDataSize - headerSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t outSize = outDataSize;
|
|
Toshihiro Shimizu |
890ddd |
char *outData = (char *)outRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//err = LZ4F_decompress(lz4dctx, outData, &outSize, mc, &ds, NULL);
|
|
Toshihiro Shimizu |
890ddd |
bool ok = lz4decompress(lz4dctx, outData, &outSize, mc, ds);
|
|
Toshihiro Shimizu |
890ddd |
LZ4F_freeDecompressionContext(lz4dctx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
compressedRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!ok)
|
|
Toshihiro Shimizu |
890ddd |
throw TException("decompress... something goes bad");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(outSize == (size_t)outDataSize);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// TRasterCodecLZO
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool lzoCompress(const QByteArray src, QByteArray &dst)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QDir exeDir(QCoreApplication::applicationDirPath());
|
|
Toshihiro Shimizu |
890ddd |
QString compressExe = exeDir.filePath("lzocompress");
|
|
Toshihiro Shimizu |
890ddd |
QProcess process;
|
|
Toshihiro Shimizu |
890ddd |
process.start(compressExe, QStringList() << QString::number(src.size()));
|
|
Toshihiro Shimizu |
890ddd |
if (!process.waitForStarted())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
process.write(src);
|
|
Toshihiro Shimizu |
890ddd |
if (!process.waitForFinished())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
dst = process.readAll();
|
|
Toshihiro Shimizu |
890ddd |
return process.exitCode() == 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool lzoDecompress(const QByteArray src, int dstSize, QByteArray &dst)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QDir exeDir(QCoreApplication::applicationDirPath());
|
|
Toshihiro Shimizu |
890ddd |
QString decompressExe = exeDir.filePath("lzodecompress");
|
|
Toshihiro Shimizu |
890ddd |
QProcess process;
|
|
Toshihiro Shimizu |
890ddd |
process.start(decompressExe, QStringList() << QString::number(dstSize) << QString::number(src.size()));
|
|
Toshihiro Shimizu |
890ddd |
if (!process.waitForStarted())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
process.write(src);
|
|
Toshihiro Shimizu |
890ddd |
if (!process.waitForFinished())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
dst = process.readAll();
|
|
Toshihiro Shimizu |
890ddd |
return process.exitCode() == 0 && dst.size() == dstSize;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
TRasterCodecLZO::TRasterCodecLZO(const std::string &name, bool useCache)
|
|
Toshihiro Shimizu |
890ddd |
: TRasterCodec(name), m_raster(), m_useCache(useCache), m_cacheId("")
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterCodecLZO::~TRasterCodecLZO()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->remove(m_cacheId);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_raster = TRasterGR8P();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT TRasterCodecLZO::doCompress(const TRasterP &inRas, int allocUnit, TRasterGR8P &outRas)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(inRas);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(inRas->getLx() == inRas->getWrap());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t inDataSize = inRas->getLx() * inRas->getLy() * inRas->getPixelSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// compress data
|
|
Toshihiro Shimizu |
890ddd |
inRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
char *inData = (char *)inRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
QByteArray compressedBuffer;
|
|
Toshihiro Shimizu |
890ddd |
if (!lzoCompress(QByteArray(inData, inDataSize), compressedBuffer))
|
|
Toshihiro Shimizu |
890ddd |
throw TException("LZO compression failed");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t maxReqSize = compressedBuffer.size(); // we have just done the compression: we know the actual size
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache) {
|
|
Toshihiro Shimizu |
890ddd |
if (m_cacheId == "")
|
|
Toshihiro Shimizu |
890ddd |
m_cacheId = TImageCache::instance()->getUniqueId();
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
outRas = ((TRasterImageP)TImageCache::instance()->get(m_cacheId, true))->getRaster();
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
outRas = m_raster;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas || outRas->getLx() < (int)maxReqSize) {
|
|
Toshihiro Shimizu |
890ddd |
outRas = TRasterGR8P();
|
|
Toshihiro Shimizu |
890ddd |
m_raster = TRasterGR8P();
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->remove(m_cacheId);
|
|
Toshihiro Shimizu |
890ddd |
outRas = TRasterGR8P(maxReqSize, 1);
|
|
Toshihiro Shimizu |
890ddd |
if (m_useCache)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->add(m_cacheId, TRasterImageP(outRas), true);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_raster = outRas;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t outSize = maxReqSize;
|
|
Toshihiro Shimizu |
890ddd |
outRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
char *buffer = (char *)outRas->getRawData(); // Change cast types, if needed
|
|
Toshihiro Shimizu |
890ddd |
if (!buffer) {
|
|
Toshihiro Shimizu |
890ddd |
outRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
memcpy(buffer, compressedBuffer.data(), outSize);
|
|
Toshihiro Shimizu |
890ddd |
outRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return outSize;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterP TRasterCodecLZO::compress(const TRasterP &inRas, int allocUnit, TINT32 &outDataSize)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TRasterGR8P rasOut;
|
|
Toshihiro Shimizu |
890ddd |
UINT outSize = doCompress(inRas, allocUnit, rasOut);
|
|
Toshihiro Shimizu |
890ddd |
if (outSize == 0)
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT headerSize = sizeof(Header);
|
|
Toshihiro Shimizu |
890ddd |
if (TBigMemoryManager::instance()->isActive() &&
|
|
Toshihiro Shimizu |
890ddd |
TBigMemoryManager::instance()->getAvailableMemoryinKb() < ((outSize + headerSize) >> 10))
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterGR8P r8(outSize + headerSize, 1);
|
|
Toshihiro Shimizu |
890ddd |
r8->lock();
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *memoryChunk = r8->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
if (!memoryChunk)
|
|
Toshihiro Shimizu |
890ddd |
return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
Header head(inRas);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
memcpy(memoryChunk, &head, headerSize);
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *tmp = memoryChunk + headerSize;
|
|
Toshihiro Shimizu |
890ddd |
rasOut->lock();
|
|
Toshihiro Shimizu |
890ddd |
memcpy(tmp, rasOut->getRawData(), outSize);
|
|
Toshihiro Shimizu |
890ddd |
r8->unlock();
|
|
Toshihiro Shimizu |
890ddd |
rasOut->unlock();
|
|
Toshihiro Shimizu |
890ddd |
outDataSize = outSize + headerSize;
|
|
Toshihiro Shimizu |
890ddd |
return r8;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRasterCodecLZO::decompress(const UCHAR *inData, TINT32 inDataSize, TRasterP &outRas, bool safeMode)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int headerSize = sizeof(Header);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Header *header = (Header *)inData;
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas) {
|
|
Toshihiro Shimizu |
890ddd |
outRas = header->createRaster();
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas)
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
if (outRas->getLx() != outRas->getWrap())
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int outDataSize = header->getRasterSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
char *mc = (char *)inData + headerSize;
|
|
Toshihiro Shimizu |
890ddd |
int ds = inDataSize - headerSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t outSize = outDataSize; // Calculate output buffer size
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QByteArray decompressedBuffer;
|
|
Toshihiro Shimizu |
890ddd |
if (!lzoDecompress(QByteArray(mc, ds), outSize, decompressedBuffer))
|
|
Toshihiro Shimizu |
890ddd |
throw TException("LZO decompression failed");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
memcpy(outRas->getRawData(), decompressedBuffer.data(), decompressedBuffer.size());
|
|
Toshihiro Shimizu |
890ddd |
bool rc = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
if (rc != true) // Check success code here
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (safeMode)
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
throw TException("decompress... something goes bad");
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(outSize == (size_t)outDataSize);
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRasterCodecLZO::decompress(const TRasterP &compressedRas, TRasterP &outRas)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int headerSize = sizeof(Header);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(compressedRas->getLy() == 1 && compressedRas->getPixelSize() == 1);
|
|
Toshihiro Shimizu |
890ddd |
UINT inDataSize = compressedRas->getLx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
compressedRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UCHAR *inData = compressedRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
Header header(inData);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas) {
|
|
Toshihiro Shimizu |
890ddd |
outRas = header.createRaster();
|
|
Toshihiro Shimizu |
890ddd |
if (!outRas)
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
if (outRas->getLx() != outRas->getWrap())
|
|
Toshihiro Shimizu |
890ddd |
throw TException();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int outDataSize = header.getRasterSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
char *mc = (char *)inData + headerSize;
|
|
Toshihiro Shimizu |
890ddd |
int ds = inDataSize - headerSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size_t outSize = outDataSize; // Calculate output buffer size
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
char *outData = (char *)outRas->getRawData();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QByteArray decompressedBuffer;
|
|
Toshihiro Shimizu |
890ddd |
if (!lzoDecompress(QByteArray(mc, ds), outSize, decompressedBuffer))
|
|
Toshihiro Shimizu |
890ddd |
throw TException("LZO decompression failed");
|
|
Toshihiro Shimizu |
890ddd |
outRas->lock();
|
|
Toshihiro Shimizu |
890ddd |
memcpy(outRas->getRawData(), decompressedBuffer.data(), decompressedBuffer.size());
|
|
Toshihiro Shimizu |
890ddd |
bool rc = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
compressedRas->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (rc != true) // Check success code here
|
|
Toshihiro Shimizu |
890ddd |
throw TException("decompress... something goes bad");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(outSize == (size_t)outDataSize);
|
|
Toshihiro Shimizu |
890ddd |
}
|