Esempio n. 1
0
 def __init__(self, const):
     self.const = const
     super().__init__(
         c.IfThenElse(
             c.this._building,
             c.Select(c.Bytes(len(self.const)), c.Pass),
             Optional(c.Const(const)),
         )
     )
def test_fieldin():
    test_struct = struct.XStruct(
        'a' / construct.Int32ub,
        'b' / construct.IfThenElse(adapters.FieldIn('a', [1, 2, 3]),
                                   construct.Int32ub, construct.Int16ub))

    assert test_struct(a=1, b=2).build() == b'\x00\x00\x00\x01\x00\x00\x00\x02'
    assert test_struct(a=2, b=2).build() == b'\x00\x00\x00\x02\x00\x00\x00\x02'
    assert test_struct(a=3, b=2).build() == b'\x00\x00\x00\x03\x00\x00\x00\x02'
    assert test_struct(a=4, b=2).build() == b'\x00\x00\x00\x04\x00\x02'
Esempio n. 3
0
class IfThenElse(cst.TContainerMixin):
    @dataclasses.dataclass
    class Then(cst.TContainerMixin):
        then_1: int = cst.sfield(cs.Int16sb)
        then_2: int = cst.sfield(cs.Int16sb)

    @dataclasses.dataclass
    class Else(cst.TContainerMixin):
        else_1: int = cst.sfield(cs.Int8sb)
        else_2: int = cst.sfield(cs.Int8sb)
        else_3: int = cst.sfield(cs.Int8sb)
        else_4: int = cst.sfield(cs.Int8sb)

    choice: int = cst.sfield(cs.Int8ub)
    if_then_else: t.Union[Then, Else] = cst.sfield(
        cs.IfThenElse(cs.this.choice == 0, cst.TStruct(Then),
                      cst.TStruct(Else)))
Esempio n. 4
0
    construct.Rename('main', CREDENTIAL_DEC_MAIN),
    construct.If(
        lambda ctx: ctx.header.unk_type == 2,
        construct.Array(lambda ctx: ctx.header.unk_blocks,
                        CREDENTIAL_DEC_BLOCK_ENC)))

# VAULT file structs.

VAULT_ATTRIBUTE_ENCRYPTED = construct.Struct(
    'VAULT_ATTRIBUTE_ENCRYPTED', construct.Byte('has_iv'),
    construct.IfThenElse(
        '', lambda ctx: ctx.has_iv,
        construct.Embed(
            construct.Struct(
                'encrypted', construct.ULInt32('iv_size'),
                construct.Bytes('iv', lambda ctx: ctx.iv_size),
                construct.Bytes('data',
                                lambda ctx: ctx.size - 1 - 4 - ctx.iv_size))),
        construct.Embed(
            construct.Struct('encrypted',
                             construct.Bytes('data',
                                             lambda ctx: ctx.size - 1)))))

VAULT_ATTRIBUTE = construct.Struct(
    'VAULT_ATTRIBUTE',
    construct.ULInt32('id'),
    construct.ULInt32('attr_unknown_1'),
    construct.ULInt32('attr_unknown_2'),
    construct.ULInt32('attr_unknown_3'),
    # Ok, this is bad, but till now I have not understood how to distinguish
    # the different structs used. Actually the last ATTRIBUTE is different.
    # Usually we have 6 more bytes zeroed, not always aligned: otherwise,
Esempio n. 5
0
    "counts" / C.Int16ul,
    "imageCount" /
    C.Computed(lambda this: this.counts & 0x3FF if this.version in
               swizzableFormats else this.counts >> 8),  #C.Int8ul,#12
    "mipCount" /
    C.Computed(lambda this:
               (this.counts >> 12 if this.version in swizzableFormats else this
                .counts & 0xFF)),  #C.Int8ul,#4
    "format" / C.Int32ul,
    "swizzleControl" / C.Int32sl,  #C.Const(1,C.Int32ul),
    "cubemapMarker" / C.Int32ul,
    "unkn04" / C.Int8ul[2],
    "NULL0" / C.Const(0, C.Int16ul),
    "swizzleData" / C.If(
        lambda ctx: ctx.version in swizzableFormats,
        C.IfThenElse(lambda ctx: ctx.version in swizzledFormats, swizzleData,
                     swizzleNull)),
    "textureHeaders" / mipData[C.this.mipCount][C.this.imageCount],
    "start" / C.Tell,
    "data" / C.GreedyBytes,
)
TEXHeader = _TEXHeader  #.compile()


def expandBlockData(texhead, swizzle):
    texs = []
    for image in texhead.textureHeaders:
        mips = []
        for mipsTex in image:
            start = mipsTex.mipOffset - texhead.start
            end = start + (mipsTex.compressedSize
                           if swizzle else mipsTex.uncompressedSize)
Esempio n. 6
0
    "frameDataOffset" / C.Int64sl,
    "frameCount" / C.Int64sl,
    "frameIndexOffset" / C.Int64sl,
    "frameIndexCount" / C.Int64sl,
    "dataOffset" / C.Int64sl,
    "mapCount" / C.Int64sl,
    "unkn32_0" / C.Float32l,
    "unkn32_1" / C.Float32l,
    "unkn3" / C.Int64sl,
    "frameData" /
    C.Pointer(C.this.frameDataOffset, Primary[C.this.frameCount]),
    "frameIndex" /
    C.Pointer(C.this.frameIndexOffset,
              C.Int32sl[C.this.frameIndexCount]),  #32-Padded to next
    "mapIndices" /
    C.IfThenElse(C.this.frameCount != 0,
                 C.Pointer(C.this.dataOffset, C.Int32sl[4]), C.Int32sl[0]),
)


def defaultMapIndices(l):
    return l + [0] * (4 - len(l))


StringHead = C.Struct("blank" / C.Int64sl, "stringOffset" / C.Int64sl,
                      "type" / C.Int32sl)
StringBody = C.Struct("string" / C.CString("utf-8"), )
StringData = C.Struct(
    "blank" / C.Int64sl, "stringOffset" / C.Int64sl, "type" / C.Int32sl,
    "string" / C.Pointer(C.this.stringOffset, C.CString("utf-8")),
    "padding" / C.Optional(C.Const(0, C.Int32sl)))
Esempio n. 7
0
        "src_addressing_mode" / addressing_mode_t,
    ))

mac_header_t = ct.Struct(
    "fcf" / fcf_t,
    "seqnum" / ct.Hex(ct.Int8ul),
    "dst_addr" / ct.Switch(
        lambda ctx: int(ctx.fcf.dst_addressing_mode), {
            int(addressing_mode_t.SHORT): short_addr_t,
            int(addressing_mode_t.LONG): long_addr_t,
        }),
    "src_addr" / ct.If(
        lambda ctx: is_address_present(ctx.fcf.src_addressing_mode),
        ct.Struct(
            "pan_id" / ct.IfThenElse(
                lambda ctx: ctx._.fcf.pan_id_comp and is_address_present(
                    ctx._.fcf.dst_addressing_mode),
                ct.Computed(ct.this._.dst_addr.pan_id), ct.Hex(ct.Int16ul)),
            "addr" / ct.Switch(
                lambda ctx: int(ctx._.fcf.src_addressing_mode), {
                    int(addressing_mode_t.SHORT): ct.Hex(ct.Int16ul),
                    int(addressing_mode_t.LONG): ct.Hex(ct.Int64ul)
                }))),
)

mpdu_t = ct.Struct(
    "mac" / mac_header_t, "pdu_offset" / ct.Tell, "pdu" /
    ct.ExprAdapter(ct.HexDump(ct.GreedyBytes), ct.obj_[:-2], ct.obj_ + "AA"),
    ct.Seek(-2, ct.io.SEEK_CUR), "fcs_offset" / ct.Tell,
    ct.If(ct.this.pdu_offset > ct.this.fcs_offset,
          ct.Error), "fcs" / ct.Hex(ct.Int16ul))
