Esempio n. 1
0
    def read(cls, fp):
        """Read the element from a file-like object.

        :param fp: file-like object
        """
        name = read_unicode_string(fp)
        classID = read_length_and_key(fp)
        value = read_unicode_string(fp)
        return cls(name, classID, value)
Esempio n. 2
0
def _decode_version_info(data):
    fp = io.BytesIO(data)

    return VersionInfo(
        read_fmt("I", fp)[0],
        read_fmt("?", fp)[0],
        read_unicode_string(fp),
        read_unicode_string(fp),
        read_fmt("I", fp)[0],
    )
Esempio n. 3
0
def _decode_version_info(data):
    fp = io.BytesIO(data)

    return VersionInfo(
        read_fmt("I", fp)[0],
        read_fmt("?", fp)[0],
        read_unicode_string(fp),
        read_unicode_string(fp),
        read_fmt("I", fp)[0],
    )
Esempio n. 4
0
def decode(data):
    """
    Reads and decodes info about linked layers.

    These are embedded files (embedded smart objects). But Adobe calls
    them "linked layers", so we'll follow that nomenclature. Note that
    non-embedded smart objects are not included here.
    """
    fp = io.BytesIO(data)
    layers = []
    while True:
        start = fp.tell()
        length_buf = fp.read(8)
        if not length_buf:
            break   # end of file
        length = struct.unpack(str('>Q'), length_buf)[0]
        liFD, version = read_fmt('4s I', fp)
        if liFD != b'liFD':
            warnings.warn('unknown layer type')
            break
        unique_id = read_pascal_string(fp, 'ascii')
        filename = read_unicode_string(fp)
        filetype, creator, filelength, have_file_open_descriptor = read_fmt('4s 4s Q B', fp)
        filetype = str(filetype)
        if have_file_open_descriptor:
            # Does not seem to contain any useful information
            undocumented_integer = read_fmt("I", fp)
            file_open_descriptor = decode_descriptor(None, fp)
        else:
            file_open_descriptor = None
        decoded = fp.read(filelength)
        # Undocumented extra field
        if version == 5:
            uuid = read_unicode_string(fp)
        else:
            uuid = None
        layers.append(
            LinkedLayer(version, unique_id, filename, filetype, file_open_descriptor,
                        creator, decoded, uuid)
        )
        # Gobble up anything that we don't know how to decode
        expected_position = start + 8 + length      # first 8 bytes contained the length
        if expected_position != fp.tell():
            warnings.warn('skipping over undocumented additional fields')
            fp.read(expected_position - fp.tell())
        # Each layer is padded to start and end at 4-byte boundary
        pad = -fp.tell() % 4
        fp.read(pad)
    return LinkedLayerCollection(layers)
Esempio n. 5
0
def decode(data):
    """
    Reads and decodes info about linked layers.

    These are embedded files (embedded smart objects). But Adobe calls
    them "linked layers", so we'll follow that nomenclature. Note that
    non-embedded smart objects are not included here.
    """
    fp = io.BytesIO(data)
    layers = []
    while True:
        start = fp.tell()
        length_buf = fp.read(8)
        if not length_buf:
            break  # end of file
        length = struct.unpack(str('>Q'), length_buf)[0]
        liFD, version = read_fmt('4s I', fp)
        if liFD != b'liFD':
            warnings.warn('unknown layer type')
            break
        unique_id = read_pascal_string(fp, 'ascii')
        filename = read_unicode_string(fp)
        filetype, creator, filelength, have_file_open_descriptor = read_fmt(
            '4s 4s Q B', fp)
        filetype = str(filetype)
        if have_file_open_descriptor:
            # Does not seem to contain any useful information
            undocumented_integer = read_fmt("I", fp)
            file_open_descriptor = decode_descriptor(None, fp)
        else:
            file_open_descriptor = None
        decoded = fp.read(filelength)
        # Undocumented extra field
        if version == 5:
            uuid = read_unicode_string(fp)
        else:
            uuid = None
        layers.append(
            LinkedLayer(version, unique_id, filename, filetype,
                        file_open_descriptor, creator, decoded, uuid))
        # Gobble up anything that we don't know how to decode
        expected_position = start + 8 + length  # first 8 bytes contained the length
        if expected_position != fp.tell():
            warnings.warn('skipping over undocumented additional fields')
            fp.read(expected_position - fp.tell())
        # Each layer is padded to start and end at 4-byte boundary
        pad = -fp.tell() % 4
        fp.read(pad)
    return LinkedLayerCollection(layers)
