#!/usr/bin/env python

import argparse
import struct

magic = 0xed26ff3a
chunk_type_raw = 0xcac1
chunk_type_dont_care = 0xcac3

version = 1
blk_sz = 0
total_chunks = 0

parser = argparse.ArgumentParser()
parser.add_argument("input", help="input ext4sp img")
parser.add_argument("output", help="generate ext4 img")
args = parser.parse_args()

def sparse_header(header):
    global blk_sz, total_chunks
    tuple = struct.unpack('IHHHHIIII', header)
    if tuple[0] == magic and tuple[1] == version:
        blk_sz = tuple[5]
        total_chunks = tuple[7]
        return True
    else:
        return False

def sparse_chunks(header):
    tuple = struct.unpack('HHII', header)
    chunk_len = tuple[2] * blk_sz
    if chunk_type_raw == tuple[0]:
        if tuple[3] == chunk_len + 12:
            output_fd.write(input_fd.read(chunk_len))
    elif chunk_type_dont_care == tuple[0]:
        if tuple[3] == 12:
            output_fd.write('\0' * chunk_len)

with open(args.input, "rb") as input_fd:
    if sparse_header(input_fd.read(28)):
        with open(args.output, "wb") as output_fd:
            n = 0
            while n < total_chunks:
                sparse_chunks(input_fd.read(12))
                n += 1
    else:
        print "Format Unknown"
