Guest User

isp-extract.py

a guest
Sep 10th, 2023
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.41 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # SPDX-License-Identifier: MIT
  3.  
  4. import argparse
  5. import os
  6. import platform
  7. import struct
  8.  
  9. ISP_DIRNAME = "isp"
  10. ISP_INSTALL_PREFIX = "/lib/firmware/"
  11.  
  12. ISP_SETFILE_COUNT = 48
  13. ISP_SETFILE_ALIGNMENT = 0x1000
  14.  
  15. ISP_SETFILES = [
  16. [0x248, 0x18200103, "1820_01XX.dat", 0x442c],
  17. [0x248, 0x18220201, "1822_02XX.dat", 0x442c],
  18. [0x343, 0x52210211, "5221_02XX.dat", 0x4870],
  19. [0x354, 0x92510208, "9251_02XX.dat", 0xa5ec],
  20. [0x356, 0x48200107, "4820_01XX.dat", 0x9324],
  21. [0x356, 0x48200206, "4820_02XX.dat", 0x9324],
  22. [0x364, 0x87200103, "8720_01XX.dat", 0x36ac],
  23. [0x364, 0x87230101, "8723_01XX.dat", 0x361c],
  24. [0x372, 0x38200108, "3820_01XX.dat", 0xfdb0],
  25. [0x372, 0x38200205, "3820_02XX.dat", 0xfdb0],
  26. [0x372, 0x38201104, "3820_11XX.dat", 0xfdb0],
  27. [0x372, 0x38201204, "3820_12XX.dat", 0xfdb0],
  28. [0x405, 0x97200102, "9720_01XX.dat", 0x92c8],
  29. [0x405, 0x97210102, "9721_01XX.dat", 0x9818],
  30. [0x405, 0x97230101, "9723_01XX.dat", 0x92c8],
  31. [0x414, 0x25200102, "2520_01XX.dat", 0xa444],
  32. [0x503, 0x78200109, "7820_01XX.dat", 0xb268],
  33. [0x503, 0x78200206, "7820_02XX.dat", 0xb268],
  34. [0x505, 0x39210102, "3921_01XX.dat", 0x89b0],
  35. [0x514, 0x28200108, "2820_01XX.dat", 0xa198],
  36. [0x514, 0x28200205, "2820_02XX.dat", 0xa198],
  37. [0x514, 0x28200305, "2820_03XX.dat", 0xa198],
  38. [0x514, 0x28200405, "2820_04XX.dat", 0xa198],
  39. [0x558, 0x19210106, "1921_01XX.dat", 0xad40],
  40. [0x558, 0x19220201, "1922_02XX.dat", 0xad40],
  41. [0x603, 0x79200109, "7920_01XX.dat", 0xad2c],
  42. [0x603, 0x79200205, "7920_02XX.dat", 0xad2c],
  43. [0x603, 0x79210104, "7921_01XX.dat", 0xad90],
  44. [0x613, 0x49200108, "4920_01XX.dat", 0x9324],
  45. [0x613, 0x49200204, "4920_02XX.dat", 0x9324],
  46. [0x614, 0x29210107, "2921_01XX.dat", 0xed6c],
  47. [0x614, 0x29210202, "2921_02XX.dat", 0xed6c],
  48. [0x614, 0x29220201, "2922_02XX.dat", 0xed6c],
  49. [0x633, 0x36220111, "3622_01XX.dat", 0x100d4],
  50. [0x703, 0x77210106, "7721_01XX.dat", 0x936c],
  51. [0x703, 0x77220106, "7722_01XX.dat", 0xac20],
  52. [0x713, 0x47210107, "4721_01XX.dat", 0x936c],
  53. [0x713, 0x47220109, "4722_01XX.dat", 0x9218],
  54. [0x714, 0x20220107, "2022_01XX.dat", 0xa198],
  55. [0x772, 0x37210106, "3721_01XX.dat", 0xfdf8],
  56. [0x772, 0x37211106, "3721_11XX.dat", 0xfe14],
  57. [0x772, 0x37220104, "3722_01XX.dat", 0xfca4],
  58. [0x772, 0x37230106, "3723_01XX.dat", 0xfca4],
  59. [0x814, 0x21230101, "2123_01XX.dat", 0xed54],
  60. [0x853, 0x76220112, "7622_01XX.dat", 0x247f8],
  61. [0x913, 0x75230107, "7523_01XX.dat", 0x247f8],
  62. [0xd56, 0x62210102, "6221_01XX.dat", 0x1b80],
  63. [0xd56, 0x62220102, "6222_01XX.dat", 0x1b80],
  64. ]
  65. assert(len(ISP_SETFILES) == ISP_SETFILE_COUNT)
  66.  
  67. def round_up(x, y): return ((x + (y - 1)) & (-y))
  68.  
  69. def isp_setfile_header_check(hdr):
  70. return (
  71. (hdr[2] == 0x0) and
  72. (hdr[3] == 0x0) and
  73. (hdr[4] & 0xff000000 == hdr[4]) and (hdr[4]) and
  74. (hdr[5] & 0xffff0000 == hdr[5]) and (hdr[5]) and
  75. (hdr[6] == 0x0) and
  76. (hdr[7] == 0x3c00000)
  77. )
  78.  
  79. def isp_extract(src_path):
  80. data = open(src_path, "rb").read()
  81. up = struct.unpack(">" + "L"*(len(data) // 4), data) # big endian indeed
  82.  
  83. files = []
  84. found = 0
  85. for n in range(len(data) // ISP_SETFILE_ALIGNMENT):
  86. pos = (n * ISP_SETFILE_ALIGNMENT) // 4
  87. offset = pos * 4
  88. # search for magic constant at 4K boundary
  89. candidates = [cand for cand in ISP_SETFILES if cand[1] == up[pos]]
  90. if (len(candidates) == 0): continue
  91. for cand in candidates:
  92. sensor, magic, fname, size = cand
  93. size = round_up(size, 64) # align to be safe
  94. dat = data[offset:offset+size]
  95.  
  96. header = struct.unpack(">" + "L"*8, dat[:8*4])
  97. if (not isp_setfile_header_check(header)): continue
  98.  
  99. sensor_name = "%x_%s" % (sensor, fname.replace(".dat", "", 1))
  100. print("isp-extract: %02d/%02d: Found sensor %s data at offset 0x%x" % (found + 1, ISP_SETFILE_COUNT, sensor_name, offset))
  101. files.append((fname, dat))
  102. found += 1
  103. break
  104.  
  105. if (found != ISP_SETFILE_COUNT):
  106. raise ValueError("isp-extract: Found %02d/%02d calibration files. Please report this bug" % (found, ISP_SETFILE_COUNT))
  107. print("isp-extract: Found all %02d/%02d sensor calibration files!" % (found, ISP_SETFILE_COUNT))
  108. return files
  109.  
  110.  
  111. if __name__ == '__main__':
  112. parser = argparse.ArgumentParser(prog="isp-extract", description='Extract ISP sensor calibration files')
  113. parser.add_argument('--input', help='path to appleh13camerad', default="appleh13camerad")
  114. parser.add_argument('--outdir', help='output directory prefix', default="/tmp/isp-extract")
  115. parser.add_argument('--install', help='install files (requires root)', action='store_true')
  116. args = parser.parse_args()
  117.  
  118. files = isp_extract(args.input)
  119.  
  120. if (args.install):
  121. if (platform.system() != "Linux"):
  122. raise RuntimeError("isp-extract: You can only install on linux")
  123. if (os.geteuid() != 0):
  124. raise RuntimeError("isp-extract: You must be root to install")
  125. outdir = os.path.join(ISP_INSTALL_PREFIX, ISP_DIRNAME)
  126. else:
  127. outdir = os.path.join(args.outdir, ISP_DIRNAME)
  128.  
  129. os.makedirs(outdir, exist_ok=True)
  130. for fname, dat in files:
  131. open(os.path.join(outdir, fname), "wb").write(dat)
  132.  
Advertisement
Add Comment
Please, Sign In to add comment