mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-04 02:13:38 +00:00
980e05cc99
Backported 400 revisions from rev 1de4961-8897c5b (2018-2014). Move core/benchmark, core/cmd_line, core/memory, core/profiler and core/timeout to core/optional/* Remove metadata/qt* PORT: Version 2.0a3 (inline with 3.0a3 @ f80c7d5). Basic Support for XMP Packets. tga: improvements to adhere more closely to the spec. pdf: slightly improved parsing. rar: fix TypeError on unknown block types. Add MacRoman win32 codepage. tiff/exif: support SubIFDs and tiled images. Add method to export metadata in dictionary. mpeg_video: don't attempt to parse Stream past length. mpeg_video: parse ESCR correctly, add SCR value. Change centralise CustomFragments. field: don't set parser class if class is None, to enable autodetect. field: add value/display for CustomFragment. parser: inline warning to enable tracebacks in debug mode. Fix empty bytestrings in makePrintable. Fix contentSize in jpeg.py to account for image_data blocks. Fix the ELF parser. Enhance the AR archive parser. elf parser: fix wrong wrong fields order in parsing little endian section flags. elf parser: add s390 as a machine type. Flesh out mp4 parser. PORT: Version 2.0a1 (inline with 3.0a1). Major refactoring and PEP8. Fix ResourceWarning warnings on files. Add a close() method and support for the context manager protocol ("with obj: ...") to parsers, input and output streams. metadata: get comment from ZIP. Support for InputIOStream.read(0). Fix sizeGe when size is None. Remove unused new_seekable_field_set file. Remove parser Mapsforge .map. Remove parser Parallel Realities Starfighter .pak files. sevenzip: fix for newer archives. java: update access flags and modifiers for Java 1.7 and update description text for most recent Java. Support ustar prefix field in tar archives. Remove file_system* parsers. Remove misc parsers 3d0, 3ds, gnome_keyring, msoffice*, mstask, ole*, word*. Remove program parsers macho, nds, prc. Support non-8bit Character subclasses. Python parser supports Python 3.7. Enhance mpeg_ts parser to support MTS/M2TS. Support for creation date in tiff. Change don't hardcode errno constant. PORT: 1.9.1 Internal Only: The following are legacy reference to upstream commit messages. Relevant changes up to b0a115f8. Use integer division. Replace HACHOIR_ERRORS with Exception. Fix metadata.Data: make it sortable. Import fixes from e7de492. PORT: Version 2.0a1 (inline with 3.0a1 @ e9f8fad). Replace hachoir.core.field with hachoir.field Replace hachoir.core.stream with hachoir.stream Remove the compatibility module for PY1.5 to PY2.5. metadata: support TIFF picture. metadata: fix string normalization. metadata: fix datetime regex Fix hachoir bug #57. FileFromInputStream: fix comparison between None and an int. InputIOStream: open the file in binary mode.
180 lines
6.1 KiB
Python
180 lines
6.1 KiB
Python
from hachoir.field import (FieldSet,
|
|
UInt16, UInt32, Enum, String, Bytes, Bits, TimestampUUID60)
|
|
from hachoir.parser.video.fourcc import video_fourcc_name
|
|
from hachoir.core.bits import str2hex
|
|
from hachoir.core.text_handler import textHandler, hexadecimal
|
|
from hachoir.parser.network.common import MAC48_Address
|
|
|
|
# Dictionary: Windows codepage => Python charset name
|
|
CODEPAGE_CHARSET = {
|
|
874: "CP874",
|
|
# 932: Japanese Shift-JIS
|
|
# 936: Simplified Chinese GBK
|
|
# 949: Korean
|
|
# 950: Traditional Chinese Big5
|
|
1250: "WINDOWS-1250",
|
|
1251: "WINDOWS-1251",
|
|
1252: "WINDOWS-1252",
|
|
1253: "WINDOWS-1253",
|
|
1254: "WINDOWS-1254",
|
|
1255: "WINDOWS-1255",
|
|
1256: "WINDOWS-1256",
|
|
1257: "WINDOWS-1257",
|
|
1258: "WINDOWS-1258",
|
|
10000: "MacRoman",
|
|
65001: "UTF-8",
|
|
}
|
|
|
|
|
|
class PascalStringWin16(FieldSet):
|
|
def __init__(self, parent, name, description=None, strip=None, charset="UTF-16-LE"):
|
|
FieldSet.__init__(self, parent, name, description)
|
|
length = self["length"].value
|
|
self._size = 16 + length * 16
|
|
self.strip = strip
|
|
self.charset = charset
|
|
|
|
def createFields(self):
|
|
yield UInt16(self, "length", "Length in widechar characters")
|
|
size = self["length"].value
|
|
if size:
|
|
yield String(self, "text", size * 2, charset=self.charset, strip=self.strip)
|
|
|
|
def createValue(self):
|
|
if "text" in self:
|
|
return self["text"].value
|
|
else:
|
|
return None
|
|
|
|
|
|
class PascalStringWin32(FieldSet):
|
|
def __init__(self, parent, name, description=None, strip=None, charset="UTF-16-LE"):
|
|
FieldSet.__init__(self, parent, name, description)
|
|
length = self["length"].value
|
|
self._size = 32 + length * 16
|
|
self.strip = strip
|
|
self.charset = charset
|
|
|
|
def createFields(self):
|
|
yield UInt32(self, "length", "Length in widechar characters")
|
|
size = self["length"].value
|
|
if size:
|
|
yield String(self, "text", size * 2, charset=self.charset, strip=self.strip)
|
|
|
|
def createValue(self):
|
|
if "text" in self:
|
|
return self["text"].value
|
|
else:
|
|
return None
|
|
|
|
|
|
class GUID(FieldSet):
|
|
"""
|
|
Windows 128 bits Globally Unique Identifier (GUID)
|
|
|
|
See RFC 4122
|
|
"""
|
|
static_size = 128
|
|
NULL = "00000000-0000-0000-0000-000000000000"
|
|
FIELD_NAMES = {
|
|
3: ("sha1_high", "sha1_low"),
|
|
4: ("random_high", "random_low"),
|
|
5: ("md5_high", "md5_low"),
|
|
}
|
|
VERSION_NAME = {
|
|
1: "Timestamp & MAC-48",
|
|
2: "DCE Security version",
|
|
3: "Name SHA-1 hash",
|
|
4: "Randomly generated",
|
|
5: "Name MD5 hash",
|
|
}
|
|
VARIANT_NAME = {
|
|
0: "NCS",
|
|
2: "Leach-Salz",
|
|
# 5: Microsoft Corporation?
|
|
6: "Microsoft Corporation",
|
|
7: "Reserved Future",
|
|
}
|
|
|
|
def __init__(self, *args):
|
|
FieldSet.__init__(self, *args)
|
|
self.version = self.stream.readBits(
|
|
self.absolute_address + 32 + 16 + 12, 4, self.endian)
|
|
|
|
def createFields(self):
|
|
if self.version == 1:
|
|
yield TimestampUUID60(self, "time")
|
|
yield Enum(Bits(self, "version", 4), self.VERSION_NAME)
|
|
yield Enum(Bits(self, "variant", 3), self.VARIANT_NAME)
|
|
yield textHandler(Bits(self, "clock", 13), hexadecimal)
|
|
# yield textHandler(Bits(self, "clock", 16), hexadecimal)
|
|
if self.version == 1:
|
|
yield MAC48_Address(self, "mac", "IEEE 802 MAC address")
|
|
else:
|
|
yield Bytes(self, "node", 6)
|
|
else:
|
|
namea, nameb = self.FIELD_NAMES.get(
|
|
self.version, ("data_a", "data_b"))
|
|
yield textHandler(Bits(self, namea, 60), hexadecimal)
|
|
yield Enum(Bits(self, "version", 4), self.VERSION_NAME)
|
|
yield Enum(Bits(self, "variant", 3), self.VARIANT_NAME)
|
|
yield textHandler(Bits(self, nameb, 61), hexadecimal)
|
|
|
|
def createValue(self):
|
|
addr = self.absolute_address
|
|
a = self.stream.readBits(addr, 32, self.endian)
|
|
b = self.stream.readBits(addr + 32, 16, self.endian)
|
|
c = self.stream.readBits(addr + 48, 16, self.endian)
|
|
d = self.stream.readBytes(addr + 64, 2)
|
|
e = self.stream.readBytes(addr + 80, 6)
|
|
return "%08X-%04X-%04X-%s-%s" % (a, b, c, str2hex(d), str2hex(e))
|
|
|
|
def createDisplay(self):
|
|
value = self.value
|
|
if value == self.NULL:
|
|
name = "Null GUID: "
|
|
else:
|
|
name = "GUID v%u (%s): " % (self.version, self["version"].display)
|
|
return name + value
|
|
|
|
def createRawDisplay(self):
|
|
value = self.stream.readBytes(self.absolute_address, 16)
|
|
return str2hex(value, format=r"\x%02x")
|
|
|
|
|
|
class BitmapInfoHeader(FieldSet):
|
|
""" Win32 BITMAPINFOHEADER structure from GDI """
|
|
static_size = 40 * 8
|
|
|
|
COMPRESSION_NAME = {
|
|
0: u"Uncompressed (RGB)",
|
|
1: u"RLE (8 bits)",
|
|
2: u"RLE (4 bits)",
|
|
3: u"Bitfields",
|
|
4: u"JPEG",
|
|
5: u"PNG"
|
|
}
|
|
|
|
def __init__(self, parent, name, use_fourcc=False):
|
|
FieldSet.__init__(self, parent, name)
|
|
self._use_fourcc = use_fourcc
|
|
|
|
def createFields(self):
|
|
yield UInt32(self, "hdr_size", "Header size (in bytes) (=40)")
|
|
yield UInt32(self, "width", "Width")
|
|
yield UInt32(self, "height", "Height")
|
|
yield UInt16(self, "nb_planes", "Color planes")
|
|
yield UInt16(self, "bpp", "Bits/pixel")
|
|
if self._use_fourcc:
|
|
yield Enum(String(self, "codec", 4, charset="ASCII"), video_fourcc_name)
|
|
else:
|
|
yield Enum(UInt32(self, "codec", "Compression"), self.COMPRESSION_NAME)
|
|
yield UInt32(self, "size", "Image size (in bytes)")
|
|
yield UInt32(self, "xres", "X pixels per meter")
|
|
yield UInt32(self, "yres", "Y pixels per meter")
|
|
yield UInt32(self, "color_used", "Number of used colors")
|
|
yield UInt32(self, "color_important", "Number of important colors")
|
|
|
|
def createDescription(self):
|
|
return "Bitmap info header: %ux%u pixels, %u bits/pixel" % \
|
|
(self["width"].value, self["height"].value, self["bpp"].value)
|