217     public $charset        = 
'ABCDEFGHKLMNPRSTUVWYZabcdefghklmnprstuvwyz23456789';
 
  366         $this->securimage_path = dirname(__FILE__);
 
  368         if (is_array($options) && 
sizeof($options) > 0) {
 
  369             foreach($options as $prop => $val) {
 
  380         if ($this->ttf_file == null) {
 
  381             $this->ttf_file = $this->securimage_path . 
'/AHGBold.ttf';
 
  386         if ($this->wordlist_file == null) {
 
  387             $this->wordlist_file = $this->securimage_path . 
'/words/words.txt';
 
  390         if ($this->sqlite_database == null) {
 
  391             $this->sqlite_database = $this->securimage_path . 
'/database/securimage.sqlite';
 
  394         if ($this->audio_path == null) {
 
  395             $this->audio_path = $this->securimage_path . 
'/audio/';
 
  406         if ($this->
namespace == null || !is_string($this->
namespace)) {
 
  407             $this->
namespace = 'default';
 
  411         if ( session_id() == 
'' ) { 
 
  412             if ($this->session_name != null && trim($this->session_name) != 
'') {
 
  413                 session_name(trim($this->session_name)); 
 
  425         return dirname(__FILE__);
 
  441     public function show($background_image = 
'')
 
  443         if($background_image != 
'' && is_readable($background_image)) {
 
  444             $this->bgimg = $background_image;
 
  465         $this->code_entered = 
$code;
 
  467         return $this->correct_code;
 
  483         header(
"Content-Disposition: attachment; filename=\"securimage_audio.{$ext}\"");
 
  484         header(
'Cache-Control: no-store, no-cache, must-revalidate');
 
  485         header(
'Expires: Sun, 1 Jan 2000 12:00:00 GMT');
 
  486         header(
'Last-Modified: ' . gmdate(
'D, d M Y H:i:s') . 
'GMT');
 
  487         header(
'Content-type: audio/x-wav');
 
  491         header(
'Content-Length: ' . strlen($audio));
 
  502         if( ($this->
use_transparent_text == 
true || $this->bgimg != 
'') && function_exists(
'imagecreatetruecolor')) {
 
  503             $imagecreate = 
'imagecreatetruecolor';
 
  505             $imagecreate = 
'imagecreate';
 
  512         imagepalettecopy($this->tmpimg, $this->im);
 
  524         if ($this->
perturbation > 0 && is_readable($this->ttf_file)) {
 
  545         $this->gdbgcolor = imagecolorallocate($this->im,
 
  547                                               $this->image_bg_color->g,
 
  548                                               $this->image_bg_color->b);
 
  553             $this->gdtextcolor = imagecolorallocatealpha($this->im,
 
  555                                                          $this->text_color->g,
 
  556                                                          $this->text_color->b,
 
  558             $this->gdlinecolor = imagecolorallocatealpha($this->im,
 
  560                                                          $this->line_color->g,
 
  561                                                          $this->line_color->b,
 
  563             $this->gdnoisecolor = imagecolorallocatealpha($this->im,
 
  565                                                           $this->noise_color->g,
 
  566                                                           $this->noise_color->b,
 
  569             $this->gdtextcolor = imagecolorallocate($this->im,
 
  571                                                     $this->text_color->g,
 
  572                                                     $this->text_color->b);
 
  573             $this->gdlinecolor = imagecolorallocate($this->im,
 
  575                                                     $this->line_color->g,
 
  576                                                     $this->line_color->b);
 
  577             $this->gdnoisecolor = imagecolorallocate($this->im,
 
  579                                                           $this->noise_color->g,
 
  580                                                           $this->noise_color->b);
 
  583         $this->gdsignaturecolor = imagecolorallocate($this->im,
 
  585                                                      $this->signature_color->g,
 
  586                                                      $this->signature_color->b);
 
  596         imagefilledrectangle($this->im, 0, 0,
 
  599         imagefilledrectangle($this->tmpimg, 0, 0,
 
  603         if ($this->bgimg == 
'') {
 
  604             if ($this->background_directory != null && 
 
  605                 is_dir($this->background_directory) &&
 
  606                 is_readable($this->background_directory))
 
  615         if ($this->bgimg == 
'') {
 
  619         $dat = @getimagesize($this->bgimg);
 
  625             case 1:  $newim = @imagecreatefromgif($this->bgimg); 
break;
 
  626             case 2:  $newim = @imagecreatefromjpeg($this->bgimg); 
break;
 
  627             case 3:  $newim = @imagecreatefrompng($this->bgimg); 
break;
 
  633         imagecopyresized($this->im, $newim, 0, 0, 0, 0,
 
  635                          imagesx($newim), imagesy($newim));
 
  645         if ( ($dh = opendir($this->background_directory)) !== 
false) {
 
  646             while ((
$file = readdir($dh)) !== 
false) {
 
  647                 if (preg_match(
'/(jpg|gif|png)$/i', 
$file)) $images[] = 
$file;
 
  652             if (
sizeof($images) > 0) {
 
  653                 return rtrim($this->background_directory, 
'/') . 
'/' . $images[rand(0, 
sizeof($images)-1)];
 
  667         switch($this->captcha_type) {
 
  668             case self::SI_CAPTCHA_MATHEMATIC:
 
  670                 $signs = array(
'+', 
'-', 
'x');
 
  673                 $sign  = $signs[rand(0, 2)];
 
  676                     case 'x': $c = $left * $right; 
break;
 
  677                     case '-': $c = $left - $right; 
break;
 
  678                     default:  $c = $left + $right; 
break;
 
  682                 $this->code_display = 
"$left $sign $right";
 
  688                 if ($this->
use_wordlist && is_readable($this->wordlist_file)) {
 
  692                 if ($this->code == 
false) {
 
  712         if (!is_readable($this->ttf_file)) {
 
  713             imagestring($this->im, 4, 10, ($this->
image_height / 2) - 5, 
'Failed to load TTF font file!', $this->gdtextcolor);
 
  716                 $font_size = $height2 * .4;
 
  717                 $bb = imageftbbox($font_size, 0, $this->ttf_file, $this->code_display);
 
  718                 $tx = $bb[4] - $bb[0];
 
  719                 $ty = $bb[5] - $bb[1];
 
  720                 $x  = floor($width2 / 2 - $tx / 2 - $bb[0]);
 
  721                 $y  = round($height2 / 2 - $ty / 2 - $bb[1]);
 
  723                 imagettftext($this->tmpimg, $font_size, 0, $x, $y, $this->gdtextcolor, $this->ttf_file, $this->code_display);
 
  726                 $bb = imageftbbox($font_size, 0, $this->ttf_file, $this->code_display);
 
  727                 $tx = $bb[4] - $bb[0];
 
  728                 $ty = $bb[5] - $bb[1];
 
  729                 $x  = floor($this->
image_width / 2 - $tx / 2 - $bb[0]);
 
  732                 imagettftext($this->im, $font_size, 0, $x, $y, $this->gdtextcolor, $this->ttf_file, $this->code_display);
 
  749         for ($i = 0; $i < $numpoles; ++ $i) {
 
  753             $tmp     = ((- $this->
frand()) * 0.15) - .15;
 
  757         $bgCol = imagecolorat($this->tmpimg, 0, 0);
 
  760         imagepalettecopy($this->im, $this->tmpimg); 
 
  766                 for ($i = 0; $i < $numpoles; ++ $i) {
 
  769                     if ($dx == 0 && $dy == 0) {
 
  772                     $r = sqrt($dx * $dx + $dy * $dy);
 
  776                     $rscale = $amp[$i] * sin(3.14 * $r / $rad[$i]);
 
  783                 if ($x >= 0 && $x < $width2 && $y >= 0 && $y < $height2) {
 
  784                     $c = imagecolorat($this->tmpimg, $x, $y);
 
  787                     imagesetpixel($this->im, $ix, $iy, $c);
 
  799             $x = $this->
image_width * (1 + $line) / ($this->num_lines + 1);
 
  803             $theta = ($this->
frand() - 0.5) * M_PI * 0.7;
 
  805             $len = rand($w * 0.4, $w * 0.7);
 
  808             $k = $this->
frand() * 0.6 + 0.2;
 
  810             $phi = $this->
frand() * 6.28;
 
  812             $dx = $step * cos($theta);
 
  813             $dy = $step * sin($theta);
 
  815             $amp = 1.5 * $this->
frand() / ($k + 5.0 / $len);
 
  816             $x0 = $x - 0.5 * $len * cos($theta);
 
  817             $y0 = $y - 0.5 * $len * sin($theta);
 
  819             $ldx = round(- $dy * $lwid);
 
  820             $ldy = round($dx * $lwid);
 
  822             for ($i = 0; $i < 
$n; ++ $i) {
 
  823                 $x = $x0 + $i * $dx + $amp * $dy * sin($k * $i * $step + $phi);
 
  824                 $y = $y0 + $i * $dy - $amp * $dx * sin($k * $i * $step + $phi);
 
  825                 imagefilledrectangle($this->im, $x, $y, $x + $lwid, $y + $lwid, $this->gdlinecolor);
 
  841         $t0 = microtime(
true);
 
  849             $x = rand(10, $width);
 
  850             $y = rand(10, $height);
 
  852             if ($x - 
$size <= 0 && $y - 
$size <= 0) 
continue; 
 
  853             imagefilledarc($this->tmpimg, $x, $y, 
$size, 
$size, 0, 360, $this->gdnoisecolor, IMG_ARC_PIE);
 
  856         $t1 = microtime(
true);
 
  874         $bbox = imagettfbbox(10, 0, $this->signature_font, $this->
image_signature);
 
  875         $textlen = $bbox[2] - $bbox[0];
 
  879         imagettftext($this->im, 10, 0, $x, $y, $this->gdsignaturecolor, $this->signature_font, $this->
image_signature); 
 
  887         header(
"Expires: Mon, 26 Jul 1997 05:00:00 GMT");
 
  888         header(
"Last-Modified: " . gmdate(
"D, d M Y H:i:s") . 
"GMT");
 
  889         header(
"Cache-Control: no-store, no-cache, must-revalidate");
 
  890         header(
"Cache-Control: post-check=0, pre-check=0", 
false);
 
  891         header(
"Pragma: no-cache");
 
  893         switch ($this->image_type) {
 
  894             case self::SI_IMAGE_JPEG:
 
  895                 header(
"Content-Type: image/jpeg");
 
  896                 imagejpeg($this->im, null, 90);
 
  898             case self::SI_IMAGE_GIF:
 
  899                 header(
"Content-Type: image/gif");
 
  903                 header(
"Content-Type: image/png");
 
  908         imagedestroy($this->im);
 
  930         for($i = 0; $i < strlen(
$code); ++$i) {
 
  931             $letters[] = 
$code{$i};
 
  934         if ($format == 
'mp3') {
 
  946         $fp = @fopen($this->wordlist_file, 
'rb');
 
  947         if (!$fp) 
return false;
 
  949         $fsize = filesize($this->wordlist_file);
 
  950         if ($fsize < 128) 
return false; 
 
  952         fseek($fp, rand(0, $fsize - 64), SEEK_SET); 
 
  953         $data = fread($fp, 64); 
 
  957         $start = @strpos(
$data, 
"\n", rand(0, 56)) + 1; 
 
  958         $end   = @strpos(
$data, 
"\n", $start);          
 
  960         if ($start === 
false) {
 
  962         } 
else if ($end === 
false) {
 
  963             $end = strlen(
$data);
 
  966         return strtolower(substr(
$data, $start, $end - $start)); 
 
  977             $code .= $this->charset{rand(0, $cslen - 1)};
 
  995         if ($this->case_sensitive == 
false && preg_match(
'/[A-Z]/', 
$code)) {
 
  998             $this->case_sensitive = 
true;
 
 1001         $code_entered = trim( (($this->case_sensitive) ? $this->code_entered
 
 1002                                                        : strtolower($this->code_entered))
 
 1004         $this->correct_code = 
false;
 
 1007             if (
$code == $code_entered) {
 
 1008                 $this->correct_code = 
true;
 
 1023         if (isset(
$_SESSION[
'securimage_code_value'][$this->
namespace]) &&
 
 1024          trim(
$_SESSION[
'securimage_code_value'][$this->
namespace]) != 
'') {
 
 1026             $_SESSION[
'securimage_code_ctime'][$this->
namespace]) == 
false) {
 
 1029         } 
else if ($this->use_sqlite_db == 
true && function_exists(
'sqlite_open')) {
 
 1058         if ($this->use_sqlite_db && $this->sqlite_handle !== 
false) {
 
 1059             $ip      = $_SERVER[
'REMOTE_ADDR'];
 
 1062             $success = sqlite_query($this->sqlite_handle,
 
 1063                                     "INSERT OR REPLACE INTO codes(ip, code, namespace, created) 
 1064                                     VALUES('$ip', '$code', '{$this->namespace}', $time)");
 
 1075         $this->sqlite_handle = 
false;
 
 1077         if ($this->use_sqlite_db && function_exists(
'sqlite_open')) {
 
 1078             $this->sqlite_handle = sqlite_open($this->sqlite_database, 0666, $error);
 
 1080             if ($this->sqlite_handle !== 
false) {
 
 1081                 $res = sqlite_query($this->sqlite_handle, 
"PRAGMA table_info(codes)");
 
 1082                 if (sqlite_num_rows(
$res) == 0) {
 
 1083                     sqlite_query($this->sqlite_handle, 
"CREATE TABLE codes (ip VARCHAR(32) PRIMARY KEY, code VARCHAR(32) NOT NULL, namespace VARCHAR(32) NOT NULL, created INTEGER)");
 
 1087             return $this->sqlite_handle != 
false;
 
 1100         if ($this->use_sqlite_db && $this->sqlite_handle !== 
false) {
 
 1101             $ip = $_SERVER[
'REMOTE_ADDR'];
 
 1102             $ns = sqlite_escape_string($this->
namespace);
 
 1104             $res = sqlite_query($this->sqlite_handle, 
"SELECT * FROM codes WHERE ip = '$ip' AND namespace = '$ns'");
 
 1105             if (
$res && sqlite_num_rows(
$res) > 0) {
 
 1121         if (is_resource($this->sqlite_handle)) {
 
 1122             $ip = $_SERVER[
'REMOTE_ADDR'];
 
 1123             $ns = sqlite_escape_string($this->
namespace);
 
 1125             sqlite_query($this->sqlite_handle, 
"DELETE FROM codes WHERE ip = '$ip' AND namespace = '$ns'");
 
 1134         if ($this->use_sqlite_db && $this->sqlite_handle !== 
false) {
 
 1136             $limit = (!is_numeric($this->expiry_time) || $this->expiry_time < 1) ? 86400 : $this->expiry_time;
 
 1138             sqlite_query($this->sqlite_handle, 
"DELETE FROM codes WHERE $now - created > $limit");
 
 1150         if (!is_numeric($this->expiry_time) || $this->expiry_time < 1) {
 
 1152         } 
else if (time() - $creation_time < $this->expiry_time) {
 
 1183         $out_bpersample = 0;
 
 1185         $removeChunks   = array(
'LIST', 
'DISP', 
'NOTE');
 
 1187         for ($i = 0; $i < 
sizeof($letters); ++$i) {
 
 1188             $letter   = $letters[$i];
 
 1189             $filename = $this->audio_path . strtoupper($letter) . 
'.wav';
 
 1193             if (
$data === 
false) {
 
 1198             $header = substr(
$data, 0, 36);
 
 1199             $info   = unpack(
'NChunkID/VChunkSize/NFormat/NSubChunk1ID/' 
 1200                             .
'VSubChunk1Size/vAudioFormat/vNumChannels/' 
 1201                             .
'VSampleRate/VByteRate/vBlockAlign/vBitsPerSample',
 
 1204             $dataPos        = strpos(
$data, 
'data');
 
 1205             $out_channels   = $info[
'NumChannels'];
 
 1206             $out_samplert   = $info[
'SampleRate'];
 
 1207             $out_bpersample = $info[
'BitsPerSample'];
 
 1209             if ($dataPos === 
false) {
 
 1215             if ($info[
'AudioFormat'] != 1) {
 
 1221             if ($info[
'SubChunk1Size'] != 16 && $info[
'SubChunk1Size'] != 18) {
 
 1227             if ($info[
'SubChunk1Size'] > 16) {
 
 1228                 $header .= substr(
$data, 36, $info[
'SubChunk1Size'] - 16);
 
 1233                 $out_data = $header . 
'data';
 
 1238             foreach($removeChunks as $chunk) {
 
 1239                 $chunkPos = strpos(
$data, $chunk);
 
 1240                 if ($chunkPos !== 
false) {
 
 1241                     $listSize = unpack(
'VSize', substr(
$data, $chunkPos + 4, 4));
 
 1244                             substr(
$data, $chunkPos + 8 + $listSize[
'Size']);
 
 1246                     $removed += $listSize[
'Size'] + 8;
 
 1250             $dataSize    = unpack(
'VSubchunk2Size', substr(
$data, $dataPos + 4, 4));
 
 1251             $dataSize[
'Subchunk2Size'] -= $removed;
 
 1252             $out_data   .= substr(
$data, $dataPos + 8, $dataSize[
'Subchunk2Size'] * ($out_bpersample / 8));
 
 1253             $numSamples += $dataSize[
'Subchunk2Size'];
 
 1256         $filesize  = strlen($out_data);
 
 1257         $chunkSize = $filesize - 8;
 
 1258         $dataCSize = $numSamples;
 
 1260         $out_data = substr_replace($out_data, pack(
'V', $chunkSize), 4, 4);
 
 1261         $out_data = substr_replace($out_data, pack(
'V', $numSamples), 40 + ($info[
'SubChunk1Size'] - 16), 4);
 
 1275         $start = strpos(
$data, 
'data') + 4; 
 
 1276         if ($start === 
false) $start = 44;  
 
 1278         $start  += rand(1, 4); 
 
 1279         $datalen = strlen(
$data) - $start;
 
 1282         for ($i = $start; $i < $datalen; $i += $step) {
 
 1283             $ch = ord(
$data{$i});
 
 1284             if ($ch == 0 || $ch == 255) 
continue;
 
 1286             if ($ch < 16 || $ch > 239) {
 
 1289                 $ch += rand(-12, 12);
 
 1292             if ($ch < 0) $ch = 0; 
else if ($ch > 255) $ch = 255;
 
 1294             $data{$i} = chr($ch);
 
 1309         return @file_get_contents(dirname(__FILE__) . 
'/audio/error.wav');
 
 1314         return 0.0001 * rand(0,9999);
 
 1324         if ($color == null) {
 
 1326         } 
else if (is_string($color)) {
 
 1332         } 
else if (is_array($color) && 
sizeof($color) == 3) {
 
 1369         $args = func_get_args();
 
 1371         if (
sizeof($args) == 0) {
 
 1375         } 
else if (
sizeof($args) == 1) {
 
 1377             if (substr($color, 0, 1) == 
'#') {
 
 1378                 $color = substr($color, 1);
 
 1381             if (strlen($color) != 3 && strlen($color) != 6) {
 
 1382                 throw new InvalidArgumentException(
 
 1383                   'Invalid HTML color code passed to Securimage_Color' 
 1388         } 
else if (
sizeof($args) == 3) {
 
 1391             throw new InvalidArgumentException(
 
 1392               'Securimage_Color constructor expects 0, 1 or 3 arguments; ' . 
sizeof($args) . 
' given' 
 1405         if ($red < 0)     $red   = 0;
 
 1406         if ($red > 255)   $red   = 255;
 
 1407         if ($green < 0)   $green = 0;
 
 1408         if ($green > 255) $green = 255;
 
 1409         if ($blue < 0)    $blue  = 0;
 
 1410         if ($blue > 255)  $blue  = 255;
 
 1423         if (strlen($color) == 3) {
 
 1424             $red   = str_repeat(substr($color, 0, 1), 2);
 
 1425             $green = str_repeat(substr($color, 1, 1), 2);
 
 1426             $blue  = str_repeat(substr($color, 2, 1), 2);
 
 1428             $red   = substr($color, 0, 2);
 
 1429             $green = substr($color, 2, 2);
 
 1430             $blue  = substr($color, 4, 2); 
 
 1433         $this->r = hexdec($red);
 
 1434         $this->g = hexdec($green);
 
 1435         $this->b = hexdec($blue);