Eamorr
Eamorr

Reputation: 10012

Convert hex stream to GIF

How do I create a .gif file from the following HEX stream:

0d 0a 0d 0a 47 49 46 38 39 61 01 00 01 00 80 ff 00 ff ff ff 00 00 00 2c 00 00 00 00 01 00 01 00 00 02 02 44 01 00 3b

3b is the GIF file terminator

I'm trying to do it following the guide at http://en.wikipedia.org/wiki/Graphics_Interchange_Format#Example_GIF_file

I'd like to implement this in either Perl or C/C++. Any language will do though.

Many thanks in advance,


Thanks guys for all the replies. I removed the leading '0d 0a 0d 0a'...

Here's what I have sofar:

#!/usr/bin/perl
use strict;
use warnings;

open(IN,"<test.txt");
open(OUT,">test.gif");

my @lines=<IN>;

foreach my $line (@lines){
        $line=~s/\n//g;
        my @bytes=split(/ /,$line);
        foreach my $byte (@bytes){
                print OUT $byte;
        }
}
close(OUT);
close(IN);

Upvotes: 3

Views: 3842

Answers (4)

nibot
nibot

Reputation: 14928

You can do it in the shell, using GNU echo:

$ /bin/echo -n -e "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\xff\x00\xff\xff\xff\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3b" > foo.gif

$ identify foo.gif
foo.gif GIF 1x1 1x1+0+0 8-bit PseudoClass 2c 36B 0.000u 0:00.000

You can also use the xxd command which will "make a hexdump or do the reverse". Annoyingly, however, it seems very picky about the input format. Here's an example using xxd:

$ cat > mygif.hex <<END
0000000: 4749 4638 3961 0100 0100 80ff 00ff ffff
0000010: 0000 002c 0000 0000 0100 0100 0002 0244
0000020: 0100 3b0a
END

$ xxd -r < mygif.hex > mygif.gif

gvim has an interface to xxd. Use the "Tools → Convert To Hex" menu option (keyboard: :%!xxd) and then "Tools → Convert Back" (:%!xxd -r).

EMACS also has a built-in hex editor, which is accessed by M-x hexl-mode (see Editing Binary Files in the manual). It's also a little bit annoying, because you have to type C-M-x (i.e. Ctrl-Meta-X) before entering a character by its hex code:

EMACS hexl-mode

Of course, it is very easy to write a simple C program to do the conversion:

#include <stdio.h>

int main(int argc, char **argv) {
  unsigned int c;
  while (1 == scanf("%x", &c))
    putchar(c);
  return 0;
}

usage:

$ gcc -Wall unhexify.c -o unhexify
$ echo  "47 49 46 38 39 61 01 00 01 00 80 ff 
         00 ff ff ff 00 00 00 2c 00 00 00 00 
         01 00 01 00 00 02 02 44 01 00 3b" | ./unhexify > mygif.gif

Also: many answers here in this code golf question.

Upvotes: 8

ikegami
ikegami

Reputation: 386361

perl -ne'
   BEGIN { binmode STDOUT }
   s/\s//g;
   print pack "H*", $_;
' file.hex > file.gif

Perl 5.14:

perl -ne'
   BEGIN { binmode STDOUT }
   print pack "H*", s/\s//gr;
' file.hex > file.gif

(-n and print can be replaced with -p and $_ = if you want to golf (shorten the length of the program.)

Upvotes: 3

Jonathan Leffler
Jonathan Leffler

Reputation: 754490

  • Open a new file for writing (in binary mode) with the .gif extension.
  • Read each pair of hex characters.
  • Convert the hex to a byte (char) value.
  • Write the byte to the opened file.
  • When finished, close the file.

If the hex data represents a GIF image, the file should contain it.

Upvotes: 5

Chas. Owens
Chas. Owens

Reputation: 64919

You may want to read the documentation for unpack (or hex) and pack. You may also find the perlio documentation useful for creating a raw file handle (so perl doesn't try to help you with things like encodings or line endings).

Upvotes: 2

Related Questions