S
scmark15
Guest
Okay for those who read my "TIM files for those starting out" (https://www.ff7catalog.com/threads/6560/)
thread my last post had a sample code to use PHP to read 8 bit TIM files. I decided this should have its own thread because
this thread isn't about how TIM files store there data but how to view them using PHP.
What you need to begin:
-IIS or Apache Server running PHP 5
-A copy of the script below (Just copy & paste it to notepad and save it as TIMViewer.php)
-A few TIM files (must be copied to the same directory as the TIMViewer.php script)
Code: [Select]
Usage:
Open your browser and type in the address of the script ie. "localhost/TIMViewer.php?file=tim.tim"
Where "tim.tim" is change it to the file name of your TIM file.
If the file is a 4 bit or an 8 bit TIM add "&clut=x" (x is which clut you wish to use to view the image, default is 1)
=> "localhost/TIMViewer.php?file=mytim.tim&clut=1" (this would view the image with the 1st clut from the mytim.tim file)
Notes:
-This is not the most efficient coding or fastest loading but it does work.
-Big TIM files might take a long time to load.
-This script is writen purely by me and can be edited freely (Please post your updated code if you modify)
-Script does not show image as any graphic file (it's actually a table <= maybe why it's slow loading)
Tested with:
- Works with FF6 character faces (4bpp)
- Works with FF7 character faces (8bpp)
- Works with FF9 game over screen (16bpp)
- Works with adobe TIM plugin for all bpp (used to test 24bpp)
----------------------------------------------------------------------------------------------------------
-Enjoy
SCMark15
thread my last post had a sample code to use PHP to read 8 bit TIM files. I decided this should have its own thread because
this thread isn't about how TIM files store there data but how to view them using PHP.
What you need to begin:
-IIS or Apache Server running PHP 5
-A copy of the script below (Just copy & paste it to notepad and save it as TIMViewer.php)
-A few TIM files (must be copied to the same directory as the TIMViewer.php script)
Code: [Select]
Code:
<html><head> <title>TIM Viewer</title> <style> <!-- body, table, tr, td{ font-family: courier new; font-size: 11px; } --> </style></head><body><?phpif(isset($_GET['file'])){ $infile = $_GET['file'];}else{ die("Error: no file selected");}$curCLUT = 1;if(isset($_GET['clut'])){ $curCLUT = $_GET['clut'];}$handle = fopen($infile, 'rb');//// HEX => CONVERT => BINARY//function hexbin($strHex) { $strBin = ''; for($i = 0; $i < strlen($strHex); $i++){ $strBin .= sprintf("%04s", decbin(hexdec($strHex[$i]))); } return $strBin;}//// ABGR[1555] => CONVERT => RGB[888]//function getRGB($color){ $colorBin = hexbin(str_repeat("0", 4 - strlen(dechex($color))) . dechex($color)); $a1 = substr($colorBin, 0, 1); $b5 = substr($colorBin, 1, 5); $g5 = substr($colorBin, 6, 5); $r5 = substr($colorBin, 11, 5); $alphadec = bindec($a1); $bluedec = bindec($b5); $greendec = bindec($g5); $reddec = bindec($r5); $a8 = $alphadec * 8; // Older BGR[1555] to RGB[888] Conversion // (Output is slightly darker) // $r8 = $reddec * 8; // $g8 = $greendec * 8; // $b8 = $bluedec * 8; // New BGR[1555] to RGB[888] Conversion // (Output is slightly brighter) $r8 = round(($reddec * 8) + ($reddec / 31 * 7)); $g8 = round(($greendec * 8) + ($greendec / 31 * 7)); $b8 = round(($bluedec * 8) + ($bluedec / 31 * 7)); // Alpha is ignored // $RGBAlpha = strtoupper(str_repeat("0", 2-strlen(dechex($a8))) . dechex($a8)); $RGBRed = strtoupper(str_repeat("0", 2 - strlen(dechex($r8))) . dechex($r8)); $RGBGreen = strtoupper(str_repeat("0", 2 - strlen(dechex($g8))) . dechex($g8)); $RGBBlue = strtoupper(str_repeat("0", 2 - strlen(dechex($b8))) . dechex($b8)); $RGB = $RGBRed . $RGBGreen . $RGBBlue; return $RGB;}//// FILE HEADER//$data = unpack("V2", fread($handle, 8));$timMagic = '0x' . dechex($data[1]);$timType = '0x0' . $data[2];unset($data);if($timType == 0x08 || $timType == 0x09){ // // CLUT HEADER // $data = unpack('Vlong/v4short', fread($handle, 12)); $clutLength = $data['long']; $clutX = $data['short1']; $clutY = $data['short2']; $colorNum = $data['short3']; $clutCount = $data['short4']; unset($data); // // CLUT DATA // for($x = 1; $x <= $clutCount; $x++){ for($i = 1; $i <= $colorNum; $i++){ $data = unpack('v', fread($handle, 2)); $clutData[$x][$i] = getRGB($data[1]); } } unset($data);}//// IMAGE HEADER//$data = unpack('Vlong/v4short', fread($handle, 12));$imgLength = $data['long'];$imgX = $data['short1'];$imgY = $data['short2'];$imgPitch = $data['short3'];$imgHeight = $data['short4'];unset($data);//// IMAGE WIDTH FIX//if($timType == 0x08){ $imgWidth = $imgPitch * 4; $imgArea = ($imgPitch * 2) * $imgHeight;}else if($timType == 0x09){ $imgWidth = $imgPitch * 2; $imgArea = $imgWidth * $imgHeight;}else if($timType == 0x02){ $imgWidth = $imgPitch; $imgArea = $imgWidth * $imgHeight;}else if($timType == 0x03){ $imgWidth = $imgPitch / 1.5; $imgArea = $imgWidth * $imgHeight;}//// File Info//echo '<h3>File Info</h3>' . "\n";echo 'TIM Header: ' . $timMagic . '
' . "\n";if($timType == 0x08){ $bpp = '4bpp';}else if($timType == 0x09){ $bpp = '8bpp';}else if($timType == 0x02){ $bpp = '16bpp';}else if($timType == 0x03){ $bpp = '24bpp';}echo 'TIM Type: ' . $timType . ' => ' . $bpp . '
' . "\n";echo '
';if($timType == 0x08 || $timType == 0x09){ echo '<b>CLUT Header</b><br />' . "\n"; echo 'CLUT Size: ' . $clutLength . ' Bytes
' . "\n"; echo 'H. Res: ' . $clutX . '
' . "\n"; echo 'V. Res: ' . $clutY . '
' . "\n"; echo '# of Colors: ' . $colorNum . '
' . "\n"; echo '# of CLUTS: ' . $clutCount . '
' . "\n"; echo '
' . "\n"; echo '<b>CLUT (Color Look-Up Table)</b><br />' . "\n"; echo '<table border="0" cellpadding="0" cellspacing="2"><tr>' . "\n"; $count = 0; for($i = 1; $i <= $colorNum; $i++){ $color = $clutData[$curCLUT][$i]; echo '<td style="border: #000000 1px solid; background-color: #' . $color . '; height: 16px; text-align: center; width: 16px;"> </td>' . "\n"; $count++; if($count == 4 && $colorNum == 16){ echo '</tr><tr>' . "\n"; $count = 0; }else if($count == 16 && $colorNum == 256){ echo '</tr><tr>' . "\n"; $count = 0; } } echo '</tr></table>' . "\n"; echo '
' . "\n";}echo '<b>Image Header</b><br />' . "\n";echo 'Image Size: ' . $imgLength . ' Bytes
' . "\n";echo 'Org. X: ' . $imgX . '
' . "\n";echo 'Org. Y: ' . $imgY . '
' . "\n";echo 'Width: ' . $imgWidth . 'px
' . "\n";echo 'Height: ' . $imgHeight . 'px
' . "\n";echo '
' . "\n";echo '<h3>Output</h3>' . "\n";echo '<table border="0" cellpadding="0" cellspacing="0" height="' . $imgHeight . '" width="' . $imgWidth . '"><tr>' . "\n";if($timType == 0x08 || $timType == 0x09){ $count = 0; for($i = 1; $i <= $imgArea; $i++){ if($timType == 0x08){ $buff = fread($handle, 1); $data = unpack('h', $buff); $highNibble = hexdec($data[1]) + 1; unset($data); $data = unpack('H', $buff); $lowNibble = hexdec($data[1]) + 1; unset($data); $count++; echo '<td style="background-color: #' . $clutData[$curCLUT][$highNibble] .'"></td>' . "\n"; $count++; echo '<td style="background-color: #' . $clutData[$curCLUT][$lowNibble] .'"></td>' . "\n"; }else if($timType == 0x09){ $buff = fread($handle, 1); $data = unpack('C', $buff); $picked = $data[1] + 1; unset($data); $count++; echo '<td style="background-color: #' . $clutData[$curCLUT][$picked] .'"></td>' . "\n"; } if($count == $imgWidth){ $count = 0; echo '</tr><tr>' . "\n"; } } echo '</tr></table>' . "\n";}else if($timType == 0x02){ $count = 0; for($i = 1; $i <= $imgArea; $i++){ $data = unpack('v', fread($handle, 2)); $rawData = getRGB($data[1]); unset($data); $count++; echo '<td style="background-color: #' . $rawData . '"></td>' . "\n"; if($count == $imgWidth){ $count = 0; echo '</tr><tr>' . "\n"; } }}else if($timType == 0x03){ $count = 0; for($i = 1; $i <= $imgArea; $i++){ $data = unpack('C3', fread($handle, 3)); $rawData = strtoupper(str_repeat("0", 2 - strlen(dechex($data[1]))) . dechex($data[1])) . strtoupper(str_repeat("0", 2 - strlen(dechex($data[2]))) . dechex($data[2])) . strtoupper(str_repeat("0", 2 - strlen(dechex($data[3]))) . dechex($data[3])); unset($data); $count++; echo '<td style="background-color: #' . $rawData . '"></td>' . "\n"; $rawData = ''; if($count == $imgWidth){ $count = 0; echo '</tr><tr>' . "\n"; } }}else{ die("Error: Invalid TIM file");}echo '</tr></table>' . "\n";fclose($handle);?></body></html>
Open your browser and type in the address of the script ie. "localhost/TIMViewer.php?file=tim.tim"
Where "tim.tim" is change it to the file name of your TIM file.
If the file is a 4 bit or an 8 bit TIM add "&clut=x" (x is which clut you wish to use to view the image, default is 1)
=> "localhost/TIMViewer.php?file=mytim.tim&clut=1" (this would view the image with the 1st clut from the mytim.tim file)
Notes:
-This is not the most efficient coding or fastest loading but it does work.
-Big TIM files might take a long time to load.
-This script is writen purely by me and can be edited freely (Please post your updated code if you modify)
-Script does not show image as any graphic file (it's actually a table <= maybe why it's slow loading)
Tested with:
- Works with FF6 character faces (4bpp)
- Works with FF7 character faces (8bpp)
- Works with FF9 game over screen (16bpp)
- Works with adobe TIM plugin for all bpp (used to test 24bpp)
----------------------------------------------------------------------------------------------------------
-Enjoy
SCMark15
Last edited: