Location: PHPKode > scripts > EasyPhpWipeJPG > wipejpg.php
<?php

/**

EasyPhpWipeJPG version 1.0.1 - PHP5
Remove all EXIF, IPTC & Comment information from JPG files

Copyright (c) 2011 JF Nutbroek <hide@address.com>
Visit http://www.mywebmymail.com for more information 

Permission to use, copy, modify, and/or distribute this software for any
purpose without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

*/

session_start();

// Turn error reporting off
error_reporting(0);

// Verify if browser supports inline images
if (!isset($_SESSION['RFC2397'])) {$_SESSION['RFC2397'] = get_rfc2397();}

// Verify if we need to make a backup
if (isset($_REQUEST['backup']))
	$_SESSION['wipe_backup'] = true;
else if (!isset($_SESSION['wipe_backup']))
	$_SESSION['wipe_backup'] = false;	

// Verify if we need to include subdirectories
if (isset($_REQUEST['subdir'])) 
	$_SESSION['wipe_subdir'] = true;
else if (!isset($_SESSION['wipe_subdir'])) 
	$_SESSION['wipe_subdir'] = false;	

// Determine directory structure 
if(isset($_REQUEST['analyze_structure'])) {
	$_SESSION['wipe_structure'] = array();
	$homedir = getcwd();
	$_SESSION['wipe_structure'][] = $homedir;
	if ($_SESSION['wipe_subdir']) {
		if ($dir = opendir($homedir)) {
			while ($dirname = readdir($dir)) {
				if (substr($dirname,0,1) != '.' && is_dir($homedir . '/' . $dirname)) {
					$_SESSION['wipe_structure'][] = $homedir . '/' . $dirname;
					structure($homedir . '/' . $dirname . '/');
				}
			}
		}
	}
}

// Find all JPG files
if(isset($_REQUEST['analyze_files'])) {
	$_SESSION['wipe_images'] = array();
	foreach($_SESSION['wipe_structure'] as $target_dir) {
		if ($dir = opendir($target_dir)) {
			while ($filename = readdir($dir)) {
				if (substr($dirname, 0, 1) != '.' && !is_dir($target_dir . '/' . $filename)) {
					$extension = strtolower(substr($filename, strrpos($filename,'.') + 1, strlen($filename)));
					if ($extension == 'jpg' || $extension == 'jpeg') {
						$_SESSION['wipe_images'][] = $target_dir . '/' . $filename;
					}
				}
			}
		}		
	}
	$_SESSION['wipe_total'] = count($_SESSION['wipe_images']);
	$_SESSION['wipe_bytes'] = 0;
	$_SESSION['wipe_wiped'] = 0;
	$_SESSION['wipe_log'] = array();
}

// Process and wipe JPG images - max. 4 seconds per batch
if(isset($_REQUEST['processing']) && !isset($_REQUEST['analyze_files'])) {
	$start = time();
	while ((time() - $start) < 4 && count($_SESSION['wipe_images']) > 0) {
		$lastkey = count($_SESSION['wipe_images']) - 1;
		$_SESSION['wipe_log'][] = wipe($_SESSION['wipe_images'][$lastkey], $_SESSION['wipe_images'][$lastkey], $_SESSION['wipe_backup']);
		array_pop($_SESSION['wipe_images']);
	}
}

// Restore original images
if (isset($_REQUEST['restore'])) {
	$all_images = array();
	foreach($_SESSION['wipe_structure'] as $target_dir) {
		if ($dir = opendir($target_dir)) {
			while ($filename = readdir($dir)) {
				if (substr($dirname, 0, 1) != '.' && !is_dir($target_dir . '/' . $filename)) {
					$extension = strtolower(substr($filename, strrpos($filename, '.') + 1, strlen($filename)));
					if (($extension == 'jpg' || $extension == 'jpeg') && strpos($filename, 'wipebackup_') !== false) {
						$all_images[] = $target_dir . '/' . $filename;
					}
				}
			}
		}		
	}
	foreach ($all_images as $image) {
		$real_name = substr(basename($image), 11, strlen(basename($image)));
		unlink(dirname($image) . '/' . $real_name);
		rename($image , dirname($image) . '/' . $real_name);
	}
}

