- It turns out that a very fast Adler-32 implementation exists, this removes the bulk of my runtime fears and allows me to make the script a little more readable.

- Found a neat way to express the size of the image computationally instead of counting the length
- Removed pointless iteration variables, they removed readability


git-svn-id: file:///svn/phpbb/trunk@5538 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
David M 2006-02-09 07:02:50 +00:00
parent 9d95b33c2c
commit 677f9aedbf

View file

@ -40,18 +40,17 @@ class ucp_confirm
WHERE session_id = '" . $db->sql_escape($user->session_id) . "' WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
AND confirm_id = '" . $db->sql_escape($confirm_id) . "'"; AND confirm_id = '" . $db->sql_escape($confirm_id) . "'";
$result = $db->sql_query($sql); $result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
// If we have a row then grab data else create a new id // If we have a row then grab data else create a new id
if ($row = $db->sql_fetchrow($result)) if (!$row)
{
$db->sql_freeresult($result);
$code = $row['code'];
}
else
{ {
exit; exit;
} }
$code = $row['code'];
// If we can we will generate a single filtered png, we avoid nastiness via emulation of some Zlib stuff // If we can we will generate a single filtered png, we avoid nastiness via emulation of some Zlib stuff
$_png = $this->define_filtered_pngs(); $_png = $this->define_filtered_pngs();
@ -59,14 +58,13 @@ class ucp_confirm
$total_height = 50; $total_height = 50;
$img_height = 40; $img_height = 40;
$img_width = 0; $img_width = 0;
$l = 0;
list($usec, $sec) = explode(' ', microtime()); list($usec, $sec) = explode(' ', microtime());
mt_srand($sec * $usec); mt_srand($sec * $usec);
$char_widths = array(); $char_widths = array();
$code_len = strlen($code); $code_len = strlen($code);
for ($i = 0; $i < $code_len; ++$i) for ($i = 0; $i < $code_len; $i++)
{ {
$char = $code{$i}; $char = $code{$i};
@ -80,20 +78,18 @@ class ucp_confirm
$image = ''; $image = '';
$hold_chars = array(); $hold_chars = array();
for ($i = 0; $i < $total_height; ++$i) for ($i = 0; $i < $total_height; $i++)
{ {
$image .= chr(0); $image .= chr(0);
if ($i > $offset_y && $i < $offset_y + $img_height) if ($i > $offset_y && $i < $offset_y + $img_height)
{ {
$j = 0; for ($k = 0; $k < $offset_x; $k++)
for ($k = 0; $k < $offset_x; ++$k)
{ {
$image .= chr(mt_rand(140, 255)); $image .= chr(mt_rand(140, 255));
} }
for ($k = 0; $k < $code_len; ++$k) for ($k = 0; $k < $code_len; $k++)
{ {
$char = $code{$k}; $char = $code{$k};
@ -101,19 +97,17 @@ class ucp_confirm
{ {
$hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n")); $hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n"));
} }
$image .= $this->randomise(substr($hold_chars[$char][$l], 1), $char_widths[$j++]); $image .= $this->randomise(substr($hold_chars[$char][$i - $offset_y - 1], 1), $char_widths[$k]);
} }
for ($k = $offset_x + $img_width; $k < $total_width; ++$k) for ($k = $offset_x + $img_width; $k < $total_width; $k++)
{ {
$image .= chr(mt_rand(140, 255)); $image .= chr(mt_rand(140, 255));
} }
++$l;
} }
else else
{ {
for ($k = 0; $k < $total_width; ++$k) for ($k = 0; $k < $total_width; $k++)
{ {
$image .= chr(mt_rand(140, 255)); $image .= chr(mt_rand(140, 255));
} }
@ -142,7 +136,7 @@ class ucp_confirm
$new_line = ''; $new_line = '';
$end = strlen($scanline) - ceil($width/2); $end = strlen($scanline) - ceil($width/2);
for ($i = floor($width/2); $i < $end; ++$i) for ($i = floor($width/2); $i < $end; $i++)
{ {
$pixel = ord($scanline{$i}); $pixel = ord($scanline{$i});
@ -196,18 +190,39 @@ class ucp_confirm
} }
else else
{ {
$len = strlen($raw_image); // The total length of this image, uncompressed, is just a calculation of pixels
// Adler-32 hash, lets go! $len = $temp_len = ($width + 1) * $height;
// Optimized Adler-32 loop ported from the GNU Classpath project
$s1 = 1; $s1 = 1;
$s2 = 0; $s2 = 0;
for ($n = 0; $n < $len; ++$n) { $i = 0;
$s1 = ($s1 + ord($raw_image[$n])) % 65521; while ($temp_len > 0)
$s2 = ($s2 + $s1) % 65521; {
// We can defer the modulo operation:
// s1 maximally grows from 65521 to 65521 + 255 * 3800
// s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
$n = 3800;
if ($n > $temp_len)
{
$n = $temp_len;
}
$temp_len -= $n;
while (--$n >= 0)
{
$s1 += (ord($raw_image[$i++]) & 255);
$s2 += $s1;
}
$s1 %= 65521;
$s2 %= 65521;
} }
$adler = ($s2 << 16) | $s1; $adler = ($s2 << 16) | $s1;
// This is the same thing as gzcompress($raw_image, 0) // This is the same thing as gzcompress($raw_image, 0)
$raw_image = pack('C7', 0x78, 0x01, 1, $len & 255, ($len >> 8) & 255, 255 - ($len & 255), 255 - (($len >> 8) & 255)) . $raw_image; $raw_image = pack('C7', 0x78, 0x01, 0x01, $len, ($len >> 8) & 255, ~$len & 255, ~($len >> 8)) . $raw_image;
$raw_image .= pack('C4', ($adler >> 24) & 255, ($adler >> 16) & 255, ($adler >> 8) & 255, $adler & 255); $raw_image .= pack('C4', ($adler >> 24) & 255, ($adler >> 16) & 255, ($adler >> 8) & 255, $adler & 255);
// The Zlib header + Adler hash make us add on 11
$len += 11; $len += 11;
} }
$image .= $this->png_chunk($len, 'IDAT', $raw_image); $image .= $this->png_chunk($len, 'IDAT', $raw_image);