Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #!/usr/bin/perl
  2. #
  3. # Disassemble a GIF file and display the sections and chunks within.
  4. #
  5. # Warning: only part of the specification is implemented.
  6. #
  7.  
  8. use strict;
  9. use warnings;
  10.  
  11. die "Usage: $0 IMAGE\n" unless @ARGV == 1;
  12. my ($image) = @ARGV;
  13.  
  14. open IMAGE, '<', $image or die "$0: open $image: $!\n";
  15. undef $/;
  16. my $gif = <IMAGE>;
  17. close IMAGE;
  18.  
  19. print "$image: ", length $gif, " bytes\n\n";
  20.  
  21. my @gif = unpack 'C*', $gif;
  22. my $z = 0;
  23.  
  24. output_chunk('Header', 6);
  25. output_chunk('Logical Screen Descriptor', 7);
  26.  
  27. my $global_colors = $gif[10] & 0x80;
  28. my $color_table_size = 2 << ($gif[10] & 0x07);
  29.  
  30. if ($global_colors) {
  31.         output_chunk('Global Color Table', $color_table_size * 3);
  32. }
  33.  
  34. while (1) {
  35.         while ($gif[$z] == 0x21) {
  36.                 if ($gif[$z + 1] == 0xf9) {
  37.                         output_chunk('Graphic Control Extension', 5 + 2);
  38.                 } elsif ($gif[$z + 1] == 0xfe) {
  39.                         output_chunk('Comment Extension', 2);
  40.                 } elsif ($gif[$z + 1] == 0x01) {
  41.                         output_chunk('Plain Text Extension', 13 + 2);
  42.                 } elsif ($gif[$z + 1] == 0xff) {
  43.                         output_chunk('Application Extension', 12 + 2);
  44.                 } else {
  45.                         output_chunk((sprintf 'Unknown Extension 0x%.2x',
  46.                                         $gif[$z + 1]), $gif[$z + 2] + 3);
  47.                 }
  48.                
  49.                 while ($gif[$z] != 0) {
  50.                         output_chunk('Data Sub-block', $gif[$z] + 1);
  51.                 }
  52.                 output_chunk('Block Terminator', 1);
  53.         }
  54.        
  55.         if ($gif[$z] == 0x3b) {
  56.                 output_chunk('Trailer', 1);
  57.                 last;
  58.         }
  59.        
  60.         if ($gif[$z] != 0x2c) {
  61.                 last;
  62.         }
  63.        
  64.         output_chunk('Image Descriptor', 10);
  65.        
  66.         output_chunk('Table Based Image Data', 1);
  67.  
  68.         while ($gif[$z] != 0) {
  69.                 output_chunk('Data Sub-block', $gif[$z] + 1);
  70.         }
  71.         output_chunk('Block Terminator', 1);
  72. }
  73.  
  74. if ($z != @gif) {
  75.         output_chunk('*** Junk on End ***', @gif - $z);
  76. }
  77.  
  78.  
  79. #
  80. # Output a chunk of data as hex and characters.
  81. #
  82. sub output_chunk
  83. {
  84.         my ($description, $length) = @_;
  85.  
  86.         print "$description";
  87.         for (my $i = 0; $i != $length; $i++) {
  88.                 if ($i % 8 == 0) {
  89.                         print "\n";
  90.                         printf "%8i:  ", $z + $i;
  91.                 }
  92.                 if ($z + $i == @gif) {
  93.                         print "EOF\n\n";
  94.                         print "Unexpected end of file\n";
  95.                         exit;
  96.                 }
  97.                 my $c = $gif[$z + $i];
  98.                 printf "%.2x ", $c;
  99.                 if (32 <= $c and $c <= 126) {
  100.                         printf "'%c'", $c;
  101.                 } else {
  102.                         print "   ";
  103.                 }
  104.                 print "   ";
  105.         }
  106.         print "\n\n";
  107.        
  108.         $z += $length;
  109. }
  110.