Esempio n. 8
0
 def struct(cls):
     return construct.Struct(
         "signature" / construct.Const(b"vf"),
         "version" / _LMArchiveVersionValidator(construct.Int32ul),
         "count" / construct.Int32ul,
         "filenames" / construct.Array(
             construct.this.count,
             construct.IfThenElse(
                 construct.this.version >= 100,
                 construct.Prefixed(
                     construct.Int32ul,
                     construct.Transformed(
                         construct.GreedyString('cp932'),
                         LMObfuscator().transform_bytes,
                         None,
                         LMObfuscator().transform_bytes,
                         None,
                     ),
                 ),
                 construct.PascalString(construct.Int32ul, 'cp932'),
             )),
         "offsets" / construct.Array(
             construct.this.count + 1,
             construct.Struct(
                 "offset_low" / construct.IfThenElse(
                     construct.this._.version >= 100,
                     construct.Transformed(
                         construct.Int32ul,
                         LMObfuscator().transform_int,
                         4,
                         LMObfuscator().transform_int,
                         4,
                     ),
                     construct.Int32ul,
                 ),
                 # offset_high always 0 if ver < 101
                 "offset_high" / construct.IfThenElse(
                     construct.this._.version >= 101,
                     construct.Transformed(
                         construct.Int32ul,
                         LMObfuscator().transform_int,
                         4,
                         LMObfuscator().transform_int_high,
                         4,
                     ),
                     construct.Int32ul,
                 ),
             ),
         ),
         "compress_types" /
         construct.Array(construct.this.count,
                         construct.Enum(construct.Byte, LMCompressType)),
         "unk1s" / construct.Array(
             construct.this.count,
             # construct.Transformed(
             #     construct.Int32ul,
             #     LMObfuscator().transform_int,
             #     4,
             #     LMObfuscator().transform_int,
             #     4,
             # ),
             construct.Int32ul,
         ),
         "checksums" / construct.Array(
             construct.this.count,
             construct.Int32ul,
         ),
         "encrypt_flags" / construct.Array(
             construct.this.count,
             construct.Byte,
         ),
     )
