Example #1
0
function Encode_PIM($tag, $Byte_Align)
{
    // Create a string to receive the packed data
    $packed_data = "";
    // Check that this tag is for Print Image Matching Info
    if ($tag['Type'] == "PIM") {
        // Check that the tag has been decoded - otherwise we don't need to do anything
        if (is_array($tag['Data']) && count($tag['Data']) > 0) {
            // Add the header to the packed data
            $packed_data .= "PrintIM";
            // Add the version to the packed data
            $packed_data .= $tag['Data']['Version'] . "";
            // Create a string to receive the tag data
            $tag_data_str = "";
            // Cycle through each tag
            $tag_count = 0;
            foreach ($tag['Data'] as $key => $curr_tag) {
                // Make sure this is a tag and not supplementary info
                if (is_numeric($key)) {
                    // Count how many tags are created
                    $tag_count++;
                    // Add the tag number to the packed tag data
                    $tag_data_str .= put_IFD_Data_Type($curr_tag['Tag Number'], 3, $Byte_Align);
                    // Add the tag data to the packed tag data
                    $tag_data_str .= $curr_tag['Data'];
                }
            }
            // Add the tag count to the packed data
            $packed_data .= put_IFD_Data_Type($tag_count, 3, $Byte_Align);
            // Add the packed tag data to the packed data
            $packed_data .= $tag_data_str;
        }
    }
    // Return the resulting packed data
    return $packed_data;
}
Example #2
0
function get_IFD_Packed_Data($ifd_data, $IFD_offset, $Byte_Align, $Another_IFD)
{
    $ifd_body_str = "";
    $ifd_data_str = "";
    $Tag_Definitions_Name = $ifd_data['Tags Name'];
    // Count the Tags in this IFD
    $tag_count = 0;
    foreach ($ifd_data as $key => $tag) {
        // Make sure we only count the Tags, not other information keys
        if (is_numeric($key)) {
            $tag_count++;
        }
    }
    // Add the Tag count to the packed data
    $packed_data = put_IFD_Data_Type($tag_count, 3, $Byte_Align);
    // Calculate the total length of the IFD (without the offset data)
    $IFD_len = 2 + $tag_count * 12 + 4;
    // Cycle through each tag
    foreach ($ifd_data as $key => $tag) {
        // Make sure this is a tag, not another information key
        if (is_numeric($key)) {
            // Add the tag number to the packed data
            $ifd_body_str .= put_IFD_Data_Type($tag['Tag Number'], 3, $Byte_Align);
            // Add the Data type to the packed data
            $ifd_body_str .= put_IFD_Data_Type($tag['Data Type'], 3, $Byte_Align);
            // Check if this is a Print Image Matching entry
            if ($tag['Type'] == "PIM") {
                // This is a Print Image Matching entry,
                // encode it
                $data = Encode_PIM($tag, $Byte_Align);
            } else {
                if (($Tag_Definitions_Name == "EXIF" || $Tag_Definitions_Name == "TIFF") && $tag['Tag Number'] == 33723) {
                    // This is a IPTC/NAA Record, encode it
                    $data = put_IPTC($tag['Data']);
                } else {
                    if (($Tag_Definitions_Name == "EXIF" || $Tag_Definitions_Name == "TIFF") && $tag['Tag Number'] == 700) {
                        // This is a XMP Record, encode it
                        $data = write_XMP_array_to_text($tag['Data']);
                    } else {
                        if (($Tag_Definitions_Name == "EXIF" || $Tag_Definitions_Name == "TIFF") && $tag['Tag Number'] == 34377) {
                            // This is a Photoshop IRB Record, encode it
                            $data = pack_Photoshop_IRB_Data($tag['Data']);
                        } else {
                            if ($tag['Tag Number'] == 513 && $Tag_Definitions_Name == "TIFF") {
                                // The Exif Thumbnail Offset is a pointer but of type Long, not Unknown
                                // Hence we need to put the data into the packed string separately
                                // Calculate the thumbnail offset
                                $data_offset = $IFD_offset + $IFD_len + strlen($ifd_data_str);
                                // Create the Offset for the IFD
                                $data = put_IFD_Data_Type($data_offset, 4, $Byte_Align);
                                // Store the thumbnail
                                $ifd_data_str .= $tag['Data'];
                            } else {
                                if ($tag['Tag Number'] == 514 && $Tag_Definitions_Name == "TIFF") {
                                    // Encode the Thumbnail Length
                                    $data = put_IFD_Data_Type(strlen($ifd_data[513]['Data']), 4, $Byte_Align);
                                } else {
                                    if ($tag['Type'] == "SubIFD") {
                                        // This is a Sub-IFD
                                        // Calculate the offset to the start of the Sub-IFD
                                        $data_offset = $IFD_offset + $IFD_len + strlen($ifd_data_str);
                                        // Get the packed data for the IFD chain as the data for this tag
                                        $data = get_IFD_Array_Packed_Data($tag['Data'], $data_offset, $Byte_Align);
                                    } else {
                                        // Not a special tag
                                        // Create a string to receive the data
                                        $data = "";
                                        // Check if this is a type Unknown tag
                                        if ($tag['Data Type'] != 7) {
                                            // NOT type Unknown
                                            // Cycle through each data value and add it to the data string
                                            foreach ($tag['Data'] as $data_val) {
                                                $data .= put_IFD_Data_Type($data_val, $tag['Data Type'], $Byte_Align);
                                            }
                                        } else {
                                            // This is a type Unknown - just add the data as is to the data string
                                            $data .= $tag['Data'];
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // Pad the data string out to at least 4 bytes
            $data = str_pad($data, 4, "");
            // Check if the data type is an ASCII String or type Unknown
            if ($tag['Data Type'] == 2 || $tag['Data Type'] == 7) {
                // This is an ASCII String or type Unknown
                // Add the Length of the string to the packed data as the Count
                $ifd_body_str .= put_IFD_Data_Type(strlen($data), 4, $Byte_Align);
            } else {
                // Add the array count to the packed data as the Count
                $ifd_body_str .= put_IFD_Data_Type(count($tag['Data']), 4, $Byte_Align);
            }
            // Check if the data is over 4 bytes long
            if (strlen($data) > 4) {
                // Data is longer than 4 bytes - it needs to be offset
                // Check if this entry is the Maker Note
                if ($Tag_Definitions_Name == "EXIF" && $tag['Tag Number'] == 37500) {
                    // This is the makernote - It will have already been stored
                    // at its original offset to help preserve it
                    // all we need to do is add the Offset to the IFD packed data
                    $data_offset = $tag['Offset'];
                    $ifd_body_str .= put_IFD_Data_Type($data_offset, 4, $Byte_Align);
                } else {
                    // This is NOT the makernote
                    // Calculate the data offset
                    $data_offset = $IFD_offset + $IFD_len + strlen($ifd_data_str);
                    // Add the offset to the IFD packed data
                    $ifd_body_str .= put_IFD_Data_Type($data_offset, 4, $Byte_Align);
                    // Add the data to the offset packed data
                    $ifd_data_str .= $data;
                }
            } else {
                // Data is less than or equal to 4 bytes - Add it to the packed IFD data as is
                $ifd_body_str .= $data;
            }
        }
    }
    // Assemble the IFD body onto the packed data
    $packed_data .= $ifd_body_str;
    // Check if there is another IFD after this one
    if ($Another_IFD === TRUE) {
        // There is another IFD after this
        // Calculate the Next-IFD offset so that it goes immediately after this IFD
        $next_ifd_offset = $IFD_offset + $IFD_len + strlen($ifd_data_str);
    } else {
        // There is NO IFD after this - indicate with offset=0
        $next_ifd_offset = 0;
    }
    // Add the Next-IFD offset to the packed data
    $packed_data .= put_IFD_Data_Type($next_ifd_offset, 4, $Byte_Align);
    // Add the offset data to the packed data
    $packed_data .= $ifd_data_str;
    // Return the resulting packed data
    return $packed_data;
}