binary file creation clarification

Discussion in 'Perl Misc' started by IJALAB, Jun 3, 2014.

  1. IJALAB

    IJALAB Guest

    Hi All,

    I have a file in the following format in txt file
    ff68 adde ed5b 9ddc fe3d 7ad8 cf1c 2f39 c81c fbde be2a fcdf b9d9 e838 6a6c 0d4e 493e 9d2a 5f3c cc89 490c 29c9 efad 3d7e fc1b fb2b 3cae 7e0b 9c2f 3d6a 9df9 598e 5cfb daaa 2deb 79bd 1d99 8da8 98ab bfda b87d 194e ce2b a9db a899 cd6a 5af8 793c 5e1c af9e cf3c 9c9e c8bc fa9d ed9b 0bde aff8 7bcd 9fde 1abe 4b8b 5959 4839 2b9e 0d69 1b29 3d7d 0e9f ccba 2e8b f94a cbed fe3e 5dbe ad1a eda9 ce1d cf7a 3fca bc8e ff08 cbda 69bf cd1d

    This is basically a jpeg file content and i need to make this file to .bin file so that i want to check if the jpeg is opening fine.

    Can someone help on how this can be done. I am trying with the following code but since i have not used pack till now, i am not sure of my mistake. thanks for the help.

    #!/usr/bin/perl

    $buffer = "";
    $infile = "Jpeg_hex.txt";
    $outfile = "binary.bin";
    open (INFILE, "<", $infile) or die "Not able to open the file. \n";
    open (my $outfile, ">:raw", "binary.bin") or die "Not able to open the filefor writing. \n";
    binmode (OUTFILE);


    local $/ = \1;
    while ( my $byte = <INFILE> ) {
    print $outfile pack('s<', $byte) ;
    }



    close (INFILE) or die "Not able to close the file: $infile \n";
    close ($outfile) or die "Not able to close the file: $outfile \n";



    regards
    bala
     
    IJALAB, Jun 3, 2014
    #1
    1. Advertisements

  2. Assuming that the byte order should be identical to the one in the text
    file (ie, ff68 should end up as 0xff, 0x68 and not 0x68, 0xff), the
    following loop works:

    my $data;
    while ($data = <INFILE>) {
    for ($data) {
    /\G([0-9a-f]{4})/gc && do {
    print $outfile (pack('H4', $1));
    redo;
    };

    /\G\s+/gc and redo;

    /\G$/ and last;

    die("Huh?\n");
    }
    }

    Something like

    print $outfile (pack('v', hex($1)));

    could be used to convert the input 'numerically', ie, interpret ff68 as
    0xff68 and write that in little-endian byte-order (bytes 0x68, 0xff).

    NB: The inner for-loop shows an example of a lexical analyzer written in
    Perl. /\G([0-9a-f]{4})/gc tries to match a 4-digit hex number at the
    current match position. In case of success, it in converts than and
    re-executed the loop. Should it fail, the /\G\s+/gc tries to match a
    sequence of whitespace characters at the current match position. In case
    of success, the loop is executed. Lastly /\G$/ looks for the end of the
    string. If found, the inner loop is terminated. When none of the regexes
    matched, the die is executed because the code doesn't know what to do
    with the input. The \G anchors a regex match to the point where the last
    regex match 'stopped matching', /g means 'find everything', ie, "don't
    reset the match position to zero" and the /c "also, don't reset it in
    case the match failed".
     
    Rainer Weikusat, Jun 3, 2014
    #2
    1. Advertisements

  3. IJALAB

    IJALAB Guest

    Hi Rainer
    Your code worked perfect for my purpose. thanks a ton and thanks for the explanation of the syntax as well

    regards
     
    IJALAB, Jun 3, 2014
    #3
  4. Assuming that input files don't contain errors, that debugging the code
    is not intended and that having multiple copies of the data in memory is
    no problem, this can also be written as

    perl -e 'print pack "(H4)*", map { split " " } <>'

    The input data can either be read from STDIN or from a file (or sequence
    of files) passed as arguments, output will be written to STDOUT.
     
    Rainer Weikusat, Jun 4, 2014
    #4
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.