Esempio n. 9
0
class FlacReader:
    FRAME_HEADER = construct.Struct(
        'frame_header', construct.Bits('sync', 14),
        construct.Bits('reserved', 2), construct.Bits('block_size', 4),
        construct.Bits('sample_rate', 4),
        construct.Bits('channel_assignment', 4),
        construct.Bits('bits_per_sample', 3), construct.Padding(1),
        construct.IfThenElse(
            'total_channels', lambda ctx1: ctx1['channel_assignment'] <= 7,
            construct.Value('c', lambda ctx2: ctx2['channel_assignment'] + 1),
            construct.Value('c', lambda ctx3: 2)), UTF8('frame_number'),
        construct.IfThenElse(
            'extended_block_size', lambda ctx1: ctx1['block_size'] == 6,
            construct.Bits('b', 8),
            construct.If(lambda ctx2: ctx2['block_size'] == 7,
                         construct.Bits('b', 16))),
        construct.IfThenElse(
            'extended_sample_rate', lambda ctx1: ctx1['sample_rate'] == 12,
            construct.Bits('s', 8),
            construct.If(lambda ctx2: ctx2['sample_rate'] in (13, 14),
                         construct.Bits('s', 16))), construct.Bits('crc8', 8))

    UNARY = construct.Struct(
        'unary',
        construct.RepeatUntil(lambda obj, ctx: obj == '\x01',
                              construct.Field('bytes', 1)),
        construct.Value('value', lambda ctx: len(ctx['bytes']) - 1))

    SUBFRAME_HEADER = construct.Struct(
        'subframe_header', construct.Padding(1),
        construct.Bits('subframe_type', 6),
        construct.Flag('has_wasted_bits_per_sample'),
        construct.IfThenElse('wasted_bits_per_sample',
                             lambda ctx: ctx['has_wasted_bits_per_sample'],
                             PlusOne(Unary('value')),
                             construct.Value('value', lambda ctx2: 0)))

    GET_BLOCKSIZE_FROM_STREAMINFO = -1
    GET_8BIT_BLOCKSIZE_FROM_END_OF_HEADER = -2
    GET_16BIT_BLOCKSIZE_FROM_END_OF_HEADER = -3

    BLOCK_SIZE = (GET_BLOCKSIZE_FROM_STREAMINFO, 192, 576, 1152, 2304, 4608,
                  GET_8BIT_BLOCKSIZE_FROM_END_OF_HEADER,
                  GET_16BIT_BLOCKSIZE_FROM_END_OF_HEADER, 256, 512, 1024, 2048,
                  4096, 8192, 16384, 32768)

    GET_SAMPLE_SIZE_FROM_STREAMINFO = -1
    SAMPLE_SIZE = (GET_SAMPLE_SIZE_FROM_STREAMINFO, 8, 12, None, 16, 20, 24,
                   None)

    def FIXED0(subframe, residual, i):
        subframe.insert(i, residual[i])

    def FIXED1(subframe, residual, i):
        subframe.insert(i, subframe[i - 1] + residual[i])

    def FIXED2(subframe, residual, i):
        subframe.insert(i,
                        ((2 * subframe[i - 1]) - subframe[i - 2] + \
                         residual[i]))

    def FIXED3(subframe, residual, i):
        subframe.insert(i,
                        ((3 * subframe[i - 1]) - (3 * subframe[i - 2]) + \
                         subframe[i - 3] + residual[i]))

    def FIXED4(subframe, residual, i):
        subframe.insert(i,
                        ((4 * subframe[i - 1]) - (6 * subframe[i - 2]) + \
                         (4 * subframe[i - 3]) - subframe[i - 4] + residual[i]))

    #iterates over all of the channels, in order
    def MERGE_INDEPENDENT(channel_list):
        channel_data = [iter(c) for c in channel_list]

        while (True):
            for channel in channel_data:
                yield channel.next()

    def MERGE_LEFT(channel_list):
        channel_left = iter(channel_list[0])
        channel_side = iter(channel_list[1])

        while (True):
            left = channel_left.next()
            side = channel_side.next()

            yield left
            yield left - side

    def MERGE_RIGHT(channel_list):
        channel_side = iter(channel_list[0])
        channel_right = iter(channel_list[1])

        while (True):
            side = channel_side.next()
            right = channel_right.next()

            yield side + right
            yield right

    def MERGE_MID(channel_list):
        channel_mid = iter(channel_list[0])
        channel_side = iter(channel_list[1])

        while (True):
            mid = channel_mid.next()
            side = channel_side.next()

            mid = mid << 1
            mid |= (side & 0x1)

            yield (mid + side) >> 1
            yield (mid - side) >> 1

    CHANNEL_FUNCTIONS = (MERGE_INDEPENDENT, MERGE_INDEPENDENT,
                         MERGE_INDEPENDENT, MERGE_INDEPENDENT,
                         MERGE_INDEPENDENT, MERGE_INDEPENDENT,
                         MERGE_INDEPENDENT, MERGE_INDEPENDENT, MERGE_LEFT,
                         MERGE_RIGHT, MERGE_MID)

    FIXED_FUNCTIONS = (FIXED0, FIXED1, FIXED2, FIXED3, FIXED4)

    def __init__(self, flac_stream):
        self.stream = BufferedStream(flac_stream)
        self.streaminfo = None
        self.bitstream = None

        #ensure the file starts with 'fLaC'
        self.read_stream_marker()

        #initialize self.bitstream
        self.begin_bitstream()

        #find self.streaminfo in case we need it
        self.read_metadata_blocks()

    def close(self):
        if (self.bitstream != None):
            self.bitstream.close()
        else:
            self.stream.close()

    def read_stream_marker(self):
        if (self.stream.read(4) != 'fLaC'):
            raise FlacStreamException('invalid stream marker')

    def read_metadata_blocks(self):
        block = audiotools.FlacAudio.METADATA_BLOCK_HEADER.parse_stream(
            self.stream)
        while (block.last_block == 0):
            if (block.block_type == 0):
                self.streaminfo = audiotools.FlacAudio.STREAMINFO.parse_stream(
                    self.stream)
            else:
                self.stream.seek(block.block_length, 1)

            block = audiotools.FlacAudio.METADATA_BLOCK_HEADER.parse_stream(
                self.stream)
        self.stream.seek(block.block_length, 1)

    def begin_bitstream(self):
        import bitstream

        #self.bitstream = construct.BitStreamReader(self.stream)
        self.bitstream = bitstream.BitStreamReader(self.stream)

    def read_frame(self):
        self.stream.reset_buffer()

        try:
            header = FlacReader.FRAME_HEADER.parse_stream(self.bitstream)
        except construct.core.FieldError:
            return ""

        if (header.sync != 0x3FFE):
            raise FlacStreamException('invalid sync')

        if (crc8(self.stream.getvalue()[0:-1]) != header.crc8):
            raise FlacStreamException('crc8 checksum failed')

        #block_size tells us how many samples we need from each subframe
        block_size = FlacReader.BLOCK_SIZE[header.block_size]
        if (block_size == self.GET_BLOCKSIZE_FROM_STREAMINFO):
            block_size = self.streaminfo.maximum_blocksize

        elif ((block_size == self.GET_8BIT_BLOCKSIZE_FROM_END_OF_HEADER)
              or (block_size == self.GET_16BIT_BLOCKSIZE_FROM_END_OF_HEADER)):
            block_size = header.extended_block_size + 1

        #grab subframe data as 32-bit array objects
        subframe_data = []

        for channel_number in xrange(header.total_channels):
            subframe_data.append(
                self.read_subframe(header, block_size, channel_number))

        crc16sum = crc16(self.stream.getvalue())

        #try to byte-align the stream
        if (len(self.bitstream.buffer) > 0):
            self.bitstream.read(len(self.bitstream.buffer))

        if (crc16sum != construct.Bits('crc16', 16).parse_stream(
                self.bitstream)):
            raise FlacStreamException('crc16 checksum failed')

        #convert our list of subframe data arrays into
        #a string of sample data
        if (FlacReader.SAMPLE_SIZE[header.bits_per_sample] == 16):
            merged_frames = array.array(
                'h', FlacReader.CHANNEL_FUNCTIONS[header.channel_assignment](
                    subframe_data))

            if (audiotools.BIG_ENDIAN):
                merged_frames.byteswap()

            return merged_frames.tostring()

        elif (FlacReader.SAMPLE_SIZE[header.bits_per_sample] == 8):
            merged_frames = array.array(
                'b', FlacReader.CHANNEL_FUNCTIONS[header.channel_assignment](
                    subframe_data))

            return merged_frames.tostring()

        else:
            if (FlacReader.SAMPLE_SIZE[header.bits_per_sample] == \
                self.GET_SAMPLE_SIZE_FROM_STREAMINFO):
                bits_per_sample = self.streaminfo.bits_per_sample + 1

            elif (FlacReader.SAMPLE_SIZE[header.bits_per_sample] == None):
                raise FlacStreamException('invalid bits per sample')

            else:
                bits_per_sample = FlacReader.SAMPLE_SIZE[
                    header.bits_per_sample]

            stream = construct.GreedyRepeater(
                construct.BitStruct(
                    'bits',
                    construct.Bits('value',
                                   bits_per_sample,
                                   swapped=True,
                                   signed=True)))

            return stream.build([
                construct.Container(value=v)
                for v in FlacReader.CHANNEL_FUNCTIONS[
                    header.channel_assignment](subframe_data)
            ])

    def read_subframe(self, frame_header, block_size, channel_number):
        subframe_header = \
                        FlacReader.SUBFRAME_HEADER.parse_stream(self.bitstream)

        #figure out the bits-per-sample of this subframe
        if ((frame_header.channel_assignment == 8) and (channel_number == 1)):
            #if channel is stored as left+difference
            #and this is the difference, add 1 bit
            bits_per_sample = FlacReader.SAMPLE_SIZE[
                frame_header.bits_per_sample] + 1

        elif ((frame_header.channel_assignment == 9)
              and (channel_number == 0)):
            #if channel is stored as difference+right
            #and this is the difference, add 1 bit
            bits_per_sample = FlacReader.SAMPLE_SIZE[
                frame_header.bits_per_sample] + 1

        elif ((frame_header.channel_assignment == 10)
              and (channel_number == 1)):
            #if channel is stored as average+difference
            #and this is the difference, add 1 bit
            bits_per_sample = FlacReader.SAMPLE_SIZE[
                frame_header.bits_per_sample] + 1

        else:
            #otherwise, use the number from the frame header
            bits_per_sample = FlacReader.SAMPLE_SIZE[
                frame_header.bits_per_sample]

        if (subframe_header.has_wasted_bits_per_sample):
            bits_per_sample -= subframe_header.wasted_bits_per_sample

        if (subframe_header.subframe_type == 0):
            subframe = self.read_subframe_constant(block_size, bits_per_sample)

        elif (subframe_header.subframe_type == 1):
            subframe = self.read_subframe_verbatim(block_size, bits_per_sample)

        elif ((subframe_header.subframe_type & 0x38) == 0x08):
            subframe = self.read_subframe_fixed(
                subframe_header.subframe_type & 0x07, block_size,
                bits_per_sample)

        elif ((subframe_header.subframe_type & 0x20) == 0x20):
            subframe = self.read_subframe_lpc(
                (subframe_header.subframe_type & 0x1F) + 1, block_size,
                bits_per_sample)

        else:
            raise FlacStreamException('invalid subframe type')

        if (subframe_header.has_wasted_bits_per_sample):
            return array.array('i', [
                i << subframe_header.wasted_bits_per_sample for i in subframe
            ])
        else:
            return subframe

    def read_subframe_constant(self, block_size, bits_per_sample):
        sample = construct.Bits('b',
                                bits_per_sample).parse_stream(self.bitstream)

        subframe = array.array('i', [sample] * block_size)

        return subframe

    def read_subframe_verbatim(self, block_size, bits_per_sample):
        return array.array(
            'i',
            construct.StrictRepeater(
                block_size,
                construct.Bits("samples", bits_per_sample,
                               signed=True)).parse_stream(self.bitstream))

    def read_subframe_fixed(self, order, block_size, bits_per_sample):
        samples = construct.StrictRepeater(
            order,
            construct.Bits("warm_up_samples", bits_per_sample, signed=True))

        subframe = array.array('i', samples.parse_stream(self.bitstream))

        residual = self.read_residual(block_size, order)

        fixed_func = self.FIXED_FUNCTIONS[order]

        for i in xrange(len(subframe), block_size):
            fixed_func(subframe, residual, i)

        return subframe

    def read_subframe_lpc(self, order, block_size, bits_per_sample):
        samples = construct.StrictRepeater(
            order,
            construct.Bits("warm_up_samples", bits_per_sample, signed=True))

        subframe = array.array('i', samples.parse_stream(self.bitstream))

        lpc_precision = construct.Bits('lpc_precision', 4).parse_stream(
            self.bitstream) + 1

        lpc_shift = construct.Bits('lpc_shift', 5).parse_stream(self.bitstream)

        coefficients = array.array(
            'i',
            construct.StrictRepeater(
                order,
                construct.Bits('coefficients', lpc_precision,
                               signed=True)).parse_stream(self.bitstream))

        residual = self.read_residual(block_size, order)

        for i in xrange(len(subframe), block_size):
            subframe.insert(i,
                            (sum(
                [coefficients[j] * subframe[i - j - 1] for j in
                 xrange(0,len(coefficients))]) >> lpc_shift) + \
                            residual[i])

        return subframe

    def read_residual(self, block_size, predictor_order):
        rice = array.array('i')

        #add some dummy rice so that the Rice index matches
        #that of the rest of the subframe
        for i in xrange(predictor_order):
            rice.append(0)

        coding_method = self.bitstream.read(2)
        if (coding_method == '\x00\x00'):
            rice2 = False
        elif (coding_method == '\x00\x01'):
            rice2 = True
        else:
            raise FlacStreamException('invalid residual coding method')

        partition_order = construct.Bits('partition_order',
                                         4).parse_stream(self.bitstream)

        if (partition_order > 0):
            total_samples = ((block_size / 2**partition_order) -
                             predictor_order)
            rice.extend(self.read_encoded_rice(total_samples, rice2))

            for i in xrange(1, 2**partition_order):
                total_samples = (block_size / 2**partition_order)

                rice.extend(self.read_encoded_rice(total_samples, rice2))
        else:
            rice.extend(
                self.read_encoded_rice(block_size - predictor_order, rice2))

        return rice

    def read_encoded_rice(self, total_samples, rice2=False):
        bin_to_int = construct.lib.binary.bin_to_int

        samples = array.array('i')

        if (not rice2):
            rice_parameter = construct.Bits('rice_parameter',
                                            4).parse_stream(self.bitstream)
        else:
            rice_parameter = construct.Bits('rice_parameter',
                                            5).parse_stream(self.bitstream)

        if (rice_parameter != 0xF):
            #a Rice encoded residual
            for x in xrange(total_samples):

                #count the number of 0 bits before the next 1 bit
                #(unary encoding)
                #to find our most significant bits
                msb = 0
                s = self.bitstream.read(1)
                while (s != '\x01'):
                    msb += 1
                    s = self.bitstream.read(1)

                #grab the proper number of least significant bits
                lsb = bin_to_int(self.bitstream.read(rice_parameter))

                #combine msb and lsb to get the Rice-encoded value
                value = (msb << rice_parameter) | lsb
                if ((value & 0x1) == 0x1):  #negative
                    samples.append(-(value >> 1) - 1)
                else:  #positive
                    samples.append(value >> 1)
        else:
            #unencoded residual

            bits_per_sample = construct.Bits('escape_code',
                                             5).parse_stream(self.bitstream)

            sample = construct.Bits("sample", bits_per_sample, signed=True)

            for x in xrange(total_samples):
                samples.append(sample.parse_stream(self.bitstream))

        return samples
