Skip to content

Instantly share code, notes, and snippets.

@madongchunqiu
Created October 13, 2016 09:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save madongchunqiu/7acabde377f3a1148fa17f3e1d9ca325 to your computer and use it in GitHub Desktop.
Save madongchunqiu/7acabde377f3a1148fa17f3e1d9ca325 to your computer and use it in GitHub Desktop.
# code from - https://github.com/pmeenan/progressive-scans
# get the size of each scan of a progressive jpeg
<?php
function GetImageScans($src, &$info) {
$scans = null;
if (is_file($src)) {
$size = getimagesize($src);
$info['src'] = $src;
$info['size'] = filesize($src);
$info['width'] = $size[0];
$info['height'] = $size[1];
$file = fopen($src, 'rb');
if ($file) {
$bytes = fread($file, $info['size']);
// process the jpeg markers
$i = 0;
$scan_start = 0;
$size = strlen($bytes);
$try = 0;
while (FindNextScan($bytes, $size, $i)) {
$scan_length = $i - $scan_start;
$ratio = $scan_length/$info['size'] * 100;
$try++;
$output = printf("scan No. %d, bytes = %d (%0.2f%%) \n", $try, $scan_length, $ratio);
$scans[] = substr($bytes, $scan_start, $scan_length);
$scan_start = $i;
}
fclose($file);
}
}
return $scans;
}
function FindNextScan(&$bytes, $size, &$i) {
$found = false;
if ($i < $size) {
while (!$found && FindNextMarker($bytes, $size, $i, $marker, $marker_length)) {
if (bin2hex($marker) == 'ffda') {
$found = true;
}
$i += $marker_length;
}
if (!$found) {
$found = true;
$i = $size;
}
}
return $found;
}
function FindNextMarker(&$bytes, $size, &$i, &$marker, &$marker_length) {
$marker_length = 0;
$marker = null;
$found = false;
$nolength = array('d0','d1','d2','d3','d4','d5','d6','d7','d8','d9','01');
$sos = 'da';
if ($i < $size) {
$val = dechex(ord($bytes[$i]));
if ($val == 'ff') {
$marker = $bytes[$i];
// ff can repeat, the actual marker comes from the first non-ff
while ($val == 'ff') {
$i++;
$val = dechex(ord($bytes[$i]));
}
$marker .= $bytes[$i];
$i++;
if (in_array($val, $nolength)) {
$found = true;
} elseif($val == $sos) {
// image data
$j = $i + 1;
$next_marker = $size;
while ($j < $size - 1 && !$found) {
$val = dechex(ord($bytes[$j]));
if ($val == 'ff') {
$k = $j + 1;
$val = dechex(ord($bytes[$k]));
if ($val != '00') { // escaping
while ($k < $size = 1 && $val == 'ff') {
$k++;
$val = dechex(ord($bytes[$k]));
}
$next_marker = $j;
$found = true;
}
}
$j++;
}
$marker_length = $next_marker - $i;
} elseif ($i + 1 < $size) {
$l1 = ord($bytes[$i]);
$l2 = ord($bytes[$i+1]);
$marker_length = $l1 * 256 + $l2;
$found = true;
}
}
}
return $found;
}
$info = [];
GetImageScans($argv[1], $info);
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment