PageRenderTime 49ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/includes/exifer1_5/makers/gps.php

https://github.com/aravindc/pixelpost
PHP | 238 lines | 143 code | 46 blank | 49 comment | 63 complexity | e59bd871e0792139bc33d971540812f3 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. // SVN file version:
  3. // $Id$
  4. //================================================================================================
  5. //================================================================================================
  6. //================================================================================================
  7. /*
  8. Exifer
  9. Extracts EXIF information from digital photos.
  10. Copyright Š 2003 Jake Olefsky
  11. http://www.offsky.com/software/exif/index.php
  12. jake@olefsky.com
  13. Please see exif.php for the complete information about this software.
  14. ------------
  15. This program is free software; you can redistribute it and/or modify it under the terms of
  16. the GNU General Public License as published by the Free Software Foundation; either version 2
  17. of the License, or (at your option) any later version.
  18. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  19. without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  20. See the GNU General Public License for more details. http://www.gnu.org/copyleft/gpl.html
  21. */
  22. //================================================================================================
  23. //================================================================================================
  24. //================================================================================================
  25. //=================
  26. // Looks up the name of the tag
  27. //====================================================================
  28. function lookup_GPS_tag($tag) {
  29. switch($tag) {
  30. case "0000": $tag = "Version";break;
  31. case "0001": $tag = "Latitude Reference";break; //north or south
  32. case "0002": $tag = "Latitude";break; //dd mm.mm or dd mm ss
  33. case "0003": $tag = "Longitude Reference";break; //east or west
  34. case "0004": $tag = "Longitude";break; //dd mm.mm or dd mm ss
  35. case "0005": $tag = "Altitude Reference";break; //sea level or below sea level
  36. case "0006": $tag = "Altitude";break; //positive rational number
  37. case "0007": $tag = "Time";break; //three positive rational numbers
  38. case "0008": $tag = "Satellite";break; //text string up to 999 bytes long
  39. case "0009": $tag = "ReceiveStatus";break; //in progress or interop
  40. case "000a": $tag = "MeasurementMode";break; //2D or 3D
  41. case "000b": $tag = "MeasurementPrecision";break; //positive rational number
  42. case "000c": $tag = "SpeedUnit";break; //KPH, MPH, knots
  43. case "000d": $tag = "ReceiverSpeed";break; //positive rational number
  44. case "000e": $tag = "MovementDirectionRef";break; //true or magnetic north
  45. case "000f": $tag = "MovementDirection";break; //positive rational number
  46. case "0010": $tag = "ImageDirectionRef";break; //true or magnetic north
  47. case "0011": $tag = "ImageDirection";break; //positive rational number
  48. case "0012": $tag = "GeodeticSurveyData";break; //text string up to 999 bytes long
  49. case "0013": $tag = "DestLatitudeRef";break; //north or south
  50. case "0014": $tag = "DestinationLatitude";break; //three positive rational numbers
  51. case "0015": $tag = "DestLongitudeRef";break; //east or west
  52. case "0016": $tag = "DestinationLongitude";break; //three positive rational numbers
  53. case "0017": $tag = "DestBearingRef";break; //true or magnetic north
  54. case "0018": $tag = "DestinationBearing";break; //positive rational number
  55. case "0019": $tag = "DestDistanceRef";break; //km, miles, knots
  56. case "001a": $tag = "DestinationDistance";break; //positive rational number
  57. case "001b": $tag = "ProcessingMethod";break;
  58. case "001c": $tag = "AreaInformation";break;
  59. case "001d": $tag = "Datestamp";break; //text string 10 bytes long
  60. case "001e": $tag = "DifferentialCorrection";break; //integer in range 0-65535
  61. default: $tag = "unknown:".$tag;break;
  62. }
  63. return $tag;
  64. }
  65. //=================
  66. // Formats a rational number
  67. //====================================================================
  68. function GPSRational($data, $intel) {
  69. if($intel==1) $top = hexdec(substr($data,8,8)); //intel stores them bottom-top
  70. else $top = hexdec(substr($data,0,8)); //motorola stores them top-bottom
  71. if($intel==1) $bottom = hexdec(substr($data,0,8)); //intel stores them bottom-top
  72. else $bottom = hexdec(substr($data,8,8)); //motorola stores them top-bottom
  73. if($bottom!=0) $data=$top/$bottom;
  74. else if($top==0) $data = 0;
  75. else $data=$top."/".$bottom;
  76. return $data;
  77. }
  78. //=================
  79. // Formats Data for the data type
  80. //====================================================================
  81. function formatGPSData($type,$tag,$intel,$data) {
  82. if($type=="ASCII") {
  83. } else if($type=="URATIONAL" || $type=="SRATIONAL") {
  84. $data = bin2hex($data);
  85. if($intel==1) $data = intel2Moto($data);
  86. if($intel==1) $top = hexdec(substr($data,8,8)); //intel stores them bottom-top
  87. else $top = hexdec(substr($data,0,8)); //motorola stores them top-bottom
  88. if($intel==1) $bottom = hexdec(substr($data,0,8)); //intel stores them bottom-top
  89. else $bottom = hexdec(substr($data,8,8)); //motorola stores them top-bottom
  90. if($type=="SRATIONAL" && $top>2147483647) $top = $top - 4294967296; //this makes the number signed instead of unsigned
  91. if($tag=="0002" || $tag=="0004") { //Latitude
  92. //fix from Scott Menzer at the forums.
  93. if ($intel==1) {
  94. $seconds = GPSRational(substr($data,0,16),$intel);
  95. $minutes = GPSRational(substr($data,16,16),$intel);
  96. $hour = GPSRational(substr($data,32,16),$intel);
  97. } else {
  98. $hour = GPSRational(substr($data,0,16),$intel);
  99. $minutes = GPSRational(substr($data,16,16),$intel);
  100. $seconds = GPSRational(substr($data,32,16),$intel);
  101. }
  102. $data = $hour+$minutes/60+$seconds/3600;
  103. } else if($tag=="0007") { //Time
  104. $seconds = GPSRational(substr($data,0,16),$intel);
  105. $minutes = GPSRational(substr($data,16,16),$intel);
  106. $hour = GPSRational(substr($data,32,16),$intel);
  107. $data = $hour.":".$minutes.":".$seconds;
  108. } else {
  109. if($bottom!=0) $data=$top/$bottom;
  110. else if($top==0) $data = 0;
  111. else $data=$top."/".$bottom;
  112. }
  113. } else if($type=="USHORT" || $type=="SSHORT" || $type=="ULONG" || $type=="SLONG" || $type=="FLOAT" || $type=="DOUBLE") {
  114. $data = bin2hex($data);
  115. if($intel==1) $data = intel2Moto($data);
  116. $data=hexdec($data);
  117. } else if($type=="UNDEFINED") {
  118. } else if($type=="UBYTE") {
  119. $data = bin2hex($data);
  120. if($intel==1) $num = intel2Moto($data);
  121. if($tag=="0000") { //Latitude
  122. $data = hexdec(substr($data,0,2)).".". hexdec(substr($data,2,2)).".". hexdec(substr($data,4,2)).".". hexdec(substr($data,6,2));
  123. }
  124. } else {
  125. $data = bin2hex($data);
  126. if($intel==1) $data = intel2Moto($data);
  127. }
  128. return $data;
  129. }
  130. //=================
  131. // GPS Special data section
  132. // Useful websites
  133. // http://drewnoakes.com/code/exif/sampleOutput.html
  134. // http://www.geosnapper.com
  135. //====================================================================
  136. function parseGPS($block,&$result,$offset,$seek, $globalOffset) {
  137. if($result['Endien']=="Intel") $intel=1;
  138. else $intel=0;
  139. $v = fseek($seek,$globalOffset+$offset); //offsets are from TIFF header which is 12 bytes from the start of the file
  140. if($v==-1) {
  141. $result['Errors'] = $result['Errors']++;
  142. }
  143. $num = bin2hex(fread( $seek, 2 ));
  144. if($intel==1) $num = intel2Moto($num);
  145. $num=hexdec($num);
  146. $result['GPS']['NumTags'] = $num;
  147. if ($num > 0) $block = fread( $seek, $num*12 );
  148. $place = 0;
  149. //loop thru all tags Each field is 12 bytes
  150. for($i=0;$i<$num;$i++) {
  151. //2 byte tag
  152. $tag = bin2hex(substr($block,$place,2));$place+=2;
  153. if($intel==1) $tag = intel2Moto($tag);
  154. $tag_name = lookup_GPS_tag($tag);
  155. //2 byte datatype
  156. $type = bin2hex(substr($block,$place,2));$place+=2;
  157. if($intel==1) $type = intel2Moto($type);
  158. lookup_type($type,$size);
  159. //4 byte number of elements
  160. $count = bin2hex(substr($block,$place,4));$place+=4;
  161. if($intel==1) $count = intel2Moto($count);
  162. $bytesofdata = $size*hexdec($count);
  163. //4 byte value or pointer to value if larger than 4 bytes
  164. $value = substr($block,$place,4);$place+=4;
  165. if($bytesofdata<=4) {
  166. $data = $value;
  167. } else {
  168. $value = bin2hex($value);
  169. if($intel==1) $value = intel2Moto($value);
  170. $v = fseek($seek,$globalOffset+hexdec($value)); //offsets are from TIFF header which is 12 bytes from the start of the file
  171. if($v==0 && $bytesofdata < $GLOBALS['exiferFileSize']) {
  172. $data = fread($seek, $bytesofdata);
  173. } else {
  174. $result['Errors'] = $result['Errors']++;
  175. }
  176. }
  177. if($result['VerboseOutput']==1) {
  178. $result['GPS'][$tag_name] = formatGPSData($type,$tag,$intel,$data);
  179. $result['GPS'][$tag_name."_Verbose"]['RawData'] = bin2hex($data);
  180. $result['GPS'][$tag_name."_Verbose"]['Type'] = $type;
  181. $result['GPS'][$tag_name."_Verbose"]['Bytes'] = $bytesofdata;
  182. } else {
  183. $result['GPS'][$tag_name] = formatGPSData($type,$tag,$intel,$data);
  184. }
  185. }
  186. }
  187. ?>