<?php
  
/* (c) yoya@awm.jp */
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)',
    
0xFFFF => 'NONE',
    );

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);


$i = -1;
while (
strlen($marker1 $bs->getByte()) > 0) {
  
$i += 1;
  
$segment_data sprintf("%c"$marker1);
    if (
$marker1 != 0xFF) {
        
sprinf(STDERR"ERROR: Illegal Tag Marker(0x%02x??)\n",
               
$marker1);
    }
    
$marker2 $bs->getByte();
  
$segment_data .= sprintf("%c"$marker2);
    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);
  
$filename sprintf("segment_%04d.%s"$iget_marker_name($marker2));
  
file_put_contents($filename$segment_data);
        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);    
  
$filename sprintf("segment_%04d.%s"$iget_marker_name($marker2));
  
$bs2 = new BitStream();
  
$bs2->putBytesBE($length2);
  
file_put_contents($filename$segment_data $bs2->getData() .$data);
    if (
$marker2 == 0xDA) { // SOS
      
$segment_data '';
      
$i++;
$prev_marker2 0xFFFF;
            while (
strlen($marker1 $bs->getByte()) > 0) {
                if (
$marker1 != 0xFF) {
              
$segment_data .= sprintf("%c"$marker1);
                    continue;
                }
                
$marker2 $bs->getByte();
                if (
$marker2 == 0x00) {
              
$segment_data .= sprintf("%c"$marker1);
              
$segment_data .= sprintf("%c"$marker2);

                    continue;
                }


  
$filename sprintf("segment_%04d.%s"$iget_marker_name($prev_marker2));
  
file_put_contents($filename$segment_data);

        
$prev_marker2 $marker2;


                if ((
0xD0 <= $marker2) && ($marker2 <= 0xD7)) {
                    
printf("MARKER: %s(FF%02X)\n",
                           
get_marker_name($marker2),
                           
$marker2);
                    
$segment_data sprintf("%c%c"$marker1$marker2);
                } else {
                    
$pos $bs->getByteOffset();
                    
$bs->setByteOffset($pos 2);
              
$segment_data '';
                    break; 
// while loop break;
                
}
            }
        }
        break;
    }
}