// Remove backup images
if (isset($_REQUEST['remove'])) {
	foreach($_SESSION['wipe_structure'] as $target_dir) {
		if ($dir = opendir($target_dir)) {
			while ($filename = readdir($dir)) {
				if (substr($dirname, 0, 1) != '.' && !is_dir($target_dir . '/' . $filename)) {
					$extension = strtolower(substr($filename, strrpos($filename, '.') + 1, strlen($filename)));
					if (($extension == 'jpg' || $extension == 'jpeg') && strpos($filename, 'wipebackup_') !== false) {
						unlink($target_dir . '/' . $filename);
					}
				}
			}
		}		
	}
}

// The page head containing CSS code
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><title>EasyPhpWipeJPG &copy; 2011 www.mywebmymail.com</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style type="text/css">  
body {
    background-color   : #CDE;
    height             : 100%; 
    max-height         : 100%; 
    font-family        : Verdana, Helvetica, Arial, sans-serif;
    font-size          : 0.75em;
    color              : #666; 
}
#content {
    position           : fixed;
    width              : 800px;
    left               : 50px;
    top                : 25px;
    height             : auto;    
    overflow           : hidden; 
    margin             : 15px; 
    background-color   : #FFF; 
    padding            : 15px; 
    text-align         : center;   
}
.button {
  font-family          : Verdana, Helvetica, Arial, sans-serif;
  font-size            : 12px;  
  color                : #000;
  background-color     : #CDE;
  border               : 1px solid #000;
  padding              : 3px;
}
.topleft {
    position           : absolute;
    font-size          : 0;  
    left               : 0;    
    top                : 0; 
}
.topright {
    position           : absolute;
    font-size          : 0;     
    right              : 0;    
    top                : 0;     
}
.bottomleft {
    position           : absolute;
    font-size          : 0;  
    left               : 0;    
    bottom             : 0;       
}
.bottomright {
    position           : absolute;
    font-size          : 0;  
    right              : 0;    
    bottom             : 0;      
}
a:link,a:visited {
    color              : #666;
    text-decoration    : none;
}
a:hover {
    text-decoration    : underline;
}
</style>
<?

// Determine if we are batch processing images
if (isset($_REQUEST['processing']) || isset($_REQUEST['analyze_structure'])) {
	echo "</head><body onload=\"javascript: setTimeout('document.forms[0].submit();',1000);\">\n";  
} else {
	echo "</head><body>\n";
}

// Start of page
echo "<div id=\"content\">\n";
echo "<form method=\"post\" action=\"wipejpg.php\" enctype=\"multipart/form-data\">";
echo "<div class=\"topleft\">" .  topleftsprite() . "</div>\n";
echo "<div class=\"topright\">" .  toprightsprite() . "</div>\n";

// Welcome page
if (!isset($_REQUEST['processing']) && !isset($_REQUEST['cancel']) && !isset($_REQUEST['restore']) && !isset($_REQUEST['remove']) && !isset($_REQUEST['complete']) && !isset($_REQUEST['analyze_structure'])) {
	unset($_SESSION['wipe_backup']);
	unset($_SESSION['wipe_subdir']);
	echo '<strong>Welcome to EasyPhpWipeJPG !</strong><p>This script will remove all EXIF, IPTC & Comment information from JPG images.';
	echo '<br />The resulting image will be 100% identical to the original image, without any quality loss (binary wipe).<p><strong>Why shoud you remove EXIF, IPTC & Comment information?</strong></p>';
	echo '<ul><li><em>For privacy considerations</em><br />The image might contain sensitive data (camera brand, model, GPS location, etc.)</li>';
	echo '<p><li><em>For SEO considerations</em><br />Unwanted tags from manufacturers like "LEAD Technologies Inc. V1.01"</li></p>';
	echo '<p><li><em>To reduce filesize</em><br />If you have many images online, it is a waste of harddisc capacity</li></p></ul>';
	echo '<strong>Configure the options below and start cleaning up your JPG images!</strong><p>';
	echo '<input type="checkbox" name="backup" value="backup" /> Backup the original images (you may restore or remove them later)<br />';
	echo '<input type="checkbox" name="subdir" value="subdir" checked="checked" /> Search and include images from the entire subdirectory structure';
	echo '<p><input type="submit" name="Submit" class="button" value="Start Wipe!" onclick="this.value=\'Please wait...\';" onmouseover="this.style.cursor=\'pointer\'" /><input type="hidden" name="analyze_structure" value="now!"></p>';
}

