ZCI

.ZCI is a multimedia-related aggregate format that was mainly used on educational CD-ROMs by Zane Publishing. It is sometimes called PowerCD Multimedia format.

ZCI is evidently a platform-independent format, with the relevant CDs typically supporting Windows 3.x and Macintosh.

[More research is needed to understand the nature of this format.]

Specification
A partial specification of the format is below:


 * Files start with ASCII "".
 * Unknown, likely a version
 * Table of contents offset
 * File count

The purpose of the bytes between 16-2096 is unknown. It includes file offsets, but often skips files or contains sequences with low values. File data appears to always begin at an offset of 2096.

The Table of contents appears at the end of the file and has entries in the format:


 * File name (8.3 format, null-padded)
 * unk1
 * Offset

Each entry's offset refers to another structure within the file with the following format:


 * File name (8.3 format, null-padded)
 * unk2 (, often zero)
 * unk3
 * File size
 * unk4
 * unk5

Entry notes:


 * Entries often being with the magic bytes.
 * Entry data appears to be in a custom format (as noted by the extension not matching the data, i.e. a GIF file does not contain the expected GIF signature).
 * Assumed the entries are compressed, although an attempt using common compression methods did not yield any results.

Extract
The following Python source can be used to partially inspect and extract files within a  file:

import struct import os

header_format = '<4sIII' header_format_size = struct.calcsize(header_format)

entry_format = '<13sII' entry_format_size = struct.calcsize(entry_format)

file_data_format = '<13sbIIII' file_data_format_size = struct.calcsize(file_data_format)

with open('PRESBASE.ZCI', 'rb') as f:	[magic_bytes, version, table_offset, file_count] = struct.unpack(header_format, f.read(header_format_size)) print("Magic bytes: {}".format(magic_bytes)) print("Version: {}".format(version)) print("Table offset: {}".format(table_offset)) print("File count: {}".format(file_count)) assert magic_bytes == b'CRRW' assert version == 2 assert table_offset > 0 assert file_count > 0

entries = {} f.seek(table_offset)

for _ in range(file_count): [file_name_bytes, unk1, offset] = struct.unpack(entry_format, f.read(entry_format_size)) file_name = file_name_bytes.decode('ascii').rstrip('\x00')

entries[file_name] = { 'file_name': file_name, 'unk1': unk1, 'offset': offset, }	for key, entry in entries.items: f.seek(entry['offset']) [file_name_bytes, unk2, unk3, file_size, unk4, unk5] = struct.unpack(file_data_format, f.read(file_data_format_size)) file_name = file_name_bytes.decode('ascii').rstrip('\x00') assert file_name == entry['file_name']

file_data = f.read(file_size) entries[key].update({			'unk2': unk2,			'unk3': unk3,			'unk4': unk4,			'unk5': unk5,			'file_size': file_size,			'file_data': file_data,		})

for key, entry in entries.items: with open(os.path.join('output', key), 'wb+') as f:			f.write(entry['file_data'])

Sample files

 * Examples of CDs containing ZCI files:, ,

Links

 * .zci info from FileInfo.com