Chunk* load_chunk(std::ifstream& stream, int x, int z)
{
	ByteString bytes;

	uint32_t metadataOffset = 4 * (x + z * 32);
	stream.seekg(metadataOffset);

	bytes = read_bytes_from_stream(stream, 4);
	uint32_t offset = bytes.read<uint32_t>() >> 8;

	if(offset == 0) {
		return NULL;
	}

	stream.seekg(4096 * offset);

	bytes = read_bytes_from_stream(stream, 5);
	uint32_t bytecount = bytes.read<uint32_t>();

	bytes = read_bytes_from_stream(stream, bytecount - 1);

	// decompress
	unsigned long uncompressedLength;
	ByteString uncompressedData(CHUNK_INFLATE_MAX);
	
	std::cout << uncompress(uncompressedData.bytes(), &uncompressedLength, bytes.bytes(), bytecount - 1) << std::endl;;

	//std::cout << uncompressedLength << std::endl;
	print_byte_array(uncompressedData.bytes(), uncompressedLength);

	return read_chunk(ByteString(uncompressedData));
}
Exemple #2
0
uint32_t TIGER::decodeCDRM(iostream *dataStream, uint32_t &size, string &path, string &name)
{
	bool changes = false;
	CDRM_Header table;
	dataStream->read((char*)&table, sizeof(CDRM_Header));
	if (table.magic != 0x4D524443)
		exit(-1);
	vector<CDRM_BlockHeader> BlockHeader(table.count);
	dataStream->read((char*)BlockHeader.data(), table.count*sizeof(CDRM_BlockHeader));

	size = 0;
	uint32_t total_size = 0;
	uint32_t offset = 0;
	for (uint32_t i = 0; i < BlockHeader.size(); i++)	//Calculate total size.
	{
		size += BlockHeader[i].uncompressedSize;
	}
	total_size = size;
	auto_ptr<char> uncompressedData(new char[size]);
	for (uint32_t i = 0; i < BlockHeader.size(); i++)
	{
		uint32_t pos = dataStream->tellg();
		pos = ((pos + 15) / 16) * 16;
		dataStream->seekg(pos);	//Data is 16byte aligned.
		dataStream->seekp(pos);	//Data is 16byte aligned.
		if (BlockHeader[i].blockType == 1)
		{
			dataStream->read(uncompressedData.get() + offset, BlockHeader[i].uncompressedSize);
			offset += BlockHeader[i].uncompressedSize;
		}
		else if (BlockHeader[i].blockType == 2)
		{
			auto_ptr<char> compressedData(new char[BlockHeader[i].compressedSize]);
			dataStream->read(compressedData.get(), BlockHeader[i].compressedSize);
			int ret = Z_OK;
			uLong uncompressSize = size - offset;
			uint8_t *dataPtr = (uint8_t*)uncompressedData.get() + offset;
			ret = uncompress(dataPtr, &uncompressSize, (Bytef*)compressedData.get(), BlockHeader[i].compressedSize);
			offset += BlockHeader[i].uncompressedSize;
			if ((ret != Z_OK) && (ret != Z_STREAM_END))
			{
				exit(ret);
			}
		}
	}
	CDRM_BlockFooter footer;
	dataStream->seekg(((((uint64_t)dataStream->tellg()) + 15) / 16) * 16);	//Data is 16byte aligned.
	dataStream->read((char*)&footer, sizeof(footer));
	switch (((uint32_t*)(uncompressedData.get()))[0])
	{
	case '9DCP':	//PCD9
	{
		uncompressedData = decodePCD9(uncompressedData, size, path, name);
		changes = true;
	}
	break;
	case 0x00000006:
	{
		if ((currentMode == UNPACK))
		{
			try
			{
				string fullpath = path + "\\" + name + ".mesh";
				cout << "Writing \"" << fullpath << "\"\n";
				//Scene scene(uncompressedData.get() , size);
				fstream output(fullpath, ios_base::binary | ios_base::out);
				if (!output.is_open())
					exit(errno);
				output.write(uncompressedData.get(), size);
				output.close();
			}
			catch (exception e)
			{
				cout << e.what();
			}
		}
		//return -1;
	}
	default:
	{
		if (writeDRM && (currentMode == UNPACK))
		{
			string fullpath = path + "\\" + name + ".drm";
			cout << "Writing \"" << fullpath << "\"\n";
			fstream output(fullpath, ios_base::binary | ios_base::out);
			if (!output.is_open())
				exit(errno);
			output.write(uncompressedData.get(), size);
			output.close();
		}
	}
	}
	if (currentMode == PACK /*&& changes*/)
	{
		if (total_size != size)
		{
			cout << "Incorrect size\n";
			exit(-1);
		}

		/*Find next free CDRM*/
		tigerFiles[4]->seekg(0);
		tigerFiles[4]->seekp(0);
		uint32_t blockheaderpos = 0;
		CDRM_Header i;
		while (true)
		{
			uint32_t size = 0;
			i.load(tigerFiles[4]);
			if (i.magic == 0)
				break;
			size += i.count*sizeof(CDRM_BlockHeader);
			size = ((size + 15) / 16) * 16;
			CDRM_BlockHeader j;
			for (int k = 0;k < i.count;k++)
			{
				j.load(tigerFiles[4]);
				size += j.compressedSize;
			}
			size = (((size + 0x800 - 1) / 0x800) * 0x800);
			blockheaderpos += size;
			size -= sizeof(CDRM_Header);
			tigerFiles[4]->seekg(size, ios_base::cur);
			tigerFiles[4]->seekp(size, ios_base::cur);
		}

		tigerFiles[4]->seekg(blockheaderpos);
		tigerFiles[4]->seekp(blockheaderpos);
		tigerFiles[4]->write((char*)&table, sizeof(CDRM_Header));
		blockheaderpos = tigerFiles[4]->tellp();
		tigerFiles[4]->write((char*)BlockHeader.data(), sizeof(CDRM_BlockHeader)*BlockHeader.size());
		tigerFiles[4]->seekp(((((uint64_t)tigerFiles[4]->tellp()) + 15) / 16) * 16);	//Data is 16byte aligned.
		for (uint32_t i = 0; i < BlockHeader.size(); i++)
		{
			BlockHeader[i].uncompressedSize = size;
			if (BlockHeader[i].blockType == 1)
			{
				BlockHeader[i].compressedSize = BlockHeader[i].uncompressedSize;
				tigerFiles[4]->write(uncompressedData.get(), BlockHeader[i].uncompressedSize);
			}
			else if (BlockHeader[i].blockType == 2)
			{
				auto_ptr<char> compressedData(new char[BlockHeader[i].uncompressedSize]);
				int ret = Z_OK;
				BlockHeader[i].compressedSize = BlockHeader[i].uncompressedSize;
				ret = compress2((Bytef*)compressedData.get(), (uLongf*)(&BlockHeader[i].compressedSize), (Bytef*)uncompressedData.get(), BlockHeader[i].uncompressedSize, 4);
				if ((ret != Z_OK) && (ret != Z_STREAM_END))
				{
					cout << "Error Compressing\n";
					exit(ret);
				}
				tigerFiles[4]->write(compressedData.get(), BlockHeader[i].compressedSize);
			}
		}

		uint32_t cdrm_footer = tigerFiles[4]->tellp();
		cdrm_footer = ((cdrm_footer + 15) / 16) * 16;

		footer.relative_offset = 0x800 - (cdrm_footer % 0x800);
		tigerFiles[4]->seekp(cdrm_footer);	//Data is 16byte aligned.
		tigerFiles[4]->write((char*)&footer, sizeof(CDRM_BlockFooter));
		tigerFiles[4]->seekp(blockheaderpos);
		tigerFiles[4]->write((char*)BlockHeader.data(), sizeof(CDRM_BlockHeader)*BlockHeader.size());
		tigerFiles[4]->flush();
		return (blockheaderpos & 0xFFFFFF00) | 4;
	}

	return -1;
}
Exemple #3
0
static void TestFlate(skiatest::Reporter* reporter, SkMemoryStream* testStream,
                      size_t dataSize) {
    SkASSERT(testStream != NULL);

    SkAutoDataUnref testData(new_test_data(dataSize));
    SkASSERT(testData->size() == dataSize);

    testStream->setMemory(testData->data(), dataSize, /*copyData=*/ true);
    SkDynamicMemoryWStream compressed;
    bool deflateSuccess = SkFlate::Deflate(testStream, &compressed);
    REPORTER_ASSERT(reporter, deflateSuccess);

    // Check that the input data wasn't changed.
    size_t inputSize = testStream->getLength();
    if (inputSize == 0) {
        inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
    }
    REPORTER_ASSERT(reporter, dataSize == inputSize);
    if (dataSize == inputSize) {
        REPORTER_ASSERT(reporter, memcmp(testData->data(),
                                         testStream->getMemoryBase(),
                                         dataSize) == 0);
    }

    size_t compressedSize = compressed.getOffset();

    SkAutoDataUnref compressedData(compressed.copyToData());
    testStream->setData(compressedData.get());

    SkDynamicMemoryWStream uncompressed;
    bool inflateSuccess = SkFlate::Inflate(testStream, &uncompressed);
    REPORTER_ASSERT(reporter, inflateSuccess);

    // Check that the input data wasn't changed.
    inputSize = testStream->getLength();
    if (inputSize == 0) {
        inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
    }
    REPORTER_ASSERT(reporter,  compressedSize == inputSize);
    if (compressedData->size() == inputSize) {
        REPORTER_ASSERT(reporter, memcmp(testStream->getMemoryBase(),
                                         compressedData->data(),
                                         compressedData->size()) == 0);
    }

    // Check that the uncompressed data matches the source data.
    SkAutoDataUnref uncompressedData(uncompressed.copyToData());
    REPORTER_ASSERT(reporter, dataSize == uncompressedData->size());
    if (dataSize == uncompressedData->size()) {
        REPORTER_ASSERT(reporter, memcmp(testData->data(),
                                         uncompressedData->data(),
                                         dataSize) == 0);
    }

    if (compressedSize < 1) { return; }

    double compressionRatio = static_cast<double>(dataSize) / compressedSize;
    // Assert that some compression took place.
    REPORTER_ASSERT(reporter, compressionRatio > 1.2);

    if (reporter->verbose()) {
        SkDebugf("Flate Test: \t input size: " SK_SIZE_T_SPECIFIER
                 "\tcompressed size: " SK_SIZE_T_SPECIFIER
                 "\tratio: %.4g\n",
                 dataSize, compressedSize, compressionRatio);
    }
}