// Analyze directory structure page
if (isset($_REQUEST['analyze_structure'])) {
	echo '<strong>EasyPhpWipeJPG is searching for images!</strong>';
	echo '<p>Detected ' .  (count($_SESSION['wipe_structure']) - 1)  .  ' directories<br />';
	echo '<p><strong>Please wait ...</strong></p>';
	echo '<input type="hidden" name="analyze_files" value="inprogress"><input type="hidden" name="processing" value="inprogress">';
	echo '<p><input type="button" class="button" value="Cancel!" onclick="location.href=(\'wipejpg.php?cancel=true\');" onmouseover="this.style.cursor=\'pointer\'" /></p>';
}

// Batch processing page
if (isset($_REQUEST['processing'])) {
	echo '<strong>EasyPhpWipeJPG is processing images!</strong>';
	echo '<p>Detected ' .  (count($_SESSION['wipe_structure']) - 1)  .  ' directories<br />';
	echo 'Detected ' .  $_SESSION['wipe_total']  .  ' JPG images</p>';
	echo '<p>Processed ' .  ($_SESSION['wipe_total'] - count($_SESSION['wipe_images']))  .  ' JPG images and counting ...</p>';
	echo '<p><strong>Please wait ...</strong></p>';
	if (count($_SESSION['wipe_images']) > 0)
		echo '<input type="hidden" name="processing" value="inprogress">';
	else
		echo '<input type="hidden" name="complete" value="inprogress">';
	echo '<p><input type="button" class="button" value="Cancel!" onclick="location.href=(\'wipejpg.php?cancel=true\');" onmouseover="this.style.cursor=\'pointer\'" /></p>';
}

// Processing completed
if (isset($_REQUEST['cancel']) || isset($_REQUEST['complete'])) {
	echo '<strong>EasyPhpWipeJPG</strong>';
	echo '<p>Processed ' .  ($_SESSION['wipe_total'] - count($_SESSION['wipe_images']))  .  ' JPG images</p>';
	if ($_SESSION['wipe_wiped'] == 0) {
		echo '<p>No images were wiped (no EXIF, IPTC or comments found)</p>';
	} else {
		echo '<p>Wiped ' .  $_SESSION['wipe_wiped']  .  ' JPG images</p>';
		echo '<p>Reclaimed ' .  bytesToSize1024($_SESSION['wipe_bytes']) .  ' of harddisc space</p>';		
	}
	if ($_SESSION['wipe_backup'] && $_SESSION['wipe_wiped'] > 0) {
		echo '<p><strong>Please make your selection:</strong></p>';
		echo '<p><input type="button" class="button" value="Restore backup images" onclick="location.href=(\'wipejpg.php?restore=true\');" onmouseover="this.style.cursor=\'pointer\'" /></p>';
		echo '<p><input type="button" class="button" value="Remove backup images!" onclick="location.href=(\'wipejpg.php?remove=true\');" onmouseover="this.style.cursor=\'pointer\'" /></p>';
	} else {
		echo '<p><strong>Thank you for using EasyPhpWipeJPG!</strong></p><p>Did this help you? Consider a donation: <a href="http://www.mywebmymail.com/digitalshop/digitalshop.php?p=donation" style="color:#FF0000;">Donate!</a></p>';	
	}
	if($_SESSION['wipe_log'] != '') {
		echo "<script language=\"JavaScript\">\n";
		echo "function expandCollapse(divsection) {\n";
		echo "	var element = document.getElementById(divsection);\n";
		echo "	element.style.display = (element.style.display == \"none\") ? \"block\" : \"none\";\n";
		echo "}\n";
		echo "</script>\n";
		echo '<a href="#" onclick="expandCollapse(\'log\');"><em>View log</em></a><div id="log" style="display:none;width: 100%;height: 250px;font-size : 9px;line-height:90%;text-align : left;padding-top : 15px;padding-left : 100px;overflow: auto;">';
		$homedir = getcwd() . '/';
		foreach ($_SESSION['wipe_log'] as $log) {
			$log = str_replace($homedir, '', $log);
			echo "$log <br />\n";	
		}
		echo '</div>';
	}
}

