Binary files, substrings and (un)packing.

L

Leandro Pardini

Hello there,

I'm trying to process a binary file and I really don't know how. The
story: gPhoto2 downloads the images from my camera just fine, but
small areas of 10x3 pixels are screwed up. I found exactly where the
problem happens and wrote a simple interpolation filter that works
like a charm... under DOS, using the old QuickBasic. I've used Perl
for a while, but never to handle binary data, so I'm at a loss; and I
really want to get this working under Linux, so I can stop switching
OSs every time I download photos from my camera.

Basically, I need to extract two substrings from a binary string,
average them and then reinsert them in the string. I gather I must use
unpack() with the substrings to return two integer arrays with the
byte values, create a third array with the averages and then use
pack() to convert them to binary again and then reinsert them into the
bigger string. Problem is, I have no clue how to do it.

I'll put an example and see if someone can help me do this: let's say
the input buffer is '000121888565000' (those are the ascii values
represented by numbers, not the actual numbers in ascii form). I want
to use unpack to get the substring '121' (location 4, 3 bytes long) in
an array {1,2,1} and the substring '565' (location 10, 3 bytes long)
in an array {5,6,5}, then average the two arrays to get a {3,4,3}
array, then use pack to reinsert them in the buffer so it contains
'000121343565000'. How on earth can I do that?

Thanks in advance,
Leandro.
 
J

Jim Gibson

Leandro said:
Hello there,

I'm trying to process a binary file and I really don't know how. The
story: gPhoto2 downloads the images from my camera just fine, but
small areas of 10x3 pixels are screwed up. I found exactly where the
problem happens and wrote a simple interpolation filter that works
like a charm... under DOS, using the old QuickBasic. I've used Perl
for a while, but never to handle binary data, so I'm at a loss; and I
really want to get this working under Linux, so I can stop switching
OSs every time I download photos from my camera.

Basically, I need to extract two substrings from a binary string,
average them and then reinsert them in the string. I gather I must use
unpack() with the substrings to return two integer arrays with the
byte values, create a third array with the averages and then use
pack() to convert them to binary again and then reinsert them into the
bigger string. Problem is, I have no clue how to do it.

I'll put an example and see if someone can help me do this: let's say
the input buffer is '000121888565000' (those are the ascii values
represented by numbers, not the actual numbers in ascii form). I want
to use unpack to get the substring '121' (location 4, 3 bytes long) in
an array {1,2,1} and the substring '565' (location 10, 3 bytes long)
in an array {5,6,5}, then average the two arrays to get a {3,4,3}
array, then use pack to reinsert them in the buffer so it contains
'000121343565000'. How on earth can I do that?

Thanks in advance,
Leandro.

I am not sure from your description what exactly is the input of your
data. You show 15 digits from 0 - 8, so I will assume that they are
4-bit integers packed into a 60-bit binary string. Here is a way to do
what you want (I first use pack to generate the 60-bit string, then use
unpack to get the 15 4-bit nybbles, do the averaging and replacing,
then use pack again to generate the 60-bit result:


#!/opt/perl/bin/perl

use strict;
use warnings;

# create binary value for testing
my $input = pack("h" x 15, split(//,'000121888565000'));

# unpack bytes in input
my @bytes = unpack("h" x 15, $input );
print "input: ", @bytes, "\n";

# average and replace
for my $i ( 0..2 ) {
$bytes[6+$i] = int(($bytes[3+$i] + $bytes[9+$i])/2);
}

# pack into binary string
my $output = pack("h" x 15, @bytes);

# unpack and print result
my @result = unpack("h" x 15, $output);
print "result: ", @result, "\n";

FYI: this newsgroup is defunct. Try comp.lang.perl.misc in the future
for better responses.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top