/add-ons/pjmt/Photoshop_IRB.php
PHP | 1514 lines | 924 code | 214 blank | 376 comment | 88 complexity | e58043abc2d91c4d79fa8f5f487ca4ef MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, GPL-3.0, Apache-2.0, BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- <?
-
- /******************************************************************************
- *
- * Filename: Photoshop_IRB.php
- *
- * Description: Provides functions for reading and writing information to/from
- * the 'App 13' Photoshop Information Resource Block segment of
- * JPEG format files
- *
- * Author: Evan Hunter
- *
- * Date: 23/7/2004
- *
- * Project: PHP JPEG Metadata Toolkit
- *
- * Revision: 1.11
- *
- * Changes: 1.00 -> 1.02 : changed get_Photoshop_IRB to work with corrupted
- * resource names which Photoshop can still read
- * 1.02 -> 1.03 : Fixed put_Photoshop_IRB to output "Photoshop 3.0\x00"
- * string with every APP13 segment, not just the first one
- * 1.03 -> 1.10 : changed get_Photoshop_IRB to fix processing of embedded resource names,
- * after discovering that Photoshop does not process
- * resource names according to the standard :
- * "Adobe Photoshop 6.0 File Formats Specification, Version 6.0, Release 2, November 2000"
- * This is an update to the change 1.00 -> 1.02, which was not fully correct
- * changed put_Photoshop_IRB to fix the writing of embedded resource name,
- * to avoid creating blank resources, and to fix a problem
- * causing the IRB block to be incorrectly positioned if no APP segments existed.
- * changed get_Photoshop_IPTC to initialise the output array correctly.
- * 1.10 -> 1.11 : Moved code out of get_Photoshop_IRB into new function unpack_Photoshop_IRB_Data
- * to allow reading of IRB blocks embedded within EXIF (for TIFF Files)
- * Moved code out of put_Photoshop_IRB into new function pack_Photoshop_IRB_Data
- * to allow writing of IRB blocks embedded within EXIF (for TIFF Files)
- * Enabled the usage of $GLOBALS['HIDE_UNKNOWN_TAGS'] to hide unknown resources
- * changed Interpret_IRB_to_HTML to allow thumbnail links to work when
- * toolkit is portable across directories
- *
- *
- * URL: http://electronics.ozhiker.com
- *
- * Copyright: Copyright Evan Hunter 2004
- *
- * License: This file is part of the PHP JPEG Metadata Toolkit.
- *
- * The PHP JPEG Metadata Toolkit is free software; you can
- * redistribute it and/or modify it under the terms of the
- * GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * The PHP JPEG Metadata Toolkit is distributed in the hope
- * that it will be useful, but WITHOUT ANY WARRANTY; without
- * even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with the PHP JPEG Metadata Toolkit; if not,
- * write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * If you require a different license for commercial or other
- * purposes, please contact the author: evan@ozhiker.com
- *
- ******************************************************************************/
-
- // Change: as of version 1.11 - added to ensure the HIDE_UNKNOWN_TAGS variable is set even if EXIF.php is not included
- if ( !isset( $GLOBALS['HIDE_UNKNOWN_TAGS'] ) ) $GLOBALS['HIDE_UNKNOWN_TAGS']= FALSE;
-
- include_once 'IPTC.php';
- include_once 'Unicode.php';
-
-
-
- // TODO: Many Photoshop IRB resources not interpeted
- // TODO: Obtain a copy of the Photoshop CS File Format Specification
- // TODO: Find out what Photoshop IRB resources 1061, 1062 & 1064 are
- // TODO: Test get_Photoshop_IRB and put_Photoshop_IRB with multiple APP13 segments
-
- /******************************************************************************
- *
- * Function: get_Photoshop_IRB
- *
- * Description: Retrieves the Photoshop Information Resource Block (IRB) information
- * from an App13 JPEG segment and returns it as an array. This may
- * include IPTC-NAA IIM Information. Uses information
- * supplied by the get_jpeg_header_data function
- *
- * Parameters: jpeg_header_data - a JPEG header data array in the same format
- * as from get_jpeg_header_data
- *
- * Returns: IRBdata - The array of Photoshop IRB records
- * FALSE - if an APP 13 Photoshop IRB segment could not be found,
- * or if an error occured
- *
- ******************************************************************************/
-
- function get_Photoshop_IRB( $jpeg_header_data )
- {
- // Photoshop Image Resource blocks can span several JPEG APP13 segments, so we need to join them up if there are more than one
- $joined_IRB = "";
-
-
- //Cycle through the header segments
- for( $i = 0; $i < count( $jpeg_header_data ); $i++ )
- {
- // If we find an APP13 header,
- if ( strcmp ( $jpeg_header_data[$i]['SegName'], "APP13" ) == 0 )
- {
- // And if it has the photoshop label,
- if( strncmp ( $jpeg_header_data[$i]['SegData'], "Photoshop 3.0\x00", 14) == 0 )
- {
- // join it to the other previous IRB data
- $joined_IRB .= substr ( $jpeg_header_data[$i]['SegData'], 14 );
- }
- }
- }
-
- // If there was some Photoshop IRB information found,
- if ( $joined_IRB != "" )
- {
- // Found a Photoshop Image Resource Block - extract it.
- // Change: Moved code into unpack_Photoshop_IRB_Data to allow TIFF reading as of 1.11
- return unpack_Photoshop_IRB_Data( $joined_IRB );
-
- }
- else
- {
- // No Photoshop IRB found
- return FALSE;
- }
-
- }
-
- /******************************************************************************
- * End of Function: get_Photoshop_IRB
- ******************************************************************************/
-
-
-
-
-
-
-
-
-
-
- /******************************************************************************
- *
- * Function: put_Photoshop_IRB
- *
- * Description: Adds or modifies the Photoshop Information Resource Block (IRB)
- * information from an App13 JPEG segment. If a Photoshop IRB already
- * exists, it is replaced, otherwise a new one is inserted, using the
- * supplied data. Uses information supplied by the get_jpeg_header_data
- * function
- *
- * Parameters: jpeg_header_data - a JPEG header data array in the same format
- * as from get_jpeg_header_data
- * new_IRB_data - an array of the data to be stored in the Photoshop
- * IRB segment. Should be in the same format as received
- * from get_Photoshop_IRB
- *
- * Returns: jpeg_header_data - the JPEG header data array with the
- * Photoshop IRB added.
- * FALSE - if an error occured
- *
- ******************************************************************************/
-
- function put_Photoshop_IRB( $jpeg_header_data, $new_IRB_data )
- {
- // Delete all existing Photoshop IRB blocks - the new one will replace them
-
- //Cycle through the header segments
- for( $i = 0; $i < count( $jpeg_header_data ) ; $i++ )
- {
- // If we find an APP13 header,
- if ( strcmp ( $jpeg_header_data[$i]['SegName'], "APP13" ) == 0 )
- {
- // And if it has the photoshop label,
- if( strncmp ( $jpeg_header_data[$i]['SegData'], "Photoshop 3.0\x00", 14) == 0 )
- {
- // Delete the block information - it needs to be rebuilt
- array_splice( $jpeg_header_data, $i, 1 );
- }
- }
- }
-
-
- // Now we have deleted the pre-existing blocks
-
-
- // Retrieve the Packed Photoshop IRB Data
- // Change: Moved code into pack_Photoshop_IRB_Data to allow TIFF writing as of 1.11
- $packed_IRB_data = pack_Photoshop_IRB_Data( $new_IRB_data );
-
- // Change : This section changed to fix incorrect positioning of IRB segment, as of revision 1.10
- // when there are no APP segments present
-
- //Cycle through the header segments in reverse order (to find where to put the APP13 block - after any APP0 to APP12 blocks)
- $i = count( $jpeg_header_data ) - 1;
- while (( $i >= 0 ) && ( ( $jpeg_header_data[$i]['SegType'] > 0xED ) || ( $jpeg_header_data[$i]['SegType'] < 0xE0 ) ) )
- {
- $i--;
- }
-
-
-
- // Cycle through the packed output data until it's size is less than 32000 bytes, outputting each 32000 byte block to an APP13 segment
- while ( strlen( $packed_IRB_data ) > 32000 )
- {
- // Change: Fixed put_Photoshop_IRB to output "Photoshop 3.0\x00" string with every APP13 segment, not just the first one, as of 1.03
-
- // Write a 32000 byte APP13 segment
- array_splice($jpeg_header_data, $i +1 , 0, array( "SegType" => 0xED,
- "SegName" => "APP13",
- "SegDesc" => $GLOBALS[ "JPEG_Segment_Descriptions" ][ 0xED ],
- "SegData" => "Photoshop 3.0\x00" . substr( $packed_IRB_data,0,32000) ) );
-
- // Delete the 32000 bytes from the packed output data, that were just output
- $packed_IRB_data = substr_replace($packed_IRB_data, '', 0, 32000);
- $i++;
- }
-
- // Write the last block of packed output data to an APP13 segment - Note array_splice doesn't work with multidimensional arrays, hence inserting a blank string
- array_splice($jpeg_header_data, $i + 1 , 0, "" );
- $jpeg_header_data[$i + 1] = array( "SegType" => 0xED,
- "SegName" => "APP13",
- "SegDesc" => $GLOBALS[ "JPEG_Segment_Descriptions" ][ 0xED ],
- "SegData" => "Photoshop 3.0\x00" . $packed_IRB_data );
-
- return $jpeg_header_data;
- }
-
- /******************************************************************************
- * End of Function: put_Photoshop_IRB
- ******************************************************************************/
-
-
-
-
-
-
-
-
- /******************************************************************************
- *
- * Function: get_Photoshop_IPTC
- *
- * Description: Retrieves IPTC-NAA IIM information from within a Photoshop
- * IRB (if it is present) and returns it in an array. Uses
- * information supplied by the get_jpeg_header_data function
- *
- * Parameters: Photoshop_IRB_data - an array of Photoshop IRB records, as
- * returned from get_Photoshop_IRB
- *
- * Returns: IPTC_Data_Out - The array of IPTC-NAA IIM records
- * FALSE - if an IPTC-NAA IIM record could not be found, or if
- * an error occured
- *
- ******************************************************************************/
-
- function get_Photoshop_IPTC( $Photoshop_IRB_data )
- {
-
- // Change: Initialise array correctly, as of revision 1.10
- $IPTC_Data_Out = array();
-
- //Cycle through the Photoshop 8BIM records looking for the IPTC-NAA record
- for( $i = 0; $i < count( $Photoshop_IRB_data ); $i++ )
- {
- // Check if each record is a IPTC record (which has id 0x0404)
- if ( $Photoshop_IRB_data[$i]['ResID'] == 0x0404 )
- {
- // We've found an IPTC block - Decode it
- $IPTC_Data_Out = get_IPTC( $Photoshop_IRB_data[$i]['ResData'] );
- }
- }
-
- // If there was no records put into the output array,
- if ( count( $IPTC_Data_Out ) == 0 )
- {
- // Then return false
- return FALSE;
- }
- else
- {
- // Otherwise return the array
- return $IPTC_Data_Out;
- }
-
- }
- /******************************************************************************
- * End of Function: get_Photoshop_IPTC
- ******************************************************************************/
-
-
-
-
-
-
- /******************************************************************************
- *
- * Function: put_Photoshop_IPTC
- *
- * Description: Inserts a new IPTC-NAA IIM resource into a Photoshop
- * IRB, or replaces an the existing resource if one is present.
- * Uses information supplied by the get_Photoshop_IRB function
- *
- * Parameters: Photoshop_IRB_data - an array of Photoshop IRB records, as
- * returned from get_Photoshop_IRB, into
- * which the IPTC-NAA IIM record will be inserted
- * new_IPTC_block - an array of IPTC-NAA records in the same format
- * as those returned by get_Photoshop_IPTC
- *
- * Returns: Photoshop_IRB_data - The Photoshop IRB array with the
- * IPTC-NAA IIM resource inserted
- *
- ******************************************************************************/
-
- function put_Photoshop_IPTC( $Photoshop_IRB_data, $new_IPTC_block )
- {
- $iptc_block_pos = -1;
-
- //Cycle through the 8BIM records looking for the IPTC-NAA record
- for( $i = 0; $i < count( $Photoshop_IRB_data ); $i++ )
- {
- // Check if each record is a IPTC record (which has id 0x0404)
- if ( $Photoshop_IRB_data[$i]['ResID'] == 0x0404 )
- {
- // We've found an IPTC block - save the position
- $iptc_block_pos = $i;
- }
- }
-
- // If no IPTC block was found, create a new one
- if ( $iptc_block_pos == -1 )
- {
- // New block position will be at the end of the array
- $iptc_block_pos = count( $Photoshop_IRB_data );
- }
-
-
- // Write the new IRB resource to the Photoshop IRB array with no data
- $Photoshop_IRB_data[$iptc_block_pos] = array( "ResID" => 0x0404,
- "ResName" => $GLOBALS['Photoshop_ID_Names'][ 0x0404 ],
- "ResDesc" => $GLOBALS[ "Photoshop_ID_Descriptions" ][ 0x0404 ],
- "ResEmbeddedName" => "\x00\x00",
- "ResData" => put_IPTC( $new_IPTC_block ) );
-
-
- // Return the modified IRB
- return $Photoshop_IRB_data;
- }
-
- /******************************************************************************
- * End of Function: put_Photoshop_IPTC
- ******************************************************************************/
-
-
-
-
-
-
-
-
- /******************************************************************************
- *
- * Function: Interpret_IRB_to_HTML
- *
- * Description: Generates html showing the information contained in a Photoshop
- * IRB data array, as retrieved with get_Photoshop_IRB, including
- * any IPTC-NAA IIM records found.
- *
- * Please note that the following resource numbers are not currently
- * decoded: ( Many of these do not apply to JPEG images)
- * 0x03E9, 0x03EE, 0x03EF, 0x03F0, 0x03F1, 0x03F2, 0x03F6, 0x03F9,
- * 0x03FA, 0x03FB, 0x03FD, 0x03FE, 0x0400, 0x0401, 0x0402, 0x0405,
- * 0x040E, 0x040F, 0x0410, 0x0412, 0x0413, 0x0415, 0x0416, 0x0417,
- * 0x041B, 0x041C, 0x041D, 0x0BB7
- *
- * ( Also these Obsolete resource numbers)
- * 0x03E8, 0x03EB, 0x03FC, 0x03FF, 0x0403
- *
- *
- * Parameters: IRB_array - a Photoshop IRB data array as from get_Photoshop_IRB
- * filename - the name of the JPEG file being processed ( used
- * by the script which displays the Photoshop thumbnail)
- *
- *
- * Returns: output_str - the HTML string
- *
- ******************************************************************************/
-
- function Interpret_IRB_to_HTML( $IRB_array, $filename )
- {
- // Create a string to receive the HTML
- $output_str = "";
-
- // Check if the Photoshop IRB array is valid
- if ( $IRB_array !== FALSE )
- {
-
- // Create another string to receive secondary HTML to be appended at the end
- $secondary_output_str = "";
-
- // Add the Heading to the HTML
- $output_str .= "<h2 class=\"Photoshop_Main_Heading\">Contains Photoshop Information Resource Block (IRB)</h2>";
-
- // Add Table to the HTML
- $output_str .= "<table class=\"Photoshop_Table\" border=1>\n";
-
- // Cycle through each of the Photoshop IRB records, creating HTML for each
- foreach( $IRB_array as $IRB_Resource )
- {
- // Check if the entry is a known Photoshop IRB resource
-
- // Get the Name of the Resource
- if ( array_key_exists( $IRB_Resource['ResID'], $GLOBALS[ "Photoshop_ID_Names" ] ) )
- {
- $Resource_Name = $GLOBALS['Photoshop_ID_Names'][ $IRB_Resource['ResID'] ];
- }
- else
- {
- // Change: Added check for $GLOBALS['HIDE_UNKNOWN_TAGS'] to allow hiding of unknown resources as of 1.11
- if ( $GLOBALS['HIDE_UNKNOWN_TAGS'] == TRUE )
- {
- continue;
- }
- else
- {
- // Unknown Resource - Make appropriate name
- $Resource_Name = "Unknown Resource (". $IRB_Resource['ResID'] .")";
- }
- }
-
- // Add HTML for the resource as appropriate
- switch ( $IRB_Resource['ResID'] )
- {
-
- case 0x0404 : // IPTC-NAA IIM Record
- $secondary_output_str .= Interpret_IPTC_to_HTML( get_IPTC( $IRB_Resource['ResData'] ) );
- break;
-
- case 0x040B : // URL
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><a href=\"" . $IRB_Resource['ResData'] . "\">" . htmlentities( $IRB_Resource['ResData'] ) ."</a></td></tr>\n";
- break;
-
- case 0x040A : // Copyright Marked
- if ( hexdec( bin2hex( $IRB_Resource['ResData'] ) ) == 1 )
- {
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>Image is Copyrighted Material</pre></td></tr>\n";
- }
- else
- {
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>Image is Not Copyrighted Material</pre></td></tr>\n";
- }
- break;
-
- case 0x040D : // Global Lighting Angle
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>Global lighting angle for effects layer = " . hexdec( bin2hex( $IRB_Resource['ResData'] ) ) . " degrees</pre></td></tr>\n";
- break;
-
- case 0x0419 : // Global Altitude
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>Global Altitude = " . hexdec( bin2hex( $IRB_Resource['ResData'] ) ) . "</pre></td></tr>\n";
- break;
-
- case 0x0421 : // Version Info
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>\n";
- $output_str .= "Version = " . hexdec( bin2hex( substr( $IRB_Resource['ResData'], 0, 4 ) ) ) . "\n";
- $output_str .= "Has Real Merged Data = " . ord( $IRB_Resource['ResData']{4} ) . "\n";
- $writer_size = hexdec( bin2hex( substr( $IRB_Resource['ResData'], 5, 4 ) ) ) * 2;
-
- $output_str .= "Writer Name = " . HTML_UTF16_Escape( substr( $IRB_Resource['ResData'], 9, $writer_size ), TRUE ) . "\n";
- $reader_size = hexdec( bin2hex( substr( $IRB_Resource['ResData'], 9 + $writer_size , 4 ) ) ) * 2;
- $output_str .= "Reader Name = " . HTML_UTF16_Escape( substr( $IRB_Resource['ResData'], 13 + $writer_size, $reader_size ), TRUE ) . "\n";
- $output_str .= "File Version = " . hexdec( bin2hex( substr( $IRB_Resource['ResData'], 13 + $writer_size + $reader_size, 4 ) ) ) . "\n";
- $output_str .= "</pre></td></tr>\n";
- break;
-
- case 0x0411 : // ICC Untagged
- if ( $IRB_Resource['ResData'] == "\x01" )
- {
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>Intentionally untagged - any assumed ICC profile handling disabled</pre></td></tr>\n";
- }
- else
- {
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>Unknown value (0x" .bin2hex( $IRB_Resource['ResData'] ). ")</pre></td></tr>\n";
- }
- break;
-
- case 0x041A : // Slices
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\">";
-
- // Unpack the first 24 bytes
- $Slices_Info = unpack("NVersion/NBound_top/NBound_left/NBound_bottom/NBound_right/NStringlen", $IRB_Resource['ResData'] );
- $output_str .= "Version = " . $Slices_Info['Version'] . "<br>\n";
- $output_str .= "Bounding Rectangle = Top:" . $Slices_Info['Bound_top'] . ", Left:" . $Slices_Info['Bound_left'] . ", Bottom:" . $Slices_Info['Bound_bottom'] . ", Right:" . $Slices_Info['Bound_right'] . " (Pixels)<br>\n";
- $Slicepos = 24;
-
- // Extract a Unicode String
- $output_str .= "Text = '" . HTML_UTF16_Escape( substr( $IRB_Resource['ResData'], 24, $Slices_Info['Stringlen']*2), TRUE ) . "'<br>\n";
- $Slicepos += $Slices_Info['Stringlen'] * 2;
-
- // Unpack the number of Slices
- $Num_Slices = hexdec( bin2hex( substr( $IRB_Resource['ResData'], $Slicepos, 4 ) ) );
- $output_str .= "Number of Slices = " . $Num_Slices . "\n";
- $Slicepos += 4;
-
- // Cycle through the slices
- for( $i = 1; $i <= $Num_Slices; $i++ )
- {
- $output_str .= "<br><br>Slice $i:<br>\n";
-
- // Unpack the first 16 bytes of the slice
- $SliceA = unpack("NID/NGroupID/NOrigin/NStringlen", substr($IRB_Resource['ResData'], $Slicepos ) );
- $Slicepos += 16;
- $output_str .= "ID = " . $SliceA['ID'] . "<br>\n";
- $output_str .= "Group ID = " . $SliceA['GroupID'] . "<br>\n";
- $output_str .= "Origin = " . $SliceA['Origin'] . "<br>\n";
-
- // Extract a Unicode String
- $output_str .= "Text = '" . HTML_UTF16_Escape( substr( $IRB_Resource['ResData'], $Slicepos, $SliceA['Stringlen']*2), TRUE ) . "'<br>\n";
- $Slicepos += $SliceA['Stringlen'] * 2;
-
- // Unpack the next 24 bytes of the slice
- $SliceB = unpack("NType/NLeftPos/NTopPos/NRightPos/NBottomPos/NURLlen", substr($IRB_Resource['ResData'], $Slicepos ) );
- $Slicepos += 24;
- $output_str .= "Type = " . $SliceB['Type'] . "<br>\n";
- $output_str .= "Position = Top:" . $SliceB['TopPos'] . ", Left:" . $SliceB['LeftPos'] . ", Bottom:" . $SliceB['BottomPos'] . ", Right:" . $SliceB['RightPos'] . " (Pixels)<br>\n";
-
- // Extract a Unicode String
- $output_str .= "URL = <a href='" . substr( $IRB_Resource['ResData'], $Slicepos, $SliceB['URLlen']*2) . "'>" . HTML_UTF16_Escape( substr( $IRB_Resource['ResData'], $Slicepos, $SliceB['URLlen']*2), TRUE ) . "</a><br>\n";
- $Slicepos += $SliceB['URLlen'] * 2;
-
- // Unpack the length of a Unicode String
- $Targetlen = hexdec( bin2hex( substr( $IRB_Resource['ResData'], $Slicepos, 4 ) ) );
- $Slicepos += 4;
- // Extract a Unicode String
- $output_str .= "Target = '" . HTML_UTF16_Escape( substr( $IRB_Resource['ResData'], $Slicepos, $Targetlen*2), TRUE ) . "'<br>\n";
- $Slicepos += $Targetlen * 2;
-
- // Unpack the length of a Unicode String
- $Messagelen = hexdec( bin2hex( substr( $IRB_Resource['ResData'], $Slicepos, 4 ) ) );
- $Slicepos += 4;
- // Extract a Unicode String
- $output_str .= "Message = '" . HTML_UTF16_Escape( substr( $IRB_Resource['ResData'], $Slicepos, $Messagelen*2), TRUE ) . "'<br>\n";
- $Slicepos += $Messagelen * 2;
-
- // Unpack the length of a Unicode String
- $AltTaglen = hexdec( bin2hex( substr( $IRB_Resource['ResData'], $Slicepos, 4 ) ) );
- $Slicepos += 4;
- // Extract a Unicode String
- $output_str .= "Alt Tag = '" . HTML_UTF16_Escape( substr( $IRB_Resource['ResData'], $Slicepos, $AltTaglen*2), TRUE ) . "'<br>\n";
- $Slicepos += $AltTaglen * 2;
-
- // Unpack the HTML flag
- if ( ord( $IRB_Resource['ResData']{ $Slicepos } ) === 0x01 )
- {
- $output_str .= "Cell Text is HTML<br>\n";
- }
- else
- {
- $output_str .= "Cell Text is NOT HTML<br>\n";
- }
- $Slicepos++;
-
- // Unpack the length of a Unicode String
- $CellTextlen = hexdec( bin2hex( substr( $IRB_Resource['ResData'], $Slicepos, 4 ) ) );
- $Slicepos += 4;
- // Extract a Unicode String
- $output_str .= "Cell Text = '" . HTML_UTF16_Escape( substr( $IRB_Resource['ResData'], $Slicepos, $CellTextlen*2), TRUE ) . "'<br>\n";
- $Slicepos += $CellTextlen * 2;
-
-
- // Unpack the last 12 bytes of the slice
- $SliceC = unpack("NAlignH/NAlignV/CAlpha/CRed/CGreen/CBlue", substr($IRB_Resource['ResData'], $Slicepos ) );
- $Slicepos += 12;
- $output_str .= "Alignment = Horizontal:" . $SliceC['AlignH'] . ", Vertical:" . $SliceC['AlignV'] . "<br>\n";
- $output_str .= "Alpha Colour = " . $SliceC['Alpha'] . "<br>\n";
- $output_str .= "Red = " . $SliceC['Red'] . "<br>\n";
- $output_str .= "Green = " . $SliceC['Green'] . "<br>\n";
- $output_str .= "Blue = " . $SliceC['Blue'] . "\n";
- }
-
- $output_str .= "</td></tr>\n";
-
- break;
-
-
- case 0x0408 : // Grid and Guides information
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\">";
-
- // Unpack the Grids info
- $Grid_Info = unpack("NVersion/NGridCycleH/NGridCycleV/NGuideCount", $IRB_Resource['ResData'] );
- $output_str .= "Version = " . $Grid_Info['Version'] . "<br>\n";
- $output_str .= "Grid Cycle = " . $Grid_Info['GridCycleH']/32 . " Pixel(s) x " . $Grid_Info['GridCycleV']/32 . " Pixel(s)<br>\n";
- $output_str .= "Number of Guides = " . $Grid_Info['GuideCount'] . "\n";
-
- // Cycle through the Guides
- for( $i = 0; $i < $Grid_Info['GuideCount']; $i++ )
- {
- // Unpack the info for this guide
- $Guide_Info = unpack("NLocation/CDirection", substr($IRB_Resource['ResData'],16+$i*5,5) );
- $output_str .= "<br>Guide $i : Location = " . $Guide_Info['Location']/32 . " Pixel(s) from edge";
- if ( $Guide_Info['Direction'] === 0 )
- {
- $output_str .= ", Vertical\n";
- }
- else
- {
- $output_str .= ", Horizontal\n";
- }
- }
- break;
- $output_str .= "</td></tr>\n";
-
- case 0x0406 : // JPEG Quality
- $Qual_Info = unpack("nQuality/nFormat/nScans/Cconst", $IRB_Resource['ResData'] );
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\">";
- switch ( $Qual_Info['Quality'] )
- {
- case 0xFFFD:
- $output_str .= "Quality 1 (Low)<br>\n";
- break;
- case 0xFFFE:
- $output_str .= "Quality 2 (Low)<br>\n";
- break;
- case 0xFFFF:
- $output_str .= "Quality 3 (Low)<br>\n";
- break;
- case 0x0000:
- $output_str .= "Quality 4 (Low)<br>\n";
- break;
- case 0x0001:
- $output_str .= "Quality 5 (Medium)<br>\n";
- break;
- case 0x0002:
- $output_str .= "Quality 6 (Medium)<br>\n";
- break;
- case 0x0003:
- $output_str .= "Quality 7 (Medium)<br>\n";
- break;
- case 0x0004:
- $output_str .= "Quality 8 (High)<br>\n";
- break;
- case 0x0005:
- $output_str .= "Quality 9 (High)<br>\n";
- break;
- case 0x0006:
- $output_str .= "Quality 10 (Maximum)<br>\n";
- break;
- case 0x0007:
- $output_str .= "Quality 11 (Maximum)<br>\n";
- break;
- case 0x0008:
- $output_str .= "Quality 12 (Maximum)<br>\n";
- break;
- default:
- $output_str .= "Unknown Quality (" . $Qual_Info['Quality'] . ")<br>\n";
- break;
- }
-
- switch ( $Qual_Info['Format'] )
- {
- case 0x0000:
- $output_str .= "Standard Format\n";
- break;
- case 0x0001:
- $output_str .= "Optimised Format\n";
- break;
- case 0x0101:
- $output_str .= "Progressive Format<br>\n";
- break;
- default:
- $output_str .= "Unknown Format (" . $Qual_Info['Format'] .")\n";
- break;
- }
- if ( $Qual_Info['Format'] == 0x0101 )
- {
- switch ( $Qual_Info['Scans'] )
- {
- case 0x0001:
- $output_str .= "3 Scans\n";
- break;
- case 0x0002:
- $output_str .= "4 Scans\n";
- break;
- case 0x0003:
- $output_str .= "5 Scans\n";
- break;
- default:
- $output_str .= "Unknown number of scans (" . $Qual_Info['Scans'] .")\n";
- break;
- }
- }
- $output_str .= "</td></tr>\n";
- break;
-
- case 0x0409 : // Thumbnail Resource
- case 0x040C : // Thumbnail Resource
- $thumb_data = unpack("NFormat/NWidth/NHeight/NWidthBytes/NSize/NCompressedSize/nBitsPixel/nPlanes", $IRB_Resource['ResData'] );
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>\n";
- $output_str .= "Format = " . (( $thumb_data['Format'] == 1 ) ? "JPEG RGB\n" : "Raw RGB\n");
- $output_str .= "Width = " . $thumb_data['Width'] . "\n";
- $output_str .= "Height = " . $thumb_data['Height'] . "\n";
- $output_str .= "Padded Row Bytes = " . $thumb_data['WidthBytes'] . " bytes\n";
- $output_str .= "Total Size = " . $thumb_data['Size'] . " bytes\n";
- $output_str .= "Compressed Size = " . $thumb_data['CompressedSize'] . " bytes\n";
- $output_str .= "Bits per Pixel = " . $thumb_data['BitsPixel'] . " bits\n";
- $output_str .= "Number of planes = " . $thumb_data['Planes'] . " bytes\n";
-
- // Change: as of version 1.11 - Changed to make thumbnail link portable across directories
- // Build the path of the thumbnail script and its filename parameter to put in a url
- $link_str = get_relative_path( dirname(__FILE__) . "/get_ps_thumb.php" , getcwd ( ) );
- $link_str .= "?filename=";
- $link_str .= get_relative_path( $filename, dirname(__FILE__) );
-
- // Add thumbnail link to html
- $output_str .= "Thumbnail Data:</pre><a class=\"Photoshop_Thumbnail_Link\" href=\"$link_str\"><img class=\"Photoshop_Thumbnail_Link\" src=\"$link_str\"></a>\n";
-
- $output_str .= "</td></tr>\n";
- break;
-
- case 0x0414 : // Document Specific ID's
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>" . hexdec( bin2hex( $IRB_Resource['ResData'] ) ) . "</pre></td></tr>\n";
- break;
-
- case 0x041E : // URL List
- $URL_count = hexdec( bin2hex( substr( $IRB_Resource['ResData'], 0, 4 ) ) );
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\">\n";
- $output_str .= "$URL_count URL's in list<br>\n";
- $urlstr = substr( $IRB_Resource['ResData'], 4 );
- // TODO: Check if URL List in Photoshop IRB works
- for( $i = 0; $i < $URL_count; $i++ )
- {
- $url_data = unpack( "NLong/NID/NURLSize", $urlstr );
- $output_str .= "URL $i info: long = " . $url_data['Long'] .", ";
- $output_str .= "ID = " . $url_data['ID'] . ", ";
- $urlstr = substr( $urlstr, 12 );
- $url = substr( $urlstr, 0, $url_data['URLSize'] );
- $output_str .= "URL = <a href=\"" . xml_UTF16_clean( $url, TRUE ) . "\">" . HTML_UTF16_Escape( $url, TRUE ) . "</a><br>\n";
- }
- $output_str .= "</td></tr>\n";
- break;
- case 0x03F4 : // Grayscale and multichannel halftoning information.
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>\n";
- $output_str .= Interpret_Halftone( $IRB_Resource['ResData'] );
- $output_str .= "</pre></td></tr>\n";
- break;
- case 0x03F5 : // Color halftoning information
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>\n";
- $output_str .= "Cyan Halftoning Info:\n" . Interpret_Halftone( substr( $IRB_Resource['ResData'], 0, 18 ) ) . "\n\n";
- $output_str .= "Magenta Halftoning Info:\n" . Interpret_Halftone( substr( $IRB_Resource['ResData'], 18, 18 ) ) . "\n\n";
- $output_str .= "Yellow Halftoning Info:\n" . Interpret_Halftone( substr( $IRB_Resource['ResData'], 36, 18 ) ) . "\n";
- $output_str .= "Black Halftoning Info:\n" . Interpret_Halftone( substr( $IRB_Resource['ResData'], 54, 18 ) ) . "\n";
- $output_str .= "</pre></td></tr>\n";
- break;
-
- case 0x03F7 : // Grayscale and multichannel transfer function.
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>\n";
- $output_str .= Interpret_Transfer_Function( substr( $IRB_Resource['ResData'], 0, 28 ) ) ;
- $output_str .= "</pre></td></tr>\n";
- break;
-
- case 0x03F8 : // Color transfer functions
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>\n";
- $output_str .= "Red Transfer Function: \n" . Interpret_Transfer_Function( substr( $IRB_Resource['ResData'], 0, 28 ) ) . "\n\n";
- $output_str .= "Green Transfer Function: \n" . Interpret_Transfer_Function( substr( $IRB_Resource['ResData'], 28, 28 ) ) . "\n\n";
- $output_str .= "Blue Transfer Function: \n" . Interpret_Transfer_Function( substr( $IRB_Resource['ResData'], 56, 28 ) ) . "\n";
- $output_str .= "</pre></td></tr>\n";
- break;
-
- case 0x03F3 : // Print Flags
- $output_str .= "<tr class=\"Photoshop_Table_Row\"><td class=\"Photoshop_Caption_Cell\">$Resource_Name</td><td class=\"Photoshop_Value_Cell\"><pre>\n";
- if ( $IRB_Resource['ResData']{0} == "\x01" )
- {
- $output_str .= "Labels Selected\n";
- }
- else
- {
- $output_str .= "Labels Not Selected\n";
- }
- if ( $IRB_Resource['ResData']{1} == "\x01" )
- {
- $output_str .= "Crop Marks Selected\n";
- }
- else
- {
- $output_str .= "Crop Marks Not Selected\n";
- }
- if ( $IRB_Resource['ResData']{2} == "\x01" )
- {
- $output_str .= "Color Bars Selected\n";
- }
- else
- {
- $output_str .= "Color Bars Not Selected\n";
- }
- if ( $IRB_Resource['ResData']{3} == "\x01" )
- {
- $output_str .= "Registration Marks Selected\n";…
Large files files are truncated, but you can click here to view the full file