Binary files, substrings and (un)packing.

Discussion in 'Perl' started by Leandro Pardini, Oct 25, 2003.

  1. 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.

    --
    "A mind stretched by a new idea never goes back to its original
    dimensions."
    My Junk Box: http://LeandroTLZ.DeviantArt.com/?complangperl
     
    Leandro Pardini, Oct 25, 2003
    #1
    1. Advertising

  2. Leandro Pardini

    Jim Gibson Guest

    In article <>, Leandro
    Pardini <> wrote:

    > 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.
     
    Jim Gibson, Oct 27, 2003
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?iso-8859-1?q?Lars_Rune_N=F8stdal?=

    Bit-fields and packing/alignment

    =?iso-8859-1?q?Lars_Rune_N=F8stdal?=, Jul 26, 2004, in forum: C++
    Replies:
    3
    Views:
    4,480
    Jack Klein
    Jul 27, 2004
  2. Taylor Howell
    Replies:
    5
    Views:
    470
    Andrew Phillips
    Apr 20, 2005
  3. Timothy Hume
    Replies:
    2
    Views:
    505
    Brian Szmyd
    Sep 10, 2004
  4. Jim
    Replies:
    6
    Views:
    743
  5. Lucas L.
    Replies:
    12
    Views:
    200
    ara.t.howard
    Jun 16, 2008
Loading...

Share This Page