PageRenderTime 38ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/exif/makers/nikon.php

https://github.com/tchemineau/kohana-exif
PHP | 411 lines | 325 code | 35 blank | 51 comment | 86 complexity | 668c2aa4ad8c540f1ec938bee8bfa813 MD5 | raw file
  1. <?php //================================================================================================
  2. //================================================================================================
  3. //================================================================================================
  4. /*
  5. Exifer
  6. Extracts EXIF information from digital photos.
  7. Copyright ďż˝ 2003 Jake Olefsky
  8. http://www.offsky.com/software/exif/index.php
  9. jake@olefsky.com
  10. Please see exif.php for the complete information about this software.
  11. ------------
  12. This program is free software; you can redistribute it and/or modify it under the terms of
  13. the GNU General Public License as published by the Free Software Foundation; either version 2
  14. of the License, or (at your option) any later version.
  15. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  16. without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. See the GNU General Public License for more details. http://www.gnu.org/copyleft/gpl.html
  18. */
  19. //================================================================================================
  20. //================================================================================================
  21. //================================================================================================
  22. //=================
  23. // Looks up the name of the tag for the MakerNote (Depends on Manufacturer)
  24. //====================================================================
  25. function lookup_Nikon_tag($tag,$model) {
  26. if($model==0) {
  27. switch($tag) {
  28. case "0003": $tag = "Quality";break;
  29. case "0004": $tag = "ColorMode";break;
  30. case "0005": $tag = "ImageAdjustment";break;
  31. case "0006": $tag = "CCDSensitivity";break;
  32. case "0007": $tag = "WhiteBalance";break;
  33. case "0008": $tag = "Focus";break;
  34. case "0009": $tag = "Unknown2";break;
  35. case "000a": $tag = "DigitalZoom";break;
  36. case "000b": $tag = gettext("Converter");break;
  37. default: $tag = "unknown:".$tag;break;
  38. }
  39. } else if($model==1) {
  40. switch($tag) {
  41. case "0002": $tag = "ISOSetting";break;
  42. case "0003": $tag = "ColorMode";break;
  43. case "0004": $tag = "Quality";break;
  44. case "0005": $tag = "Whitebalance";break;
  45. case "0006": $tag = "ImageSharpening";break;
  46. case "0007": $tag = "FocusMode";break;
  47. case "0008": $tag = "FlashSetting";break;
  48. case "0009": $tag = "FlashMode";break;
  49. case "000b": $tag = "WhiteBalanceFine";break;
  50. case "000c": $tag = "WB_RBLevels";break;
  51. case "000d": $tag = "ProgramShift";break;
  52. case "000e": $tag = "ExposureDifference";break;
  53. case "000f": $tag = "ISOSelection";break;
  54. case "0010": $tag = "DataDump";break;
  55. case "0011": $tag = "NikonPreview";break;
  56. case "0012": $tag = "FlashExposureComp";break;
  57. case "0013": $tag = "ISOSetting2";break;
  58. case "0014": $tag = "ColorBalanceA";break;
  59. case "0016": $tag = "ImageBoundary";break;
  60. case "0017": $tag = "FlashExposureComp";break;
  61. case "0018": $tag = "FlashExposureBracketValue";break;
  62. case "0019": $tag = "ExposureBracketValue";break;
  63. case "001a": $tag = "ImageProcessing";break;
  64. case "001b": $tag = "CropHiSpeed";break;
  65. case "001c": $tag = "ExposureTuning";break;
  66. case "001d": $tag = "SerialNumber";break;
  67. case "001e": $tag = "ColorSpace";break;
  68. case "001f": $tag = "VRInfo";break;
  69. case "0020": $tag = "ImageAuthentication";break;
  70. case "0022": $tag = "ActiveD-Lighting";break;
  71. case "0023": $tag = "PictureControl";break;
  72. case "0024": $tag = "WorldTime";break;
  73. case "0025": $tag = "ISOInfo";break;
  74. case "002a": $tag = "VignetteControl";break;
  75. case "002b": $tag = "DistortInfo";break;
  76. case "0080": $tag = "ImageAdjustment";break;
  77. case "0081": $tag = "ToneCompensation";break;
  78. case "0082": $tag = "Adapter";break;
  79. case "0083": $tag = "LensType";break;
  80. case "0084": $tag = "LensInfo";break;
  81. case "0085": $tag = "ManualFocusDistance";break;
  82. case "0086": $tag = "DigitalZoom";break;
  83. case "0087": $tag = "FlashUsed";break;
  84. case "0088": $tag = "AFFocusPosition";break;
  85. case "0089": $tag = "ShootingMode";break;
  86. case "008b": $tag = "LensFStops";break;
  87. case "008c": $tag = "ContrastCurve";break;
  88. case "008d": $tag = "ColorMode";break;
  89. case "0090": $tag = "LightType";break;
  90. case "0092": $tag = "HueAdjustment";break;
  91. case "0093": $tag = "NEFCompression";break;
  92. case "0094": $tag = "Saturation";break;
  93. case "0095": $tag = "NoiseReduction";break;
  94. case "009a": $tag = "SensorPixelSize";break;
  95. default: $tag = "unknown:".$tag;break;
  96. }
  97. }
  98. return $tag;
  99. }
  100. //=================
  101. // Formats Data for the data type
  102. //====================================================================
  103. function formatNikonData($type,$tag,$intel,$model,$data) {
  104. switch ($type) {
  105. case "ASCII":
  106. break; // do nothing!
  107. case "URATIONAL":
  108. case"SRATIONAL":
  109. switch ($tag) {
  110. case '0084': // LensInfo
  111. $minFL = unRational(substr($data,0,8),$type,$intel);
  112. $maxFL = unRational(substr($data,8,8),$type,$intel);
  113. $minSP = unRational(substr($data,16,8),$type,$intel);
  114. $maxSP = unRational(substr($data,24,8),$type,$intel);
  115. if ($minFL == $maxFL) {
  116. $data = sprintf('%0.0f f/%0.0f',$minFL,$minSP);
  117. } elseif ($minSP == $maxSP) {
  118. $data = sprintf('%0.0f-%0.0fmm f/%0.1f',$minFL,$maxFL,$minSP);
  119. } else {
  120. $data = sprintf('%0.0f-%0.0fmm f/%0.1f-%0.1f',$minFL,$maxFL,$minSP,$maxSP);
  121. }
  122. break;
  123. case "0085":
  124. if ($model==1) $data=unRational($data,$type,$intel)." m"; //ManualFocusDistance
  125. break;
  126. case "0086":
  127. if ($model==1) $data=unRational($data,$type,$intel)."x"; //DigitalZoom
  128. break;
  129. case "000a":
  130. if ($model==0) $data=unRational($data,$type,$intel)."x"; //DigitalZoom
  131. break;
  132. default:
  133. $data=unRational($data,$type,$intel);
  134. break;
  135. }
  136. break;
  137. case "USHORT":
  138. case $type=="SSHORT":
  139. case $type=="ULONG":
  140. case $type=="SLONG":
  141. case $type=="FLOAT":
  142. case $type=="DOUBLE":
  143. $data = rational($data,$type,$intel);
  144. switch ($tag) {
  145. case "0003":
  146. if ($model==0) { //Quality
  147. switch ($data) {
  148. case 1: $data = gettext("VGA Basic"); break;
  149. case 2: $data = gettext("VGA Normal"); break;
  150. case 3: $data = gettext("VGA Fine"); break;
  151. case 4: $data = gettext("SXGA Basic"); break;
  152. case 5: $data = gettext("SXGA Normal"); break;
  153. case 6: $data = gettext("SXGA Fine"); break;
  154. default: $data = gettext("Unknown").": ".$data; break;
  155. }
  156. }
  157. break;
  158. case "0004":
  159. if ($model==0) { //Color
  160. switch ($data) {
  161. case 1: $data = gettext("Color"); break;
  162. case 2: $data = gettext("Monochrome"); break;
  163. default: $data = gettext("Unknown").": ".$data; break;
  164. }
  165. }
  166. break;
  167. case "0005":
  168. if ($model==0) { //Image Adjustment
  169. switch ($data) {
  170. case 0: $data = gettext("Normal"); break;
  171. case 1: $data = gettext("Bright+"); break;
  172. case 2: $data = gettext("Bright-"); break;
  173. case 3: $data = gettext("Contrast+"); break;
  174. case 4: $data = gettext("Contrast-"); break;
  175. default: $data = gettext("Unknown").": ".$data; break;
  176. }
  177. }
  178. break;
  179. case "0006":
  180. if ($model==0) { //CCD Sensitivity
  181. switch($data) {
  182. case 0: $data = "ISO-80"; break;
  183. case 2: $data = "ISO-160"; break;
  184. case 4: $data = "ISO-320"; break;
  185. case 5: $data = "ISO-100"; break;
  186. default: $data = gettext("Unknown").": ".$data; break;
  187. }
  188. }
  189. break;
  190. case "0007":
  191. if ($model==0) { //White Balance
  192. switch ($data) {
  193. case 0: $data = gettext("Auto"); break;
  194. case 1: $data = gettext("Preset"); break;
  195. case 2: $data = gettext("Daylight"); break;
  196. case 3: $data = gettext("Incandescence"); break;
  197. case 4: $data = gettext("Fluorescence"); break;
  198. case 5: $data = gettext("Cloudy"); break;
  199. case 6: $data = gettext("SpeedLight"); break;
  200. default: $data = gettext("Unknown").": ".$data; break;
  201. }
  202. }
  203. break;
  204. case "000b":
  205. if ($model==0) { //Converter
  206. switch ($data) {
  207. case 0: $data = gettext("None"); break;
  208. case 1: $data = gettext("Fisheye"); break;
  209. default: $data = gettext("Unknown").": ".$data; break;
  210. }
  211. }
  212. break;
  213. }
  214. break;
  215. case "UNDEFINED":
  216. switch ($tag) {
  217. case "0001":
  218. if ($model==1) $data=$data/100; break; //Unknown (Version?)
  219. break;
  220. case "0088":
  221. if ($model==1) { //AF Focus Position
  222. $temp = gettext("Center");
  223. $data = bin2hex($data);
  224. $data = str_replace("01","Top",$data);
  225. $data = str_replace("02","Bottom",$data);
  226. $data = str_replace("03","Left",$data);
  227. $data = str_replace("04","Right",$data);
  228. $data = str_replace("00","",$data);
  229. if(strlen($data)==0) $data = $temp;
  230. }
  231. break;
  232. }
  233. break;
  234. default:
  235. $data = bin2hex($data);
  236. if($intel==1) $data = intel2Moto($data);
  237. switch ($tag) {
  238. case "0083":
  239. if ($model==1) { //Lens Type
  240. $data = hexdec(substr($data,0,2));
  241. switch ($data) {
  242. case 0: $data = gettext("AF non D"); break;
  243. case 1: $data = gettext("Manual"); break;
  244. case 2: $data = "AF-D or AF-S"; break;
  245. case 6: $data = "AF-D G"; break;
  246. case 10: $data = "AF-D VR"; break;
  247. case 14: $data = "AF-D G VR"; break;
  248. default: $data = gettext("Unknown").": ".$data; break;
  249. }
  250. }
  251. break;
  252. case "0087":
  253. if ($model==1) { //Flash type
  254. $data = hexdec(substr($data,0,2));
  255. if($data == 0) $data = gettext("Did Not Fire");
  256. else if($data == 4) $data = gettext("Unknown");
  257. else if($data == 7) $data = gettext("External");
  258. else if($data == 9) $data = gettext("On Camera");
  259. else $data = gettext("Unknown").": ".$data;
  260. }
  261. break;
  262. }
  263. break;
  264. }
  265. return $data;
  266. }
  267. //=================
  268. // Nikon Special data section
  269. //====================================================================
  270. function parseNikon($block,&$result) {
  271. if($result['Endien']=="Intel") $intel=1;
  272. else $intel=0;
  273. $model = $result['IFD0']['Model'];
  274. //these 6 models start with "Nikon". Other models dont.
  275. if($model=="E700\0" || $model=="E800\0" || $model=="E900\0" || $model=="E900S\0" || $model=="E910\0" || $model=="E950\0") {
  276. $place=8; //current place
  277. $model = 0;
  278. //Get number of tags (2 bytes)
  279. $num = bin2hex(substr($block,$place,2));$place+=2;
  280. if($intel==1) $num = intel2Moto($num);
  281. $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = hexdec($num);
  282. //loop thru all tags Each field is 12 bytes
  283. for($i=0;$i<hexdec($num);$i++) {
  284. //2 byte tag
  285. $tag = bin2hex(substr($block,$place,2));$place+=2;
  286. if($intel==1) $tag = intel2Moto($tag);
  287. $tag_name = lookup_Nikon_tag($tag, $model);
  288. //2 byte type
  289. $type = bin2hex(substr($block,$place,2));$place+=2;
  290. if($intel==1) $type = intel2Moto($type);
  291. lookup_type($type,$size);
  292. //4 byte count of number of data units
  293. $count = bin2hex(substr($block,$place,4));$place+=4;
  294. if($intel==1) $count = intel2Moto($count);
  295. $bytesofdata = $size*hexdec($count);
  296. //4 byte value of data or pointer to data
  297. $value = substr($block,$place,4);$place+=4;
  298. //if tag is 0002 then its the ASCII value which we know is at 140 so calc offset
  299. //THIS HACK ONLY WORKS WITH EARLY NIKON MODELS
  300. if($tag=="0002") $offset = hexdec($value)-140;
  301. if($bytesofdata<=4) {
  302. $data = $value;
  303. } else {
  304. $value = bin2hex($value);
  305. if($intel==1) $value = intel2Moto($value);
  306. $data = substr($block,hexdec($value)-$offset,$bytesofdata*2);
  307. }
  308. $formated_data = formatNikonData($type,$tag,$intel,$model,$data);
  309. if($result['VerboseOutput']==1) {
  310. $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
  311. $result['SubIFD']['MakerNote'][$tag_name."_Verbose"]['RawData'] = $data;
  312. $result['SubIFD']['MakerNote'][$tag_name."_Verbose"]['Type'] = $type;
  313. $result['SubIFD']['MakerNote'][$tag_name."_Verbose"]['Bytes'] = $bytesofdata;
  314. } else {
  315. $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
  316. }
  317. }
  318. } else {
  319. $place=0;//current place
  320. $model = 1;
  321. $nikon = substr($block,$place,8);$place+=8;
  322. $endien = substr($block,$place,4);$place+=4;
  323. //2 bytes of 0x002a
  324. $tag = bin2hex(substr($block,$place,2));$place+=2;
  325. //Then 4 bytes of offset to IFD0 (usually 8 which includes all 8 bytes of TIFF header)
  326. $offset = bin2hex(substr($block,$place,4));$place+=4;
  327. if($intel==1) $offset = intel2Moto($offset);
  328. if(hexdec($offset)>8) $place+=$offset-8;
  329. //Get number of tags (2 bytes)
  330. $num = bin2hex(substr($block,$place,2));$place+=2;
  331. if($intel==1) $num = intel2Moto($num);
  332. //loop thru all tags Each field is 12 bytes
  333. for($i=0;$i<hexdec($num);$i++) {
  334. //2 byte tag
  335. $tag = bin2hex(substr($block,$place,2));$place+=2;
  336. if($intel==1) $tag = intel2Moto($tag);
  337. $tag_name = lookup_Nikon_tag($tag, $model);
  338. //2 byte type
  339. $type = bin2hex(substr($block,$place,2));$place+=2;
  340. if($intel==1) $type = intel2Moto($type);
  341. lookup_type($type,$size);
  342. //4 byte count of number of data units
  343. $count = bin2hex(substr($block,$place,4));$place+=4;
  344. if($intel==1) $count = intel2Moto($count);
  345. $bytesofdata = $size*hexdec($count);
  346. //4 byte value of data or pointer to data
  347. $value = substr($block,$place,4);$place+=4;
  348. if($bytesofdata<=4) {
  349. $data = $value;
  350. } else {
  351. $value = bin2hex($value);
  352. if($intel==1) $value = intel2Moto($value);
  353. $data = substr($block,hexdec($value)+hexdec($offset)+2,$bytesofdata);
  354. }
  355. $formated_data = formatNikonData($type,$tag,$intel,$model,$data);
  356. if($result['VerboseOutput']==1) {
  357. $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
  358. if($type=="URATIONAL" || $type=="SRATIONAL" || $type=="USHORT" || $type=="SSHORT" || $type=="ULONG" || $type=="SLONG" || $type=="FLOAT" || $type=="DOUBLE") {
  359. $data = bin2hex($data);
  360. if($intel==1) $data = intel2Moto($data);
  361. }
  362. $result['SubIFD']['MakerNote'][$tag_name."_Verbose"]['RawData'] = $data;
  363. $result['SubIFD']['MakerNote'][$tag_name."_Verbose"]['Type'] = $type;
  364. $result['SubIFD']['MakerNote'][$tag_name."_Verbose"]['Bytes'] = $bytesofdata;
  365. } else {
  366. $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
  367. }
  368. }
  369. }
  370. }
  371. ?>