This repository has been archived on 2024-11-28. You can view files and clone it, but cannot push or open issues or pull requests.
MatritumCantat_Web/www/components/com_zoom/classes/iptc/JFIF.php

427 lines
19 KiB
PHP
Raw Normal View History

<?php
/******************************************************************************
*
* Filename: JFIF.php
*
* Description: Provides functions for reading and writing information to/from
* JPEG File Interchange Format (JFIF) segments and
* JFIF Extension (JFXX) segments within a JPEG file.
*
* Author: Evan Hunter
*
* Date: 24/7/2004
*
* Project: PHP JPEG Metadata Toolkit
*
* Revision: 1.00
*
* 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
*
******************************************************************************/
/******************************************************************************
*
* Function: get_JFIF
*
* Description: Retrieves information from a JPEG File Interchange Format (JFIF)
* segment and returns it in an array. 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: JFIF_data - an array of JFIF data
* FALSE - if a JFIF segment could not be found
*
******************************************************************************/
function get_JFIF( $jpeg_header_data )
{
//Cycle through the header segments
for( $i = 0; $i < count( $jpeg_header_data ); $i++ )
{
// If we find an APP0 header,
if ( strcmp ( $jpeg_header_data[$i]['SegName'], "APP0" ) == 0 )
{
// And if it has the JFIF label,
if( strncmp ( $jpeg_header_data[$i]['SegData'], "JFIF\x00", 5) == 0 )
{
// Found a JPEG File Interchange Format (JFIF) Block
// unpack the JFIF data from the incoming string
// First is the JFIF label string
// Then a two byte version number
// Then a byte, units identifier, ( 0 = aspect ration, 1 = dpi, 2 = dpcm)
// Then a two byte int X-Axis pixel Density (resolution)
// Then a two byte int Y-Axis pixel Density (resolution)
// Then a byte X-Axis JFIF thumbnail size
// Then a byte Y-Axis JFIF thumbnail size
// Then the uncompressed RGB JFIF thumbnail data
$JFIF_data = unpack( 'a5JFIF/C2Version/CUnits/nXDensity/nYDensity/CThumbX/CThumbY/a*ThumbData', $jpeg_header_data[$i]['SegData'] );
return $JFIF_data;
}
}
}
return FALSE;
}
/******************************************************************************
* End of Function: get_JFIF
******************************************************************************/
/******************************************************************************
*
* Function: put_JFIF
*
* Description: Creates a new JFIF segment from an array of JFIF data in the
* same format as would be retrieved from get_JFIF, and inserts
* this segment into the supplied JPEG header array
*
* Parameters: jpeg_header_data - a JPEG header data array in the same format
* as from get_jpeg_header_data, into which the
* new JFIF segment will be put
* new_JFIF_array - a JFIF information array in the same format as
* from get_JFIF, to create the new segment
*
* Returns: jpeg_header_data - the JPEG header data array with the new
* JFIF segment added
*
******************************************************************************/
function put_JFIF( $jpeg_header_data, $new_JFIF_array )
{
// pack the JFIF data into its proper format for a JPEG file
$packed_data = pack( 'a5CCCnnCCa*',"JFIF\x00", $new_JFIF_array['Version1'], $new_JFIF_array['Version2'], $new_JFIF_array['Units'], $new_JFIF_array['XDensity'], $new_JFIF_array['YDensity'], $new_JFIF_array['ThumbX'], $new_JFIF_array['ThumbY'], $new_JFIF_array['ThumbData'] );
//Cycle through the header segments
for( $i = 0; $i < count( $jpeg_header_data ); $i++ )
{
// If we find an APP0 header,
if ( strcmp ( $jpeg_header_data[$i]['SegName'], "APP0" ) == 0 )
{
// And if it has the JFIF label,
if( strncmp ( $jpeg_header_data[$i]['SegData'], "JFIF\x00", 5) == 0 )
{
// Found a preexisting JFIF block - Replace it with the new one and return.
$jpeg_header_data[$i]['SegData'] = $packed_data;
return $jpeg_header_data;
}
}
}
// No preexisting JFIF block found, insert a new one at the start of the header data.
array_splice($jpeg_header_data, 0 , 0, array( array( "SegType" => 0xE0,
"SegName" => "APP0",
"SegDesc" => $GLOBALS[ "JPEG_Segment_Descriptions" ][ 0xE0 ],
"SegData" => $packed_data ) ) );
return $jpeg_header_data;
}
/******************************************************************************
* End of Function: put_JFIF
******************************************************************************/
/******************************************************************************
*
* Function: Interpret_JFIF_to_HTML
*
* Description: Generates html showing the JFIF information contained in
* a JFIF data array, as retrieved with get_JFIF
*
* Parameters: JFIF_array - a JFIF data array, as from get_JFIF
* filename - the name of the JPEG file being processed ( used
* by the script which displays the JFIF thumbnail)
*
*
* Returns: output - the HTML string
*
******************************************************************************/
function Interpret_JFIF_to_HTML( $JFIF_array, $filename )
{
$output = "";
if ( $JFIF_array !== FALSE )
{
$output .= "<H2 class=\"JFIF_Main_Heading\">Contains JPEG File Interchange Format (JFIF) Information</H2>\n";
$output .= "\n<table class=\"JFIF_Table\" border=1>\n";
$output .= "<tr class=\"JFIF_Table_Row\"><td class=\"JFIF_Caption_Cell\">JFIF version: </td><td class=\"JFIF_Value_Cell\">". sprintf( "%d.%02d", $JFIF_array['Version1'], $JFIF_array['Version2'] ) . "</td></tr>\n";
if ( $JFIF_array['Units'] == 0 )
{
$output .= "<tr class=\"JFIF_Table_Row\"><td class=\"JFIF_Caption_Cell\">Pixel Aspect Ratio: </td><td class=\"JFIF_Value_Cell\">" . $JFIF_array['XDensity'] ." x " . $JFIF_array['YDensity'] . "</td></tr>\n";
}
elseif ( $JFIF_array['Units'] == 1 )
{
$output .= "<tr class=\"JFIF_Table_Row\"><td class=\"JFIF_Caption_Cell\">Resolution: </td><td class=\"JFIF_Value_Cell\">" . $JFIF_array['XDensity'] ." x " . $JFIF_array['YDensity'] . " pixels per inch</td></tr>\n";
}
elseif ( $JFIF_array['Units'] == 2 )
{
$output .= "<tr class=\"JFIF_Table_Row\"><td class=\"JFIF_Caption_Cell\">Resolution: </td><td class=\"JFIF_Value_Cell\">" . $JFIF_array['XDensity'] ." x " . $JFIF_array['YDensity'] . " pixels per cm</td></tr>\n";
}
$output .= "<tr class=\"JFIF_Table_Row\"><td class=\"JFIF_Caption_Cell\">JFIF (uncompressed) thumbnail: </td><td class=\"JFIF_Value_Cell\">";
if ( ( $JFIF_array['ThumbX'] != 0 ) && ( $JFIF_array['ThumbY'] != 0 ) )
{
$output .= $JFIF_array['ThumbX'] ." x " . $JFIF_array['ThumbY'] . " pixels, Thumbnail Display Not Yet Implemented</td></tr>\n";
// TODO Implement JFIF Thumbnail display
}
else
{
$output .= "None</td></tr>\n";
}
$output .= "</table><br>\n";
}
return $output;
}
/******************************************************************************
* End of Function: Interpret_JFIF_to_HTML
******************************************************************************/
/******************************************************************************
*
* Function: get_JFXX
*
* Description: Retrieves information from a JPEG File Interchange Format Extension (JFXX)
* segment and returns it in an array. 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: JFXX_data - an array of JFXX data
* FALSE - if a JFXX segment could not be found
*
******************************************************************************/
function get_JFXX( $jpeg_header_data )
{
//Cycle through the header segments
for( $i = 0; $i < count( $jpeg_header_data ); $i++ )
{
// If we find an APP0 header,
if ( strcmp ( $jpeg_header_data[$i]['SegName'], "APP0" ) == 0 )
{
// And if it has the JFIF label,
if( strncmp ( $jpeg_header_data[$i]['SegData'], "JFXX\x00", 5) == 0 )
{
// Found a JPEG File Interchange Format Extension (JFXX) Block
// unpack the JFXX data from the incoming string
// First is the 5 byte JFXX label string
// Then a 1 byte Extension code, indicating Thumbnail Format
// Then the thumbnail data
$JFXX_data = unpack( 'a5JFXX/CExtension_Code/a*ThumbData', $jpeg_header_data[$i]['SegData'] );
return $JFXX_data;
}
}
}
return FALSE;
}
/******************************************************************************
* End of Function: get_JFXX
******************************************************************************/
/******************************************************************************
*
* Function: put_JFXX
*
* Description: Creates a new JFXX segment from an array of JFXX data in the
* same format as would be retrieved from get_JFXX, and inserts
* this segment into the supplied JPEG header array
*
* Parameters: jpeg_header_data - a JPEG header data array in the same format
* as from get_jpeg_header_data, into which the
* new JFXX segment will be put
* new_JFXX_array - a JFXX information array in the same format as
* from get_JFXX, to create the new segment
*
* Returns: jpeg_header_data - the JPEG header data array with the new
* JFXX segment added
*
******************************************************************************/
function put_JFXX( $jpeg_header_data, $new_JFXX_array )
{
// pack the JFXX data into its proper format for a JPEG file
$packed_data = pack( 'a5Ca*',"JFXX\x00", $new_JFXX_array['Extension_Code'], $new_JFXX_array['ThumbData'] );
$JFIF_pos = -1;
//Cycle through the header segments
for( $i = 0; $i < count( $jpeg_header_data ); $i++ )
{
// If we find an APP0 header,
if ( strcmp ( $jpeg_header_data[$i]['SegName'], "APP0" ) == 0 )
{
// And if it has the JFXX label,
if( strncmp ( $jpeg_header_data[$i]['SegData'], "JFXX\x00", 5) == 0 )
{
// Found a preexisting JFXX block - Replace it with the new one and return.
$jpeg_header_data[$i]['SegData'] = $packed_data;
return $jpeg_header_data;
}
// if it has the JFIF label,
if( strncmp ( $jpeg_header_data[$i][SegData], "JFIF\x00", 5) == 0 )
{
// Found a preexisting JFIF block - Mark it in case we need to insert the JFXX after it
$JFIF_pos = $i;
}
}
}
// No preexisting JFXX block found
// Check if a JFIF segment was found,
if ( $JFIF_pos !== -1 )
{
// A pre-existing JFIF segment was found,
// insert the new JFXX segment after it.
array_splice($jpeg_header_data, $JFIF_pos +1 , 0, array ( array( "SegType" => 0xE0,
"SegName" => "APP0",
"SegDesc" => $GLOBALS[ "JPEG_Segment_Descriptions" ][ 0xE0 ],
"SegData" => $packed_data ) ) );
}
else
{
// No pre-existing JFIF segment was found,
// insert a new JFIF and the new JFXX segment at the start of the array.
// Insert new JFXX segment
array_splice($jpeg_header_data, 0 , 0, array( array( "SegType" => 0xE0,
"SegName" => "APP0",
"SegDesc" => $GLOBALS[ "JPEG_Segment_Descriptions" ][ 0xE0 ],
"SegData" => $packed_data ) ) );
// Create a new JFIF to be inserted at the start of
// the array, with generic values
$packed_data = pack( 'a5CCCnnCCa*',"JFIF\x00", 1, 2, 1, 72, 72, 0, 0, "" );
array_splice($jpeg_header_data, 0 , 0, array( array( "SegType" => 0xE0,
"SegName" => "APP0",
"SegDesc" => $GLOBALS[ "JPEG_Segment_Descriptions" ][ 0xE0 ],
"SegData" => $packed_data ) ) );
}
return $jpeg_header_data;
}
/******************************************************************************
* End of Function: put_JFIF
******************************************************************************/
/******************************************************************************
*
* Function: Interpret_JFXX_to_HTML
*
* Description: Generates html showing the JFXX thumbnail contained in
* a JFXX data array, as retrieved with get_JFXX
*
* Parameters: JFXX_array - a JFXX information array in the same format as
* from get_JFXX, to create the new segment
* filename - the name of the JPEG file being processed ( used
* by the script which displays the JFXX thumbnail)
*
* Returns: output - the Html string
*
******************************************************************************/
function Interpret_JFXX_to_HTML( $JFXX_array, $filename )
{
$output = "";
if ( $JFXX_array !== FALSE )
{
$output .= "<H2 class=\"JFXX_Main_Heading\">Contains JPEG File Interchange Extension Format (JFXX) Thumbnail</H2>\n";
switch ( $JFXX_array['Extension_Code'] )
{
case 0x10 : $output .= "<p class=\"JFXX_Text\">JFXX Thumbnail is JPEG Encoded</p>\n";
$output .= "<a class=\"JFXX_Thumbnail_Link\" href=\"get_jfxx_thumb.php?filename=$filename\"><img class=\"JFXX_Thumbnail\" src=\"get_jfxx_thumb.php?filename=$filename\"></a>\n";
break;
case 0x11 : $output .= "<p class=\"JFXX_Text\">JFXX Thumbnail is Encoded 1 byte/pixel</p>\n";
$output .= "<p class=\"JFXX_Text\">Thumbnail Display Not Implemented Yet</p>\n";
break;
case 0x13 : $output .= "<p class=\"JFXX_Text\">JFXX Thumbnail is Encoded 3 bytes/pixel</p>\n";
$output .= "<p class=\"JFXX_Text\">Thumbnail Display Not Implemented Yet</p>\n";
break;
default : $output .= "<p class=\"JFXX_Text\">JFXX Thumbnail is Encoded with Unknown format</p>\n";
break;
// TODO: Implement JFXX one and three bytes per pixel thumbnail decoding
}
}
return $output;
}
/******************************************************************************
* End of Function: Interpret_JFXX_to_HTML
******************************************************************************/
?>