#!/usr/bin/php -q

<?php
ini_set('memory_limit', '128M'); //potentially heavy arrays

if (strtolower(substr(PHP_OS, 0, 3) != 'win')) { //windoze detection
  $nonwin32 = true; //whitch is a good thing :)
}

function askconfirm () { //ask for confirm
  echo "(y/n)";
  $confirm = strtolower(trim(fgets(STDIN)));
  if ($confirm == 'y') {
    return true;
  } elseif ($confirm == 'n') {
    return false;
  } else {
    return askconfirm();
  }
}

function line_echo ($string, $linelen) { //one-line echo in console quick-fix
  $strlen = strlen($string);
  if ($strlen > $linelen) {
    echo "\nline_echo error: String too long\n";
  } else {
    $i = 0;
    while ($i < intval($linelen)) {
      $spaces .= ' ';
      $backs .= '\b';
      $i++;
    }
    echo shell_exec('echo -e "'.$backs.$spaces.$backs.'\c"; echo -e "'.$string.'\c"');
  }
}

function progressbar ($total, $progress, $numblocks) { //draw progress bar
  $linelen = intval($numblocks)+6;
  $blocks = round(($progress/$total*$numblocks), 0);
  $procent = round(($progress/$total*100), 0).'%';
  $a = 0;
  $b = 0;
  while ($a < $blocks) {
    $blockprint .= '#';
    $a++;
  }
  while ($b < ($numblocks-$blocks)) {
    $spaceprint .= ' ';
    $b++;
  }
  $string = '['.$blockprint.$spaceprint.']'.$procent;
  line_echo($string, $linelen);
}

function getmicrotime () { //tnx PHP.NET
  list($usec, $sec) = explode(' ',microtime());
  return ((float)$usec + (float)$sec);
}
  
function rgb2hex($rgb) { //tnx PHP.NET
  return sprintf("%06X", $rgb);
}
  
function write($string, $handle) { //short fwrite function
  @fwrite($handle, $string, strlen($string));
}

function asktype() { //ask for the filetype
  echo "Type [jpg/gif/png/bmp]:";
  $type = strtolower(trim(fgets(STDIN)));
  if (!in_array($type, array('jpg', 'gif', 'png', 'bmp'))) {
    $type = asktype();
  }
  return $type;
}

function askxpix() { //xpix question
  echo "Xpix [int]:";
  $xpix = intval(strtolower(trim(fgets(STDIN))));
  if ($xpix == 0 || $xpix === false) {
    $xpix = askxpix();
  }
  return $xpix;
}

function askypix() { //ypix question
  echo "Ypix [int]:";
  $ypix = intval(strtolower(trim(fgets(STDIN))));
  if ($ypix == 0 || $ypix === false) {
    $ypix = askypix();
  }
  return $ypix;
}

function askimage() { //image question
  echo "Image [filename]:";
  $filein = trim(fgets(STDIN));
  if (!file_exists($filein)) {
    $filein = askimage();
  } else {
    return $filein;
  }
}

function askfile() { //out question
  echo "HtmlFile [filename]:";
  $fileout = trim(fgets(STDIN));
  return $fileout;
}

