void ExtractCine::unpackFile(Common::File &file) { char fileName[15]; unsigned int entryCount = file.readUint16BE(); // How many entries? unsigned int entrySize = file.readUint16BE(); // How many bytes per entry? assert(entrySize == 0x1e); while (entryCount--) { file.read_throwsOnError(fileName, 14); fileName[14] = '\0'; Common::Filename outPath(_outputPath); outPath.setFullName(fileName); uint32 offset = file.readUint32BE(); unsigned int packedSize = file.readUint32BE(); unsigned int unpackedSize = file.readUint32BE(); // Skip one file.readUint32BE(); unsigned int savedPos = file.pos(); print("unpacking '%s' ... ", outPath.getFullName().c_str()); Common::File fpOut(outPath, "wb"); file.seek(offset, SEEK_SET); assert(unpackedSize >= packedSize); uint8 *data = (uint8 *)calloc(unpackedSize, 1); uint8 *packedData = (uint8 *)calloc(packedSize, 1); assert(data); assert(packedData); file.read_throwsOnError(packedData, packedSize); bool status = true; if (packedSize != unpackedSize) { CineUnpacker cineUnpacker; status = cineUnpacker.unpack(packedData, packedSize, data, unpackedSize); } else { memcpy(data, packedData, packedSize); } free(packedData); fpOut.write(data, unpackedSize); free(data); if (!status) { print("CRC ERROR"); } else { print("ok"); } print(", packedSize %u unpackedSize %u", packedSize, unpackedSize); file.seek(savedPos, SEEK_SET); } }
uint32 CompressTouche::compress_sound_data_file(uint32 current_offset, Common::File &output, Common::File &input, uint32 *offs_table, uint32 *size_table, int len) { int i, size; uint8 buf[2048]; uint32 start_offset = current_offset; /* write 0 offsets/sizes table */ for (i = 0; i < len; ++i) { offs_table[i] = input.readUint32LE(); size_table[i] = input.readUint32LE(); output.writeUint32LE(0); output.writeUint32LE(0); current_offset += 8; } for (i = 0; i < len; ++i) { if (size_table[i] == 0) { offs_table[i] = 0; } else { input.seek(offs_table[i], SEEK_SET); input.read_throwsOnError(buf, 8); if (memcmp(buf, "Creative", 8) != 0) { error("Invalid VOC data found"); } print("VOC found (pos = %d) :", offs_table[i]); input.seek(18, SEEK_CUR); extractAndEncodeVOC(TEMP_RAW, input, _format); /* append converted data to output file */ Common::File temp(tempEncoded, "rb"); size_table[i] = 0; while ((size = temp.read_noThrow(buf, 2048)) > 0) { output.write(buf, size); size_table[i] += size; } offs_table[i] = current_offset; current_offset += size_table[i]; } } /* fix data offsets table */ output.seek(start_offset, SEEK_SET); for (i = 0; i < len; ++i) { output.writeUint32LE(offs_table[i]); output.writeUint32LE(size_table[i]); } output.seek(0, SEEK_END); return current_offset; }