Last active
October 1, 2024 00:54
-
-
Save thetoine/ec53bc625ddeeddd1a7f79f1d43000f8 to your computer and use it in GitHub Desktop.
Rive format: extract width/height dimensions from binary file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Open the binary file | |
$filename = 'file.riv'; | |
$file = fopen($filename, 'rb'); | |
if (!$file) { | |
exit(); // Exit if file cannot be opened | |
} | |
// Read the first 4 bytes and check if it's 'RIVE' | |
$byte = fread($file, 4); | |
if ($byte !== 'RIVE') { | |
echo "Not a valid Rive file\n"; | |
exit(); // Exit if it's not a RIVE file | |
} | |
$majorVersion = fread($file, 1); // Major version | |
$minorVersion = fread($file, 1); // Minor version | |
// convert to integer | |
$majorVersion = ord($majorVersion); | |
$minorVersion = ord($minorVersion); | |
echo "Rive File Version: $majorVersion.$minorVersion\n"; | |
// Read the next byte (TOC) | |
$byte = fread($file, 1); | |
$properties = [ | |
'widths' => [], | |
'heights' => [] | |
]; | |
$minValue = 1; | |
$maxValue = 10000; | |
$widths = []; | |
$heights = []; | |
// Read all objects until the returned byte is 0, which should be the last property | |
while (!feof($file)) { | |
$value = null; | |
// Advance the byte by 1 | |
$byte = fread($file, 1); | |
if (!$byte) { | |
break; // Exit if end of file or empty byte | |
} | |
// Grab the property type | |
$property = ord($byte); // Convert the byte to an integer | |
// Next 4 bytes are the property value | |
if ($property == 7) { // width | |
$value = unpack('f', fread($file, 4))[1]; // Read 4 bytes as a float | |
if($value >= $minValue && $value <= $maxValue) { | |
$widths[] = $value; | |
} | |
} elseif ($property == 8) { // height | |
$value = unpack('f', fread($file, 4))[1]; // Read 4 bytes as a float | |
if($value >= $minValue && $value <= $maxValue) { | |
$heights[] = $value; | |
} | |
} | |
} | |
// Close the file | |
fclose($file); | |
// sort values by descending order | |
rsort($widths, SORT_NUMERIC); | |
rsort($heights, SORT_NUMERIC); | |
// return the properties (Width and Height) | |
if (isset($widths[0]) && isset($heights[0])) { | |
return [ | |
'width' => $widths[0] ?? null, | |
'height' => $heights[0] ?? null | |
]; | |
} else { | |
return null; | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment