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
}