source: extensions/charlies_content/getid3/getid3/module.audio-video.asf.php @ 8804

Last change on this file since 8804 was 3544, checked in by vdigital, 15 years ago

Change: getid3 upgraded to -> 1.7.9

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 109.4 KB
Line 
1<?php
2/////////////////////////////////////////////////////////////////
3/// getID3() by James Heinrich <info@getid3.org>               //
4//  available at http://getid3.sourceforge.net                 //
5//            or http://www.getid3.org                         //
6/////////////////////////////////////////////////////////////////
7// See readme.txt for more details                             //
8/////////////////////////////////////////////////////////////////
9//                                                             //
10// module.audio-video.asf.php                                  //
11// module for analyzing ASF, WMA and WMV files                 //
12// dependencies: module.audio-video.riff.php                   //
13//                                                            ///
14/////////////////////////////////////////////////////////////////
15
16getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
17
18$GUIDarray = getid3_asf::KnownGUIDs();
19foreach ($GUIDarray as $GUIDname => $hexstringvalue) {
20        // initialize all GUID constants
21        define($GUIDname, getid3_asf::GUIDtoBytestring($hexstringvalue));
22}
23
24
25
26class getid3_asf
27{
28
29        function getid3_asf(&$fd, &$ThisFileInfo) {
30
31                // Shortcuts
32                $thisfile_audio = &$ThisFileInfo['audio'];
33                $thisfile_video = &$ThisFileInfo['video'];
34                $ThisFileInfo['asf'] = array();
35                $thisfile_asf        = &$ThisFileInfo['asf'];
36                $thisfile_asf['comments'] = array();
37                $thisfile_asf_comments    = &$thisfile_asf['comments'];
38                $thisfile_asf['header_object'] = array();
39                $thisfile_asf_headerobject     = &$thisfile_asf['header_object'];
40
41
42                // ASF structure:
43                // * Header Object [required]
44                //   * File Properties Object [required]   (global file attributes)
45                //   * Stream Properties Object [required] (defines media stream & characteristics)
46                //   * Header Extension Object [required]  (additional functionality)
47                //   * Content Description Object          (bibliographic information)
48                //   * Script Command Object               (commands for during playback)
49                //   * Marker Object                       (named jumped points within the file)
50                // * Data Object [required]
51                //   * Data Packets
52                // * Index Object
53
54                // Header Object: (mandatory, one only)
55                // Field Name                   Field Type   Size (bits)
56                // Object ID                    GUID         128             // GUID for header object - GETID3_ASF_Header_Object
57                // Object Size                  QWORD        64              // size of header object, including 30 bytes of Header Object header
58                // Number of Header Objects     DWORD        32              // number of objects in header object
59                // Reserved1                    BYTE         8               // hardcoded: 0x01
60                // Reserved2                    BYTE         8               // hardcoded: 0x02
61
62                $ThisFileInfo['fileformat'] = 'asf';
63
64                fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
65                $HeaderObjectData = fread($fd, 30);
66
67                $thisfile_asf_headerobject['objectid']      = substr($HeaderObjectData, 0, 16);
68                $thisfile_asf_headerobject['objectid_guid'] = $this->BytestringToGUID($thisfile_asf_headerobject['objectid']);
69                if ($thisfile_asf_headerobject['objectid'] != GETID3_ASF_Header_Object) {
70                        $ThisFileInfo['warning'][] = 'ASF header GUID {'.$this->BytestringToGUID($thisfile_asf_headerobject['objectid']).'} does not match expected "GETID3_ASF_Header_Object" GUID {'.$this->BytestringToGUID(GETID3_ASF_Header_Object).'}';
71                        unset($ThisFileInfo['fileformat']);
72                        unset($ThisFileInfo['asf']);
73                        return false;
74                        break;
75                }
76                $thisfile_asf_headerobject['objectsize']    = getid3_lib::LittleEndian2Int(substr($HeaderObjectData, 16, 8));
77                $thisfile_asf_headerobject['headerobjects'] = getid3_lib::LittleEndian2Int(substr($HeaderObjectData, 24, 4));
78                $thisfile_asf_headerobject['reserved1']     = getid3_lib::LittleEndian2Int(substr($HeaderObjectData, 28, 1));
79                $thisfile_asf_headerobject['reserved2']     = getid3_lib::LittleEndian2Int(substr($HeaderObjectData, 29, 1));
80
81                $ASFHeaderData = fread($fd, $thisfile_asf_headerobject['objectsize'] - 30);
82                $offset = 0;
83
84                for ($HeaderObjectsCounter = 0; $HeaderObjectsCounter < $thisfile_asf_headerobject['headerobjects']; $HeaderObjectsCounter++) {
85                        $NextObjectGUID     = substr($ASFHeaderData, $offset, 16);
86                        $offset += 16;
87                        $NextObjectGUIDtext = $this->BytestringToGUID($NextObjectGUID);
88                        $NextObjectSize = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
89                        $offset += 8;
90                        switch ($NextObjectGUID) {
91
92                                case GETID3_ASF_File_Properties_Object:
93                                        // File Properties Object: (mandatory, one only)
94                                        // Field Name                   Field Type   Size (bits)
95                                        // Object ID                    GUID         128             // GUID for file properties object - GETID3_ASF_File_Properties_Object
96                                        // Object Size                  QWORD        64              // size of file properties object, including 104 bytes of File Properties Object header
97                                        // File ID                      GUID         128             // unique ID - identical to File ID in Data Object
98                                        // File Size                    QWORD        64              // entire file in bytes. Invalid if Broadcast Flag == 1
99                                        // Creation Date                QWORD        64              // date & time of file creation. Maybe invalid if Broadcast Flag == 1
100                                        // Data Packets Count           QWORD        64              // number of data packets in Data Object. Invalid if Broadcast Flag == 1
101                                        // Play Duration                QWORD        64              // playtime, in 100-nanosecond units. Invalid if Broadcast Flag == 1
102                                        // Send Duration                QWORD        64              // time needed to send file, in 100-nanosecond units. Players can ignore this value. Invalid if Broadcast Flag == 1
103                                        // Preroll                      QWORD        64              // time to buffer data before starting to play file, in 1-millisecond units. If <> 0, PlayDuration and PresentationTime have been offset by this amount
104                                        // Flags                        DWORD        32              //
105                                        // * Broadcast Flag             bits         1  (0x01)       // file is currently being written, some header values are invalid
106                                        // * Seekable Flag              bits         1  (0x02)       // is file seekable
107                                        // * Reserved                   bits         30 (0xFFFFFFFC) // reserved - set to zero
108                                        // Minimum Data Packet Size     DWORD        32              // in bytes. should be same as Maximum Data Packet Size. Invalid if Broadcast Flag == 1
109                                        // Maximum Data Packet Size     DWORD        32              // in bytes. should be same as Minimum Data Packet Size. Invalid if Broadcast Flag == 1
110                                        // Maximum Bitrate              DWORD        32              // maximum instantaneous bitrate in bits per second for entire file, including all data streams and ASF overhead
111
112                                        // shortcut
113                                        $thisfile_asf['file_properties_object'] = array();
114                                        $thisfile_asf_filepropertiesobject      = &$thisfile_asf['file_properties_object'];
115
116                                        $thisfile_asf_filepropertiesobject['objectid']           = $NextObjectGUID;
117                                        $thisfile_asf_filepropertiesobject['objectid_guid']      = $NextObjectGUIDtext;
118                                        $thisfile_asf_filepropertiesobject['objectsize']         = $NextObjectSize;
119                                        $thisfile_asf_filepropertiesobject['fileid']             = substr($ASFHeaderData, $offset, 16);
120                                        $offset += 16;
121                                        $thisfile_asf_filepropertiesobject['fileid_guid']        = $this->BytestringToGUID($thisfile_asf_filepropertiesobject['fileid']);
122                                        $thisfile_asf_filepropertiesobject['filesize']           = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
123                                        $offset += 8;
124                                        $thisfile_asf_filepropertiesobject['creation_date']      = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
125                                        $thisfile_asf_filepropertiesobject['creation_date_unix'] = $this->FILETIMEtoUNIXtime($thisfile_asf_filepropertiesobject['creation_date']);
126                                        $offset += 8;
127                                        $thisfile_asf_filepropertiesobject['data_packets']       = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
128                                        $offset += 8;
129                                        $thisfile_asf_filepropertiesobject['play_duration']      = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
130                                        $offset += 8;
131                                        $thisfile_asf_filepropertiesobject['send_duration']      = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
132                                        $offset += 8;
133                                        $thisfile_asf_filepropertiesobject['preroll']            = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
134                                        $offset += 8;
135                                        $thisfile_asf_filepropertiesobject['flags_raw']          = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
136                                        $offset += 4;
137                                        $thisfile_asf_filepropertiesobject['flags']['broadcast'] = (bool) ($thisfile_asf_filepropertiesobject['flags_raw'] & 0x0001);
138                                        $thisfile_asf_filepropertiesobject['flags']['seekable']  = (bool) ($thisfile_asf_filepropertiesobject['flags_raw'] & 0x0002);
139
140                                        $thisfile_asf_filepropertiesobject['min_packet_size']    = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
141                                        $offset += 4;
142                                        $thisfile_asf_filepropertiesobject['max_packet_size']    = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
143                                        $offset += 4;
144                                        $thisfile_asf_filepropertiesobject['max_bitrate']        = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
145                                        $offset += 4;
146
147                                        if ($thisfile_asf_filepropertiesobject['flags']['broadcast']) {
148
149                                                // broadcast flag is set, some values invalid
150                                                unset($thisfile_asf_filepropertiesobject['filesize']);
151                                                unset($thisfile_asf_filepropertiesobject['data_packets']);
152                                                unset($thisfile_asf_filepropertiesobject['play_duration']);
153                                                unset($thisfile_asf_filepropertiesobject['send_duration']);
154                                                unset($thisfile_asf_filepropertiesobject['min_packet_size']);
155                                                unset($thisfile_asf_filepropertiesobject['max_packet_size']);
156
157                                        } else {
158
159                                                // broadcast flag NOT set, perform calculations
160                                                $ThisFileInfo['playtime_seconds'] = ($thisfile_asf_filepropertiesobject['play_duration'] / 10000000) - ($thisfile_asf_filepropertiesobject['preroll'] / 1000);
161
162                                                //$ThisFileInfo['bitrate'] = $thisfile_asf_filepropertiesobject['max_bitrate'];
163                                                $ThisFileInfo['bitrate'] = ((isset($thisfile_asf_filepropertiesobject['filesize']) ? $thisfile_asf_filepropertiesobject['filesize'] : $ThisFileInfo['filesize']) * 8) / $ThisFileInfo['playtime_seconds'];
164                                        }
165                                        break;
166
167                                case GETID3_ASF_Stream_Properties_Object:
168                                        // Stream Properties Object: (mandatory, one per media stream)
169                                        // Field Name                   Field Type   Size (bits)
170                                        // Object ID                    GUID         128             // GUID for stream properties object - GETID3_ASF_Stream_Properties_Object
171                                        // Object Size                  QWORD        64              // size of stream properties object, including 78 bytes of Stream Properties Object header
172                                        // Stream Type                  GUID         128             // GETID3_ASF_Audio_Media, GETID3_ASF_Video_Media or GETID3_ASF_Command_Media
173                                        // Error Correction Type        GUID         128             // GETID3_ASF_Audio_Spread for audio-only streams, GETID3_ASF_No_Error_Correction for other stream types
174                                        // Time Offset                  QWORD        64              // 100-nanosecond units. typically zero. added to all timestamps of samples in the stream
175                                        // Type-Specific Data Length    DWORD        32              // number of bytes for Type-Specific Data field
176                                        // Error Correction Data Length DWORD        32              // number of bytes for Error Correction Data field
177                                        // Flags                        WORD         16              //
178                                        // * Stream Number              bits         7 (0x007F)      // number of this stream.  1 <= valid <= 127
179                                        // * Reserved                   bits         8 (0x7F80)      // reserved - set to zero
180                                        // * Encrypted Content Flag     bits         1 (0x8000)      // stream contents encrypted if set
181                                        // Reserved                     DWORD        32              // reserved - set to zero
182                                        // Type-Specific Data           BYTESTREAM   variable        // type-specific format data, depending on value of Stream Type
183                                        // Error Correction Data        BYTESTREAM   variable        // error-correction-specific format data, depending on value of Error Correct Type
184
185                                        // There is one GETID3_ASF_Stream_Properties_Object for each stream (audio, video) but the
186                                        // stream number isn't known until halfway through decoding the structure, hence it
187                                        // it is decoded to a temporary variable and then stuck in the appropriate index later
188
189                                        $StreamPropertiesObjectData['objectid']           = $NextObjectGUID;
190                                        $StreamPropertiesObjectData['objectid_guid']      = $NextObjectGUIDtext;
191                                        $StreamPropertiesObjectData['objectsize']         = $NextObjectSize;
192                                        $StreamPropertiesObjectData['stream_type']        = substr($ASFHeaderData, $offset, 16);
193                                        $offset += 16;
194                                        $StreamPropertiesObjectData['stream_type_guid']   = $this->BytestringToGUID($StreamPropertiesObjectData['stream_type']);
195                                        $StreamPropertiesObjectData['error_correct_type'] = substr($ASFHeaderData, $offset, 16);
196                                        $offset += 16;
197                                        $StreamPropertiesObjectData['error_correct_guid'] = $this->BytestringToGUID($StreamPropertiesObjectData['error_correct_type']);
198                                        $StreamPropertiesObjectData['time_offset']        = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
199                                        $offset += 8;
200                                        $StreamPropertiesObjectData['type_data_length']   = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
201                                        $offset += 4;
202                                        $StreamPropertiesObjectData['error_data_length']  = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
203                                        $offset += 4;
204                                        $StreamPropertiesObjectData['flags_raw']          = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
205                                        $offset += 2;
206                                        $StreamPropertiesObjectStreamNumber               = $StreamPropertiesObjectData['flags_raw'] & 0x007F;
207                                        $StreamPropertiesObjectData['flags']['encrypted'] = (bool) ($StreamPropertiesObjectData['flags_raw'] & 0x8000);
208
209                                        $offset += 4; // reserved - DWORD
210                                        $StreamPropertiesObjectData['type_specific_data'] = substr($ASFHeaderData, $offset, $StreamPropertiesObjectData['type_data_length']);
211                                        $offset += $StreamPropertiesObjectData['type_data_length'];
212                                        $StreamPropertiesObjectData['error_correct_data'] = substr($ASFHeaderData, $offset, $StreamPropertiesObjectData['error_data_length']);
213                                        $offset += $StreamPropertiesObjectData['error_data_length'];
214
215                                        switch ($StreamPropertiesObjectData['stream_type']) {
216
217                                                case GETID3_ASF_Audio_Media:
218                                                        $thisfile_audio['dataformat']   = (!empty($thisfile_audio['dataformat'])   ? $thisfile_audio['dataformat']   : 'asf');
219                                                        $thisfile_audio['bitrate_mode'] = (!empty($thisfile_audio['bitrate_mode']) ? $thisfile_audio['bitrate_mode'] : 'cbr');
220
221                                                        $audiodata = getid3_riff::RIFFparseWAVEFORMATex(substr($StreamPropertiesObjectData['type_specific_data'], 0, 16));
222                                                        unset($audiodata['raw']);
223                                                        $thisfile_audio = getid3_lib::array_merge_noclobber($audiodata, $thisfile_audio);
224                                                        break;
225
226                                                case GETID3_ASF_Video_Media:
227                                                        $thisfile_video['dataformat']   = (!empty($thisfile_video['dataformat'])   ? $thisfile_video['dataformat']   : 'asf');
228                                                        $thisfile_video['bitrate_mode'] = (!empty($thisfile_video['bitrate_mode']) ? $thisfile_video['bitrate_mode'] : 'cbr');
229                                                        break;
230
231                                                case GETID3_ASF_Command_Media:
232                                                default:
233                                                        // do nothing
234                                                        break;
235
236                                        }
237
238                                        $thisfile_asf['stream_properties_object'][$StreamPropertiesObjectStreamNumber] = $StreamPropertiesObjectData;
239                                        unset($StreamPropertiesObjectData); // clear for next stream, if any
240                                        break;
241
242                                case GETID3_ASF_Header_Extension_Object:
243                                        // Header Extension Object: (mandatory, one only)
244                                        // Field Name                   Field Type   Size (bits)
245                                        // Object ID                    GUID         128             // GUID for Header Extension object - GETID3_ASF_Header_Extension_Object
246                                        // Object Size                  QWORD        64              // size of Header Extension object, including 46 bytes of Header Extension Object header
247                                        // Reserved Field 1             GUID         128             // hardcoded: GETID3_ASF_Reserved_1
248                                        // Reserved Field 2             WORD         16              // hardcoded: 0x00000006
249                                        // Header Extension Data Size   DWORD        32              // in bytes. valid: 0, or > 24. equals object size minus 46
250                                        // Header Extension Data        BYTESTREAM   variable        // array of zero or more extended header objects
251
252                                        // shortcut
253                                        $thisfile_asf['header_extension_object'] = array();
254                                        $thisfile_asf_headerextensionobject      = &$thisfile_asf['header_extension_object'];
255
256                                        $thisfile_asf_headerextensionobject['objectid']            = $NextObjectGUID;
257                                        $thisfile_asf_headerextensionobject['objectid_guid']       = $NextObjectGUIDtext;
258                                        $thisfile_asf_headerextensionobject['objectsize']          = $NextObjectSize;
259                                        $thisfile_asf_headerextensionobject['reserved_1']          = substr($ASFHeaderData, $offset, 16);
260                                        $offset += 16;
261                                        $thisfile_asf_headerextensionobject['reserved_1_guid']     = $this->BytestringToGUID($thisfile_asf_headerextensionobject['reserved_1']);
262                                        if ($thisfile_asf_headerextensionobject['reserved_1'] != GETID3_ASF_Reserved_1) {
263                                                $ThisFileInfo['warning'][] = 'header_extension_object.reserved_1 GUID ('.$this->BytestringToGUID($thisfile_asf_headerextensionobject['reserved_1']).') does not match expected "GETID3_ASF_Reserved_1" GUID ('.$this->BytestringToGUID(GETID3_ASF_Reserved_1).')';
264                                                //return false;
265                                                break;
266                                        }
267                                        $thisfile_asf_headerextensionobject['reserved_2']          = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
268                                        $offset += 2;
269                                        if ($thisfile_asf_headerextensionobject['reserved_2'] != 6) {
270                                                $ThisFileInfo['warning'][] = 'header_extension_object.reserved_2 ('.getid3_lib::PrintHexBytes($thisfile_asf_headerextensionobject['reserved_2']).') does not match expected value of "6"';
271                                                //return false;
272                                                break;
273                                        }
274                                        $thisfile_asf_headerextensionobject['extension_data_size'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
275                                        $offset += 4;
276                                        $thisfile_asf_headerextensionobject['extension_data']      =                              substr($ASFHeaderData, $offset, $thisfile_asf_headerextensionobject['extension_data_size']);
277                                        $offset += $thisfile_asf_headerextensionobject['extension_data_size'];
278                                        break;
279
280                                case GETID3_ASF_Codec_List_Object:
281                                        // Codec List Object: (optional, one only)
282                                        // Field Name                   Field Type   Size (bits)
283                                        // Object ID                    GUID         128             // GUID for Codec List object - GETID3_ASF_Codec_List_Object
284                                        // Object Size                  QWORD        64              // size of Codec List object, including 44 bytes of Codec List Object header
285                                        // Reserved                     GUID         128             // hardcoded: 86D15241-311D-11D0-A3A4-00A0C90348F6
286                                        // Codec Entries Count          DWORD        32              // number of entries in Codec Entries array
287                                        // Codec Entries                array of:    variable        //
288                                        // * Type                       WORD         16              // 0x0001 = Video Codec, 0x0002 = Audio Codec, 0xFFFF = Unknown Codec
289                                        // * Codec Name Length          WORD         16              // number of Unicode characters stored in the Codec Name field
290                                        // * Codec Name                 WCHAR        variable        // array of Unicode characters - name of codec used to create the content
291                                        // * Codec Description Length   WORD         16              // number of Unicode characters stored in the Codec Description field
292                                        // * Codec Description          WCHAR        variable        // array of Unicode characters - description of format used to create the content
293                                        // * Codec Information Length   WORD         16              // number of Unicode characters stored in the Codec Information field
294                                        // * Codec Information          BYTESTREAM   variable        // opaque array of information bytes about the codec used to create the content
295
296                                        // shortcut
297                                        $thisfile_asf['codec_list_object'] = array();
298                                        $thisfile_asf_codeclistobject      = &$thisfile_asf['codec_list_object'];
299
300                                        $thisfile_asf_codeclistobject['objectid']                  = $NextObjectGUID;
301                                        $thisfile_asf_codeclistobject['objectid_guid']             = $NextObjectGUIDtext;
302                                        $thisfile_asf_codeclistobject['objectsize']                = $NextObjectSize;
303                                        $thisfile_asf_codeclistobject['reserved']                  = substr($ASFHeaderData, $offset, 16);
304                                        $offset += 16;
305                                        $thisfile_asf_codeclistobject['reserved_guid']             = $this->BytestringToGUID($thisfile_asf_codeclistobject['reserved']);
306                                        if ($thisfile_asf_codeclistobject['reserved'] != $this->GUIDtoBytestring('86D15241-311D-11D0-A3A4-00A0C90348F6')) {
307                                                $ThisFileInfo['warning'][] = 'codec_list_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_codeclistobject['reserved']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {86D15241-311D-11D0-A3A4-00A0C90348F6}';
308                                                //return false;
309                                                break;
310                                        }
311                                        $thisfile_asf_codeclistobject['codec_entries_count'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
312                                        $offset += 4;
313                                        for ($CodecEntryCounter = 0; $CodecEntryCounter < $thisfile_asf_codeclistobject['codec_entries_count']; $CodecEntryCounter++) {
314                                                // shortcut
315                                                $thisfile_asf_codeclistobject['codec_entries'][$CodecEntryCounter] = array();
316                                                $thisfile_asf_codeclistobject_codecentries_current = &$thisfile_asf_codeclistobject['codec_entries'][$CodecEntryCounter];
317
318                                                $thisfile_asf_codeclistobject_codecentries_current['type_raw'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
319                                                $offset += 2;
320                                                $thisfile_asf_codeclistobject_codecentries_current['type'] = $this->ASFCodecListObjectTypeLookup($thisfile_asf_codeclistobject_codecentries_current['type_raw']);
321
322                                                $CodecNameLength = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2)) * 2; // 2 bytes per character
323                                                $offset += 2;
324                                                $thisfile_asf_codeclistobject_codecentries_current['name'] = substr($ASFHeaderData, $offset, $CodecNameLength);
325                                                $offset += $CodecNameLength;
326
327                                                $CodecDescriptionLength = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2)) * 2; // 2 bytes per character
328                                                $offset += 2;
329                                                $thisfile_asf_codeclistobject_codecentries_current['description'] = substr($ASFHeaderData, $offset, $CodecDescriptionLength);
330                                                $offset += $CodecDescriptionLength;
331
332                                                $CodecInformationLength = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
333                                                $offset += 2;
334                                                $thisfile_asf_codeclistobject_codecentries_current['information'] = substr($ASFHeaderData, $offset, $CodecInformationLength);
335                                                $offset += $CodecInformationLength;
336
337                                                if ($thisfile_asf_codeclistobject_codecentries_current['type_raw'] == 2) {
338                                                        // audio codec
339                                                        if (strpos($thisfile_asf_codeclistobject_codecentries_current['description'], ',') === false) {
340                                                                $ThisFileInfo['error'][] = '[asf][codec_list_object][codec_entries]['.$CodecEntryCounter.'][description] expected to contain comma-seperated list of parameters: "'.$thisfile_asf_codeclistobject_codecentries_current['description'].'"';
341                                                                return false;
342                                                        }
343                                                        list($AudioCodecBitrate, $AudioCodecFrequency, $AudioCodecChannels) = explode(',', $this->TrimConvert($thisfile_asf_codeclistobject_codecentries_current['description']));
344                                                        $thisfile_audio['codec'] = $this->TrimConvert($thisfile_asf_codeclistobject_codecentries_current['name']);
345
346                                                        if (!isset($thisfile_audio['bitrate']) && strstr($AudioCodecBitrate, 'kbps')) {
347                                                                $thisfile_audio['bitrate'] = (int) (trim(str_replace('kbps', '', $AudioCodecBitrate)) * 1000);
348                                                        }
349                                                        //if (!isset($thisfile_video['bitrate']) && isset($thisfile_audio['bitrate']) && isset($thisfile_asf['file_properties_object']['max_bitrate']) && ($thisfile_asf_codeclistobject['codec_entries_count'] > 1)) {
350                                                        if (!@$thisfile_video['bitrate'] && @$thisfile_audio['bitrate'] && @$ThisFileInfo['bitrate']) {
351                                                                //$thisfile_video['bitrate'] = $thisfile_asf['file_properties_object']['max_bitrate'] - $thisfile_audio['bitrate'];
352                                                                $thisfile_video['bitrate'] = $ThisFileInfo['bitrate'] - $thisfile_audio['bitrate'];
353                                                        }
354
355                                                        $AudioCodecFrequency = (int) trim(str_replace('kHz', '', $AudioCodecFrequency));
356                                                        switch ($AudioCodecFrequency) {
357                                                                case 8:
358                                                                case 8000:
359                                                                        $thisfile_audio['sample_rate'] = 8000;
360                                                                        break;
361
362                                                                case 11:
363                                                                case 11025:
364                                                                        $thisfile_audio['sample_rate'] = 11025;
365                                                                        break;
366
367                                                                case 12:
368                                                                case 12000:
369                                                                        $thisfile_audio['sample_rate'] = 12000;
370                                                                        break;
371
372                                                                case 16:
373                                                                case 16000:
374                                                                        $thisfile_audio['sample_rate'] = 16000;
375                                                                        break;
376
377                                                                case 22:
378                                                                case 22050:
379                                                                        $thisfile_audio['sample_rate'] = 22050;
380                                                                        break;
381
382                                                                case 24:
383                                                                case 24000:
384                                                                        $thisfile_audio['sample_rate'] = 24000;
385                                                                        break;
386
387                                                                case 32:
388                                                                case 32000:
389                                                                        $thisfile_audio['sample_rate'] = 32000;
390                                                                        break;
391
392                                                                case 44:
393                                                                case 441000:
394                                                                        $thisfile_audio['sample_rate'] = 44100;
395                                                                        break;
396
397                                                                case 48:
398                                                                case 48000:
399                                                                        $thisfile_audio['sample_rate'] = 48000;
400                                                                        break;
401
402                                                                default:
403                                                                        $ThisFileInfo['warning'][] = 'unknown frequency: "'.$AudioCodecFrequency.'" ('.$this->TrimConvert($thisfile_asf_codeclistobject_codecentries_current['description']).')';
404                                                                        break;
405                                                        }
406
407                                                        if (!isset($thisfile_audio['channels'])) {
408                                                                if (strstr($AudioCodecChannels, 'stereo')) {
409                                                                        $thisfile_audio['channels'] = 2;
410                                                                } elseif (strstr($AudioCodecChannels, 'mono')) {
411                                                                        $thisfile_audio['channels'] = 1;
412                                                                }
413                                                        }
414                                                }
415                                        }
416                                        break;
417
418                                case GETID3_ASF_Script_Command_Object:
419                                        // Script Command Object: (optional, one only)
420                                        // Field Name                   Field Type   Size (bits)
421                                        // Object ID                    GUID         128             // GUID for Script Command object - GETID3_ASF_Script_Command_Object
422                                        // Object Size                  QWORD        64              // size of Script Command object, including 44 bytes of Script Command Object header
423                                        // Reserved                     GUID         128             // hardcoded: 4B1ACBE3-100B-11D0-A39B-00A0C90348F6
424                                        // Commands Count               WORD         16              // number of Commands structures in the Script Commands Objects
425                                        // Command Types Count          WORD         16              // number of Command Types structures in the Script Commands Objects
426                                        // Command Types                array of:    variable        //
427                                        // * Command Type Name Length   WORD         16              // number of Unicode characters for Command Type Name
428                                        // * Command Type Name          WCHAR        variable        // array of Unicode characters - name of a type of command
429                                        // Commands                     array of:    variable        //
430                                        // * Presentation Time          DWORD        32              // presentation time of that command, in milliseconds
431                                        // * Type Index                 WORD         16              // type of this command, as a zero-based index into the array of Command Types of this object
432                                        // * Command Name Length        WORD         16              // number of Unicode characters for Command Name
433                                        // * Command Name               WCHAR        variable        // array of Unicode characters - name of this command
434
435                                        // shortcut
436                                        $thisfile_asf['script_command_object'] = array();
437                                        $thisfile_asf_scriptcommandobject      = &$thisfile_asf['script_command_object'];
438
439                                        $thisfile_asf_scriptcommandobject['objectid']             = $NextObjectGUID;
440                                        $thisfile_asf_scriptcommandobject['objectid_guid']        = $NextObjectGUIDtext;
441                                        $thisfile_asf_scriptcommandobject['objectsize']           = $NextObjectSize;
442                                        $thisfile_asf_scriptcommandobject['reserved']             = substr($ASFHeaderData, $offset, 16);
443                                        $offset += 16;
444                                        $thisfile_asf_scriptcommandobject['reserved_guid']        = $this->BytestringToGUID($thisfile_asf_scriptcommandobject['reserved']);
445                                        if ($thisfile_asf_scriptcommandobject['reserved'] != $this->GUIDtoBytestring('4B1ACBE3-100B-11D0-A39B-00A0C90348F6')) {
446                                                $ThisFileInfo['warning'][] = 'script_command_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_scriptcommandobject['reserved']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {4B1ACBE3-100B-11D0-A39B-00A0C90348F6}';
447                                                //return false;
448                                                break;
449                                        }
450                                        $thisfile_asf_scriptcommandobject['commands_count']       = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
451                                        $offset += 2;
452                                        $thisfile_asf_scriptcommandobject['command_types_count']  = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
453                                        $offset += 2;
454                                        for ($CommandTypesCounter = 0; $CommandTypesCounter < $thisfile_asf_scriptcommandobject['command_types_count']; $CommandTypesCounter++) {
455                                                $CommandTypeNameLength = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2)) * 2; // 2 bytes per character
456                                                $offset += 2;
457                                                $thisfile_asf_scriptcommandobject['command_types'][$CommandTypesCounter]['name'] = substr($ASFHeaderData, $offset, $CommandTypeNameLength);
458                                                $offset += $CommandTypeNameLength;
459                                        }
460                                        for ($CommandsCounter = 0; $CommandsCounter < $thisfile_asf_scriptcommandobject['commands_count']; $CommandsCounter++) {
461                                                $thisfile_asf_scriptcommandobject['commands'][$CommandsCounter]['presentation_time']  = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
462                                                $offset += 4;
463                                                $thisfile_asf_scriptcommandobject['commands'][$CommandsCounter]['type_index']         = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
464                                                $offset += 2;
465
466                                                $CommandTypeNameLength = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2)) * 2; // 2 bytes per character
467                                                $offset += 2;
468                                                $thisfile_asf_scriptcommandobject['commands'][$CommandsCounter]['name'] = substr($ASFHeaderData, $offset, $CommandTypeNameLength);
469                                                $offset += $CommandTypeNameLength;
470                                        }
471                                        break;
472
473                                case GETID3_ASF_Marker_Object:
474                                        // Marker Object: (optional, one only)
475                                        // Field Name                   Field Type   Size (bits)
476                                        // Object ID                    GUID         128             // GUID for Marker object - GETID3_ASF_Marker_Object
477                                        // Object Size                  QWORD        64              // size of Marker object, including 48 bytes of Marker Object header
478                                        // Reserved                     GUID         128             // hardcoded: 4CFEDB20-75F6-11CF-9C0F-00A0C90349CB
479                                        // Markers Count                DWORD        32              // number of Marker structures in Marker Object
480                                        // Reserved                     WORD         16              // hardcoded: 0x0000
481                                        // Name Length                  WORD         16              // number of bytes in the Name field
482                                        // Name                         WCHAR        variable        // name of the Marker Object
483                                        // Markers                      array of:    variable        //
484                                        // * Offset                     QWORD        64              // byte offset into Data Object
485                                        // * Presentation Time          QWORD        64              // in 100-nanosecond units
486                                        // * Entry Length               WORD         16              // length in bytes of (Send Time + Flags + Marker Description Length + Marker Description + Padding)
487                                        // * Send Time                  DWORD        32              // in milliseconds
488                                        // * Flags                      DWORD        32              // hardcoded: 0x00000000
489                                        // * Marker Description Length  DWORD        32              // number of bytes in Marker Description field
490                                        // * Marker Description         WCHAR        variable        // array of Unicode characters - description of marker entry
491                                        // * Padding                    BYTESTREAM   variable        // optional padding bytes
492
493                                        // shortcut
494                                        $thisfile_asf['marker_object'] = array();
495                                        $thisfile_asf_markerobject     = &$thisfile_asf['marker_object'];
496
497                                        $thisfile_asf_markerobject['objectid']             = $NextObjectGUID;
498                                        $thisfile_asf_markerobject['objectid_guid']        = $NextObjectGUIDtext;
499                                        $thisfile_asf_markerobject['objectsize']           = $NextObjectSize;
500                                        $thisfile_asf_markerobject['reserved']             = substr($ASFHeaderData, $offset, 16);
501                                        $offset += 16;
502                                        $thisfile_asf_markerobject['reserved_guid']        = $this->BytestringToGUID($thisfile_asf_markerobject['reserved']);
503                                        if ($thisfile_asf_markerobject['reserved'] != $this->GUIDtoBytestring('4CFEDB20-75F6-11CF-9C0F-00A0C90349CB')) {
504                                                $ThisFileInfo['warning'][] = 'marker_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_markerobject['reserved_1']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {4CFEDB20-75F6-11CF-9C0F-00A0C90349CB}';
505                                                break;
506                                        }
507                                        $thisfile_asf_markerobject['markers_count'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
508                                        $offset += 4;
509                                        $thisfile_asf_markerobject['reserved_2'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
510                                        $offset += 2;
511                                        if ($thisfile_asf_markerobject['reserved_2'] != 0) {
512                                                $ThisFileInfo['warning'][] = 'marker_object.reserved_2 ('.getid3_lib::PrintHexBytes($thisfile_asf_markerobject['reserved_2']).') does not match expected value of "0"';
513                                                break;
514                                        }
515                                        $thisfile_asf_markerobject['name_length'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
516                                        $offset += 2;
517                                        $thisfile_asf_markerobject['name'] = substr($ASFHeaderData, $offset, $thisfile_asf_markerobject['name_length']);
518                                        $offset += $thisfile_asf_markerobject['name_length'];
519                                        for ($MarkersCounter = 0; $MarkersCounter < $thisfile_asf_markerobject['markers_count']; $MarkersCounter++) {
520                                                $thisfile_asf_markerobject['markers'][$MarkersCounter]['offset']  = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
521                                                $offset += 8;
522                                                $thisfile_asf_markerobject['markers'][$MarkersCounter]['presentation_time']         = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
523                                                $offset += 8;
524                                                $thisfile_asf_markerobject['markers'][$MarkersCounter]['entry_length']              = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
525                                                $offset += 2;
526                                                $thisfile_asf_markerobject['markers'][$MarkersCounter]['send_time']                 = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
527                                                $offset += 4;
528                                                $thisfile_asf_markerobject['markers'][$MarkersCounter]['flags']                     = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
529                                                $offset += 4;
530                                                $thisfile_asf_markerobject['markers'][$MarkersCounter]['marker_description_length'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
531                                                $offset += 4;
532                                                $thisfile_asf_markerobject['markers'][$MarkersCounter]['marker_description']        = substr($ASFHeaderData, $offset, $thisfile_asf_markerobject['markers'][$MarkersCounter]['marker_description_length']);
533                                                $offset += $thisfile_asf_markerobject['markers'][$MarkersCounter]['marker_description_length'];
534                                                $PaddingLength = $thisfile_asf_markerobject['markers'][$MarkersCounter]['entry_length'] - 4 -  4 - 4 - $thisfile_asf_markerobject['markers'][$MarkersCounter]['marker_description_length'];
535                                                if ($PaddingLength > 0) {
536                                                        $thisfile_asf_markerobject['markers'][$MarkersCounter]['padding']               = substr($ASFHeaderData, $offset, $PaddingLength);
537                                                        $offset += $PaddingLength;
538                                                }
539                                        }
540                                        break;
541
542                                case GETID3_ASF_Bitrate_Mutual_Exclusion_Object:
543                                        // Bitrate Mutual Exclusion Object: (optional)
544                                        // Field Name                   Field Type   Size (bits)
545                                        // Object ID                    GUID         128             // GUID for Bitrate Mutual Exclusion object - GETID3_ASF_Bitrate_Mutual_Exclusion_Object
546                                        // Object Size                  QWORD        64              // size of Bitrate Mutual Exclusion object, including 42 bytes of Bitrate Mutual Exclusion Object header
547                                        // Exlusion Type                GUID         128             // nature of mutual exclusion relationship. one of: (GETID3_ASF_Mutex_Bitrate, GETID3_ASF_Mutex_Unknown)
548                                        // Stream Numbers Count         WORD         16              // number of video streams
549                                        // Stream Numbers               WORD         variable        // array of mutually exclusive video stream numbers. 1 <= valid <= 127
550
551                                        // shortcut
552                                        $thisfile_asf['bitrate_mutual_exclusion_object'] = array();
553                                        $thisfile_asf_bitratemutualexclusionobject       = &$thisfile_asf['bitrate_mutual_exclusion_object'];
554
555                                        $thisfile_asf_bitratemutualexclusionobject['objectid']             = $NextObjectGUID;
556                                        $thisfile_asf_bitratemutualexclusionobject['objectid_guid']        = $NextObjectGUIDtext;
557                                        $thisfile_asf_bitratemutualexclusionobject['objectsize']           = $NextObjectSize;
558                                        $thisfile_asf_bitratemutualexclusionobject['reserved']             = substr($ASFHeaderData, $offset, 16);
559                                        $thisfile_asf_bitratemutualexclusionobject['reserved_guid']        = $this->BytestringToGUID($thisfile_asf_bitratemutualexclusionobject['reserved']);
560                                        $offset += 16;
561                                        if (($thisfile_asf_bitratemutualexclusionobject['reserved'] != GETID3_ASF_Mutex_Bitrate) && ($thisfile_asf_bitratemutualexclusionobject['reserved'] != GETID3_ASF_Mutex_Unknown)) {
562                                                $ThisFileInfo['warning'][] = 'bitrate_mutual_exclusion_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_bitratemutualexclusionobject['reserved']).'} does not match expected "GETID3_ASF_Mutex_Bitrate" GUID {'.$this->BytestringToGUID(GETID3_ASF_Mutex_Bitrate).'} or  "GETID3_ASF_Mutex_Unknown" GUID {'.$this->BytestringToGUID(GETID3_ASF_Mutex_Unknown).'}';
563                                                //return false;
564                                                break;
565                                        }
566                                        $thisfile_asf_bitratemutualexclusionobject['stream_numbers_count'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
567                                        $offset += 2;
568                                        for ($StreamNumberCounter = 0; $StreamNumberCounter < $thisfile_asf_bitratemutualexclusionobject['stream_numbers_count']; $StreamNumberCounter++) {
569                                                $thisfile_asf_bitratemutualexclusionobject['stream_numbers'][$StreamNumberCounter] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
570                                                $offset += 2;
571                                        }
572                                        break;
573
574                                case GETID3_ASF_Error_Correction_Object:
575                                        // Error Correction Object: (optional, one only)
576                                        // Field Name                   Field Type   Size (bits)
577                                        // Object ID                    GUID         128             // GUID for Error Correction object - GETID3_ASF_Error_Correction_Object
578                                        // Object Size                  QWORD        64              // size of Error Correction object, including 44 bytes of Error Correction Object header
579                                        // Error Correction Type        GUID         128             // type of error correction. one of: (GETID3_ASF_No_Error_Correction, GETID3_ASF_Audio_Spread)
580                                        // Error Correction Data Length DWORD        32              // number of bytes in Error Correction Data field
581                                        // Error Correction Data        BYTESTREAM   variable        // structure depends on value of Error Correction Type field
582
583                                        // shortcut
584                                        $thisfile_asf['error_correction_object'] = array();
585                                        $thisfile_asf_errorcorrectionobject      = &$thisfile_asf['error_correction_object'];
586
587                                        $thisfile_asf_errorcorrectionobject['objectid']              = $NextObjectGUID;
588                                        $thisfile_asf_errorcorrectionobject['objectid_guid']         = $NextObjectGUIDtext;
589                                        $thisfile_asf_errorcorrectionobject['objectsize']            = $NextObjectSize;
590                                        $thisfile_asf_errorcorrectionobject['error_correction_type'] = substr($ASFHeaderData, $offset, 16);
591                                        $offset += 16;
592                                        $thisfile_asf_errorcorrectionobject['error_correction_guid'] = $this->BytestringToGUID($thisfile_asf_errorcorrectionobject['error_correction_type']);
593                                        $thisfile_asf_errorcorrectionobject['error_correction_data_length'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
594                                        $offset += 4;
595                                        switch ($thisfile_asf_errorcorrectionobject['error_correction_type']) {
596                                                case GETID3_ASF_No_Error_Correction:
597                                                        // should be no data, but just in case there is, skip to the end of the field
598                                                        $offset += $thisfile_asf_errorcorrectionobject['error_correction_data_length'];
599                                                        break;
600
601                                                case GETID3_ASF_Audio_Spread:
602                                                        // Field Name                   Field Type   Size (bits)
603                                                        // Span                         BYTE         8               // number of packets over which audio will be spread.
604                                                        // Virtual Packet Length        WORD         16              // size of largest audio payload found in audio stream
605                                                        // Virtual Chunk Length         WORD         16              // size of largest audio payload found in audio stream
606                                                        // Silence Data Length          WORD         16              // number of bytes in Silence Data field
607                                                        // Silence Data                 BYTESTREAM   variable        // hardcoded: 0x00 * (Silence Data Length) bytes
608
609                                                        $thisfile_asf_errorcorrectionobject['span']                  = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 1));
610                                                        $offset += 1;
611                                                        $thisfile_asf_errorcorrectionobject['virtual_packet_length'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
612                                                        $offset += 2;
613                                                        $thisfile_asf_errorcorrectionobject['virtual_chunk_length']  = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
614                                                        $offset += 2;
615                                                        $thisfile_asf_errorcorrectionobject['silence_data_length']   = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
616                                                        $offset += 2;
617                                                        $thisfile_asf_errorcorrectionobject['silence_data']          = substr($ASFHeaderData, $offset, $thisfile_asf_errorcorrectionobject['silence_data_length']);
618                                                        $offset += $thisfile_asf_errorcorrectionobject['silence_data_length'];
619                                                        break;
620
621                                                default:
622                                                        $ThisFileInfo['warning'][] = 'error_correction_object.error_correction_type GUID {'.$this->BytestringToGUID($thisfile_asf_errorcorrectionobject['reserved']).'} does not match expected "GETID3_ASF_No_Error_Correction" GUID {'.$this->BytestringToGUID(GETID3_ASF_No_Error_Correction).'} or  "GETID3_ASF_Audio_Spread" GUID {'.$this->BytestringToGUID(GETID3_ASF_Audio_Spread).'}';
623                                                        //return false;
624                                                        break;
625                                        }
626
627                                        break;
628
629                                case GETID3_ASF_Content_Description_Object:
630                                        // Content Description Object: (optional, one only)
631                                        // Field Name                   Field Type   Size (bits)
632                                        // Object ID                    GUID         128             // GUID for Content Description object - GETID3_ASF_Content_Description_Object
633                                        // Object Size                  QWORD        64              // size of Content Description object, including 34 bytes of Content Description Object header
634                                        // Title Length                 WORD         16              // number of bytes in Title field
635                                        // Author Length                WORD         16              // number of bytes in Author field
636                                        // Copyright Length             WORD         16              // number of bytes in Copyright field
637                                        // Description Length           WORD         16              // number of bytes in Description field
638                                        // Rating Length                WORD         16              // number of bytes in Rating field
639                                        // Title                        WCHAR        16              // array of Unicode characters - Title
640                                        // Author                       WCHAR        16              // array of Unicode characters - Author
641                                        // Copyright                    WCHAR        16              // array of Unicode characters - Copyright
642                                        // Description                  WCHAR        16              // array of Unicode characters - Description
643                                        // Rating                       WCHAR        16              // array of Unicode characters - Rating
644
645                                        // shortcut
646                                        $thisfile_asf['content_description_object'] = array();
647                                        $thisfile_asf_contentdescriptionobject      = &$thisfile_asf['content_description_object'];
648
649                                        $thisfile_asf_contentdescriptionobject['objectid']              = $NextObjectGUID;
650                                        $thisfile_asf_contentdescriptionobject['objectid_guid']         = $NextObjectGUIDtext;
651                                        $thisfile_asf_contentdescriptionobject['objectsize']            = $NextObjectSize;
652                                        $thisfile_asf_contentdescriptionobject['title_length']          = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
653                                        $offset += 2;
654                                        $thisfile_asf_contentdescriptionobject['author_length']         = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
655                                        $offset += 2;
656                                        $thisfile_asf_contentdescriptionobject['copyright_length']      = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
657                                        $offset += 2;
658                                        $thisfile_asf_contentdescriptionobject['description_length']    = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
659                                        $offset += 2;
660                                        $thisfile_asf_contentdescriptionobject['rating_length']         = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
661                                        $offset += 2;
662                                        $thisfile_asf_contentdescriptionobject['title']                 = substr($ASFHeaderData, $offset, $thisfile_asf_contentdescriptionobject['title_length']);
663                                        $offset += $thisfile_asf_contentdescriptionobject['title_length'];
664                                        $thisfile_asf_contentdescriptionobject['author']                = substr($ASFHeaderData, $offset, $thisfile_asf_contentdescriptionobject['author_length']);
665                                        $offset += $thisfile_asf_contentdescriptionobject['author_length'];
666                                        $thisfile_asf_contentdescriptionobject['copyright']             = substr($ASFHeaderData, $offset, $thisfile_asf_contentdescriptionobject['copyright_length']);
667                                        $offset += $thisfile_asf_contentdescriptionobject['copyright_length'];
668                                        $thisfile_asf_contentdescriptionobject['description']           = substr($ASFHeaderData, $offset, $thisfile_asf_contentdescriptionobject['description_length']);
669                                        $offset += $thisfile_asf_contentdescriptionobject['description_length'];
670                                        $thisfile_asf_contentdescriptionobject['rating']                = substr($ASFHeaderData, $offset, $thisfile_asf_contentdescriptionobject['rating_length']);
671                                        $offset += $thisfile_asf_contentdescriptionobject['rating_length'];
672
673                                        $ASFcommentKeysToCopy = array('title'=>'title', 'author'=>'artist', 'copyright'=>'copyright', 'description'=>'comment', 'rating'=>'rating');
674                                        foreach ($ASFcommentKeysToCopy as $keytocopyfrom => $keytocopyto) {
675                                                if (!empty($thisfile_asf_contentdescriptionobject[$keytocopyfrom])) {
676                                                        $thisfile_asf_comments[$keytocopyto][] = $this->TrimTerm($thisfile_asf_contentdescriptionobject[$keytocopyfrom]);
677                                                }
678                                        }
679                                        break;
680
681                                case GETID3_ASF_Extended_Content_Description_Object:
682                                        // Extended Content Description Object: (optional, one only)
683                                        // Field Name                   Field Type   Size (bits)
684                                        // Object ID                    GUID         128             // GUID for Extended Content Description object - GETID3_ASF_Extended_Content_Description_Object
685                                        // Object Size                  QWORD        64              // size of ExtendedContent Description object, including 26 bytes of Extended Content Description Object header
686                                        // Content Descriptors Count    WORD         16              // number of entries in Content Descriptors list
687                                        // Content Descriptors          array of:    variable        //
688                                        // * Descriptor Name Length     WORD         16              // size in bytes of Descriptor Name field
689                                        // * Descriptor Name            WCHAR        variable        // array of Unicode characters - Descriptor Name
690                                        // * Descriptor Value Data Type WORD         16              // Lookup array:
691                                                                                                                                                                        // 0x0000 = Unicode String (variable length)
692                                                                                                                                                                        // 0x0001 = BYTE array     (variable length)
693                                                                                                                                                                        // 0x0002 = BOOL           (DWORD, 32 bits)
694                                                                                                                                                                        // 0x0003 = DWORD          (DWORD, 32 bits)
695                                                                                                                                                                        // 0x0004 = QWORD          (QWORD, 64 bits)
696                                                                                                                                                                        // 0x0005 = WORD           (WORD,  16 bits)
697                                        // * Descriptor Value Length    WORD         16              // number of bytes stored in Descriptor Value field
698                                        // * Descriptor Value           variable     variable        // value for Content Descriptor
699
700                                        // shortcut
701                                        $thisfile_asf['extended_content_description_object'] = array();
702                                        $thisfile_asf_extendedcontentdescriptionobject       = &$thisfile_asf['extended_content_description_object'];
703
704                                        $thisfile_asf_extendedcontentdescriptionobject['objectid']                  = $NextObjectGUID;
705                                        $thisfile_asf_extendedcontentdescriptionobject['objectid_guid']             = $NextObjectGUIDtext;
706                                        $thisfile_asf_extendedcontentdescriptionobject['objectsize']                = $NextObjectSize;
707                                        $thisfile_asf_extendedcontentdescriptionobject['content_descriptors_count'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
708                                        $offset += 2;
709                                        for ($ExtendedContentDescriptorsCounter = 0; $ExtendedContentDescriptorsCounter < $thisfile_asf_extendedcontentdescriptionobject['content_descriptors_count']; $ExtendedContentDescriptorsCounter++) {
710                                                // shortcut
711                                                $thisfile_asf_extendedcontentdescriptionobject['content_descriptors'][$ExtendedContentDescriptorsCounter] = array();
712                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current                                  = &$thisfile_asf_extendedcontentdescriptionobject['content_descriptors'][$ExtendedContentDescriptorsCounter];
713
714                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['base_offset']  = $offset + 30;
715                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['name_length']  = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
716                                                $offset += 2;
717                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['name']         = substr($ASFHeaderData, $offset, $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['name_length']);
718                                                $offset += $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['name_length'];
719                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_type']   = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
720                                                $offset += 2;
721                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_length'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
722                                                $offset += 2;
723                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']        = substr($ASFHeaderData, $offset, $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_length']);
724                                                $offset += $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_length'];
725                                                switch ($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_type']) {
726                                                        case 0x0000: // Unicode string
727                                                                break;
728
729                                                        case 0x0001: // BYTE array
730                                                                // do nothing
731                                                                break;
732
733                                                        case 0x0002: // BOOL
734                                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'] = (bool) getid3_lib::LittleEndian2Int($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']);
735                                                                break;
736
737                                                        case 0x0003: // DWORD
738                                                        case 0x0004: // QWORD
739                                                        case 0x0005: // WORD
740                                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'] = getid3_lib::LittleEndian2Int($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']);
741                                                                break;
742
743                                                        default:
744                                                                $ThisFileInfo['warning'][] = 'extended_content_description.content_descriptors.'.$ExtendedContentDescriptorsCounter.'.value_type is invalid ('.$thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_type'].')';
745                                                                //return false;
746                                                                break;
747                                                }
748                                                switch ($this->TrimConvert(strtolower($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['name']))) {
749
750                                                        case 'wm/albumartist':
751                                                        case 'artist':
752                                                                $thisfile_asf_comments['artist'] = array($this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
753                                                                break;
754
755                                                        case 'wm/albumtitle':
756                                                        case 'album':
757                                                                $thisfile_asf_comments['album']  = array($this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
758                                                                break;
759
760                                                        case 'wm/genre':
761                                                        case 'genre':
762                                                                $thisfile_asf_comments['genre'] = array($this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
763                                                                break;
764
765                                                        case 'wm/tracknumber':
766                                                        case 'tracknumber':
767                                                                $thisfile_asf_comments['track'] = array(intval($this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'])));
768                                                                break;
769
770                                                        case 'wm/track':
771                                                                if (empty($thisfile_asf_comments['track'])) {
772                                                                        $thisfile_asf_comments['track'] = array(1 + $this->TrimConvert($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
773                                                                }
774                                                                break;
775
776                                                        case 'wm/year':
777                                                        case 'year':
778                                                        case 'date':
779                                                                $thisfile_asf_comments['year'] = array( $this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
780                                                                break;
781
782                                                        case 'wm/lyrics':
783                                                        case 'lyrics':
784                                                                $thisfile_asf_comments['lyrics'] = array($this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
785                                                                break;
786
787                                                        case 'isvbr':
788                                                                if ($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']) {
789                                                                        $thisfile_audio['bitrate_mode'] = 'vbr';
790                                                                        $thisfile_video['bitrate_mode'] = 'vbr';
791                                                                }
792                                                                break;
793
794                                                        case 'id3':
795                                                                // id3v2 module might not be loaded
796                                                                if (class_exists('getid3_id3v2')) {
797                                                                    $tempfile         = tempnam('*', 'getID3');
798                                                                    $tempfilehandle   = fopen($tempfile, "wb");
799                                                                        $tempThisfileInfo = array('encoding'=>$ThisFileInfo['encoding']);
800                                                                        fwrite($tempfilehandle, $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']);
801                                                                        fclose($tempfilehandle);
802
803                                                                        $tempfilehandle = fopen($tempfile, "rb");
804                                                                        $id3 = new getid3_id3v2($tempfilehandle, $tempThisfileInfo);
805                                                                        unset($id3);
806                                                                        fclose($tempfilehandle);
807                                                                        unlink($tempfile);
808
809                                                                        $ThisFileInfo['id3v2'] = $tempThisfileInfo['id3v2'];
810                                                                        unset($tempThisfileInfo);
811                                                                }
812                                                                break;
813
814                                                        case 'wm/encodingtime':
815                                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['encoding_time_unix'] = $this->FILETIMEtoUNIXtime($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']);
816                                                                $thisfile_asf_comments['encoding_time_unix'] = array($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['encoding_time_unix']);
817                                                                break;
818
819                                                        case 'wm/picture':
820                                                                //typedef struct _WMPicture{
821                                                                //  LPWSTR  pwszMIMEType;
822                                                                //  BYTE  bPictureType;
823                                                                //  LPWSTR  pwszDescription;
824                                                                //  DWORD  dwDataLen;
825                                                                //  BYTE*  pbData;
826                                                                //} WM_PICTURE;
827
828                                                                $wm_picture_offset = 0;
829                                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_type_id'] = getid3_lib::LittleEndian2Int(substr($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'], $wm_picture_offset, 1));
830                                                                $wm_picture_offset += 1;
831                                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_type']    = $this->WMpictureTypeLookup($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_type_id']);
832                                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_size']    = getid3_lib::LittleEndian2Int(substr($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'], $wm_picture_offset, 4));
833                                                                $wm_picture_offset += 4;
834
835                                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_mime'] = '';
836                                                                do {
837                                                                        $next_byte_pair = substr($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'], $wm_picture_offset, 2);
838                                                                        $wm_picture_offset += 2;
839                                                                        $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_mime'] .= $next_byte_pair;
840                                                                } while ($next_byte_pair !== "\x00\x00");
841
842                                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_description'] = '';
843                                                                do {
844                                                                        $next_byte_pair = substr($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'], $wm_picture_offset, 2);
845                                                                        $wm_picture_offset += 2;
846                                                                        $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_description'] .= $next_byte_pair;
847                                                                } while ($next_byte_pair !== "\x00\x00");
848
849                                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['dataoffset'] = $wm_picture_offset;
850                                                                $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['data'] = substr($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'], $wm_picture_offset);
851                                                                unset($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']);
852
853                                                                break;
854
855                                                        default:
856                                                                switch ($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_type']) {
857                                                                        case 0: // Unicode string
858                                                                                if (substr($this->TrimConvert($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['name']), 0, 3) == 'WM/') {
859                                                                                        $thisfile_asf_comments[str_replace('wm/', '', strtolower($this->TrimConvert($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['name'])))] = array($this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
860                                                                                }
861                                                                                break;
862
863                                                                        case 1:
864                                                                                break;
865                                                                }
866                                                                break;
867                                                }
868
869                                        }
870                                        break;
871
872                                case GETID3_ASF_Stream_Bitrate_Properties_Object:
873                                        // Stream Bitrate Properties Object: (optional, one only)
874                                        // Field Name                   Field Type   Size (bits)
875                                        // Object ID                    GUID         128             // GUID for Stream Bitrate Properties object - GETID3_ASF_Stream_Bitrate_Properties_Object
876                                        // Object Size                  QWORD        64              // size of Extended Content Description object, including 26 bytes of Stream Bitrate Properties Object header
877                                        // Bitrate Records Count        WORD         16              // number of records in Bitrate Records
878                                        // Bitrate Records              array of:    variable        //
879                                        // * Flags                      WORD         16              //
880                                        // * * Stream Number            bits         7  (0x007F)     // number of this stream
881                                        // * * Reserved                 bits         9  (0xFF80)     // hardcoded: 0
882                                        // * Average Bitrate            DWORD        32              // in bits per second
883
884                                        // shortcut
885                                        $thisfile_asf['stream_bitrate_properties_object'] = array();
886                                        $thisfile_asf_streambitratepropertiesobject       = &$thisfile_asf['stream_bitrate_properties_object'];
887
888                                        $thisfile_asf_streambitratepropertiesobject['objectid']                  = $NextObjectGUID;
889                                        $thisfile_asf_streambitratepropertiesobject['objectid_guid']             = $NextObjectGUIDtext;
890                                        $thisfile_asf_streambitratepropertiesobject['objectsize']                = $NextObjectSize;
891                                        $thisfile_asf_streambitratepropertiesobject['bitrate_records_count']     = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
892                                        $offset += 2;
893                                        for ($BitrateRecordsCounter = 0; $BitrateRecordsCounter < $thisfile_asf_streambitratepropertiesobject['bitrate_records_count']; $BitrateRecordsCounter++) {
894                                                $thisfile_asf_streambitratepropertiesobject['bitrate_records'][$BitrateRecordsCounter]['flags_raw'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
895                                                $offset += 2;
896                                                $thisfile_asf_streambitratepropertiesobject['bitrate_records'][$BitrateRecordsCounter]['flags']['stream_number'] = $thisfile_asf_streambitratepropertiesobject['bitrate_records'][$BitrateRecordsCounter]['flags_raw'] & 0x007F;
897                                                $thisfile_asf_streambitratepropertiesobject['bitrate_records'][$BitrateRecordsCounter]['bitrate'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
898                                                $offset += 4;
899                                        }
900                                        break;
901
902                                case GETID3_ASF_Padding_Object:
903                                        // Padding Object: (optional)
904                                        // Field Name                   Field Type   Size (bits)
905                                        // Object ID                    GUID         128             // GUID for Padding object - GETID3_ASF_Padding_Object
906                                        // Object Size                  QWORD        64              // size of Padding object, including 24 bytes of ASF Padding Object header
907                                        // Padding Data                 BYTESTREAM   variable        // ignore
908
909                                        // shortcut
910                                        $thisfile_asf['padding_object'] = array();
911                                        $thisfile_asf_paddingobject     = &$thisfile_asf['padding_object'];
912
913                                        $thisfile_asf_paddingobject['objectid']                  = $NextObjectGUID;
914                                        $thisfile_asf_paddingobject['objectid_guid']             = $NextObjectGUIDtext;
915                                        $thisfile_asf_paddingobject['objectsize']                = $NextObjectSize;
916                                        $thisfile_asf_paddingobject['padding_length']            = $thisfile_asf_paddingobject['objectsize'] - 16 - 8;
917                                        $thisfile_asf_paddingobject['padding']                   = substr($ASFHeaderData, $offset, $thisfile_asf_paddingobject['padding_length']);
918                                        $offset += ($NextObjectSize - 16 - 8);
919                                        break;
920
921                                case GETID3_ASF_Extended_Content_Encryption_Object:
922                                case GETID3_ASF_Content_Encryption_Object:
923                                        // WMA DRM - just ignore
924                                        $offset += ($NextObjectSize - 16 - 8);
925                                        break;
926
927                                default:
928                                        // Implementations shall ignore any standard or non-standard object that they do not know how to handle.
929                                        if ($this->GUIDname($NextObjectGUIDtext)) {
930                                                $ThisFileInfo['warning'][] = 'unhandled GUID "'.$this->GUIDname($NextObjectGUIDtext).'" {'.$NextObjectGUIDtext.'} in ASF header at offset '.($offset - 16 - 8);
931                                        } else {
932                                                $ThisFileInfo['warning'][] = 'unknown GUID {'.$NextObjectGUIDtext.'} in ASF header at offset '.($offset - 16 - 8);
933                                        }
934                                        $offset += ($NextObjectSize - 16 - 8);
935                                        break;
936                        }
937                }
938                if (isset($thisfile_asf_streambitrateproperties['bitrate_records_count'])) {
939                        $ASFbitrateAudio = 0;
940                        $ASFbitrateVideo = 0;
941                        for ($BitrateRecordsCounter = 0; $BitrateRecordsCounter < $thisfile_asf_streambitrateproperties['bitrate_records_count']; $BitrateRecordsCounter++) {
942                                if (isset($thisfile_asf_codeclistobject['codec_entries'][$BitrateRecordsCounter])) {
943                                        switch ($thisfile_asf_codeclistobject['codec_entries'][$BitrateRecordsCounter]['type_raw']) {
944                                                case 1:
945                                                        $ASFbitrateVideo += $thisfile_asf_streambitrateproperties['bitrate_records'][$BitrateRecordsCounter]['bitrate'];
946                                                        break;
947
948                                                case 2:
949                                                        $ASFbitrateAudio += $thisfile_asf_streambitrateproperties['bitrate_records'][$BitrateRecordsCounter]['bitrate'];
950                                                        break;
951
952                                                default:
953                                                        // do nothing
954                                                        break;
955                                        }
956                                }
957                        }
958                        if ($ASFbitrateAudio > 0) {
959                                $thisfile_audio['bitrate'] = $ASFbitrateAudio;
960                        }
961                        if ($ASFbitrateVideo > 0) {
962                                $thisfile_video['bitrate'] = $ASFbitrateVideo;
963                        }
964                }
965                if (isset($thisfile_asf['stream_properties_object']) && is_array($thisfile_asf['stream_properties_object'])) {
966
967                        $thisfile_audio['bitrate'] = 0;
968                        $thisfile_video['bitrate'] = 0;
969
970                        foreach ($thisfile_asf['stream_properties_object'] as $streamnumber => $streamdata) {
971
972                                switch ($streamdata['stream_type']) {
973                                        case GETID3_ASF_Audio_Media:
974                                                // Field Name                   Field Type   Size (bits)
975                                                // Codec ID / Format Tag        WORD         16              // unique ID of audio codec - defined as wFormatTag field of WAVEFORMATEX structure
976                                                // Number of Channels           WORD         16              // number of channels of audio - defined as nChannels field of WAVEFORMATEX structure
977                                                // Samples Per Second           DWORD        32              // in Hertz - defined as nSamplesPerSec field of WAVEFORMATEX structure
978                                                // Average number of Bytes/sec  DWORD        32              // bytes/sec of audio stream  - defined as nAvgBytesPerSec field of WAVEFORMATEX structure
979                                                // Block Alignment              WORD         16              // block size in bytes of audio codec - defined as nBlockAlign field of WAVEFORMATEX structure
980                                                // Bits per sample              WORD         16              // bits per sample of mono data. set to zero for variable bitrate codecs. defined as wBitsPerSample field of WAVEFORMATEX structure
981                                                // Codec Specific Data Size     WORD         16              // size in bytes of Codec Specific Data buffer - defined as cbSize field of WAVEFORMATEX structure
982                                                // Codec Specific Data          BYTESTREAM   variable        // array of codec-specific data bytes
983
984                                                // shortcut
985                                                $thisfile_asf['audio_media'][$streamnumber] = array();
986                                                $thisfile_asf_audiomedia_currentstream      = &$thisfile_asf['audio_media'][$streamnumber];
987
988                                                $audiomediaoffset = 0;
989
990                                                $thisfile_asf_audiomedia_currentstream = getid3_riff::RIFFparseWAVEFORMATex(substr($streamdata['type_specific_data'], $audiomediaoffset, 16));
991                                                $audiomediaoffset += 16;
992
993                                                $thisfile_audio['lossless'] = false;
994                                                switch ($thisfile_asf_audiomedia_currentstream['raw']['wFormatTag']) {
995                                                        case 0x0001: // PCM
996                                                        case 0x0163: // WMA9 Lossless
997                                                                $thisfile_audio['lossless'] = true;
998                                                                break;
999                                                }
1000
1001                                                if (!empty($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'])) {
1002                                                        foreach ($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'] as $dummy => $dataarray) {
1003                                                                if (@$dataarray['flags']['stream_number'] == $streamnumber) {
1004                                                                        $thisfile_asf_audiomedia_currentstream['bitrate'] = $dataarray['bitrate'];
1005                                                                        $thisfile_audio['bitrate'] += $dataarray['bitrate'];
1006                                                                        break;
1007                                                                }
1008                                                        }
1009                                                } else {
1010                                                        if (@$thisfile_asf_audiomedia_currentstream['bytes_sec']) {
1011                                                                $thisfile_audio['bitrate'] += $thisfile_asf_audiomedia_currentstream['bytes_sec'] * 8;
1012                                                        } elseif (@$thisfile_asf_audiomedia_currentstream['bitrate']) {
1013                                                                $thisfile_audio['bitrate'] += $thisfile_asf_audiomedia_currentstream['bitrate'];
1014                                                        }
1015                                                }
1016                                                $thisfile_audio['streams'][$streamnumber]                = $thisfile_asf_audiomedia_currentstream;
1017                                                $thisfile_audio['streams'][$streamnumber]['wformattag']  = $thisfile_asf_audiomedia_currentstream['raw']['wFormatTag'];
1018                                                $thisfile_audio['streams'][$streamnumber]['lossless']    = $thisfile_audio['lossless'];
1019                                                $thisfile_audio['streams'][$streamnumber]['bitrate']     = $thisfile_audio['bitrate'];
1020                                                $thisfile_audio['streams'][$streamnumber]['dataformat']  = 'wma';
1021                                                unset($thisfile_audio['streams'][$streamnumber]['raw']);
1022
1023                                                $thisfile_asf_audiomedia_currentstream['codec_data_size'] = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $audiomediaoffset, 2));
1024                                                $audiomediaoffset += 2;
1025                                                $thisfile_asf_audiomedia_currentstream['codec_data']      = substr($streamdata['type_specific_data'], $audiomediaoffset, $thisfile_asf_audiomedia_currentstream['codec_data_size']);
1026                                                $audiomediaoffset += $thisfile_asf_audiomedia_currentstream['codec_data_size'];
1027
1028                                                break;
1029
1030                                        case GETID3_ASF_Video_Media:
1031                                                // Field Name                   Field Type   Size (bits)
1032                                                // Encoded Image Width          DWORD        32              // width of image in pixels
1033                                                // Encoded Image Height         DWORD        32              // height of image in pixels
1034                                                // Reserved Flags               BYTE         8               // hardcoded: 0x02
1035                                                // Format Data Size             WORD         16              // size of Format Data field in bytes
1036                                                // Format Data                  array of:    variable        //
1037                                                // * Format Data Size           DWORD        32              // number of bytes in Format Data field, in bytes - defined as biSize field of BITMAPINFOHEADER structure
1038                                                // * Image Width                LONG         32              // width of encoded image in pixels - defined as biWidth field of BITMAPINFOHEADER structure
1039                                                // * Image Height               LONG         32              // height of encoded image in pixels - defined as biHeight field of BITMAPINFOHEADER structure
1040                                                // * Reserved                   WORD         16              // hardcoded: 0x0001 - defined as biPlanes field of BITMAPINFOHEADER structure
1041                                                // * Bits Per Pixel Count       WORD         16              // bits per pixel - defined as biBitCount field of BITMAPINFOHEADER structure
1042                                                // * Compression ID             FOURCC       32              // fourcc of video codec - defined as biCompression field of BITMAPINFOHEADER structure
1043                                                // * Image Size                 DWORD        32              // image size in bytes - defined as biSizeImage field of BITMAPINFOHEADER structure
1044                                                // * Horizontal Pixels / Meter  DWORD        32              // horizontal resolution of target device in pixels per meter - defined as biXPelsPerMeter field of BITMAPINFOHEADER structure
1045                                                // * Vertical Pixels / Meter    DWORD        32              // vertical resolution of target device in pixels per meter - defined as biYPelsPerMeter field of BITMAPINFOHEADER structure
1046                                                // * Colors Used Count          DWORD        32              // number of color indexes in the color table that are actually used - defined as biClrUsed field of BITMAPINFOHEADER structure
1047                                                // * Important Colors Count     DWORD        32              // number of color index required for displaying bitmap. if zero, all colors are required. defined as biClrImportant field of BITMAPINFOHEADER structure
1048                                                // * Codec Specific Data        BYTESTREAM   variable        // array of codec-specific data bytes
1049
1050                                                // shortcut
1051                                                $thisfile_asf['video_media'][$streamnumber] = array();
1052                                                $thisfile_asf_videomedia_currentstream      = &$thisfile_asf['video_media'][$streamnumber];
1053
1054                                                $videomediaoffset = 0;
1055                                                $thisfile_asf_videomedia_currentstream['image_width']                     = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 4));
1056                                                $videomediaoffset += 4;
1057                                                $thisfile_asf_videomedia_currentstream['image_height']                    = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 4));
1058                                                $videomediaoffset += 4;
1059                                                $thisfile_asf_videomedia_currentstream['flags']                           = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 1));
1060                                                $videomediaoffset += 1;
1061                                                $thisfile_asf_videomedia_currentstream['format_data_size']                = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 2));
1062                                                $videomediaoffset += 2;
1063                                                $thisfile_asf_videomedia_currentstream['format_data']['format_data_size'] = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 4));
1064                                                $videomediaoffset += 4;
1065                                                $thisfile_asf_videomedia_currentstream['format_data']['image_width']      = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 4));
1066                                                $videomediaoffset += 4;
1067                                                $thisfile_asf_videomedia_currentstream['format_data']['image_height']     = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 4));
1068                                                $videomediaoffset += 4;
1069                                                $thisfile_asf_videomedia_currentstream['format_data']['reserved']         = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 2));
1070                                                $videomediaoffset += 2;
1071                                                $thisfile_asf_videomedia_currentstream['format_data']['bits_per_pixel']   = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 2));
1072                                                $videomediaoffset += 2;
1073                                                $thisfile_asf_videomedia_currentstream['format_data']['codec_fourcc']     = substr($streamdata['type_specific_data'], $videomediaoffset, 4);
1074                                                $videomediaoffset += 4;
1075                                                $thisfile_asf_videomedia_currentstream['format_data']['image_size']       = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 4));
1076                                                $videomediaoffset += 4;
1077                                                $thisfile_asf_videomedia_currentstream['format_data']['horizontal_pels']  = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 4));
1078                                                $videomediaoffset += 4;
1079                                                $thisfile_asf_videomedia_currentstream['format_data']['vertical_pels']    = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 4));
1080                                                $videomediaoffset += 4;
1081                                                $thisfile_asf_videomedia_currentstream['format_data']['colors_used']      = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 4));
1082                                                $videomediaoffset += 4;
1083                                                $thisfile_asf_videomedia_currentstream['format_data']['colors_important'] = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $videomediaoffset, 4));
1084                                                $videomediaoffset += 4;
1085                                                $thisfile_asf_videomedia_currentstream['format_data']['codec_data']       = substr($streamdata['type_specific_data'], $videomediaoffset);
1086
1087                                                if (!empty($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'])) {
1088                                                        foreach ($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'] as $dummy => $dataarray) {
1089                                                                if (@$dataarray['flags']['stream_number'] == $streamnumber) {
1090                                                                        $thisfile_asf_videomedia_currentstream['bitrate'] = $dataarray['bitrate'];
1091                                                                        $thisfile_video['streams'][$streamnumber]['bitrate'] = $dataarray['bitrate'];
1092                                                                        $thisfile_video['bitrate'] += $dataarray['bitrate'];
1093                                                                        break;
1094                                                                }
1095                                                        }
1096                                                }
1097
1098                                                $thisfile_asf_videomedia_currentstream['format_data']['codec'] = getid3_riff::RIFFfourccLookup($thisfile_asf_videomedia_currentstream['format_data']['codec_fourcc']);
1099
1100                                                $thisfile_video['streams'][$streamnumber]['fourcc']          = $thisfile_asf_videomedia_currentstream['format_data']['codec_fourcc'];
1101                                                $thisfile_video['streams'][$streamnumber]['codec']           = $thisfile_asf_videomedia_currentstream['format_data']['codec'];
1102                                                $thisfile_video['streams'][$streamnumber]['resolution_x']    = $thisfile_asf_videomedia_currentstream['image_width'];
1103                                                $thisfile_video['streams'][$streamnumber]['resolution_y']    = $thisfile_asf_videomedia_currentstream['image_height'];
1104                                                $thisfile_video['streams'][$streamnumber]['bits_per_sample'] = $thisfile_asf_videomedia_currentstream['format_data']['bits_per_pixel'];
1105                                                break;
1106
1107                                        default:
1108                                                break;
1109                                }
1110                        }
1111                }
1112
1113                while (ftell($fd) < $ThisFileInfo['avdataend']) {
1114                        $NextObjectDataHeader = fread($fd, 24);
1115                        $offset = 0;
1116                        $NextObjectGUID = substr($NextObjectDataHeader, 0, 16);
1117                        $offset += 16;
1118                        $NextObjectGUIDtext = $this->BytestringToGUID($NextObjectGUID);
1119                        $NextObjectSize = getid3_lib::LittleEndian2Int(substr($NextObjectDataHeader, $offset, 8));
1120                        $offset += 8;
1121
1122                        switch ($NextObjectGUID) {
1123                                case GETID3_ASF_Data_Object:
1124                                        // Data Object: (mandatory, one only)
1125                                        // Field Name                       Field Type   Size (bits)
1126                                        // Object ID                        GUID         128             // GUID for Data object - GETID3_ASF_Data_Object
1127                                        // Object Size                      QWORD        64              // size of Data object, including 50 bytes of Data Object header. may be 0 if FilePropertiesObject.BroadcastFlag == 1
1128                                        // File ID                          GUID         128             // unique identifier. identical to File ID field in Header Object
1129                                        // Total Data Packets               QWORD        64              // number of Data Packet entries in Data Object. invalid if FilePropertiesObject.BroadcastFlag == 1
1130                                        // Reserved                         WORD         16              // hardcoded: 0x0101
1131
1132                                        // shortcut
1133                                        $thisfile_asf['data_object'] = array();
1134                                        $thisfile_asf_dataobject     = &$thisfile_asf['data_object'];
1135
1136                                        $DataObjectData = $NextObjectDataHeader.fread($fd, 50 - 24);
1137                                        $offset = 24;
1138
1139                                        $thisfile_asf_dataobject['objectid']           = $NextObjectGUID;
1140                                        $thisfile_asf_dataobject['objectid_guid']      = $NextObjectGUIDtext;
1141                                        $thisfile_asf_dataobject['objectsize']         = $NextObjectSize;
1142
1143                                        $thisfile_asf_dataobject['fileid']             = substr($DataObjectData, $offset, 16);
1144                                        $offset += 16;
1145                                        $thisfile_asf_dataobject['fileid_guid']        = $this->BytestringToGUID($thisfile_asf_dataobject['fileid']);
1146                                        $thisfile_asf_dataobject['total_data_packets'] = getid3_lib::LittleEndian2Int(substr($DataObjectData, $offset, 8));
1147                                        $offset += 8;
1148                                        $thisfile_asf_dataobject['reserved']           = getid3_lib::LittleEndian2Int(substr($DataObjectData, $offset, 2));
1149                                        $offset += 2;
1150                                        if ($thisfile_asf_dataobject['reserved'] != 0x0101) {
1151                                                $ThisFileInfo['warning'][] = 'data_object.reserved ('.getid3_lib::PrintHexBytes($thisfile_asf_dataobject['reserved']).') does not match expected value of "0x0101"';
1152                                                //return false;
1153                                                break;
1154                                        }
1155
1156                                        // Data Packets                     array of:    variable        //
1157                                        // * Error Correction Flags         BYTE         8               //
1158                                        // * * Error Correction Data Length bits         4               // if Error Correction Length Type == 00, size of Error Correction Data in bytes, else hardcoded: 0000
1159                                        // * * Opaque Data Present          bits         1               //
1160                                        // * * Error Correction Length Type bits         2               // number of bits for size of the error correction data. hardcoded: 00
1161                                        // * * Error Correction Present     bits         1               // If set, use Opaque Data Packet structure, else use Payload structure
1162                                        // * Error Correction Data
1163
1164                                        $ThisFileInfo['avdataoffset'] = ftell($fd);
1165                                        fseek($fd, ($thisfile_asf_dataobject['objectsize'] - 50), SEEK_CUR); // skip actual audio/video data
1166                                        $ThisFileInfo['avdataend'] = ftell($fd);
1167                                        break;
1168
1169                                case GETID3_ASF_Simple_Index_Object:
1170                                        // Simple Index Object: (optional, recommended, one per video stream)
1171                                        // Field Name                       Field Type   Size (bits)
1172                                        // Object ID                        GUID         128             // GUID for Simple Index object - GETID3_ASF_Data_Object
1173                                        // Object Size                      QWORD        64              // size of Simple Index object, including 56 bytes of Simple Index Object header
1174                                        // File ID                          GUID         128             // unique identifier. may be zero or identical to File ID field in Data Object and Header Object
1175                                        // Index Entry Time Interval        QWORD        64              // interval between index entries in 100-nanosecond units
1176                                        // Maximum Packet Count             DWORD        32              // maximum packet count for all index entries
1177                                        // Index Entries Count              DWORD        32              // number of Index Entries structures
1178                                        // Index Entries                    array of:    variable        //
1179                                        // * Packet Number                  DWORD        32              // number of the Data Packet associated with this index entry
1180                                        // * Packet Count                   WORD         16              // number of Data Packets to sent at this index entry
1181
1182                                        // shortcut
1183                                        $thisfile_asf['simple_index_object'] = array();
1184                                        $thisfile_asf_simpleindexobject      = &$thisfile_asf['simple_index_object'];
1185
1186                                        $SimpleIndexObjectData = $NextObjectDataHeader.fread($fd, 56 - 24);
1187                                        $offset = 24;
1188
1189                                        $thisfile_asf_simpleindexobject['objectid']                  = $NextObjectGUID;
1190                                        $thisfile_asf_simpleindexobject['objectid_guid']             = $NextObjectGUIDtext;
1191                                        $thisfile_asf_simpleindexobject['objectsize']                = $NextObjectSize;
1192
1193                                        $thisfile_asf_simpleindexobject['fileid']                    =                  substr($SimpleIndexObjectData, $offset, 16);
1194                                        $offset += 16;
1195                                        $thisfile_asf_simpleindexobject['fileid_guid']               = $this->BytestringToGUID($thisfile_asf_simpleindexobject['fileid']);
1196                                        $thisfile_asf_simpleindexobject['index_entry_time_interval'] = getid3_lib::LittleEndian2Int(substr($SimpleIndexObjectData, $offset, 8));
1197                                        $offset += 8;
1198                                        $thisfile_asf_simpleindexobject['maximum_packet_count']      = getid3_lib::LittleEndian2Int(substr($SimpleIndexObjectData, $offset, 4));
1199                                        $offset += 4;
1200                                        $thisfile_asf_simpleindexobject['index_entries_count']       = getid3_lib::LittleEndian2Int(substr($SimpleIndexObjectData, $offset, 4));
1201                                        $offset += 4;
1202
1203                                        $IndexEntriesData = $SimpleIndexObjectData.fread($fd, 6 * $thisfile_asf_simpleindexobject['index_entries_count']);
1204                                        for ($IndexEntriesCounter = 0; $IndexEntriesCounter < $thisfile_asf_simpleindexobject['index_entries_count']; $IndexEntriesCounter++) {
1205                                                $thisfile_asf_simpleindexobject['index_entries'][$IndexEntriesCounter]['packet_number'] = getid3_lib::LittleEndian2Int(substr($IndexEntriesData, $offset, 4));
1206                                                $offset += 4;
1207                                                $thisfile_asf_simpleindexobject['index_entries'][$IndexEntriesCounter]['packet_count']  = getid3_lib::LittleEndian2Int(substr($IndexEntriesData, $offset, 4));
1208                                                $offset += 2;
1209                                        }
1210
1211                                        break;
1212
1213                                case GETID3_ASF_Index_Object:
1214                                        // 6.2 ASF top-level Index Object (optional but recommended when appropriate, 0 or 1)
1215                                        // Field Name                       Field Type   Size (bits)
1216                                        // Object ID                        GUID         128             // GUID for the Index Object - GETID3_ASF_Index_Object
1217                                        // Object Size                      QWORD        64              // Specifies the size, in bytes, of the Index Object, including at least 34 bytes of Index Object header
1218                                        // Index Entry Time Interval        DWORD        32              // Specifies the time interval between each index entry in ms.
1219                                        // Index Specifiers Count           WORD         16              // Specifies the number of Index Specifiers structures in this Index Object.
1220                                        // Index Blocks Count               DWORD        32              // Specifies the number of Index Blocks structures in this Index Object.
1221
1222                                        // Index Entry Time Interval        DWORD        32              // Specifies the time interval between index entries in milliseconds.  This value cannot be 0.
1223                                        // Index Specifiers Count           WORD         16              // Specifies the number of entries in the Index Specifiers list.  Valid values are 1 and greater.
1224                                        // Index Specifiers                 array of:    varies          //
1225                                        // * Stream Number                  WORD         16              // Specifies the stream number that the Index Specifiers refer to. Valid values are between 1 and 127.
1226                                        // * Index Type                     WORD         16              // Specifies Index Type values as follows:
1227                                                                                                                                                                        //   1 = Nearest Past Data Packet - indexes point to the data packet whose presentation time is closest to the index entry time.
1228                                                                                                                                                                        //   2 = Nearest Past Media Object - indexes point to the closest data packet containing an entire object or first fragment of an object.
1229                                                                                                                                                                        //   3 = Nearest Past Cleanpoint. - indexes point to the closest data packet containing an entire object (or first fragment of an object) that has the Cleanpoint Flag set.
1230                                                                                                                                                                        //   Nearest Past Cleanpoint is the most common type of index.
1231                                        // Index Entry Count                DWORD        32              // Specifies the number of Index Entries in the block.
1232                                        // * Block Positions                QWORD        varies          // Specifies a list of byte offsets of the beginnings of the blocks relative to the beginning of the first Data Packet (i.e., the beginning of the Data Object + 50 bytes). The number of entries in this list is specified by the value of the Index Specifiers Count field. The order of those byte offsets is tied to the order in which Index Specifiers are listed.
1233                                        // * Index Entries                  array of:    varies          //
1234                                        // * * Offsets                      DWORD        varies          // An offset value of 0xffffffff indicates an invalid offset value
1235
1236                                        // shortcut
1237                                        $thisfile_asf['asf_index_object'] = array();
1238                                        $thisfile_asf_asfindexobject      = &$thisfile_asf['asf_index_object'];
1239
1240                                        $ASFIndexObjectData = $NextObjectDataHeader.fread($fd, 34 - 24);
1241                                        $offset = 24;
1242
1243                                        $thisfile_asf_asfindexobject['objectid']                  = $NextObjectGUID;
1244                                        $thisfile_asf_asfindexobject['objectid_guid']             = $NextObjectGUIDtext;
1245                                        $thisfile_asf_asfindexobject['objectsize']                = $NextObjectSize;
1246
1247                                        $thisfile_asf_asfindexobject['entry_time_interval']       = getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 4));
1248                                        $offset += 4;
1249                                        $thisfile_asf_asfindexobject['index_specifiers_count']    = getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 2));
1250                                        $offset += 2;
1251                                        $thisfile_asf_asfindexobject['index_blocks_count']        = getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 4));
1252                                        $offset += 4;
1253
1254                                        $ASFIndexObjectData .= fread($fd, 4 * $thisfile_asf_asfindexobject['index_specifiers_count']);
1255                                        for ($IndexSpecifiersCounter = 0; $IndexSpecifiersCounter < $thisfile_asf_asfindexobject['index_specifiers_count']; $IndexSpecifiersCounter++) {
1256                                                $IndexSpecifierStreamNumber = getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 2));
1257                                                $offset += 2;
1258                                                $thisfile_asf_asfindexobject['index_specifiers'][$IndexSpecifiersCounter]['stream_number']   = $IndexSpecifierStreamNumber;
1259                                                $thisfile_asf_asfindexobject['index_specifiers'][$IndexSpecifiersCounter]['index_type']      = getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 2));
1260                                                $offset += 2;
1261                                                $thisfile_asf_asfindexobject['index_specifiers'][$IndexSpecifiersCounter]['index_type_text'] = $this->ASFIndexObjectIndexTypeLookup($thisfile_asf_asfindexobject['index_specifiers'][$IndexSpecifiersCounter]['index_type']);
1262                                        }
1263
1264                                        $ASFIndexObjectData .= fread($fd, 4);
1265                                        $thisfile_asf_asfindexobject['index_entry_count'] = getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 4));
1266                                        $offset += 4;
1267
1268                                        $ASFIndexObjectData .= fread($fd, 8 * $thisfile_asf_asfindexobject['index_specifiers_count']);
1269                                        for ($IndexSpecifiersCounter = 0; $IndexSpecifiersCounter < $thisfile_asf_asfindexobject['index_specifiers_count']; $IndexSpecifiersCounter++) {
1270                                                $thisfile_asf_asfindexobject['block_positions'][$IndexSpecifiersCounter] = getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 8));
1271                                                $offset += 8;
1272                                        }
1273
1274                                        $ASFIndexObjectData .= fread($fd, 4 * $thisfile_asf_asfindexobject['index_specifiers_count'] * $thisfile_asf_asfindexobject['index_entry_count']);
1275                                        for ($IndexEntryCounter = 0; $IndexEntryCounter < $thisfile_asf_asfindexobject['index_entry_count']; $IndexEntryCounter++) {
1276                                                for ($IndexSpecifiersCounter = 0; $IndexSpecifiersCounter < $thisfile_asf_asfindexobject['index_specifiers_count']; $IndexSpecifiersCounter++) {
1277                                                        $thisfile_asf_asfindexobject['offsets'][$IndexSpecifiersCounter][$IndexEntryCounter] = getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 4));
1278                                                        $offset += 4;
1279                                                }
1280                                        }
1281                                        break;
1282
1283
1284                                default:
1285                                        // Implementations shall ignore any standard or non-standard object that they do not know how to handle.
1286                                        if ($this->GUIDname($NextObjectGUIDtext)) {
1287                                                $ThisFileInfo['warning'][] = 'unhandled GUID "'.$this->GUIDname($NextObjectGUIDtext).'" {'.$NextObjectGUIDtext.'} in ASF body at offset '.($offset - 16 - 8);
1288                                        } else {
1289                                                $ThisFileInfo['warning'][] = 'unknown GUID {'.$NextObjectGUIDtext.'} in ASF body at offset '.(ftell($fd) - 16 - 8);
1290                                        }
1291                                        fseek($fd, ($NextObjectSize - 16 - 8), SEEK_CUR);
1292                                        break;
1293                        }
1294                }
1295
1296                if (isset($thisfile_asf_codeclistobject['codec_entries']) && is_array($thisfile_asf_codeclistobject['codec_entries'])) {
1297                        foreach ($thisfile_asf_codeclistobject['codec_entries'] as $streamnumber => $streamdata) {
1298                                switch ($streamdata['information']) {
1299                                        case 'WMV1':
1300                                        case 'WMV2':
1301                                        case 'WMV3':
1302                    case 'MSS1':
1303                    case 'MSS2':
1304                    case 'WMVA':
1305                    case 'WVC1':
1306                    case 'WMVP':
1307                    case 'WVP2':
1308                                                $thisfile_video['dataformat'] = 'wmv';
1309                                                $ThisFileInfo['mime_type']    = 'video/x-ms-wmv';
1310                                                break;
1311
1312                                        case 'MP42':
1313                                        case 'MP43':
1314                                        case 'MP4S':
1315                                        case 'mp4s':
1316                                                $thisfile_video['dataformat'] = 'asf';
1317                                                $ThisFileInfo['mime_type']    = 'video/x-ms-asf';
1318                                                break;
1319
1320                                        default:
1321                                                switch ($streamdata['type_raw']) {
1322                                                        case 1:
1323                                                                if (strstr($this->TrimConvert($streamdata['name']), 'Windows Media')) {
1324                                                                        $thisfile_video['dataformat'] = 'wmv';
1325                                                                        if ($ThisFileInfo['mime_type'] == 'video/x-ms-asf') {
1326                                                                                $ThisFileInfo['mime_type'] = 'video/x-ms-wmv';
1327                                                                        }
1328                                                                }
1329                                                                break;
1330
1331                                                        case 2:
1332                                                                if (strstr($this->TrimConvert($streamdata['name']), 'Windows Media')) {
1333                                                                        $thisfile_audio['dataformat'] = 'wma';
1334                                                                        if ($ThisFileInfo['mime_type'] == 'video/x-ms-asf') {
1335                                                                                $ThisFileInfo['mime_type'] = 'audio/x-ms-wma';
1336                                                                        }
1337                                                                }
1338                                                                break;
1339
1340                                                }
1341                                                break;
1342                                }
1343                        }
1344                }
1345
1346                switch (@$thisfile_audio['codec']) {
1347                        case 'MPEG Layer-3':
1348                                $thisfile_audio['dataformat'] = 'mp3';
1349                                break;
1350
1351                        default:
1352                                break;
1353                }
1354
1355                if (isset($thisfile_asf_codeclistobject['codec_entries'])) {
1356                        foreach ($thisfile_asf_codeclistobject['codec_entries'] as $streamnumber => $streamdata) {
1357                                switch ($streamdata['type_raw']) {
1358
1359                                        case 1: // video
1360                                                $thisfile_video['encoder'] = $this->TrimConvert($thisfile_asf_codeclistobject['codec_entries'][$streamnumber]['name']);
1361                                                break;
1362
1363                                        case 2: // audio
1364                                                $thisfile_audio['encoder'] = $this->TrimConvert($thisfile_asf_codeclistobject['codec_entries'][$streamnumber]['name']);
1365
1366                                                // AH 2003-10-01
1367                                                $thisfile_audio['encoder_options'] = $this->TrimConvert($thisfile_asf_codeclistobject['codec_entries'][0]['description']);
1368
1369                                                $thisfile_audio['codec']   = $thisfile_audio['encoder'];
1370                                                break;
1371
1372                                        default:
1373                                                $ThisFileInfo['warning'][] = 'Unknown streamtype: [codec_list_object][codec_entries]['.$streamnumber.'][type_raw] == '.$streamdata['type_raw'];
1374                                                break;
1375
1376                                }
1377                        }
1378                }
1379
1380                if (isset($ThisFileInfo['audio'])) {
1381                        $thisfile_audio['lossless']           = (isset($thisfile_audio['lossless'])           ? $thisfile_audio['lossless']           : false);
1382                        $thisfile_audio['dataformat']         = (!empty($thisfile_audio['dataformat'])        ? $thisfile_audio['dataformat']         : 'asf');
1383                }
1384                if (!empty($thisfile_video['dataformat'])) {
1385                        $thisfile_video['lossless']           = (isset($thisfile_audio['lossless'])           ? $thisfile_audio['lossless']           : false);
1386                        $thisfile_video['pixel_aspect_ratio'] = (isset($thisfile_audio['pixel_aspect_ratio']) ? $thisfile_audio['pixel_aspect_ratio'] : (float) 1);
1387                        $thisfile_video['dataformat']         = (!empty($thisfile_video['dataformat'])        ? $thisfile_video['dataformat']         : 'asf');
1388                }
1389                if (!empty($thisfile_video['streams'])) {
1390                        $thisfile_video['streams']['resolution_x'] = 0;
1391                        $thisfile_video['streams']['resolution_y'] = 0;
1392                        foreach ($thisfile_video['streams'] as $key => $valuearray) {
1393                                if (($valuearray['resolution_x'] > $thisfile_video['streams']['resolution_x']) || ($valuearray['resolution_y'] > $thisfile_video['streams']['resolution_y'])) {
1394                                        $thisfile_video['resolution_x'] = $valuearray['resolution_x'];
1395                                        $thisfile_video['resolution_y'] = $valuearray['resolution_y'];
1396                                }
1397                        }
1398                }
1399                $ThisFileInfo['bitrate'] = @$thisfile_audio['bitrate'] + @$thisfile_video['bitrate'];
1400
1401                if ((!isset($ThisFileInfo['playtime_seconds']) || ($ThisFileInfo['playtime_seconds'] <= 0)) && ($ThisFileInfo['bitrate'] > 0)) {
1402                        $ThisFileInfo['playtime_seconds'] = ($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset']) / ($ThisFileInfo['bitrate'] / 8);
1403                }
1404
1405                return true;
1406        }
1407
1408        function ASFCodecListObjectTypeLookup($CodecListType) {
1409                static $ASFCodecListObjectTypeLookup = array();
1410                if (empty($ASFCodecListObjectTypeLookup)) {
1411                        $ASFCodecListObjectTypeLookup[0x0001] = 'Video Codec';
1412                        $ASFCodecListObjectTypeLookup[0x0002] = 'Audio Codec';
1413                        $ASFCodecListObjectTypeLookup[0xFFFF] = 'Unknown Codec';
1414                }
1415
1416                return (isset($ASFCodecListObjectTypeLookup[$CodecListType]) ? $ASFCodecListObjectTypeLookup[$CodecListType] : 'Invalid Codec Type');
1417        }
1418
1419        function KnownGUIDs() {
1420                static $GUIDarray = array();
1421                if (empty($GUIDarray)) {
1422                        $GUIDarray['GETID3_ASF_Extended_Stream_Properties_Object']   = '14E6A5CB-C672-4332-8399-A96952065B5A';
1423                        $GUIDarray['GETID3_ASF_Padding_Object']                      = '1806D474-CADF-4509-A4BA-9AABCB96AAE8';
1424                        $GUIDarray['GETID3_ASF_Payload_Ext_Syst_Pixel_Aspect_Ratio'] = '1B1EE554-F9EA-4BC8-821A-376B74E4C4B8';
1425                        $GUIDarray['GETID3_ASF_Script_Command_Object']               = '1EFB1A30-0B62-11D0-A39B-00A0C90348F6';
1426                        $GUIDarray['GETID3_ASF_No_Error_Correction']                 = '20FB5700-5B55-11CF-A8FD-00805F5C442B';
1427                        $GUIDarray['GETID3_ASF_Content_Branding_Object']             = '2211B3FA-BD23-11D2-B4B7-00A0C955FC6E';
1428                        $GUIDarray['GETID3_ASF_Content_Encryption_Object']           = '2211B3FB-BD23-11D2-B4B7-00A0C955FC6E';
1429                        $GUIDarray['GETID3_ASF_Digital_Signature_Object']            = '2211B3FC-BD23-11D2-B4B7-00A0C955FC6E';
1430                        $GUIDarray['GETID3_ASF_Extended_Content_Encryption_Object']  = '298AE614-2622-4C17-B935-DAE07EE9289C';
1431                        $GUIDarray['GETID3_ASF_Simple_Index_Object']                 = '33000890-E5B1-11CF-89F4-00A0C90349CB';
1432                        $GUIDarray['GETID3_ASF_Degradable_JPEG_Media']               = '35907DE0-E415-11CF-A917-00805F5C442B';
1433                        $GUIDarray['GETID3_ASF_Payload_Extension_System_Timecode']   = '399595EC-8667-4E2D-8FDB-98814CE76C1E';
1434                        $GUIDarray['GETID3_ASF_Binary_Media']                        = '3AFB65E2-47EF-40F2-AC2C-70A90D71D343';
1435                        $GUIDarray['GETID3_ASF_Timecode_Index_Object']               = '3CB73FD0-0C4A-4803-953D-EDF7B6228F0C';
1436                        $GUIDarray['GETID3_ASF_Metadata_Library_Object']             = '44231C94-9498-49D1-A141-1D134E457054';
1437                        $GUIDarray['GETID3_ASF_Reserved_3']                          = '4B1ACBE3-100B-11D0-A39B-00A0C90348F6';
1438                        $GUIDarray['GETID3_ASF_Reserved_4']                          = '4CFEDB20-75F6-11CF-9C0F-00A0C90349CB';
1439                        $GUIDarray['GETID3_ASF_Command_Media']                       = '59DACFC0-59E6-11D0-A3AC-00A0C90348F6';
1440                        $GUIDarray['GETID3_ASF_Header_Extension_Object']             = '5FBF03B5-A92E-11CF-8EE3-00C00C205365';
1441                        $GUIDarray['GETID3_ASF_Media_Object_Index_Parameters_Obj']   = '6B203BAD-3F11-4E84-ACA8-D7613DE2CFA7';
1442                        $GUIDarray['GETID3_ASF_Header_Object']                       = '75B22630-668E-11CF-A6D9-00AA0062CE6C';
1443                        $GUIDarray['GETID3_ASF_Content_Description_Object']          = '75B22633-668E-11CF-A6D9-00AA0062CE6C';
1444                        $GUIDarray['GETID3_ASF_Error_Correction_Object']             = '75B22635-668E-11CF-A6D9-00AA0062CE6C';
1445                        $GUIDarray['GETID3_ASF_Data_Object']                         = '75B22636-668E-11CF-A6D9-00AA0062CE6C';
1446                        $GUIDarray['GETID3_ASF_Web_Stream_Media_Subtype']            = '776257D4-C627-41CB-8F81-7AC7FF1C40CC';
1447                        $GUIDarray['GETID3_ASF_Stream_Bitrate_Properties_Object']    = '7BF875CE-468D-11D1-8D82-006097C9A2B2';
1448                        $GUIDarray['GETID3_ASF_Language_List_Object']                = '7C4346A9-EFE0-4BFC-B229-393EDE415C85';
1449                        $GUIDarray['GETID3_ASF_Codec_List_Object']                   = '86D15240-311D-11D0-A3A4-00A0C90348F6';
1450                        $GUIDarray['GETID3_ASF_Reserved_2']                          = '86D15241-311D-11D0-A3A4-00A0C90348F6';
1451                        $GUIDarray['GETID3_ASF_File_Properties_Object']              = '8CABDCA1-A947-11CF-8EE4-00C00C205365';
1452                        $GUIDarray['GETID3_ASF_File_Transfer_Media']                 = '91BD222C-F21C-497A-8B6D-5AA86BFC0185';
1453                        $GUIDarray['GETID3_ASF_Old_RTP_Extension_Data']              = '96800C63-4C94-11D1-837B-0080C7A37F95';
1454                        $GUIDarray['GETID3_ASF_Advanced_Mutual_Exclusion_Object']    = 'A08649CF-4775-4670-8A16-6E35357566CD';
1455                        $GUIDarray['GETID3_ASF_Bandwidth_Sharing_Object']            = 'A69609E6-517B-11D2-B6AF-00C04FD908E9';
1456                        $GUIDarray['GETID3_ASF_Reserved_1']                          = 'ABD3D211-A9BA-11cf-8EE6-00C00C205365';
1457                        $GUIDarray['GETID3_ASF_Bandwidth_Sharing_Exclusive']         = 'AF6060AA-5197-11D2-B6AF-00C04FD908E9';
1458                        $GUIDarray['GETID3_ASF_Bandwidth_Sharing_Partial']           = 'AF6060AB-5197-11D2-B6AF-00C04FD908E9';
1459                        $GUIDarray['GETID3_ASF_JFIF_Media']                          = 'B61BE100-5B4E-11CF-A8FD-00805F5C442B';
1460                        $GUIDarray['GETID3_ASF_Stream_Properties_Object']            = 'B7DC0791-A9B7-11CF-8EE6-00C00C205365';
1461                        $GUIDarray['GETID3_ASF_Video_Media']                         = 'BC19EFC0-5B4D-11CF-A8FD-00805F5C442B';
1462                        $GUIDarray['GETID3_ASF_Audio_Spread']                        = 'BFC3CD50-618F-11CF-8BB2-00AA00B4E220';
1463                        $GUIDarray['GETID3_ASF_Metadata_Object']                     = 'C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA';
1464                        $GUIDarray['GETID3_ASF_Payload_Ext_Syst_Sample_Duration']    = 'C6BD9450-867F-4907-83A3-C77921B733AD';
1465                        $GUIDarray['GETID3_ASF_Group_Mutual_Exclusion_Object']       = 'D1465A40-5A79-4338-B71B-E36B8FD6C249';
1466                        $GUIDarray['GETID3_ASF_Extended_Content_Description_Object'] = 'D2D0A440-E307-11D2-97F0-00A0C95EA850';
1467                        $GUIDarray['GETID3_ASF_Stream_Prioritization_Object']        = 'D4FED15B-88D3-454F-81F0-ED5C45999E24';
1468                        $GUIDarray['GETID3_ASF_Payload_Ext_System_Content_Type']     = 'D590DC20-07BC-436C-9CF7-F3BBFBF1A4DC';
1469                        $GUIDarray['GETID3_ASF_Old_File_Properties_Object']          = 'D6E229D0-35DA-11D1-9034-00A0C90349BE';
1470                        $GUIDarray['GETID3_ASF_Old_ASF_Header_Object']               = 'D6E229D1-35DA-11D1-9034-00A0C90349BE';
1471                        $GUIDarray['GETID3_ASF_Old_ASF_Data_Object']                 = 'D6E229D2-35DA-11D1-9034-00A0C90349BE';
1472                        $GUIDarray['GETID3_ASF_Index_Object']                        = 'D6E229D3-35DA-11D1-9034-00A0C90349BE';
1473                        $GUIDarray['GETID3_ASF_Old_Stream_Properties_Object']        = 'D6E229D4-35DA-11D1-9034-00A0C90349BE';
1474                        $GUIDarray['GETID3_ASF_Old_Content_Description_Object']      = 'D6E229D5-35DA-11D1-9034-00A0C90349BE';
1475                        $GUIDarray['GETID3_ASF_Old_Script_Command_Object']           = 'D6E229D6-35DA-11D1-9034-00A0C90349BE';
1476                        $GUIDarray['GETID3_ASF_Old_Marker_Object']                   = 'D6E229D7-35DA-11D1-9034-00A0C90349BE';
1477                        $GUIDarray['GETID3_ASF_Old_Component_Download_Object']       = 'D6E229D8-35DA-11D1-9034-00A0C90349BE';
1478                        $GUIDarray['GETID3_ASF_Old_Stream_Group_Object']             = 'D6E229D9-35DA-11D1-9034-00A0C90349BE';
1479                        $GUIDarray['GETID3_ASF_Old_Scalable_Object']                 = 'D6E229DA-35DA-11D1-9034-00A0C90349BE';
1480                        $GUIDarray['GETID3_ASF_Old_Prioritization_Object']           = 'D6E229DB-35DA-11D1-9034-00A0C90349BE';
1481                        $GUIDarray['GETID3_ASF_Bitrate_Mutual_Exclusion_Object']     = 'D6E229DC-35DA-11D1-9034-00A0C90349BE';
1482                        $GUIDarray['GETID3_ASF_Old_Inter_Media_Dependency_Object']   = 'D6E229DD-35DA-11D1-9034-00A0C90349BE';
1483                        $GUIDarray['GETID3_ASF_Old_Rating_Object']                   = 'D6E229DE-35DA-11D1-9034-00A0C90349BE';
1484                        $GUIDarray['GETID3_ASF_Index_Parameters_Object']             = 'D6E229DF-35DA-11D1-9034-00A0C90349BE';
1485                        $GUIDarray['GETID3_ASF_Old_Color_Table_Object']              = 'D6E229E0-35DA-11D1-9034-00A0C90349BE';
1486                        $GUIDarray['GETID3_ASF_Old_Language_List_Object']            = 'D6E229E1-35DA-11D1-9034-00A0C90349BE';
1487                        $GUIDarray['GETID3_ASF_Old_Audio_Media']                     = 'D6E229E2-35DA-11D1-9034-00A0C90349BE';
1488                        $GUIDarray['GETID3_ASF_Old_Video_Media']                     = 'D6E229E3-35DA-11D1-9034-00A0C90349BE';
1489                        $GUIDarray['GETID3_ASF_Old_Image_Media']                     = 'D6E229E4-35DA-11D1-9034-00A0C90349BE';
1490                        $GUIDarray['GETID3_ASF_Old_Timecode_Media']                  = 'D6E229E5-35DA-11D1-9034-00A0C90349BE';
1491                        $GUIDarray['GETID3_ASF_Old_Text_Media']                      = 'D6E229E6-35DA-11D1-9034-00A0C90349BE';
1492                        $GUIDarray['GETID3_ASF_Old_MIDI_Media']                      = 'D6E229E7-35DA-11D1-9034-00A0C90349BE';
1493                        $GUIDarray['GETID3_ASF_Old_Command_Media']                   = 'D6E229E8-35DA-11D1-9034-00A0C90349BE';
1494                        $GUIDarray['GETID3_ASF_Old_No_Error_Concealment']            = 'D6E229EA-35DA-11D1-9034-00A0C90349BE';
1495                        $GUIDarray['GETID3_ASF_Old_Scrambled_Audio']                 = 'D6E229EB-35DA-11D1-9034-00A0C90349BE';
1496                        $GUIDarray['GETID3_ASF_Old_No_Color_Table']                  = 'D6E229EC-35DA-11D1-9034-00A0C90349BE';
1497                        $GUIDarray['GETID3_ASF_Old_SMPTE_Time']                      = 'D6E229ED-35DA-11D1-9034-00A0C90349BE';
1498                        $GUIDarray['GETID3_ASF_Old_ASCII_Text']                      = 'D6E229EE-35DA-11D1-9034-00A0C90349BE';
1499                        $GUIDarray['GETID3_ASF_Old_Unicode_Text']                    = 'D6E229EF-35DA-11D1-9034-00A0C90349BE';
1500                        $GUIDarray['GETID3_ASF_Old_HTML_Text']                       = 'D6E229F0-35DA-11D1-9034-00A0C90349BE';
1501                        $GUIDarray['GETID3_ASF_Old_URL_Command']                     = 'D6E229F1-35DA-11D1-9034-00A0C90349BE';
1502                        $GUIDarray['GETID3_ASF_Old_Filename_Command']                = 'D6E229F2-35DA-11D1-9034-00A0C90349BE';
1503                        $GUIDarray['GETID3_ASF_Old_ACM_Codec']                       = 'D6E229F3-35DA-11D1-9034-00A0C90349BE';
1504                        $GUIDarray['GETID3_ASF_Old_VCM_Codec']                       = 'D6E229F4-35DA-11D1-9034-00A0C90349BE';
1505                        $GUIDarray['GETID3_ASF_Old_QuickTime_Codec']                 = 'D6E229F5-35DA-11D1-9034-00A0C90349BE';
1506                        $GUIDarray['GETID3_ASF_Old_DirectShow_Transform_Filter']     = 'D6E229F6-35DA-11D1-9034-00A0C90349BE';
1507                        $GUIDarray['GETID3_ASF_Old_DirectShow_Rendering_Filter']     = 'D6E229F7-35DA-11D1-9034-00A0C90349BE';
1508                        $GUIDarray['GETID3_ASF_Old_No_Enhancement']                  = 'D6E229F8-35DA-11D1-9034-00A0C90349BE';
1509                        $GUIDarray['GETID3_ASF_Old_Unknown_Enhancement_Type']        = 'D6E229F9-35DA-11D1-9034-00A0C90349BE';
1510                        $GUIDarray['GETID3_ASF_Old_Temporal_Enhancement']            = 'D6E229FA-35DA-11D1-9034-00A0C90349BE';
1511                        $GUIDarray['GETID3_ASF_Old_Spatial_Enhancement']             = 'D6E229FB-35DA-11D1-9034-00A0C90349BE';
1512                        $GUIDarray['GETID3_ASF_Old_Quality_Enhancement']             = 'D6E229FC-35DA-11D1-9034-00A0C90349BE';
1513                        $GUIDarray['GETID3_ASF_Old_Number_of_Channels_Enhancement']  = 'D6E229FD-35DA-11D1-9034-00A0C90349BE';
1514                        $GUIDarray['GETID3_ASF_Old_Frequency_Response_Enhancement']  = 'D6E229FE-35DA-11D1-9034-00A0C90349BE';
1515                        $GUIDarray['GETID3_ASF_Old_Media_Object']                    = 'D6E229FF-35DA-11D1-9034-00A0C90349BE';
1516                        $GUIDarray['GETID3_ASF_Mutex_Language']                      = 'D6E22A00-35DA-11D1-9034-00A0C90349BE';
1517                        $GUIDarray['GETID3_ASF_Mutex_Bitrate']                       = 'D6E22A01-35DA-11D1-9034-00A0C90349BE';
1518                        $GUIDarray['GETID3_ASF_Mutex_Unknown']                       = 'D6E22A02-35DA-11D1-9034-00A0C90349BE';
1519                        $GUIDarray['GETID3_ASF_Old_ASF_Placeholder_Object']          = 'D6E22A0E-35DA-11D1-9034-00A0C90349BE';
1520                        $GUIDarray['GETID3_ASF_Old_Data_Unit_Extension_Object']      = 'D6E22A0F-35DA-11D1-9034-00A0C90349BE';
1521                        $GUIDarray['GETID3_ASF_Web_Stream_Format']                   = 'DA1E6B13-8359-4050-B398-388E965BF00C';
1522                        $GUIDarray['GETID3_ASF_Payload_Ext_System_File_Name']        = 'E165EC0E-19ED-45D7-B4A7-25CBD1E28E9B';
1523                        $GUIDarray['GETID3_ASF_Marker_Object']                       = 'F487CD01-A951-11CF-8EE6-00C00C205365';
1524                        $GUIDarray['GETID3_ASF_Timecode_Index_Parameters_Object']    = 'F55E496D-9797-4B5D-8C8B-604DFE9BFB24';
1525                        $GUIDarray['GETID3_ASF_Audio_Media']                         = 'F8699E40-5B4D-11CF-A8FD-00805F5C442B';
1526                        $GUIDarray['GETID3_ASF_Media_Object_Index_Object']           = 'FEB103F8-12AD-4C64-840F-2A1D2F7AD48C';
1527                        $GUIDarray['GETID3_ASF_Alt_Extended_Content_Encryption_Obj'] = 'FF889EF1-ADEE-40DA-9E71-98704BB928CE';
1528                }
1529                return $GUIDarray;
1530        }
1531
1532        function GUIDname($GUIDstring) {
1533                static $GUIDarray = array();
1534                if (empty($GUIDarray)) {
1535                        $GUIDarray = $this->KnownGUIDs();
1536                }
1537                return array_search($GUIDstring, $GUIDarray);
1538        }
1539
1540        function ASFIndexObjectIndexTypeLookup($id) {
1541                static $ASFIndexObjectIndexTypeLookup = array();
1542                if (empty($ASFIndexObjectIndexTypeLookup)) {
1543                        $ASFIndexObjectIndexTypeLookup[1] = 'Nearest Past Data Packet';
1544                        $ASFIndexObjectIndexTypeLookup[2] = 'Nearest Past Media Object';
1545                        $ASFIndexObjectIndexTypeLookup[3] = 'Nearest Past Cleanpoint';
1546                }
1547                return (isset($ASFIndexObjectIndexTypeLookup[$id]) ? $ASFIndexObjectIndexTypeLookup[$id] : 'invalid');
1548        }
1549
1550        function GUIDtoBytestring($GUIDstring) {
1551                // Microsoft defines these 16-byte (128-bit) GUIDs in the strangest way:
1552                // first 4 bytes are in little-endian order
1553                // next 2 bytes are appended in little-endian order
1554                // next 2 bytes are appended in little-endian order
1555                // next 2 bytes are appended in big-endian order
1556                // next 6 bytes are appended in big-endian order
1557
1558                // AaBbCcDd-EeFf-GgHh-IiJj-KkLlMmNnOoPp is stored as this 16-byte string:
1559                // $Dd $Cc $Bb $Aa $Ff $Ee $Hh $Gg $Ii $Jj $Kk $Ll $Mm $Nn $Oo $Pp
1560
1561                $hexbytecharstring  = chr(hexdec(substr($GUIDstring,  6, 2)));
1562                $hexbytecharstring .= chr(hexdec(substr($GUIDstring,  4, 2)));
1563                $hexbytecharstring .= chr(hexdec(substr($GUIDstring,  2, 2)));
1564                $hexbytecharstring .= chr(hexdec(substr($GUIDstring,  0, 2)));
1565
1566                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 11, 2)));
1567                $hexbytecharstring .= chr(hexdec(substr($GUIDstring,  9, 2)));
1568
1569                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 16, 2)));
1570                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 14, 2)));
1571
1572                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 19, 2)));
1573                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 21, 2)));
1574
1575                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 24, 2)));
1576                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 26, 2)));
1577                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 28, 2)));
1578                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 30, 2)));
1579                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 32, 2)));
1580                $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 34, 2)));
1581
1582                return $hexbytecharstring;
1583        }
1584
1585        function BytestringToGUID($Bytestring) {
1586                $GUIDstring  = str_pad(dechex(ord($Bytestring{3})),  2, '0', STR_PAD_LEFT);
1587                $GUIDstring .= str_pad(dechex(ord($Bytestring{2})),  2, '0', STR_PAD_LEFT);
1588                $GUIDstring .= str_pad(dechex(ord($Bytestring{1})),  2, '0', STR_PAD_LEFT);
1589                $GUIDstring .= str_pad(dechex(ord($Bytestring{0})),  2, '0', STR_PAD_LEFT);
1590                $GUIDstring .= '-';
1591                $GUIDstring .= str_pad(dechex(ord($Bytestring{5})),  2, '0', STR_PAD_LEFT);
1592                $GUIDstring .= str_pad(dechex(ord($Bytestring{4})),  2, '0', STR_PAD_LEFT);
1593                $GUIDstring .= '-';
1594                $GUIDstring .= str_pad(dechex(ord($Bytestring{7})),  2, '0', STR_PAD_LEFT);
1595                $GUIDstring .= str_pad(dechex(ord($Bytestring{6})),  2, '0', STR_PAD_LEFT);
1596                $GUIDstring .= '-';
1597                $GUIDstring .= str_pad(dechex(ord($Bytestring{8})),  2, '0', STR_PAD_LEFT);
1598                $GUIDstring .= str_pad(dechex(ord($Bytestring{9})),  2, '0', STR_PAD_LEFT);
1599                $GUIDstring .= '-';
1600                $GUIDstring .= str_pad(dechex(ord($Bytestring{10})), 2, '0', STR_PAD_LEFT);
1601                $GUIDstring .= str_pad(dechex(ord($Bytestring{11})), 2, '0', STR_PAD_LEFT);
1602                $GUIDstring .= str_pad(dechex(ord($Bytestring{12})), 2, '0', STR_PAD_LEFT);
1603                $GUIDstring .= str_pad(dechex(ord($Bytestring{13})), 2, '0', STR_PAD_LEFT);
1604                $GUIDstring .= str_pad(dechex(ord($Bytestring{14})), 2, '0', STR_PAD_LEFT);
1605                $GUIDstring .= str_pad(dechex(ord($Bytestring{15})), 2, '0', STR_PAD_LEFT);
1606
1607                return strtoupper($GUIDstring);
1608        }
1609
1610        function FILETIMEtoUNIXtime($FILETIME, $round=true) {
1611                // FILETIME is a 64-bit unsigned integer representing
1612                // the number of 100-nanosecond intervals since January 1, 1601
1613                // UNIX timestamp is number of seconds since January 1, 1970
1614                // 116444736000000000 = 10000000 * 60 * 60 * 24 * 365 * 369 + 89 leap days
1615                if ($round) {
1616                        return intval(round(($FILETIME - 116444736000000000) / 10000000));
1617                }
1618                return ($FILETIME - 116444736000000000) / 10000000;
1619        }
1620
1621        function WMpictureTypeLookup($WMpictureType) {
1622                static $WMpictureTypeLookup = array();
1623                if (empty($WMpictureTypeLookup)) {
1624                        $WMpictureTypeLookup[0x03] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Front Cover');
1625                        $WMpictureTypeLookup[0x04] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Back Cover');
1626                        $WMpictureTypeLookup[0x00] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'User Defined');
1627                        $WMpictureTypeLookup[0x05] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Leaflet Page');
1628                        $WMpictureTypeLookup[0x06] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Media Label');
1629                        $WMpictureTypeLookup[0x07] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Lead Artist');
1630                        $WMpictureTypeLookup[0x08] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Artist');
1631                        $WMpictureTypeLookup[0x09] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Conductor');
1632                        $WMpictureTypeLookup[0x0A] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Band');
1633                        $WMpictureTypeLookup[0x0B] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Composer');
1634                        $WMpictureTypeLookup[0x0C] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Lyricist');
1635                        $WMpictureTypeLookup[0x0D] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Recording Location');
1636                        $WMpictureTypeLookup[0x0E] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'During Recording');
1637                        $WMpictureTypeLookup[0x0F] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'During Performance');
1638                        $WMpictureTypeLookup[0x10] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Video Screen Capture');
1639                        $WMpictureTypeLookup[0x12] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Illustration');
1640                        $WMpictureTypeLookup[0x13] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Band Logotype');
1641                        $WMpictureTypeLookup[0x14] = getid3_lib::iconv_fallback('ISO-8859-1', 'UTF-16LE', 'Publisher Logotype');
1642                }
1643                return @$WMpictureTypeLookup[$WMpictureType];
1644        }
1645
1646
1647        // Remove terminator 00 00 and convert UNICODE to Latin-1
1648        function TrimConvert($string) {
1649
1650                // remove terminator, only if present (it should be, but...)
1651                if (substr($string, strlen($string) - 2, 2) == "\x00\x00") {
1652                        $string = substr($string, 0, strlen($string) - 2);
1653                }
1654
1655                // convert
1656                return trim(getid3_lib::iconv_fallback('UTF-16LE', 'ISO-8859-1', $string), ' ');
1657        }
1658
1659
1660        function TrimTerm($string) {
1661
1662                // remove terminator, only if present (it should be, but...)
1663                if (substr($string, -2) == "\x00\x00") {
1664                        $string = substr($string, 0, -2);
1665                }
1666                return $string;
1667        }
1668
1669
1670}
1671
1672
1673?>
Note: See TracBrowser for help on using the repository browser.