1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of the Metadata project. |
4
|
|
|
* |
5
|
|
|
* @author Daniel Schröder <[email protected]> |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace GravityMedia\Metadata\ID3v2\Reader; |
9
|
|
|
|
10
|
|
|
use GravityMedia\Metadata\ID3v2\Reader; |
11
|
|
|
use GravityMedia\Metadata\ID3v2\Version; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* ID3v2 picture frame reader class. |
15
|
|
|
* |
16
|
|
|
* @package GravityMedia\Metadata\ID3v2\Reader |
17
|
|
|
*/ |
18
|
|
|
class PictureFrameReader extends Reader |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* @var int |
22
|
|
|
*/ |
23
|
|
|
private $encoding; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var string |
27
|
|
|
*/ |
28
|
|
|
private $imageFormat; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var string |
32
|
|
|
*/ |
33
|
|
|
private $mimeType; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var int |
37
|
|
|
*/ |
38
|
|
|
private $type; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @var string |
42
|
|
|
*/ |
43
|
|
|
private $description; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @var string |
47
|
|
|
*/ |
48
|
|
|
private $data; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Read encoding. |
52
|
|
|
* |
53
|
|
|
* @return int |
54
|
|
|
*/ |
55
|
|
|
protected function readEncoding() |
56
|
|
|
{ |
57
|
|
|
$this->getStream()->seek($this->getOffset()); |
58
|
|
|
|
59
|
|
|
return $this->getStream()->readUInt8(); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Get encoding. |
64
|
|
|
* |
65
|
|
|
* @return int |
66
|
|
|
*/ |
67
|
|
|
public function getEncoding() |
68
|
|
|
{ |
69
|
|
|
if (null === $this->encoding) { |
70
|
|
|
$this->encoding = $this->readEncoding(); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
return $this->encoding; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Read image format. |
78
|
|
|
* |
79
|
|
|
* @return string |
80
|
|
|
*/ |
81
|
|
View Code Duplication |
protected function readImageFormat() |
|
|
|
|
82
|
|
|
{ |
83
|
|
|
if (Version::VERSION_22 !== $this->getVersion()) { |
84
|
|
|
return ''; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
$this->getStream()->seek($this->getOffset() + 1); |
88
|
|
|
|
89
|
|
|
return $this->getStream()->read(3); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Get image format. |
94
|
|
|
* |
95
|
|
|
* @return string |
96
|
|
|
*/ |
97
|
|
|
public function getImageFormat() |
98
|
|
|
{ |
99
|
|
|
if (null === $this->imageFormat) { |
100
|
|
|
$this->imageFormat = $this->readImageFormat(); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
return $this->imageFormat; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Read mime type. |
108
|
|
|
* |
109
|
|
|
* @return string |
110
|
|
|
*/ |
111
|
|
|
protected function readMimeType() |
112
|
|
|
{ |
113
|
|
|
if (Version::VERSION_22 === $this->getVersion()) { |
114
|
|
|
return ''; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
$this->getStream()->seek($this->getOffset() + 1); |
118
|
|
|
|
119
|
|
|
$mimeType = ''; |
120
|
|
|
while (!$this->getStream()->eof()) { |
121
|
|
|
$char = $this->getStream()->read(1); |
122
|
|
|
if ("\x00" === $char) { |
123
|
|
|
break; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
$mimeType .= $char; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
return $mimeType; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Get mime type. |
134
|
|
|
* |
135
|
|
|
* @return string |
136
|
|
|
*/ |
137
|
|
|
public function getMimeType() |
138
|
|
|
{ |
139
|
|
|
if (null === $this->mimeType) { |
140
|
|
|
$this->mimeType = $this->readMimeType(); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
return $this->mimeType; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* Get type. |
148
|
|
|
* |
149
|
|
|
* @return int |
150
|
|
|
*/ |
151
|
|
|
protected function readType() |
152
|
|
|
{ |
153
|
|
|
$offset = 4; |
154
|
|
|
if (Version::VERSION_22 !== $this->getVersion()) { |
155
|
|
|
$offset = 2 + strlen($this->getMimeType()); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
$this->getStream()->seek($this->getOffset() + $offset); |
159
|
|
|
|
160
|
|
|
return $this->getStream()->readUInt8(); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Get type. |
165
|
|
|
* |
166
|
|
|
* @return int |
167
|
|
|
*/ |
168
|
|
|
public function getType() |
169
|
|
|
{ |
170
|
|
|
if (null === $this->type) { |
171
|
|
|
$this->type = $this->readType(); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
return $this->type; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Read description. |
179
|
|
|
* |
180
|
|
|
* @return string |
181
|
|
|
*/ |
182
|
|
|
protected function readDescription() |
183
|
|
|
{ |
184
|
|
|
$offset = 5; |
185
|
|
|
if (Version::VERSION_22 !== $this->getVersion()) { |
186
|
|
|
$offset = 3 + strlen($this->getMimeType()); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
$this->getStream()->seek($this->getOffset() + $offset); |
190
|
|
|
|
191
|
|
|
$description = ''; |
192
|
|
|
while (!$this->getStream()->eof()) { |
193
|
|
|
$char = $this->getStream()->read(1); |
194
|
|
|
if ("\x00" === $char) { |
195
|
|
|
break; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
$description .= $char; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
return $description; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* Get description. |
206
|
|
|
* |
207
|
|
|
* @return string |
208
|
|
|
*/ |
209
|
|
|
public function getDescription() |
210
|
|
|
{ |
211
|
|
|
if (null === $this->description) { |
212
|
|
|
$this->description = $this->readDescription(); |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
return $this->description; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* Read data. |
220
|
|
|
* |
221
|
|
|
* @return string |
222
|
|
|
*/ |
223
|
|
|
protected function readData() |
224
|
|
|
{ |
225
|
|
|
$offset = 6 + strlen($this->getDescription()); |
226
|
|
|
if (Version::VERSION_22 !== $this->getVersion()) { |
227
|
|
|
$offset = 4 + strlen($this->getMimeType()) + strlen($this->getDescription()); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
$length = $this->getStream()->getSize() - $offset; |
231
|
|
|
if ($length < 1) { |
232
|
|
|
return ''; |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
$this->getStream()->seek($this->getOffset() + $offset); |
236
|
|
|
|
237
|
|
|
return $this->getStream()->read($length); |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* Get data. |
242
|
|
|
* |
243
|
|
|
* @return string |
244
|
|
|
*/ |
245
|
|
|
public function getData() |
246
|
|
|
{ |
247
|
|
|
if (null === $this->data) { |
248
|
|
|
$this->data = $this->readData(); |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
return $this->data; |
252
|
|
|
} |
253
|
|
|
} |
254
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.