Esempio n. 6
0
def decode_descriptor(_, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)

    items = []
    item_count = read_fmt("I", fp)[0]
    while len(items) < item_count:
        item_length = read_fmt("I", fp)[0]
        key = fp.read(item_length or 4)
        ostype = fp.read(4)

        decode_ostype = get_ostype_decode_func(ostype)
        if not decode_ostype:
            # For some reason, name can appear in the middle of items...
            if key == ReferenceOSType.NAME:
                fp.seek(fp.tell() - 4)
                name = decode_name(key, fp)
                continue

            raise UnknownOSType('Unknown descriptor item of type %r' % ostype)

        value = decode_ostype(key, fp)
        if value is None:
            warnings.warn("%r (%r) is None" % (key, ostype))
        items.append((key, value))

    return Descriptor(name, classID, items)
Esempio n. 7
0
def decode_prop(key, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)
    keyID_length = read_fmt("I", fp)[0]
    keyID = fp.read(keyID_length or 4)
    return Property(name, classID, keyID)
Esempio n. 8
0
def _decode_gradient_settings(data, **kwargs):
    fp = io.BytesIO(data)
    version, is_reversed, is_dithered = read_fmt("H 2B", fp)
    if version != 1:
        warnings.warn("Invalid Gradient settings version %s" % (version))
        return data
    name = read_unicode_string(fp)
    color_count = read_fmt("H", fp)[0]
    color_stops = []
    for i in range(color_count):
        location, midpoint, mode = read_fmt("2i H", fp)
        color = read_fmt("4H", fp)
        color_stops.append(ColorStop(location, midpoint, mode, color))
        read_fmt("H", fp)  # Undocumented pad.
    transparency_count = read_fmt("H", fp)[0]
    transparency_stops = []
    for i in range(transparency_count):
        transparency_stops.append(read_fmt("2I H", fp))

    expansion, interpolation, length, mode = read_fmt("4H", fp)
    if expansion != 2 or length != 32:
        warnings.warn("Ignoring Gradient settings")
        return data
    random_seed, show_transparency, use_vector_color = read_fmt("I 2H", fp)
    roughness, color_model = read_fmt("I H", fp)
    minimum_color = read_fmt("4H", fp)
    maximum_color = read_fmt("4H", fp)
    read_fmt("H", fp)  # Dummy pad.

    return GradientSettings(version, is_reversed, is_dithered, name,
                            color_stops, transparency_stops, expansion,
                            interpolation, length, mode, random_seed,
                            show_transparency, use_vector_color, roughness,
                            color_model, minimum_color, maximum_color)
Esempio n. 9
0
def decode_prop(key, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)
    keyID_length = read_fmt("I", fp)[0]
    keyID = fp.read(keyID_length or 4)
    return Property(name, classID, keyID)
Esempio n. 10
0
def test_unicode_string_wr(fixture, padding):
    with io.BytesIO() as f:
        write_unicode_string(f, fixture, padding=padding)
        data = f.getvalue()

    with io.BytesIO(data) as f:
        output = read_unicode_string(f, padding=padding)
        assert fixture == output
Esempio n. 11
0
    def read(cls, fp, **kwargs):
        kind = LinkedLayerType(read_fmt('4s', fp)[0])
        version = read_fmt('I', fp)[0]
        assert 1 <= version and version <= 7, 'Invalid version %d' % (version)
        uuid = read_pascal_string(fp, 'macroman', padding=1)
        filename = read_unicode_string(fp)
        filetype, creator, datasize, open_file = read_fmt('4s4sQB', fp)
        if open_file:
            open_file = DescriptorBlock.read(fp, padding=1)
        else:
            open_file = None

        linked_file = None
        timestamp = None
        data = None
        filesize = None
        child_id = None
        mod_time = None
        lock_state = None

        if kind == LinkedLayerType.EXTERNAL:
            linked_file = DescriptorBlock.read(fp, padding=1)
            if version > 3:
                timestamp = read_fmt('I4Bd', fp)
            filesize = read_fmt('Q', fp)[0]  # External file size.
            if version > 2:
                data = fp.read(datasize)
        elif kind == LinkedLayerType.ALIAS:
            read_fmt('8x', fp)
        if kind == LinkedLayerType.DATA:
            data = fp.read(datasize)
            assert len(data) == datasize, '(%d vs %d)' % (len(data), datasize)

        # The followings are not well documented...
        if version >= 5:
            child_id = read_unicode_string(fp)
        if version >= 6:
            mod_time = read_fmt('d', fp)[0]
        if version >= 7:
            lock_state = read_fmt('B', fp)[0]
        if kind == LinkedLayerType.EXTERNAL and version == 2:
            data = fp.read(datasize)

        return cls(kind, version, uuid, filename, filetype, creator, filesize,
                   open_file, linked_file, timestamp, data, child_id, mod_time,
                   lock_state)
