Conversion of 24bit binary to int
pmaupin at speakeasy.net
Thu Nov 13 05:26:38 CET 2003
> Thanks for the example!
> The format is binary with no formating characters to indicate start/end of
> each block (fixed size).
> A file is about 6MB (and about 300 of them again...), so
> Ch1: 1536B (512*3B) - the 3B are big endian (int)
> Ch6: 1536B (512*3B)
> And then it is repeated till the end (say Y sets of Ch1 (the same for
> Ch1,Y: 1536B (512*3B)
> Ch6,Y: 1536B (512*3B)
> And idealy I would like to convert it to this format:
> Ch1: Y*512*4B (normal int with little endian)
> And that is the end :)
OK, now that I have a beer and a specification, here is some code
which (I think) should do what (I think) you are asking for.
On my Athlon 2200+ (marketing number) computer, with the source
file cached by the OS, it operates at around 10 source megabytes/second.
(That should be about 3 minutes plus actual file I/O operations
for the 300 6MB files you describe.)
Verifying that it actually produces the data you expect is up to you :)
def mungeio(srcfile,dstfile, numchannels=6, blocksize=512):
This function converts 24 bit RGB into 32 bit BGR0,
and simultaneously de-interleaves video from multiple
sources. The parameters are:
srcfile -- an file object opened with 'rb'
(or similar object)
dstfile -- a file object opened with 'wb'
(or similar object)
numchannels -- the number of interleaved video channels
blocksize -- the number of pixels per channel on
each interleaved block (interleave factor)
This function reads all the data from srcfile and writes
it to dstfile. It is up to the caller to close both files.
The function asserts that the amount of data to be read
from the source file is an integral multiple of
This function assumes that multiple copies of the data
will easily fit into RAM, as the target file size is
6MB for the source files and 8MB for the destination
files. If this is not a good assumption, it should
be rearchitected to output to one file per channel,
and then stitch the output files together at the end.
srcblocksize = blocksize * 3
dstblocksize = blocksize * 4
This function accepts a string representing a single
source block, and returns a string representing a
single destination block.
srcarray = array.array('B',src)
for i in range(3):
dstarray[2-i::4] = srcarray[i::3]
channellist = [ for i in range(numchannels)]
for channel in channellist:
data = srcfile.read(srcblocksize)
if len(data) != srcblocksize:
continue # (with while statement)
break # Propagate break from 'for' out of 'while'
# Check that input file length is valid (no leftovers),
# and then write the result.
assert channel is channellist and not len(data)
Actual I/O done in a separate function so it can
be more easily unit-tested.
srcfile = open(srcname,'rb')
dstfile = open(dstname,'wb')
More information about the Python-list