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)); }
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; }
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); } }