UnpackImage.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. # NOTE: This script is test under Python 3.x
  2. __copyright__ = "Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved"
  3. import sys
  4. import crcmod
  5. class UnpackImage:
  6. def __init__(self, pack_file_name, nocrc):
  7. self.img_list = []
  8. try:
  9. with open(pack_file_name, "rb") as pack_file:
  10. self.pack_data = pack_file.read()
  11. except (IOError, OSError) as err:
  12. print(f"Open {pack_file_name} failed")
  13. sys.exit(err)
  14. if self.pack_data[0:4] != b'\x20\x54\x56\x4e':
  15. print(f"{pack_file_name} marker check failed")
  16. sys.exit(0)
  17. print("Waiting for unpack Images ...")
  18. if nocrc == 0:
  19. print("check pack file crc32 ...")
  20. crc32_func = crcmod.predefined.mkCrcFun('crc-32')
  21. checksum = crc32_func(self.pack_data[8:])
  22. if checksum != int.from_bytes(self.pack_data[4:8], byteorder='little'):
  23. print(f"{pack_file_name} CRC check failed")
  24. sys.exit(0)
  25. self.image_cnt = int.from_bytes(self.pack_data[8:12], byteorder='little')
  26. # 1st image descriptor begins @ 0x10
  27. index = 0x10
  28. for _ in range(self.image_cnt):
  29. # Put the image length, offset ,attribute in list
  30. self.img_list.append([int.from_bytes(self.pack_data[index: index + 8], byteorder='little'),
  31. int.from_bytes(self.pack_data[index + 8: index + 16], byteorder='little'),
  32. int.from_bytes(self.pack_data[index + 16: index + 20], byteorder='little'),
  33. index + 24])
  34. index += int.from_bytes(self.pack_data[index: index + 8], byteorder='little') + 24 # 24 is image header
  35. if index % 16 != 0:
  36. index += 16 - (index & 0xF) # round to 16-byte align
  37. def img_count(self):
  38. return self.image_cnt
  39. def img_attr(self, index):
  40. if index < self.image_cnt:
  41. # No need to return the last entry, actual offset in image file.
  42. # And should return integers instead of list of integer here
  43. return self.img_list[index][0], self.img_list[index][1], self.img_list[index][2]
  44. else:
  45. print("Invalid image index")
  46. return 0, 0, 0
  47. def img_content(self, index, offset, size):
  48. if index >= self.image_cnt:
  49. print("Invalid image index")
  50. return ''
  51. if offset > self.img_list[index][0] or offset + size > self.img_list[index][0]:
  52. print("Invalid offset")
  53. return ''
  54. return self.pack_data[self.img_list[index][3] + offset: self.img_list[index][3] + offset + size]