Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#include "tiio_tzl.h"
Toshihiro Shimizu 890ddd
#include "tmachine.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tfilepath_io.h"
Toshihiro Shimizu 890ddd
#include "tpixelcm.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tcodec.h"
Toshihiro Shimizu 890ddd
#include <stdio.h>
</stdio.h>
Toshihiro Shimizu 890ddd
#include "trastercm.h"
Toshihiro Shimizu 890ddd
#include "timageinfo.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tcontenthistory.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd

Campbell Barton d0e335
#include <qbytearray>
</qbytearray>
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !defined(TNZ_LITTLE_ENDIAN)
Toshihiro Shimizu 890ddd
TNZ_LITTLE_ENDIAN undefined !!
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	const int CURRENT_VERSION = 14;
Toshihiro Shimizu 890ddd
const int CREATOR_LENGTH = 40;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
char *reverse(char *buffer, int size)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	char *start = buffer;
Toshihiro Shimizu 890ddd
	char *end = start + size;
Toshihiro Shimizu 890ddd
	while (start < --end) {
Toshihiro Shimizu 890ddd
		char tmp = *start;
Toshihiro Shimizu 890ddd
		*start++ = *end;
Toshihiro Shimizu 890ddd
		*end = tmp;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return buffer;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
int tfwrite(const char *data, const unsigned int count, FILE *f)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return fwrite(data, sizeof(char), count, f);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
int tfwrite(UCHAR *data, const unsigned int count, FILE *f)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return fwrite(data, sizeof(char), count, f);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
int tfwrite(TINT32 *data, const unsigned int count, FILE *f)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (count == 1) {
Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
		TUINT32 dataToWrite = swapTINT32(*data);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		TUINT32 dataToWrite = *data;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		return fwrite(&dataToWrite, sizeof(TINT32), 1, f);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	assert(0);
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
int tfwrite(TUINT32 *data, const unsigned int count, FILE *f)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (count == 1) {
Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
		TUINT32 dataToWrite = swapTINT32(*data);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		TUINT32 dataToWrite = *data;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		return fwrite(&dataToWrite, sizeof(TINT32), 1, f);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	assert(0);
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
int tfwrite(double *data, unsigned int count, FILE *f)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (count == 1) {
Toshihiro Shimizu 890ddd
		double v = *data;
Toshihiro Shimizu 890ddd
		char *ptr = (char *)&v;
Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
		ptr = reverse((char *)&v, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		return fwrite(ptr, sizeof(double), 1, f);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	assert(0);
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TImageReaderTzl
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
bool erasedFrame; // Vera se รจ stato rimosso almeno un frame.
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
bool writeVersionAndCreator(FILE *chan, const char *version, QString creator)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!chan)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	tfwrite(version, strlen(version), chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// creator : CREATOR_LENGTH characater
Toshihiro Shimizu 890ddd
	char s[CREATOR_LENGTH];
Toshihiro Shimizu 890ddd
	if (creator.length() == 0)
Toshihiro Shimizu 890ddd
		creator = "UNKNOWN";
Toshihiro Shimizu 890ddd
	memset(s, 0, sizeof s);
Toshihiro Shimizu 890ddd
	if (creator.length() > CREATOR_LENGTH - 1)
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Toshihiro Shimizu 890ddd
		memcpy(s, creator.toLatin1(), CREATOR_LENGTH - 1);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		memcpy(s, creator.toAscii(), CREATOR_LENGTH - 1);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Toshihiro Shimizu 890ddd
		memcpy(s, creator.toLatin1(), creator.length());
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		memcpy(s, creator.toAscii(), creator.length());
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	tfwrite(s, CREATOR_LENGTH, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
bool readVersion(FILE *chan, int &version)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	char magic[8];
Toshihiro Shimizu 890ddd
	memset(magic, 0, sizeof(magic));
Toshihiro Shimizu 890ddd
	fread(&magic, sizeof(char), 8, chan);
Shinya Kitaoka 3bfa54
	if (std::string(magic).substr(0, 5) == "TLV10")
Toshihiro Shimizu 890ddd
		version = 10;
Shinya Kitaoka 3bfa54
	else if (std::string(magic, 5) == "TLV11")
Toshihiro Shimizu 890ddd
		version = 11;
Shinya Kitaoka 3bfa54
	else if (std::string(magic, 5) == "TLV12")
Toshihiro Shimizu 890ddd
		version = 12;
Shinya Kitaoka 3bfa54
	else if (std::string(magic, 5) == "TLV13")
Toshihiro Shimizu 890ddd
		version = 13;
Shinya Kitaoka 3bfa54
	else if (std::string(magic, 5) == "TLV14")
Toshihiro Shimizu 890ddd
		version = 14;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		fclose(chan);
Toshihiro Shimizu 890ddd
		chan = 0;
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
bool readHeaderAndOffsets(FILE *chan, TzlOffsetMap &frameOffsTable, TzlOffsetMap &iconOffsTable,
Toshihiro Shimizu 890ddd
						  TDimension &res, int &version, QString &creator, TINT32 *_frameCount, TINT32 *_offsetTablePos, TINT32 *_iconOffsetTablePos, TLevelP level)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TINT32 hdrSize;
Toshihiro Shimizu 890ddd
	TINT32 lx = 0, ly = 0, frameCount = 0;
Toshihiro Shimizu 890ddd
	char codec[4];
Toshihiro Shimizu 890ddd
	TINT32 offsetTablePos;
Toshihiro Shimizu 890ddd
	TINT32 iconOffsetTablePos;
Toshihiro Shimizu 890ddd
	//char magic[8];
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(frameOffsTable.empty());
Toshihiro Shimizu 890ddd
	assert(iconOffsTable.empty());
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!readVersion(chan, version))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// read creator
Toshihiro Shimizu 890ddd
	if (version == 14) {
Toshihiro Shimizu 890ddd
		char buffer[CREATOR_LENGTH + 1];
Toshihiro Shimizu 890ddd
		memset(buffer, 0, sizeof buffer);
Toshihiro Shimizu 890ddd
		fread(&buffer, sizeof(char), CREATOR_LENGTH, chan);
Toshihiro Shimizu 890ddd
		creator = buffer;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fread(&hdrSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&lx, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&ly, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&frameCount, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (version > 10) {
Toshihiro Shimizu 890ddd
		fread(&offsetTablePos, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&iconOffsetTablePos, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
		offsetTablePos = swapTINT32(offsetTablePos);
Toshihiro Shimizu 890ddd
		iconOffsetTablePos = swapTINT32(iconOffsetTablePos);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fread(&codec, 4, 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	hdrSize = swapTINT32(hdrSize);
Toshihiro Shimizu 890ddd
	lx = swapTINT32(lx);
Toshihiro Shimizu 890ddd
	ly = swapTINT32(ly);
Toshihiro Shimizu 890ddd
	frameCount = swapTINT32(frameCount);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	assert(0 < frameCount && frameCount < 60000);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (version > 10 && offsetTablePos != 0 && iconOffsetTablePos != 0) {
Toshihiro Shimizu 890ddd
		//assert(offsetTablePos>0);
Toshihiro Shimizu 890ddd
		assert(frameCount > 0);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		fseek(chan, offsetTablePos, SEEK_SET);
Toshihiro Shimizu 890ddd
		TFrameId oldFid(TFrameId::EMPTY_FRAME);
Toshihiro Shimizu 890ddd
		for (int i = 0; i < (int)frameCount; i++) {
Toshihiro Shimizu 890ddd
			TINT32 number, offs, length;
Toshihiro Shimizu 890ddd
			char letter;
Toshihiro Shimizu 890ddd
			fread(&number, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
			fread(&letter, sizeof(char), 1, chan);
Toshihiro Shimizu 890ddd
			fread(&offs, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
			if (version >= 12)
Toshihiro Shimizu 890ddd
				fread(&length, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
			number = swapTINT32(number);
Toshihiro Shimizu 890ddd
			offs = swapTINT32(offs);
Toshihiro Shimizu 890ddd
			if (version == 12)
Toshihiro Shimizu 890ddd
				length = swapTINT32(length);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
			//		std::cout << "#" << i << std::hex << " n 0x" << number << " l 0x" << letter << " o 0x" << offs << std::dec << std::endl;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
			TFrameId fid(number, letter);
Toshihiro Shimizu 890ddd
			//assert(i==0 || oldFid
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
			if (version >= 12) {
Toshihiro Shimizu 890ddd
				frameOffsTable[fid] = TzlChunk(offs, length);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				frameOffsTable[fid] = TzlChunk(offs, 0);
Toshihiro Shimizu 890ddd
				if (i > 0) {
Toshihiro Shimizu 890ddd
					frameOffsTable[oldFid].m_length = offs - frameOffsTable[oldFid].m_offs;
Toshihiro Shimizu 890ddd
					assert(frameOffsTable[oldFid].m_length > 0);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				if (i == frameCount - 1) {
Toshihiro Shimizu 890ddd
					frameOffsTable[fid].m_length = offsetTablePos - offs;
Toshihiro Shimizu 890ddd
					assert(frameOffsTable[fid].m_length > 0);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			oldFid = fid;
Toshihiro Shimizu 890ddd
			if (level)
Toshihiro Shimizu 890ddd
				level->setFrame(fid, TImageP());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (version >= 13) {
Toshihiro Shimizu 890ddd
			// Build IconOffsetTable
Toshihiro Shimizu 890ddd
			fseek(chan, iconOffsetTablePos, SEEK_SET);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
			for (int i = 0; i < (int)frameCount; i++) {
Toshihiro Shimizu 890ddd
				TINT32 number, thumbnailOffs, thumbnailLength;
Toshihiro Shimizu 890ddd
				char letter;
Toshihiro Shimizu 890ddd
				fread(&number, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
				fread(&letter, sizeof(char), 1, chan);
Toshihiro Shimizu 890ddd
				fread(&thumbnailOffs, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
				fread(&thumbnailLength, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
				number = swapTINT32(number);
Toshihiro Shimizu 890ddd
				thumbnailOffs = swapTINT32(thumbnailOffs);
Toshihiro Shimizu 890ddd
				thumbnailLength = swapTINT32(thumbnailLength);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
				TFrameId fid(number, letter);
Toshihiro Shimizu 890ddd
				iconOffsTable[fid] = TzlChunk(thumbnailOffs, thumbnailLength);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		//m_frameOffsTable.resize(frameCount);
Toshihiro Shimizu 890ddd
		frameOffsTable[TFrameId(1)] = TzlChunk(ftell(chan), 0);
Toshihiro Shimizu 890ddd
		iconOffsTable[TFrameId(1)] = TzlChunk(ftell(chan), 0);
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		for (i = 2; i <= (int)frameCount; i++) {
Toshihiro Shimizu 890ddd
			frameOffsTable[TFrameId(i)] = TzlChunk(0, 0);
Toshihiro Shimizu 890ddd
			iconOffsTable[TFrameId(i)] = TzlChunk(0, 0);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (level)
Toshihiro Shimizu 890ddd
			for (i = 1; i <= (int)frameCount; i++)
Toshihiro Shimizu 890ddd
				level->setFrame(TFrameId(i), TImageP());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	res.lx = lx;
Toshihiro Shimizu 890ddd
	res.ly = ly;
Toshihiro Shimizu 890ddd
	if (_offsetTablePos)
Toshihiro Shimizu 890ddd
		*_offsetTablePos = offsetTablePos;
Toshihiro Shimizu 890ddd
	if (_iconOffsetTablePos)
Toshihiro Shimizu 890ddd
		*_iconOffsetTablePos = iconOffsetTablePos;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (_frameCount)
Toshihiro Shimizu 890ddd
		*_frameCount = frameCount;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
bool adjustIconAspectRatio(TDimension &outDimension, TDimension inDimension, TDimension imageRes)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TINT32 iconLx = inDimension.lx, iconLy = inDimension.ly;
Toshihiro Shimizu 890ddd
	assert(iconLx > 0 && iconLy > 0);
Toshihiro Shimizu 890ddd
	assert(imageRes.lx > 0 && imageRes.ly > 0);
Toshihiro Shimizu 890ddd
	if (iconLx <= 0 || iconLy <= 0 || imageRes.lx <= 0 || imageRes.ly <= 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	int lx = imageRes.lx;
Toshihiro Shimizu 890ddd
	int ly = imageRes.ly;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (tmax(double(lx) / inDimension.lx, double(ly) / inDimension.ly) == double(ly) / inDimension.ly)
Toshihiro Shimizu 890ddd
		iconLx = tround((double(lx) * inDimension.ly) / ly);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		iconLy = tround((double(ly) * inDimension.lx) / lx);
Toshihiro Shimizu 890ddd
	outDimension = TDimension(iconLx, iconLy);
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void getThumbnail(TRasterP ras, int shrink, TRasterP &thumbnail)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int j = 0;
Toshihiro Shimizu 890ddd
	int y = 0;
Toshihiro Shimizu 890ddd
	TPixel32 *pix2 = (TPixel32 *)thumbnail->getRawData();
Toshihiro Shimizu 890ddd
	for (j = 0; j < thumbnail->getLy(); j++) {
Toshihiro Shimizu 890ddd
		ras->lock();
Toshihiro Shimizu 890ddd
		TPixel32 *pix = (TPixel32 *)ras->getRawData() + y * ras->getLx();
Toshihiro Shimizu 890ddd
		TPixel32 *endPix = pix2 + thumbnail->getLx();
Toshihiro Shimizu 890ddd
		while (pix2 < endPix) {
Toshihiro Shimizu 890ddd
			*pix2++ = *pix;
Toshihiro Shimizu 890ddd
			pix += shrink;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		y += shrink;
Toshihiro Shimizu 890ddd
		ras->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
class TImageReaderTzl : public TImageReader
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TImageReaderTzl(const TFilePath &f, const TFrameId &fid, TLevelReaderTzl *);
Toshihiro Shimizu 890ddd
	~TImageReaderTzl() {}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	// not implemented
Toshihiro Shimizu 890ddd
	TImageReaderTzl(const TImageReaderTzl &);
Toshihiro Shimizu 890ddd
	TImageReaderTzl &operator=(const TImageReaderTzl &src);
Toshihiro Shimizu 890ddd
	TImageP load10();
Toshihiro Shimizu 890ddd
	TImageP load11();
Toshihiro Shimizu 890ddd
	TImageP load13(); // Aggiunta iconcine
Toshihiro Shimizu 890ddd
	TImageP load14(); //	Aggiunto creator con lunghezza fissa
Toshihiro Shimizu 890ddd
	const TImageInfo *getImageInfo10() const;
Toshihiro Shimizu 890ddd
	const TImageInfo *getImageInfo11() const; // vale anche le versioni > di 11
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	//! Indice del frame del livello
Toshihiro Shimizu 890ddd
	TFrameId m_fid;
Toshihiro Shimizu 890ddd
	TImageP load();
Toshihiro Shimizu 890ddd
	TImageP loadIcon()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_isIcon = true;
Toshihiro Shimizu 890ddd
		return load();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	const TImageInfo *getImageInfo() const;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//TImageP doLoad();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TDimension getSize() const;
Toshihiro Shimizu 890ddd
	TRect getBBox() const;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	//! Size of image
Toshihiro Shimizu 890ddd
	int m_lx, m_ly;
Toshihiro Shimizu 890ddd
	bool m_isIcon;
Toshihiro Shimizu 890ddd
	//! Reference to level reader
Toshihiro Shimizu 890ddd
	TLevelReaderTzl *m_lrp;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TImageWriterTzl
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
class TImageWriterTzl : public TImageWriter
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//! Reference to level writer
Toshihiro Shimizu 890ddd
	TLevelWriterTzl *m_lwp;
Toshihiro Shimizu 890ddd
	TFrameId m_fid;
Toshihiro Shimizu 890ddd
	TDimension m_iconSize; // Dimensioni dell'iconcina salvata all'interno del file tlv
Toshihiro Shimizu 890ddd
						   //	In genere questo parametro viene settato come quello impostato dall'utente
Toshihiro Shimizu 890ddd
						   // nelle preferenze.
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TImageWriterTzl(TLevelWriterTzl *lw, TFrameId fid) : TImageWriter(TFilePath()), m_lwp(lw), m_fid(fid), m_iconSize(TDimension(80, 60)) {}
Toshihiro Shimizu 890ddd
	~TImageWriterTzl() {}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	// not implemented
Toshihiro Shimizu 890ddd
	TImageWriterTzl(const TImageWriterTzl &);
Toshihiro Shimizu 890ddd
	TImageWriterTzl &operator=(const TImageWriterTzl &src);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	void save(const TImageP &img) { m_lwp->save(img, m_fid); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TWriterInfo
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd

Shinya Kitaoka 3bfa54
TWriterInfo *TWriterInfoTzl::create(const std::string &ext) 
Toshihiro Shimizu 890ddd
{ 
Toshihiro Shimizu 890ddd
  return new TWriterInfoTzl(); 
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TWriterInfo *TWriterInfoTzl::clone() const 
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  return new TWriterInfoTzl(*this); 
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
class Header
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	enum RasType {
Toshihiro Shimizu 890ddd
		Raster32RGBM,
Toshihiro Shimizu 890ddd
		Raster64RGBM,
Toshihiro Shimizu 890ddd
		Raster32CM,
Toshihiro Shimizu 890ddd
		RasterGR8,
Toshihiro Shimizu 890ddd
		RasterUnknown
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	int m_lx;
Toshihiro Shimizu 890ddd
	int m_ly;
Toshihiro Shimizu 890ddd
	RasType m_rasType;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void TLevelWriterTzl::buildFreeChunksTable()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::set<tzlchunk> occupiedChunks;
</tzlchunk>
Toshihiro Shimizu 890ddd
	TzlOffsetMap::const_iterator it1 = m_frameOffsTable.begin();
Toshihiro Shimizu 890ddd
	TINT32 lastOccupiedPos = 0; // ultima posizione all'interno del file occupata dall'ultima immagine(grande o icona)
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	while (it1 != m_frameOffsTable.end()) {
Toshihiro Shimizu 890ddd
		occupiedChunks.insert(TzlChunk(it1->second.m_offs, it1->second.m_length));
Toshihiro Shimizu 890ddd
		if (it1->second.m_offs + it1->second.m_length > lastOccupiedPos)
Toshihiro Shimizu 890ddd
			lastOccupiedPos = it1->second.m_offs + it1->second.m_length - 1;
Toshihiro Shimizu 890ddd
		it1++;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	TzlOffsetMap::const_iterator iconIt1 = m_iconOffsTable.begin();
Toshihiro Shimizu 890ddd
	while (iconIt1 != m_iconOffsTable.end()) {
Toshihiro Shimizu 890ddd
		occupiedChunks.insert(TzlChunk(iconIt1->second.m_offs, iconIt1->second.m_length));
Toshihiro Shimizu 890ddd
		if (iconIt1->second.m_offs + iconIt1->second.m_length > lastOccupiedPos)
Toshihiro Shimizu 890ddd
			lastOccupiedPos = iconIt1->second.m_offs + iconIt1->second.m_length - 1;
Toshihiro Shimizu 890ddd
		iconIt1++;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	std::set<tzlchunk>::const_iterator it2 = occupiedChunks.begin();
</tzlchunk>
Toshihiro Shimizu 890ddd
	TINT32 curPos; // prima posizione utile nel file in cui vengono memorizzati i dati relativi alle immagini
Toshihiro Shimizu 890ddd
	if (m_version == 13)
Toshihiro Shimizu 890ddd
		curPos = 6 * sizeof(TINT32) + 4 * sizeof(char) + 8 * sizeof(char);
Toshihiro Shimizu 890ddd
	else if (m_version == 14)
Toshihiro Shimizu 890ddd
		curPos = 6 * sizeof(TINT32) + 4 * sizeof(char) + 8 * sizeof(char) + CREATOR_LENGTH * sizeof(char);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		curPos = it2->m_offs;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	while (it2 != occupiedChunks.end()) {
Toshihiro Shimizu 890ddd
		assert(it2->m_offs >= curPos);
Toshihiro Shimizu 890ddd
		if (it2->m_offs > curPos)
Toshihiro Shimizu 890ddd
			m_freeChunks.insert(TzlChunk(curPos, it2->m_offs - curPos));
Toshihiro Shimizu 890ddd
		curPos = it2->m_offs + it2->m_length;
Toshihiro Shimizu 890ddd
		it2++;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	assert(lastOccupiedPos < m_offsetTablePos);
Toshihiro Shimizu 890ddd
	if (lastOccupiedPos + 1 < m_offsetTablePos)
Toshihiro Shimizu 890ddd
		m_freeChunks.insert(TzlChunk(lastOccupiedPos + 1, m_offsetTablePos - lastOccupiedPos));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TLevelWriterTzl
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TLevelWriterTzl::TLevelWriterTzl(const TFilePath &path, TPropertyGroup *info)
Toshihiro Shimizu 890ddd
	: TLevelWriter(path, info), m_headerWritten(false), m_creatorWritten(false), m_chan(0), m_frameCountPos(0), m_frameCount(0), m_palette(0), m_res(0, 0), m_exists(false), m_version(CURRENT_VERSION), m_updatedIconsSize(false), m_currentIconSize(0, 0), m_iconSize(TDimension(80, 60)), m_userIconSize(TDimension(80, 60)), m_adjustRatio(false), m_codec(new TRasterCodecLZO("LZO", true)), m_overwritePaletteFlag(true)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_path = path;
Toshihiro Shimizu 890ddd
	m_palettePath = path.withNoFrame().withType("tpl");
Toshihiro Shimizu 890ddd
	TFileStatus fs(path);
Toshihiro Shimizu 890ddd
	m_magic = "TLV14B1a"; // actual version
Toshihiro Shimizu 890ddd
	erasedFrame = false;
Toshihiro Shimizu 890ddd
	// version TLV10B1a: first version
Toshihiro Shimizu 890ddd
	// version TLV11B1a: added frameIds
Toshihiro Shimizu 890ddd
	// version TLV12B1a: incremental writings
Toshihiro Shimizu 890ddd
	// version TLV13B1a: added thumbnails
Toshihiro Shimizu 890ddd
	// version TLV15B1a: add creator string (fixed size = CREATOR_LENGTH char)
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (fs.doesExist()) {
Toshihiro Shimizu 890ddd
		//if (!fs.isWritable())
Toshihiro Shimizu 890ddd
		m_chan = fopen(path, "rb+");
Toshihiro Shimizu 890ddd
		/*--- ่ชฐใ‹ใŒ้–‹ใ„ใฆใ„ใ‚‹ใ€ใพใŸใฏๆจฉ้™ใŒ็„กใ„ใจใ ---*/
Toshihiro Shimizu 890ddd
		if (!m_chan) {
Toshihiro Shimizu 890ddd
			throw TSystemException(path, "can't fopen.");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		/*--- TLVใƒ•ใ‚กใ‚คใƒซใฎใƒ˜ใƒƒใƒ€ใŒๆญฃใ—ใ่ชญใ‚ใชใ‹ใฃใŸๅ ดๅˆ ---*/
Toshihiro Shimizu 890ddd
		if (!readHeaderAndOffsets(m_chan,
Toshihiro Shimizu 890ddd
								  m_frameOffsTable,
Toshihiro Shimizu 890ddd
								  m_iconOffsTable,
Toshihiro Shimizu 890ddd
								  m_res,
Toshihiro Shimizu 890ddd
								  m_version,
Toshihiro Shimizu 890ddd
								  m_creator,
Toshihiro Shimizu 890ddd
								  &m_frameCount,
Toshihiro Shimizu 890ddd
								  &m_offsetTablePos,
Toshihiro Shimizu 890ddd
								  &m_iconOffsetTablePos,
Toshihiro Shimizu 890ddd
								  0)) {
Toshihiro Shimizu 890ddd
			throw TSystemException(path, "can't readHeaderAndOffsets.");
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			if (m_version >= 12)
Toshihiro Shimizu 890ddd
				buildFreeChunksTable();
Toshihiro Shimizu 890ddd
			m_headerWritten = true;
Toshihiro Shimizu 890ddd
			m_exists = true;
Toshihiro Shimizu 890ddd
			if (m_version == 14)
Toshihiro Shimizu 890ddd
				m_frameCountPos = 8 + CREATOR_LENGTH + 3 * sizeof(TINT32);
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				m_frameCountPos = 8 + 3 * sizeof(TINT32);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (!m_exists) {
Toshihiro Shimizu 890ddd
		TFilePath parentDir = path.getParentDir();
Toshihiro Shimizu 890ddd
		if (!TFileStatus(parentDir).doesExist()) {
Toshihiro Shimizu 890ddd
			try {
Toshihiro Shimizu 890ddd
				TSystem::mkDir(parentDir);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
			} catch (...) {
Toshihiro Shimizu 890ddd
				return;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		m_chan = fopen(path, "wb");
Toshihiro Shimizu 890ddd
		if (!m_chan)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (!writeVersionAndCreator(m_chan, m_magic, m_creator))
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TLevelWriterTzl::~TLevelWriterTzl()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_version < CURRENT_VERSION) {
Toshihiro Shimizu 890ddd
		if (!convertToLatestVersion())
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		assert(m_version == CURRENT_VERSION);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	delete m_codec;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TINT32 offsetMapPos = 0;
Toshihiro Shimizu 890ddd
	TINT32 iconOffsetMapPos = 0;
Toshihiro Shimizu 890ddd
	if (!m_chan)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(m_frameCount == (int)m_frameOffsTable.size());
Toshihiro Shimizu 890ddd
	assert(m_frameCount == (int)m_iconOffsTable.size());
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	offsetMapPos = (m_exists ? m_offsetTablePos : ftell(m_chan));
Toshihiro Shimizu 890ddd
	fseek(m_chan, offsetMapPos, SEEK_SET);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it = m_frameOffsTable.begin();
Toshihiro Shimizu 890ddd
	for (; it != m_frameOffsTable.end(); ++it) {
Toshihiro Shimizu 890ddd
		TFrameId fid = it->first;
Toshihiro Shimizu 890ddd
		TINT32 num = fid.getNumber();
Toshihiro Shimizu 890ddd
		char letter = fid.getLetter();
Toshihiro Shimizu 890ddd
		TINT32 offs = it->second.m_offs;
Toshihiro Shimizu 890ddd
		TINT32 length = it->second.m_length;
Toshihiro Shimizu 890ddd
		tfwrite(&num, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&letter, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&offs, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&length, 1, m_chan);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// Write Icon Offset Table after frameOffsTable
Toshihiro Shimizu 890ddd
	iconOffsetMapPos = ftell(m_chan); //(m_exists?m_iconOffsetTablePos: ftell(m_chan));
Toshihiro Shimizu 890ddd
	fseek(m_chan, iconOffsetMapPos, SEEK_SET);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator iconIt = m_iconOffsTable.begin();
Toshihiro Shimizu 890ddd
	for (; iconIt != m_iconOffsTable.end(); ++iconIt) {
Toshihiro Shimizu 890ddd
		TFrameId fid = iconIt->first;
Toshihiro Shimizu 890ddd
		TINT32 num = fid.getNumber();
Toshihiro Shimizu 890ddd
		char letter = fid.getLetter();
Toshihiro Shimizu 890ddd
		TINT32 thumbnailOffs = iconIt->second.m_offs;
Toshihiro Shimizu 890ddd
		TINT32 thumbnailLength = iconIt->second.m_length;
Toshihiro Shimizu 890ddd
		tfwrite(&num, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&letter, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&thumbnailOffs, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&thumbnailLength, 1, m_chan);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fseek(m_chan, m_frameCountPos, SEEK_SET);
Toshihiro Shimizu 890ddd
	TINT32 frameCount = m_frameCount;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	tfwrite(&frameCount, 1, m_chan);
Toshihiro Shimizu 890ddd
	tfwrite(&offsetMapPos, 1, m_chan);
Toshihiro Shimizu 890ddd
	tfwrite(&iconOffsetMapPos, 1, m_chan);
Toshihiro Shimizu 890ddd
	fclose(m_chan);
Toshihiro Shimizu 890ddd
	m_chan = 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (m_palette && m_overwritePaletteFlag && (m_palette->getDirtyFlag() || !TSystem::doesExistFileOrLevel(m_palettePath))) {
Toshihiro Shimizu 890ddd
		TOStream os(m_palettePath);
Toshihiro Shimizu 890ddd
		os << m_palette;
Toshihiro Shimizu 890ddd
		m_palette->release();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (m_contentHistory) {
Toshihiro Shimizu 890ddd
		TFilePath historyFp = m_path.withNoFrame().withType("hst");
Toshihiro Shimizu 890ddd
		FILE *historyChan = fopen(historyFp, "w");
Toshihiro Shimizu 890ddd
		if (historyChan) {
Shinya Kitaoka 3bfa54
			std::string historyData = m_contentHistory->serialize().toStdString();
Toshihiro Shimizu 890ddd
			fwrite(&historyData[0], 1, historyData.length(), historyChan);
Toshihiro Shimizu 890ddd
			fclose(historyChan);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	// Se lo spazio libero (cioรจ la somma di tutti i buchi che si sono creati tra i frame)
Toshihiro Shimizu 890ddd
	// รจ maggiore di una certa soglia oppure รจ stato rimosso almeno un frame allora ottimizzo il file
Toshihiro Shimizu 890ddd
	// (in pratica risalvo il file da capo senza buchi).
Toshihiro Shimizu 890ddd
	if (getFreeSpace() > 0.3 || erasedFrame)
Toshihiro Shimizu 890ddd
		optimize();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TImageWriterP TLevelWriterTzl::getFrameWriter(TFrameId fid)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return new TImageWriterTzl(this, fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void TLevelWriterTzl::writeHeader(const TDimension &size)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_headerWritten = true;
Toshihiro Shimizu 890ddd
	const char *codec = "LZO ";
Toshihiro Shimizu 890ddd
	int codecLen = strlen(codec);
Toshihiro Shimizu 890ddd
	TINT32 hdrSize = 3 * sizeof(TINT32) + codecLen;
Toshihiro Shimizu 890ddd
	TINT32 lx = size.lx, ly = size.ly, intval = 1;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	tfwrite(&hdrSize, 1, m_chan);
Toshihiro Shimizu 890ddd
	tfwrite(&lx, 1, m_chan);
Toshihiro Shimizu 890ddd
	tfwrite(&ly, 1, m_chan);
Toshihiro Shimizu 890ddd
	m_frameCountPos = ftell(m_chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(m_frameCountPos == 8 + CREATOR_LENGTH + 3 * sizeof(TINT32));
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//I put the place for the frameCount, which I will write in this position at the end  (see in the distructor)
Toshihiro Shimizu 890ddd
	tfwrite(&intval, 1, m_chan);
Toshihiro Shimizu 890ddd
	//I put the place for the offsetTableOffset, which I will write in this position at the end  (see in the distructor)
Toshihiro Shimizu 890ddd
	intval = 0;
Toshihiro Shimizu 890ddd
	tfwrite(&intval, 1, m_chan);
Toshihiro Shimizu 890ddd
	//I put the place for the iconOffsetTableOffset, which I will write in this position at the end  (see in the distructor)
Toshihiro Shimizu 890ddd
	tfwrite(&intval, 1, m_chan);
Toshihiro Shimizu 890ddd
	tfwrite(codec, codecLen, m_chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void TLevelWriterTzl::addFreeChunk(TINT32 offs, TINT32 length)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::set<tzlchunk>::iterator it = m_freeChunks.begin();
</tzlchunk>
Toshihiro Shimizu 890ddd
	while (it != m_freeChunks.end()) {
Toshihiro Shimizu 890ddd
		//if (it->m_offs>offs+length+1)
Toshihiro Shimizu 890ddd
		//  break;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		if (it->m_offs + it->m_length == offs) //accorpo due chunks in uno
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			TzlChunk chunk(it->m_offs, it->m_length + length);
Toshihiro Shimizu 890ddd
			m_freeChunks.erase(it);
Toshihiro Shimizu 890ddd
			m_freeChunks.insert(chunk);
Toshihiro Shimizu 890ddd
			//it->m_length += length;
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		} else if (offs + length == it->m_offs) {
Toshihiro Shimizu 890ddd
			TzlChunk chunk(offs, it->m_length + length);
Toshihiro Shimizu 890ddd
			m_freeChunks.erase(it);
Toshihiro Shimizu 890ddd
			m_freeChunks.insert(chunk);
Toshihiro Shimizu 890ddd
			//it->m_offs = offs;
Toshihiro Shimizu 890ddd
			//it->m_length += length;
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		it++;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (it == m_freeChunks.end())
Toshihiro Shimizu 890ddd
		m_freeChunks.insert(TzlChunk(offs, length));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TINT32 TLevelWriterTzl::findSavingChunk(const TFrameId &fid, TINT32 length, bool isIcon)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it;
Toshihiro Shimizu 890ddd
	//prima libero il chunk del fid, se c'e'. accorpo con altro chunk se trovo uno contiguo.
Toshihiro Shimizu 890ddd
	if (!isIcon) {
Toshihiro Shimizu 890ddd
		if ((it = m_frameOffsTable.find(fid)) != m_frameOffsTable.end()) {
Toshihiro Shimizu 890ddd
			addFreeChunk(it->second.m_offs, it->second.m_length);
Toshihiro Shimizu 890ddd
			m_frameOffsTable.erase(it);
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			m_frameCount++;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		if ((it = m_iconOffsTable.find(fid)) != m_iconOffsTable.end()) {
Toshihiro Shimizu 890ddd
			addFreeChunk(it->second.m_offs, it->second.m_length);
Toshihiro Shimizu 890ddd
			m_iconOffsTable.erase(it);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//ora cerco un cioncone libero con la piu' piccola memoria sufficiente
Toshihiro Shimizu 890ddd
	std::set<tzlchunk>::iterator it1 = m_freeChunks.begin(), found = m_freeChunks.end();
</tzlchunk>
Toshihiro Shimizu 890ddd
	for (; it1 != m_freeChunks.end(); it1++) {
Toshihiro Shimizu 890ddd
		//   TINT32 _length = it1->m_length;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		if (it1->m_length >= length &&
Toshihiro Shimizu 890ddd
			(found == m_freeChunks.end() ||
Toshihiro Shimizu 890ddd
			 found->m_length > it1->m_length))
Toshihiro Shimizu 890ddd
			found = it1;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (found != m_freeChunks.end()) {
Toshihiro Shimizu 890ddd
		//  TINT32 _length = found->m_length;
Toshihiro Shimizu 890ddd
		TINT32 _offset = found->m_offs;
Toshihiro Shimizu 890ddd
		if (found->m_length > length) {
Toshihiro Shimizu 890ddd
			TzlChunk chunk(found->m_offs + length, found->m_length - length);
Toshihiro Shimizu 890ddd
			m_freeChunks.insert(chunk);
Toshihiro Shimizu 890ddd
			//found->m_offs+=length;
Toshihiro Shimizu 890ddd
			//found->m_length-=length;
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			assert(found->m_length == length);
Toshihiro Shimizu 890ddd
		m_freeChunks.erase(found);
Toshihiro Shimizu 890ddd
		return _offset;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		m_offsetTablePos += length;
Toshihiro Shimizu 890ddd
		return m_offsetTablePos - length;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
bool TLevelWriterTzl::convertToLatestVersion()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFileStatus fs(m_path);
Toshihiro Shimizu 890ddd
	// se il file รจ di una versione precedente deve necessariamente giร  esistere su disco
Toshihiro Shimizu 890ddd
	assert(fs.doesExist());
Toshihiro Shimizu 890ddd
	if (!fs.doesExist())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	m_exists = false;
Toshihiro Shimizu 890ddd
	m_frameCount = 0;
Toshihiro Shimizu 890ddd
	m_frameOffsTable = TzlOffsetMap();
Toshihiro Shimizu 890ddd
	m_iconOffsTable = TzlOffsetMap();
Toshihiro Shimizu 890ddd
	m_headerWritten = false;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fclose(m_chan);
Toshihiro Shimizu 890ddd
	m_chan = 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	std::string tempName = "~" + m_path.getName() + "tmp&.tlv";
Toshihiro Shimizu 890ddd
	TFilePath tempPath = TSystem::getTempDir() + tempName;
Toshihiro Shimizu 890ddd
	if (TSystem::doesExistFileOrLevel(m_path)) {
Toshihiro Shimizu 890ddd
		assert(m_path != tempPath);
Toshihiro Shimizu 890ddd
		if (TSystem::doesExistFileOrLevel(tempPath))
Toshihiro Shimizu 890ddd
			TSystem::deleteFile(tempPath);
Toshihiro Shimizu 890ddd
		TSystem::copyFile(tempPath, m_path);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	m_chan = fopen(m_path, "rb+");
Toshihiro Shimizu 890ddd
	if (!m_chan)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (!writeVersionAndCreator(m_chan, m_magic, m_creator))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	m_creatorWritten = true;
Toshihiro Shimizu 890ddd
	m_version = CURRENT_VERSION;
Toshihiro Shimizu 890ddd
	TLevelReaderP lr(tempPath);
Toshihiro Shimizu 890ddd
	if (!lr)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	TLevelP level = lr->loadInfo();
Toshihiro Shimizu 890ddd
	for (TLevel::Iterator it = level->begin(); it != level->end(); ++it) {
Toshihiro Shimizu 890ddd
		save(lr->getFrameReader(it->first)->load(), it->first);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	lr = TLevelReaderP();
Toshihiro Shimizu 890ddd
	if (TSystem::doesExistFileOrLevel(tempPath)) {
Toshihiro Shimizu 890ddd
		TSystem::deleteFile(tempPath);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TINT32 offsetMapPos = 0;
Toshihiro Shimizu 890ddd
	TINT32 iconOffsetMapPos = 0;
Toshihiro Shimizu 890ddd
	if (!m_chan)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(m_frameCount == (int)m_frameOffsTable.size());
Toshihiro Shimizu 890ddd
	assert(m_frameCount == (int)m_iconOffsTable.size());
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	offsetMapPos = (m_exists ? m_offsetTablePos : ftell(m_chan));
Toshihiro Shimizu 890ddd
	fseek(m_chan, offsetMapPos, SEEK_SET);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it2 = m_frameOffsTable.begin();
Toshihiro Shimizu 890ddd
	for (; it2 != m_frameOffsTable.end(); ++it2) {
Toshihiro Shimizu 890ddd
		TFrameId fid = it2->first;
Toshihiro Shimizu 890ddd
		TINT32 num = fid.getNumber();
Toshihiro Shimizu 890ddd
		char letter = fid.getLetter();
Toshihiro Shimizu 890ddd
		TINT32 offs = it2->second.m_offs;
Toshihiro Shimizu 890ddd
		TINT32 length = it2->second.m_length;
Toshihiro Shimizu 890ddd
		tfwrite(&num, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&letter, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&offs, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&length, 1, m_chan);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	iconOffsetMapPos = ftell(m_chan);
Toshihiro Shimizu 890ddd
	fseek(m_chan, iconOffsetMapPos, SEEK_SET);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator iconIt = m_iconOffsTable.begin();
Toshihiro Shimizu 890ddd
	for (; iconIt != m_iconOffsTable.end(); ++iconIt) {
Toshihiro Shimizu 890ddd
		TFrameId fid = iconIt->first;
Toshihiro Shimizu 890ddd
		TINT32 num = fid.getNumber();
Toshihiro Shimizu 890ddd
		char letter = fid.getLetter();
Toshihiro Shimizu 890ddd
		TINT32 thumbnailOffs = iconIt->second.m_offs;
Toshihiro Shimizu 890ddd
		TINT32 thumbnailLength = iconIt->second.m_length;
Toshihiro Shimizu 890ddd
		tfwrite(&num, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&letter, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&thumbnailOffs, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&thumbnailLength, 1, m_chan);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fseek(m_chan, m_frameCountPos, SEEK_SET);
Toshihiro Shimizu 890ddd
	TINT32 frameCount = m_frameCount;
Toshihiro Shimizu 890ddd
	tfwrite(&frameCount, 1, m_chan);
Toshihiro Shimizu 890ddd
	tfwrite(&offsetMapPos, 1, m_chan);
Toshihiro Shimizu 890ddd
	tfwrite(&iconOffsetMapPos, 1, m_chan);
Toshihiro Shimizu 890ddd
	m_frameOffsTable = TzlOffsetMap();
Toshihiro Shimizu 890ddd
	m_iconOffsTable = TzlOffsetMap();
Toshihiro Shimizu 890ddd
	m_frameCount = 0;
Toshihiro Shimizu 890ddd
	m_res = TDimension();
Toshihiro Shimizu 890ddd
	fclose(m_chan);
Toshihiro Shimizu 890ddd
	m_chan = 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (m_palette && (m_palette->getDirtyFlag() || !TSystem::doesExistFileOrLevel(m_palettePath))) {
Toshihiro Shimizu 890ddd
		TOStream os(m_palettePath);
Toshihiro Shimizu 890ddd
		os << m_palette;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//else
Toshihiro Shimizu 890ddd
	//	m_palette = 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	m_chan = fopen(m_path, "rb+");
Toshihiro Shimizu 890ddd
	if (!m_chan)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (!readHeaderAndOffsets(m_chan, m_frameOffsTable, m_iconOffsTable, m_res, m_version, m_creator, &m_frameCount, &m_offsetTablePos, &m_iconOffsetTablePos, 0))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	m_freeChunks.clear();
Toshihiro Shimizu 890ddd
	buildFreeChunksTable();
Toshihiro Shimizu 890ddd
	m_headerWritten = true;
Toshihiro Shimizu 890ddd
	m_exists = true;
Toshihiro Shimizu 890ddd
	m_frameCountPos = 8 + CREATOR_LENGTH + 3 * sizeof(TINT32);
Toshihiro Shimizu 890ddd
	assert(m_version == CURRENT_VERSION);
Toshihiro Shimizu 890ddd
	if (!m_renumberTable.empty())
Toshihiro Shimizu 890ddd
		renumberFids(m_renumberTable);
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
void TLevelWriterTzl::saveImage(const TImageP &img, const TFrameId &_fid, bool isIcon)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFrameId fid = _fid;
Toshihiro Shimizu 890ddd
	if (!m_chan)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// se il file รจ di una versione precedente allora lo converto prima
Toshihiro Shimizu 890ddd
	if (m_version < CURRENT_VERSION) {
Toshihiro Shimizu 890ddd
		if (!convertToLatestVersion())
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		assert(m_version == CURRENT_VERSION);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!m_updatedIconsSize && m_exists)
Toshihiro Shimizu 890ddd
		m_updatedIconsSize = checkIconSize(getIconSize());
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TToonzImageP ti = img;
Toshihiro Shimizu 890ddd
	if (!ti)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!m_palette) {
Toshihiro Shimizu 890ddd
		m_palette = ti->getPalette();
Toshihiro Shimizu 890ddd
		if (m_palette)
Toshihiro Shimizu 890ddd
			m_palette->addRef();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!m_creatorWritten) {
Toshihiro Shimizu 890ddd
		fseek(m_chan, 0, SEEK_SET);
Toshihiro Shimizu 890ddd
		writeVersionAndCreator(m_chan, m_magic, m_creator);
Toshihiro Shimizu 890ddd
		m_creatorWritten = true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (!m_headerWritten)
Toshihiro Shimizu 890ddd
		writeHeader(ti->getSize());
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (m_res != TDimension())
Toshihiro Shimizu 890ddd
		if (!isIcon)
Toshihiro Shimizu 890ddd
			assert(m_res == ti->getSize());
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			assert(getIconSize() == ti->getSize());
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		m_res = ti->getSize();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRect sb = ti->getSavebox();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TINT32 sbx0 = sb.x0, sby0 = sb.y0, sblx = sb.getLx(), sbly = sb.getLy();
Toshihiro Shimizu 890ddd
	TINT32 buffSize = 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	UCHAR *buff = 0; //  = ti->getCompressedBuffer(buffSize);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRasterP cmras = ti->getRaster();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(cmras);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (cmras->getBounds() != sb) {
Toshihiro Shimizu 890ddd
		TRect rectToExtract = sb;
Toshihiro Shimizu 890ddd
		if (!rectToExtract.isEmpty()) {
Toshihiro Shimizu 890ddd
			TRasterP smallRaster = cmras->extract(rectToExtract)->clone();
Toshihiro Shimizu 890ddd
			assert(rectToExtract == sb);
Toshihiro Shimizu 890ddd
			cmras = smallRaster;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			cmras = cmras->create(1, 1);
Toshihiro Shimizu 890ddd
			cmras->clear();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRasterGR8P rCompressed = m_codec->compress(cmras, 1, buffSize);
Toshihiro Shimizu 890ddd
	if (rCompressed == TRasterGR8P()) {
Toshihiro Shimizu 890ddd
		static bool firstTime = true;
Toshihiro Shimizu 890ddd
		if (firstTime) {
Toshihiro Shimizu 890ddd
			firstTime = false;
Toshihiro Shimizu 890ddd
			//MessageBox( NULL, "Cannot save level, out of memory!", "Warning!", MB_OK);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	rCompressed->lock();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	buffSize = rCompressed->getLx();
Toshihiro Shimizu 890ddd
	buff = rCompressed->getRawData();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(buffSize);
Toshihiro Shimizu 890ddd
	assert(buff);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	Header *header = (Header *)buff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRasterP ras;
Toshihiro Shimizu 890ddd
	m_codec->decompress(buff, buffSize, ras);
Toshihiro Shimizu 890ddd
	delete[] buff;
Toshihiro Shimizu 890ddd
	assert((TRasterCM32P)ras);
Toshihiro Shimizu 890ddd
	assert(ras->getLx() == header->m_lx);
Toshihiro Shimizu 890ddd
	assert(ras->getLy() == header->m_ly);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	for (int y = 0; y < ras->getLy(); ++y) {
Toshihiro Shimizu 890ddd
		ras->lock();
Toshihiro Shimizu 890ddd
		TINT32 *pix = ((TINT32 *)ras->getRawData()) + y * ras->getLx();
Toshihiro Shimizu 890ddd
		TINT32 *endPix = pix + ras->getLx();
Toshihiro Shimizu 890ddd
		while (pix < endPix) {
Toshihiro Shimizu 890ddd
			*pix = swapTINT32(*pix);
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		ras->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	rCompressed = m_codec->compress(ras, 1, buffSize);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	header = (Header *)buff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	header->m_lx = swapTINT32(header->m_lx);
Toshihiro Shimizu 890ddd
	header->m_ly = swapTINT32(header->m_ly);
Toshihiro Shimizu 890ddd
	header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	double xdpi = 1, ydpi = 1;
Toshihiro Shimizu 890ddd
	ti->getDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TINT32 theBuffSize = buffSize;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TINT32 length = 0;
Toshihiro Shimizu 890ddd
	if (!isIcon)
Toshihiro Shimizu 890ddd
		length = 5 * sizeof(TINT32) + 2 * sizeof(double) + theBuffSize;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		length = 3 * sizeof(TINT32) + theBuffSize;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (fid == TFrameId()) {
Toshihiro Shimizu 890ddd
		assert(!m_exists);
Toshihiro Shimizu 890ddd
		if (m_frameOffsTable.empty())
Toshihiro Shimizu 890ddd
			fid = (m_frameOffsTable.empty()) ? TFrameId(1, 0) : TFrameId(m_frameOffsTable.rbegin()->first.getNumber() + 1, 0);
Toshihiro Shimizu 890ddd
		if (m_iconOffsTable.empty())
Toshihiro Shimizu 890ddd
			fid = (m_iconOffsTable.empty()) ? TFrameId(1, 0) : TFrameId(m_iconOffsTable.rbegin()->first.getNumber() + 1, 0);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!m_exists) {
Toshihiro Shimizu 890ddd
		long offs = ftell(m_chan);
Toshihiro Shimizu 890ddd
		if (!isIcon) {
Toshihiro Shimizu 890ddd
			m_frameOffsTable[fid] = TzlChunk(offs, length);
Toshihiro Shimizu 890ddd
			m_frameCount++;
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			m_iconOffsTable[fid] = TzlChunk(offs, length);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		long frameOffset = findSavingChunk(fid, length, isIcon);
Toshihiro Shimizu 890ddd
		if (!isIcon)
Toshihiro Shimizu 890ddd
			m_frameOffsTable[fid] = TzlChunk(frameOffset, length);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			m_iconOffsTable[fid] = TzlChunk(frameOffset, length);
Toshihiro Shimizu 890ddd
		fseek(m_chan, frameOffset, SEEK_SET);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (!isIcon) {
Toshihiro Shimizu 890ddd
		tfwrite(&sbx0, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&sby0, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&sblx, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&sbly, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&buffSize, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&xdpi, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&ydpi, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(buff, theBuffSize, m_chan);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		TINT32 iconLx = getIconSize().lx;
Toshihiro Shimizu 890ddd
		TINT32 iconLy = getIconSize().ly;
Toshihiro Shimizu 890ddd
		tfwrite(&iconLx, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&iconLy, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(&buffSize, 1, m_chan);
Toshihiro Shimizu 890ddd
		tfwrite(buff, theBuffSize, m_chan);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	rCompressed->unlock();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	//delete [] buff;
Toshihiro Shimizu 890ddd
	//#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void TLevelWriterTzl::doSave(const TImageP &img, const TFrameId &_fid)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// salvo l'immagine grande
Toshihiro Shimizu 890ddd
	saveImage(img, _fid);
Toshihiro Shimizu 890ddd
	if (!img)
Toshihiro Shimizu 890ddd
		throw(TException("Saving tlv: it is not possible to create the image frame."));
Toshihiro Shimizu 890ddd
	// creo l'iconcina
Toshihiro Shimizu 890ddd
	TImageP icon = TImageP();
Toshihiro Shimizu 890ddd
	createIcon(img, icon);
Toshihiro Shimizu 890ddd
	assert(icon);
Toshihiro Shimizu 890ddd
	if (!icon)
Toshihiro Shimizu 890ddd
		throw(TException("Saving tlv: it is not possible to create the image icon."));
Toshihiro Shimizu 890ddd
	// salvo l'iconcina
Toshihiro Shimizu 890ddd
	saveImage(icon, _fid, true);
Toshihiro Shimizu 890ddd
	return;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
void TLevelWriterTzl::save(const TImageP &img, const TFrameId &fid)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	doSave(img, fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
void TLevelWriterTzl::save(const TImageP &img)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	doSave(img, TFrameId());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
void TLevelWriterTzl::saveIcon(const TImageP &img, const TFrameId &fid)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// salvo su file come icona
Toshihiro Shimizu 890ddd
	saveImage(img, fid, true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void TLevelWriterTzl::setPalette(TPalette *palette)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_palette) {
Toshihiro Shimizu 890ddd
		m_palette = palette;
Toshihiro Shimizu 890ddd
		m_palette->addRef();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
void TLevelWriterTzl::renumberFids(const std::map<tframeid, tframeid=""> &renumberTable)
</tframeid,>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_renumberTable = renumberTable;
Toshihiro Shimizu 890ddd
	if (m_version < 13)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (m_frameOffsTable.empty() || !m_exists)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// Rimozione dei frame non presenti nella prima colonna di renumberTable
Toshihiro Shimizu 890ddd
	std::map<tframeid, tzlchunk=""> frameOffsTableTemp;
</tframeid,>
Toshihiro Shimizu 890ddd
	frameOffsTableTemp = m_frameOffsTable;
Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it = frameOffsTableTemp.begin();
Toshihiro Shimizu 890ddd
	while (it != frameOffsTableTemp.end()) {
Toshihiro Shimizu 890ddd
		TFrameId fid = it->first;
Toshihiro Shimizu 890ddd
		std::map<tframeid, tframeid="">::const_iterator it2 = renumberTable.find(fid);
</tframeid,>
Toshihiro Shimizu 890ddd
		if (it2 == renumberTable.end())
Toshihiro Shimizu 890ddd
			remove(fid);
Toshihiro Shimizu 890ddd
		it++;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	std::map<tframeid, tzlchunk=""> frameOffsTable, iconOffsTable;
</tframeid,>
Toshihiro Shimizu 890ddd
	// Renumber Frame
Toshihiro Shimizu 890ddd
	std::map<tframeid, tframeid="">::const_iterator it3 = renumberTable.begin();
</tframeid,>
Toshihiro Shimizu 890ddd
	while (it3 != renumberTable.end()) {
Toshihiro Shimizu 890ddd
		TFrameId fidToRenumber = it3->first;
Toshihiro Shimizu 890ddd
		TzlOffsetMap::iterator it = m_frameOffsTable.find(fidToRenumber);
Toshihiro Shimizu 890ddd
		TzlOffsetMap::iterator iconIt = m_iconOffsTable.find(fidToRenumber);
Toshihiro Shimizu 890ddd
		if (it != m_frameOffsTable.end())
Toshihiro Shimizu 890ddd
			frameOffsTable[it3->second] = it->second;
Toshihiro Shimizu 890ddd
		if (m_iconOffsTable.size() > 0 && iconIt != m_iconOffsTable.end())
Toshihiro Shimizu 890ddd
			iconOffsTable[it3->second] = iconIt->second;
Toshihiro Shimizu 890ddd
		it3++;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	m_frameOffsTable.clear();
Toshihiro Shimizu 890ddd
	m_frameOffsTable = frameOffsTable;
Toshihiro Shimizu 890ddd
	m_iconOffsTable.clear();
Toshihiro Shimizu 890ddd
	m_iconOffsTable = iconOffsTable;
Toshihiro Shimizu 890ddd
	m_frameCount = m_frameOffsTable.size();
Toshihiro Shimizu 890ddd
	//buildFreeChunksTable();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void TLevelWriterTzl::createIcon(const TImageP &imgIn, TImageP &imgOut)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Creo iconcina e poi la salvo
Toshihiro Shimizu 890ddd
	TToonzImageP ti = imgIn;
Toshihiro Shimizu 890ddd
	if (!ti)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TRect sb = ti->getSavebox();
Toshihiro Shimizu 890ddd
	TINT32 sbx0 = sb.x0, sby0 = sb.y0, sblx = sb.getLx(), sbly = sb.getLy();
Toshihiro Shimizu 890ddd
	TRasterP cmras = ti->getRaster();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(m_iconSize.lx > 0 && m_iconSize.ly > 0);
Toshihiro Shimizu 890ddd
	if (m_iconSize.lx <= 0 || m_iconSize.ly <= 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TINT32 iconLx = m_iconSize.lx, iconLy = m_iconSize.ly;
Toshihiro Shimizu 890ddd
	if (cmras->getLx() <= iconLx && cmras->getLy() <= iconLy) {
Toshihiro Shimizu 890ddd
		iconLx = cmras->getLx();
Toshihiro Shimizu 890ddd
		iconLy = cmras->getLy();
Toshihiro Shimizu 890ddd
		m_iconSize = TDimension(iconLx, iconLy);
Toshihiro Shimizu 890ddd
		imgOut = imgIn;
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRasterCM32P thumbnailRas(iconLx, iconLy);
Toshihiro Shimizu 890ddd
	if (iconLx > 0 && iconLy > 0) {
Toshihiro Shimizu 890ddd
		// Do thumbnail
Toshihiro Shimizu 890ddd
		TRop::makeIcon(thumbnailRas, TRasterCM32P(cmras));
Toshihiro Shimizu 890ddd
		assert(thumbnailRas);
Toshihiro Shimizu 890ddd
		if (!thumbnailRas)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	// Compute savebox
Toshihiro Shimizu 890ddd
	if (ti->getSize().lx <= 0 || ti->getSize().ly <= 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TRect tmp_savebox;
Toshihiro Shimizu 890ddd
	TRect savebox;
Toshihiro Shimizu 890ddd
	TRop::computeBBox(thumbnailRas, tmp_savebox);
Toshihiro Shimizu 890ddd
	if (tmp_savebox.isEmpty()) {
Toshihiro Shimizu 890ddd
		TINT32 iconsbx0 = tround((double)iconLx * sbx0 / ti->getSize().lx);
Toshihiro Shimizu 890ddd
		TINT32 iconsby0 = tround((double)iconLy * sby0 / ti->getSize().ly);
Toshihiro Shimizu 890ddd
		TINT32 iconsblx = tmax(tround((double)iconLx * sblx / ti->getSize().lx), 1);
Toshihiro Shimizu 890ddd
		TINT32 iconsbly = tmax(tround((double)iconLy * sbly / ti->getSize().ly), 1);
Toshihiro Shimizu 890ddd
		savebox = TRect(TPoint(iconsbx0, iconsby0), TDimension(iconsblx, iconsbly));
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		savebox = tmp_savebox;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!TRect(m_iconSize).contains(savebox)) //it should be better to use tfloor instead of tround in the previous lines:
Toshihiro Shimizu 890ddd
											  //sometimes, for rounding problems, the savebox is outside 1 pixel the raster size.
Toshihiro Shimizu 890ddd
											  //the best solution should be to replace tround with tfloor here
Toshihiro Shimizu 890ddd
											  //and in the icon reading of tzl 1.4 (method load14),
Toshihiro Shimizu 890ddd
											  //but this way the old 1.4 tzl are not readed correctly (crash!)
Toshihiro Shimizu 890ddd
											  //so, this 'if' is a patch. vinz
Toshihiro Shimizu 890ddd
		savebox = savebox * TRect(m_iconSize);
Toshihiro Shimizu 890ddd
	thumbnailRas->clearOutside(savebox);
Toshihiro Shimizu 890ddd
	TToonzImageP ticon(thumbnailRas, savebox);
Toshihiro Shimizu 890ddd
	double xdpi = 1, ydpi = 1;
Toshihiro Shimizu 890ddd
	ti->getDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd
	ticon->setDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd
	ticon->setPalette(ti->getPalette());
Toshihiro Shimizu 890ddd
	imgOut = TImageP(ticon);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void TLevelWriterTzl::remove(const TFrameId &fid)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it = m_frameOffsTable.find(fid);
Toshihiro Shimizu 890ddd
	// se il fid non esiste non faccio nulla
Toshihiro Shimizu 890ddd
	if (it == m_frameOffsTable.end())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	// aggiungo spazio vuoto
Toshihiro Shimizu 890ddd
	//m_freeChunks.insert(TzlChunk(it->second.m_offs, it->second.m_length));
Toshihiro Shimizu 890ddd
	addFreeChunk(it->second.m_offs, it->second.m_length);
Toshihiro Shimizu 890ddd
	// cancello l'immagine dalla tabella
Toshihiro Shimizu 890ddd
	m_frameOffsTable.erase(it);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (m_iconOffsTable.size() > 0) {
Toshihiro Shimizu 890ddd
		TzlOffsetMap::iterator iconIt = m_iconOffsTable.find(fid);
Toshihiro Shimizu 890ddd
		// deve necessariamente esserci anche l'iconcina
Toshihiro Shimizu 890ddd
		assert(iconIt != m_iconOffsTable.end());
Toshihiro Shimizu 890ddd
		if (iconIt == m_iconOffsTable.end())
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		// aggiungo spazio vuoto
Toshihiro Shimizu 890ddd
		//m_freeChunks.insert(TzlChunk(iconIt->second.m_offs, iconIt->second.m_length));
Toshihiro Shimizu 890ddd
		addFreeChunk(iconIt->second.m_offs, iconIt->second.m_length);
Toshihiro Shimizu 890ddd
		// Cancello la relativa icona
Toshihiro Shimizu 890ddd
		m_iconOffsTable.erase(iconIt);
Toshihiro Shimizu 890ddd
		erasedFrame = true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void TLevelWriterTzl::setIconSize(TDimension iconSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(iconSize.lx > 0 && iconSize.ly > 0);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	m_iconSize = TDimension(iconSize.lx, iconSize.ly);
Toshihiro Shimizu 890ddd
	m_userIconSize = TDimension(iconSize.lx, iconSize.ly); // Used in TLevelWriterTzl::optimize().
Toshihiro Shimizu 890ddd
														   // Observe that m_iconSize may change below.
Toshihiro Shimizu 890ddd
	if (m_version >= 13 && m_exists) {
Toshihiro Shimizu 890ddd
		// A supported level file already exists at the specified path
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		// Check whether icons stored in the file already
Toshihiro Shimizu 890ddd
		// have the required size
Toshihiro Shimizu 890ddd
		if (!m_updatedIconsSize)							// m_updatedIconsSize tells whether
Toshihiro Shimizu 890ddd
			m_updatedIconsSize = checkIconSize(m_iconSize); // icon sizes in the file match m_iconSize
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		if (!m_updatedIconsSize) {
Toshihiro Shimizu 890ddd
			// Icons in the stored file mismatch with the
Toshihiro Shimizu 890ddd
			// required size. They need to be resized.
Toshihiro Shimizu 890ddd
			m_updatedIconsSize = resizeIcons(m_iconSize);
Toshihiro Shimizu 890ddd
			assert(m_updatedIconsSize);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Checks the icons size stored inside an already existing level
Toshihiro Shimizu 890ddd
            file, and compares it with the specified newSize.
Toshihiro Shimizu 890ddd
  \return   Whether the specified newSize \a matches the icons size in
Toshihiro Shimizu 890ddd
            the level file.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
bool TLevelWriterTzl::checkIconSize(const TDimension &newSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(m_version >= 13);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!m_exists ||
Toshihiro Shimizu 890ddd
		m_iconOffsTable.empty() ||
Toshihiro Shimizu 890ddd
		!m_chan ||
Toshihiro Shimizu 890ddd
		m_version < 13)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// Read the size of icons in the file
Toshihiro Shimizu 890ddd
	TINT32 iconLx = 0, iconLy = 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	long currentPos = ftell(m_chan); // Backup current reading position in the file
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it = m_iconOffsTable.begin();
Toshihiro Shimizu 890ddd
	long offs = it->second.m_offs;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fseek(m_chan, offs, SEEK_SET);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fread(&iconLx, sizeof(TINT32), 1, m_chan);
Toshihiro Shimizu 890ddd
	fread(&iconLy, sizeof(TINT32), 1, m_chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fseek(m_chan, currentPos, SEEK_SET); // Reset to the original position in the file
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(iconLx > 0 && iconLy > 0);
Toshihiro Shimizu 890ddd
	if (iconLx <= 0 || iconLy <= 0 || iconLx > m_res.lx || iconLy > m_res.ly)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	m_currentIconSize = TDimension(iconLx, iconLy); // This is not performed if the above pre-emptive
Toshihiro Shimizu 890ddd
													// bailout kicks in. BTW, m_currentIconSize
Toshihiro Shimizu 890ddd
													// is currently UNUSED! Should be cleaned up...
Toshihiro Shimizu 890ddd
	// Compare newSize against read icon size in the file
Toshihiro Shimizu 890ddd
	return (m_currentIconSize == newSize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
bool TLevelWriterTzl::resizeIcons(const TDimension &newSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_exists)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (m_iconOffsTable.empty())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (!m_chan)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	assert(m_version >= 13);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// faccio una copia di m_path per poi usarla per la resizeIcons()
Toshihiro Shimizu 890ddd
	fclose(m_chan);
Toshihiro Shimizu 890ddd
	m_chan = 0;
Toshihiro Shimizu 890ddd
	TFileStatus fs(m_path);
Toshihiro Shimizu 890ddd
	assert(fs.doesExist());
Toshihiro Shimizu 890ddd
	if (!fs.doesExist())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	std::string tempName = "~" + m_path.getName() + "tmpIcon&.tlv";
Toshihiro Shimizu 890ddd
	TFilePath tempPath = TSystem::getTempDir() + tempName;
Toshihiro Shimizu 890ddd
	if (TSystem::doesExistFileOrLevel(m_path)) {
Toshihiro Shimizu 890ddd
		assert(m_path != tempPath);
Toshihiro Shimizu 890ddd
		if (TSystem::doesExistFileOrLevel(tempPath))
Toshihiro Shimizu 890ddd
			TSystem::deleteFile(tempPath);
Toshihiro Shimizu 890ddd
		TSystem::copyFile(tempPath, m_path);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	m_chan = fopen(m_path, "rb+");
Toshihiro Shimizu 890ddd
	assert(m_chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(TSystem::doesExistFileOrLevel(tempPath));
Toshihiro Shimizu 890ddd
	if (!TSystem::doesExistFileOrLevel(tempPath))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	TLevelReaderP lr(tempPath);
Toshihiro Shimizu 890ddd
	TLevelP level = lr->loadInfo();
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
	if(m_currentIconSize.lx>newSize.lx && m_currentIconSize.ly>newSize.ly)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		for(TLevel::Iterator it=level->begin(); it != level->end(); ++it)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			TImageReaderP ir = lr->getFrameReader(it->first);
Toshihiro Shimizu 890ddd
			
Toshihiro Shimizu 890ddd
			// carico l'iconcina
Toshihiro Shimizu 890ddd
		  TImageP img = ir->loadIcon();
Toshihiro Shimizu 890ddd
			TImageP icon;
Toshihiro Shimizu 890ddd
			createIcon(img,icon);
Toshihiro Shimizu 890ddd
			saveIcon(icon,it->first);			
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
	{				 */
Toshihiro Shimizu 890ddd
	// leggo tutte le immagini da file e creo le iconcine da da zero
Toshihiro Shimizu 890ddd
	for (TLevel::Iterator it = level->begin(); it != level->end(); ++it) {
Toshihiro Shimizu 890ddd
		// carico l'iconcina
Toshihiro Shimizu 890ddd
		TImageP img = lr->getFrameReader(it->first)->load();
Toshihiro Shimizu 890ddd
		// creo e salvo
Toshihiro Shimizu 890ddd
		TImageP icon;
Toshihiro Shimizu 890ddd
		createIcon(img, icon);
Toshihiro Shimizu 890ddd
		saveIcon(icon, it->first);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//}
Toshihiro Shimizu 890ddd
	lr = TLevelReaderP();
Toshihiro Shimizu 890ddd
	// delete m_tempPath
Toshihiro Shimizu 890ddd
	if (TSystem::doesExistFileOrLevel(tempPath)) {
Toshihiro Shimizu 890ddd
		TSystem::deleteFile(tempPath);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
float TLevelWriterTzl::getFreeSpace()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_exists && m_version >= 13) {
Toshihiro Shimizu 890ddd
		TINT32 freeSpace = 0;
Toshihiro Shimizu 890ddd
		std::set<tzlchunk>::iterator it = m_freeChunks.begin();
</tzlchunk>
Toshihiro Shimizu 890ddd
		for (; it != m_freeChunks.end(); ++it)
Toshihiro Shimizu 890ddd
			freeSpace += it->m_length;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		TINT32 totalSpace = 0;
Toshihiro Shimizu 890ddd
		if (m_version == 13)
Toshihiro Shimizu 890ddd
			totalSpace = m_offsetTablePos - 6 * sizeof(TINT32) - 4 * sizeof(char) - 8 * sizeof(char);
Toshihiro Shimizu 890ddd
		else if (m_version == 14)
Toshihiro Shimizu 890ddd
			totalSpace = m_offsetTablePos - 6 * sizeof(TINT32) - 4 * sizeof(char) - 8 * sizeof(char) - CREATOR_LENGTH * sizeof(char);
Toshihiro Shimizu 890ddd
		assert(totalSpace > 0);
Toshihiro Shimizu 890ddd
		return (float)freeSpace / totalSpace;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
// creo il file ottimizzato, cioรจ senza spazi liberi
Toshihiro Shimizu 890ddd
bool TLevelWriterTzl::optimize()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFileStatus fs(m_path);
Toshihiro Shimizu 890ddd
	assert(fs.doesExist());
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	std::string tempName = "~" + m_path.getName() + "tmp&.tlv";
Toshihiro Shimizu 890ddd
	TFilePath tempPath = TSystem::getTempDir() + tempName; // Path temporaneo del file ottimizzato
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (TSystem::doesExistFileOrLevel(tempPath))
Toshihiro Shimizu 890ddd
		TSystem::deleteFile(tempPath);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TLevelWriterP lw(tempPath);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TLevelReaderP lr(m_path);
Toshihiro Shimizu 890ddd
	lw->setIconSize(m_userIconSize);
Toshihiro Shimizu 890ddd
	TLevelP level = lr->loadInfo();
Toshihiro Shimizu 890ddd
	if (!level || level->getFrameCount() == 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	TLevel::Iterator levelIt = level->begin();
Toshihiro Shimizu 890ddd
	for (levelIt; levelIt != level->end(); ++levelIt) {
Toshihiro Shimizu 890ddd
		TToonzImageP img = lr->getFrameReader(levelIt->first)->load();
Toshihiro Shimizu 890ddd
		assert(img);
Toshihiro Shimizu 890ddd
		lw->getFrameWriter(levelIt->first)->save(img);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	lr = TLevelReaderP();
Toshihiro Shimizu 890ddd
	lw = TLevelWriterP();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// Se il file tempPath (ottimizzato) รจ stato creato
Toshihiro Shimizu 890ddd
	// lo copio sostituendolo ad m_path
Toshihiro Shimizu 890ddd
	if (TSystem::doesExistFileOrLevel(tempPath)) {
Toshihiro Shimizu 890ddd
		assert(m_path != tempPath);
Toshihiro Shimizu 890ddd
		if (TSystem::doesExistFileOrLevel(m_path))
Toshihiro Shimizu 890ddd
			TSystem::deleteFile(m_path); // Cancello il file non ottimizzato
Toshihiro Shimizu 890ddd
		TSystem::copyFile(m_path, tempPath);
Toshihiro Shimizu 890ddd
		TSystem::deleteFile(tempPath);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TLevelReaderTzl
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void TLevelReaderTzl::readPalette()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFilePath pltfp = m_path.withNoFrame().withType("tpl");
Toshihiro Shimizu 890ddd
	TFileStatus fs(pltfp);
Toshihiro Shimizu 890ddd
	TPersist *p = 0;
Toshihiro Shimizu 890ddd
	TIStream is(pltfp);
Toshihiro Shimizu 890ddd
	TPalette *palette = 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (is && fs.doesExist()) {
Toshihiro Shimizu 890ddd
		is >> p;
Toshihiro Shimizu 890ddd
		palette = dynamic_cast<tpalette *="">(p);
</tpalette>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!palette) {
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		palette = new TPalette();
Toshihiro Shimizu 890ddd
		for (i = 1; i < 128 + 32; i++)
Toshihiro Shimizu 890ddd
			palette->addStyle(TPixel32(127, 150, 255));
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		for (i = 0; i < 10; i++)
Toshihiro Shimizu 890ddd
			palette->getPage(0)->addStyle(i + 1);
Toshihiro Shimizu 890ddd
		for (i = 0; i < 10; i++)
Toshihiro Shimizu 890ddd
			palette->getPage(0)->addStyle(128 + i);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (m_level)
Toshihiro Shimizu 890ddd
		m_level->setPalette(palette);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TLevelReaderTzl::TLevelReaderTzl(const TFilePath &path)
Toshihiro Shimizu 890ddd
	: TLevelReader(path), m_chan(0), m_res(0, 0), m_xDpi(0), m_yDpi(0), m_version(0), m_frameOffsTable(), m_iconOffsTable(), m_level(), m_readPalette(true)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	m_chan = fopen(path, "rb");
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!m_chan)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!readHeaderAndOffsets(m_chan, m_frameOffsTable, m_iconOffsTable, m_res, m_version, m_creator, 0, 0, 0, m_level))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TFilePath historyFp = path.withNoFrame().withType("hst");
Toshihiro Shimizu 890ddd
	FILE *historyChan = fopen(historyFp, "r");
Toshihiro Shimizu 890ddd
	if (historyChan) {
Toshihiro Shimizu 890ddd
		// read the whole file into historyData string
Toshihiro Shimizu 890ddd
		fseek(historyChan, 0, SEEK_END);
Toshihiro Shimizu 890ddd
		long lSize = ftell(historyChan);
Toshihiro Shimizu 890ddd
		rewind(historyChan);
Shinya Kitaoka 3bfa54
		std::string historyData(lSize, '\0');
Toshihiro Shimizu 890ddd
		fread(&historyData[0], 1, lSize, historyChan);
Toshihiro Shimizu 890ddd
		fclose(historyChan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		if (!m_contentHistory)
Toshihiro Shimizu 890ddd
			m_contentHistory = new TContentHistory(true);
Toshihiro Shimizu 890ddd
		m_contentHistory->deserialize(QString::fromStdString(historyData));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// UCHAR *imgBuff = new UCHAR[imgBuffSize];
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// fclose(m_chan);
Toshihiro Shimizu 890ddd
	// m_chan = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
void TLevelReaderTzl::doReadPalette(bool doReadIt)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_readPalette = doReadIt;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TLevelReaderTzl::~TLevelReaderTzl()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_chan)
Toshihiro Shimizu 890ddd
		fclose(m_chan);
Toshihiro Shimizu 890ddd
	m_chan = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TLevelP TLevelReaderTzl::loadInfo()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_level && m_level->getPalette() == 0 && m_readPalette)
Toshihiro Shimizu 890ddd
		readPalette();
Toshihiro Shimizu 890ddd
	return m_level;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TImageReaderP TLevelReaderTzl::getFrameReader(TFrameId fid)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_level && m_level->getPalette() == 0 && m_readPalette)
Toshihiro Shimizu 890ddd
		readPalette();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	return new TImageReaderTzl(getFilePath(), fid, this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
QString TLevelReaderTzl::getCreator()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_version < 14)
Toshihiro Shimizu 890ddd
		return "";
Toshihiro Shimizu 890ddd
	return m_creator;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
bool TLevelReaderTzl::getIconSize(TDimension &iconSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_iconOffsTable.empty())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (m_version < 13)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	assert(m_chan);
Toshihiro Shimizu 890ddd
	TINT32 currentPos = ftell(m_chan);
Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it = m_iconOffsTable.begin();
Toshihiro Shimizu 890ddd
	TINT32 offs = it->second.m_offs;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fseek(m_chan, offs, SEEK_SET);
Toshihiro Shimizu 890ddd
	TINT32 iconLx = 0, iconLy = 0;
Toshihiro Shimizu 890ddd
	// leggo la dimensione delle iconcine nel file
Toshihiro Shimizu 890ddd
	fread(&iconLx, sizeof(TINT32), 1, m_chan);
Toshihiro Shimizu 890ddd
	fread(&iconLy, sizeof(TINT32), 1, m_chan);
Toshihiro Shimizu 890ddd
	assert(iconLx > 0 && iconLy > 0);
Toshihiro Shimizu 890ddd
	// ritorno alla posizione corrente
Toshihiro Shimizu 890ddd
	fseek(m_chan, currentPos, SEEK_SET);
Toshihiro Shimizu 890ddd
	iconSize = TDimension(iconLx, iconLy);
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TImageReaderTzl
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TImageReaderTzl::TImageReaderTzl(
Toshihiro Shimizu 890ddd
	const TFilePath &f,
Toshihiro Shimizu 890ddd
	const TFrameId &fid,
Toshihiro Shimizu 890ddd
	TLevelReaderTzl *lr)
Toshihiro Shimizu 890ddd
	: TImageReader(f), m_fid(fid), m_lrp(lr), m_lx(lr->m_res.lx), m_ly(lr->m_res.ly), m_isIcon(false)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TImageP TImageReaderTzl::load10()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FILE *chan = m_lrp->m_chan;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!chan)
Toshihiro Shimizu 890ddd
		return TImageP();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Toshihiro Shimizu 890ddd
	TINT32 sbx0, sby0, sblx, sbly;
Toshihiro Shimizu 890ddd
	TINT32 actualBuffSize;
Toshihiro Shimizu 890ddd
	double xdpi = 1, ydpi = 1;
Toshihiro Shimizu 890ddd
	TINT32 imgBuffSize = 0;
Toshihiro Shimizu 890ddd
	UCHAR *imgBuff = 0;
Toshihiro Shimizu 890ddd
	int frameIndex = m_fid.getNumber();
Toshihiro Shimizu 890ddd
	//int pos = ftell(chan);
Toshihiro Shimizu 890ddd
	/*if(m_lrp->m_frameIndex>=m_frameIndex)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
     fseek(chan, m_lrp->m_framesOffset, SEEK_SET);
Toshihiro Shimizu 890ddd
     m_lrp->m_frameIndex = 0;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  int k = m_lrp->m_frameIndex + 1;
Toshihiro Shimizu 890ddd
  m_lrp->m_frameIndex = m_frameIndex;*/
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	int k;
Toshihiro Shimizu 890ddd
	if (m_lrp->m_frameOffsTable[TFrameId(frameIndex)].m_offs == 0) {
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		for (i = 2; m_lrp->m_frameOffsTable[TFrameId(i)].m_offs != 0 && i <= m_fid.getNumber(); i++)
Toshihiro Shimizu 890ddd
			;
Toshihiro Shimizu 890ddd
		if (i == frameIndex)
Toshihiro Shimizu 890ddd
			i = 2;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		fseek(chan, m_lrp->m_frameOffsTable[TFrameId(i - 1)].m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd
		k = i - 1;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		fseek(chan, m_lrp->m_frameOffsTable[TFrameId(frameIndex)].m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd
		k = frameIndex;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (; k <= frameIndex; k++) {
Toshihiro Shimizu 890ddd
		m_lrp->m_frameOffsTable[TFrameId(k)] = TzlChunk(ftell(chan), 0);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		fread(&sbx0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&sby0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&sblx, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&sbly, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&xdpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
		sbx0 = swapTINT32(sbx0);
Toshihiro Shimizu 890ddd
		sby0 = swapTINT32(sby0);
Toshihiro Shimizu 890ddd
		sblx = swapTINT32(sblx);
Toshihiro Shimizu 890ddd
		sbly = swapTINT32(sbly);
Toshihiro Shimizu 890ddd
		actualBuffSize = swapTINT32(actualBuffSize);
Toshihiro Shimizu 890ddd
		reverse((char *)&xdpi, sizeof(double));
Toshihiro Shimizu 890ddd
		reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		imgBuffSize = m_lx * m_ly * sizeof(TPixelCM32);
Toshihiro Shimizu 890ddd
		assert(actualBuffSize <= imgBuffSize);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		delete[] imgBuff;
Toshihiro Shimizu 890ddd
		imgBuff = new UCHAR[imgBuffSize];
Toshihiro Shimizu 890ddd
		//int ret =
Toshihiro Shimizu 890ddd
		fread(imgBuff, actualBuffSize, 1, chan);
Toshihiro Shimizu 890ddd
		//assert(ret==1);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	header->m_lx = swapTINT32(header->m_lx);
Toshihiro Shimizu 890ddd
	header->m_ly = swapTINT32(header->m_ly);
Toshihiro Shimizu 890ddd
	header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRasterCodecLZO codec("LZO", false);
Toshihiro Shimizu 890ddd
	TRasterP ras;
Toshihiro Shimizu 890ddd
	if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Toshihiro Shimizu 890ddd
		return TImageP();
Toshihiro Shimizu 890ddd
	assert((TRasterCM32P)ras);
Toshihiro Shimizu 890ddd
	assert(ras->getLx() == header->m_lx);
Toshihiro Shimizu 890ddd
	assert(ras->getLy() == header->m_ly);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	ras->lock();
Toshihiro Shimizu 890ddd
	for (int y = 0; y < ras->getLy(); ++y) {
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		TINT32 *pix = ((TINT32 *)ras->getRawData(0, y));
Toshihiro Shimizu 890ddd
		TINT32 *endPix = pix + ras->getLx();
Toshihiro Shimizu 890ddd
		while (pix < endPix) {
Toshihiro Shimizu 890ddd
			*pix = swapTINT32(*pix);
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	ras->unlock();
Toshihiro Shimizu 890ddd
// codec.compress(ras, 1, &imgBuff, actualBuffSize);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRect savebox(TPoint(sbx0, sby0), TDimension(sblx, sbly));
Toshihiro Shimizu 890ddd
	TDimension imgSize(m_lrp->m_res.lx, m_lrp->m_res.ly);
Toshihiro Shimizu 890ddd
	assert(TRect(imgSize).contains(savebox));
Toshihiro Shimizu 890ddd
	if (imgSize != savebox.getSize() && !savebox.isEmpty()) {
Toshihiro Shimizu 890ddd
		assert(TRect(imgSize).contains(savebox));
Toshihiro Shimizu 890ddd
		TRasterCM32P fullRas(imgSize);
Toshihiro Shimizu 890ddd
		TPixelCM32 bgColor;
Toshihiro Shimizu 890ddd
		fullRas->fillOutside(savebox, bgColor);
Toshihiro Shimizu 890ddd
		assert(savebox.getSize() == ras->getSize());
Toshihiro Shimizu 890ddd
		fullRas->extractT(savebox)->copy(ras);
Toshihiro Shimizu 890ddd
		ras = fullRas;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	delete[] imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// codec.decompress(m_compressedBuffer, m_compressedBufferSize, ras);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// assert(0);
Toshihiro Shimizu 890ddd
	// TToonzImageP ti; //  = new TToonzImage(m_lx,m_ly,savebox,imgBuff,actualBuffSize);
Toshihiro Shimizu 890ddd
	TToonzImageP ti(ras, savebox);
Toshihiro Shimizu 890ddd
	// if(dpiflag)
Toshihiro Shimizu 890ddd
	ti->setDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd
	// m_lrp->m_level->setFrame(TFrameId(m_frameIndex+1), ti);
Toshihiro Shimizu 890ddd
	ti->setPalette(m_lrp->m_level->getPalette());
Toshihiro Shimizu 890ddd
	//delete [] imgBuff;
Toshihiro Shimizu 890ddd
	//imgBuff = 0;
Toshihiro Shimizu 890ddd
	return ti;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//ToonzImageUtils::updateRas32(ti);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TImageP TImageReaderTzl::load11()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FILE *chan = m_lrp->m_chan;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!chan)
Toshihiro Shimizu 890ddd
		return TImageP();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Toshihiro Shimizu 890ddd
	TINT32 sbx0, sby0, sblx, sbly;
Toshihiro Shimizu 890ddd
	TINT32 actualBuffSize;
Toshihiro Shimizu 890ddd
	double xdpi = 1, ydpi = 1;
Toshihiro Shimizu 890ddd
	TINT32 imgBuffSize = 0;
Toshihiro Shimizu 890ddd
	UCHAR *imgBuff = 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(!m_lrp->m_frameOffsTable.empty());
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//int pos = ftell(chan);
Toshihiro Shimizu 890ddd
	/*if(m_lrp->m_frameIndex>=m_frameIndex)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
     fseek(chan, m_lrp->m_framesOffset, SEEK_SET);
Toshihiro Shimizu 890ddd
     m_lrp->m_frameIndex = 0;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  int k = m_lrp->m_frameIndex + 1;
Toshihiro Shimizu 890ddd
  m_lrp->m_frameIndex = m_frameIndex;*/
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it = m_lrp->m_frameOffsTable.find(m_fid);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (it == m_lrp->m_frameOffsTable.end())
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fseek(chan, it->second.m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fread(&sbx0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sby0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sblx, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sbly, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fread(&xdpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	sbx0 = swapTINT32(sbx0);
Toshihiro Shimizu 890ddd
	sby0 = swapTINT32(sby0);
Toshihiro Shimizu 890ddd
	sblx = swapTINT32(sblx);
Toshihiro Shimizu 890ddd
	sbly = swapTINT32(sbly);
Toshihiro Shimizu 890ddd
	actualBuffSize = swapTINT32(actualBuffSize);
Toshihiro Shimizu 890ddd
	reverse((char *)&xdpi, sizeof(double));
Toshihiro Shimizu 890ddd
	reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	imgBuffSize = m_lx * m_ly * sizeof(TPixelCM32);
Toshihiro Shimizu 890ddd
	assert(actualBuffSize <= imgBuffSize);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	imgBuff = new UCHAR[imgBuffSize];
Toshihiro Shimizu 890ddd
	//int ret =
Toshihiro Shimizu 890ddd
	fread(imgBuff, actualBuffSize, 1, chan);
Toshihiro Shimizu 890ddd
	//assert(ret==1);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	header->m_lx = swapTINT32(header->m_lx);
Toshihiro Shimizu 890ddd
	header->m_ly = swapTINT32(header->m_ly);
Toshihiro Shimizu 890ddd
	header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRasterCodecLZO codec("LZO", false);
Toshihiro Shimizu 890ddd
	TRasterP ras;
Toshihiro Shimizu 890ddd
	if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Toshihiro Shimizu 890ddd
		return TImageP();
Toshihiro Shimizu 890ddd
	assert((TRasterCM32P)ras);
Toshihiro Shimizu 890ddd
	assert(ras->getLx() == header->m_lx);
Toshihiro Shimizu 890ddd
	assert(ras->getLy() == header->m_ly);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	for (int y = 0; y < ras->getLy(); ++y) {
Toshihiro Shimizu 890ddd
		ras->lock();
Toshihiro Shimizu 890ddd
		TINT32 *pix = ((TINT32 *)ras->getRawData(0, y));
Toshihiro Shimizu 890ddd
		TINT32 *endPix = pix + ras->getLx();
Toshihiro Shimizu 890ddd
		while (pix < endPix) {
Toshihiro Shimizu 890ddd
			*pix = swapTINT32(*pix);
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		ras->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
// codec.compress(ras, 1, &imgBuff, actualBuffSize);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRect savebox(TPoint(sbx0, sby0), TDimension(sblx, sbly));
Toshihiro Shimizu 890ddd
	TDimension imgSize(m_lrp->m_res.lx, m_lrp->m_res.ly);
Toshihiro Shimizu 890ddd
	assert(TRect(imgSize).contains(savebox));
Toshihiro Shimizu 890ddd
	if (imgSize != savebox.getSize() && !savebox.isEmpty()) {
Toshihiro Shimizu 890ddd
		assert(TRect(imgSize).contains(savebox));
Toshihiro Shimizu 890ddd
		TRasterCM32P fullRas(imgSize);
Toshihiro Shimizu 890ddd
		TPixelCM32 bgColor;
Toshihiro Shimizu 890ddd
		fullRas->fillOutside(savebox, bgColor);
Toshihiro Shimizu 890ddd
		assert(savebox.getSize() == ras->getSize());
Toshihiro Shimizu 890ddd
		fullRas->extractT(savebox)->copy(ras);
Toshihiro Shimizu 890ddd
		ras = fullRas;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	delete[] imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// codec.decompress(m_compressedBuffer, m_compressedBufferSize, ras);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// assert(0);
Toshihiro Shimizu 890ddd
	// TToonzImageP ti; //  = new TToonzImage(m_lx,m_ly,savebox,imgBuff,actualBuffSize);
Toshihiro Shimizu 890ddd
	TToonzImageP ti(ras, savebox);
Toshihiro Shimizu 890ddd
	// if(dpiflag)
Toshihiro Shimizu 890ddd
	ti->setDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd
	// m_lrp->m_level->setFrame(TFrameId(m_frameIndex+1), ti);
Toshihiro Shimizu 890ddd
	ti->setPalette(m_lrp->m_level->getPalette());
Toshihiro Shimizu 890ddd
	//delete [] imgBuff;
Toshihiro Shimizu 890ddd
	//imgBuff = 0;
Toshihiro Shimizu 890ddd
	return ti;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//ToonzImageUtils::updateRas32(ti);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TImageP TImageReaderTzl::load13()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FILE *chan = m_lrp->m_chan;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!chan)
Toshihiro Shimizu 890ddd
		return TImageP();
Toshihiro Shimizu 890ddd
	// SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Toshihiro Shimizu 890ddd
	TINT32 sbx0, sby0, sblx, sbly;
Toshihiro Shimizu 890ddd
	TINT32 actualBuffSize;
Toshihiro Shimizu 890ddd
	double xdpi = 1, ydpi = 1;
Toshihiro Shimizu 890ddd
	TINT32 imgBuffSize = 0;
Toshihiro Shimizu 890ddd
	UCHAR *imgBuff = 0;
Toshihiro Shimizu 890ddd
	TINT32 iconLx = 0, iconLy = 0;
Toshihiro Shimizu 890ddd
	assert(!m_lrp->m_frameOffsTable.empty());
Toshihiro Shimizu 890ddd
	assert(!m_lrp->m_iconOffsTable.empty());
Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it = m_lrp->m_frameOffsTable.find(m_fid);
Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator iconIt = m_lrp->m_iconOffsTable.find(m_fid);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (it == m_lrp->m_frameOffsTable.end() || iconIt == m_lrp->m_iconOffsTable.end())
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fseek(chan, it->second.m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd
	fread(&sbx0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sby0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sblx, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sbly, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&xdpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	sbx0 = swapTINT32(sbx0);
Toshihiro Shimizu 890ddd
	sby0 = swapTINT32(sby0);
Toshihiro Shimizu 890ddd
	sblx = swapTINT32(sblx);
Toshihiro Shimizu 890ddd
	sbly = swapTINT32(sbly);
Toshihiro Shimizu 890ddd
	actualBuffSize = swapTINT32(actualBuffSize);
Toshihiro Shimizu 890ddd
	reverse((char *)&xdpi, sizeof(double));
Toshihiro Shimizu 890ddd
	reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	// Carico l'icona dal file
Toshihiro Shimizu 890ddd
	if (m_isIcon) {
Toshihiro Shimizu 890ddd
		fseek(chan, iconIt->second.m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd
		fread(&iconLx, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&iconLy, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		assert(iconLx > 0 && iconLy > 0);
Toshihiro Shimizu 890ddd
		if (iconLx <= 0 || iconLy <= 0)
Toshihiro Shimizu 890ddd
			throw TException();
Toshihiro Shimizu 890ddd
		fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		imgBuffSize = (iconLx * iconLy * sizeof(TPixelCM32));
Toshihiro Shimizu 890ddd
		imgBuff = new UCHAR[imgBuffSize];
Toshihiro Shimizu 890ddd
		fread(imgBuff, actualBuffSize, 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
		Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd
		header->m_lx = swapTINT32(header->m_lx);
Toshihiro Shimizu 890ddd
		header->m_ly = swapTINT32(header->m_ly);
Toshihiro Shimizu 890ddd
		header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		TRasterCodecLZO codec("LZO", false);
Toshihiro Shimizu 890ddd
		TRasterP ras;
Toshihiro Shimizu 890ddd
		if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Toshihiro Shimizu 890ddd
			return TImageP();
Toshihiro Shimizu 890ddd
		assert((TRasterCM32P)ras);
Toshihiro Shimizu 890ddd
		delete[] imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		for (int y = 0; y < ras->getLy(); ++y) {
Toshihiro Shimizu 890ddd
			ras->lock();
Toshihiro Shimizu 890ddd
			TINT32 *pix = ((TINT32 *)ras->getRawData(0, y));
Toshihiro Shimizu 890ddd
			TINT32 *endPix = pix + ras->getLx();
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				*pix = swapTINT32(*pix);
Toshihiro Shimizu 890ddd
				pix++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			ras->unlock();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		/*
Toshihiro Shimizu 890ddd
			TINT32 iconsbx0 = tround((double)iconLx*sbx0/m_lrp->m_res.lx);
Toshihiro Shimizu 890ddd
			TINT32 iconsby0 = tround((double)iconLy*sby0/m_lrp->m_res.ly); 
Toshihiro Shimizu 890ddd
			TRect savebox(TPoint(iconsbx0,iconsby0), TDimension(ras->getLx(),ras->getLy()));
Toshihiro Shimizu 890ddd
			 */
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		// Compute savebox
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		TINT32 iconsbx0 = tround((double)iconLx * sbx0 / m_lrp->m_res.lx);
Toshihiro Shimizu 890ddd
		TINT32 iconsby0 = tround((double)iconLy * sby0 / m_lrp->m_res.ly); //+tround((double)(iconLy-ly)/2);
Toshihiro Shimizu 890ddd
		TINT32 iconsblx = tround((double)iconLx * sblx / m_lrp->m_res.lx);
Toshihiro Shimizu 890ddd
		TINT32 iconsbly = tround((double)iconLy * sbly / m_lrp->m_res.ly);
Toshihiro Shimizu 890ddd
		TRect savebox(TPoint(iconsbx0, iconsby0), TDimension(iconsblx, iconsbly));
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		//int ly = tround((double)m_lrp->m_res.ly*iconLx/m_lrp->m_res.lx);
Toshihiro Shimizu 890ddd
		//TRect rect(TPoint(0,tround((double)(iconLy-ly)/2)),TDimension(iconLx,ly));
Toshihiro Shimizu 890ddd
		//TPixelCM32 bgColorRect(1,0,100);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		TDimension imgSize(iconLx, iconLy);
Toshihiro Shimizu 890ddd
		assert(TRect(imgSize).contains(savebox));
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		if (imgSize != savebox.getSize() && !savebox.isEmpty()) {
Toshihiro Shimizu 890ddd
			assert(TRect(imgSize).contains(savebox));
Toshihiro Shimizu 890ddd
			TRasterCM32P fullRas(imgSize);
Toshihiro Shimizu 890ddd
			TPixelCM32 bgColor;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
			fullRas->fillOutside(savebox, bgColor);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
			//fullRas->extractT(rect)->fill(bgColorRect);
Toshihiro Shimizu 890ddd
			assert(savebox.getSize() == ras->getSize());
Toshihiro Shimizu 890ddd
			fullRas->extractT(savebox)->copy(ras);
Toshihiro Shimizu 890ddd
			ras = fullRas;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		TToonzImageP ti(ras, savebox);
Toshihiro Shimizu 890ddd
		ti->setDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd
		ti->setPalette(m_lrp->m_level->getPalette());
Toshihiro Shimizu 890ddd
		return ti;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRasterCM32P raux = TRasterCM32P(m_lx, m_ly);
Toshihiro Shimizu 890ddd
	raux->lock();
Toshihiro Shimizu 890ddd
	imgBuff = (UCHAR *)raux->getRawData(); //new UCHAR[imgBuffSize];
Toshihiro Shimizu 890ddd
	//imgBuff = new UCHAR[imgBuffSize];
Toshihiro Shimizu 890ddd
	//imgBuffSize = m_lx*m_ly*sizeof(TPixelCM32);
Toshihiro Shimizu 890ddd
	//assert(actualBuffSize <= imgBuffSize);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//imgBuff = new UCHAR[imgBuffSize];
Toshihiro Shimizu 890ddd
	//int ret =
Toshihiro Shimizu 890ddd
	fread(imgBuff, actualBuffSize, 1, chan);
Toshihiro Shimizu 890ddd
	//assert(ret==1);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	header->m_lx = swapTINT32(header->m_lx);
Toshihiro Shimizu 890ddd
	header->m_ly = swapTINT32(header->m_ly);
Toshihiro Shimizu 890ddd
	header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRasterCodecLZO codec("LZO", false);
Toshihiro Shimizu 890ddd
	TRasterP ras;
Toshihiro Shimizu 890ddd
	if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Toshihiro Shimizu 890ddd
		return TImageP();
Toshihiro Shimizu 890ddd
	assert((TRasterCM32P)ras);
Toshihiro Shimizu 890ddd
	assert(ras->getLx() == header->m_lx);
Toshihiro Shimizu 890ddd
	assert(ras->getLy() == header->m_ly);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	for (int y = 0; y < ras->getLy(); ++y) {
Toshihiro Shimizu 890ddd
		ras->lock();
Toshihiro Shimizu 890ddd
		TINT32 *pix = ((TINT32 *)ras->getRawData(0, y));
Toshihiro Shimizu 890ddd
		TINT32 *endPix = pix + ras->getLx();
Toshihiro Shimizu 890ddd
		while (pix < endPix) {
Toshihiro Shimizu 890ddd
			*pix = swapTINT32(*pix);
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		ras->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
// codec.compress(ras, 1, &imgBuff, actualBuffSize);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRect savebox(TPoint(sbx0, sby0), TDimension(sblx, sbly));
Toshihiro Shimizu 890ddd
	TDimension imgSize(m_lrp->m_res.lx, m_lrp->m_res.ly);
Toshihiro Shimizu 890ddd
	assert(TRect(imgSize).contains(savebox));
Toshihiro Shimizu 890ddd
	if (imgSize != savebox.getSize() && !savebox.isEmpty()) {
Toshihiro Shimizu 890ddd
		assert(TRect(imgSize).contains(savebox));
Toshihiro Shimizu 890ddd
		TRasterCM32P fullRas(imgSize);
Toshihiro Shimizu 890ddd
		TPixelCM32 bgColor;
Toshihiro Shimizu 890ddd
		fullRas->fillOutside(savebox, bgColor);
Toshihiro Shimizu 890ddd
		assert(savebox.getSize() == ras->getSize());
Toshihiro Shimizu 890ddd
		fullRas->extractT(savebox)->copy(ras);
Toshihiro Shimizu 890ddd
		ras = fullRas;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	raux->unlock();
Toshihiro Shimizu 890ddd
	raux = TRasterCM32P();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//delete [] imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// codec.decompress(m_compressedBuffer, m_compressedBufferSize, ras);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// assert(0);
Toshihiro Shimizu 890ddd
	// TToonzImageP ti; //  = new TToonzImage(m_lx,m_ly,savebox,imgBuff,actualBuffSize);
Toshihiro Shimizu 890ddd
	TToonzImageP ti(ras, savebox);
Toshihiro Shimizu 890ddd
	// if(dpiflag)
Toshihiro Shimizu 890ddd
	ti->setDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd
	// m_lrp->m_level->setFrame(TFrameId(m_frameIndex+1), ti);
Toshihiro Shimizu 890ddd
	ti->setPalette(m_lrp->m_level->getPalette());
Toshihiro Shimizu 890ddd
	//delete [] imgBuff;
Toshihiro Shimizu 890ddd
	//imgBuff = 0;
Toshihiro Shimizu 890ddd
	return ti;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//ToonzImageUtils::updateRas32(ti);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
// Restituisce la regione del raster shrinkata e la relativa savebox.
Toshihiro Shimizu 890ddd
TRect applyShrinkAndRegion(TRasterP &ras, int shrink, TRect region, TRect savebox)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// estraggo la regione solo se essa ha coordinate valide.
Toshihiro Shimizu 890ddd
	if (!region.isEmpty() && region != TRect() && region.getLx() > 0 && region.getLy() > 0)
Toshihiro Shimizu 890ddd
		ras = ras->extract(region);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		region = TRect(0, 0, ras->getLx() - 1, ras->getLy() - 1);
Toshihiro Shimizu 890ddd
	if (shrink > 1) {
Toshihiro Shimizu 890ddd
		ras = TRop::shrink(ras, shrink);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	// calcolo la nuova savebox
Toshihiro Shimizu 890ddd
	savebox *= region;
Toshihiro Shimizu 890ddd
	if (savebox == TRect() || savebox.getLx() <= 0 || savebox.getLy() <= 0)
Toshihiro Shimizu 890ddd
		return TRect();
Toshihiro Shimizu 890ddd
	int firstColIndexOfLayer = (savebox.x0 - region.x0) - 1 + shrink - (abs(savebox.x0 - region.x0 - 1) % shrink);
Toshihiro Shimizu 890ddd
	int firstRowIndexOfLayer = (savebox.y0 - region.y0) - 1 + shrink - (abs(savebox.y0 - region.y0 - 1) % shrink);
Toshihiro Shimizu 890ddd
	savebox.x0 = (firstColIndexOfLayer) / shrink;
Toshihiro Shimizu 890ddd
	savebox.y0 = (firstRowIndexOfLayer) / shrink;
Toshihiro Shimizu 890ddd
	savebox.x1 = savebox.x0 + (savebox.getLx()) / shrink - 1;
Toshihiro Shimizu 890ddd
	savebox.y1 = savebox.y0 + (savebox.getLy()) / shrink - 1;
Toshihiro Shimizu 890ddd
	return savebox;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TImageP TImageReaderTzl::load14()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FILE *chan = m_lrp->m_chan;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!chan)
Toshihiro Shimizu 890ddd
		return TImageP();
Toshihiro Shimizu 890ddd
	// SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Toshihiro Shimizu 890ddd
	TINT32 sbx0 = 0, sby0 = 0, sblx, sbly;
Toshihiro Shimizu 890ddd
	TINT32 actualBuffSize;
Toshihiro Shimizu 890ddd
	double xdpi = 1, ydpi = 1;
Toshihiro Shimizu 890ddd
	//TINT32 imgBuffSize = 0;
Toshihiro Shimizu 890ddd
	UCHAR *imgBuff = 0;
Toshihiro Shimizu 890ddd
	TINT32 iconLx = 0, iconLy = 0;
Toshihiro Shimizu 890ddd
	assert(!m_lrp->m_frameOffsTable.empty());
Toshihiro Shimizu 890ddd
	assert(!m_lrp->m_iconOffsTable.empty());
Toshihiro Shimizu 890ddd
	if (m_lrp->m_frameOffsTable.empty())
Toshihiro Shimizu 890ddd
		throw TException("Loading tlv: the frames table is empty.");
Toshihiro Shimizu 890ddd
	if (m_lrp->m_iconOffsTable.empty())
Toshihiro Shimizu 890ddd
		throw TException("Loading tlv: the frames icons table is empty.");
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it = m_lrp->m_frameOffsTable.find(m_fid);
Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator iconIt = m_lrp->m_iconOffsTable.find(m_fid);
Toshihiro Shimizu 890ddd
	if (it == m_lrp->m_frameOffsTable.end() || iconIt == m_lrp->m_iconOffsTable.end())
Toshihiro Shimizu 890ddd
		throw TException("Loading tlv: frame ID not found.");
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fseek(chan, it->second.m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd
	fread(&sbx0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sby0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sblx, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sbly, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&xdpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (sbx0 < 0 || sby0 < 0 || sblx < 0 || sbly < 0 || sblx > m_lx || sbly > m_ly)
Toshihiro Shimizu 890ddd
		throw TException("Loading tlv: savebox dimension error.");
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	sbx0 = swapTINT32(sbx0);
Toshihiro Shimizu 890ddd
	sby0 = swapTINT32(sby0);
Toshihiro Shimizu 890ddd
	sblx = swapTINT32(sblx);
Toshihiro Shimizu 890ddd
	sbly = swapTINT32(sbly);
Toshihiro Shimizu 890ddd
	actualBuffSize = swapTINT32(actualBuffSize);
Toshihiro Shimizu 890ddd
	reverse((char *)&xdpi, sizeof(double));
Toshihiro Shimizu 890ddd
	reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// Carico l'icona dal file
Toshihiro Shimizu 890ddd
	if (m_isIcon) {
Toshihiro Shimizu 890ddd
		fseek(chan, iconIt->second.m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd
		fread(&iconLx, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&iconLy, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		assert(iconLx > 0 && iconLy > 0);
Toshihiro Shimizu 890ddd
		if (iconLx < 0 || iconLy < 0 || iconLx > m_lx || iconLy > m_ly)
Toshihiro Shimizu 890ddd
			throw TException("Loading tlv: bad icon size.");
Toshihiro Shimizu 890ddd
		fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		assert(actualBuffSize > 0 && actualBuffSize <= (int)(iconLx * iconLx * sizeof(TPixelCM32)));
Toshihiro Shimizu 890ddd
		if (actualBuffSize <= 0 || actualBuffSize > (int)(iconLx * iconLx * sizeof(TPixelCM32)))
Toshihiro Shimizu 890ddd
			throw TException("Loading tlv: icon buffer size error.");
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		TRasterCM32P raux = TRasterCM32P(iconLx, iconLy);
Toshihiro Shimizu 890ddd
		if (!raux)
Toshihiro Shimizu 890ddd
			return TImageP();
Toshihiro Shimizu 890ddd
		raux->lock();
Toshihiro Shimizu 890ddd
		imgBuff = (UCHAR *)raux->getRawData(); //new UCHAR[imgBuffSize];
Toshihiro Shimizu 890ddd
		fread(imgBuff, actualBuffSize, 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
		Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd
		header->m_lx = swapTINT32(header->m_lx);
Toshihiro Shimizu 890ddd
		header->m_ly = swapTINT32(header->m_ly);
Toshihiro Shimizu 890ddd
		header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		TRasterCodecLZO codec("LZO", false);
Toshihiro Shimizu 890ddd
		TRasterP ras;
Toshihiro Shimizu 890ddd
		if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Toshihiro Shimizu 890ddd
			return TImageP();
Toshihiro Shimizu 890ddd
		assert((TRasterCM32P)ras);
Toshihiro Shimizu 890ddd
		raux->unlock();
Toshihiro Shimizu 890ddd
		raux = TRasterCM32P();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		for (int y = 0; y < ras->getLy(); ++y) {
Toshihiro Shimizu 890ddd
			ras->lock();
Toshihiro Shimizu 890ddd
			TINT32 *pix = ((TINT32 *)ras->getRawData(0, y));
Toshihiro Shimizu 890ddd
			TINT32 *endPix = pix + ras->getLx();
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				*pix = swapTINT32(*pix);
Toshihiro Shimizu 890ddd
				pix++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			ras->unlock();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		/*
Toshihiro Shimizu 890ddd
			TINT32 iconsbx0 = tround((double)iconLx*sbx0/m_lrp->m_res.lx);
Toshihiro Shimizu 890ddd
			TINT32 iconsby0 = tround((double)iconLy*sby0/m_lrp->m_res.ly); 
Toshihiro Shimizu 890ddd
			TRect savebox(TPoint(iconsbx0,iconsby0), TDimension(ras->getLx(),ras->getLy()));
Toshihiro Shimizu 890ddd
			 */
Toshihiro Shimizu 890ddd
		if (m_lrp->m_res.lx == 0 || m_lrp->m_res.ly == 0)
Toshihiro Shimizu 890ddd
			return TImageP();
Toshihiro Shimizu 890ddd
		// Compute savebox
Toshihiro Shimizu 890ddd
		if (m_lrp->m_res.lx < 0 || m_lrp->m_res.ly < 0)
Toshihiro Shimizu 890ddd
			throw TException("Loading tlv: icon resolution error");
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		TRect tmp_savebox;
Toshihiro Shimizu 890ddd
		TRect savebox;
Toshihiro Shimizu 890ddd
		TRop::computeBBox(ras, tmp_savebox);
Toshihiro Shimizu 890ddd
		if (tmp_savebox.isEmpty()) {
Toshihiro Shimizu 890ddd
			TINT32 iconsbx0 = tround((double)iconLx * sbx0 / m_lrp->m_res.lx);
Toshihiro Shimizu 890ddd
			TINT32 iconsby0 = tround((double)iconLy * sby0 / m_lrp->m_res.ly);
Toshihiro Shimizu 890ddd
			TINT32 iconsblx = tmax(tround((double)iconLx * sblx / m_lrp->m_res.lx), 1);
Toshihiro Shimizu 890ddd
			TINT32 iconsbly = tmax(tround((double)iconLy * sbly / m_lrp->m_res.ly), 1);
Toshihiro Shimizu 890ddd
			savebox = TRect(TPoint(iconsbx0, iconsby0), TDimension(iconsblx, iconsbly));
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			TINT32 iconsbx0 = tfloor((double)iconLx * sbx0 / m_lrp->m_res.lx);
Toshihiro Shimizu 890ddd
			TINT32 iconsby0 = tfloor((double)iconLy * sby0 / m_lrp->m_res.ly);
Toshihiro Shimizu 890ddd
			savebox = TRect(TPoint(iconsbx0, iconsby0), TDimension(tmp_savebox.getLx(), tmp_savebox.getLy()));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		//int ly = tround((double)m_lrp->m_res.ly*iconLx/m_lrp->m_res.lx);
Toshihiro Shimizu 890ddd
		//TRect rect(TPoint(0,tround((double)(iconLy-ly)/2)),TDimension(iconLx,ly));
Toshihiro Shimizu 890ddd
		//TPixelCM32 bgColorRect(1,0,100);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		TDimension imgSize(iconLx, iconLy);
Toshihiro Shimizu 890ddd
		if (!TRect(imgSize).contains(savebox)) //for this 'if', see comment in createIcon method. vinz
Toshihiro Shimizu 890ddd
			savebox = savebox * TRect(imgSize);
Toshihiro Shimizu 890ddd
		//if(!TRect(imgSize).contains(savebox)) throw TException("Loading tlv: bad icon savebox size.");
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		if (imgSize != savebox.getSize()) {
Toshihiro Shimizu 890ddd
			TRasterCM32P fullRas(imgSize);
Toshihiro Shimizu 890ddd
			TPixelCM32 bgColor;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
			fullRas->fillOutside(savebox, bgColor);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
			//fullRas->extractT(rect)->fill(bgColorRect);
Toshihiro Shimizu 890ddd
			//assert(savebox.getSize() == ras->getSize());
Toshihiro Shimizu 890ddd
			if (savebox.getSize() != ras->getSize())
Toshihiro Shimizu 890ddd
				throw TException("Loading tlv: bad icon savebox size.");
Toshihiro Shimizu 890ddd
			fullRas->extractT(savebox)->copy(ras);
Toshihiro Shimizu 890ddd
			ras = fullRas;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		TToonzImageP ti(ras, savebox);
Toshihiro Shimizu 890ddd
		ti->setDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd
		ti->setPalette(m_lrp->m_level->getPalette());
Toshihiro Shimizu 890ddd
		return ti;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	assert(actualBuffSize > 0 && actualBuffSize <= (int)(m_lx * m_ly * sizeof(TPixelCM32)));
Toshihiro Shimizu 890ddd
	if (actualBuffSize <= 0 || actualBuffSize > (int)(m_lx * m_ly * sizeof(TPixelCM32)))
Toshihiro Shimizu 890ddd
		throw TException("Loading tlv: buffer size error");
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRasterCM32P raux = TRasterCM32P(m_lx, m_ly);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//imgBuffSize = m_lx*m_ly*sizeof(TPixelCM32);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	raux->lock();
Toshihiro Shimizu 890ddd
	imgBuff = (UCHAR *)raux->getRawData(); //new UCHAR[imgBuffSize];
Toshihiro Shimizu 890ddd
										   //int ret =
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fread(imgBuff, actualBuffSize, 1, chan);
Toshihiro Shimizu 890ddd
	//assert(ret==1);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	header->m_lx = swapTINT32(header->m_lx);
Toshihiro Shimizu 890ddd
	header->m_ly = swapTINT32(header->m_ly);
Toshihiro Shimizu 890ddd
	header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRasterCodecLZO codec("LZO", false);
Toshihiro Shimizu 890ddd
	TRasterP ras;
Toshihiro Shimizu 890ddd
	if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Toshihiro Shimizu 890ddd
		return TImageP();
Toshihiro Shimizu 890ddd
	assert((TRasterCM32P)ras);
Toshihiro Shimizu 890ddd
	assert(ras->getLx() == header->m_lx);
Toshihiro Shimizu 890ddd
	assert(ras->getLy() == header->m_ly);
Toshihiro Shimizu 890ddd
	if (ras->getLx() != header->m_lx)
Toshihiro Shimizu 890ddd
		throw TException("Loading tlv: lx dimension error.");
Toshihiro Shimizu 890ddd
	if (ras->getLy() != header->m_ly)
Toshihiro Shimizu 890ddd
		throw TException("Loading tlv: ly dimension error.");
Toshihiro Shimizu 890ddd
	raux->unlock();
Toshihiro Shimizu 890ddd
	raux = TRasterCM32P();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	for (int y = 0; y < ras->getLy(); ++y) {
Toshihiro Shimizu 890ddd
		ras->lock();
Toshihiro Shimizu 890ddd
		TINT32 *pix = ((TINT32 *)ras->getRawData(0, y));
Toshihiro Shimizu 890ddd
		TINT32 *endPix = pix + ras->getLx();
Toshihiro Shimizu 890ddd
		while (pix < endPix) {
Toshihiro Shimizu 890ddd
			*pix = swapTINT32(*pix);
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		ras->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
// codec.compress(ras, 1, &imgBuff, actualBuffSize);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TRect savebox(TPoint(sbx0, sby0), TDimension(sblx, sbly));
Toshihiro Shimizu 890ddd
	TDimension imgSize(m_lrp->m_res.lx, m_lrp->m_res.ly);
Toshihiro Shimizu 890ddd
	assert(TRect(imgSize).contains(savebox));
Toshihiro Shimizu 890ddd
	if (!TRect(imgSize).contains(savebox))
Toshihiro Shimizu 890ddd
		throw TException("Loading tlv: bad savebox size.");
Toshihiro Shimizu 890ddd
	if (imgSize != savebox.getSize()) {
Toshihiro Shimizu 890ddd
		TRasterCM32P fullRas(imgSize);
Toshihiro Shimizu 890ddd
		TPixelCM32 bgColor;
Toshihiro Shimizu 890ddd
		if (!savebox.isEmpty()) {
Toshihiro Shimizu 890ddd
			fullRas->fillOutside(savebox, bgColor);
Toshihiro Shimizu 890ddd
			assert(savebox.getSize() == ras->getSize());
Toshihiro Shimizu 890ddd
			if (savebox.getSize() != ras->getSize())
Toshihiro Shimizu 890ddd
				throw TException("Loading tlv: bad icon savebox size.");
Toshihiro Shimizu 890ddd
			fullRas->extractT(savebox)->copy(ras);
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			fullRas->clear();
Toshihiro Shimizu 890ddd
		ras = fullRas;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TToonzImageP ti(ras, savebox);
Toshihiro Shimizu 890ddd
	// if(dpiflag)
Toshihiro Shimizu 890ddd
	ti->setDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd
	// m_lrp->m_level->setFrame(TFrameId(m_frameIndex+1), ti);
Toshihiro Shimizu 890ddd
	ti->setPalette(m_lrp->m_level->getPalette());
Toshihiro Shimizu 890ddd
	//delete [] imgBuff;
Toshihiro Shimizu 890ddd
	//imgBuff = 0;
Toshihiro Shimizu 890ddd
	return ti;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//ToonzImageUtils::updateRas32(ti);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TImageP TImageReaderTzl::load()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int version = m_lrp->m_version;
Toshihiro Shimizu 890ddd
	TImageP image = TImageP();
Toshihiro Shimizu 890ddd
	switch (version) {
Toshihiro Shimizu 890ddd
	case 11:
Toshihiro Shimizu 890ddd
		if (!m_lrp->m_frameOffsTable.empty())
Toshihiro Shimizu 890ddd
			image = load11();
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case 12:
Toshihiro Shimizu 890ddd
		if (!m_lrp->m_frameOffsTable.empty())
Toshihiro Shimizu 890ddd
			image = load11();
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case 13:
Toshihiro Shimizu 890ddd
		if (!m_lrp->m_frameOffsTable.empty() && !m_lrp->m_iconOffsTable.empty())
Toshihiro Shimizu 890ddd
			image = load13();
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case 14:
Toshihiro Shimizu 890ddd
		if (!m_lrp->m_frameOffsTable.empty() && !m_lrp->m_iconOffsTable.empty())
Toshihiro Shimizu 890ddd
			image = load14();
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	default:
Toshihiro Shimizu 890ddd
		image = load10();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (image == TImageP())
Toshihiro Shimizu 890ddd
		return TImageP();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (!m_isIcon) {
Toshihiro Shimizu 890ddd
		TToonzImageP ti = image;
Toshihiro Shimizu 890ddd
		if (!ti)
Toshihiro Shimizu 890ddd
			return TImageP();
Toshihiro Shimizu 890ddd
		TRasterP ras = ti->getRaster();
Toshihiro Shimizu 890ddd
		TRect savebox = ti->getSavebox();
Toshihiro Shimizu 890ddd
		if (m_region != TRect() && m_region.getLx() > 0 && m_region.getLy() > 0) {
Toshihiro Shimizu 890ddd
			m_region *= TRect(0, 0, ti->getSize().lx, ti->getSize().ly);
Toshihiro Shimizu 890ddd
			if (m_region.isEmpty() || m_region == TRect() || m_region.getLx() <= 0 || m_region.getLy() <= 0)
Toshihiro Shimizu 890ddd
				return TImageP();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		savebox = applyShrinkAndRegion(ras, m_shrink, m_region, savebox);
Toshihiro Shimizu 890ddd
		if (savebox == TRect()) {
Toshihiro Shimizu 890ddd
			if (m_region != TRect()) {
Toshihiro Shimizu 890ddd
				ras = ras->create(m_region.getLx(), m_region.getLy());
Toshihiro Shimizu 890ddd
				ras->clear();
Toshihiro Shimizu 890ddd
				savebox = m_region;
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				//se sia la savebox che la regione sono vuote non faccio nulla
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		ti->setCMapped(ras);
Toshihiro Shimizu 890ddd
		ti->setSavebox(savebox);
Toshihiro Shimizu 890ddd
		return ti;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return image;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
const TImageInfo *TImageReaderTzl::getImageInfo11() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(!m_lrp->m_frameOffsTable.empty());
Toshihiro Shimizu 890ddd
	FILE *chan = m_lrp->m_chan;
Toshihiro Shimizu 890ddd
	if (!chan)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	TzlOffsetMap::iterator it = m_lrp->m_frameOffsTable.find(m_fid);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	if (it == m_lrp->m_frameOffsTable.end())
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fseek(chan, it->second.m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Toshihiro Shimizu 890ddd
	TINT32 sbx0, sby0, sblx, sbly;
Toshihiro Shimizu 890ddd
	TINT32 actualBuffSize;
Toshihiro Shimizu 890ddd
	double xdpi = 1, ydpi = 1;
Toshihiro Shimizu 890ddd
	//  TINT32 imgBuffSize = 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//int pos = ftell(chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fread(&sbx0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sby0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sblx, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&sbly, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	fread(&xdpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd
	fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	sbx0 = swapTINT32(sbx0);
Toshihiro Shimizu 890ddd
	sby0 = swapTINT32(sby0);
Toshihiro Shimizu 890ddd
	sblx = swapTINT32(sblx);
Toshihiro Shimizu 890ddd
	sbly = swapTINT32(sbly);
Toshihiro Shimizu 890ddd
	actualBuffSize = swapTINT32(actualBuffSize);
Toshihiro Shimizu 890ddd
	reverse((char *)&xdpi, sizeof(double));
Toshihiro Shimizu 890ddd
	reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	static TImageInfo info;
Toshihiro Shimizu 890ddd
	info.m_x0 = sbx0;
Toshihiro Shimizu 890ddd
	info.m_y0 = sby0;
Toshihiro Shimizu 890ddd
	info.m_x1 = sbx0 + sblx - 1;
Toshihiro Shimizu 890ddd
	info.m_y1 = sby0 + sbly - 1;
Toshihiro Shimizu 890ddd
	info.m_lx = m_lx;
Toshihiro Shimizu 890ddd
	info.m_ly = m_ly;
Toshihiro Shimizu 890ddd
	info.m_dpix = xdpi;
Toshihiro Shimizu 890ddd
	info.m_dpiy = ydpi;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//m_lrp->m_frameIndex = m_frameIndex;
Toshihiro Shimizu 890ddd
	return &info;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
const TImageInfo *TImageReaderTzl::getImageInfo10() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FILE *chan = m_lrp->m_chan;
Toshihiro Shimizu 890ddd
	if (!chan)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	// SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Toshihiro Shimizu 890ddd
	TINT32 sbx0, sby0, sblx, sbly;
Toshihiro Shimizu 890ddd
	TINT32 actualBuffSize;
Toshihiro Shimizu 890ddd
	double xdpi = 1, ydpi = 1;
Toshihiro Shimizu 890ddd
	TINT32 imgBuffSize = 0;
Toshihiro Shimizu 890ddd
	UCHAR *imgBuff = 0;
Toshihiro Shimizu 890ddd
	int frameIndex = m_fid.getNumber();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//int pos = ftell(chan);
Toshihiro Shimizu 890ddd
	assert(m_lrp->m_frameOffsTable[TFrameId(1)].m_offs > 0);
Toshihiro Shimizu 890ddd
	int k;
Toshihiro Shimizu 890ddd
	if (m_lrp->m_frameOffsTable[TFrameId(frameIndex)].m_offs == 0) {
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		for (i = 2; m_lrp->m_frameOffsTable[TFrameId(i)].m_offs != 0 && i <= frameIndex; i++)
Toshihiro Shimizu 890ddd
			;
Toshihiro Shimizu 890ddd
		if (i == frameIndex)
Toshihiro Shimizu 890ddd
			i = 2;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		fseek(chan, m_lrp->m_frameOffsTable[TFrameId(i - 1)].m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd
		k = i - 1;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		fseek(chan, m_lrp->m_frameOffsTable[TFrameId(frameIndex)].m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd
		k = frameIndex;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	for (; k <= frameIndex; k++) {
Toshihiro Shimizu 890ddd
		m_lrp->m_frameOffsTable[TFrameId(k)] = TzlChunk(ftell(chan), 0);
Toshihiro Shimizu 890ddd
		fread(&sbx0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&sby0, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&sblx, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&sbly, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		fread(&xdpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd
		fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
		sbx0 = swapTINT32(sbx0);
Toshihiro Shimizu 890ddd
		sby0 = swapTINT32(sby0);
Toshihiro Shimizu 890ddd
		sblx = swapTINT32(sblx);
Toshihiro Shimizu 890ddd
		sbly = swapTINT32(sbly);
Toshihiro Shimizu 890ddd
		actualBuffSize = swapTINT32(actualBuffSize);
Toshihiro Shimizu 890ddd
		reverse((char *)&xdpi, sizeof(double));
Toshihiro Shimizu 890ddd
		reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
		imgBuffSize = m_lx * m_ly * sizeof(TPixelCM32);
Toshihiro Shimizu 890ddd
		assert(actualBuffSize <= imgBuffSize);
Toshihiro Shimizu 890ddd
		delete[] imgBuff;
Toshihiro Shimizu 890ddd
		imgBuff = new UCHAR[imgBuffSize];
Toshihiro Shimizu 890ddd
		fread(imgBuff, actualBuffSize, 1, chan);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
	header->m_lx = swapTINT32(header->m_lx);
Toshihiro Shimizu 890ddd
	header->m_ly = swapTINT32(header->m_ly);
Toshihiro Shimizu 890ddd
	header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	delete[] imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	static TImageInfo info;
Toshihiro Shimizu 890ddd
	info.m_x0 = sbx0;
Toshihiro Shimizu 890ddd
	info.m_y0 = sby0;
Toshihiro Shimizu 890ddd
	info.m_x1 = sbx0 + sblx - 1;
Toshihiro Shimizu 890ddd
	info.m_y1 = sby0 + sbly - 1;
Toshihiro Shimizu 890ddd
	info.m_lx = m_lx;
Toshihiro Shimizu 890ddd
	info.m_ly = m_ly;
Toshihiro Shimizu 890ddd
	info.m_dpix = xdpi;
Toshihiro Shimizu 890ddd
	info.m_dpiy = ydpi;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
	//m_lrp->m_frameIndex = m_frameIndex;
Toshihiro Shimizu 890ddd
	return &info;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
const TImageInfo *TImageReaderTzl::getImageInfo() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_lrp->m_version > 10 && !m_lrp->m_frameOffsTable.empty())
Toshihiro Shimizu 890ddd
		return getImageInfo11();
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return getImageInfo10();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TDimension TImageReaderTzl::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TDimension(m_lx, m_ly);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TRect TImageReaderTzl::getBBox() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TRect(getSize());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd