Skip to content

Commit 4e7aca9

Browse files
authored
Merge pull request #403 from StudioMaX/2.0-with-1.9.22-202207161647
Sync 2.0 with 1.9.22-202207161647
2 parents b19ed0e + 1ea0196 commit 4e7aca9

17 files changed

+341
-56
lines changed

.github/workflows/continuous-integration.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ jobs:
2020
- "7.4"
2121
- "8.0"
2222
- "8.1"
23+
- "8.2"
2324
steps:
2425
- uses: "actions/checkout@v2"
2526
- uses: "shivammathur/setup-php@v2"
2627
with:
2728
php-version: "${{ matrix.php-version }}"
2829
ini-values: error_reporting=-1, display_errors=On
2930
coverage: "none"
30-
- uses: "ramsey/composer-install@v1"
31+
- uses: "ramsey/composer-install@v2"
3132
- name: "Run the linter"
3233
run: "composer lint -- --colors"
3334

@@ -41,7 +42,7 @@ jobs:
4142
php-version: "7.4"
4243
tools: "phpstan:0.12.99"
4344
coverage: "none"
44-
- uses: "ramsey/composer-install@v1"
45+
- uses: "ramsey/composer-install@v2"
4546
- name: "Run PHPStan"
4647
run: "phpstan analyse -c phpstan.neon -l 4 src tests"
4748

changelog.txt

+24
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,30 @@
1818
Version History
1919
===============
2020

