piexif.js 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471
  1. /* piexifjs
  2. The MIT License (MIT)
  3. Copyright (c) 2014, 2015 hMatoba(https://github.com/hMatoba)
  4. Permission is hereby granted, free of charge, to any person obtaining a copy
  5. of this software and associated documentation files (the "Software"), to deal
  6. in the Software without restriction, including without limitation the rights
  7. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. copies of the Software, and to permit persons to whom the Software is
  9. furnished to do so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included in all
  11. copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18. SOFTWARE.
  19. */
  20. (function () {
  21. "use strict";
  22. var that = {};
  23. that.version = "1.03";
  24. that.remove = function (jpeg) {
  25. var b64 = false;
  26. if (jpeg.slice(0, 2) == "\xff\xd8") {
  27. } else if (jpeg.slice(0, 23) == "data:image/jpeg;base64," || jpeg.slice(0, 22) == "data:image/jpg;base64,") {
  28. jpeg = atob(jpeg.split(",")[1]);
  29. b64 = true;
  30. } else {
  31. throw ("Given data is not jpeg.");
  32. }
  33. var segments = splitIntoSegments(jpeg);
  34. if (segments[1].slice(0, 2) == "\xff\xe1" &&
  35. segments[1].slice(4, 10) == "Exif\x00\x00") {
  36. segments = [segments[0]].concat(segments.slice(2));
  37. } else if (segments[2].slice(0, 2) == "\xff\xe1" &&
  38. segments[2].slice(4, 10) == "Exif\x00\x00") {
  39. segments = segments.slice(0, 2).concat(segments.slice(3));
  40. } else {
  41. throw("Exif not found.");
  42. }
  43. var new_data = segments.join("");
  44. if (b64) {
  45. new_data = "data:image/jpeg;base64," + btoa(new_data);
  46. }
  47. return new_data;
  48. };
  49. that.insert = function (exif, jpeg) {
  50. var b64 = false;
  51. if (exif.slice(0, 6) != "\x45\x78\x69\x66\x00\x00") {
  52. throw ("Given data is not exif.");
  53. }
  54. if (jpeg.slice(0, 2) == "\xff\xd8") {
  55. } else if (jpeg.slice(0, 23) == "data:image/jpeg;base64," || jpeg.slice(0, 22) == "data:image/jpg;base64,") {
  56. jpeg = atob(jpeg.split(",")[1]);
  57. b64 = true;
  58. } else {
  59. throw ("Given data is not jpeg.");
  60. }
  61. var exifStr = "\xff\xe1" + pack(">H", [exif.length + 2]) + exif;
  62. var segments = splitIntoSegments(jpeg);
  63. var new_data = mergeSegments(segments, exifStr);
  64. if (b64) {
  65. new_data = "data:image/jpeg;base64," + btoa(new_data);
  66. }
  67. return new_data;
  68. };
  69. that.load = function (data) {
  70. var input_data;
  71. if (typeof (data) == "string") {
  72. if (data.slice(0, 2) == "\xff\xd8") {
  73. input_data = data;
  74. } else if (data.slice(0, 23) == "data:image/jpeg;base64," || data.slice(0, 22) == "data:image/jpg;base64,") {
  75. input_data = atob(data.split(",")[1]);
  76. } else if (data.slice(0, 4) == "Exif") {
  77. input_data = data.slice(6);
  78. } else {
  79. throw ("'load' gots invalid file data.");
  80. }
  81. } else {
  82. throw ("'load' gots invalid type argument.");
  83. }
  84. var exifDict = {};
  85. var exif_dict = {
  86. "0th": {},
  87. "Exif": {},
  88. "GPS": {},
  89. "Interop": {},
  90. "1st": {},
  91. "thumbnail": null
  92. };
  93. var exifReader = new ExifReader(input_data);
  94. if (exifReader.tiftag === null) {
  95. return exif_dict;
  96. }
  97. if (exifReader.tiftag.slice(0, 2) == "\x49\x49") {
  98. exifReader.endian_mark = "<";
  99. } else {
  100. exifReader.endian_mark = ">";
  101. }
  102. var pointer = unpack(exifReader.endian_mark + "L",
  103. exifReader.tiftag.slice(4, 8))[0];
  104. exif_dict["0th"] = exifReader.get_ifd(pointer, "0th");
  105. var first_ifd_pointer = exif_dict["0th"]["first_ifd_pointer"];
  106. delete exif_dict["0th"]["first_ifd_pointer"];
  107. if (34665 in exif_dict["0th"]) {
  108. pointer = exif_dict["0th"][34665];
  109. exif_dict["Exif"] = exifReader.get_ifd(pointer, "Exif");
  110. }
  111. if (34853 in exif_dict["0th"]) {
  112. pointer = exif_dict["0th"][34853];
  113. exif_dict["GPS"] = exifReader.get_ifd(pointer, "GPS");
  114. }
  115. if (40965 in exif_dict["Exif"]) {
  116. pointer = exif_dict["Exif"][40965];
  117. exif_dict["Interop"] = exifReader.get_ifd(pointer, "Interop");
  118. }
  119. if (first_ifd_pointer != "\x00\x00\x00\x00") {
  120. pointer = unpack(exifReader.endian_mark + "L",
  121. first_ifd_pointer)[0];
  122. exif_dict["1st"] = exifReader.get_ifd(pointer, "1st");
  123. if ((513 in exif_dict["1st"]) && (514 in exif_dict["1st"])) {
  124. var end = exif_dict["1st"][513] + exif_dict["1st"][514];
  125. var thumb = exifReader.tiftag.slice(exif_dict["1st"][513], end);
  126. exif_dict["thumbnail"] = thumb;
  127. }
  128. }
  129. return exif_dict;
  130. };
  131. that.dump = function (exif_dict_original) {
  132. var TIFF_HEADER_LENGTH = 8;
  133. var exif_dict = copy(exif_dict_original);
  134. var header = "Exif\x00\x00\x4d\x4d\x00\x2a\x00\x00\x00\x08";
  135. var exif_is = false;
  136. var gps_is = false;
  137. var interop_is = false;
  138. var first_is = false;
  139. var zeroth_ifd,
  140. exif_ifd,
  141. interop_ifd,
  142. gps_ifd,
  143. first_ifd;
  144. if ("0th" in exif_dict) {
  145. zeroth_ifd = exif_dict["0th"];
  146. } else {
  147. zeroth_ifd = {};
  148. }
  149. if ((("Exif" in exif_dict) && (Object.keys(exif_dict["Exif"]).length)) ||
  150. (("Interop" in exif_dict) && (Object.keys(exif_dict["Interop"]).length))) {
  151. zeroth_ifd[34665] = 1;
  152. exif_is = true;
  153. exif_ifd = exif_dict["Exif"];
  154. if (("Interop" in exif_dict) && Object.keys(exif_dict["Interop"]).length) {
  155. exif_ifd[40965] = 1;
  156. interop_is = true;
  157. interop_ifd = exif_dict["Interop"];
  158. } else if (Object.keys(exif_ifd).indexOf(that.ExifIFD.InteroperabilityTag.toString()) > -1) {
  159. delete exif_ifd[40965];
  160. }
  161. } else if (Object.keys(zeroth_ifd).indexOf(that.ImageIFD.ExifTag.toString()) > -1) {
  162. delete zeroth_ifd[34665];
  163. }
  164. if (("GPS" in exif_dict) && (Object.keys(exif_dict["GPS"]).length)) {
  165. zeroth_ifd[that.ImageIFD.GPSTag] = 1;
  166. gps_is = true;
  167. gps_ifd = exif_dict["GPS"];
  168. } else if (Object.keys(zeroth_ifd).indexOf(that.ImageIFD.GPSTag.toString()) > -1) {
  169. delete zeroth_ifd[that.ImageIFD.GPSTag];
  170. }
  171. if (("1st" in exif_dict) &&
  172. ("thumbnail" in exif_dict) &&
  173. (exif_dict["thumbnail"] != null)) {
  174. first_is = true;
  175. exif_dict["1st"][513] = 1;
  176. exif_dict["1st"][514] = 1;
  177. first_ifd = exif_dict["1st"];
  178. }
  179. var zeroth_set = _dict_to_bytes(zeroth_ifd, "0th", 0);
  180. var zeroth_length = (zeroth_set[0].length + exif_is * 12 + gps_is * 12 + 4 +
  181. zeroth_set[1].length);
  182. var exif_set,
  183. exif_bytes = "",
  184. exif_length = 0,
  185. gps_set,
  186. gps_bytes = "",
  187. gps_length = 0,
  188. interop_set,
  189. interop_bytes = "",
  190. interop_length = 0,
  191. first_set,
  192. first_bytes = "",
  193. thumbnail;
  194. if (exif_is) {
  195. exif_set = _dict_to_bytes(exif_ifd, "Exif", zeroth_length);
  196. exif_length = exif_set[0].length + interop_is * 12 + exif_set[1].length;
  197. }
  198. if (gps_is) {
  199. gps_set = _dict_to_bytes(gps_ifd, "GPS", zeroth_length + exif_length);
  200. gps_bytes = gps_set.join("");
  201. gps_length = gps_bytes.length;
  202. }
  203. if (interop_is) {
  204. var offset = zeroth_length + exif_length + gps_length;
  205. interop_set = _dict_to_bytes(interop_ifd, "Interop", offset);
  206. interop_bytes = interop_set.join("");
  207. interop_length = interop_bytes.length;
  208. }
  209. if (first_is) {
  210. var offset = zeroth_length + exif_length + gps_length + interop_length;
  211. first_set = _dict_to_bytes(first_ifd, "1st", offset);
  212. thumbnail = _get_thumbnail(exif_dict["thumbnail"]);
  213. if (thumbnail.length > 64000) {
  214. throw ("Given thumbnail is too large. max 64kB");
  215. }
  216. }
  217. var exif_pointer = "",
  218. gps_pointer = "",
  219. interop_pointer = "",
  220. first_ifd_pointer = "\x00\x00\x00\x00";
  221. if (exif_is) {
  222. var pointer_value = TIFF_HEADER_LENGTH + zeroth_length;
  223. var pointer_str = pack(">L", [pointer_value]);
  224. var key = 34665;
  225. var key_str = pack(">H", [key]);
  226. var type_str = pack(">H", [TYPES["Long"]]);
  227. var length_str = pack(">L", [1]);
  228. exif_pointer = key_str + type_str + length_str + pointer_str;
  229. }
  230. if (gps_is) {
  231. var pointer_value = TIFF_HEADER_LENGTH + zeroth_length + exif_length;
  232. var pointer_str = pack(">L", [pointer_value]);
  233. var key = 34853;
  234. var key_str = pack(">H", [key]);
  235. var type_str = pack(">H", [TYPES["Long"]]);
  236. var length_str = pack(">L", [1]);
  237. gps_pointer = key_str + type_str + length_str + pointer_str;
  238. }
  239. if (interop_is) {
  240. var pointer_value = (TIFF_HEADER_LENGTH +
  241. zeroth_length + exif_length + gps_length);
  242. var pointer_str = pack(">L", [pointer_value]);
  243. var key = 40965;
  244. var key_str = pack(">H", [key]);
  245. var type_str = pack(">H", [TYPES["Long"]]);
  246. var length_str = pack(">L", [1]);
  247. interop_pointer = key_str + type_str + length_str + pointer_str;
  248. }
  249. if (first_is) {
  250. var pointer_value = (TIFF_HEADER_LENGTH + zeroth_length +
  251. exif_length + gps_length + interop_length);
  252. first_ifd_pointer = pack(">L", [pointer_value]);
  253. var thumbnail_pointer = (pointer_value + first_set[0].length + 24 +
  254. 4 + first_set[1].length);
  255. var thumbnail_p_bytes = ("\x02\x01\x00\x04\x00\x00\x00\x01" +
  256. pack(">L", [thumbnail_pointer]));
  257. var thumbnail_length_bytes = ("\x02\x02\x00\x04\x00\x00\x00\x01" +
  258. pack(">L", [thumbnail.length]));
  259. first_bytes = (first_set[0] + thumbnail_p_bytes +
  260. thumbnail_length_bytes + "\x00\x00\x00\x00" +
  261. first_set[1] + thumbnail);
  262. }
  263. var zeroth_bytes = (zeroth_set[0] + exif_pointer + gps_pointer +
  264. first_ifd_pointer + zeroth_set[1]);
  265. if (exif_is) {
  266. exif_bytes = exif_set[0] + interop_pointer + exif_set[1];
  267. }
  268. return (header + zeroth_bytes + exif_bytes + gps_bytes +
  269. interop_bytes + first_bytes);
  270. };
  271. function copy(obj) {
  272. return JSON.parse(JSON.stringify(obj));
  273. }
  274. function _get_thumbnail(jpeg) {
  275. var segments = splitIntoSegments(jpeg);
  276. while (("\xff\xe0" <= segments[1].slice(0, 2)) && (segments[1].slice(0, 2) <= "\xff\xef")) {
  277. segments = [segments[0]].concat(segments.slice(2));
  278. }
  279. return segments.join("");
  280. }
  281. function _pack_byte(array) {
  282. return pack(">" + nStr("B", array.length), array);
  283. }
  284. function _pack_short(array) {
  285. return pack(">" + nStr("H", array.length), array);
  286. }
  287. function _pack_long(array) {
  288. return pack(">" + nStr("L", array.length), array);
  289. }
  290. function _value_to_bytes(raw_value, value_type, offset) {
  291. var four_bytes_over = "";
  292. var value_str = "";
  293. var length,
  294. new_value,
  295. num,
  296. den;
  297. if (value_type == "Byte") {
  298. length = raw_value.length;
  299. if (length <= 4) {
  300. value_str = (_pack_byte(raw_value) +
  301. nStr("\x00", 4 - length));
  302. } else {
  303. value_str = pack(">L", [offset]);
  304. four_bytes_over = _pack_byte(raw_value);
  305. }
  306. } else if (value_type == "Short") {
  307. length = raw_value.length;
  308. if (length <= 2) {
  309. value_str = (_pack_short(raw_value) +
  310. nStr("\x00\x00", 2 - length));
  311. } else {
  312. value_str = pack(">L", [offset]);
  313. four_bytes_over = _pack_short(raw_value);
  314. }
  315. } else if (value_type == "Long") {
  316. length = raw_value.length;
  317. if (length <= 1) {
  318. value_str = _pack_long(raw_value);
  319. } else {
  320. value_str = pack(">L", [offset]);
  321. four_bytes_over = _pack_long(raw_value);
  322. }
  323. } else if (value_type == "Ascii") {
  324. new_value = raw_value + "\x00";
  325. length = new_value.length;
  326. if (length > 4) {
  327. value_str = pack(">L", [offset]);
  328. four_bytes_over = new_value;
  329. } else {
  330. value_str = new_value + nStr("\x00", 4 - length);
  331. }
  332. } else if (value_type == "Rational") {
  333. if (typeof (raw_value[0]) == "number") {
  334. length = 1;
  335. num = raw_value[0];
  336. den = raw_value[1];
  337. new_value = pack(">L", [num]) + pack(">L", [den]);
  338. } else {
  339. length = raw_value.length;
  340. new_value = "";
  341. for (var n = 0; n < length; n++) {
  342. num = raw_value[n][0];
  343. den = raw_value[n][1];
  344. new_value += (pack(">L", [num]) +
  345. pack(">L", [den]));
  346. }
  347. }
  348. value_str = pack(">L", [offset]);
  349. four_bytes_over = new_value;
  350. } else if (value_type == "SRational") {
  351. if (typeof (raw_value[0]) == "number") {
  352. length = 1;
  353. num = raw_value[0];
  354. den = raw_value[1];
  355. new_value = pack(">l", [num]) + pack(">l", [den]);
  356. } else {
  357. length = raw_value.length;
  358. new_value = "";
  359. for (var n = 0; n < length; n++) {
  360. num = raw_value[n][0];
  361. den = raw_value[n][1];
  362. new_value += (pack(">l", [num]) +
  363. pack(">l", [den]));
  364. }
  365. }
  366. value_str = pack(">L", [offset]);
  367. four_bytes_over = new_value;
  368. } else if (value_type == "Undefined") {
  369. length = raw_value.length;
  370. if (length > 4) {
  371. value_str = pack(">L", [offset]);
  372. four_bytes_over = raw_value;
  373. } else {
  374. value_str = raw_value + nStr("\x00", 4 - length);
  375. }
  376. }
  377. var length_str = pack(">L", [length]);
  378. return [length_str, value_str, four_bytes_over];
  379. }
  380. function _dict_to_bytes(ifd_dict, ifd, ifd_offset) {
  381. var TIFF_HEADER_LENGTH = 8;
  382. var tag_count = Object.keys(ifd_dict).length;
  383. var entry_header = pack(">H", [tag_count]);
  384. var entries_length;
  385. if (["0th", "1st"].indexOf(ifd) > -1) {
  386. entries_length = 2 + tag_count * 12 + 4;
  387. } else {
  388. entries_length = 2 + tag_count * 12;
  389. }
  390. var entries = "";
  391. var values = "";
  392. var key;
  393. for (var key in ifd_dict) {
  394. if (typeof (key) == "string") {
  395. key = parseInt(key);
  396. }
  397. if ((ifd == "0th") && ([34665, 34853].indexOf(key) > -1)) {
  398. continue;
  399. } else if ((ifd == "Exif") && (key == 40965)) {
  400. continue;
  401. } else if ((ifd == "1st") && ([513, 514].indexOf(key) > -1)) {
  402. continue;
  403. }
  404. var raw_value = ifd_dict[key];
  405. var key_str = pack(">H", [key]);
  406. var value_type = TAGS[ifd][key]["type"];
  407. var type_str = pack(">H", [TYPES[value_type]]);
  408. if (typeof (raw_value) == "number") {
  409. raw_value = [raw_value];
  410. }
  411. var offset = TIFF_HEADER_LENGTH + entries_length + ifd_offset + values.length;
  412. var b = _value_to_bytes(raw_value, value_type, offset);
  413. var length_str = b[0];
  414. var value_str = b[1];
  415. var four_bytes_over = b[2];
  416. entries += key_str + type_str + length_str + value_str;
  417. values += four_bytes_over;
  418. }
  419. return [entry_header + entries, values];
  420. }
  421. function ExifReader(data) {
  422. var segments,
  423. app1;
  424. if (data.slice(0, 2) == "\xff\xd8") { // JPEG
  425. segments = splitIntoSegments(data);
  426. app1 = getExifSeg(segments);
  427. if (app1) {
  428. this.tiftag = app1.slice(10);
  429. } else {
  430. this.tiftag = null;
  431. }
  432. } else if (["\x49\x49", "\x4d\x4d"].indexOf(data.slice(0, 2)) > -1) { // TIFF
  433. this.tiftag = data;
  434. } else if (data.slice(0, 4) == "Exif") { // Exif
  435. this.tiftag = data.slice(6);
  436. } else {
  437. throw ("Given file is neither JPEG nor TIFF.");
  438. }
  439. }
  440. ExifReader.prototype = {
  441. get_ifd: function (pointer, ifd_name) {
  442. var ifd_dict = {};
  443. var tag_count = unpack(this.endian_mark + "H",
  444. this.tiftag.slice(pointer, pointer + 2))[0];
  445. var offset = pointer + 2;
  446. var t;
  447. if (["0th", "1st"].indexOf(ifd_name) > -1) {
  448. t = "Image";
  449. } else {
  450. t = ifd_name;
  451. }
  452. for (var x = 0; x < tag_count; x++) {
  453. pointer = offset + 12 * x;
  454. var tag = unpack(this.endian_mark + "H",
  455. this.tiftag.slice(pointer, pointer + 2))[0];
  456. var value_type = unpack(this.endian_mark + "H",
  457. this.tiftag.slice(pointer + 2, pointer + 4))[0];
  458. var value_num = unpack(this.endian_mark + "L",
  459. this.tiftag.slice(pointer + 4, pointer + 8))[0];
  460. var value = this.tiftag.slice(pointer + 8, pointer + 12);
  461. var v_set = [value_type, value_num, value];
  462. if (tag in TAGS[t]) {
  463. ifd_dict[tag] = this.convert_value(v_set);
  464. }
  465. }
  466. if (ifd_name == "0th") {
  467. pointer = offset + 12 * tag_count;
  468. ifd_dict["first_ifd_pointer"] = this.tiftag.slice(pointer, pointer + 4);
  469. }
  470. return ifd_dict;
  471. },
  472. convert_value: function (val) {
  473. var data = null;
  474. var t = val[0];
  475. var length = val[1];
  476. var value = val[2];
  477. var pointer;
  478. if (t == 1) { // BYTE
  479. if (length > 4) {
  480. pointer = unpack(this.endian_mark + "L", value)[0];
  481. data = unpack(this.endian_mark + nStr("B", length),
  482. this.tiftag.slice(pointer, pointer + length));
  483. } else {
  484. data = unpack(this.endian_mark + nStr("B", length), value.slice(0, length));
  485. }
  486. } else if (t == 2) { // ASCII
  487. if (length > 4) {
  488. pointer = unpack(this.endian_mark + "L", value)[0];
  489. data = this.tiftag.slice(pointer, pointer + length - 1);
  490. } else {
  491. data = value.slice(0, length - 1);
  492. }
  493. } else if (t == 3) { // SHORT
  494. if (length > 2) {
  495. pointer = unpack(this.endian_mark + "L", value)[0];
  496. data = unpack(this.endian_mark + nStr("H", length),
  497. this.tiftag.slice(pointer, pointer + length * 2));
  498. } else {
  499. data = unpack(this.endian_mark + nStr("H", length),
  500. value.slice(0, length * 2));
  501. }
  502. } else if (t == 4) { // LONG
  503. if (length > 1) {
  504. pointer = unpack(this.endian_mark + "L", value)[0];
  505. data = unpack(this.endian_mark + nStr("L", length),
  506. this.tiftag.slice(pointer, pointer + length * 4));
  507. } else {
  508. data = unpack(this.endian_mark + nStr("L", length),
  509. value);
  510. }
  511. } else if (t == 5) { // RATIONAL
  512. pointer = unpack(this.endian_mark + "L", value)[0];
  513. if (length > 1) {
  514. data = [];
  515. for (var x = 0; x < length; x++) {
  516. data.push([unpack(this.endian_mark + "L",
  517. this.tiftag.slice(pointer + x * 8, pointer + 4 + x * 8))[0],
  518. unpack(this.endian_mark + "L",
  519. this.tiftag.slice(pointer + 4 + x * 8, pointer + 8 + x * 8))[0]
  520. ]);
  521. }
  522. } else {
  523. data = [unpack(this.endian_mark + "L",
  524. this.tiftag.slice(pointer, pointer + 4))[0],
  525. unpack(this.endian_mark + "L",
  526. this.tiftag.slice(pointer + 4, pointer + 8))[0]
  527. ];
  528. }
  529. } else if (t == 7) { // UNDEFINED BYTES
  530. if (length > 4) {
  531. pointer = unpack(this.endian_mark + "L", value)[0];
  532. data = this.tiftag.slice(pointer, pointer + length);
  533. } else {
  534. data = value.slice(0, length);
  535. }
  536. } else if (t == 10) { // SRATIONAL
  537. pointer = unpack(this.endian_mark + "L", value)[0];
  538. if (length > 1) {
  539. data = [];
  540. for (var x = 0; x < length; x++) {
  541. data.push([unpack(this.endian_mark + "l",
  542. this.tiftag.slice(pointer + x * 8, pointer + 4 + x * 8))[0],
  543. unpack(this.endian_mark + "l",
  544. this.tiftag.slice(pointer + 4 + x * 8, pointer + 8 + x * 8))[0]
  545. ]);
  546. }
  547. } else {
  548. data = [unpack(this.endian_mark + "l",
  549. this.tiftag.slice(pointer, pointer + 4))[0],
  550. unpack(this.endian_mark + "l",
  551. this.tiftag.slice(pointer + 4, pointer + 8))[0]
  552. ];
  553. }
  554. } else {
  555. throw ("Exif might be wrong. Got incorrect value " +
  556. "type to decode. type:" + t);
  557. }
  558. if ((data instanceof Array) && (data.length == 1)) {
  559. return data[0];
  560. } else {
  561. return data;
  562. }
  563. },
  564. };
  565. if (typeof window !== "undefined" && typeof window.btoa === "function") {
  566. var btoa = window.btoa;
  567. }
  568. if (typeof btoa === "undefined") {
  569. var btoa = function (input) { var output = "";
  570. var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  571. var i = 0;
  572. var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  573. while (i < input.length) {
  574. chr1 = input.charCodeAt(i++);
  575. chr2 = input.charCodeAt(i++);
  576. chr3 = input.charCodeAt(i++);
  577. enc1 = chr1 >> 2;
  578. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  579. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  580. enc4 = chr3 & 63;
  581. if (isNaN(chr2)) {
  582. enc3 = enc4 = 64;
  583. } else if (isNaN(chr3)) {
  584. enc4 = 64;
  585. }
  586. output = output +
  587. keyStr.charAt(enc1) + keyStr.charAt(enc2) +
  588. keyStr.charAt(enc3) + keyStr.charAt(enc4);
  589. }
  590. return output;
  591. };
  592. }
  593. if (typeof window !== "undefined" && typeof window.atob === "function") {
  594. var atob = window.atob;
  595. }
  596. if (typeof atob === "undefined") {
  597. var atob = function (input) {
  598. var output = "";
  599. var chr1, chr2, chr3;
  600. var enc1, enc2, enc3, enc4;
  601. var i = 0;
  602. var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  603. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  604. while (i < input.length) {
  605. enc1 = keyStr.indexOf(input.charAt(i++));
  606. enc2 = keyStr.indexOf(input.charAt(i++));
  607. enc3 = keyStr.indexOf(input.charAt(i++));
  608. enc4 = keyStr.indexOf(input.charAt(i++));
  609. chr1 = (enc1 << 2) | (enc2 >> 4);
  610. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  611. chr3 = ((enc3 & 3) << 6) | enc4;
  612. output = output + String.fromCharCode(chr1);
  613. if (enc3 != 64) {
  614. output = output + String.fromCharCode(chr2);
  615. }
  616. if (enc4 != 64) {
  617. output = output + String.fromCharCode(chr3);
  618. }
  619. }
  620. return output;
  621. };
  622. }
  623. function getImageSize(imageArray) {
  624. var segments = slice2Segments(imageArray);
  625. var seg,
  626. width,
  627. height,
  628. SOF = [192, 193, 194, 195, 197, 198, 199, 201, 202, 203, 205, 206, 207];
  629. for (var x = 0; x < segments.length; x++) {
  630. seg = segments[x];
  631. if (SOF.indexOf(seg[1]) >= 0) {
  632. height = seg[5] * 256 + seg[6];
  633. width = seg[7] * 256 + seg[8];
  634. break;
  635. }
  636. }
  637. return [width, height];
  638. }
  639. function pack(mark, array) {
  640. if (!(array instanceof Array)) {
  641. throw ("'pack' error. Got invalid type argument.");
  642. }
  643. if ((mark.length - 1) != array.length) {
  644. throw ("'pack' error. " + (mark.length - 1) + " marks, " + array.length + " elements.");
  645. }
  646. var littleEndian;
  647. if (mark[0] == "<") {
  648. littleEndian = true;
  649. } else if (mark[0] == ">") {
  650. littleEndian = false;
  651. } else {
  652. throw ("");
  653. }
  654. var packed = "";
  655. var p = 1;
  656. var val = null;
  657. var c = null;
  658. var valStr = null;
  659. while (c = mark[p]) {
  660. if (c.toLowerCase() == "b") {
  661. val = array[p - 1];
  662. if ((c == "b") && (val < 0)) {
  663. val += 0x100;
  664. }
  665. if ((val > 0xff) || (val < 0)) {
  666. throw ("'pack' error.");
  667. } else {
  668. valStr = String.fromCharCode(val);
  669. }
  670. } else if (c == "H") {
  671. val = array[p - 1];
  672. if ((val > 0xffff) || (val < 0)) {
  673. throw ("'pack' error.");
  674. } else {
  675. valStr = String.fromCharCode(Math.floor((val % 0x10000) / 0x100)) +
  676. String.fromCharCode(val % 0x100);
  677. if (littleEndian) {
  678. valStr = valStr.split("").reverse().join("");
  679. }
  680. }
  681. } else if (c.toLowerCase() == "l") {
  682. val = array[p - 1];
  683. if ((c == "l") && (val < 0)) {
  684. val += 0x100000000;
  685. }
  686. if ((val > 0xffffffff) || (val < 0)) {
  687. throw ("'pack' error.");
  688. } else {
  689. valStr = String.fromCharCode(Math.floor(val / 0x1000000)) +
  690. String.fromCharCode(Math.floor((val % 0x1000000) / 0x10000)) +
  691. String.fromCharCode(Math.floor((val % 0x10000) / 0x100)) +
  692. String.fromCharCode(val % 0x100);
  693. if (littleEndian) {
  694. valStr = valStr.split("").reverse().join("");
  695. }
  696. }
  697. } else {
  698. throw ("'pack' error.");
  699. }
  700. packed += valStr;
  701. p += 1;
  702. }
  703. return packed;
  704. }
  705. function unpack(mark, str) {
  706. if (typeof (str) != "string") {
  707. throw ("'unpack' error. Got invalid type argument.");
  708. }
  709. var l = 0;
  710. for (var markPointer = 1; markPointer < mark.length; markPointer++) {
  711. if (mark[markPointer].toLowerCase() == "b") {
  712. l += 1;
  713. } else if (mark[markPointer].toLowerCase() == "h") {
  714. l += 2;
  715. } else if (mark[markPointer].toLowerCase() == "l") {
  716. l += 4;
  717. } else {
  718. throw ("'unpack' error. Got invalid mark.");
  719. }
  720. }
  721. if (l != str.length) {
  722. throw ("'unpack' error. Mismatch between symbol and string length. " + l + ":" + str.length);
  723. }
  724. var littleEndian;
  725. if (mark[0] == "<") {
  726. littleEndian = true;
  727. } else if (mark[0] == ">") {
  728. littleEndian = false;
  729. } else {
  730. throw ("'unpack' error.");
  731. }
  732. var unpacked = [];
  733. var strPointer = 0;
  734. var p = 1;
  735. var val = null;
  736. var c = null;
  737. var length = null;
  738. var sliced = "";
  739. while (c = mark[p]) {
  740. if (c.toLowerCase() == "b") {
  741. length = 1;
  742. sliced = str.slice(strPointer, strPointer + length);
  743. val = sliced.charCodeAt(0);
  744. if ((c == "b") && (val >= 0x80)) {
  745. val -= 0x100;
  746. }
  747. } else if (c == "H") {
  748. length = 2;
  749. sliced = str.slice(strPointer, strPointer + length);
  750. if (littleEndian) {
  751. sliced = sliced.split("").reverse().join("");
  752. }
  753. val = sliced.charCodeAt(0) * 0x100 +
  754. sliced.charCodeAt(1);
  755. } else if (c.toLowerCase() == "l") {
  756. length = 4;
  757. sliced = str.slice(strPointer, strPointer + length);
  758. if (littleEndian) {
  759. sliced = sliced.split("").reverse().join("");
  760. }
  761. val = sliced.charCodeAt(0) * 0x1000000 +
  762. sliced.charCodeAt(1) * 0x10000 +
  763. sliced.charCodeAt(2) * 0x100 +
  764. sliced.charCodeAt(3);
  765. if ((c == "l") && (val >= 0x80000000)) {
  766. val -= 0x100000000;
  767. }
  768. } else {
  769. throw ("'unpack' error. " + c);
  770. }
  771. unpacked.push(val);
  772. strPointer += length;
  773. p += 1;
  774. }
  775. return unpacked;
  776. }
  777. function nStr(ch, num) {
  778. var str = "";
  779. for (var i = 0; i < num; i++) {
  780. str += ch;
  781. }
  782. return str;
  783. }
  784. function splitIntoSegments(data) {
  785. if (data.slice(0, 2) != "\xff\xd8") {
  786. throw ("Given data isn't JPEG.");
  787. }
  788. var head = 2;
  789. var segments = ["\xff\xd8"];
  790. while (true) {
  791. if (data.slice(head, head + 2) == "\xff\xda") {
  792. segments.push(data.slice(head));
  793. break;
  794. } else {
  795. var length = unpack(">H", data.slice(head + 2, head + 4))[0];
  796. var endPoint = head + length + 2;
  797. segments.push(data.slice(head, endPoint));
  798. head = endPoint;
  799. }
  800. if (head >= data.length) {
  801. throw ("Wrong JPEG data.");
  802. }
  803. }
  804. return segments;
  805. }
  806. function getExifSeg(segments) {
  807. var seg;
  808. for (var i = 0; i < segments.length; i++) {
  809. seg = segments[i];
  810. if (seg.slice(0, 2) == "\xff\xe1" &&
  811. seg.slice(4, 10) == "Exif\x00\x00") {
  812. return seg;
  813. }
  814. }
  815. return null;
  816. }
  817. function mergeSegments(segments, exif) {
  818. if (segments[1].slice(0, 2) == "\xff\xe0" &&
  819. (segments[2].slice(0, 2) == "\xff\xe1" &&
  820. segments[2].slice(4, 10) == "Exif\x00\x00")) {
  821. if (exif) {
  822. segments[2] = exif;
  823. segments = ["\xff\xd8"].concat(segments.slice(2));
  824. } else if (exif == null) {
  825. segments = segments.slice(0, 2).concat(segments.slice(3));
  826. } else {
  827. segments = segments.slice(0).concat(segments.slice(2));
  828. }
  829. } else if (segments[1].slice(0, 2) == "\xff\xe0") {
  830. if (exif) {
  831. segments[1] = exif;
  832. }
  833. } else if (segments[1].slice(0, 2) == "\xff\xe1" &&
  834. segments[1].slice(4, 10) == "Exif\x00\x00") {
  835. if (exif) {
  836. segments[1] = exif;
  837. } else if (exif == null) {
  838. segments = segments.slice(0).concat(segments.slice(2));
  839. }
  840. } else {
  841. if (exif) {
  842. segments = [segments[0], exif].concat(segments.slice(1));
  843. }
  844. }
  845. return segments.join("");
  846. }
  847. function toHex(str) {
  848. var hexStr = "";
  849. for (var i = 0; i < str.length; i++) {
  850. var h = str.charCodeAt(i);
  851. var hex = ((h < 10) ? "0" : "") + h.toString(16);
  852. hexStr += hex + " ";
  853. }
  854. return hexStr;
  855. }
  856. var TYPES = {
  857. "Byte": 1,
  858. "Ascii": 2,
  859. "Short": 3,
  860. "Long": 4,
  861. "Rational": 5,
  862. "Undefined": 7,
  863. "SLong": 9,
  864. "SRational": 10
  865. };
  866. var TAGS = {
  867. 'Image': {
  868. 11: {
  869. 'name': 'ProcessingSoftware',
  870. 'type': 'Ascii'
  871. },
  872. 254: {
  873. 'name': 'NewSubfileType',
  874. 'type': 'Long'
  875. },
  876. 255: {
  877. 'name': 'SubfileType',
  878. 'type': 'Short'
  879. },
  880. 256: {
  881. 'name': 'ImageWidth',
  882. 'type': 'Long'
  883. },
  884. 257: {
  885. 'name': 'ImageLength',
  886. 'type': 'Long'
  887. },
  888. 258: {
  889. 'name': 'BitsPerSample',
  890. 'type': 'Short'
  891. },
  892. 259: {
  893. 'name': 'Compression',
  894. 'type': 'Short'
  895. },
  896. 262: {
  897. 'name': 'PhotometricInterpretation',
  898. 'type': 'Short'
  899. },
  900. 263: {
  901. 'name': 'Threshholding',
  902. 'type': 'Short'
  903. },
  904. 264: {
  905. 'name': 'CellWidth',
  906. 'type': 'Short'
  907. },
  908. 265: {
  909. 'name': 'CellLength',
  910. 'type': 'Short'
  911. },
  912. 266: {
  913. 'name': 'FillOrder',
  914. 'type': 'Short'
  915. },
  916. 269: {
  917. 'name': 'DocumentName',
  918. 'type': 'Ascii'
  919. },
  920. 270: {
  921. 'name': 'ImageDescription',
  922. 'type': 'Ascii'
  923. },
  924. 271: {
  925. 'name': 'Make',
  926. 'type': 'Ascii'
  927. },
  928. 272: {
  929. 'name': 'Model',
  930. 'type': 'Ascii'
  931. },
  932. 273: {
  933. 'name': 'StripOffsets',
  934. 'type': 'Long'
  935. },
  936. 274: {
  937. 'name': 'Orientation',
  938. 'type': 'Short'
  939. },
  940. 277: {
  941. 'name': 'SamplesPerPixel',
  942. 'type': 'Short'
  943. },
  944. 278: {
  945. 'name': 'RowsPerStrip',
  946. 'type': 'Long'
  947. },
  948. 279: {
  949. 'name': 'StripByteCounts',
  950. 'type': 'Long'
  951. },
  952. 282: {
  953. 'name': 'XResolution',
  954. 'type': 'Rational'
  955. },
  956. 283: {
  957. 'name': 'YResolution',
  958. 'type': 'Rational'
  959. },
  960. 284: {
  961. 'name': 'PlanarConfiguration',
  962. 'type': 'Short'
  963. },
  964. 290: {
  965. 'name': 'GrayResponseUnit',
  966. 'type': 'Short'
  967. },
  968. 291: {
  969. 'name': 'GrayResponseCurve',
  970. 'type': 'Short'
  971. },
  972. 292: {
  973. 'name': 'T4Options',
  974. 'type': 'Long'
  975. },
  976. 293: {
  977. 'name': 'T6Options',
  978. 'type': 'Long'
  979. },
  980. 296: {
  981. 'name': 'ResolutionUnit',
  982. 'type': 'Short'
  983. },
  984. 301: {
  985. 'name': 'TransferFunction',
  986. 'type': 'Short'
  987. },
  988. 305: {
  989. 'name': 'Software',
  990. 'type': 'Ascii'
  991. },
  992. 306: {
  993. 'name': 'DateTime',
  994. 'type': 'Ascii'
  995. },
  996. 315: {
  997. 'name': 'Artist',
  998. 'type': 'Ascii'
  999. },
  1000. 316: {
  1001. 'name': 'HostComputer',
  1002. 'type': 'Ascii'
  1003. },
  1004. 317: {
  1005. 'name': 'Predictor',
  1006. 'type': 'Short'
  1007. },
  1008. 318: {
  1009. 'name': 'WhitePoint',
  1010. 'type': 'Rational'
  1011. },
  1012. 319: {
  1013. 'name': 'PrimaryChromaticities',
  1014. 'type': 'Rational'
  1015. },
  1016. 320: {
  1017. 'name': 'ColorMap',
  1018. 'type': 'Short'
  1019. },
  1020. 321: {
  1021. 'name': 'HalftoneHints',
  1022. 'type': 'Short'
  1023. },
  1024. 322: {
  1025. 'name': 'TileWidth',
  1026. 'type': 'Short'
  1027. },
  1028. 323: {
  1029. 'name': 'TileLength',
  1030. 'type': 'Short'
  1031. },
  1032. 324: {
  1033. 'name': 'TileOffsets',
  1034. 'type': 'Short'
  1035. },
  1036. 325: {
  1037. 'name': 'TileByteCounts',
  1038. 'type': 'Short'
  1039. },
  1040. 330: {
  1041. 'name': 'SubIFDs',
  1042. 'type': 'Long'
  1043. },
  1044. 332: {
  1045. 'name': 'InkSet',
  1046. 'type': 'Short'
  1047. },
  1048. 333: {
  1049. 'name': 'InkNames',
  1050. 'type': 'Ascii'
  1051. },
  1052. 334: {
  1053. 'name': 'NumberOfInks',
  1054. 'type': 'Short'
  1055. },
  1056. 336: {
  1057. 'name': 'DotRange',
  1058. 'type': 'Byte'
  1059. },
  1060. 337: {
  1061. 'name': 'TargetPrinter',
  1062. 'type': 'Ascii'
  1063. },
  1064. 338: {
  1065. 'name': 'ExtraSamples',
  1066. 'type': 'Short'
  1067. },
  1068. 339: {
  1069. 'name': 'SampleFormat',
  1070. 'type': 'Short'
  1071. },
  1072. 340: {
  1073. 'name': 'SMinSampleValue',
  1074. 'type': 'Short'
  1075. },
  1076. 341: {
  1077. 'name': 'SMaxSampleValue',
  1078. 'type': 'Short'
  1079. },
  1080. 342: {
  1081. 'name': 'TransferRange',
  1082. 'type': 'Short'
  1083. },
  1084. 343: {
  1085. 'name': 'ClipPath',
  1086. 'type': 'Byte'
  1087. },
  1088. 344: {
  1089. 'name': 'XClipPathUnits',
  1090. 'type': 'Long'
  1091. },
  1092. 345: {
  1093. 'name': 'YClipPathUnits',
  1094. 'type': 'Long'
  1095. },
  1096. 346: {
  1097. 'name': 'Indexed',
  1098. 'type': 'Short'
  1099. },
  1100. 347: {
  1101. 'name': 'JPEGTables',
  1102. 'type': 'Undefined'
  1103. },
  1104. 351: {
  1105. 'name': 'OPIProxy',
  1106. 'type': 'Short'
  1107. },
  1108. 512: {
  1109. 'name': 'JPEGProc',
  1110. 'type': 'Long'
  1111. },
  1112. 513: {
  1113. 'name': 'JPEGInterchangeFormat',
  1114. 'type': 'Long'
  1115. },
  1116. 514: {
  1117. 'name': 'JPEGInterchangeFormatLength',
  1118. 'type': 'Long'
  1119. },
  1120. 515: {
  1121. 'name': 'JPEGRestartInterval',
  1122. 'type': 'Short'
  1123. },
  1124. 517: {
  1125. 'name': 'JPEGLosslessPredictors',
  1126. 'type': 'Short'
  1127. },
  1128. 518: {
  1129. 'name': 'JPEGPointTransforms',
  1130. 'type': 'Short'
  1131. },
  1132. 519: {
  1133. 'name': 'JPEGQTables',
  1134. 'type': 'Long'
  1135. },
  1136. 520: {
  1137. 'name': 'JPEGDCTables',
  1138. 'type': 'Long'
  1139. },
  1140. 521: {
  1141. 'name': 'JPEGACTables',
  1142. 'type': 'Long'
  1143. },
  1144. 529: {
  1145. 'name': 'YCbCrCoefficients',
  1146. 'type': 'Rational'
  1147. },
  1148. 530: {
  1149. 'name': 'YCbCrSubSampling',
  1150. 'type': 'Short'
  1151. },
  1152. 531: {
  1153. 'name': 'YCbCrPositioning',
  1154. 'type': 'Short'
  1155. },
  1156. 532: {
  1157. 'name': 'ReferenceBlackWhite',
  1158. 'type': 'Rational'
  1159. },
  1160. 700: {
  1161. 'name': 'XMLPacket',
  1162. 'type': 'Byte'
  1163. },
  1164. 18246: {
  1165. 'name': 'Rating',
  1166. 'type': 'Short'
  1167. },
  1168. 18249: {
  1169. 'name': 'RatingPercent',
  1170. 'type': 'Short'
  1171. },
  1172. 32781: {
  1173. 'name': 'ImageID',
  1174. 'type': 'Ascii'
  1175. },
  1176. 33421: {
  1177. 'name': 'CFARepeatPatternDim',
  1178. 'type': 'Short'
  1179. },
  1180. 33422: {
  1181. 'name': 'CFAPattern',
  1182. 'type': 'Byte'
  1183. },
  1184. 33423: {
  1185. 'name': 'BatteryLevel',
  1186. 'type': 'Rational'
  1187. },
  1188. 33432: {
  1189. 'name': 'Copyright',
  1190. 'type': 'Ascii'
  1191. },
  1192. 33434: {
  1193. 'name': 'ExposureTime',
  1194. 'type': 'Rational'
  1195. },
  1196. 34377: {
  1197. 'name': 'ImageResources',
  1198. 'type': 'Byte'
  1199. },
  1200. 34665: {
  1201. 'name': 'ExifTag',
  1202. 'type': 'Long'
  1203. },
  1204. 34675: {
  1205. 'name': 'InterColorProfile',
  1206. 'type': 'Undefined'
  1207. },
  1208. 34853: {
  1209. 'name': 'GPSTag',
  1210. 'type': 'Long'
  1211. },
  1212. 34857: {
  1213. 'name': 'Interlace',
  1214. 'type': 'Short'
  1215. },
  1216. 34858: {
  1217. 'name': 'TimeZoneOffset',
  1218. 'type': 'Long'
  1219. },
  1220. 34859: {
  1221. 'name': 'SelfTimerMode',
  1222. 'type': 'Short'
  1223. },
  1224. 37387: {
  1225. 'name': 'FlashEnergy',
  1226. 'type': 'Rational'
  1227. },
  1228. 37388: {
  1229. 'name': 'SpatialFrequencyResponse',
  1230. 'type': 'Undefined'
  1231. },
  1232. 37389: {
  1233. 'name': 'Noise',
  1234. 'type': 'Undefined'
  1235. },
  1236. 37390: {
  1237. 'name': 'FocalPlaneXResolution',
  1238. 'type': 'Rational'
  1239. },
  1240. 37391: {
  1241. 'name': 'FocalPlaneYResolution',
  1242. 'type': 'Rational'
  1243. },
  1244. 37392: {
  1245. 'name': 'FocalPlaneResolutionUnit',
  1246. 'type': 'Short'
  1247. },
  1248. 37393: {
  1249. 'name': 'ImageNumber',
  1250. 'type': 'Long'
  1251. },
  1252. 37394: {
  1253. 'name': 'SecurityClassification',
  1254. 'type': 'Ascii'
  1255. },
  1256. 37395: {
  1257. 'name': 'ImageHistory',
  1258. 'type': 'Ascii'
  1259. },
  1260. 37397: {
  1261. 'name': 'ExposureIndex',
  1262. 'type': 'Rational'
  1263. },
  1264. 37398: {
  1265. 'name': 'TIFFEPStandardID',
  1266. 'type': 'Byte'
  1267. },
  1268. 37399: {
  1269. 'name': 'SensingMethod',
  1270. 'type': 'Short'
  1271. },
  1272. 40091: {
  1273. 'name': 'XPTitle',
  1274. 'type': 'Byte'
  1275. },
  1276. 40092: {
  1277. 'name': 'XPComment',
  1278. 'type': 'Byte'
  1279. },
  1280. 40093: {
  1281. 'name': 'XPAuthor',
  1282. 'type': 'Byte'
  1283. },
  1284. 40094: {
  1285. 'name': 'XPKeywords',
  1286. 'type': 'Byte'
  1287. },
  1288. 40095: {
  1289. 'name': 'XPSubject',
  1290. 'type': 'Byte'
  1291. },
  1292. 50341: {
  1293. 'name': 'PrintImageMatching',
  1294. 'type': 'Undefined'
  1295. },
  1296. 50706: {
  1297. 'name': 'DNGVersion',
  1298. 'type': 'Byte'
  1299. },
  1300. 50707: {
  1301. 'name': 'DNGBackwardVersion',
  1302. 'type': 'Byte'
  1303. },
  1304. 50708: {
  1305. 'name': 'UniqueCameraModel',
  1306. 'type': 'Ascii'
  1307. },
  1308. 50709: {
  1309. 'name': 'LocalizedCameraModel',
  1310. 'type': 'Byte'
  1311. },
  1312. 50710: {
  1313. 'name': 'CFAPlaneColor',
  1314. 'type': 'Byte'
  1315. },
  1316. 50711: {
  1317. 'name': 'CFALayout',
  1318. 'type': 'Short'
  1319. },
  1320. 50712: {
  1321. 'name': 'LinearizationTable',
  1322. 'type': 'Short'
  1323. },
  1324. 50713: {
  1325. 'name': 'BlackLevelRepeatDim',
  1326. 'type': 'Short'
  1327. },
  1328. 50714: {
  1329. 'name': 'BlackLevel',
  1330. 'type': 'Rational'
  1331. },
  1332. 50715: {
  1333. 'name': 'BlackLevelDeltaH',
  1334. 'type': 'SRational'
  1335. },
  1336. 50716: {
  1337. 'name': 'BlackLevelDeltaV',
  1338. 'type': 'SRational'
  1339. },
  1340. 50717: {
  1341. 'name': 'WhiteLevel',
  1342. 'type': 'Short'
  1343. },
  1344. 50718: {
  1345. 'name': 'DefaultScale',
  1346. 'type': 'Rational'
  1347. },
  1348. 50719: {
  1349. 'name': 'DefaultCropOrigin',
  1350. 'type': 'Short'
  1351. },
  1352. 50720: {
  1353. 'name': 'DefaultCropSize',
  1354. 'type': 'Short'
  1355. },
  1356. 50721: {
  1357. 'name': 'ColorMatrix1',
  1358. 'type': 'SRational'
  1359. },
  1360. 50722: {
  1361. 'name': 'ColorMatrix2',
  1362. 'type': 'SRational'
  1363. },
  1364. 50723: {
  1365. 'name': 'CameraCalibration1',
  1366. 'type': 'SRational'
  1367. },
  1368. 50724: {
  1369. 'name': 'CameraCalibration2',
  1370. 'type': 'SRational'
  1371. },
  1372. 50725: {
  1373. 'name': 'ReductionMatrix1',
  1374. 'type': 'SRational'
  1375. },
  1376. 50726: {
  1377. 'name': 'ReductionMatrix2',
  1378. 'type': 'SRational'
  1379. },
  1380. 50727: {
  1381. 'name': 'AnalogBalance',
  1382. 'type': 'Rational'
  1383. },
  1384. 50728: {
  1385. 'name': 'AsShotNeutral',
  1386. 'type': 'Short'
  1387. },
  1388. 50729: {
  1389. 'name': 'AsShotWhiteXY',
  1390. 'type': 'Rational'
  1391. },
  1392. 50730: {
  1393. 'name': 'BaselineExposure',
  1394. 'type': 'SRational'
  1395. },
  1396. 50731: {
  1397. 'name': 'BaselineNoise',
  1398. 'type': 'Rational'
  1399. },
  1400. 50732: {
  1401. 'name': 'BaselineSharpness',
  1402. 'type': 'Rational'
  1403. },
  1404. 50733: {
  1405. 'name': 'BayerGreenSplit',
  1406. 'type': 'Long'
  1407. },
  1408. 50734: {
  1409. 'name': 'LinearResponseLimit',
  1410. 'type': 'Rational'
  1411. },
  1412. 50735: {
  1413. 'name': 'CameraSerialNumber',
  1414. 'type': 'Ascii'
  1415. },
  1416. 50736: {
  1417. 'name': 'LensInfo',
  1418. 'type': 'Rational'
  1419. },
  1420. 50737: {
  1421. 'name': 'ChromaBlurRadius',
  1422. 'type': 'Rational'
  1423. },
  1424. 50738: {
  1425. 'name': 'AntiAliasStrength',
  1426. 'type': 'Rational'
  1427. },
  1428. 50739: {
  1429. 'name': 'ShadowScale',
  1430. 'type': 'SRational'
  1431. },
  1432. 50740: {
  1433. 'name': 'DNGPrivateData',
  1434. 'type': 'Byte'
  1435. },
  1436. 50741: {
  1437. 'name': 'MakerNoteSafety',
  1438. 'type': 'Short'
  1439. },
  1440. 50778: {
  1441. 'name': 'CalibrationIlluminant1',
  1442. 'type': 'Short'
  1443. },
  1444. 50779: {
  1445. 'name': 'CalibrationIlluminant2',
  1446. 'type': 'Short'
  1447. },
  1448. 50780: {
  1449. 'name': 'BestQualityScale',
  1450. 'type': 'Rational'
  1451. },
  1452. 50781: {
  1453. 'name': 'RawDataUniqueID',
  1454. 'type': 'Byte'
  1455. },
  1456. 50827: {
  1457. 'name': 'OriginalRawFileName',
  1458. 'type': 'Byte'
  1459. },
  1460. 50828: {
  1461. 'name': 'OriginalRawFileData',
  1462. 'type': 'Undefined'
  1463. },
  1464. 50829: {
  1465. 'name': 'ActiveArea',
  1466. 'type': 'Short'
  1467. },
  1468. 50830: {
  1469. 'name': 'MaskedAreas',
  1470. 'type': 'Short'
  1471. },
  1472. 50831: {
  1473. 'name': 'AsShotICCProfile',
  1474. 'type': 'Undefined'
  1475. },
  1476. 50832: {
  1477. 'name': 'AsShotPreProfileMatrix',
  1478. 'type': 'SRational'
  1479. },
  1480. 50833: {
  1481. 'name': 'CurrentICCProfile',
  1482. 'type': 'Undefined'
  1483. },
  1484. 50834: {
  1485. 'name': 'CurrentPreProfileMatrix',
  1486. 'type': 'SRational'
  1487. },
  1488. 50879: {
  1489. 'name': 'ColorimetricReference',
  1490. 'type': 'Short'
  1491. },
  1492. 50931: {
  1493. 'name': 'CameraCalibrationSignature',
  1494. 'type': 'Byte'
  1495. },
  1496. 50932: {
  1497. 'name': 'ProfileCalibrationSignature',
  1498. 'type': 'Byte'
  1499. },
  1500. 50934: {
  1501. 'name': 'AsShotProfileName',
  1502. 'type': 'Byte'
  1503. },
  1504. 50935: {
  1505. 'name': 'NoiseReductionApplied',
  1506. 'type': 'Rational'
  1507. },
  1508. 50936: {
  1509. 'name': 'ProfileName',
  1510. 'type': 'Byte'
  1511. },
  1512. 50937: {
  1513. 'name': 'ProfileHueSatMapDims',
  1514. 'type': 'Long'
  1515. },
  1516. 50938: {
  1517. 'name': 'ProfileHueSatMapData1',
  1518. 'type': 'Float'
  1519. },
  1520. 50939: {
  1521. 'name': 'ProfileHueSatMapData2',
  1522. 'type': 'Float'
  1523. },
  1524. 50940: {
  1525. 'name': 'ProfileToneCurve',
  1526. 'type': 'Float'
  1527. },
  1528. 50941: {
  1529. 'name': 'ProfileEmbedPolicy',
  1530. 'type': 'Long'
  1531. },
  1532. 50942: {
  1533. 'name': 'ProfileCopyright',
  1534. 'type': 'Byte'
  1535. },
  1536. 50964: {
  1537. 'name': 'ForwardMatrix1',
  1538. 'type': 'SRational'
  1539. },
  1540. 50965: {
  1541. 'name': 'ForwardMatrix2',
  1542. 'type': 'SRational'
  1543. },
  1544. 50966: {
  1545. 'name': 'PreviewApplicationName',
  1546. 'type': 'Byte'
  1547. },
  1548. 50967: {
  1549. 'name': 'PreviewApplicationVersion',
  1550. 'type': 'Byte'
  1551. },
  1552. 50968: {
  1553. 'name': 'PreviewSettingsName',
  1554. 'type': 'Byte'
  1555. },
  1556. 50969: {
  1557. 'name': 'PreviewSettingsDigest',
  1558. 'type': 'Byte'
  1559. },
  1560. 50970: {
  1561. 'name': 'PreviewColorSpace',
  1562. 'type': 'Long'
  1563. },
  1564. 50971: {
  1565. 'name': 'PreviewDateTime',
  1566. 'type': 'Ascii'
  1567. },
  1568. 50972: {
  1569. 'name': 'RawImageDigest',
  1570. 'type': 'Undefined'
  1571. },
  1572. 50973: {
  1573. 'name': 'OriginalRawFileDigest',
  1574. 'type': 'Undefined'
  1575. },
  1576. 50974: {
  1577. 'name': 'SubTileBlockSize',
  1578. 'type': 'Long'
  1579. },
  1580. 50975: {
  1581. 'name': 'RowInterleaveFactor',
  1582. 'type': 'Long'
  1583. },
  1584. 50981: {
  1585. 'name': 'ProfileLookTableDims',
  1586. 'type': 'Long'
  1587. },
  1588. 50982: {
  1589. 'name': 'ProfileLookTableData',
  1590. 'type': 'Float'
  1591. },
  1592. 51008: {
  1593. 'name': 'OpcodeList1',
  1594. 'type': 'Undefined'
  1595. },
  1596. 51009: {
  1597. 'name': 'OpcodeList2',
  1598. 'type': 'Undefined'
  1599. },
  1600. 51022: {
  1601. 'name': 'OpcodeList3',
  1602. 'type': 'Undefined'
  1603. }
  1604. },
  1605. 'Exif': {
  1606. 33434: {
  1607. 'name': 'ExposureTime',
  1608. 'type': 'Rational'
  1609. },
  1610. 33437: {
  1611. 'name': 'FNumber',
  1612. 'type': 'Rational'
  1613. },
  1614. 34850: {
  1615. 'name': 'ExposureProgram',
  1616. 'type': 'Short'
  1617. },
  1618. 34852: {
  1619. 'name': 'SpectralSensitivity',
  1620. 'type': 'Ascii'
  1621. },
  1622. 34855: {
  1623. 'name': 'ISOSpeedRatings',
  1624. 'type': 'Short'
  1625. },
  1626. 34856: {
  1627. 'name': 'OECF',
  1628. 'type': 'Undefined'
  1629. },
  1630. 34864: {
  1631. 'name': 'SensitivityType',
  1632. 'type': 'Short'
  1633. },
  1634. 34865: {
  1635. 'name': 'StandardOutputSensitivity',
  1636. 'type': 'Long'
  1637. },
  1638. 34866: {
  1639. 'name': 'RecommendedExposureIndex',
  1640. 'type': 'Long'
  1641. },
  1642. 34867: {
  1643. 'name': 'ISOSpeed',
  1644. 'type': 'Long'
  1645. },
  1646. 34868: {
  1647. 'name': 'ISOSpeedLatitudeyyy',
  1648. 'type': 'Long'
  1649. },
  1650. 34869: {
  1651. 'name': 'ISOSpeedLatitudezzz',
  1652. 'type': 'Long'
  1653. },
  1654. 36864: {
  1655. 'name': 'ExifVersion',
  1656. 'type': 'Undefined'
  1657. },
  1658. 36867: {
  1659. 'name': 'DateTimeOriginal',
  1660. 'type': 'Ascii'
  1661. },
  1662. 36868: {
  1663. 'name': 'DateTimeDigitized',
  1664. 'type': 'Ascii'
  1665. },
  1666. 37121: {
  1667. 'name': 'ComponentsConfiguration',
  1668. 'type': 'Undefined'
  1669. },
  1670. 37122: {
  1671. 'name': 'CompressedBitsPerPixel',
  1672. 'type': 'Rational'
  1673. },
  1674. 37377: {
  1675. 'name': 'ShutterSpeedValue',
  1676. 'type': 'SRational'
  1677. },
  1678. 37378: {
  1679. 'name': 'ApertureValue',
  1680. 'type': 'Rational'
  1681. },
  1682. 37379: {
  1683. 'name': 'BrightnessValue',
  1684. 'type': 'SRational'
  1685. },
  1686. 37380: {
  1687. 'name': 'ExposureBiasValue',
  1688. 'type': 'SRational'
  1689. },
  1690. 37381: {
  1691. 'name': 'MaxApertureValue',
  1692. 'type': 'Rational'
  1693. },
  1694. 37382: {
  1695. 'name': 'SubjectDistance',
  1696. 'type': 'Rational'
  1697. },
  1698. 37383: {
  1699. 'name': 'MeteringMode',
  1700. 'type': 'Short'
  1701. },
  1702. 37384: {
  1703. 'name': 'LightSource',
  1704. 'type': 'Short'
  1705. },
  1706. 37385: {
  1707. 'name': 'Flash',
  1708. 'type': 'Short'
  1709. },
  1710. 37386: {
  1711. 'name': 'FocalLength',
  1712. 'type': 'Rational'
  1713. },
  1714. 37396: {
  1715. 'name': 'SubjectArea',
  1716. 'type': 'Short'
  1717. },
  1718. 37500: {
  1719. 'name': 'MakerNote',
  1720. 'type': 'Undefined'
  1721. },
  1722. 37510: {
  1723. 'name': 'UserComment',
  1724. 'type': 'Ascii'
  1725. },
  1726. 37520: {
  1727. 'name': 'SubSecTime',
  1728. 'type': 'Ascii'
  1729. },
  1730. 37521: {
  1731. 'name': 'SubSecTimeOriginal',
  1732. 'type': 'Ascii'
  1733. },
  1734. 37522: {
  1735. 'name': 'SubSecTimeDigitized',
  1736. 'type': 'Ascii'
  1737. },
  1738. 40960: {
  1739. 'name': 'FlashpixVersion',
  1740. 'type': 'Undefined'
  1741. },
  1742. 40961: {
  1743. 'name': 'ColorSpace',
  1744. 'type': 'Short'
  1745. },
  1746. 40962: {
  1747. 'name': 'PixelXDimension',
  1748. 'type': 'Long'
  1749. },
  1750. 40963: {
  1751. 'name': 'PixelYDimension',
  1752. 'type': 'Long'
  1753. },
  1754. 40964: {
  1755. 'name': 'RelatedSoundFile',
  1756. 'type': 'Ascii'
  1757. },
  1758. 40965: {
  1759. 'name': 'InteroperabilityTag',
  1760. 'type': 'Long'
  1761. },
  1762. 41483: {
  1763. 'name': 'FlashEnergy',
  1764. 'type': 'Rational'
  1765. },
  1766. 41484: {
  1767. 'name': 'SpatialFrequencyResponse',
  1768. 'type': 'Undefined'
  1769. },
  1770. 41486: {
  1771. 'name': 'FocalPlaneXResolution',
  1772. 'type': 'Rational'
  1773. },
  1774. 41487: {
  1775. 'name': 'FocalPlaneYResolution',
  1776. 'type': 'Rational'
  1777. },
  1778. 41488: {
  1779. 'name': 'FocalPlaneResolutionUnit',
  1780. 'type': 'Short'
  1781. },
  1782. 41492: {
  1783. 'name': 'SubjectLocation',
  1784. 'type': 'Short'
  1785. },
  1786. 41493: {
  1787. 'name': 'ExposureIndex',
  1788. 'type': 'Rational'
  1789. },
  1790. 41495: {
  1791. 'name': 'SensingMethod',
  1792. 'type': 'Short'
  1793. },
  1794. 41728: {
  1795. 'name': 'FileSource',
  1796. 'type': 'Undefined'
  1797. },
  1798. 41729: {
  1799. 'name': 'SceneType',
  1800. 'type': 'Undefined'
  1801. },
  1802. 41730: {
  1803. 'name': 'CFAPattern',
  1804. 'type': 'Undefined'
  1805. },
  1806. 41985: {
  1807. 'name': 'CustomRendered',
  1808. 'type': 'Short'
  1809. },
  1810. 41986: {
  1811. 'name': 'ExposureMode',
  1812. 'type': 'Short'
  1813. },
  1814. 41987: {
  1815. 'name': 'WhiteBalance',
  1816. 'type': 'Short'
  1817. },
  1818. 41988: {
  1819. 'name': 'DigitalZoomRatio',
  1820. 'type': 'Rational'
  1821. },
  1822. 41989: {
  1823. 'name': 'FocalLengthIn35mmFilm',
  1824. 'type': 'Short'
  1825. },
  1826. 41990: {
  1827. 'name': 'SceneCaptureType',
  1828. 'type': 'Short'
  1829. },
  1830. 41991: {
  1831. 'name': 'GainControl',
  1832. 'type': 'Short'
  1833. },
  1834. 41992: {
  1835. 'name': 'Contrast',
  1836. 'type': 'Short'
  1837. },
  1838. 41993: {
  1839. 'name': 'Saturation',
  1840. 'type': 'Short'
  1841. },
  1842. 41994: {
  1843. 'name': 'Sharpness',
  1844. 'type': 'Short'
  1845. },
  1846. 41995: {
  1847. 'name': 'DeviceSettingDescription',
  1848. 'type': 'Undefined'
  1849. },
  1850. 41996: {
  1851. 'name': 'SubjectDistanceRange',
  1852. 'type': 'Short'
  1853. },
  1854. 42016: {
  1855. 'name': 'ImageUniqueID',
  1856. 'type': 'Ascii'
  1857. },
  1858. 42032: {
  1859. 'name': 'CameraOwnerName',
  1860. 'type': 'Ascii'
  1861. },
  1862. 42033: {
  1863. 'name': 'BodySerialNumber',
  1864. 'type': 'Ascii'
  1865. },
  1866. 42034: {
  1867. 'name': 'LensSpecification',
  1868. 'type': 'Rational'
  1869. },
  1870. 42035: {
  1871. 'name': 'LensMake',
  1872. 'type': 'Ascii'
  1873. },
  1874. 42036: {
  1875. 'name': 'LensModel',
  1876. 'type': 'Ascii'
  1877. },
  1878. 42037: {
  1879. 'name': 'LensSerialNumber',
  1880. 'type': 'Ascii'
  1881. },
  1882. 42240: {
  1883. 'name': 'Gamma',
  1884. 'type': 'Rational'
  1885. }
  1886. },
  1887. 'GPS': {
  1888. 0: {
  1889. 'name': 'GPSVersionID',
  1890. 'type': 'Byte'
  1891. },
  1892. 1: {
  1893. 'name': 'GPSLatitudeRef',
  1894. 'type': 'Ascii'
  1895. },
  1896. 2: {
  1897. 'name': 'GPSLatitude',
  1898. 'type': 'Rational'
  1899. },
  1900. 3: {
  1901. 'name': 'GPSLongitudeRef',
  1902. 'type': 'Ascii'
  1903. },
  1904. 4: {
  1905. 'name': 'GPSLongitude',
  1906. 'type': 'Rational'
  1907. },
  1908. 5: {
  1909. 'name': 'GPSAltitudeRef',
  1910. 'type': 'Byte'
  1911. },
  1912. 6: {
  1913. 'name': 'GPSAltitude',
  1914. 'type': 'Rational'
  1915. },
  1916. 7: {
  1917. 'name': 'GPSTimeStamp',
  1918. 'type': 'Rational'
  1919. },
  1920. 8: {
  1921. 'name': 'GPSSatellites',
  1922. 'type': 'Ascii'
  1923. },
  1924. 9: {
  1925. 'name': 'GPSStatus',
  1926. 'type': 'Ascii'
  1927. },
  1928. 10: {
  1929. 'name': 'GPSMeasureMode',
  1930. 'type': 'Ascii'
  1931. },
  1932. 11: {
  1933. 'name': 'GPSDOP',
  1934. 'type': 'Rational'
  1935. },
  1936. 12: {
  1937. 'name': 'GPSSpeedRef',
  1938. 'type': 'Ascii'
  1939. },
  1940. 13: {
  1941. 'name': 'GPSSpeed',
  1942. 'type': 'Rational'
  1943. },
  1944. 14: {
  1945. 'name': 'GPSTrackRef',
  1946. 'type': 'Ascii'
  1947. },
  1948. 15: {
  1949. 'name': 'GPSTrack',
  1950. 'type': 'Rational'
  1951. },
  1952. 16: {
  1953. 'name': 'GPSImgDirectionRef',
  1954. 'type': 'Ascii'
  1955. },
  1956. 17: {
  1957. 'name': 'GPSImgDirection',
  1958. 'type': 'Rational'
  1959. },
  1960. 18: {
  1961. 'name': 'GPSMapDatum',
  1962. 'type': 'Ascii'
  1963. },
  1964. 19: {
  1965. 'name': 'GPSDestLatitudeRef',
  1966. 'type': 'Ascii'
  1967. },
  1968. 20: {
  1969. 'name': 'GPSDestLatitude',
  1970. 'type': 'Rational'
  1971. },
  1972. 21: {
  1973. 'name': 'GPSDestLongitudeRef',
  1974. 'type': 'Ascii'
  1975. },
  1976. 22: {
  1977. 'name': 'GPSDestLongitude',
  1978. 'type': 'Rational'
  1979. },
  1980. 23: {
  1981. 'name': 'GPSDestBearingRef',
  1982. 'type': 'Ascii'
  1983. },
  1984. 24: {
  1985. 'name': 'GPSDestBearing',
  1986. 'type': 'Rational'
  1987. },
  1988. 25: {
  1989. 'name': 'GPSDestDistanceRef',
  1990. 'type': 'Ascii'
  1991. },
  1992. 26: {
  1993. 'name': 'GPSDestDistance',
  1994. 'type': 'Rational'
  1995. },
  1996. 27: {
  1997. 'name': 'GPSProcessingMethod',
  1998. 'type': 'Undefined'
  1999. },
  2000. 28: {
  2001. 'name': 'GPSAreaInformation',
  2002. 'type': 'Undefined'
  2003. },
  2004. 29: {
  2005. 'name': 'GPSDateStamp',
  2006. 'type': 'Ascii'
  2007. },
  2008. 30: {
  2009. 'name': 'GPSDifferential',
  2010. 'type': 'Short'
  2011. },
  2012. 31: {
  2013. 'name': 'GPSHPositioningError',
  2014. 'type': 'Rational'
  2015. }
  2016. },
  2017. 'Interop': {
  2018. 1: {
  2019. 'name': 'InteroperabilityIndex',
  2020. 'type': 'Ascii'
  2021. }
  2022. },
  2023. };
  2024. TAGS["0th"] = TAGS["Image"];
  2025. TAGS["1st"] = TAGS["Image"];
  2026. that.TAGS = TAGS;
  2027. that.ImageIFD = {
  2028. ProcessingSoftware:11,
  2029. NewSubfileType:254,
  2030. SubfileType:255,
  2031. ImageWidth:256,
  2032. ImageLength:257,
  2033. BitsPerSample:258,
  2034. Compression:259,
  2035. PhotometricInterpretation:262,
  2036. Threshholding:263,
  2037. CellWidth:264,
  2038. CellLength:265,
  2039. FillOrder:266,
  2040. DocumentName:269,
  2041. ImageDescription:270,
  2042. Make:271,
  2043. Model:272,
  2044. StripOffsets:273,
  2045. Orientation:274,
  2046. SamplesPerPixel:277,
  2047. RowsPerStrip:278,
  2048. StripByteCounts:279,
  2049. XResolution:282,
  2050. YResolution:283,
  2051. PlanarConfiguration:284,
  2052. GrayResponseUnit:290,
  2053. GrayResponseCurve:291,
  2054. T4Options:292,
  2055. T6Options:293,
  2056. ResolutionUnit:296,
  2057. TransferFunction:301,
  2058. Software:305,
  2059. DateTime:306,
  2060. Artist:315,
  2061. HostComputer:316,
  2062. Predictor:317,
  2063. WhitePoint:318,
  2064. PrimaryChromaticities:319,
  2065. ColorMap:320,
  2066. HalftoneHints:321,
  2067. TileWidth:322,
  2068. TileLength:323,
  2069. TileOffsets:324,
  2070. TileByteCounts:325,
  2071. SubIFDs:330,
  2072. InkSet:332,
  2073. InkNames:333,
  2074. NumberOfInks:334,
  2075. DotRange:336,
  2076. TargetPrinter:337,
  2077. ExtraSamples:338,
  2078. SampleFormat:339,
  2079. SMinSampleValue:340,
  2080. SMaxSampleValue:341,
  2081. TransferRange:342,
  2082. ClipPath:343,
  2083. XClipPathUnits:344,
  2084. YClipPathUnits:345,
  2085. Indexed:346,
  2086. JPEGTables:347,
  2087. OPIProxy:351,
  2088. JPEGProc:512,
  2089. JPEGInterchangeFormat:513,
  2090. JPEGInterchangeFormatLength:514,
  2091. JPEGRestartInterval:515,
  2092. JPEGLosslessPredictors:517,
  2093. JPEGPointTransforms:518,
  2094. JPEGQTables:519,
  2095. JPEGDCTables:520,
  2096. JPEGACTables:521,
  2097. YCbCrCoefficients:529,
  2098. YCbCrSubSampling:530,
  2099. YCbCrPositioning:531,
  2100. ReferenceBlackWhite:532,
  2101. XMLPacket:700,
  2102. Rating:18246,
  2103. RatingPercent:18249,
  2104. ImageID:32781,
  2105. CFARepeatPatternDim:33421,
  2106. CFAPattern:33422,
  2107. BatteryLevel:33423,
  2108. Copyright:33432,
  2109. ExposureTime:33434,
  2110. ImageResources:34377,
  2111. ExifTag:34665,
  2112. InterColorProfile:34675,
  2113. GPSTag:34853,
  2114. Interlace:34857,
  2115. TimeZoneOffset:34858,
  2116. SelfTimerMode:34859,
  2117. FlashEnergy:37387,
  2118. SpatialFrequencyResponse:37388,
  2119. Noise:37389,
  2120. FocalPlaneXResolution:37390,
  2121. FocalPlaneYResolution:37391,
  2122. FocalPlaneResolutionUnit:37392,
  2123. ImageNumber:37393,
  2124. SecurityClassification:37394,
  2125. ImageHistory:37395,
  2126. ExposureIndex:37397,
  2127. TIFFEPStandardID:37398,
  2128. SensingMethod:37399,
  2129. XPTitle:40091,
  2130. XPComment:40092,
  2131. XPAuthor:40093,
  2132. XPKeywords:40094,
  2133. XPSubject:40095,
  2134. PrintImageMatching:50341,
  2135. DNGVersion:50706,
  2136. DNGBackwardVersion:50707,
  2137. UniqueCameraModel:50708,
  2138. LocalizedCameraModel:50709,
  2139. CFAPlaneColor:50710,
  2140. CFALayout:50711,
  2141. LinearizationTable:50712,
  2142. BlackLevelRepeatDim:50713,
  2143. BlackLevel:50714,
  2144. BlackLevelDeltaH:50715,
  2145. BlackLevelDeltaV:50716,
  2146. WhiteLevel:50717,
  2147. DefaultScale:50718,
  2148. DefaultCropOrigin:50719,
  2149. DefaultCropSize:50720,
  2150. ColorMatrix1:50721,
  2151. ColorMatrix2:50722,
  2152. CameraCalibration1:50723,
  2153. CameraCalibration2:50724,
  2154. ReductionMatrix1:50725,
  2155. ReductionMatrix2:50726,
  2156. AnalogBalance:50727,
  2157. AsShotNeutral:50728,
  2158. AsShotWhiteXY:50729,
  2159. BaselineExposure:50730,
  2160. BaselineNoise:50731,
  2161. BaselineSharpness:50732,
  2162. BayerGreenSplit:50733,
  2163. LinearResponseLimit:50734,
  2164. CameraSerialNumber:50735,
  2165. LensInfo:50736,
  2166. ChromaBlurRadius:50737,
  2167. AntiAliasStrength:50738,
  2168. ShadowScale:50739,
  2169. DNGPrivateData:50740,
  2170. MakerNoteSafety:50741,
  2171. CalibrationIlluminant1:50778,
  2172. CalibrationIlluminant2:50779,
  2173. BestQualityScale:50780,
  2174. RawDataUniqueID:50781,
  2175. OriginalRawFileName:50827,
  2176. OriginalRawFileData:50828,
  2177. ActiveArea:50829,
  2178. MaskedAreas:50830,
  2179. AsShotICCProfile:50831,
  2180. AsShotPreProfileMatrix:50832,
  2181. CurrentICCProfile:50833,
  2182. CurrentPreProfileMatrix:50834,
  2183. ColorimetricReference:50879,
  2184. CameraCalibrationSignature:50931,
  2185. ProfileCalibrationSignature:50932,
  2186. AsShotProfileName:50934,
  2187. NoiseReductionApplied:50935,
  2188. ProfileName:50936,
  2189. ProfileHueSatMapDims:50937,
  2190. ProfileHueSatMapData1:50938,
  2191. ProfileHueSatMapData2:50939,
  2192. ProfileToneCurve:50940,
  2193. ProfileEmbedPolicy:50941,
  2194. ProfileCopyright:50942,
  2195. ForwardMatrix1:50964,
  2196. ForwardMatrix2:50965,
  2197. PreviewApplicationName:50966,
  2198. PreviewApplicationVersion:50967,
  2199. PreviewSettingsName:50968,
  2200. PreviewSettingsDigest:50969,
  2201. PreviewColorSpace:50970,
  2202. PreviewDateTime:50971,
  2203. RawImageDigest:50972,
  2204. OriginalRawFileDigest:50973,
  2205. SubTileBlockSize:50974,
  2206. RowInterleaveFactor:50975,
  2207. ProfileLookTableDims:50981,
  2208. ProfileLookTableData:50982,
  2209. OpcodeList1:51008,
  2210. OpcodeList2:51009,
  2211. OpcodeList3:51022,
  2212. NoiseProfile:51041,
  2213. };
  2214. that.ExifIFD = {
  2215. ExposureTime:33434,
  2216. FNumber:33437,
  2217. ExposureProgram:34850,
  2218. SpectralSensitivity:34852,
  2219. ISOSpeedRatings:34855,
  2220. OECF:34856,
  2221. SensitivityType:34864,
  2222. StandardOutputSensitivity:34865,
  2223. RecommendedExposureIndex:34866,
  2224. ISOSpeed:34867,
  2225. ISOSpeedLatitudeyyy:34868,
  2226. ISOSpeedLatitudezzz:34869,
  2227. ExifVersion:36864,
  2228. DateTimeOriginal:36867,
  2229. DateTimeDigitized:36868,
  2230. ComponentsConfiguration:37121,
  2231. CompressedBitsPerPixel:37122,
  2232. ShutterSpeedValue:37377,
  2233. ApertureValue:37378,
  2234. BrightnessValue:37379,
  2235. ExposureBiasValue:37380,
  2236. MaxApertureValue:37381,
  2237. SubjectDistance:37382,
  2238. MeteringMode:37383,
  2239. LightSource:37384,
  2240. Flash:37385,
  2241. FocalLength:37386,
  2242. SubjectArea:37396,
  2243. MakerNote:37500,
  2244. UserComment:37510,
  2245. SubSecTime:37520,
  2246. SubSecTimeOriginal:37521,
  2247. SubSecTimeDigitized:37522,
  2248. FlashpixVersion:40960,
  2249. ColorSpace:40961,
  2250. PixelXDimension:40962,
  2251. PixelYDimension:40963,
  2252. RelatedSoundFile:40964,
  2253. InteroperabilityTag:40965,
  2254. FlashEnergy:41483,
  2255. SpatialFrequencyResponse:41484,
  2256. FocalPlaneXResolution:41486,
  2257. FocalPlaneYResolution:41487,
  2258. FocalPlaneResolutionUnit:41488,
  2259. SubjectLocation:41492,
  2260. ExposureIndex:41493,
  2261. SensingMethod:41495,
  2262. FileSource:41728,
  2263. SceneType:41729,
  2264. CFAPattern:41730,
  2265. CustomRendered:41985,
  2266. ExposureMode:41986,
  2267. WhiteBalance:41987,
  2268. DigitalZoomRatio:41988,
  2269. FocalLengthIn35mmFilm:41989,
  2270. SceneCaptureType:41990,
  2271. GainControl:41991,
  2272. Contrast:41992,
  2273. Saturation:41993,
  2274. Sharpness:41994,
  2275. DeviceSettingDescription:41995,
  2276. SubjectDistanceRange:41996,
  2277. ImageUniqueID:42016,
  2278. CameraOwnerName:42032,
  2279. BodySerialNumber:42033,
  2280. LensSpecification:42034,
  2281. LensMake:42035,
  2282. LensModel:42036,
  2283. LensSerialNumber:42037,
  2284. Gamma:42240,
  2285. };
  2286. that.GPSIFD = {
  2287. GPSVersionID:0,
  2288. GPSLatitudeRef:1,
  2289. GPSLatitude:2,
  2290. GPSLongitudeRef:3,
  2291. GPSLongitude:4,
  2292. GPSAltitudeRef:5,
  2293. GPSAltitude:6,
  2294. GPSTimeStamp:7,
  2295. GPSSatellites:8,
  2296. GPSStatus:9,
  2297. GPSMeasureMode:10,
  2298. GPSDOP:11,
  2299. GPSSpeedRef:12,
  2300. GPSSpeed:13,
  2301. GPSTrackRef:14,
  2302. GPSTrack:15,
  2303. GPSImgDirectionRef:16,
  2304. GPSImgDirection:17,
  2305. GPSMapDatum:18,
  2306. GPSDestLatitudeRef:19,
  2307. GPSDestLatitude:20,
  2308. GPSDestLongitudeRef:21,
  2309. GPSDestLongitude:22,
  2310. GPSDestBearingRef:23,
  2311. GPSDestBearing:24,
  2312. GPSDestDistanceRef:25,
  2313. GPSDestDistance:26,
  2314. GPSProcessingMethod:27,
  2315. GPSAreaInformation:28,
  2316. GPSDateStamp:29,
  2317. GPSDifferential:30,
  2318. GPSHPositioningError:31,
  2319. };
  2320. that.InteropIFD = {
  2321. InteroperabilityIndex:1,
  2322. };
  2323. that.GPSHelper = {
  2324. degToDmsRational:function (degFloat) {
  2325. var minFloat = degFloat % 1 * 60;
  2326. var secFloat = minFloat % 1 * 60;
  2327. var deg = Math.floor(degFloat);
  2328. var min = Math.floor(minFloat);
  2329. var sec = Math.round(secFloat * 100);
  2330. return [[deg, 1], [min, 1], [sec, 100]];
  2331. }
  2332. };
  2333. if (typeof exports !== 'undefined') {
  2334. if (typeof module !== 'undefined' && module.exports) {
  2335. exports = module.exports = that;
  2336. }
  2337. exports.piexif = that;
  2338. } else {
  2339. window.piexif = that;
  2340. }
  2341. })();