// Restore / Remove completed
if (isset($_REQUEST['restore']) || isset($_REQUEST['remove'])) {
	echo '<strong>EasyPhpWipeJPG</strong>';
	if (isset($_REQUEST['restore']))
		echo '<p>Original JPG images restored!</p>';
	if (isset($_REQUEST['remove']))
		echo '<p>Backup JPG images removed!</p>';	
	echo '<p><strong>Thank you for using EasyPhpWipeJPG!</strong></p><p>Did this help you? Consider a donation: <a href="http://www.mywebmymail.com/digitalshop/digitalshop.php?p=donation" style="color:#FF0000;">Donate!</a></p>';
}

// End of page
echo "<div class=\"bottomleft\">" .  bottomleftsprite() . "</div>\n";
echo "<div class=\"bottomright\">" .  bottomrightsprite() . "</div>\n";
echo "<div style=\"font-size : 9px;text-align : center;padding-top : 15px;\">&copy; 2011 - <a href=\"http://www.mywebmymail.com\">http://www.mywebmymail.com</a><div>";
echo "</form></div></body></html>\n";

// Functions

function structure($path) {

	global $homedir;
	if ($dir = opendir($path)) {
		while ($dirname = readdir($dir)) {
			if (substr($dirname,0,1) != '.' && is_dir($path . '/' . $dirname)) {
				$_SESSION['wipe_structure'][] = substr($path, strlen($homedir) + 1) . $dirname;
				structure($path . $dirname . '/');
			}
		}
	}  

}

function wipe($src_image, $des_image, $backup = false, $chmod_level = '0755') {
	
	if (!file_exists($src_image)) {return "File does not exist: $src_image <br />";}
	$wipe = false;
	$src_file = fopen($src_image, 'rb');
	if ($src_file) {
		$header = unpack("C1byte1/" . "C1byte2/", fread($src_file, 2));
		if ($header['byte1'] == 0xff & $header['byte2'] == 0xd8) {
			$header = unpack("C1byte1/" . "C1byte2/", fread($src_file, 2));
			while ($header['byte1'] == 0xff && ($header['byte2'] >= 0xe0 && $header['byte2'] <= 0xef || $header['byte2'] == 0xfe)) {
				$length = unpack("n1length", fread($src_file, 2));	
				fseek($src_file, $length['length'] - 2, SEEK_CUR);
				$header = unpack("C1byte1/" . "C1byte2/", fread($src_file, 2));
				$wipe = true;
			}
			if ($wipe) {
				fseek($src_file, -2, SEEK_CUR);
				$src_size = filesize($src_image);
				$image_data = "\xff\xd8" . fread($src_file, $src_size);
				fclose($src_file);
				if ($backup) {
					if (!rename($src_image , dirname($src_image) . '/wipebackup_' . basename($src_image))) {return "Unable to create backup file for: $src_image <br />";}
					chmod(dirname($src_image) . '/wipebackup_' . basename($src_image), octdec($chmod_level));
				} else {
					clearstatcache();
				}
				$des_file = fopen($des_image, 'w');
				if ($des_file) {
					fwrite($des_file, $image_data);
					fclose($des_file);
					chmod($des_image, octdec($chmod_level));
					$wiped = $src_size - filesize($des_image);
					$_SESSION['wipe_bytes'] += $wiped;
					$_SESSION['wipe_wiped'] += 1;
					return "Wiped: $src_image, $wiped bytes reclaimed<br/>";
				} else {
					return "Unable to create destination file: $des_image <br />";
				}
			} else {
				fclose($src_file);
				return "JPG did not contain EXIF, IPTC or comment data: $src_image <br />";
			}
		} else {
			fclose($src_file);
			return "Invalid JPG file: $src_image <br />";
		}
	} else {
		return "Unable to open file: $src_image <br />";
	}
	
}