Esempio n. 12
0
    def read(cls, fp):
        """Read the element from a file-like object.

        :param fp: file-like object
        """
        name = read_unicode_string(fp)
        classID = read_length_and_key(fp)
        offset = read_fmt('I', fp)[0]
        return cls(name, classID, offset)
Esempio n. 13
0
def decode_enum_ref(key, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)
    typeID_length = read_fmt("I", fp)[0]
    typeID = fp.read(typeID_length or 4)
    enum_length = read_fmt("I", fp)[0]
    enum = fp.read(enum_length or 4)
    return EnumReference(name, classID, typeID, enum)
Esempio n. 14
0
def decode_enum_ref(key, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)
    typeID_length = read_fmt("I", fp)[0]
    typeID = fp.read(typeID_length or 4)
    enum_length = read_fmt("I", fp)[0]
    enum = fp.read(enum_length or 4)
    return EnumReference(name, classID, typeID, enum)
Esempio n. 15
0
def _decode_slices_v6(fp):
    bbox = read_fmt('4I', fp)
    name = read_unicode_string(fp)
    count = read_fmt('I', fp)[0]
    items = []
    for index in range(count):
        items.append(_decode_slices_v6_block(fp))
    return SlicesHeaderV6(bbox[0], bbox[1], bbox[2], bbox[3], name, count,
                          items)
Esempio n. 16
0
def decode_descriptor(data):
    fp = io.BytesIO(data)
    name = read_unicode_string(fp)

    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)

    item_count = read_fmt("I", fp)[0]
    items = fp.read() # TODO: detailed parsing

    return Descriptor(name, classID, item_count, items)
Esempio n. 17
0
def test_unicode_stringrw(fixture, padding):
    with io.BytesIO(fixture) as f:
        data = read_unicode_string(f, padding=padding)
        print(len(fixture), f.tell())

    print('%d %r' % (len(data), data))

    with io.BytesIO() as f:
        write_unicode_string(f, data, padding=padding)
        output = f.getvalue()
        assert fixture == output
Esempio n. 18
0
 def read(cls, fp):
     slice_id, group_id, origin = read_fmt('3I', fp)
     associated_id = read_fmt('I', fp)[0] if origin == 1 else None
     name = read_unicode_string(fp)
     slice_type = read_fmt('I', fp)[0]
     bbox = read_fmt('4I', fp)
     url = read_unicode_string(fp)
     target = read_unicode_string(fp)
     message = read_unicode_string(fp)
     alt_tag = read_unicode_string(fp)
     cell_is_html = read_fmt('?', fp)[0]
     cell_text = read_unicode_string(fp)
     horizontal_align, vertical_align = read_fmt('2I', fp)
     alpha, red, green, blue = read_fmt('4B', fp)
     data = None
     if is_readable(fp, 4):
         # There is no easy distinction between descriptor block and
         # next slice v6 item here...
         current_position = fp.tell()
         version = read_fmt('I', fp)[0]
         fp.seek(-4, 1)
         if version == 16:
             try:
                 data = DescriptorBlock.read(fp)
                 if data.classID == b'\x00\x00\x00\x00':
                     data = None
                     raise ValueError(data)
             except ValueError:
                 logger.debug('Failed to read DescriptorBlock')
                 fp.seek(current_position)
     return cls(slice_id, group_id, origin, associated_id, name, slice_type,
                bbox, url, target, message, alt_tag, cell_is_html,
                cell_text, horizontal_align, vertical_align, alpha, red,
                green, blue, data)
Esempio n. 19
0
    def _read_body(cls, fp):
        name = read_unicode_string(fp, padding=1)
        classID = read_length_and_key(fp)
        items = []
        count = read_fmt('I', fp)[0]
        for _ in range(count):
            key = read_length_and_key(fp)
            ostype = OSType(fp.read(4))
            kls = TYPES.get(ostype)
            value = kls.read(fp)
            items.append((key, value))

        return dict(name=name, classID=classID, items=items)
Esempio n. 20
0
def _decode_url_list(data):
    urls = []
    fp = io.BytesIO(data)
    count = read_fmt("I", fp)[0]

    try:
        for i in range(count):
            number, id = read_fmt("2I", fp)
            url = read_unicode_string(fp)
            urls.append(UrlListItem(number, id, url))
        return urls
    except UnknownOSType as e:
        warnings.warn("Ignoring image resource %s" % e)
        return data