21+
1.9.22: [2022-09-29] James Heinrich :: 1.9.22-202207161647
22+
* bugfix #387 fails to detect h265 video codec (QuickTime)
23+
* bugfix #385 Quicktime extended atom size
24+
* bugfix #378 AAC bitrate cache warning
25+
* bugfix #376 simplexml_load_string improvments
26+
* bugfix #374 MOD improved SoundTracker support
27+
* bugfix #371 fragmented MP4 unsupported warning
28+
* bugfix #369 fix remote URLs pattern
29+
* bugfix #366 change @error-suppress to isset (quicktime)
30+
* bugfix #365 ZIP array offset on value of type int
31+
* bugfix #364 add support for ANIMEXTS1.0 in GIF files
32+
* bugfix #363 ASF improve support of Header Extension Object data
33+
* bugfix #362 version update for ramsey/composer-install
34+
* bugfix #359 MPEG-2 aspect ratio divide-by-zero
35+
* bugfix #358 free format mp3 bitrate
36+
* bugfix #355 undefined array key in ID3v2 chapters
37+
* bugfix #352 avoid false detection of Musepack format
38+
* bugfix #351 Incorrect length passed to fread on a flac file
39+
* bugfix #348 more targeted usage of clearstatcache calls
40+
* bugfix #347 fixed reported by PHPStan v0.12.99
41+
* bugfix QuickTime support 'ID32' frame (ID3v2 inside QT)
42+
* bugfix fix various PHP 8.1 issues
43+
* bugfix PDF prevent undefined index
44+
2145
1.9.21: [2021-09-22] James Heinrich :: 1.9.21-202109171300
2246
» add support for RIFF.guan
2347
¤ add ID3v1 genres 148-191

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"php-parallel-lint/php-parallel-lint": "^1.0"
4242
},
4343
"scripts": {
44-
"lint": "parallel-lint --exclude vendor --exclude .git .",
44+
"lint": "parallel-lint --show-deprecated --exclude vendor --exclude .git .",
4545
"test": [
4646
"composer lint"
4747
]

readme.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ if ($fp_remote = fopen($remotefilename, 'rb')) {
188188
$remote_headers = array_change_key_case(get_headers($remotefilename, 1), CASE_LOWER);
189189
$remote_filesize = (isset($remote_headers['content-length']) ? (is_array($remote_headers['content-length']) ? $remote_headers['content-length'][count($remote_headers['content-length']) - 1] : $remote_headers['content-length']) : null);
190190

191-
// Initialize getID3 engine
192-
$getID3 = new getID3;
191+
// Initialize GetID3 engine
192+
$getID3 = new GetID3;
193193

194194
$ThisFileInfo = $getID3->analyze($localtempfilename, $remote_filesize, basename($remotefilename));
195195

src/GetID3.php

+11-10
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class GetID3
119119
public $option_md5_data = false;
120120

121121
/**
122-
* Use MD5 of source file if availble - only FLAC and OptimFROG
122+
* Use MD5 of source file if available - only FLAC and OptimFROG
123123
*
124124
* @var bool
125125
*/
@@ -319,7 +319,7 @@ class GetID3
319319
*/
320320
protected $startup_warning = '';
321321

322-
const VERSION = '2.0.x-202112151109';
322+
const VERSION = '2.0.x-202207161647';
323323
const FREAD_BUFFER_SIZE = 32768;
324324

325325
const ATTACHMENTS_NONE = false;
@@ -887,14 +887,15 @@ public function GetFileFormatArray() {
887887
'mime_type' => 'audio/x-monkeys-audio',
888888
),
889889

890-
// has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available
891-
// // MOD - audio - MODule (assorted sub-formats)
892-
// 'mod' => array(
893-
// 'pattern' => '^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)',
894-
// 'module' => 'Audio\\Mod',
895-
// 'option' => 'mod',
896-
// 'mime_type' => 'audio/mod',
897-
// ),
890+
891+
// MOD - audio - MODule (SoundTracker)
892+
'mod' => array(
893+
//'pattern' => '^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)', // has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available
894+
'pattern' => '^.{1080}(M\\.K\\.)',
895+
'module' => 'Audio\\Mod',
896+
'option' => 'mod',
897+
'mime_type' => 'audio/mod',
898+
),
898899

899900
// MOD - audio - MODule (Impulse Tracker)
900901
'it' => array(

src/Module/Archive/Zip.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ public function ZIPparseLocalFileHeader() {
297297
$DataDescriptor = $this->fread(16);
298298
$LocalFileHeader['data_descriptor']['signature'] = Utils::LittleEndian2Int(substr($DataDescriptor, 0, 4));
299299
if ($LocalFileHeader['data_descriptor']['signature'] != 0x08074B50) { // "PK\x07\x08"
300-
$this->getid3->warning('invalid Local File Header Data Descriptor Signature at offset '.($this->ftell() - 16).' - expecting 08 07 4B 50, found '.Utils::PrintHexBytes($LocalFileHeader['data_descriptor']['signature']));
300+
$this->getid3->warning('invalid Local File Header Data Descriptor Signature at offset '.($this->ftell() - 16).' - expecting 08 07 4B 50, found '.Utils::PrintHexBytes(substr($DataDescriptor, 0, 4)));
301301
$this->fseek($LocalFileHeader['offset']); // seek back to where filepointer originally was so it can be handled properly
302302
return false;
303303
}

src/Module/Audio/Aac.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ public function getAACADTSheaderFilepointer($MaxFramesToScan=1000000, $ReturnExt
400400
if (!isset($BitrateCache[$FrameLength])) {
401401
$BitrateCache[$FrameLength] = ($info['aac']['header']['sample_frequency'] / 1024) * $FrameLength * 8;
402402
}
403-
Utils::safe_inc($info['aac']['bitrate_distribution'][$BitrateCache[$FrameLength]], 1);
403+
Utils::safe_inc($info['aac']['bitrate_distribution'][(string)$BitrateCache[$FrameLength]], 1);
404404

405405
$info['aac'][$framenumber]['aac_frame_length'] = $FrameLength;
406406

src/Module/Audio/Mod.php

+49-9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
/////////////////////////////////////////////////////////////////
1717

1818
use JamesHeinrich\GetID3\Module\Handler;
19+
use JamesHeinrich\GetID3\Utils;
1920

2021
class Mod extends Handler
2122
{
@@ -30,9 +31,17 @@ public function Analyze() {
3031
return $this->getITheaderFilepointer();
3132
} elseif (preg_match('#^Extended Module#', $fileheader)) {
3233
return $this->getXMheaderFilepointer();
33-
} elseif (preg_match('#^.{44}SCRM#', $fileheader)) {
34+
} elseif (preg_match('#^.{44}SCRM#s', $fileheader)) {
3435
return $this->getS3MheaderFilepointer();
35-
} elseif (preg_match('#^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)#', $fileheader)) {
36+
//} elseif (preg_match('#^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)#s', $fileheader)) {
37+
} elseif (preg_match('#^.{1080}(M\\.K\\.)#s', $fileheader)) {
38+
/*
39+
The four letters "M.K." - This is something Mahoney & Kaktus inserted when they
40+
increased the number of samples from 15 to 31. If it's not there, the module/song
41+
uses 15 samples or the text has been removed to make the module harder to rip.
42+
Startrekker puts "FLT4" or "FLT8" there instead.
43+
If there are more than 64 patterns, PT2.3 will insert M!K! here.
44+
*/
3645
return $this->getMODheaderFilepointer();
3746
}
3847
$this->error('This is not a known type of MOD file');
@@ -44,17 +53,48 @@ public function Analyze() {
4453
*/
4554
public function getMODheaderFilepointer() {
4655
$info = &$this->getid3->info;
47-
$this->fseek($info['avdataoffset'] + 1080);
48-
$FormatID = $this->fread(4);
49-
if (!preg_match('#^(M.K.|[5-9]CHN|[1-3][0-9]CH)$#', $FormatID)) {
50-
$this->error('This is not a known type of MOD file');
56+
$this->fseek($info['avdataoffset']);
57+
$filedata = $this->fread(1084);
58+
//if (!preg_match('#^(M.K.|[5-9]CHN|[1-3][0-9]CH)$#', $FormatID)) {
59+
if (substr($filedata, 1080, 4) == 'M.K.') {
60+
61+
// + 0 song/module working title
62+
// + 20 15 sample headers (see below)
63+
// + 470 song length (number of steps in pattern table)
64+
// + 471 song speed in beats per minute (see below)
65+
// + 472 pattern step table
66+
$offset = 0;
67+
$info['mod']['title'] = rtrim(substr($filedata, $offset, 20), "\x00"); $offset += 20;
68+
69+
$info['tags']['mod']['title'] = array($info['mod']['title']);
70+
71+
for ($samplenumber = 0; $samplenumber <= 30; $samplenumber++) {
72+
$sampledata = array();
73+
$sampledata['name'] = substr($filedata, $offset, 22); $offset += 22;
74+
$sampledata['length'] = Utils::BigEndian2Int(substr($filedata, $offset, 2)); $offset += 2;
75+
$sampledata['volume'] = Utils::BigEndian2Int(substr($filedata, $offset, 2)); $offset += 2;
76+
$sampledata['repeat_offset'] = Utils::BigEndian2Int(substr($filedata, $offset, 2)); $offset += 2;
77+
$sampledata['repeat_length'] = Utils::BigEndian2Int(substr($filedata, $offset, 2)); $offset += 2;
78+
$info['mod']['samples'][$samplenumber] = $sampledata;
79+
}
80+
81+
$info['mod']['song_length'] = Utils::BigEndian2Int(substr($filedata, $offset++, 1));// Songlength. Range is 1-128.
82+
$info['mod']['bpm'] = Utils::BigEndian2Int(substr($filedata, $offset++, 1));// This byte is set to 127, so that old trackers will search through all patterns when loading. Noisetracker uses this byte for restart, ProTracker doesn't.
83+
84+
for ($songposition = 0; $songposition <= 127; $songposition++) {
85+
// Song positions 0-127. Each hold a number from 0-63 (or 0-127)
86+
// that tells the tracker what pattern to play at that position.
87+
$info['mod']['song_positions'][$songposition] = Utils::BigEndian2Int(substr($filedata, $offset++, 1));
88+
}
89+
90+
} else {
91+
$this->error('unknown MOD ID at offset 1080: '.Utils::PrintHexBytes(substr($filedata, 1080, 4)));
5192
return false;
5293
}
53-
5494
$info['fileformat'] = 'mod';
5595

56-
$this->error('MOD parsing not enabled in this version of getID3() ['.$this->getid3->version().']');
57-
return false;
96+
$this->warning('MOD (SoundTracker) parsing incomplete in this version of getID3() ['.$this->getid3->version().']');
97+
return true;
5898
}
5999

60100
/**

src/Module/Audio/Mp3.php

+8-3
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,10 @@ public function GuessEncoderOptions() {
315315
$encoder_options .= ' -b'.$thisfile_mpeg_audio_lame['bitrate_min'];
316316
}
317317

318+
if (isset($thisfile_mpeg_audio['bitrate']) && $thisfile_mpeg_audio['bitrate'] === 'free') {
319+
$encoder_options .= ' --freeformat';
320+
}
321+
318322
if (!empty($thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev']) || !empty($thisfile_mpeg_audio_lame['encoding_flags']['nogap_next'])) {
319323
$encoder_options .= ' --nogap';
320324
}
@@ -750,7 +754,8 @@ public function decodeMPEGaudioHeader($offset, &$info, $recursivesearch=true, $S
750754
unset($thisfile_mpeg_audio_lame['long_version']);
751755

752756
// It the LAME tag was only introduced in LAME v3.90
753-
// http://www.hydrogenaudio.org/?act=ST&f=15&t=9933
757+
// https://wiki.hydrogenaud.io/index.php/LAME#VBR_header_and_LAME_tag
758+
// https://hydrogenaud.io/index.php?topic=9933
754759

755760
// Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html
756761
// are assuming a 'Xing' identifier offset of 0x24, which is the case for
@@ -786,7 +791,7 @@ public function decodeMPEGaudioHeader($offset, &$info, $recursivesearch=true, $S
786791
$thisfile_mpeg_audio_lame['lowpass_frequency'] = Utils::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
787792

788793
// bytes $A7-$AE Replay Gain
789-
// http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html
794+
// https://web.archive.org/web/20021015212753/http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html
790795
// bytes $A7-$AA : 32 bit floating point "Peak signal amplitude"
791796
if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') {
792797
// LAME 3.94a16 and later - 9.23 fixed point
@@ -914,7 +919,7 @@ public function decodeMPEGaudioHeader($offset, &$info, $recursivesearch=true, $S
914919

915920

916921
// LAME CBR
917-
if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) {
922+
if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1 && $thisfile_mpeg_audio['bitrate'] !== 'free') {
918923

919924
$thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
920925
$thisfile_mpeg_audio['bitrate'] = self::ClosestStandardMP3Bitrate($thisfile_mpeg_audio['bitrate']);

src/Module/Audio/Ogg.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ public function Analyze() {
185185
if ($info['ogg']['pageheader']['theora']['pixel_aspect_denominator'] > 0) {
186186
$info['video']['pixel_aspect_ratio'] = (float) $info['ogg']['pageheader']['theora']['pixel_aspect_numerator'] / $info['ogg']['pageheader']['theora']['pixel_aspect_denominator'];
187187
}
188-
$this->warning('Ogg Theora (v3) not fully supported in this version of getID3 ['.$this->getid3->version().'] -- bitrate, playtime and all audio data are currently unavailable');
188+
$this->warning('Ogg Theora (v3) not fully supported in this version of getID3 ['.$this->getid3->version().'] -- bitrate, playtime and all audio data are currently unavailable');
189189

190190

191191
} elseif (substr($filedata, 0, 8) == "fishead\x00") {

0 commit comments

Comments
 (0)