Esempio n. 10
0
    "frame_width"           / construct.Int16ul,                                            # + 0x14
    "frame_height"          / construct.Int16ul,                                            # + 0x16
    "end_gdv_header"        / construct.Tell,
)

#
# GDV file
#
gdv_file = construct.Struct(
    "gdv_header"            / gdv_header,
    # 768-byte palette if the video is palettized (image type indicates 8 bits/pixel)
    "palette"               / construct.If(lambda ctx: ctx.gdv_header.image_type.video_depth == "PIXEL_8_BITS",
                                construct.OnDemandPointer(lambda ctx: ctx.gdv_header.end_gdv_header,
                                    construct.Array(0x300, "palette" / construct.Int8ul))),
    "start_chunks"          / construct.IfThenElse(lambda ctx: ctx.gdv_header.image_type.video_depth == "PIXEL_8_BITS",
                                construct.Computed(lambda ctx: ctx.gdv_header.end_gdv_header + 0x300),
                                construct.Computed(lambda ctx: ctx.gdv_header.end_gdv_header)),
    "chunks"                / construct.OnDemandPointer(lambda ctx: ctx.start_chunks,
        construct.Array(lambda ctx: ctx.gdv_header.nb_frames, gdv_chunk)
        ),
)

##########################
#
# Video decoder
#
##########################

