From: Operating system: Vista 64 PHP version: 5.3.5 Package: GD related Bug Type: Bug Bug description:After you write IPTC several times in the same JPEG file, the file is corrupted
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. -- Edit bug report at http://bugs.php.net/bug.php?id=54173&edit=1 -- Try a snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=54173&r=trysnapshot52 Try a snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=54173&r=trysnapshot53 Try a snapshot (trunk): http://bugs.php.net/fix.php?id=54173&r=trysnapshottrunk Fixed in SVN: http://bugs.php.net/fix.php?id=54173&r=fixed Fixed in SVN and need be documented: http://bugs.php.net/fix.php?id=54173&r=needdocs Fixed in release: http://bugs.php.net/fix.php?id=54173&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=54173&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=54173&r=needscript Try newer version: http://bugs.php.net/fix.php?id=54173&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=54173&r=support Expected behavior: http://bugs.php.net/fix.php?id=54173&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=54173&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=54173&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=54173&r=globals PHP 4 support discontinued: http://bugs.php.net/fix.php?id=54173&r=php4 Daylight Savings: http://bugs.php.net/fix.php?id=54173&r=dst IIS Stability: http://bugs.php.net/fix.php?id=54173&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=54173&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=54173&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=54173&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=54173&r=mysqlcfg