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