Skip to content
Snippets Groups Projects
Select Git revision
  • master
1 result

plugin.php

Blame
  • 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 = '';