commit 23808a3ba6bd656b3a825976f0227b277e38d474 Author: Nymiro Date: Mon Oct 20 11:44:49 2025 +1300 添加 .DS_Store 文件 diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..2aab8c4 Binary files /dev/null and b/.DS_Store differ diff --git a/__pycache__/parser.cpython-314.pyc b/__pycache__/parser.cpython-314.pyc new file mode 100644 index 0000000..b2ca2b0 Binary files /dev/null and b/__pycache__/parser.cpython-314.pyc differ diff --git a/apple.HEIC b/apple.HEIC new file mode 100644 index 0000000..747371d Binary files /dev/null and b/apple.HEIC differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..5d017c6 --- /dev/null +++ b/main.py @@ -0,0 +1,28 @@ +from parser import parse_boxes + +def main(): + # Test with the Apple HEIC file + print("--- Analyzing Apple HEIC file ---") + try: + with open('apple.heic', 'rb') as f: + top_level_boxes = parse_boxes(f) + for box in top_level_boxes: + print(box) + except FileNotFoundError: + print("Error: apple.heic not found.") + + print("\n" + "="*40 + "\n") + + # Test with the Samsung HEIC file + print("--- Analyzing Samsung HEIC file ---") + try: + with open('samsung.heic', 'rb') as f: + top_level_boxes = parse_boxes(f) + for box in top_level_boxes: + print(box) + except FileNotFoundError: + print("Error: samsung.heic not found.") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/parser.py b/parser.py new file mode 100644 index 0000000..f701a23 --- /dev/null +++ b/parser.py @@ -0,0 +1,78 @@ +import struct + +class Box: + """ + Represents a generic ISOBMFF box. + """ + def __init__(self, size: int, box_type: str, offset: int, raw_data: bytes): + self.size = size + self.type = box_type + self.offset = offset + self.raw_data = raw_data + self.children = [] # Will be populated for container boxes + + def __repr__(self) -> str: + # e.g., + return f"" + +# In parser.py + +from typing import List, BinaryIO + +def parse_boxes(stream: BinaryIO) -> List[Box]: + """ + Parses all top-level boxes from a file stream, handling special size cases. + """ + boxes = [] + + stream.seek(0, 2) + file_size = stream.tell() + stream.seek(0) + + while stream.tell() < file_size: + current_offset = stream.tell() + + # Read the standard 8-byte header + header = stream.read(8) + if len(header) < 8: + break + + size = struct.unpack('>I', header[:4])[0] + box_type = header[4:].decode('ascii') + + header_size = 8 + content_size = 0 + + # --- NEW: Handle special size cases --- + if size == 1: + # The actual size is a 64-bit integer following the type + largesize_header = stream.read(8) + if len(largesize_header) < 8: + break + size = struct.unpack('>Q', largesize_header)[0] + header_size = 16 + content_size = size - header_size + elif size == 0: + # The box extends to the end of the file + content_size = file_size - current_offset - header_size + size = content_size + header_size + else: + # Standard size + content_size = size - header_size + # --- End of new code --- + + # Read the box's content (raw_data) + # We need to rewind a bit if we read largesize header to get all content + stream.seek(current_offset + header_size) + raw_data = stream.read(content_size) + if len(raw_data) < content_size: + # Avoids errors on truncated files + break + + box = Box(size, box_type, current_offset, raw_data) + boxes.append(box) + + # Seek to the beginning of the next box + stream.seek(current_offset + size) + + return boxes \ No newline at end of file diff --git a/samsung.heic b/samsung.heic new file mode 100755 index 0000000..458a338 Binary files /dev/null and b/samsung.heic differ