| 
        php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
 PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             
             [2015-07-18 00:11 UTC] cmb@php.net
 
-Summary:          After you write IPTC several times
                   in the same JPEG file, the file is corrupted
+Summary:          Repeated iptcembed() corrupts JPEG
                   file
-Status:           Open
+Status:           Verified
-Operating System: Vista 64
+Operating System: *
-PHP Version:      5.3.5
+PHP Version:      5.6.11
-Assigned To:
+Assigned To:      cmb
  [2015-07-18 00:11 UTC] cmb@php.net
  [2015-07-18 00:11 UTC] cmb@php.net
  [2015-07-18 19:14 UTC] cmb@php.net
 
-Summary:          Repeated iptcembed() corrupts JPEG
                   file
+Summary:          After you write IPTC several times
                   in the same JPEG file, the file is corrupted
-Status:           Verified
+Status:           Feedback
-Operating System: *
+Operating System: Vista 64
-PHP Version:      5.6.11
+PHP Version:      5.3.5
  [2015-07-18 19:14 UTC] cmb@php.net
  [2015-07-26 04:22 UTC] php-bugs at lists dot php dot net
  | 
    |||||||||||||||||||||||||||||||||||||
            
                 
                Copyright © 2001-2025 The PHP GroupAll rights reserved.  | 
        Last updated: Tue Nov 04 01:00:02 2025 UTC | 
Description: ------------ Sometimes writing IPTC in a JPEG file seems to corrupt it. This behaviour happens after you write several times in the same file (after 10 to 20 times or so...). The consequence is that the next call to GetImageSize on this file will fail. I don't know if the problem comes from iptcembed or from GetImageSize. I am using Wampserver 2 with PHP 5.3.0 on Vista 64. Test script: --------------- <?php $file_path_and_name="020SC_BF0196D001_M.jpg"; $iptc_field_to_modify="2#005"; //Read IPTC from file if (!GetImageSize($file_path_and_name, $getimagesize_result)) { echo("GetImageSize error<br />"); die(); } //Handle return from GetImageSize if (!isset($getimagesize_result["APP13"])) $iptc_array=array(); else { //Get APP13 $iptcparse_result=iptcparse($getimagesize_result["APP13"]); if ($iptcparse_result===false) { echo("iptcparse error<br />"); die(); } //Handle iptcparse result $iptc_array=array(); foreach ($iptcparse_result as $iptcparse_index => &$iptcparse_value) { $iptc_array[$iptcparse_index]=""; for($i=0;$i<count($iptcparse_value);$i++) $iptc_array[$iptcparse_index].=($i<count($iptcparse_value)-1)?$iptcparse_value[$i].",":$iptcparse_value[$i]; } } //foreach($iptc_array as $index => $value) // echo($index." ".$value."<br />"); if (isset($iptc_array["2#005"])) echo($iptc_array["2#005"]."<br />"); //Modify the value in the IPTC array $iptc_array[$iptc_field_to_modify]=rand (1, 1000); //Transform the the IPTC array into a string to be used by iptcembed $string_for_iptcembed=""; foreach($iptc_array as $iptc_array_index => &$iptc_array_value) { $iptc_array_index=substr($iptc_array_index, 2); $length = strlen($iptc_array_value); $retval = chr(0x1C).chr(2).chr($iptc_array_index); if($length < 0x8000) $retval .= chr($length >> 8).chr($length& 0xFF); else{ $retval .= chr(0x80).chr(0x04). chr(($length >> 24)& 0xFF). chr(($length >> 16)& 0xFF). chr(($length >> 8)& 0xFF). chr($length& 0xFF); } $string_for_iptcembed.=$retval.$iptc_array_value; } //Call to iptcembed $binary_data=iptcembed($string_for_iptcembed, $file_path_and_name); if ($binary_data===false) { echo("iptcembed error<br />"); die(); } //TODO ??? It doesn't solve the problem anyway... //@unlink($file_path_and_name);//delete if exists //Open file for writing if (DIRECTORY_SEPARATOR=="/") $file = fopen($file_path_and_name, "w");//linux else if (DIRECTORY_SEPARATOR=="\\") $file = fopen($file_path_and_name, "wb");//windows if(!$file) { echo("fopen error<br />"); die(); } //Writing if (false===fwrite($file, $binary_data)) { echo("fwrite error<br />"); if(fclose($file)===false) echo("fclose error<br />"); die(); } //Close file if(fclose($file)===false) { echo("fclose error<br />"); die(); } //Let's check that everything went fine: //Sometimes writing IPTC in a JPEG file seems to corrupt it. //This behaviour happens after you write several times in the same file (after 10 to 20 times or so...). //The only solution I found to fix the problem: create a new file with imagecreatefromjpeg. But this has 2 main inconvenients: // - it takes long (3 to 4 seconds with a high res file) // - you loose every other metadata: XMP, EXIF... if(false===GetImageSize($file_path_and_name, $bogus)) { echo("!!!!!!!!!!!!!!!!!!!!!! GetImageSize error !!!!!!!!!!!!!!!!!!!!!!!!!!!<br />"); $image = imagecreatefromjpeg($file_path_and_name); if ($image===false) { echo("imagecreatefromjpeg error<br />"); die(); } if (false===imagejpeg($image, $file_path_and_name)) { echo("imagejpeg error<br />"); die(); } } ?> Expected result: ---------------- Each call should do exactly the same as the previous one : read and write IPTC metadata. Actual result: -------------- After several times, GetImageSize returns false.