#
# 32-bit bit queue & stream reader
#
Esempio n. 11
0
 def __init__(self, websocket, mode):
     self._websocket = websocket
     self._mode = mode
     self._inbound_packet = construct.Struct(
         "type" / construct.Enum(
             construct.Int8ul,
             setup=0,
             killed=1,
             kill=2,
             remove=3,
             sync=4,
             club_collision=5,
             wall_collision=6,
             set_leaderboard=7,
             set_target_dim=8
         ),
         "payload" / construct.Switch(
             construct.this.type, {
                 "setup": construct.Struct(
                     "server_version" / construct.CString(encoding="utf8"),
                     construct.Check(lambda ctx: ctx.server_version == CLIENT_VERSION),
                     "syncer_value" / construct.Int32ul,
                     "game_mode" / construct.Mapping(
                         construct.Int8ul, {
                             0: Mode.ffa,
                             1: Mode.tdm
                         },
                         dict() # This packet is only received
                     ),
                     "setup_value" / construct.Int32ul
                 ),
                 "killed": construct.Pass,
                 "kill": construct.Struct("stamp" / construct.Int32ul),
                 "remove": construct.Struct(
                     "enqueue_param" / construct.Int32ul, # TODO: Figure out purpose
                     "player_id" / construct.Int32ul
                 ),
                 "sync": construct.Struct(
                     "timestamp" / construct.Int32ul,
                     "remove_count" / construct.Int32ul,
                     "removal_array" / construct.Array(
                         construct.this.remove_count,
                         construct.Int32ul
                     ),
                     "sync_count" / construct.Int32ul,
                     "sync_array" / construct.Array(
                         construct.this.sync_count,
                         construct.Struct(
                             "player_id" / construct.Int32ul,
                             "player_state" / physical_state,
                             "mace_state" / physical_state,
                             "mace_radius" / construct.Float32l
                         )
                     )
                 ),
                 "club_collision": construct.Struct(
                     "enqueue_param" / construct.Int32ul, # TODO: Figure out purpose
                     "p" / vector2d, # TODO: Figure out purpose
                     "i" / construct.Float32l, # TODO: Figure out purpose
                     "first_id" / construct.Int32ul,
                     "first_state" / physical_state,
                     "second_id" / construct.Int32ul,
                     "second_state" / physical_state
                 ),
                 "wall_collision": construct.Struct(
                     "enqueue_param" / construct.Int32ul, # TODO: Figure out purpose
                     "p" / vector2d, # TODO: Figure out purpose
                     "i" / construct.Float32l, # TODO: Figure out purpose
                     "player_id" / construct.Int32ul,
                     "player_state" / physical_state,
                     "mace_radius" / construct.Float32l
                 ),
                 "set_leaderboard": construct.Struct(
                     "player_count" / construct.Int32ul,
                     "total" / construct.Int32ul, # TODO: Figure out purpose,
                     construct.IfThenElse(
                         lambda ctx: self._mode == Mode.ffa,
                         construct.Struct( # FFA
                             "count" / construct.Int8ul,
                             "first_entry_id" / construct.Int32ul,
                             "leaderboard" / construct.Array(
                                 construct.this.count,
                                 construct.Struct(
                                     "name" / construct.CString(encoding="utf8"),
                                     "score" / construct.Int32ul,
                                     )
                                 ),
                             "king_name" / construct.CString(encoding="utf8"),
                             "king_score" / construct.Int32ul,
                             "place" / construct.Int32ul,
                             "score" / construct.Int32ul
                         ),
                         construct.Array(
                             3,
                             construct.Struct(
                                 "id" / construct.Int8ul,
                                 "score" / construct.Int32ul,
                                 "count" / construct.Int32ul
                             )
                         )
                     )
                 ),
                 "set_target_dim": construct.Struct("target_dim" / vector2d)
             }
         )
     )
     self._outbound_packet = construct.Struct(
         "type" / construct.Enum(
             construct.Int8ul,
             play=0,
             direction=1,
             move_up=2,
             move_down=3,
             move_left=4,
             move_right=5,
             stop_move_up=6,
             stop_move_down=7,
             stop_move_left=8,
             stop_move_right=9
         ),
         "payload" / construct.Switch(
             construct.this.type, {
                 "play": construct.Pass
                         # TODO: Implement the rest of the packets
             }
         )
     )