Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #9
0
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;
}
Example #10
0
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);
}
Example #11
0
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;
    }
}
Example #12
0
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;
}