Horde_Pdf_Writer::_parsePNG PHP Method

_parsePNG() protected method

Extract info from a PNG file.
protected _parsePNG ( string $file ) : array
$file string Filename of PNG image
return array Assoc. array of info
    protected function _parsePNG($file)
    {
        // Extract info from a PNG file.
        $f = fopen($file, 'rb');
        if (!$f) {
            throw new Horde_Pdf_Exception(sprintf('Unable to open image file: %s', $file));
        }
        // Check signature.
        if (fread($f, 8) != chr(137) . 'PNG' . chr(13) . chr(10) . chr(26) . chr(10)) {
            throw new Horde_Pdf_Exception(sprintf('Not a PNG file: %s', $file));
        }
        // Read header chunk.
        fread($f, 4);
        if (fread($f, 4) != 'IHDR') {
            throw new Horde_Pdf_Exception(sprintf('Incorrect PNG file: %s', $file));
        }
        $width = $this->_freadInt($f);
        $height = $this->_freadInt($f);
        $bpc = ord(fread($f, 1));
        if ($bpc > 8) {
            throw new Horde_Pdf_Exception(sprintf('16-bit depth not supported: %s', $file));
        }
        $ct = ord(fread($f, 1));
        if ($ct == 0) {
            $colspace = 'DeviceGray';
        } elseif ($ct == 2) {
            $colspace = 'DeviceRGB';
        } elseif ($ct == 3) {
            $colspace = 'Indexed';
        } else {
            throw new Horde_Pdf_Exception(sprintf('Alpha channel not supported: %s', $file));
        }
        if (ord(fread($f, 1)) != 0) {
            throw new Horde_Pdf_Exception(sprintf('Unknown compression method: %s', $file));
        }
        if (ord(fread($f, 1)) != 0) {
            throw new Horde_Pdf_Exception(sprintf('Unknown filter method: %s', $file));
        }
        if (ord(fread($f, 1)) != 0) {
            throw new Horde_Pdf_Exception(sprintf('Interlacing not supported: %s', $file));
        }
        fread($f, 4);
        $parms = '/DecodeParms <</Predictor 15 /Colors ' . ($ct == 2 ? 3 : 1) . ' /BitsPerComponent ' . $bpc . ' /Columns ' . $width . '>>';
        // Scan chunks looking for palette, transparency and image data.
        $pal = '';
        $trns = '';
        $data = '';
        do {
            $n = $this->_freadInt($f);
            $type = fread($f, 4);
            if ($type == 'PLTE') {
                // Read palette
                $pal = fread($f, $n);
                fread($f, 4);
            } elseif ($type == 'tRNS') {
                // Read transparency info
                $t = fread($f, $n);
                if ($ct == 0) {
                    $trns = array(ord(substr($t, 1, 1)));
                } elseif ($ct == 2) {
                    $trns = array(ord(substr($t, 1, 1)), ord(substr($t, 3, 1)), ord(substr($t, 5, 1)));
                } else {
                    $pos = strpos($t, chr(0));
                    if (is_int($pos)) {
                        $trns = array($pos);
                    }
                }
                fread($f, 4);
            } elseif ($type == 'IDAT') {
                // Read image data block
                $data .= fread($f, $n);
                fread($f, 4);
            } elseif ($type == 'IEND') {
                break;
            } else {
                fread($f, $n + 4);
            }
        } while ($n);
        if ($colspace == 'Indexed' && empty($pal)) {
            throw new Horde_Pdf_Exception(sprintf('Missing palette in: %s', $file));
        }
        fclose($f);
        return array('w' => $width, 'h' => $height, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'FlateDecode', 'parms' => $parms, 'pal' => $pal, 'trns' => $trns, 'data' => $data);
    }