Select Git revision
libjpeg.php 13.54 KiB
<?php
function get_jpeg_header_data( &$buff, $buff_len, $want=null ) {
$data = buffer_read( $buff, $buff_len, 2, true ); // Read the first two characters
// Check that the first two characters are 0xFF 0xDA (SOI - Start of image)
if ( $data != "\xFF\xD8" ) {
// No SOI (FF D8) at start of file - This probably isn't a JPEG file - close file and return;
return false;
}
$data = buffer_read( $buff, $buff_len, 2 ); // Read the third character
// Check that the third character is 0xFF (Start of first segment header)
if ( $data{0} != "\xFF" ) {
// NO FF found - close file and return - JPEG is probably corrupted
return false;
}
// Cycle through the file until, one of:
// 1) an EOI (End of image) marker is hit,
// 2) we have hit the compressed image data (no more headers are allowed after data)
// 3) or end of file is hit
$headerdata = array();
$hit_compressed_image_data = FALSE;
while ( ( $data{1} != "\xD9" ) && ( !$hit_compressed_image_data) && ( $data != '' ) ) {
// Found a segment to look at.
// Check that the segment marker is not a Restart marker - restart markers don't have size or data after them
if ( ( ord($data{1}) < 0xD0 ) || ( ord($data{1}) > 0xD7 ) ) {
// Segment isn't a Restart marker
$sizestr = buffer_read( $buff, $buff_len, 2 ); // Read the next two bytes (size)
if ( null === $sizestr )
break;
$decodedsize = unpack ("nsize", $sizestr); // convert the size bytes to an integer
// Read the segment data with length indicated by the previously read size
$segdata = buffer_read( $buff, $buff_len, $decodedsize['size'] - 2 );
// Store the segment information in the output array
if ( !$want || $want == ord($data{1}) ) {
$headerdata[] = (object)array(
"SegType" => ord($data{1}),
"SegName" => $GLOBALS[ "JPEG_Segment_Names" ][ ord($data{1}) ],
"SegDesc" => $GLOBALS[ "JPEG_Segment_Descriptions" ][ ord($data{1}) ],
"SegData" => $segdata
);
}
}
// If this is a SOS (Start Of Scan) segment, then there is no more header data - the compressed image data follows
if ( $data{1} == "\xDA" ) {
$hit_compressed_image_data = true;
} else {
// Not an SOS - Read the next two bytes - should be the segment marker for the next segment
$data = buffer_read( $buff, $buff_len, 2 );
// Check that the first byte of the two is 0xFF as it should be for a marker
if ( $data{0} != "\xFF" ) {
// NO FF found - close file and return - JPEG is probably corrupted
return false;
}
}
}
return $headerdata;
}
function buffer_read( &$buff, $buff_len, $len, $new=false ) {
static $pointer = 0;
if ( $new )
$pointer = 0;
if ( $pointer + $len > $buff_len ) {
$len = $buff_len - $pointer;
if ( $len < 1 )
return null;
}
// substr() is slower and doubles the peak memory usage
$data = '';