How to make sparse image file from original firmware?
concatenate files with dd seek=$offset from xml and then sparse with img2simg
rawprogram0.xml contains
- partition name:    filename=&quot;system.img&quot;
- partition size:    num_partition_sectors=&quot;8388608&quot;
- partition offset:  start_sector=&quot;1312768&quot;

rawprogram_unsparse.xml contains system_1.img - system_53.img
- file name:         filename=&quot;system_1.img&quot;
- file size:         num_partition_sectors=&quot;262160&quot;
- file offset:       start_sector=&quot;1312768&quot;

Note: we don't want the offset so we will subtract from start_sector
1312768 - 1312768 = 0
- file name:         filename=&quot;system_1.img&quot;
- file size:         num_partition_sectors=&quot;262160&quot;
- file offset:       start_sector=&quot;0&quot;

1576968 - 1312768 = 264200
- file name:         filename=&quot;system_2.img&quot;
- file size:         num_partition_sectors=&quot;16&quot;
- file offset:       start_sector=&quot;264200&quot;

1581024 - 1312768 = 268256
- file name:         filename=&quot;system_3.img&quot;
- file size:         num_partition_sectors=&quot;256048&quot;
- file offset:       start_sector=&quot;268256&quot;

Now use the dd seek parameter to paste junks into proper offsets
(sparse is filled with zeros)
bs=$SECTOR_SIZE_IN_BYTES
seek=$start_sector
count=$num_partition_sectors
dd if=system_1.img count=262160 seek=0       bs=512 of=system_ext4.img
dd if=system_2.img count=16     seek=264200  bs=512 of=system_ext4.img
dd if=system_3.img count=256048 seek=268256  bs=512 of=system_ext4.img
...
dd if=/dev/zero    count=0      seek=8388608 bs=512 of=system_ext4.img

the result is mountable ext4 partition image
mkdir system
sudo mount -t ext4 -o loop system_ext4.img system
ls system

finally this file can be sparsed with img2simg
sudo apt install -y f2fs-tools android-tools-fsutils android-sdk-platform-tools-common
img2simg system_ext4.img system.img


GNU bash script with sed
#/bin/bash

shopt -s extglob

bs=512
label=system
input=rawprogram0.xml
output=rawprogram_unsparse.xml

source &lt;(sed -nr &quot;s,.*\s(filename=.${label}\.img.)\s.*\s(num_partition_sectors=.[0-9]+.)\s.*\s(start_sector=.[0-9]+.).*,\1; \2; \3;,p&quot; &quot;$input&quot; | head -n1)

out=$filename
off=${start_sector:-0}
end=${num_partition_sectors:-0}

printf '%s\n' &quot;${label}&quot;_+([0-9]).img | cut -d. -f1 | sort -t_ -k2n | xargs -n1 -I_ echo _.img | \
while read -r file
  do
    source &lt;(sed -nr &quot;s,.*\s(filename=.${file}.)\s.*\s(num_partition_sectors=.[0-9]+.)\s.*\s(start_sector=.[0-9]+.).*,\1; \2; \3;,p&quot; &quot;$output&quot; | head -n1)
    dd if=&quot;$filename&quot; of=&quot;$out&quot; bs=${bs:-512} count=${num_partition_sectors:-0} seek=$((start_sector-off)) status=none || exit 1
    echo &quot;filename=$filename num_partition_sectors=$num_partition_sectors start_sector=$((start_sector-off))&quot;
done

dd if=/dev/zero of=&quot;$out&quot; bs=${bs:-512} count=0 seek=$end status=none || exit 1
echo &quot;filename=$out num_partition_sectors=$end start_sector=$off&quot;

file &quot;$out&quot;
e2fsck -n &quot;$out&quot; | grep clean || exit 1
mv &quot;$out&quot; &quot;${out%.*}.raw&quot;
img2simg &quot;${out%.*}.raw&quot; &quot;$out&quot; || exit 1
file &quot;$out&quot;
echo &quot;Done.&quot;

exit 0