1<?php
2
3/*
4 * This file is part of the Assetic package, an OpenSky project.
5 *
6 * (c) 2010-2014 OpenSky Project Inc
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Assetic\Filter;
13
14use Assetic\Asset\AssetInterface;
15use Assetic\Exception\FilterException;
16use Assetic\Util\FilesystemUtils;
17
18/**
19 * Runs assets through pngout.
20 *
21 * @link http://advsys.net/ken/utils.htm#pngout
22 * @author Kris Wallsmith <kris.wallsmith@gmail.com>
23 */
24class PngoutFilter extends BaseProcessFilter
25{
26    // -c#
27    const COLOR_GREY       = '0';
28    const COLOR_RGB        = '2';
29    const COLOR_PAL        = '3';
30    const COLOR_GRAY_ALPHA = '4';
31    const COLOR_RGB_ALPHA  = '6';
32
33    // -f#
34    const FILTER_NONE  = '0';
35    const FILTER_X     = '1';
36    const FILTER_Y     = '2';
37    const FILTER_X_Y   = '3';
38    const FILTER_PAETH = '4';
39    const FILTER_MIXED = '5';
40
41    // -s#
42    const STRATEGY_XTREME        = '0';
43    const STRATEGY_INTENSE       = '1';
44    const STRATEGY_LONGEST_MATCH = '2';
45    const STRATEGY_HUFFMAN_ONLY  = '3';
46    const STRATEGY_UNCOMPRESSED  = '4';
47
48    private $pngoutBin;
49    private $color;
50    private $filter;
51    private $strategy;
52    private $blockSplitThreshold;
53
54    /**
55     * Constructor.
56     *
57     * @param string $pngoutBin Path to the pngout binary
58     */
59    public function __construct($pngoutBin = '/usr/bin/pngout')
60    {
61        $this->pngoutBin = $pngoutBin;
62    }
63
64    public function setColor($color)
65    {
66        $this->color = $color;
67    }
68
69    public function setFilter($filter)
70    {
71        $this->filter = $filter;
72    }
73
74    public function setStrategy($strategy)
75    {
76        $this->strategy = $strategy;
77    }
78
79    public function setBlockSplitThreshold($blockSplitThreshold)
80    {
81        $this->blockSplitThreshold = $blockSplitThreshold;
82    }
83
84    public function filterLoad(AssetInterface $asset)
85    {
86    }
87
88    public function filterDump(AssetInterface $asset)
89    {
90        $pb = $this->createProcessBuilder(array($this->pngoutBin));
91
92        if (null !== $this->color) {
93            $pb->add('-c'.$this->color);
94        }
95
96        if (null !== $this->filter) {
97            $pb->add('-f'.$this->filter);
98        }
99
100        if (null !== $this->strategy) {
101            $pb->add('-s'.$this->strategy);
102        }
103
104        if (null !== $this->blockSplitThreshold) {
105            $pb->add('-b'.$this->blockSplitThreshold);
106        }
107
108        $pb->add($input = FilesystemUtils::createTemporaryFile('pngout_in'));
109        file_put_contents($input, $asset->getContent());
110
111        $output = FilesystemUtils::createTemporaryFile('pngout_out');
112        unlink($output);
113        $pb->add($output .= '.png');
114
115        $proc = $pb->getProcess();
116        $code = $proc->run();
117
118        if (0 !== $code) {
119            unlink($input);
120            throw FilterException::fromProcess($proc)->setInput($asset->getContent());
121        }
122
123        $asset->setContent(file_get_contents($output));
124
125        unlink($input);
126        unlink($output);
127    }
128}
129