function get_Special_Tag_Text_Value($Tag, $Tag_Definitions_Name) { // Check what type of IFD is being decoded if ($Tag_Definitions_Name == "TIFF") { // This is a TIFF IFD (bottom level) // Check what tag number the IFD entry has. switch ($Tag['Tag Number']) { case 530: // YCbCr Sub Sampling Entry // Data contains two numerical values if ($Tag['Data'][0] == 2 && $Tag['Data'][1] == 1) { // Values are 2,1 - hence YCbCr 4:2:2 return "YCbCr 4:2:2 ratio of chrominance components to the luminance components"; } elseif ($Tag['Data'][0] == 2 && $Tag['Data'][1] == 2) { // Values are 2,2 - hence YCbCr 4:2:0 return "YCbCr 4:2:0 ratio of chrominance components to the luminance components"; } else { // Other values are unknown return "Unknown Reserved value (" . $Tag['Data'][0] . ")"; } break; default: return FALSE; } } else { if ($Tag_Definitions_Name == "EXIF") { // This is an EXIF IFD // Check what tag number the IFD entry has. switch ($Tag['Tag Number']) { case 37121: // Components configuration // Data contains 4 numerical values indicating component type $output_str = ""; // Cycle through each component for ($Num = 0; $Num < 4; $Num++) { // Construct first part of text string $output_str .= "Component " . ($Num + 1) . ": "; // Construct second part of text string via // lookup using numerical value $value = ord($Tag['Data'][$Num]); switch ($value) { case 0: $output_str .= "Does not exist\n"; break; case 1: $output_str .= "Y (Luminance)\n"; break; case 2: $output_str .= "Cb (Chroma minus Blue)\n"; break; case 3: $output_str .= "Cr (Chroma minus Red)\n"; break; case 4: $output_str .= "Red\n"; break; case 5: $output_str .= "Green\n"; break; case 6: $output_str .= "Blue\n"; break; default: $output_str .= "Unknown value {$value}\n"; } } // Return the completed string return $output_str; break; case 41730: // Colour Filter Array Pattern // The first two characters are a SHORT for Horizontal repeat pixel unit - $n_max = get_IFD_Data_Type(substr($Tag['Data'], 0, 2), 3, $Tag['Byte Align']); // The next two characters are a SHORT for Vertical repeat pixel unit - $m_max = get_IFD_Data_Type(substr($Tag['Data'], 2, 2), 3, $Tag['Byte Align']); // At least one camera type appears to have byte reversed values for N_Max and M_Max // Check if they need reversing if ($n_max > 256) { $n_max = $n_max / 256 + 256 * ($n_max % 256); } if ($m_max > 256) { $m_max = $m_max / 256 + 256 * ($m_max % 256); } $output_str = ""; // Cycle through all the elements in the resulting 2 dimensional array, for ($m = 1; $m <= $m_max; $m++) { for ($n = 1; $n <= $n_max; $n++) { // Append text from a lookup table according to // the value read for this element switch (ord($Tag['Data'][$n_max * ($m - 1) + $n + 3])) { case 0: $output_str .= "RED "; break; case 1: $output_str .= "GREEN "; break; case 2: $output_str .= "BLUE "; break; case 3: $output_str .= "CYAN "; break; case 4: $output_str .= "MAGENTA "; break; case 5: $output_str .= "YELLOW "; break; case 6: $output_str .= "WHITE "; break; default: $output_str .= "Unknown "; break; } } $output_str .= "\n"; } // Return the resulting string return $output_str; break; default: return FALSE; } } else { // Unknown IFD type, see if it is part of a makernote return get_Makernote_Text_Value($Tag, $Tag_Definitions_Name); } } }
function Decode_PIM($tag, $Tag_Definitions_Name) { // Create a new EXIF tag for the output $newtag = $tag; // Check that this tag is for Print Image Matching Info if ($tag['Type'] == "PIM") { // Check that the data starts with PrintIM if (substr($tag['Data'], 0, 8) == "PrintIM") { // Find the end of the version string if (($ver_pos = strpos($tag['Data'], "", 8)) == -1) { // couldn't find the start of the version string return $newtag; } // Create an array to receive the Data $newtag['Data'] = array(); // Extract the PrintIM version $newtag['Data']['Version'] = substr($tag['Data'], 8, $ver_pos - 8); // Skip the position over the version $count_pos = $ver_pos + 2; // Extract the count of tags - 2 bytes $PI_tag_count = get_IFD_Data_Type(substr($tag['Data'], $count_pos, 2), 3, $tag['Byte Align']); // Panasonic have put an extra Null after the Version, which // causes the tag count to be wrong - // check if it is zero - i.e. possibly wrong if ($PI_tag_count == 0) { // Tag count is zero - try moving the position by one, // then re-extracting the count $count_pos++; $PI_tag_count = get_IFD_Data_Type(substr($tag['Data'], $count_pos, 2), 3, $tag['Byte Align']); } // Extract the data part of the PrintIM block $data_part = substr($tag['Data'], $count_pos + 2); // Cycle through each tag for ($a = 0; $a < $PI_tag_count; $a++) { // Read the tag number - 2 bytes $PI_tag = get_IFD_Data_Type(substr($data_part, $a * 6, 2), 3, $tag['Byte Align']); // Read the tag data - 4 bytes $newtag['Data'][] = array('Tag Number' => $PI_tag, 'Data' => substr($data_part, $a * 6 + 2, 4), 'Decoded' => False); } } } // Return the updated tag return $newtag; }
function get_Minolta_Text_Value($Exif_Tag, $Tag_Definitions_Name) { // Check that this Tag uses Olympus type tags - otherwise it cannot be processed here if ($Tag_Definitions_Name !== "Olympus") { // Not Olympus Tags - cannot be processed here return FALSE; } // Process the tag acording to it's tag number, to produce a text value if ($Exif_Tag['Tag Number'] == 0x1 || $Exif_Tag['Tag Number'] == 0x3) { // Create the output string $output_str = ""; // Cycle through each camera setting record which are 4 byte Longs for ($i = 1; $i * 4 <= strlen($Exif_Tag['Data']); $i++) { // Exract the current 4 byte Long value (Motorola byte alignment) $value = get_IFD_Data_Type(substr($Exif_Tag['Data'], ($i - 1) * 4, 4), 4, "MM"); // Corrupt settings can cause huge values, which automatically get // put into floating point variables instead of integer variables // Hence Check that this is an integer, as problems will occur if it isn't if (is_integer($value)) { // Check if the current setting number is in the Definitions array if (array_key_exists($i, $GLOBALS["Minolta_Camera_Setting_Definitions"]) === TRUE) { // Setting is in definitions array // Get some of the information from the settings definitions array $tagname = $GLOBALS["Minolta_Camera_Setting_Definitions"][$i]['Name']; $units = ""; if (array_key_exists('Units', $GLOBALS["Minolta_Camera_Setting_Definitions"][$i])) { $units = $GLOBALS["Minolta_Camera_Setting_Definitions"][$i]['Units']; } // Check what type of field the setting is, and process accordingly if ($GLOBALS["Minolta_Camera_Setting_Definitions"][$i]['Type'] == "Lookup") { // This is a lookup table field // Check if the value read is in the lookup table if (array_key_exists($value, $GLOBALS["Minolta_Camera_Setting_Definitions"][$i])) { // Value is in the lookup table - Add it to the text $output_str .= $tagname . ": " . $GLOBALS["Minolta_Camera_Setting_Definitions"][$i][$value] . "\n"; } else { // Value is Not in the lookup table // Add a message if the user has requested to see unknown tags if ($GLOBALS['HIDE_UNKNOWN_TAGS'] == FALSE) { $output_str .= $tagname . ": Unknown Reserved Value {$value}\n"; } } } else { if ($GLOBALS["Minolta_Camera_Setting_Definitions"][$i]['Type'] == "Numeric") { // This is a numeric type add it as is to the output, with units $output_str .= $tagname . ": {$value} {$units}\n"; } else { if ($GLOBALS["Minolta_Camera_Setting_Definitions"][$i]['Type'] == "Special") { // This is a special setting, Process it according to the setting number switch ($i) { case 9: // Apex Film Speed Value $output_str .= $tagname . ": " . ($value / 8 - 1) . " ( ISO " . pow(2, $value / 8 - 1) * 3.125 . " )\n"; break; case 10: // Apex Shutter Speed Time Value $output_str .= $tagname . ": " . ($value / 8 - 6); if ($value == 8) { $output_str .= " ( 30 seconds )\n"; } else { $output_str .= " ( " . pow(2, (48 - $value) / 8) . " seconds )\n"; } break; case 11: // Apex Aperture Value $output_str .= $tagname . ": " . ($value / 8 - 1) . " ( F Stop: " . pow(2, $value / 16 - 0.5) . " )\n"; break; case 14: // Exposure Compensation $output_str .= $tagname . ": " . ($value / 3 - 2) . " {$units}\n"; break; case 17: // Interval Length $output_str .= $tagname . ": " . ($value + 1) . " {$units}\n"; break; case 19: // Focal Length $output_str .= $tagname . ": " . $value / 256 . " {$units}\n"; break; case 22: // Date $output_str .= $tagname . ": " . sprintf("%d/%d/%d", $value % 256, floor(($value - floor($value / 65536) * 65536) / 256), floor($value / 65536)) . " {$units}\n"; break; case 23: // Time $output_str .= $tagname . ": " . sprintf("%2d:%02d:%02d", floor($value / 65536), floor(($value - floor($value / 65536) * 65536) / 256), $value % 256) . " {$units}\n"; break; case 24: // Max Aperture at this focal length $output_str .= $tagname . ": F" . pow(2, $value / 16 - 0.5) . " {$units}\n"; break; case 29: // White Balance Red // White Balance Red case 30: // White Balance Green // White Balance Green case 31: // White Balance Blue $output_str .= $tagname . ": " . $value / 256 . " {$units}\n"; break; case 32: // Saturation // Saturation case 33: // Contrast $output_str .= $tagname . ": " . ($value - 3) . " {$units}\n"; break; case 36: // Flash Compensation $output_str .= $tagname . ": " . ($value - 6) / 3 . " {$units}\n"; break; case 42: // Color Filter $output_str .= $tagname . ": " . ($value - 3) . " {$units}\n"; break; case 45: // Apex Brightness Value $output_str .= $tagname . ": " . ($value / 8 - 6) . " {$units}\n"; break; default: // Unknown Special Setting // If user has requested to see the unknown tags, then add the setting to the output if ($GLOBALS['HIDE_UNKNOWN_TAGS'] == FALSE) { $output_str .= "Unknown Special Tag: {$tagname}, Value: {$value} {$units}\n"; } break; } } else { // Unknown Setting Type // If user has requested to see the unknown tags, then add the setting to the output if ($GLOBALS['HIDE_UNKNOWN_TAGS'] == FALSE) { $output_str .= "Unknown Tag Type Tag {$i}, Value: " . $value . "\n"; } } } } } else { // Unknown Setting // If user has requested to see the unknown tags, then add the setting to the output if ($GLOBALS['HIDE_UNKNOWN_TAGS'] == FALSE) { $output_str .= "Unknown Minolta Camera Setting Tag {$i}, Value: " . $value . "\n"; } } } } // Return the text string return $output_str; } else { if ($Exif_Tag['Tag Number'] == 0x88 || $Exif_Tag['Tag Number'] == 0x81) { // Konica/Minolta Thumbnail return "Thumbnail"; } else { return FALSE; } } }