Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # SPDX-License-Identifier: MIT
- import argparse
- import os
- import platform
- import struct
- ISP_DIRNAME = "isp"
- ISP_INSTALL_PREFIX = "/lib/firmware/"
- ISP_SETFILE_COUNT = 48
- ISP_SETFILE_ALIGNMENT = 0x1000
- ISP_SETFILES = [
- [0x248, 0x18200103, "1820_01XX.dat", 0x442c],
- [0x248, 0x18220201, "1822_02XX.dat", 0x442c],
- [0x343, 0x52210211, "5221_02XX.dat", 0x4870],
- [0x354, 0x92510208, "9251_02XX.dat", 0xa5ec],
- [0x356, 0x48200107, "4820_01XX.dat", 0x9324],
- [0x356, 0x48200206, "4820_02XX.dat", 0x9324],
- [0x364, 0x87200103, "8720_01XX.dat", 0x36ac],
- [0x364, 0x87230101, "8723_01XX.dat", 0x361c],
- [0x372, 0x38200108, "3820_01XX.dat", 0xfdb0],
- [0x372, 0x38200205, "3820_02XX.dat", 0xfdb0],
- [0x372, 0x38201104, "3820_11XX.dat", 0xfdb0],
- [0x372, 0x38201204, "3820_12XX.dat", 0xfdb0],
- [0x405, 0x97200102, "9720_01XX.dat", 0x92c8],
- [0x405, 0x97210102, "9721_01XX.dat", 0x9818],
- [0x405, 0x97230101, "9723_01XX.dat", 0x92c8],
- [0x414, 0x25200102, "2520_01XX.dat", 0xa444],
- [0x503, 0x78200109, "7820_01XX.dat", 0xb268],
- [0x503, 0x78200206, "7820_02XX.dat", 0xb268],
- [0x505, 0x39210102, "3921_01XX.dat", 0x89b0],
- [0x514, 0x28200108, "2820_01XX.dat", 0xa198],
- [0x514, 0x28200205, "2820_02XX.dat", 0xa198],
- [0x514, 0x28200305, "2820_03XX.dat", 0xa198],
- [0x514, 0x28200405, "2820_04XX.dat", 0xa198],
- [0x558, 0x19210106, "1921_01XX.dat", 0xad40],
- [0x558, 0x19220201, "1922_02XX.dat", 0xad40],
- [0x603, 0x79200109, "7920_01XX.dat", 0xad2c],
- [0x603, 0x79200205, "7920_02XX.dat", 0xad2c],
- [0x603, 0x79210104, "7921_01XX.dat", 0xad90],
- [0x613, 0x49200108, "4920_01XX.dat", 0x9324],
- [0x613, 0x49200204, "4920_02XX.dat", 0x9324],
- [0x614, 0x29210107, "2921_01XX.dat", 0xed6c],
- [0x614, 0x29210202, "2921_02XX.dat", 0xed6c],
- [0x614, 0x29220201, "2922_02XX.dat", 0xed6c],
- [0x633, 0x36220111, "3622_01XX.dat", 0x100d4],
- [0x703, 0x77210106, "7721_01XX.dat", 0x936c],
- [0x703, 0x77220106, "7722_01XX.dat", 0xac20],
- [0x713, 0x47210107, "4721_01XX.dat", 0x936c],
- [0x713, 0x47220109, "4722_01XX.dat", 0x9218],
- [0x714, 0x20220107, "2022_01XX.dat", 0xa198],
- [0x772, 0x37210106, "3721_01XX.dat", 0xfdf8],
- [0x772, 0x37211106, "3721_11XX.dat", 0xfe14],
- [0x772, 0x37220104, "3722_01XX.dat", 0xfca4],
- [0x772, 0x37230106, "3723_01XX.dat", 0xfca4],
- [0x814, 0x21230101, "2123_01XX.dat", 0xed54],
- [0x853, 0x76220112, "7622_01XX.dat", 0x247f8],
- [0x913, 0x75230107, "7523_01XX.dat", 0x247f8],
- [0xd56, 0x62210102, "6221_01XX.dat", 0x1b80],
- [0xd56, 0x62220102, "6222_01XX.dat", 0x1b80],
- ]
- assert(len(ISP_SETFILES) == ISP_SETFILE_COUNT)
- def round_up(x, y): return ((x + (y - 1)) & (-y))
- def isp_setfile_header_check(hdr):
- return (
- (hdr[2] == 0x0) and
- (hdr[3] == 0x0) and
- (hdr[4] & 0xff000000 == hdr[4]) and (hdr[4]) and
- (hdr[5] & 0xffff0000 == hdr[5]) and (hdr[5]) and
- (hdr[6] == 0x0) and
- (hdr[7] == 0x3c00000)
- )
- def isp_extract(src_path):
- data = open(src_path, "rb").read()
- up = struct.unpack(">" + "L"*(len(data) // 4), data) # big endian indeed
- files = []
- found = 0
- for n in range(len(data) // ISP_SETFILE_ALIGNMENT):
- pos = (n * ISP_SETFILE_ALIGNMENT) // 4
- offset = pos * 4
- # search for magic constant at 4K boundary
- candidates = [cand for cand in ISP_SETFILES if cand[1] == up[pos]]
- if (len(candidates) == 0): continue
- for cand in candidates:
- sensor, magic, fname, size = cand
- size = round_up(size, 64) # align to be safe
- dat = data[offset:offset+size]
- header = struct.unpack(">" + "L"*8, dat[:8*4])
- if (not isp_setfile_header_check(header)): continue
- sensor_name = "%x_%s" % (sensor, fname.replace(".dat", "", 1))
- print("isp-extract: %02d/%02d: Found sensor %s data at offset 0x%x" % (found + 1, ISP_SETFILE_COUNT, sensor_name, offset))
- files.append((fname, dat))
- found += 1
- break
- if (found != ISP_SETFILE_COUNT):
- raise ValueError("isp-extract: Found %02d/%02d calibration files. Please report this bug" % (found, ISP_SETFILE_COUNT))
- print("isp-extract: Found all %02d/%02d sensor calibration files!" % (found, ISP_SETFILE_COUNT))
- return files
- if __name__ == '__main__':
- parser = argparse.ArgumentParser(prog="isp-extract", description='Extract ISP sensor calibration files')
- parser.add_argument('--input', help='path to appleh13camerad', default="appleh13camerad")
- parser.add_argument('--outdir', help='output directory prefix', default="/tmp/isp-extract")
- parser.add_argument('--install', help='install files (requires root)', action='store_true')
- args = parser.parse_args()
- files = isp_extract(args.input)
- if (args.install):
- if (platform.system() != "Linux"):
- raise RuntimeError("isp-extract: You can only install on linux")
- if (os.geteuid() != 0):
- raise RuntimeError("isp-extract: You must be root to install")
- outdir = os.path.join(ISP_INSTALL_PREFIX, ISP_DIRNAME)
- else:
- outdir = os.path.join(args.outdir, ISP_DIRNAME)
- os.makedirs(outdir, exist_ok=True)
- for fname, dat in files:
- open(os.path.join(outdir, fname), "wb").write(dat)
Advertisement
Add Comment
Please, Sign In to add comment