function img2html($type, $xpix, $ypix, $file, $out, $nonwin32) { //the magic itself
  $timebegin = getmicrotime();
  if (!file_exists($file)) {
    echo "File does not exist!\r\n";
    exit;
  }
  if ($xpix <= 0 || $ypix <= 0) {
    echo "Pix size Error\r\n";
    exit;
  }
  if ($type == 'jpg') {
    $img = @imagecreatefromjpeg($file);
    if (!$img) {
      echo "Not a valid Jpeg file!\r\n";
      exit;
    }
  } elseif ($type == 'gif') {
    $img = @imagecreatefromgif($file);
    if (!$img) {
      echo "Not a valid Gif file!\r\n";
      exit;
    }
  } elseif ($type == 'png') {
    $img = @imagecreatefrompng($file);
    if (!$img) {
      echo "Not a valid PNG file!\r\n";
      exit;
    }
  } elseif ($type == 'bmp') {
    $img = @imagecreatefromwbmp($file);
    if (!$img) {
      echo "Not a valid bitmap file!\r\n";
      exit;
    }
  } else {
    echo "Wrong Type!\r\n";
    exit;
  }
  if (file_exists($out)) {
    echo "File Exists!\r\nOverwrite? ";
    $confirm = askconfirm();
    if (!$confirm) {
      exit;
    } else {
      unlink($out);
    }
  }
  $handle = @fopen($out, 'a+');
  if (!$handle) {
    echo "File Error!\r\n";
    exit;
  }
  $imgx = imagesx($img);
  $imgy = imagesy($img);
  $x = 0;
  $y = 0;
  $availablecolors = array();
  echo "Analyzing...\r\n";
  while ($y < $imgy && $y >= 0) {
    while ($x < $imgx) {
      $availablecolor = rgb2hex(imagecolorat($img, $x, $y));
      if ($availablecolors[$availablecolor]) {
        $availablecolors[$availablecolor]++;
      } else {
        $availablecolors[$availablecolor] = 1;
      }
      $x++;
    }
    $procent = round((($y+1)/$imgy*100), 0);
    if ($nonwin32) {
      progressbar(100, $procent, 20);
    } else {
      echo "Analized pixline ".($y+1)."/".$imgy." (".$procent."%)\r\n";
    }
    $x = 0;
    $y++;
  }
  echo "\r\nSorting...";
  arsort($availablecolors);
  list($tablecolor) = array_keys($availablecolors);
  echo "done.\r\nWriting...\r\n";
  write('<html><head><title>IMG2HTML: '.$file.' ('.$imgx.'x'.$imgy.')</title></head><body>'."\r\n".'<table width="'.($xpix*$imgx).'" height="'.($ypix*$imgy).'" cellpadding="0" cellspacing="0" border="0" bgcolor="#'.$tablecolor.'">'."\r\n", $handle);
  $x = 0;
  $y = 0;
  while ($y < $imgy && $y >= 0) {
    write('<tr>'."\r\n", $handle);
    $colspan = 1;
    while ($x <= $imgx) {
      $imgcolors = rgb2hex(imagecolorat($img, $x, $y));
      if ($x != 0) {
        if ($prevcolor == $imgcolors) {
          $colspan++;
        } else {
          if ($colspan != 1) {
            if ($prevcolor == $tablecolor) {
              write('<td height="'.$ypix.'" width="'.$colspan.'" colspan="'.$colspan.'"></td>'."\r\n", $handle);
            } else {
              write('<td height="'.$ypix.'" width="'.$colspan.'" colspan="'.$colspan.'" bgcolor="#'.$prevcolor.'"></td>'."\r\n", $handle);
            }
            $colspan = 1;
          } else {
            if ($prevcolor == $tablecolor) {
              write('<td height="'.$ypix.'" width="'.$xpix.'"></td>'."\r\n", $handle);
            } else {
              write('<td height="'.$ypix.'" width="'.$xpix.'" bgcolor="#'.$prevcolor.'"></td>'."\r\n", $handle);
            }
          }
        }
      }
      $prevcolor = $imgcolors;
      $x++;
    }
    write('</tr>'."\r\n", $handle);
    $procent = round((($y+1)/$imgy*100), 0);
    if ($nonwin32) {
      progressbar(100, $procent, 20);
    } else {
      echo "Wrote pixline ".($y+1)."/".$imgy." (".$procent."%)\r\n";
    }
    $x = 0;
    $y++;
  }
  write('</table>'."\r\n".'<!--Created by IMG2HTML v0.2.0 (jorrizza.net, phphulp.nl)-->'."\r\n".'</body></html>', $handle);
  @fclose($handle);
  @imagedestroy($img);
  echo "\r\nDone in ".round(getmicrotime()-$timebegin, 5)."s.\r\n";
}
echo "IMG2HTML 0.2.0\r\n";
$type = asktype();
$xpix = askxpix();
$ypix = askypix();
$filein = askimage();
$fileout = askfile();
echo "\r\n";
img2html($type, $xpix, $ypix, $filein, $fileout, $nonwin32);
?>