Esempio n. 21
0
    def read(cls, fp, **kwargs):
        version = read_fmt('I', fp)[0]
        assert version == 1, 'Invalid version %d' % (version)
        image_mode = ColorMode(read_fmt('I', fp)[0])
        point = read_fmt('2h', fp)
        name = read_unicode_string(fp)
        pattern_id = read_pascal_string(fp, encoding='ascii', padding=1)
        color_table = None
        if image_mode == ColorMode.INDEXED:
            color_table = [read_fmt("3B", fp) for i in range(256)]
            read_fmt('4x', fp)

        data = VirtualMemoryArrayList.read(fp)
        return cls(version, image_mode, point, name, pattern_id, color_table,
                   data)
Esempio n. 22
0
def _decode_pattern(data):
    fp = io.BytesIO(data)
    version, image_mode = read_fmt("2I", fp)
    if version != 1:
        warnings.warn("Unsupported patterns version %s" % (version))
        return data

    point = read_fmt("2h", fp)
    name = read_unicode_string(fp)
    pattern_id = read_pascal_string(fp, 'ascii')
    color_table = None
    if image_mode == ColorMode.INDEXED:
        color_table = [read_fmt("3B", fp) for i in range(256)]
        read_fmt('4B', fp)  # Undocumented field here...
    vma_list = _decode_virtual_memory_array_list(fp)
    return Pattern(version, image_mode, point, name, pattern_id, color_table,
                   vma_list)
Esempio n. 23
0
 def read(cls, fp, **kwargs):
     version, is_reversed, is_dithered = read_fmt('H2B', fp)
     assert version == 1, 'Invalid version %s' % (version)
     name = read_unicode_string(fp)
     count = read_fmt('H', fp)[0]
     color_stops = [ColorStop.read(fp) for _ in range(count)]
     count = read_fmt('H', fp)[0]
     transparency_stops = [TransparencyStop.read(fp) for _ in range(count)]
     expansion, interpolation, length, mode = read_fmt('4H', fp)
     assert expansion == 2, 'Invalid expansion %d' % (expansion)
     random_seed, show_transparency, use_vector_color = read_fmt('I2H', fp)
     roughness, color_model = read_fmt('IH', fp)
     minimum_color = read_fmt('4H', fp)
     maximum_color = read_fmt('4H', fp)
     read_fmt('2x', fp)  # Dummy?
     return cls(version, is_reversed, is_dithered, name, color_stops,
                transparency_stops, expansion, interpolation, length,
                mode, random_seed, show_transparency, use_vector_color,
                roughness, color_model, minimum_color, maximum_color)
Esempio n. 24
0
def decode_descriptor(fp):
    name = read_unicode_string(fp)
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)

    items = []
    item_count = read_fmt("I", fp)[0]
    for n in range(item_count):
        item_length = read_fmt("I", fp)[0]
        key = fp.read(item_length or 4)
        ostype = fp.read(4)

        decode_ostype = get_ostype(ostype)
        if decode_ostype:
            value = decode_ostype(key, fp)
            if value is not None:
                items.append((key.decode(), value))

    return Descriptor(name, classID, items)
Esempio n. 25
0
def decode_descriptor(_, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)

    items = []
    item_count = read_fmt("I", fp)[0]
    for n in range(item_count):
        item_length = read_fmt("I", fp)[0]
        key = fp.read(item_length or 4)
        ostype = fp.read(4)

        decode_ostype = get_ostype_decode_func(ostype)
        if not decode_ostype:
            raise UnknownOSType('Unknown descriptor item of type %r' % ostype)

        value = decode_ostype(key, fp)
        if value is not None:
            items.append((key, value))

    return Descriptor(name, classID, items)
Esempio n. 26
0
def decode_descriptor(_, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)

    items = []
    item_count = read_fmt("I", fp)[0]
    for n in range(item_count):
        item_length = read_fmt("I", fp)[0]
        key = fp.read(item_length or 4)
        ostype = fp.read(4)

        decode_ostype = get_ostype_decode_func(ostype)
        if not decode_ostype:
            raise UnknownOSType("Unknown descriptor item of type %r" % ostype)

        value = decode_ostype(key, fp)
        if value is not None:
            items.append((key, value))

    return Descriptor(name, classID, items)
Esempio n. 27
0
def decode_pattern(patternData):

    #print("decode pattern",somehint)
    # repeated for each pattern
    patterns = []
    endOfPatterns = len(patternData)
    if endOfPatterns == 0:
        return patterns
    print("end of pattern", endOfPatterns)

    fp = io.BytesIO(patternData)

    #image mode Bitmap = 0; Grayscale = 1; Indexed = 2; RGB = 3; CMYK = 4; Multichannel = 7; Duotone = 8; Lab = 9
    patternLength = read_fmt("I", fp)[0]
    while patternLength != 0:
        start = fp.tell()
        version, imageMode = read_fmt("II", fp)
        h, w = read_fmt("hh", fp)
        name = read_unicode_string(fp)
        unique_id = read_pascal_string(fp, 'ascii')
        print("decoding pattern", patternLength, version, imageMode, w, h,
              name, unique_id)
        data = decode_virtual_memory_array_list(fp, w, h)

        # seek to expected ending of pattern
        fp.seek(start + patternLength)

        if fp.tell() <= endOfPatterns - 4:
            patternLength = read_fmt("I", fp)[0]
        else:
            patternLength = 0
        print("pattern pos ", fp.tell(), "expected", start + patternLength,
              "end", endOfPatterns)

        patterns.append(Pattern(name, unique_id, data, w, h))

    #mode = _get_mode(len(data))

    return patterns
Esempio n. 28
0
def _decode_slices_v6_block(fp):
    slice_id, group_id, origin = read_fmt('3I', fp)
    associated_id = read_fmt('I', fp)[0] if origin == 1 else None
    name = read_unicode_string(fp)
    slice_type, left, top, right, bottom = read_fmt('5I', fp)
    url = read_unicode_string(fp)
    target = read_unicode_string(fp)
    message = read_unicode_string(fp)
    alt_tag = read_unicode_string(fp)
    cell_is_html = read_fmt('?', fp)[0]
    cell_text = read_unicode_string(fp)
    horizontal_alignment, vertical_alignment = read_fmt('2I', fp)
    alpha, red, green, blue = read_fmt('4B', fp)
    # Some version stores descriptor here, but the documentation unclear...
    descriptor = None
    return SlicesResourceBlock(
        slice_id, group_id, origin, associated_id, name, slice_type, left,
        top, right, bottom, url, target, message, alt_tag, cell_is_html,
        cell_text, horizontal_alignment, vertical_alignment, alpha, red,
        green, blue, descriptor)
Esempio n. 29
0
def decode_class(key, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)
    return Class(name, classID)
Esempio n. 30
0
 def read(cls, fp, padding=1, **kwargs):
     return cls(read_unicode_string(fp, padding=padding))
Esempio n. 31
0
def unicode_string(data):
    return read_unicode_string(io.BytesIO(data))
Esempio n. 32
0
def decode_string(key, fp):
    value = read_unicode_string(fp)[:-1]
    return String(value)
Esempio n. 33
0
def decode_offset(key, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)
    offset = read_fmt("I", fp)[0]
    return Offset(name, classID, offset)
Esempio n. 34
0
def decode_offset(key, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)
    offset = read_fmt("I", fp)[0]
    return Offset(name, classID, offset)
Esempio n. 35
0
 def read(cls, fp):
     name = read_unicode_string(fp)
     classID = read_length_and_key(fp)
     value = read_unicode_string(fp)
     return cls(name, classID, value)
Esempio n. 36
0
 def read(cls, fp):
     name = read_unicode_string(fp)
     classID = read_length_and_key(fp)
     offset = read_fmt('I', fp)[0]
     return cls(name, classID, offset)
Esempio n. 37
0
 def read(cls, fp):
     name = read_unicode_string(fp)
     classID = read_length_and_key(fp)
     typeID = read_length_and_key(fp)
     enum = read_length_and_key(fp)
     return cls(name, classID, typeID, enum)
Esempio n. 38
0
def decode_name(key, fp):
    value = read_unicode_string(fp)[:-1]
    return Name(value)
Esempio n. 39
0
def decode_class(key, fp):
    name = read_unicode_string(fp)[:-1]
    classID_length = read_fmt("I", fp)[0]
    classID = fp.read(classID_length or 4)
    return Class(name, classID)
Esempio n. 40
0
def decode_string(key, fp):
    value = read_unicode_string(fp)[:-1]
    return String(value)
Esempio n. 41
0
def decode_name(key, fp):
    value = read_unicode_string(fp)[:-1]
    return Name(value)
Esempio n. 42
0
def _decode_alpha_names_unicode(data):
    fp = io.BytesIO(data)
    return read_unicode_string(fp)[:-1]