File indexing completed on 2024-12-22 05:33:13
0001 <?php 0002 ///////////////////////////////////////////////////////////////// 0003 /// getID3() by James Heinrich <info@getid3.org> // 0004 // available at http://getid3.sourceforge.net // 0005 // or http://www.getid3.org // 0006 // also https://github.com/JamesHeinrich/getID3 // 0007 ///////////////////////////////////////////////////////////////// 0008 // See readme.txt for more details // 0009 ///////////////////////////////////////////////////////////////// 0010 // // 0011 // module.graphic.gif.php // 0012 // module for analyzing GIF Image files // 0013 // dependencies: NONE // 0014 // /// 0015 ///////////////////////////////////////////////////////////////// 0016 0017 0018 class getid3_gif extends getid3_handler 0019 { 0020 0021 public function Analyze() { 0022 $info = &$this->getid3->info; 0023 0024 $info['fileformat'] = 'gif'; 0025 $info['video']['dataformat'] = 'gif'; 0026 $info['video']['lossless'] = true; 0027 $info['video']['pixel_aspect_ratio'] = (float) 1; 0028 0029 $this->fseek($info['avdataoffset']); 0030 $GIFheader = $this->fread(13); 0031 $offset = 0; 0032 0033 $info['gif']['header']['raw']['identifier'] = substr($GIFheader, $offset, 3); 0034 $offset += 3; 0035 0036 $magic = 'GIF'; 0037 if ($info['gif']['header']['raw']['identifier'] != $magic) { 0038 $info['error'][] = 'Expecting "'.getid3_lib::PrintHexBytes($magic).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($info['gif']['header']['raw']['identifier']).'"'; 0039 unset($info['fileformat']); 0040 unset($info['gif']); 0041 return false; 0042 } 0043 0044 $info['gif']['header']['raw']['version'] = substr($GIFheader, $offset, 3); 0045 $offset += 3; 0046 $info['gif']['header']['raw']['width'] = getid3_lib::LittleEndian2Int(substr($GIFheader, $offset, 2)); 0047 $offset += 2; 0048 $info['gif']['header']['raw']['height'] = getid3_lib::LittleEndian2Int(substr($GIFheader, $offset, 2)); 0049 $offset += 2; 0050 $info['gif']['header']['raw']['flags'] = getid3_lib::LittleEndian2Int(substr($GIFheader, $offset, 1)); 0051 $offset += 1; 0052 $info['gif']['header']['raw']['bg_color_index'] = getid3_lib::LittleEndian2Int(substr($GIFheader, $offset, 1)); 0053 $offset += 1; 0054 $info['gif']['header']['raw']['aspect_ratio'] = getid3_lib::LittleEndian2Int(substr($GIFheader, $offset, 1)); 0055 $offset += 1; 0056 0057 $info['video']['resolution_x'] = $info['gif']['header']['raw']['width']; 0058 $info['video']['resolution_y'] = $info['gif']['header']['raw']['height']; 0059 $info['gif']['version'] = $info['gif']['header']['raw']['version']; 0060 $info['gif']['header']['flags']['global_color_table'] = (bool) ($info['gif']['header']['raw']['flags'] & 0x80); 0061 if ($info['gif']['header']['raw']['flags'] & 0x80) { 0062 // Number of bits per primary color available to the original image, minus 1 0063 $info['gif']['header']['bits_per_pixel'] = 3 * ((($info['gif']['header']['raw']['flags'] & 0x70) >> 4) + 1); 0064 } else { 0065 $info['gif']['header']['bits_per_pixel'] = 0; 0066 } 0067 $info['gif']['header']['flags']['global_color_sorted'] = (bool) ($info['gif']['header']['raw']['flags'] & 0x40); 0068 if ($info['gif']['header']['flags']['global_color_table']) { 0069 // the number of bytes contained in the Global Color Table. To determine that 0070 // actual size of the color table, raise 2 to [the value of the field + 1] 0071 $info['gif']['header']['global_color_size'] = pow(2, ($info['gif']['header']['raw']['flags'] & 0x07) + 1); 0072 $info['video']['bits_per_sample'] = ($info['gif']['header']['raw']['flags'] & 0x07) + 1; 0073 } else { 0074 $info['gif']['header']['global_color_size'] = 0; 0075 } 0076 if ($info['gif']['header']['raw']['aspect_ratio'] != 0) { 0077 // Aspect Ratio = (Pixel Aspect Ratio + 15) / 64 0078 $info['gif']['header']['aspect_ratio'] = ($info['gif']['header']['raw']['aspect_ratio'] + 15) / 64; 0079 } 0080 0081 // if ($info['gif']['header']['flags']['global_color_table']) { 0082 // $GIFcolorTable = $this->fread(3 * $info['gif']['header']['global_color_size']); 0083 // $offset = 0; 0084 // for ($i = 0; $i < $info['gif']['header']['global_color_size']; $i++) { 0085 // $red = getid3_lib::LittleEndian2Int(substr($GIFcolorTable, $offset++, 1)); 0086 // $green = getid3_lib::LittleEndian2Int(substr($GIFcolorTable, $offset++, 1)); 0087 // $blue = getid3_lib::LittleEndian2Int(substr($GIFcolorTable, $offset++, 1)); 0088 // $info['gif']['global_color_table'][$i] = (($red << 16) | ($green << 8) | ($blue)); 0089 // } 0090 // } 0091 // 0092 // // Image Descriptor 0093 // while (!feof($this->getid3->fp)) { 0094 // $NextBlockTest = $this->fread(1); 0095 // switch ($NextBlockTest) { 0096 // 0097 // case ',': // ',' - Image separator character 0098 // 0099 // $ImageDescriptorData = $NextBlockTest.$this->fread(9); 0100 // $ImageDescriptor = array(); 0101 // $ImageDescriptor['image_left'] = getid3_lib::LittleEndian2Int(substr($ImageDescriptorData, 1, 2)); 0102 // $ImageDescriptor['image_top'] = getid3_lib::LittleEndian2Int(substr($ImageDescriptorData, 3, 2)); 0103 // $ImageDescriptor['image_width'] = getid3_lib::LittleEndian2Int(substr($ImageDescriptorData, 5, 2)); 0104 // $ImageDescriptor['image_height'] = getid3_lib::LittleEndian2Int(substr($ImageDescriptorData, 7, 2)); 0105 // $ImageDescriptor['flags_raw'] = getid3_lib::LittleEndian2Int(substr($ImageDescriptorData, 9, 1)); 0106 // $ImageDescriptor['flags']['use_local_color_map'] = (bool) ($ImageDescriptor['flags_raw'] & 0x80); 0107 // $ImageDescriptor['flags']['image_interlaced'] = (bool) ($ImageDescriptor['flags_raw'] & 0x40); 0108 // $info['gif']['image_descriptor'][] = $ImageDescriptor; 0109 // 0110 // if ($ImageDescriptor['flags']['use_local_color_map']) { 0111 // 0112 // $info['warning'][] = 'This version of getID3() cannot parse local color maps for GIFs'; 0113 // return true; 0114 // 0115 // } 0116 //echo 'Start of raster data: '.$this->ftell().'<BR>'; 0117 // $RasterData = array(); 0118 // $RasterData['code_size'] = getid3_lib::LittleEndian2Int($this->fread(1)); 0119 // $RasterData['block_byte_count'] = getid3_lib::LittleEndian2Int($this->fread(1)); 0120 // $info['gif']['raster_data'][count($info['gif']['image_descriptor']) - 1] = $RasterData; 0121 // 0122 // $CurrentCodeSize = $RasterData['code_size'] + 1; 0123 // for ($i = 0; $i < pow(2, $RasterData['code_size']); $i++) { 0124 // $DefaultDataLookupTable[$i] = chr($i); 0125 // } 0126 // $DefaultDataLookupTable[pow(2, $RasterData['code_size']) + 0] = ''; // Clear Code 0127 // $DefaultDataLookupTable[pow(2, $RasterData['code_size']) + 1] = ''; // End Of Image Code 0128 // 0129 // 0130 // $NextValue = $this->GetLSBits($CurrentCodeSize); 0131 // echo 'Clear Code: '.$NextValue.'<BR>'; 0132 // 0133 // $NextValue = $this->GetLSBits($CurrentCodeSize); 0134 // echo 'First Color: '.$NextValue.'<BR>'; 0135 // 0136 // $Prefix = $NextValue; 0137 //$i = 0; 0138 // while ($i++ < 20) { 0139 // $NextValue = $this->GetLSBits($CurrentCodeSize); 0140 // echo $NextValue.'<BR>'; 0141 // } 0142 //return true; 0143 // break; 0144 // 0145 // case '!': 0146 // // GIF Extension Block 0147 // $ExtensionBlockData = $NextBlockTest.$this->fread(2); 0148 // $ExtensionBlock = array(); 0149 // $ExtensionBlock['function_code'] = getid3_lib::LittleEndian2Int(substr($ExtensionBlockData, 1, 1)); 0150 // $ExtensionBlock['byte_length'] = getid3_lib::LittleEndian2Int(substr($ExtensionBlockData, 2, 1)); 0151 // $ExtensionBlock['data'] = $this->fread($ExtensionBlock['byte_length']); 0152 // $info['gif']['extension_blocks'][] = $ExtensionBlock; 0153 // break; 0154 // 0155 // case ';': 0156 // $info['gif']['terminator_offset'] = $this->ftell() - 1; 0157 // // GIF Terminator 0158 // break; 0159 // 0160 // default: 0161 // break; 0162 // 0163 // 0164 // } 0165 // } 0166 0167 return true; 0168 } 0169 0170 0171 public function GetLSBits($bits) { 0172 static $bitbuffer = ''; 0173 while (strlen($bitbuffer) < $bits) { 0174 $bitbuffer = str_pad(decbin(ord($this->fread(1))), 8, '0', STR_PAD_LEFT).$bitbuffer; 0175 } 0176 $value = bindec(substr($bitbuffer, 0 - $bits)); 0177 $bitbuffer = substr($bitbuffer, 0, 0 - $bits); 0178 0179 return $value; 0180 } 0181 0182 }