1<?php
2
3namespace Mpdf\Gif;
4
5/**
6 * GIF Util - (C) 2003 Yamasoft (S/C)
7 *
8 * All Rights Reserved
9 *
10 * This file can be freely copied, distributed, modified, updated by anyone under the only
11 * condition to leave the original address (Yamasoft, http://www.yamasoft.com) and this header.
12 *
13 * @link http://www.yamasoft.com
14 */
15class Image
16{
17
18	var $m_disp;
19
20	var $m_bUser;
21
22	var $m_bTrans;
23
24	var $m_nDelay;
25
26	var $m_nTrans;
27
28	var $m_lpComm;
29
30	var $m_gih;
31
32	var $m_data;
33
34	var $m_lzw;
35
36	public function __construct()
37	{
38		unset($this->m_disp);
39		unset($this->m_bUser);
40		unset($this->m_bTrans);
41		unset($this->m_nDelay);
42		unset($this->m_nTrans);
43		unset($this->m_lpComm);
44		unset($this->m_data);
45		$this->m_gih = new ImageHeader();
46		$this->m_lzw = new Lzw();
47	}
48
49	function load($data, &$datLen)
50	{
51		$datLen = 0;
52
53		while (true) {
54			$b = ord($data[0]);
55			$data = substr($data, 1);
56			$datLen++;
57
58			switch ($b) {
59				case 0x21: // Extension
60					$len = 0;
61					if (!$this->skipExt($data, $len)) {
62						return false;
63					}
64					$datLen += $len;
65					break;
66
67				case 0x2C: // Image
68					// LOAD HEADER & COLOR TABLE
69					$len = 0;
70					if (!$this->m_gih->load($data, $len)) {
71						return false;
72					}
73					$data = substr($data, $len);
74					$datLen += $len;
75
76					// ALLOC BUFFER
77					$len = 0;
78
79					if (!($this->m_data = $this->m_lzw->deCompress($data, $len))) {
80						return false;
81					}
82
83					$data = substr($data, $len);
84					$datLen += $len;
85
86					if ($this->m_gih->m_bInterlace) {
87						$this->deInterlace();
88					}
89
90					return true;
91
92				case 0x3B: // EOF
93				default:
94					return false;
95			}
96		}
97		return false;
98	}
99
100	function skipExt(&$data, &$extLen)
101	{
102		$extLen = 0;
103
104		$b = ord($data[0]);
105		$data = substr($data, 1);
106		$extLen++;
107
108		switch ($b) {
109			case 0xF9: // Graphic Control
110				$b = ord($data[1]);
111				$this->m_disp = ($b & 0x1C) >> 2;
112				$this->m_bUser = ($b & 0x02) ? true : false;
113				$this->m_bTrans = ($b & 0x01) ? true : false;
114				$this->m_nDelay = $this->w2i(substr($data, 2, 2));
115				$this->m_nTrans = ord($data[4]);
116				break;
117
118			case 0xFE: // Comment
119				$this->m_lpComm = substr($data, 1, ord($data[0]));
120				break;
121
122			case 0x01: // Plain text
123				break;
124
125			case 0xFF: // Application
126				break;
127		}
128
129		// SKIP DEFAULT AS DEFS MAY CHANGE
130		$b = ord($data[0]);
131		$data = substr($data, 1);
132		$extLen++;
133		while ($b > 0) {
134			$data = substr($data, $b);
135			$extLen += $b;
136			$b = ord($data[0]);
137			$data = substr($data, 1);
138			$extLen++;
139		}
140		return true;
141	}
142
143	function w2i($str)
144	{
145		return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
146	}
147
148	function deInterlace()
149	{
150		$data = $this->m_data;
151
152		for ($i = 0; $i < 4; $i++) {
153			switch ($i) {
154				case 0:
155					$s = 8;
156					$y = 0;
157					break;
158
159				case 1:
160					$s = 8;
161					$y = 4;
162					break;
163
164				case 2:
165					$s = 4;
166					$y = 2;
167					break;
168
169				case 3:
170					$s = 2;
171					$y = 1;
172					break;
173			}
174
175			for (; $y < $this->m_gih->m_nHeight; $y += $s) {
176				$lne = substr($this->m_data, 0, $this->m_gih->m_nWidth);
177				$this->m_data = substr($this->m_data, $this->m_gih->m_nWidth);
178
179				$data = substr($data, 0, $y * $this->m_gih->m_nWidth) .
180					$lne .
181					substr($data, ($y + 1) * $this->m_gih->m_nWidth);
182			}
183		}
184
185		$this->m_data = $data;
186	}
187}
188