function get_rfc2397() {

	if (isset($_SERVER['HTTP_USER_AGENT'])) {
		$agent = strtolower($_SERVER['HTTP_USER_AGENT']);
		$pattern = '#(?<browser>msie|opera)[/ ]+(?<version>[0-9]+(?:\.[0-9]+)?)#';
		if (!preg_match_all($pattern, $agent, $matches))
			return true;
		$i = count($matches['browser'])-1;
		if ($matches['browser'][$i] == 'msie' && $matches['version'][$i] < 8) {
			return false;
		} else if ($matches['browser'][$i] == 'opera' && $matches['version'][$i] < 7.2) {
			return false;
		} else {
			return true;
		}
	} else {
		return true;
	}
	
}

function bytesToSize1024($bytes, $precision = 2) {

	$unit = array('B','KB','MB','GB','TB','PB','EB');
	return @round($bytes / pow(1024, ($i = floor(log($bytes, 1024)))), $precision) . ' ' . $unit[$i];
	
}

function topleftsprite() {

if (!$_SESSION['RFC2397']) return '';
return '<img src="data:image/gif;base64,R0lGODdhDgAOAOMAAMze7Ozy/Nzq9PT6/Nzm9NTi9Pz6/Mzi7Oz2/OTu9Pz+/AAAAAAAAAAAAAAA
AAAAACwAAAAADgAOAAAELxDISUkw6hSwN0lKGFKSgIljdwwoSrGtqAFB7AKgLQKE7uY+BSAoAgZr
RMUpyYwAADs=" alt="" title="" style="border :0px;width :13px;height :13px;" />';

}

function toprightsprite() {

if (!$_SESSION['RFC2397']) return '';
return '<img src="data:image/gif;base64,R0lGODdhDgAOAOMAAMze7Ozy/Nzq9PT6/Nzm9NTi9Pz6/Mzi7Oz2/OTu9Pz+/AAAAAAAAAAAAAAA
AAAAACwAAAAADgAOAAAELVCZQIC9WGkdSgFfuG2GgFnjOBwhkKrX8Y4dOI+me2/VvgU6nyLoSwg5
x+QmAgA7" alt="" title="" style="border :0px;width :14px;height :14px;" />';

}

function bottomleftsprite() {

if (!$_SESSION['RFC2397']) return '';
return '<img src="data:image/gif;base64,R0lGODdhDgAOAOMAAMze7Ozy/Nzq9PT6/Nzm9NTi9Pz6/Mzi7Oz2/OTu9Pz+/AAAAAAAAAAAAAAA
AAAAACwAAAAADgAOAAAELVDJSau94dqkK+gUkIEKcJBKAXAg4I4aoAJD586wd7uJYc0yF4E1MQF3
iYAvAgA7" alt="" title="" style="border :0px;width :14px;height :14px;" />';

}

function bottomrightsprite() {

if (!$_SESSION['RFC2397']) return '';
return '<img src="data:image/gif;base64,R0lGODdhDgAOAOMAAMze7Ozy/Nzq9PT6/Nzm9NTi9PT2/Pz6/Mzi7Oz2/OTu9Pz+/AAAAAAAAAAA
AAAAACwAAAAADgAOAAAELHDJSau151qjK+lUAUoBMB6ICSqA2JWAehlxIVdlGl9s6+O2mFBlIARt
yFYEADs=" alt="" title="" style="border :0px;width :14px;height :14px;" />';

}

?>
Return current item: EasyPhpWipeJPG