UnpackImage.py 2.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
# NOTE: This script is test under Python 3.x

__copyright__ = "Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved"

import sys
import crcmod


class UnpackImage:

W
Wayne Lin 已提交
11
    def __init__(self, pack_file_name, nocrc):
12 13 14 15 16 17 18 19 20 21 22 23
        self.img_list = []
        try:
            with open(pack_file_name, "rb") as pack_file:
                self.pack_data = pack_file.read()
        except (IOError, OSError) as err:
            print(f"Open {pack_file_name} failed")
            sys.exit(err)

        if self.pack_data[0:4] != b'\x20\x54\x56\x4e':
            print(f"{pack_file_name} marker check failed")
            sys.exit(0)

W
Wayne Lin 已提交
24 25 26 27 28 29 30 31
        print("Waiting for unpack Images ...")
        if nocrc == 0:
            print("check pack file crc32 ...")
            crc32_func = crcmod.predefined.mkCrcFun('crc-32')
            checksum = crc32_func(self.pack_data[8:])
            if checksum != int.from_bytes(self.pack_data[4:8], byteorder='little'):
                print(f"{pack_file_name} CRC check failed")
                sys.exit(0)
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
        self.image_cnt = int.from_bytes(self.pack_data[8:12], byteorder='little')
        # 1st image descriptor begins @ 0x10
        index = 0x10
        for _ in range(self.image_cnt):
            # Put the image length, offset ,attribute in list
            self.img_list.append([int.from_bytes(self.pack_data[index: index + 8], byteorder='little'),
                                  int.from_bytes(self.pack_data[index + 8: index + 16], byteorder='little'),
                                  int.from_bytes(self.pack_data[index + 16: index + 20], byteorder='little'),
                                  index + 24])
            index += int.from_bytes(self.pack_data[index: index + 8], byteorder='little') + 24  # 24 is image header
            if index % 16 != 0:
                index += 16 - (index & 0xF)   # round to 16-byte align

    def img_count(self):
        return self.image_cnt

    def img_attr(self, index):
        if index < self.image_cnt:
            # No need to return the last entry, actual offset in image file.
            # And should return integers instead of list of integer here
            return self.img_list[index][0], self.img_list[index][1], self.img_list[index][2]
        else:
            print("Invalid image index")
            return 0, 0, 0

    def img_content(self, index, offset, size):
        if index >= self.image_cnt:
            print("Invalid image index")
            return ''
        if offset > self.img_list[index][0] or offset + size > self.img_list[index][0]:
            print("Invalid offset")
            return ''

        return self.pack_data[self.img_list[index][3] + offset: self.img_list[index][3] + offset + size]