Skip to content

Instantly share code, notes, and snippets.

@sigman78
Last active December 19, 2015 18:09
Show Gist options
  • Save sigman78/5996917 to your computer and use it in GitHub Desktop.
Save sigman78/5996917 to your computer and use it in GitHub Desktop.
Convert L15 raw to 8 bit pgm image
#!/usr/bin/env python
"""l15decode.py: L15 image format decoder."""
import os, sys
from time import time
import array
NUMPY = False
try:
import numpy
NUMPY = True
except ImportError:
pass
SIGNATURE_LEN = 16
# l15 chunk identifiers
CHUNK_ID_HDR = 0
CHUNK_ID_1 = 1
CHUNK_ID_2 = 2
CHUNK_ID_3 = 3
CHUNK_ID_4 = 4
CHUNK_ID_5 = 5
CHUNK_ID_6 = 6
CHUNK_ID_RAW = 7
def copy_bytes(fin, fout, length, block_size = 64 * 1024):
out_bytes = 0
while length > 0:
to_read = min(length, block_size)
length -= to_read
b = fin.read(to_read)
written = len(b)
out_bytes += written
fout.write(b)
return out_bytes
def make_pbm(fname, width, height, colors):
f = open(fname, "wb")
f.write("P5\n")
f.write("%d\n%d\n%d\n" % (width, height, colors))
return f
def convert_line_16_to_8(aline, lcoef):
lin = array.array("H", aline)
lout = array.array("B")
for p in lin:
lout.append(int(p * lcoef))
# lout.fromlist(map(lambda x: int(x * lrecip), lin))
return lout
def convert_line_16_to_8_fast(aline, lcoef):
lin = numpy.fromstring(aline, dtype=numpy.uint16)
lout = (lin * lcoef).astype(numpy.uint8)
return lout
#def convert_line_16(aline,
def convert_img_chunk(fin, outname):
ts = time()
img_hdr = array.array("I")
img_hdr.fromfile(fin, 6)
img_lmax, img_unk2, img_chan, img_width, img_height, img_bits = tuple(img_hdr)
print "Image: %dx%dx%d" % (img_width, img_height, img_bits)
img_stride = img_width * (img_bits / 2)
lcoef = 255.0 / 0x400
cvt = convert_line_16_to_8_fast if NUMPY else convert_line_16_to_8
with make_pbm(outname, img_width, img_height, 255) as pbm:
#copy_bytes(fin, pbm, img_height * img_width * (img_bits / 8))
for ln in range(0, img_height):
in_bytes = fin.read(img_stride)
out_bytes = cvt(in_bytes, lcoef)
out_bytes.tofile(pbm)
if not ln % 10: print ln, "\r",
print time() - ts, "seconds."
def dump_chunk(fin, bytes, outfile):
with open(outfile, "wb") as fout:
copy_bytes(fin, fout, bytes)
def parse_l15(fname):
with open(fname, "rb") as f:
signature = f.read(SIGNATURE_LEN)
# a little magic due the first chunk size being an offset from the file head
chunk_ofs = -SIGNATURE_LEN
while True:
try:
mark = f.tell()
chunk_hdr = array.array("I")
chunk_hdr.fromfile(f, 2)
chunk_id, chunk_len = chunk_hdr[0], chunk_hdr[1]
print "Chunk %08x : %08x" % (chunk_id, chunk_len)
yield f, chunk_id, chunk_len
seek_to, chunk_ofs = mark + chunk_len + chunk_ofs, 0
f.seek(seek_to, os.SEEK_SET)
except EOFError:
break
def convert_l15(fname, outfile):
"""Read L15 and process chunk by chunk writting results to the outfile"""
for fin, chunk_id, chunk_len in parse_l15(fname):
if chunk_id == CHUNK_ID_RAW:
convert_img_chunk(fin, outfile + ".pbm")
else:
dump_chunk(fin, chunk_len, outfile + ".chunk." + str(chunk_id))
if __name__ == "__main__":
# substitue your input file
convert_l15("1520_1_270312160000_1.L15", "result")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment