<?php

require_once('BitStream.php');

$marker_name_table =
  array(
0xD8 => 'SOI(Start of Image)',
    
0xE0 => 'APP0'0xE1 => 'APP1'0xE2 => 'APP2'0xE3 => 'APP3',
    
0xE4 => 'APP4'0xE5 => 'APP5'0xE6 => 'APP6'0xE7 => 'APP7',
    
0xDB => 'DQT',
    
0xC0 => 'SOF0',    0xC1 => 'SOF1'0xC21 => 'SOF2',
    
0xC4 => 'DHT',
    
0xD0 => 'RST0',    0xD1 => 'RST1',    0xD2 => 'RST2',    0xD3 => 'RST3',
    
0xD4 => 'RST4',    0xD5 => 'RST5',    0xD6 => 'RST6',    0xD7 => 'RST7',
    
0xDA => 'SOS',
    
0xDD => 'DRI',
    
0xD9 => 'EOI(End Of Immage)',
    );

function 
get_marker_name($marker) {
    global 
$marker_name_table;
    if (isset(
$marker_name_table{$marker})) {
        return 
$marker_name_table{$marker};
    }
    return 
"Unknown";
}

list(
$program$file) = $argv;

if (! 
is_readable($file)) {
    
fprintf(STDERR"Cant' read file($file)\n");
    exit(
1);
}

$data file_get_contents($file);

$bs = new BitStream($data);


while (
strlen($marker1 $bs->getByte()) > 0) {
    if (
$marker1 != 0xFF) {
        
sprinf(STDERR"ERROR: Illegal Tag Marker(0x%02x??)\n",
               
$marker1);
    }
    
$marker2 $bs->getByte();
    switch(
$marker2) {
        case 
'0xD8'// SOI Start
        
case '0xD9'// EOI End
        
printf("0x%04x: %s(FF%02X)\n"$bs->getByteOffset() - 2,
               
get_marker_name($marker2), $marker2);
        break;
        case 
'0xD0': case '0xD1': case '0xD2': case '0xD3'// RST
        
case '0xD4': case '0xD5': case '0xD6': case '0xD7'// RST
        
sprinf(STDERR"ERROR: RST no SOS???\n");
        break;
        default:
        
$length $bs->getBytesBE(2);
        
$data $bs->getStrings($length 2);
        
        
printf("0x%04x: %s(FF%02X) length=(2+)%d\n"$bs->getByteOffset(),
               
get_marker_name($marker2), $marker2$length-2);
        if (
$marker2 == 0xDA) { // SOS
            
while (strlen($marker1 $bs->getByte()) > 0) {
                if (
$marker1 != 0xFF) {
                    continue;
                }
                
$marker2 $bs->getByte();
                if (
$marker2 == 0x00) {
                    continue;
                }
                if ((
0xD0 <= $marker2) && ($marker2 <= 0xD7)) {
                    
printf("MARKER: %s(FF%02X)\n",
                           
get_marker_name($marker2),
                           
$marker2);
                } else {
                    
$pos $bs->getByteOffset();
                    
$bs->setByteOffset($pos 2);
                    break; 
// while loop break;
                
}
            }
        }
        break;
    }
}