Вход Регистрация
Файл: vendor/visavi/captcha/src/GifEncoder.php
Строк: 99
<?php

declare(strict_types=1);

namespace 
VisaviCaptcha;

use 
RuntimeException;

class 
GifEncoder
{
    
/* GIF header 6 bytes */
    
private string $gif 'GIF89a';
    private array 
$buf = [];
    private 
int $img = -1;
    private 
int $lop;
    private 
int $dis;
    private array 
$ofs;
    private 
int $col;

    
/**
     * GIF encoder
     *
     * @param array  $frames
     * @param array  $delays
     * @param int    $lop
     * @param int    $dis
     * @param int    $red
     * @param int    $green
     * @param int    $blue
     * @param array  $ofs
     * @param string $mod
     *
     * @throws RuntimeException
     */
    
public function __construct(
        array 
$frames,
        array 
$delays,
        
int $lop,
        
int $dis,
        
int $red 0,
        
int $green 0,
        
int $blue 0,
        array 
$ofs = [],
        
string $mod 'bin'
    
) {
        
$this->lop = ($lop > -1) ? $lop 0;
        
$this->dis = ($dis > -1) ? min($dis3) : 2;
        
$this->col = ($red > -&& $green > -&& $blue > -1) ? ($red | ($green << 8) | ($blue << 16)) : -1;
        
$this->ofs $ofs;

        
$iMax count($frames);
        for (
$i 0$i $iMax$i++) {
            if (
strtolower($mod) === 'url') {
                
$this->buf[] = fread(fopen($frames[$i], 'rb'), filesize($frames[$i]));
            } elseif (
strtolower($mod) === 'bin') {
                
$this->buf[] = $frames[$i];
            } else {
                throw new 
RuntimeException(sprintf('%s (%s)''Unintelligible flag!'$mod));
            }

            if (! 
str_starts_with($this->buf[$i], 'GIF87a') && ! str_starts_with($this->buf[$i], 'GIF89a')) {
                throw new 
RuntimeException(sprintf('%s (%d source)''Source is not a GIF image!'$i));
            }

            for (
$j = (13 * (<< (ord($this->buf[$i][10]) & 0x07))), $k true$k$j++) {
                switch (
$this->buf[$i][$j]) {
                    case 
'!':
                        if ((
substr($this->buf[$i], ($j 3), 8)) === 'NETSCAPE') {
                            throw new 
RuntimeException(sprintf(
                                
'%s (%d source)',
                                
'Does not make animation from animated GIF source!',
                                
$i 1
                            
));
                        }
                        break;
                    case 
';':
                        
$k false;
                        break;
                }
            }
        }

        
$this->addHeader();
        
$iMax count($this->buf);
        for (
$i 0$i $iMax$i++) {
            
$this->addFrames($i$delays[$i]);
        }

        
$this->addFooter();
    }

    
/**
     * Add header
     */
    
private function addHeader(): void
    
{
        if (
ord($this->buf[0][10]) & 0x80) {
            
$cmap * (<< (ord($this->buf[0][10]) & 0x07));
            
$this->gif .= substr($this->buf[0], 67);
            
$this->gif .= substr($this->buf[0], 13$cmap);
            
$this->gif .= "!37713NETSCAPE2.031";
            
$this->gif .= chr($this->lop 0xFF) . chr(($this->lop >> 8) & 0xFF) . "";
        }
    }

    
/**
     * Add frames
     *
     * @param int $i
     * @param int $d
     */
    
private function addFrames(int $iint $d): void
    
{
        
$localStr  13 * (<< (ord($this->buf[$i][10]) & 0x07));
        
$localEnd  strlen($this->buf[$i]) - $localStr 1;
        
$localTmp  substr($this->buf[$i], $localStr$localEnd);
        
$globalLen << (ord($this->buf[0][10]) & 0x07);
        
$localLen  << (ord($this->buf[$i][10]) & 0x07);
        
$globalRgb substr($this->buf[0], 13* (<< (ord($this->buf[0][10]) & 0x07)));
        
$localRgb  substr($this->buf[$i], 13* (<< (ord($this->buf[$i][10]) & 0x07)));
        
$localExt  "!xF9x04" chr(($this->dis << 2) + 0) . chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . "x0x0";

        if (
$this->col > -&& ord($this->buf[$i][10]) & 0x80) {
            for (
$j 0$j < (<< (ord($this->buf[$i][10]) & 0x07)); $j++) {
                if (
                    
ord($localRgb[$j 0]) === (($this->col >> 16) & 0xFF)
                    && 
ord($localRgb[$j 1]) === (($this->col >> 8) & 0xFF)
                    && 
ord($localRgb[$j 2]) === (($this->col >> 0) & 0xFF)
                ) {
                    
$localExt "!xF9x04" chr(($this->dis << 2) + 1) . chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . chr($j) . "x0";
                    break;
                }
            }
        }

        switch (
$localTmp[0]) {
            case 
'!':
                
$localImg substr($localTmp810);
                
$localTmp substr($localTmp18);
                break;
            case 
',':
                
$localImg substr($localTmp010);
                
$localTmp substr($localTmp10);
                break;
            default:
                
$localImg $localTmp;
        }

        if (
$this->img > -&& ord($this->buf[$i][10]) & 0x80) {
            if (
$globalLen === $localLen && $this->blockCompare($globalRgb$localRgb$globalLen)) {
                
$this->gif .= ($localExt $localImg $localTmp);
            } else {
                if (
$this->ofs) {
                    
$localImg[1] = chr($this->ofs[$i][0] & 0xFF);
                    
$localImg[2] = chr(($this->ofs[$i][0] & 0xFF00) >> 8);
                    
$localImg[3] = chr($this->ofs[$i][1] & 0xFF);
                    
$localImg[4] = chr(($this->ofs[$i][1] & 0xFF00) >> 8);
                }

                
$byte ord($localImg[9]);
                
$byte |= 0x80;
                
$byte &= 0xF8;
                
$byte |= (ord($this->buf[$i][10]) & 0x07);
                
$localImg[9] = chr($byte);
                
$this->gif .= $localExt $localImg $localRgb $localTmp;
            }
        } else {
            
$this->gif .= ($localExt $localImg $localTmp);
        }

        
$this->img 1;
    }

    
/**
     * Add footer
     */
    
private function addFooter(): void
    
{
        
$this->gif .= ';';
    }

    
/**
     * Block compare
     *
     * @param string $globalBlock
     * @param string $localBlock
     * @param int    $len
     *
     * @return bool
     */
    
private function blockCompare(string $globalBlockstring $localBlockint $len): bool
    
{
        for (
$i 0$i $len$i++) {
            if (
                
$globalBlock[$i 0] !== $localBlock[$i 0]
                || 
$globalBlock[$i 1] !== $localBlock[$i 1]
                || 
$globalBlock[$i 2] !== $localBlock[$i 2]
            ) {
                return 
false;
            }
        }

        return 
true;
    }

    
/**
     * Get animation
     *
     * @return string
     */
    
public function getAnimation(): string
    
{
        return 
$this->gif;
    }
}
Онлайн: 0
Реклама