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
}