// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
using System.Collections.Generic;
namespace Kaitai
{
///
/// Compressed resource data in `'dcmp' (2)` format,
/// as stored in compressed resources with header type `9` and decompressor ID `2`.
///
/// The `'dcmp' (2)` decompressor resource is included in the System file of System 7.0 and later.
/// This compression format is used for a few compressed resources in System 7.0's files
/// (such as the System file).
/// This decompressor is also included with and used by some other Apple applications,
/// such as ResEdit.
/// (Note: ResEdit includes the `'dcmp' (2)` resource,
/// but none of its resources actually use this decompressor.)
///
/// This compression format is based on simple dictionary coding,
/// where each byte in the compressed data expands to two bytes,
/// based on a lookup table
/// (either included in the compressed data or provided by the decompressor).
/// An alternative "tagged" compression format is also supported,
/// which allows using two-byte literals in addition to single-byte table references,
/// at the cost of requiring an extra "tag" byte every 16 output bytes,
/// to differentiate literals and table references.
///
///
/// Reference: Source
///
public partial class Dcmp2 : KaitaiStruct
{
public Dcmp2(uint p_lenDecompressed, BytesWithIo p_headerParametersWithIo, KaitaiStream p__io, KaitaiStruct p__parent = null, Dcmp2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root ?? this;
_lenDecompressed = p_lenDecompressed;
_headerParametersWithIo = p_headerParametersWithIo;
f_headerParameters = false;
f_isLenDecompressedOdd = false;
f_defaultLookupTable = false;
f_lookupTable = false;
_read();
}
private void _read()
{
if (HeaderParameters.Flags.HasCustomLookupTable) {
_customLookupTable = new List();
for (var i = 0; i < HeaderParameters.NumCustomLookupTableEntries; i++)
{
_customLookupTable.Add(m_io.ReadBytes(2));
}
}
{
bool on = HeaderParameters.Flags.Tagged;
if (on == true)
{
__raw_data = m_io.ReadBytes(((M_Io.Size - M_Io.Pos) - (IsLenDecompressedOdd ? 1 : 0)));
var io___raw_data = new KaitaiStream(__raw_data);
_data = new TaggedData(io___raw_data, this, m_root);
}
else
{
__raw_data = m_io.ReadBytes(((M_Io.Size - M_Io.Pos) - (IsLenDecompressedOdd ? 1 : 0)));
var io___raw_data = new KaitaiStream(__raw_data);
_data = new UntaggedData(io___raw_data, this, m_root);
}
}
if (IsLenDecompressedOdd) {
_lastByte = m_io.ReadBytes(1);
}
}
///
/// Decompressor-specific parameters for this compression format,
/// as stored in the compressed resource header.
///
public partial class HeaderParameters : KaitaiStruct
{
public static HeaderParameters FromFile(string fileName)
{
return new HeaderParameters(new KaitaiStream(fileName));
}
public HeaderParameters(KaitaiStream p__io, Dcmp2 p__parent = null, Dcmp2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root;
f_numCustomLookupTableEntries = false;
_read();
}
private void _read()
{
_unknown = m_io.ReadU2be();
_numCustomLookupTableEntriesM1 = m_io.ReadU1();
_flags = new Flags(m_io, this, m_root);
}
///
/// Flags for the decompressor,
/// as stored in the decompressor-specific parameters.
///
public partial class Flags : KaitaiStruct
{
public static Flags FromFile(string fileName)
{
return new Flags(new KaitaiStream(fileName));
}
public Flags(KaitaiStream p__io, Dcmp2.HeaderParameters p__parent = null, Dcmp2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root;
f_asInt = false;
_read();
}
private void _read()
{
_reserved = m_io.ReadBitsIntBe(6);
_tagged = m_io.ReadBitsIntBe(1) != 0;
_hasCustomLookupTable = m_io.ReadBitsIntBe(1) != 0;
}
private bool f_asInt;
private byte _asInt;
///
/// The flags as a packed integer,
/// as they are stored in the data.
///
public byte AsInt
{
get
{
if (f_asInt)
return _asInt;
long _pos = m_io.Pos;
m_io.Seek(0);
_asInt = m_io.ReadU1();
m_io.Seek(_pos);
f_asInt = true;
return _asInt;
}
}
private ulong _reserved;
private bool _tagged;
private bool _hasCustomLookupTable;
private Dcmp2 m_root;
private Dcmp2.HeaderParameters m_parent;
///
/// These flags have no known usage or meaning and should always be zero.
///
public ulong Reserved { get { return _reserved; } }
///
/// Whether the "tagged" variant of this compression format should be used,
/// rather than the default "untagged" variant.
///
public bool Tagged { get { return _tagged; } }
///
/// Whether a custom lookup table is included before the compressed data,
/// which should be used instead of the default hardcoded lookup table.
///
public bool HasCustomLookupTable { get { return _hasCustomLookupTable; } }
public Dcmp2 M_Root { get { return m_root; } }
public Dcmp2.HeaderParameters M_Parent { get { return m_parent; } }
}
private bool f_numCustomLookupTableEntries;
private int? _numCustomLookupTableEntries;
///
/// The number of entries in the custom lookup table.
/// Only used if a custom lookup table is present.
///
public int? NumCustomLookupTableEntries
{
get
{
if (f_numCustomLookupTableEntries)
return _numCustomLookupTableEntries;
if (Flags.HasCustomLookupTable) {
_numCustomLookupTableEntries = (int) ((NumCustomLookupTableEntriesM1 + 1));
}
f_numCustomLookupTableEntries = true;
return _numCustomLookupTableEntries;
}
}
private ushort _unknown;
private byte _numCustomLookupTableEntriesM1;
private Flags _flags;
private Dcmp2 m_root;
private Dcmp2 m_parent;
///
/// The meaning of this field is unknown.
/// It does not appear to have any effect on the format of the compressed data or the decompression process.
///
/// The value of this field is usually zero and otherwise a small integer (< 10).
/// For `'lpch'` resources,
/// the value is always nonzero,
/// and sometimes larger than usual.
///
public ushort Unknown { get { return _unknown; } }
///
/// The number of entries in the custom lookup table,
/// minus one.
///
/// If the default lookup table is used rather than a custom one,
/// this value is zero.
///
public byte NumCustomLookupTableEntriesM1 { get { return _numCustomLookupTableEntriesM1; } }
///
/// Various flags that affect the format of the compressed data and the decompression process.
///
public Flags Flags { get { return _flags; } }
public Dcmp2 M_Root { get { return m_root; } }
public Dcmp2 M_Parent { get { return m_parent; } }
}
///
/// Compressed data in the "untagged" variant of the format.
///
public partial class UntaggedData : KaitaiStruct
{
public static UntaggedData FromFile(string fileName)
{
return new UntaggedData(new KaitaiStream(fileName));
}
public UntaggedData(KaitaiStream p__io, Dcmp2 p__parent = null, Dcmp2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root;
_read();
}
private void _read()
{
_tableReferences = new List();
{
var i = 0;
while (!m_io.IsEof) {
_tableReferences.Add(m_io.ReadU1());
i++;
}
}
}
private List _tableReferences;
private Dcmp2 m_root;
private Dcmp2 m_parent;
///
/// References into the lookup table.
/// Each reference is an integer that is expanded to two bytes by looking it up in the table.
///
public List TableReferences { get { return _tableReferences; } }
public Dcmp2 M_Root { get { return m_root; } }
public Dcmp2 M_Parent { get { return m_parent; } }
}
///
/// Compressed data in the "tagged" variant of the format.
///
public partial class TaggedData : KaitaiStruct
{
public static TaggedData FromFile(string fileName)
{
return new TaggedData(new KaitaiStream(fileName));
}
public TaggedData(KaitaiStream p__io, Dcmp2 p__parent = null, Dcmp2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root;
_read();
}
private void _read()
{
_chunks = new List();
{
var i = 0;
while (!m_io.IsEof) {
_chunks.Add(new Chunk(m_io, this, m_root));
i++;
}
}
}
///
/// A single tagged chunk of compressed data.
///
/// Each chunk expands to 16 bytes of decompressed data.
/// In compressed form,
/// the chunks have a variable length
/// (between 9 and 17 bytes)
/// depending on the value of the tag byte.
///
public partial class Chunk : KaitaiStruct
{
public static Chunk FromFile(string fileName)
{
return new Chunk(new KaitaiStream(fileName));
}
public Chunk(KaitaiStream p__io, Dcmp2.TaggedData p__parent = null, Dcmp2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root;
_read();
}
private void _read()
{
_tag = new List();
for (var i = 0; i < 8; i++)
{
_tag.Add(m_io.ReadBitsIntBe(1) != 0);
}
m_io.AlignToByte();
__raw_units = new List();
_units = new List