function get_Canon_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { // Check if the Make Field contains the word Canon if (stristr($Make_Field, "Canon") === FALSE) { // Canon not found in Make Field - can't process this return FALSE; } // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset']); // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Canon"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Canon"; $Makernote_Tag['Makernote Tags'] = "Canon"; // Return the new tag return $Makernote_Tag; }
function get_Epson_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { // Check if the Make Field contains the word Epson if (stristr($Make_Field, "Epson") === FALSE) { return FALSE; } // Check if the header exists at the start of the Makernote if (substr($Makernote_Tag['Data'], 0, 8) != "EPSON") { // This isn't a Epson Makernote, abort return FALSE; } // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 8); // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Olympus"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Epson"; $Makernote_Tag['Makernote Tags'] = "Olympus"; // Return the new tag return $Makernote_Tag; }
function get_Kyocera_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { // Check if the Make Field contains the word Contax or Kyocera if (stristr($Make_Field, "Contax") === FALSE && stristr($Make_Field, "Kyocera") === FALSE) { // Kyocera or Contax not found in maker field - abort return FALSE; } // Check if the header exists at the start of the Makernote if (substr($Makernote_Tag['Data'], 0, 22) != "KYOCERA ") { // This isn't a Kyocera Makernote, abort return FALSE; } // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 22); // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Kyocera", True, False); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Kyocera"; $Makernote_Tag['Makernote Tags'] = "Kyocera"; // Return the new tag return $Makernote_Tag; }
function get_Sony_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { // Check if the Make Field contains the word Sony if (stristr($Make_Field, "Sony") === FALSE) { // This isn't a Sony makernote return FALSE; } // Check if the header exists at the start of the Makernote if (substr($Makernote_Tag['Data'], 0, 12) != "SONY CAM " && substr($Makernote_Tag['Data'], 0, 12) != "SONY DSC ") { // This isn't a Sony Makernote, abort return FALSE; } // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 12); // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Sony", FALSE, FALSE); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Sony"; $Makernote_Tag['Makernote Tags'] = "sony"; // Return the new tag return $Makernote_Tag; }
function get_Panasonic_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { // Check if the Make Field contains the word Panasonic if (stristr($Make_Field, "Panasonic") === FALSE) { // No Panasonic in the maker - abort return FALSE; } // Check if the header exists at the start of the Makernote if (substr($Makernote_Tag['Data'], 0, 4) == "MKED") { // Panasonic Type 2 - Empty Makernote // No Makernote Data $Makernote_Tag['Makernote Type'] = "Panasonic Empty Makernote"; $Makernote_Tag['Makernote Tags'] = "-"; $Makernote_Tag['Decoded'] = TRUE; // Return the new tag return $Makernote_Tag; } else { if (substr($Makernote_Tag['Data'], 0, 12) == "Panasonic") { // Panasonic Type 1 - IFD Makernote // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 12); // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Panasonic", FALSE, FALSE); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Panasonic"; $Makernote_Tag['Makernote Tags'] = "Panasonic"; // Return the new tag return $Makernote_Tag; } else { // Unknown Header return FALSE; } } // Shouldn't get here return FALSE; }
function get_Pentax_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { // Check if the Make Field contains the word Pentax or Asahi if (stristr($Make_Field, "Pentax") === FALSE && stristr($Make_Field, "Asahi") === FALSE) { // Couldn't find Pentax or Asahi in the maker - abort return FALSE; } // Check if the header exists at the start of the Makernote if (substr($Makernote_Tag['Data'], 0, 4) == "AOC") { // Type 2 Pentax Makernote // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 6); // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Casio Type 2"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Casio Type 2"; $Makernote_Tag['Makernote Tags'] = "Casio Type 2"; // Return the new tag return $Makernote_Tag; } else { // Type 1 Penax Makernote // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 0); // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Pentax"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Pentax"; $Makernote_Tag['Makernote Tags'] = "Pentax"; // Return the new tag return $Makernote_Tag; } // Shouldn't get here return FALSE; }
function get_Ricoh_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { // Check if the Make Field contains the word Ricoh if (stristr($Make_Field, "Ricoh") === FALSE) { // Ricoh not in the Maker field - abort return FALSE; } // Check if the Text Makernote header exists at the start of the Makernote if (substr($Makernote_Tag['Data'], 0, 2) === "Rv" || substr($Makernote_Tag['Data'], 0, 3) === "Rev") { // This is a text makernote - Label it as such $Makernote_Tag['Makernote Type'] = "Ricoh Text"; $Makernote_Tag['Makernote Tags'] = "None"; $Makernote_Tag['Decoded'] = TRUE; // Return the new Makernote tag return $Makernote_Tag; } else { if ($Makernote_Tag['Data'] === str_repeat("", strlen($Makernote_Tag['Data']))) { // This is an Empty Makernote - Label it as such $Makernote_Tag['Makernote Type'] = "Ricoh Empty Makernote"; $Makernote_Tag['Makernote Tags'] = "None"; $Makernote_Tag['Decoded'] = TRUE; // Return the new Makernote tag return $Makernote_Tag; } else { if (substr($Makernote_Tag['Data'], 0, 5) === "RICOH" || substr($Makernote_Tag['Data'], 0, 5) === "Ricoh") { //This is an IFD Makernote // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 8); // Ricoh Makernote always uses Motorola Byte Alignment $Makernote_Tag['ByteAlign'] = "MM"; // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Ricoh"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Ricoh"; $Makernote_Tag['Makernote Tags'] = "Ricoh"; // Ricoh Makernotes can have a tag 0x2001 which is a Sub-IFD // Check if the tag exists if ($Makernote_Tag['Decoded Data'][0] !== FALSE && array_key_exists(0x2001, $Makernote_Tag['Decoded Data'][0])) { // Ricoh Sub-IFD tag exists - Process it // Grab the Sub-IFD tag for easier processing $SubIFD_Tag =& $Makernote_Tag['Decoded Data'][0][0x2001]; // Check if the Sub-IFD starts with the correct header if (substr($SubIFD_Tag['Data'], 0, 19) === "[Ricoh Camera Info]") { // Correct Header found // Seek to the start of the Sub-IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $SubIFD_Tag['Offset'] + 20); // Ricoh Makernote Sub-IFD always uses Motorola Byte Alignment $SubIFD_Tag['ByteAlign'] = "MM"; // Read the IFD(s) into an array $SubIFD_Tag['Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $SubIFD_Tag['ByteAlign'], "RicohSubIFD", False, False); // Save some information into the Tag element to aid interpretation $SubIFD_Tag['Decoded'] = TRUE; $SubIFD_Tag['Makernote Type'] = "Ricoh"; $SubIFD_Tag['Makernote Tags'] = "RicohSubIFD"; // Change the tag type to a Sub-IFD so it is handled automatically for interpretation $SubIFD_Tag['Type'] = "SubIFD"; $SubIFD_Tag['Tags Name'] = "RicohSubIFD"; } else { // Couldn't find header of Sub-IFD - Probably corrupt $SubIFD_Tag['Type'] = "String"; $SubIFD_Tag['Text Value'] = "Corrupted Ricoh Sub IFD"; } } // Return the new makernote tag return $Makernote_Tag; } else { // Unrecognised header for makernote - abort return FALSE; } } } }
function get_Nikon_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { // Check if the Make Field contains the word Nikon if (stristr($Make_Field, "Nikon") === FALSE) { // Nikon not found in maker field - abort return FALSE; } // Check if the header exists at the start of the Makernote if (substr($Makernote_Tag['Data'], 0, 8) == "Nikon") { // Nikon Type 1 Makernote // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 8); // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Nikon Type 1"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Nikon Type 1"; $Makernote_Tag['Makernote Tags'] = "Nikon Type 1"; // Return the new tag return $Makernote_Tag; } else { if (substr($Makernote_Tag['Data'], 0, 10) == "Nikon" || substr($Makernote_Tag['Data'], 0, 10) == "Nikon") { // Nikon Type 3 Makernote // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 10); // Read the TIFF header and IFD(s) into an array $Makernote_Tag['Decoded Data'] = process_TIFF_Header($filehnd, "Nikon Type 3"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Makernote Type'] = "Nikon Type 3"; $Makernote_Tag['Makernote Tags'] = "Nikon Type 3"; $Makernote_Tag['Decoded'] = TRUE; // Return the new tag return $Makernote_Tag; } else { if (substr($Makernote_Tag['Data'], 0, 8) == "FUJIFILM") { // Fuji Makernote - used by Nikon Coolpix 775 // Let the Fujifilm library handle it return False; } else { // No header - Nikon Type 2 // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 0); // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Nikon Type 3"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Nikon Type 2"; $Makernote_Tag['Makernote Tags'] = "Nikon Type 3"; // Return the new tag return $Makernote_Tag; } } } // Shouldn't get here return FALSE; }
function get_Fujifilm_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { // Check if the Make Field contains the word Fuji or Nikon (One Nikon camera uses this format Makernote) if (stristr($Make_Field, "Fuji") === FALSE && stristr($Make_Field, "Nikon") === FALSE) { // Couldn't find Fuji or Nikon in the maker name - abort return FALSE; } // Check if the header exists at the start of the Makernote if (substr($Makernote_Tag['Data'], 0, 8) != "FUJIFILM") { // This isn't a Fuji Makernote, abort return FALSE; } // The 4 bytes after the header are the offset to the Fujifilm IFD // Get the offset of the IFD $ifd_offset = hexdec(bin2hex(strrev(substr($Makernote_Tag['Data'], 8, 4)))); // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + $ifd_offset); // Fuji Makernotes are always Intel Byte Aligned $Makernote_Tag['ByteAlign'] = "II"; // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'], $Makernote_Tag['ByteAlign'], "Fujifilm"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Fujifilm"; $Makernote_Tag['Makernote Tags'] = "Fujifilm"; // Return the new tag return $Makernote_Tag; }
function read_IFD_universal($filehnd, $Tiff_offset, $Byte_Align, $Tag_Definitions_Name, $local_offsets = FALSE, $read_next_ptr = TRUE) { if ($filehnd == NULL || feof($filehnd)) { return array(FALSE, 0); } // Record the Name of the Tag Group used for this IFD in the output array $OutputArray['Tags Name'] = $Tag_Definitions_Name; // Record the offset of the TIFF header in the output array $OutputArray['Tiff Offset'] = $Tiff_offset; // First 2 bytes of IFD are number of entries in the IFD $No_Entries_str = network_safe_fread($filehnd, 2); $No_Entries = get_IFD_Data_Type($No_Entries_str, 3, $Byte_Align); // If the data is corrupt, the number of entries may be huge, which will cause errors // This is often caused by a lack of a Next-IFD pointer if ($No_Entries > 10000) { // Huge number of entries - abort echo "<p>Error: huge number of EXIF entries - EXIF is probably Corrupted</p>\n"; return array(FALSE, 0); } // If the data is corrupt or just stupid, the number of entries may zero, // Indicate this by returning false if ($No_Entries === 0) { // No entries - abort return array(FALSE, 0); } // Save the file position where first IFD record starts as non-standard offsets // need to know this to calculate an absolute offset $IFD_first_rec_pos = ftell($filehnd); // Read in the IFD structure $IFD_Data = network_safe_fread($filehnd, 12 * $No_Entries); // Check if the entire IFD was able to be read if (strlen($IFD_Data) != 12 * $No_Entries) { // Couldn't read the IFD Data properly, Some Casio files have no Next IFD pointer, hence cause this error echo "<p>Error: EXIF Corrupted</p>\n"; return array(FALSE, 0); } // Last 4 bytes of a standard IFD are the offset to the next IFD // Some NON-Standard IFD implementations do not have this, hence causing problems if it is read // If the Next IFD pointer has been requested to be read, if ($read_next_ptr) { // Read the pointer to the next IFD $Next_Offset_str = network_safe_fread($filehnd, 4); $Next_Offset = get_IFD_Data_Type($Next_Offset_str, 4, $Byte_Align); } else { // Otherwise set the pointer to zero ( no next IFD ) $Next_Offset = 0; } // Initialise current position to the start $pos = 0; // Loop for reading IFD entries for ($i = 0; $i < $No_Entries; $i++) { // First 2 bytes of IFD entry are the tag number ( Unsigned Short ) $Tag_No_str = substr($IFD_Data, $pos, 2); $Tag_No = get_IFD_Data_Type($Tag_No_str, 3, $Byte_Align); $pos += 2; // Next 2 bytes of IFD entry are the data format ( Unsigned Short ) $Data_Type_str = substr($IFD_Data, $pos, 2); $Data_Type = get_IFD_Data_Type($Data_Type_str, 3, $Byte_Align); $pos += 2; // If Datatype is not between 1 and 12, then skip this entry, it is probably corrupted or custom if ($Data_Type > 12 || $Data_Type < 1) { $pos += 8; continue 1; // Stop trying to process the tag any further and skip to the next one } // Next 4 bytes of IFD entry are the data count ( Unsigned Long ) $Data_Count_str = substr($IFD_Data, $pos, 4); $Data_Count = get_IFD_Data_Type($Data_Count_str, 4, $Byte_Align); $pos += 4; if ($Data_Count > 100000) { echo "<p>Error: huge EXIF data count - EXIF is probably Corrupted</p>\n"; // Some Casio files have no Next IFD pointer, hence cause errors return array(FALSE, 0); } // Total Data size is the Data Count multiplied by the size of the Data Type $Total_Data_Size = $GLOBALS['IFD_Data_Sizes'][$Data_Type] * $Data_Count; $Data_Start_pos = -1; // If the total data size is larger than 4 bytes, then the data part is the offset to the real data if ($Total_Data_Size > 4) { // Not enough room for data - offset provided instead $Data_Offset_str = substr($IFD_Data, $pos, 4); $Data_Start_pos = get_IFD_Data_Type($Data_Offset_str, 4, $Byte_Align); // In some NON-STANDARD makernotes, the offset is relative to the start of the current IFD entry if ($local_offsets) { // This is a NON-Standard IFD, seek relative to the start of the current tag fseek($filehnd, $IFD_first_rec_pos + $pos - 8 + $Data_Start_pos); } else { // This is a normal IFD, seek relative to the start of the TIFF header fseek($filehnd, $Tiff_offset + $Data_Start_pos); } // Read the data block from the offset position $DataStr = network_safe_fread($filehnd, $Total_Data_Size); } else { // The data block is less than 4 bytes, and is provided in the IFD entry, so read it $DataStr = substr($IFD_Data, $pos, $Total_Data_Size); } // Increment the position past the data $pos += 4; // Now create the entry for output array $Data_Array = array(); // Read the data items from the data block if ($Data_Type != 2 && $Data_Type != 7) { // The data type is Numerical, Read the data items from the data block for ($j = 0; $j < $Data_Count; $j++) { $Part_Data_Str = substr($DataStr, $j * $GLOBALS['IFD_Data_Sizes'][$Data_Type], $GLOBALS['IFD_Data_Sizes'][$Data_Type]); $Data_Array[] = get_IFD_Data_Type($Part_Data_Str, $Data_Type, $Byte_Align); } } elseif ($Data_Type == 2) { // The data type is String(s) (type 2) // Strip the last terminating Null $DataStr = substr($DataStr, 0, strlen($DataStr) - 1); // Split the data block into multiple strings whereever there is a Null $Data_Array = explode("", $DataStr); } else { // The data type is Unknown (type 7) // Do nothing to data $Data_Array = $DataStr; } // If this is a Sub-IFD entry, if (array_key_exists($Tag_No, $GLOBALS["IFD_Tag_Definitions"][$Tag_Definitions_Name]) && "SubIFD" == $GLOBALS["IFD_Tag_Definitions"][$Tag_Definitions_Name][$Tag_No]['Type']) { // This is a Sub-IFD entry, go and process the data forming Sub-IFD and use its output array as the new data for this entry fseek($filehnd, $Tiff_offset + $Data_Array[0]); $Data_Array = read_Multiple_IFDs($filehnd, $Tiff_offset, $Byte_Align, $GLOBALS["IFD_Tag_Definitions"][$Tag_Definitions_Name][$Tag_No]['Tags Name']); } $desc = ""; $units = ""; // Check if this tag exists in the list of tag definitions, if (array_key_exists($Tag_No, $GLOBALS["IFD_Tag_Definitions"][$Tag_Definitions_Name])) { if (array_key_exists('Description', $GLOBALS["IFD_Tag_Definitions"][$Tag_Definitions_Name][$Tag_No])) { $desc = $GLOBALS["IFD_Tag_Definitions"][$Tag_Definitions_Name][$Tag_No]['Description']; } if (array_key_exists('Units', $GLOBALS["IFD_Tag_Definitions"][$Tag_Definitions_Name][$Tag_No])) { $units = $GLOBALS["IFD_Tag_Definitions"][$Tag_Definitions_Name][$Tag_No]['Units']; } // Tag exists in definitions, append details to output array $OutputArray[$Tag_No] = array("Tag Number" => $Tag_No, "Tag Name" => $GLOBALS["IFD_Tag_Definitions"][$Tag_Definitions_Name][$Tag_No]['Name'], "Tag Description" => $desc, "Data Type" => $Data_Type, "Type" => $GLOBALS["IFD_Tag_Definitions"][$Tag_Definitions_Name][$Tag_No]['Type'], "Units" => $units, "Data" => $Data_Array); } else { // Tag doesnt exist in definitions, append unknown details to output array $OutputArray[$Tag_No] = array("Tag Number" => $Tag_No, "Tag Name" => "Unknown Tag #" . $Tag_No, "Tag Description" => "", "Data Type" => $Data_Type, "Type" => "Unknown", "Units" => "", "Data" => $Data_Array); } // Some information of type "Unknown" (type 7) might require information about // how it's position and byte alignment in order to be decoded if ($Data_Type == 7) { $OutputArray[$Tag_No]['Offset'] = $Data_Start_pos; $OutputArray[$Tag_No]['Byte Align'] = $Byte_Align; } //////////////////////////////////////////////////////////////////////// // Special Data handling //////////////////////////////////////////////////////////////////////// // Check if this is a Print Image Matching entry if ($OutputArray[$Tag_No]['Type'] == "PIM") { // This is a Print Image Matching entry, decode it. $OutputArray[$Tag_No] = Decode_PIM($OutputArray[$Tag_No], $Tag_Definitions_Name); } // Interpret the entry into a text string using a custom interpreter $text_val = get_Tag_Text_Value($OutputArray[$Tag_No], $Tag_Definitions_Name); // Check if a text string was generated if ($text_val !== FALSE) { // A string was generated, append it to the output array entry $OutputArray[$Tag_No]['Text Value'] = $text_val; $OutputArray[$Tag_No]['Decoded'] = TRUE; } else { // A string was NOT generated, append a generic string to the output array entry $OutputArray[$Tag_No]['Text Value'] = get_IFD_value_as_text($OutputArray[$Tag_No]) . " " . $units; $OutputArray[$Tag_No]['Decoded'] = FALSE; } // Check if this entry is the Maker Note if ($Tag_Definitions_Name == "EXIF" && $Tag_No == 37500) { // Save some extra information which will allow Makernote Decoding with the output array entry $OutputArray[$Tag_No]['Offset'] = $Data_Start_pos; $OutputArray[$Tag_No]['Tiff Offset'] = $Tiff_offset; $OutputArray[$Tag_No]['ByteAlign'] = $Byte_Align; // Save a pointer to this entry for Maker note processing later $GLOBALS["Maker_Note_Tag"] =& $OutputArray[$Tag_No]; } // Check if this is a IPTC/NAA Record within the EXIF IFD if (($Tag_Definitions_Name == "EXIF" || $Tag_Definitions_Name == "TIFF") && $Tag_No == 33723) { // This is a IPTC/NAA Record, interpret it and put result in the data for this entry $OutputArray[$Tag_No]['Data'] = get_IPTC($DataStr); $OutputArray[$Tag_No]['Decoded'] = TRUE; } // Change: Check for embedded XMP as of version 1.11 // Check if this is a XMP Record within the EXIF IFD if (($Tag_Definitions_Name == "EXIF" || $Tag_Definitions_Name == "TIFF") && $Tag_No == 700) { // This is a XMP Record, interpret it and put result in the data for this entry $OutputArray[$Tag_No]['Data'] = read_XMP_array_from_text($DataStr); $OutputArray[$Tag_No]['Decoded'] = TRUE; } // Change: Check for embedded IRB as of version 1.11 // Check if this is a Photoshop IRB Record within the EXIF IFD if (($Tag_Definitions_Name == "EXIF" || $Tag_Definitions_Name == "TIFF") && $Tag_No == 34377) { // This is a Photoshop IRB Record, interpret it and put result in the data for this entry $OutputArray[$Tag_No]['Data'] = unpack_Photoshop_IRB_Data($DataStr); $OutputArray[$Tag_No]['Decoded'] = TRUE; } // Exif Thumbnail // Check that both the thumbnail length and offset entries have been processed, // and that this is one of them if (($Tag_No == 513 && array_key_exists(514, $OutputArray) || $Tag_No == 514 && array_key_exists(513, $OutputArray)) && $Tag_Definitions_Name == "TIFF") { // Seek to the start of the thumbnail using the offset entry fseek($filehnd, $Tiff_offset + $OutputArray[513]['Data'][0]); // Read the thumbnail data, and replace the offset data with the thumbnail $OutputArray[513]['Data'] = network_safe_fread($filehnd, $OutputArray[514]['Data'][0]); } // Casio Thumbnail // Check that both the thumbnail length and offset entries have been processed, // and that this is one of them if (($Tag_No == 0x4 && array_key_exists(0x3, $OutputArray) || $Tag_No == 0x3 && array_key_exists(0x4, $OutputArray)) && $Tag_Definitions_Name == "Casio Type 2") { // Seek to the start of the thumbnail using the offset entry fseek($filehnd, $Tiff_offset + $OutputArray[0x4]['Data'][0]); // Read the thumbnail data, and replace the offset data with the thumbnail $OutputArray[0x4]['Data'] = network_safe_fread($filehnd, $OutputArray[0x3]['Data'][0]); } // Minolta Thumbnail // Check that both the thumbnail length and offset entries have been processed, // and that this is one of them if (($Tag_No == 0x88 && array_key_exists(0x89, $OutputArray) || $Tag_No == 0x89 && array_key_exists(0x88, $OutputArray)) && $Tag_Definitions_Name == "Olympus") { // Seek to the start of the thumbnail using the offset entry fseek($filehnd, $Tiff_offset + $OutputArray[0x88]['Data'][0]); // Read the thumbnail data, and replace the offset data with the thumbnail $OutputArray[0x88]['Data'] = network_safe_fread($filehnd, $OutputArray[0x89]['Data'][0]); // Sometimes the minolta thumbnail data is empty (or the offset is corrupt, which results in the same thing) // Check if the thumbnail data exists if ($OutputArray[0x88]['Data'] != "") { // Thumbnail exists // Minolta Thumbnails are missing their first 0xFF for some reason, // which is replaced with some weird character, so fix this $OutputArray[0x88]['Data'][0] = "ÿ"; } else { // Thumbnail doesnt exist - make it obvious $OutputArray[0x88]['Data'] = FALSE; } } } // Return the array of IFD entries and the offset to the next IFD return array($OutputArray, $Next_Offset); }
function get_Casio_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { // Check if the Make Field contains the word Casio if (stristr($Make_Field, "Casio") === FALSE) { return FALSE; } if (substr($Makernote_Tag['Data'], 0, 6) == "QVC") { // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 6); $Makernote_Tag['ByteAlign'] = "MM"; // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Casio Type 2"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Casio Type 2"; $Makernote_Tag['Makernote Tags'] = "Casio Type 2"; // Return the new tag return $Makernote_Tag; } else { // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset'] + 0); $Makernote_Tag['ByteAlign'] = "MM"; // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Casio Type 1"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Casio Type 1"; $Makernote_Tag['Makernote Tags'] = "Casio Type 1"; // Return the new tag return $Makernote_Tag; } }
function get_Minolta_Makernote($Makernote_Tag, $EXIF_Array, $filehnd, $Make_Field) { if (stristr($Make_Field, "Konica") === FALSE && stristr($Make_Field, "Minolta") === FALSE) { // Not a Konica/Minolta Makernote - Cannot decode it return False; } // There are several different headers for a Konica/Minolta Makernote // Unfortunately only one type can be decoded (the one without a header) // Check which header exists (if any) if (substr($Makernote_Tag['Data'], 0, 3) == "MLY") { // MLY Header - Can't Decode this return $Makernote_Tag; } else { if (substr($Makernote_Tag['Data'], 0, 2) == "KC") { // KC Header - Can't Decode this return $Makernote_Tag; } } if (substr($Makernote_Tag['Data'], 0, 8) == "+M+M+M+M") { // +M+M+M+M Header - Can't Decode this return $Makernote_Tag; } else { if (substr($Makernote_Tag['Data'], 0, 5) == "MINOL") { // MINOL Header - Can't Decode this return $Makernote_Tag; } else { // No Header - Decode the IFD // Seek to the start of the IFD fseek($filehnd, $Makernote_Tag['Tiff Offset'] + $Makernote_Tag['Offset']); // Read the IFD(s) into an array $Makernote_Tag['Decoded Data'] = read_Multiple_IFDs($filehnd, $Makernote_Tag['Tiff Offset'], $Makernote_Tag['ByteAlign'], "Olympus"); // Save some information into the Tag element to aid interpretation $Makernote_Tag['Decoded'] = TRUE; $Makernote_Tag['Makernote Type'] = "Minolta"; $Makernote_Tag['Makernote Tags'] = "Olympus"; // Return the new tag return $Makernote_Tag; } } // Shouldn't get here return False; }