'SOF0', 0xC1 => 'SOF1', 0xC2 => 'SOF2', 0xC3 => 'SOF4', 0xC5 => 'SOF5', 0xC6 => 'SOF6', 0xC7 => 'SOF7', 0xC8 => 'JPG', 0xC9 => 'SOF9', 0xCA => 'SOF10', 0xCB => 'SOF11', 0xCD => 'SOF13', 0xCE => 'SOF14', 0xCF => 'SOF15', 0xC4 => 'DHT', 0xCC => 'DAC', 0xD0 => 'RST0', 0xD1 => 'RST1', 0xD2 => 'RST2', 0xD3 => 'RST3', 0xD4 => 'RST4', 0xD5 => 'RST5', 0xD6 => 'RST6', 0xD7 => 'RST7', 0xD8 => 'SOI', 0xD9 => 'EOI', 0xDA => 'SOS', 0xDB => 'DQT', 0xDC => 'DNL', 0xDD => 'DRI', 0xDE => 'DHP', 0xDF => 'EXP', 0xE0 => 'APP0', 0xE1 => 'APP1', 0xE2 => 'APP2', 0xE3 => 'APP3', 0xE4 => 'APP4', 0xE5 => 'APP5', 0xE6 => 'APP6', 0xE7 => 'APP7', 0xE8 => 'APP8', 0xE9 => 'APP9', 0xEA => 'APP10', 0xEB => 'APP11', 0xEC => 'APP12', 0xED => 'APP13', 0xEE => 'APP14', 0xEF => 'APP15', 0xF0 => 'JPG0', 0xF1 => 'JPG1', 0xF2 => 'JPG2', 0xF3 => 'JPG3', 0xF4 => 'JPG4', 0xF5 => 'JPG5', 0xF6 => 'JPG6', 0xF7 => 'JPG7', 0xF8 => 'JPG8', 0xF9 => 'JPG9', 0xFA => 'JPG10', 0xFB => 'JPG11', 0xFC => 'JPG12', 0xFD => 'JPG13', 0xFE => 'COM', 0x01 => 'TEM', 0x02 => 'RES' ); $fp = @fopen($filename, 'rb'); if (!$fp) { return false; } // Read the first two characters $data = fread($fp, 2); // 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; fclose($fp); return false; } // Read the third character $data = fread($fp, 2); // 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 fclose($fp); return false; } // Flag that we havent yet hit the compressed image data $image_data = 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 while (($data{1} !== "\xD9") && !$image_data && !feof($fp)) { // 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 $segment = ord($data{1}); if (($segment < 0xD0) || ($segment > 0xD7)) { // Segment isn't a Restart marker // Read the next two bytes (size) $string_size = fread($fp, 2); // convert the size bytes to an integer $decoded_size = unpack('n', $string_size); // Save the start position of the data $seg_data_start = ftell($fp); // Read the segment data with length indicated by the previously read size $seg_data = fread($fp, $decoded_size[1] - 2); // Store the segment information in the output array $header_data[] = array( 'seg_type' => $segment, 'seg_name' => $seg_names[$segment], 'seg_datastart' => $seg_data_start, 'seg_data' => $seg_data ); } // If this is a SOS (Start Of Scan) segment, then there is no more header data - the compressed image data follows if ($segment == 0xDA) { $compressed_data = ''; while (!feof($fp)) { $compressed_data .= fread($fp, 1048576); } // Strip off EOI and anything after $eoi_pos = strpos($compressed_data, "\xFF\xD9"); $compressed_data = substr($compressed_data, 0, $eoi_pos); } else { // Not an SOS - Read the next two bytes - should be the segment marker for the next segment $data = fread($fp, 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 fclose($fp); return false; } } } // Close File fclose($fp); // Return the header data retrieved return array('header' => $header_data, 'data' => $compressed_data); } ?>