| Index: chrome/common/extensions/docs/examples/extensions/imageinfo.zip
|
| ===================================================================
|
| --- chrome/common/extensions/docs/examples/extensions/imageinfo.zip (revision 115251)
|
| +++ chrome/common/extensions/docs/examples/extensions/imageinfo.zip (working copy)
|
| @@ -1,9 +1,9 @@
|
| -PK üy>/¥â imageinfo/NOTICEThis extension uses code from the following JavaScript library:
|
| +PK Ô1=/¥â imageinfo/NOTICEThis extension uses code from the following JavaScript library:
|
|
|
| ImageInfo - A JavaScript library for reading image metadata.
|
| Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
| MIT License [http://www.nihilogic.dk/licenses/mit-license.txt]
|
| -PK MTP?[u¿E E imageinfo/background.html<!DOCTYPE html>
|
| +PK ÎQ?[u¿E E imageinfo/background.html<!DOCTYPE html>
|
| <!--
|
| * Copyright (c) 2011 The Chromium Authors. All rights reserved. Use of this
|
| * source code is governed by a BSD-style license that can be found in the
|
| @@ -17,7 +17,7 @@
|
| <script src="background.js"></script>
|
| </body>
|
| </html>
|
| -PK MTP?àZÚè è imageinfo/background.js// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +PK ÎQ?àZÚè è imageinfo/background.js// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| @@ -44,7 +44,8 @@
|
| "contexts" : ["image"],
|
| "onclick" : getClickHandler()
|
| });
|
| -PK üy>PtYÅk k imageinfo/imageinfo-128.pngPNG
|
| +PK |
|
| +T>PtYÅk k imageinfo/imageinfo-128.pngPNG
|
|
|
|
|
| IHDR Ã>aË sBIT|d pHYs ÒÝ~ü tEXtCreation Time 9/7/10uùc tEXtSoftware Adobe Fireworks CS4²Ó ÅIDATxÚí?kA G$ XA°$?@ü Blbc`g ÄÎÌÝAL¡ÉÅÕYY"XY]¬ÆýÎ1¬»½»½ËÎÎxdowvovæÍÿ˵vâ
L@ 2 ò ' ]cÌ¢ò/x±¢ÙlB\~%IZÐjµl§Ó(¯| j!Àîî®%Ê+O P?·À#:¶Mî÷ ¼NÉKÏ$ïó°øÖÚ¬Ý<:]W<¨ 7ßXûꫵg¿D)¾îÓý° Ã|±
|
| @@ -53,7 +54,8 @@
|
| 0Ê/FØ(ÓÀ)
|
| ~YSļicÙë÷yc ÿgé£|Á/k¤â°TSÆé«²¸ n]^öÏÇ`£óq¶ ¢¨ÆªæñD´ OÝæRÞ¬1 ë Ì à²ùf¯£s¦c¯'ß]&z¦ÿÌO´ ®`¯ý´nçö¶yr×<°÷̽J ´¸t)J«Ò¬´ë` ~!+ïG)ܲÐ;éÝ|9¢àymo§ªÅÁ¶ÙO ½tÌ
> @íX7ë¥ ÏÞp¼6ñ @8? Ä!@·Ûµ¶ÓéT"ãMÏÎÎN_ @d(NòjvaaFÀe¢ËtÏÏÏ÷þ®¬¬¤Ç³³³vuuµwßÒÒRzÞÅóLñß]I_ïÿkÙû¤ÇÅw×îü ç#@T£öööz«cÓñññq/ÞÖÖV/2[A×Ý3üBÊ^ËÞW4=.þééiONýÕç"ÏG¸æÔ/<ókj àλxýᮩõÈÞ7lzü4¹ëâ#@I¨¶©~WPT ÕJÝç@ÀðZwmæU°ý®¹|ä}·$E t®æû½ì ±ß5?°W¼ç«B).©{ðGÞã4Ã,(kzSü&"Y
|
| ÖÌΠͽ ¸hZVÚ?Ã`Wµ@4M(_øµàààà×þþ¾
b´Ûí:µ s gY³¡ÁðOÅMà° L@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ¨ ;!ð
|
| -Ù0 IEND®B`PK üy>EA· imageinfo/imageinfo-16.pngPNG
|
| +Ù0 IEND®B`PK |
|
| +T>EA· imageinfo/imageinfo-16.pngPNG
|
|
|
|
|
| IHDR óÿa sBIT|d pHYs ÒÝ~ü tEXtCreation Time 9/7/10uùc tEXtSoftware Adobe Fireworks CS4²Ó úIDAT8Ë¥¡
|
| @@ -62,12 +64,14 @@
|
| °8 -ÐFµWÝÈ hZ;íÎ0
|
| SN©5zk =êãÈH¥¤Ç¬ßz?
|
| 8ÍG »3h¢¯vðna¹ÈË¢,Q!*ÒEM:Ê"ÐeìÕ4¾RÀøçyð}?ÌAï(×uÕ Û¶Cñè8N)B
|
| -Ãi¸?}xxÅ¿ð¸&,æQøGWÍ{ÙãN¦¯â IEND®B`PK üy>ñ ÞÀæ æ imageinfo/imageinfo-19.pngPNG
|
| +Ãi¸?}xxÅ¿ð¸&,æQøGWÍ{ÙãN¦¯â IEND®B`PK |
|
| +T>ñ ÞÀæ æ imageinfo/imageinfo-19.pngPNG
|
|
|
|
|
| IHDR rP6Ì sBIT|d pHYs ÒÝ~ü tEXtCreation Time 9/7/10uùc tEXtSoftware Adobe Fireworks CS4²Ó @IDAT8ËÕ±JÄ@Ó¥.Ø ÂU¦®ø¾ÄéòñR©lb!
|
| ÕF¢E¯Q,.(Z«ßûwñLâ%r?dfó;;k 0%ÏïÀè¡»èÃðnÆCÞ.°hyç:g½IôA
|
| -¬¿¯ã7|ÅËtçÃ{`ãX¯·]NP BðÙ£¡saO¥Ú»Öt7?§z\o<æo³¡½rÃV°ím¢3ã,Yg§ß/¥vRGêtóÙ ¶$ å+"X k2¬U_|õOOF8¿Va;× 2è,úþYçhYÍäµ0ß÷aÛ6,Ëã8ê5Ó4¦©Ê]×Uú´4ÃØw-Ç1¢(R ¢#þCµZß$ÿ"ÏóJØ"_Úùì« F IEND®B`PK üy>ª
|
| +¬¿¯ã7|ÅËtçÃ{`ãX¯·]NP BðÙ£¡saO¥Ú»Öt7?§z\o<æo³¡½rÃV°ím¢3ã,Yg§ß/¥vRGêtóÙ ¶$ å+"X k2¬U_|õOOF8¿Va;× 2è,úþYçhYÍäµ0ß÷aÛ6,Ëã8ê5Ó4¦©Ê]×Uú´4ÃØw-Ç1¢(R ¢#þCµZß$ÿ"ÏóJØ"_Úùì« F IEND®B`PK |
|
| +T>ª
|
| T T imageinfo/imageinfo-48.pngPNG
|
|
|
|
|
| @@ -76,7 +80,7 @@
|
| ó÷_'/õO<öUÕ5zÌ+ÀÍüêó|Ø#ËnF Îï¬MǬ¿pÙó¼ØO¬ÀxöRÀü8êl°~¶àwW"u ±ßQYÑ#ÇßÜØBû³$*ºqô÷v@uU8ÑSH¶ e$NµiÃÊmî% P ô VÍ|=r3
|
| 0ëÆvÄVpÀ'-4«8u°ä¢'À"ÏT Â'μFǪ.½g Gó ШHJ@hNÑ>MG\ >;èmñº9Ö*FV8ãaÜ3ï'úÅ·ÈàºôO ªhÖy£µ¥Öh-õä5Ð 14¨Á&ÒÚ¦íXyëME £³Ç÷wiiÂüJ üu::@»ÝVN ×ëñ`0xÖï÷¹V«%PVÉ*J ¼îv»ARH Brx¯\.1x?ø"@bX©T
|
| ü0|çÁ(`"lø^Tpú}DER4ì{«x@£ÑgAõóù|{QÝE #¼z±È¶-Ùhb8¶ZH2MÓ'£È ã¼G@dY<ÀU8Ìâßúz
|
| - &õn÷64Ð IEND®B`PK MTP?
|
| + &õn÷64Ð IEND®B`PK ÎQ?
|
| dT2 2 imageinfo/info.css/**
|
| * Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| * Use of this source code is governed by a BSD-style license that can be
|
| @@ -133,7 +137,7 @@
|
| #exif, #output {
|
| display: none;
|
| }
|
| -PK MTP?óé imageinfo/info.html<!DOCTYPE html>
|
| +PK ÎQ?óé imageinfo/info.html<!DOCTYPE html>
|
| <!--
|
| * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
|
| * source code is governed by a BSD-style license that can be found in the
|
| @@ -235,7 +239,7 @@
|
| </div>
|
| </body>
|
| </html>
|
| -PK MTP?:Í Í imageinfo/info.js// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +PK ÎQ?:Í Í imageinfo/info.js// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| @@ -380,7 +384,7 @@
|
| ImageInfo.loadInfo(imageUrl, getImageInfoHandler(imageUrl));
|
| }
|
| });
|
| -PK üy>ѺåPÎ Î imageinfo/loader.gifGIF89a ð 777ÿÿÿ!ù
|
| +PK Ô1=ѺåPÎ Î imageinfo/loader.gifGIF89a ð 777ÿÿÿ!ù
|
| !þCreated with ajaxload.info !ÿNETSCAPE2.0 , -iÀí¾B;S®*½êr^g~Y®c´.ÕékÊöêZÿ* !ù
|
| , -iÀí¾;-XåµzÛ}^öI(iÕv¹ ,Ú9ÒøÎݬø* !ù
|
| , ,iÀí¾N3Åè½ÖfÌ
Çu¤Fa(±`èðXßÙÒ÷·÷öT !ù
|
| @@ -388,7 +392,7 @@
|
| j~yÜÖæÆ)äV7fõUÛçýÏoS !ù
|
| , -iÀí¾ØiÄjcÎêaÝÒIáXét®W)î
|
| ÒÞ¦«üä( !ù
|
| - , ,iÀí¾Ú+ÉpÄ×Voubæu#v'Øj)G¿0d£©«áóP ;PK MTP?Ùl
|
| + , ,iÀí¾Ú+ÉpÄ×Voubæu#v'Øj)G¿0d£©«áóP ;PK ÎQ?Ùl
|
| ä ä imageinfo/manifest.json{
|
| "name" : "Imageinfo",
|
| "version" : "1.0.1",
|
| @@ -409,1049 +413,1053 @@
|
| "content_security_policy": "default-src 'self'; connect-src *; img-src *"
|
|
|
| }
|
| -PK üy>Æ
|
| -<» ! imageinfo/imageinfo/binaryajax.js
|
| -/*
|
| - * Binary Ajax 0.1.5
|
| - * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/
|
| - * MIT License [http://www.opensource.org/licenses/mit-license.php]
|
| - */
|
| -
|
| -
|
| -var BinaryFile = function(strData, iDataOffset, iDataLength) {
|
| - var data = strData;
|
| - var dataOffset = iDataOffset || 0;
|
| - var dataLength = 0;
|
| -
|
| - this.getRawData = function() {
|
| - return data;
|
| - }
|
| -
|
| - if (typeof strData == "string") {
|
| - dataLength = iDataLength || data.length;
|
| -
|
| - this.getByteAt = function(iOffset) {
|
| - return data.charCodeAt(iOffset + dataOffset) & 0xFF;
|
| - }
|
| - } else if (typeof strData == "unknown") {
|
| - dataLength = iDataLength || IEBinary_getLength(data);
|
| -
|
| - this.getByteAt = function(iOffset) {
|
| - return IEBinary_getByteAt(data, iOffset + dataOffset);
|
| - }
|
| - }
|
| -
|
| - this.getLength = function() {
|
| - return dataLength;
|
| - }
|
| -
|
| - this.getSByteAt = function(iOffset) {
|
| - var iByte = this.getByteAt(iOffset);
|
| - if (iByte > 127)
|
| - return iByte - 256;
|
| - else
|
| - return iByte;
|
| - }
|
| -
|
| - this.getShortAt = function(iOffset, bBigEndian) {
|
| - var iShort = bBigEndian ?
|
| - (this.getByteAt(iOffset) << 8) + this.getByteAt(iOffset + 1)
|
| - : (this.getByteAt(iOffset + 1) << 8) + this.getByteAt(iOffset)
|
| - if (iShort < 0) iShort += 65536;
|
| - return iShort;
|
| - }
|
| - this.getSShortAt = function(iOffset, bBigEndian) {
|
| - var iUShort = this.getShortAt(iOffset, bBigEndian);
|
| - if (iUShort > 32767)
|
| - return iUShort - 65536;
|
| - else
|
| - return iUShort;
|
| - }
|
| - this.getLongAt = function(iOffset, bBigEndian) {
|
| - var iByte1 = this.getByteAt(iOffset),
|
| - iByte2 = this.getByteAt(iOffset + 1),
|
| - iByte3 = this.getByteAt(iOffset + 2),
|
| - iByte4 = this.getByteAt(iOffset + 3);
|
| -
|
| - var iLong = bBigEndian ?
|
| - (((((iByte1 << 8) + iByte2) << 8) + iByte3) << 8) + iByte4
|
| - : (((((iByte4 << 8) + iByte3) << 8) + iByte2) << 8) + iByte1;
|
| - if (iLong < 0) iLong += 4294967296;
|
| - return iLong;
|
| - }
|
| - this.getSLongAt = function(iOffset, bBigEndian) {
|
| - var iULong = this.getLongAt(iOffset, bBigEndian);
|
| - if (iULong > 2147483647)
|
| - return iULong - 4294967296;
|
| - else
|
| - return iULong;
|
| - }
|
| - this.getStringAt = function(iOffset, iLength) {
|
| - var aStr = [];
|
| - for (var i=iOffset,j=0;i<iOffset+iLength;i++,j++) {
|
| - aStr[j] = String.fromCharCode(this.getByteAt(i));
|
| - }
|
| - return aStr.join("");
|
| - }
|
| -
|
| - this.getCharAt = function(iOffset) {
|
| - return String.fromCharCode(this.getByteAt(iOffset));
|
| - }
|
| - this.toBase64 = function() {
|
| - return window.btoa(data);
|
| - }
|
| - this.fromBase64 = function(strBase64) {
|
| - data = window.atob(strBase64);
|
| - }
|
| -}
|
| -
|
| -
|
| -var BinaryAjax = (function() {
|
| -
|
| - function createRequest() {
|
| - var oHTTP = null;
|
| - if (window.XMLHttpRequest) {
|
| - oHTTP = new XMLHttpRequest();
|
| - } else if (window.ActiveXObject) {
|
| - oHTTP = new ActiveXObject("Microsoft.XMLHTTP");
|
| - }
|
| - return oHTTP;
|
| - }
|
| -
|
| - function getHead(strURL, fncCallback, fncError) {
|
| - var oHTTP = createRequest();
|
| - if (oHTTP) {
|
| - if (fncCallback) {
|
| - if (typeof(oHTTP.onload) != "undefined") {
|
| - oHTTP.onload = function() {
|
| - if (oHTTP.status == "200") {
|
| - fncCallback(this);
|
| - } else {
|
| - if (fncError) fncError();
|
| - }
|
| - oHTTP = null;
|
| - };
|
| - } else {
|
| - oHTTP.onreadystatechange = function() {
|
| - if (oHTTP.readyState == 4) {
|
| - if (oHTTP.status == "200") {
|
| - fncCallback(this);
|
| - } else {
|
| - if (fncError) fncError();
|
| - }
|
| - oHTTP = null;
|
| - }
|
| - };
|
| - }
|
| - }
|
| - oHTTP.open("HEAD", strURL, true);
|
| - oHTTP.send(null);
|
| - } else {
|
| - if (fncError) fncError();
|
| - }
|
| - }
|
| -
|
| - function sendRequest(strURL, fncCallback, fncError, aRange, bAcceptRanges, iFileSize) {
|
| - var oHTTP = createRequest();
|
| - if (oHTTP) {
|
| -
|
| - var iDataOffset = 0;
|
| - if (aRange && !bAcceptRanges) {
|
| - iDataOffset = aRange[0];
|
| - }
|
| - var iDataLen = 0;
|
| - if (aRange) {
|
| - iDataLen = aRange[1]-aRange[0]+1;
|
| - }
|
| -
|
| - if (fncCallback) {
|
| - if (typeof(oHTTP.onload) != "undefined") {
|
| - oHTTP.onload = function() {
|
| -
|
| - if (oHTTP.status == "200" || oHTTP.status == "206") {
|
| - this.binaryResponse = new BinaryFile(this.responseText, iDataOffset, iDataLen);
|
| - this.fileSize = iFileSize || this.getResponseHeader("Content-Length");
|
| - fncCallback(this);
|
| - } else {
|
| - if (fncError) fncError();
|
| - }
|
| - oHTTP = null;
|
| - };
|
| - } else {
|
| - oHTTP.onreadystatechange = function() {
|
| - if (oHTTP.readyState == 4) {
|
| - if (oHTTP.status == "200" || oHTTP.status == "206") {
|
| - this.binaryResponse = new BinaryFile(oHTTP.responseBody, iDataOffset, iDataLen);
|
| - this.fileSize = iFileSize || this.getResponseHeader("Content-Length");
|
| - fncCallback(this);
|
| - } else {
|
| - if (fncError) fncError();
|
| - }
|
| - oHTTP = null;
|
| - }
|
| - };
|
| - }
|
| - }
|
| - oHTTP.open("GET", strURL, true);
|
| -
|
| - if (oHTTP.overrideMimeType) oHTTP.overrideMimeType('text/plain; charset=x-user-defined');
|
| -
|
| - if (aRange && bAcceptRanges) {
|
| - oHTTP.setRequestHeader("Range", "bytes=" + aRange[0] + "-" + aRange[1]);
|
| - }
|
| -
|
| - oHTTP.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 1970 00:00:00 GMT");
|
| -
|
| - oHTTP.send(null);
|
| - } else {
|
| - if (fncError) fncError();
|
| - }
|
| - }
|
| -
|
| - return function(strURL, fncCallback, fncError, aRange) {
|
| -
|
| - if (aRange) {
|
| - getHead(
|
| - strURL,
|
| - function(oHTTP) {
|
| - var iLength = parseInt(oHTTP.getResponseHeader("Content-Length"),10);
|
| - var strAcceptRanges = oHTTP.getResponseHeader("Accept-Ranges");
|
| -
|
| - var iStart, iEnd;
|
| - iStart = aRange[0];
|
| - if (aRange[0] < 0)
|
| - iStart += iLength;
|
| - iEnd = iStart + aRange[1] - 1;
|
| -
|
| - sendRequest(strURL, fncCallback, fncError, [iStart, iEnd], (strAcceptRanges == "bytes"), iLength);
|
| - }
|
| - );
|
| -
|
| - } else {
|
| - sendRequest(strURL, fncCallback, fncError);
|
| - }
|
| - }
|
| -
|
| -}());
|
| -
|
| -
|
| -document.write(
|
| - "<script type='text/vbscript'>\r\n"
|
| - + "Function IEBinary_getByteAt(strBinary, iOffset)\r\n"
|
| - + " IEBinary_getByteAt = AscB(MidB(strBinary,iOffset+1,1))\r\n"
|
| - + "End Function\r\n"
|
| - + "Function IEBinary_getLength(strBinary)\r\n"
|
| - + " IEBinary_getLength = LenB(strBinary)\r\n"
|
| - + "End Function\r\n"
|
| - + "</script>\r\n"
|
| -);
|
| -PK üy>`ÝÿK ÿK imageinfo/imageinfo/exif.js/*
|
| - * Javascript EXIF Reader 0.1.2
|
| - * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/
|
| - * MIT License [http://www.opensource.org/licenses/mit-license.php]
|
| - */
|
| -
|
| -
|
| -var EXIF = {};
|
| -
|
| -(function() {
|
| -
|
| -var bDebug = false;
|
| -
|
| -EXIF.Tags = {
|
| -
|
| - // version tags
|
| - 0x9000 : "ExifVersion", // EXIF version
|
| - 0xA000 : "FlashpixVersion", // Flashpix format version
|
| -
|
| - // colorspace tags
|
| - 0xA001 : "ColorSpace", // Color space information tag
|
| -
|
| - // image configuration
|
| - 0xA002 : "PixelXDimension", // Valid width of meaningful image
|
| - 0xA003 : "PixelYDimension", // Valid height of meaningful image
|
| - 0x9101 : "ComponentsConfiguration", // Information about channels
|
| - 0x9102 : "CompressedBitsPerPixel", // Compressed bits per pixel
|
| -
|
| - // user information
|
| - 0x927C : "MakerNote", // Any desired information written by the manufacturer
|
| - 0x9286 : "UserComment", // Comments by user
|
| -
|
| - // related file
|
| - 0xA004 : "RelatedSoundFile", // Name of related sound file
|
| -
|
| - // date and time
|
| - 0x9003 : "DateTimeOriginal", // Date and time when the original image was generated
|
| - 0x9004 : "DateTimeDigitized", // Date and time when the image was stored digitally
|
| - 0x9290 : "SubsecTime", // Fractions of seconds for DateTime
|
| - 0x9291 : "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal
|
| - 0x9292 : "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized
|
| -
|
| - // picture-taking conditions
|
| - 0x829A : "ExposureTime", // Exposure time (in seconds)
|
| - 0x829D : "FNumber", // F number
|
| - 0x8822 : "ExposureProgram", // Exposure program
|
| - 0x8824 : "SpectralSensitivity", // Spectral sensitivity
|
| - 0x8827 : "ISOSpeedRatings", // ISO speed rating
|
| - 0x8828 : "OECF", // Optoelectric conversion factor
|
| - 0x9201 : "ShutterSpeedValue", // Shutter speed
|
| - 0x9202 : "ApertureValue", // Lens aperture
|
| - 0x9203 : "BrightnessValue", // Value of brightness
|
| - 0x9204 : "ExposureBias", // Exposure bias
|
| - 0x9205 : "MaxApertureValue", // Smallest F number of lens
|
| - 0x9206 : "SubjectDistance", // Distance to subject in meters
|
| - 0x9207 : "MeteringMode", // Metering mode
|
| - 0x9208 : "LightSource", // Kind of light source
|
| - 0x9209 : "Flash", // Flash status
|
| - 0x9214 : "SubjectArea", // Location and area of main subject
|
| - 0x920A : "FocalLength", // Focal length of the lens in mm
|
| - 0xA20B : "FlashEnergy", // Strobe energy in BCPS
|
| - 0xA20C : "SpatialFrequencyResponse", //
|
| - 0xA20E : "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit
|
| - 0xA20F : "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit
|
| - 0xA210 : "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
|
| - 0xA214 : "SubjectLocation", // Location of subject in image
|
| - 0xA215 : "ExposureIndex", // Exposure index selected on camera
|
| - 0xA217 : "SensingMethod", // Image sensor type
|
| - 0xA300 : "FileSource", // Image source (3 == DSC)
|
| - 0xA301 : "SceneType", // Scene type (1 == directly photographed)
|
| - 0xA302 : "CFAPattern", // Color filter array geometric pattern
|
| - 0xA401 : "CustomRendered", // Special processing
|
| - 0xA402 : "ExposureMode", // Exposure mode
|
| - 0xA403 : "WhiteBalance", // 1 = auto white balance, 2 = manual
|
| - 0xA404 : "DigitalZoomRation", // Digital zoom ratio
|
| - 0xA405 : "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm)
|
| - 0xA406 : "SceneCaptureType", // Type of scene
|
| - 0xA407 : "GainControl", // Degree of overall image gain adjustment
|
| - 0xA408 : "Contrast", // Direction of contrast processing applied by camera
|
| - 0xA409 : "Saturation", // Direction of saturation processing applied by camera
|
| - 0xA40A : "Sharpness", // Direction of sharpness processing applied by camera
|
| - 0xA40B : "DeviceSettingDescription", //
|
| - 0xA40C : "SubjectDistanceRange", // Distance to subject
|
| -
|
| - // other tags
|
| - 0xA005 : "InteroperabilityIFDPointer",
|
| - 0xA420 : "ImageUniqueID" // Identifier assigned uniquely to each image
|
| -};
|
| -
|
| -EXIF.TiffTags = {
|
| - 0x0100 : "ImageWidth",
|
| - 0x0101 : "ImageHeight",
|
| - 0x8769 : "ExifIFDPointer",
|
| - 0x8825 : "GPSInfoIFDPointer",
|
| - 0xA005 : "InteroperabilityIFDPointer",
|
| - 0x0102 : "BitsPerSample",
|
| - 0x0103 : "Compression",
|
| - 0x0106 : "PhotometricInterpretation",
|
| - 0x0112 : "Orientation",
|
| - 0x0115 : "SamplesPerPixel",
|
| - 0x011C : "PlanarConfiguration",
|
| - 0x0212 : "YCbCrSubSampling",
|
| - 0x0213 : "YCbCrPositioning",
|
| - 0x011A : "XResolution",
|
| - 0x011B : "YResolution",
|
| - 0x0128 : "ResolutionUnit",
|
| - 0x0111 : "StripOffsets",
|
| - 0x0116 : "RowsPerStrip",
|
| - 0x0117 : "StripByteCounts",
|
| - 0x0201 : "JPEGInterchangeFormat",
|
| - 0x0202 : "JPEGInterchangeFormatLength",
|
| - 0x012D : "TransferFunction",
|
| - 0x013E : "WhitePoint",
|
| - 0x013F : "PrimaryChromaticities",
|
| - 0x0211 : "YCbCrCoefficients",
|
| - 0x0214 : "ReferenceBlackWhite",
|
| - 0x0132 : "DateTime",
|
| - 0x010E : "ImageDescription",
|
| - 0x010F : "Make",
|
| - 0x0110 : "Model",
|
| - 0x0131 : "Software",
|
| - 0x013B : "Artist",
|
| - 0x8298 : "Copyright"
|
| -}
|
| -
|
| -EXIF.GPSTags = {
|
| - 0x0000 : "GPSVersionID",
|
| - 0x0001 : "GPSLatitudeRef",
|
| - 0x0002 : "GPSLatitude",
|
| - 0x0003 : "GPSLongitudeRef",
|
| - 0x0004 : "GPSLongitude",
|
| - 0x0005 : "GPSAltitudeRef",
|
| - 0x0006 : "GPSAltitude",
|
| - 0x0007 : "GPSTimeStamp",
|
| - 0x0008 : "GPSSatellites",
|
| - 0x0009 : "GPSStatus",
|
| - 0x000A : "GPSMeasureMode",
|
| - 0x000B : "GPSDOP",
|
| - 0x000C : "GPSSpeedRef",
|
| - 0x000D : "GPSSpeed",
|
| - 0x000E : "GPSTrackRef",
|
| - 0x000F : "GPSTrack",
|
| - 0x0010 : "GPSImgDirectionRef",
|
| - 0x0011 : "GPSImgDirection",
|
| - 0x0012 : "GPSMapDatum",
|
| - 0x0013 : "GPSDestLatitudeRef",
|
| - 0x0014 : "GPSDestLatitude",
|
| - 0x0015 : "GPSDestLongitudeRef",
|
| - 0x0016 : "GPSDestLongitude",
|
| - 0x0017 : "GPSDestBearingRef",
|
| - 0x0018 : "GPSDestBearing",
|
| - 0x0019 : "GPSDestDistanceRef",
|
| - 0x001A : "GPSDestDistance",
|
| - 0x001B : "GPSProcessingMethod",
|
| - 0x001C : "GPSAreaInformation",
|
| - 0x001D : "GPSDateStamp",
|
| - 0x001E : "GPSDifferential"
|
| -}
|
| -
|
| -EXIF.StringValues = {
|
| - ExposureProgram : {
|
| - 0 : "Not defined",
|
| - 1 : "Manual",
|
| - 2 : "Normal program",
|
| - 3 : "Aperture priority",
|
| - 4 : "Shutter priority",
|
| - 5 : "Creative program",
|
| - 6 : "Action program",
|
| - 7 : "Portrait mode",
|
| - 8 : "Landscape mode"
|
| - },
|
| - MeteringMode : {
|
| - 0 : "Unknown",
|
| - 1 : "Average",
|
| - 2 : "CenterWeightedAverage",
|
| - 3 : "Spot",
|
| - 4 : "MultiSpot",
|
| - 5 : "Pattern",
|
| - 6 : "Partial",
|
| - 255 : "Other"
|
| - },
|
| - LightSource : {
|
| - 0 : "Unknown",
|
| - 1 : "Daylight",
|
| - 2 : "Fluorescent",
|
| - 3 : "Tungsten (incandescent light)",
|
| - 4 : "Flash",
|
| - 9 : "Fine weather",
|
| - 10 : "Cloudy weather",
|
| - 11 : "Shade",
|
| - 12 : "Daylight fluorescent (D 5700 - 7100K)",
|
| - 13 : "Day white fluorescent (N 4600 - 5400K)",
|
| - 14 : "Cool white fluorescent (W 3900 - 4500K)",
|
| - 15 : "White fluorescent (WW 3200 - 3700K)",
|
| - 17 : "Standard light A",
|
| - 18 : "Standard light B",
|
| - 19 : "Standard light C",
|
| - 20 : "D55",
|
| - 21 : "D65",
|
| - 22 : "D75",
|
| - 23 : "D50",
|
| - 24 : "ISO studio tungsten",
|
| - 255 : "Other"
|
| - },
|
| - Flash : {
|
| - 0x0000 : "Flash did not fire",
|
| - 0x0001 : "Flash fired",
|
| - 0x0005 : "Strobe return light not detected",
|
| - 0x0007 : "Strobe return light detected",
|
| - 0x0009 : "Flash fired, compulsory flash mode",
|
| - 0x000D : "Flash fired, compulsory flash mode, return light not detected",
|
| - 0x000F : "Flash fired, compulsory flash mode, return light detected",
|
| - 0x0010 : "Flash did not fire, compulsory flash mode",
|
| - 0x0018 : "Flash did not fire, auto mode",
|
| - 0x0019 : "Flash fired, auto mode",
|
| - 0x001D : "Flash fired, auto mode, return light not detected",
|
| - 0x001F : "Flash fired, auto mode, return light detected",
|
| - 0x0020 : "No flash function",
|
| - 0x0041 : "Flash fired, red-eye reduction mode",
|
| - 0x0045 : "Flash fired, red-eye reduction mode, return light not detected",
|
| - 0x0047 : "Flash fired, red-eye reduction mode, return light detected",
|
| - 0x0049 : "Flash fired, compulsory flash mode, red-eye reduction mode",
|
| - 0x004D : "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",
|
| - 0x004F : "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",
|
| - 0x0059 : "Flash fired, auto mode, red-eye reduction mode",
|
| - 0x005D : "Flash fired, auto mode, return light not detected, red-eye reduction mode",
|
| - 0x005F : "Flash fired, auto mode, return light detected, red-eye reduction mode"
|
| - },
|
| - SensingMethod : {
|
| - 1 : "Not defined",
|
| - 2 : "One-chip color area sensor",
|
| - 3 : "Two-chip color area sensor",
|
| - 4 : "Three-chip color area sensor",
|
| - 5 : "Color sequential area sensor",
|
| - 7 : "Trilinear sensor",
|
| - 8 : "Color sequential linear sensor"
|
| - },
|
| - SceneCaptureType : {
|
| - 0 : "Standard",
|
| - 1 : "Landscape",
|
| - 2 : "Portrait",
|
| - 3 : "Night scene"
|
| - },
|
| - SceneType : {
|
| - 1 : "Directly photographed"
|
| - },
|
| - CustomRendered : {
|
| - 0 : "Normal process",
|
| - 1 : "Custom process"
|
| - },
|
| - WhiteBalance : {
|
| - 0 : "Auto white balance",
|
| - 1 : "Manual white balance"
|
| - },
|
| - GainControl : {
|
| - 0 : "None",
|
| - 1 : "Low gain up",
|
| - 2 : "High gain up",
|
| - 3 : "Low gain down",
|
| - 4 : "High gain down"
|
| - },
|
| - Contrast : {
|
| - 0 : "Normal",
|
| - 1 : "Soft",
|
| - 2 : "Hard"
|
| - },
|
| - Saturation : {
|
| - 0 : "Normal",
|
| - 1 : "Low saturation",
|
| - 2 : "High saturation"
|
| - },
|
| - Sharpness : {
|
| - 0 : "Normal",
|
| - 1 : "Soft",
|
| - 2 : "Hard"
|
| - },
|
| - SubjectDistanceRange : {
|
| - 0 : "Unknown",
|
| - 1 : "Macro",
|
| - 2 : "Close view",
|
| - 3 : "Distant view"
|
| - },
|
| - FileSource : {
|
| - 3 : "DSC"
|
| - },
|
| -
|
| - Components : {
|
| - 0 : "",
|
| - 1 : "Y",
|
| - 2 : "Cb",
|
| - 3 : "Cr",
|
| - 4 : "R",
|
| - 5 : "G",
|
| - 6 : "B"
|
| - }
|
| -}
|
| -
|
| -function addEvent(oElement, strEvent, fncHandler)
|
| -{
|
| - if (oElement.addEventListener) {
|
| - oElement.addEventListener(strEvent, fncHandler, false);
|
| - } else if (oElement.attachEvent) {
|
| - oElement.attachEvent("on" + strEvent, fncHandler);
|
| - }
|
| -}
|
| -
|
| -
|
| -function imageHasData(oImg)
|
| -{
|
| - return !!(oImg.exifdata);
|
| -}
|
| -
|
| -function getImageData(oImg, fncCallback)
|
| -{
|
| - BinaryAjax(
|
| - oImg.src,
|
| - function(oHTTP) {
|
| - var oEXIF = findEXIFinJPEG(oHTTP.binaryResponse);
|
| - oImg.exifdata = oEXIF || {};
|
| - if (fncCallback) fncCallback();
|
| - }
|
| - )
|
| -}
|
| -
|
| -function findEXIFinJPEG(oFile) {
|
| - var aMarkers = [];
|
| -
|
| - if (oFile.getByteAt(0) != 0xFF || oFile.getByteAt(1) != 0xD8) {
|
| - return false; // not a valid jpeg
|
| - }
|
| -
|
| - var iOffset = 2;
|
| - var iLength = oFile.getLength();
|
| - while (iOffset < iLength) {
|
| - if (oFile.getByteAt(iOffset) != 0xFF) {
|
| - if (bDebug) console.log("Not a valid marker at offset " + iOffset + ", found: " + oFile.getByteAt(iOffset));
|
| - return false; // not a valid marker, something is wrong
|
| - }
|
| -
|
| - var iMarker = oFile.getByteAt(iOffset+1);
|
| -
|
| - // we could implement handling for other markers here,
|
| - // but we're only looking for 0xFFE1 for EXIF data
|
| -
|
| - if (iMarker == 22400) {
|
| - if (bDebug) console.log("Found 0xFFE1 marker");
|
| - return readEXIFData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);
|
| - iOffset += 2 + oFile.getShortAt(iOffset+2, true);
|
| -
|
| - } else if (iMarker == 225) {
|
| - // 0xE1 = Application-specific 1 (for EXIF)
|
| - if (bDebug) console.log("Found 0xFFE1 marker");
|
| - return readEXIFData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);
|
| -
|
| - } else {
|
| - iOffset += 2 + oFile.getShortAt(iOffset+2, true);
|
| - }
|
| -
|
| - }
|
| -
|
| -}
|
| -
|
| -
|
| -function readTags(oFile, iTIFFStart, iDirStart, oStrings, bBigEnd)
|
| -{
|
| - var iEntries = oFile.getShortAt(iDirStart, bBigEnd);
|
| - var oTags = {};
|
| - for (var i=0;i<iEntries;i++) {
|
| - var iEntryOffset = iDirStart + i*12 + 2;
|
| - var strTag = oStrings[oFile.getShortAt(iEntryOffset, bBigEnd)];
|
| - if (!strTag && bDebug) console.log("Unknown tag: " + oFile.getShortAt(iEntryOffset, bBigEnd));
|
| - oTags[strTag] = readTagValue(oFile, iEntryOffset, iTIFFStart, iDirStart, bBigEnd);
|
| - }
|
| - return oTags;
|
| -}
|
| -
|
| -
|
| -function readTagValue(oFile, iEntryOffset, iTIFFStart, iDirStart, bBigEnd)
|
| -{
|
| - var iType = oFile.getShortAt(iEntryOffset+2, bBigEnd);
|
| - var iNumValues = oFile.getLongAt(iEntryOffset+4, bBigEnd);
|
| - var iValueOffset = oFile.getLongAt(iEntryOffset+8, bBigEnd) + iTIFFStart;
|
| -
|
| - switch (iType) {
|
| - case 1: // byte, 8-bit unsigned int
|
| - case 7: // undefined, 8-bit byte, value depending on field
|
| - if (iNumValues == 1) {
|
| - return oFile.getByteAt(iEntryOffset + 8, bBigEnd);
|
| - } else {
|
| - var iValOffset = iNumValues > 4 ? iValueOffset : (iEntryOffset + 8);
|
| - var aVals = [];
|
| - for (var n=0;n<iNumValues;n++) {
|
| - aVals[n] = oFile.getByteAt(iValOffset + n);
|
| - }
|
| - return aVals;
|
| - }
|
| - break;
|
| -
|
| - case 2: // ascii, 8-bit byte
|
| - var iStringOffset = iNumValues > 4 ? iValueOffset : (iEntryOffset + 8);
|
| - return oFile.getStringAt(iStringOffset, iNumValues-1);
|
| - break;
|
| -
|
| - case 3: // short, 16 bit int
|
| - if (iNumValues == 1) {
|
| - return oFile.getShortAt(iEntryOffset + 8, bBigEnd);
|
| - } else {
|
| - var iValOffset = iNumValues > 2 ? iValueOffset : (iEntryOffset + 8);
|
| - var aVals = [];
|
| - for (var n=0;n<iNumValues;n++) {
|
| - aVals[n] = oFile.getShortAt(iValOffset + 2*n, bBigEnd);
|
| - }
|
| - return aVals;
|
| - }
|
| - break;
|
| -
|
| - case 4: // long, 32 bit int
|
| - if (iNumValues == 1) {
|
| - return oFile.getLongAt(iEntryOffset + 8, bBigEnd);
|
| - } else {
|
| - var aVals = [];
|
| - for (var n=0;n<iNumValues;n++) {
|
| - aVals[n] = oFile.getLongAt(iValueOffset + 4*n, bBigEnd);
|
| - }
|
| - return aVals;
|
| - }
|
| - break;
|
| - case 5: // rational = two long values, first is numerator, second is denominator
|
| - if (iNumValues == 1) {
|
| - return oFile.getLongAt(iValueOffset, bBigEnd) / oFile.getLongAt(iValueOffset+4, bBigEnd);
|
| - } else {
|
| - var aVals = [];
|
| - for (var n=0;n<iNumValues;n++) {
|
| - aVals[n] = oFile.getLongAt(iValueOffset + 8*n, bBigEnd) / oFile.getLongAt(iValueOffset+4 + 8*n, bBigEnd);
|
| - }
|
| - return aVals;
|
| - }
|
| - break;
|
| - case 9: // slong, 32 bit signed int
|
| - if (iNumValues == 1) {
|
| - return oFile.getSLongAt(iEntryOffset + 8, bBigEnd);
|
| - } else {
|
| - var aVals = [];
|
| - for (var n=0;n<iNumValues;n++) {
|
| - aVals[n] = oFile.getSLongAt(iValueOffset + 4*n, bBigEnd);
|
| - }
|
| - return aVals;
|
| - }
|
| - break;
|
| - case 10: // signed rational, two slongs, first is numerator, second is denominator
|
| - if (iNumValues == 1) {
|
| - return oFile.getSLongAt(iValueOffset, bBigEnd) / oFile.getSLongAt(iValueOffset+4, bBigEnd);
|
| - } else {
|
| - var aVals = [];
|
| - for (var n=0;n<iNumValues;n++) {
|
| - aVals[n] = oFile.getSLongAt(iValueOffset + 8*n, bBigEnd) / oFile.getSLongAt(iValueOffset+4 + 8*n, bBigEnd);
|
| - }
|
| - return aVals;
|
| - }
|
| - break;
|
| - }
|
| -}
|
| -
|
| -
|
| -function readEXIFData(oFile, iStart, iLength)
|
| -{
|
| - if (oFile.getStringAt(iStart, 4) != "Exif") {
|
| - if (bDebug) console.log("Not valid EXIF data! " + oFile.getStringAt(iStart, 4));
|
| - return false;
|
| - }
|
| -
|
| - var bBigEnd;
|
| -
|
| - var iTIFFOffset = iStart + 6;
|
| -
|
| - // test for TIFF validity and endianness
|
| - if (oFile.getShortAt(iTIFFOffset) == 0x4949) {
|
| - bBigEnd = false;
|
| - } else if (oFile.getShortAt(iTIFFOffset) == 0x4D4D) {
|
| - bBigEnd = true;
|
| - } else {
|
| - if (bDebug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
|
| - return false;
|
| - }
|
| -
|
| - if (oFile.getShortAt(iTIFFOffset+2, bBigEnd) != 0x002A) {
|
| - if (bDebug) console.log("Not valid TIFF data! (no 0x002A)");
|
| - return false;
|
| - }
|
| -
|
| - if (oFile.getLongAt(iTIFFOffset+4, bBigEnd) != 0x00000008) {
|
| - if (bDebug) console.log("Not valid TIFF data! (First offset not 8)", oFile.getShortAt(iTIFFOffset+4, bBigEnd));
|
| - return false;
|
| - }
|
| -
|
| - var oTags = readTags(oFile, iTIFFOffset, iTIFFOffset+8, EXIF.TiffTags, bBigEnd);
|
| -
|
| - if (oTags.ExifIFDPointer) {
|
| - var oEXIFTags = readTags(oFile, iTIFFOffset, iTIFFOffset + oTags.ExifIFDPointer, EXIF.Tags, bBigEnd);
|
| - for (var strTag in oEXIFTags) {
|
| - switch (strTag) {
|
| - case "LightSource" :
|
| - case "Flash" :
|
| - case "MeteringMode" :
|
| - case "ExposureProgram" :
|
| - case "SensingMethod" :
|
| - case "SceneCaptureType" :
|
| - case "SceneType" :
|
| - case "CustomRendered" :
|
| - case "WhiteBalance" :
|
| - case "GainControl" :
|
| - case "Contrast" :
|
| - case "Saturation" :
|
| - case "Sharpness" :
|
| - case "SubjectDistanceRange" :
|
| - case "FileSource" :
|
| - oEXIFTags[strTag] = EXIF.StringValues[strTag][oEXIFTags[strTag]];
|
| - break;
|
| -
|
| - case "ExifVersion" :
|
| - case "FlashpixVersion" :
|
| - oEXIFTags[strTag] = String.fromCharCode(oEXIFTags[strTag][0], oEXIFTags[strTag][1], oEXIFTags[strTag][2], oEXIFTags[strTag][3]);
|
| - break;
|
| -
|
| - case "ComponentsConfiguration" :
|
| - oEXIFTags[strTag] =
|
| - EXIF.StringValues.Components[oEXIFTags[strTag][0]]
|
| - + EXIF.StringValues.Components[oEXIFTags[strTag][1]]
|
| - + EXIF.StringValues.Components[oEXIFTags[strTag][2]]
|
| - + EXIF.StringValues.Components[oEXIFTags[strTag][3]];
|
| - break;
|
| - }
|
| - oTags[strTag] = oEXIFTags[strTag];
|
| - }
|
| - }
|
| -
|
| - if (oTags.GPSInfoIFDPointer) {
|
| - var oGPSTags = readTags(oFile, iTIFFOffset, iTIFFOffset + oTags.GPSInfoIFDPointer, EXIF.GPSTags, bBigEnd);
|
| - for (var strTag in oGPSTags) {
|
| - switch (strTag) {
|
| - case "GPSVersionID" :
|
| - oGPSTags[strTag] = oGPSTags[strTag][0]
|
| - + "." + oGPSTags[strTag][1]
|
| - + "." + oGPSTags[strTag][2]
|
| - + "." + oGPSTags[strTag][3];
|
| - break;
|
| - }
|
| - oTags[strTag] = oGPSTags[strTag];
|
| - }
|
| - }
|
| -
|
| - return oTags;
|
| -}
|
| -
|
| -
|
| -EXIF.getData = function(oImg, fncCallback)
|
| -{
|
| - if (!oImg.complete) return false;
|
| - if (!imageHasData(oImg)) {
|
| - getImageData(oImg, fncCallback);
|
| - } else {
|
| - if (fncCallback) fncCallback();
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -EXIF.getTag = function(oImg, strTag)
|
| -{
|
| - if (!imageHasData(oImg)) return;
|
| - return oImg.exifdata[strTag];
|
| -}
|
| -
|
| -EXIF.pretty = function(oImg)
|
| -{
|
| - if (!imageHasData(oImg)) return "";
|
| - var oData = oImg.exifdata;
|
| - var strPretty = "";
|
| - for (var a in oData) {
|
| - if (oData.hasOwnProperty(a)) {
|
| - if (typeof oData[a] == "object") {
|
| - strPretty += a + " : [" + oData[a].length + " values]\r\n";
|
| - } else {
|
| - strPretty += a + " : " + oData[a] + "\r\n";
|
| - }
|
| - }
|
| - }
|
| - return strPretty;
|
| -}
|
| -
|
| -EXIF.readFromBinaryFile = function(oFile) {
|
| - return findEXIFinJPEG(oFile);
|
| -}
|
| -
|
| -function loadAllImages()
|
| -{
|
| - var aImages = document.getElementsByTagName("img");
|
| - for (var i=0;i<aImages.length;i++) {
|
| - if (aImages[i].getAttribute("exif") == "true") {
|
| - if (!aImages[i].complete) {
|
| - addEvent(aImages[i], "load",
|
| - function() {
|
| - EXIF.getData(this);
|
| - }
|
| - );
|
| - } else {
|
| - EXIF.getData(aImages[i]);
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -addEvent(window, "load", loadAllImages);
|
| -
|
| -})();
|
| -
|
| -PK üy>Îê| | imageinfo/imageinfo/imageinfo.js/*
|
| - * ImageInfo 0.1.2 - A JavaScript library for reading image metadata.
|
| - * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
| - * MIT License [http://www.nihilogic.dk/licenses/mit-license.txt]
|
| - */
|
| -
|
| -
|
| -var ImageInfo = {};
|
| -
|
| -ImageInfo.useRange = false;
|
| -ImageInfo.range = 10240;
|
| -
|
| -(function() {
|
| -
|
| - var files = [];
|
| -
|
| - function readFileData(url, callback) {
|
| - BinaryAjax(
|
| - url,
|
| - function(http) {
|
| - var tags = readInfoFromData(http.binaryResponse);
|
| - var mime = http.getResponseHeader("Content-Type");
|
| -
|
| - tags["mimeType"] = mime;
|
| - tags["byteSize"] = http.fileSize;
|
| -
|
| - files[url] = tags;
|
| - if (callback) callback();
|
| - },
|
| - null,
|
| - ImageInfo.useRange ? [0, ImageInfo.range] : null
|
| - )
|
| - }
|
| -
|
| - function readInfoFromData(data) {
|
| -
|
| - var offset = 0;
|
| -
|
| - if (data.getByteAt(0) == 0xFF && data.getByteAt(1) == 0xD8) {
|
| - return readJPEGInfo(data);
|
| - }
|
| - if (data.getByteAt(0) == 0x89 && data.getStringAt(1, 3) == "PNG") {
|
| - return readPNGInfo(data);
|
| - }
|
| - if (data.getStringAt(0,3) == "GIF") {
|
| - return readGIFInfo(data);
|
| - }
|
| - if (data.getByteAt(0) == 0x42 && data.getByteAt(1) == 0x4D) {
|
| - return readBMPInfo(data);
|
| - }
|
| - if (data.getByteAt(0) == 0x00 && data.getByteAt(1) == 0x00) {
|
| - return readICOInfo(data);
|
| - }
|
| -
|
| - return {
|
| - format : "UNKNOWN"
|
| - };
|
| - }
|
| -
|
| -
|
| - function readPNGInfo(data) {
|
| - var w = data.getLongAt(16,true);
|
| - var h = data.getLongAt(20,true);
|
| -
|
| - var bpc = data.getByteAt(24);
|
| - var ct = data.getByteAt(25);
|
| -
|
| - var bpp = bpc;
|
| - if (ct == 4) bpp *= 2;
|
| - if (ct == 2) bpp *= 3;
|
| - if (ct == 6) bpp *= 4;
|
| -
|
| - var alpha = data.getByteAt(25) >= 4;
|
| -
|
| - return {
|
| - format : "PNG",
|
| - version : "",
|
| - width : w,
|
| - height : h,
|
| - bpp : bpp,
|
| - alpha : alpha,
|
| - exif : {}
|
| - }
|
| - }
|
| -
|
| - function readGIFInfo(data) {
|
| - var version = data.getStringAt(3,3);
|
| - var w = data.getShortAt(6);
|
| - var h = data.getShortAt(8);
|
| -
|
| - var bpp = ((data.getByteAt(10) >> 4) & 7) + 1;
|
| -
|
| - return {
|
| - format : "GIF",
|
| - version : version,
|
| - width : w,
|
| - height : h,
|
| - bpp : bpp,
|
| - alpha : false,
|
| - exif : {}
|
| - }
|
| - }
|
| -
|
| - function readJPEGInfo(data) {
|
| -
|
| - var w = 0;
|
| - var h = 0;
|
| - var comps = 0;
|
| - var len = data.getLength();
|
| - var offset = 2;
|
| - while (offset < len) {
|
| - var marker = data.getShortAt(offset, true);
|
| - offset += 2;
|
| - if (marker == 0xFFC0) {
|
| - h = data.getShortAt(offset + 3, true);
|
| - w = data.getShortAt(offset + 5, true);
|
| - comps = data.getByteAt(offset + 7, true)
|
| - break;
|
| - } else {
|
| - offset += data.getShortAt(offset, true)
|
| - }
|
| - }
|
| -
|
| - var exif = {};
|
| -
|
| - if (typeof EXIF != "undefined" && EXIF.readFromBinaryFile) {
|
| - exif = EXIF.readFromBinaryFile(data);
|
| - }
|
| -
|
| - return {
|
| - format : "JPEG",
|
| - version : "",
|
| - width : w,
|
| - height : h,
|
| - bpp : comps * 8,
|
| - alpha : false,
|
| - exif : exif
|
| - }
|
| - }
|
| -
|
| - function readBMPInfo(data) {
|
| - var w = data.getLongAt(18);
|
| - var h = data.getLongAt(22);
|
| - var bpp = data.getShortAt(28);
|
| - return {
|
| - format : "BMP",
|
| - version : "",
|
| - width : w,
|
| - height : h,
|
| - bpp : bpp,
|
| - alpha : false,
|
| - exif : {}
|
| - }
|
| - }
|
| -
|
| - ImageInfo.loadInfo = function(url, cb) {
|
| - if (!files[url]) {
|
| - readFileData(url, cb);
|
| - } else {
|
| - if (cb) cb();
|
| - }
|
| - }
|
| -
|
| - ImageInfo.getAllFields = function(url) {
|
| - if (!files[url]) return null;
|
| -
|
| - var tags = {};
|
| - for (var a in files[url]) {
|
| - if (files[url].hasOwnProperty(a))
|
| - tags[a] = files[url][a];
|
| - }
|
| - return tags;
|
| - }
|
| -
|
| - ImageInfo.getField = function(url, field) {
|
| - if (!files[url]) return null;
|
| - return files[url][field];
|
| - }
|
| -
|
| -
|
| -})();
|
| -
|
| -PK Ýò>øÐ¶r r imageinfo/imageinfo/readme.txt
|
| +PK Ô1=\ ® ® ! imageinfo/imageinfo/binaryajax.js
|
| +/*
|
| + * Binary Ajax 0.1.5
|
| + * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/
|
| + * MIT License [http://www.opensource.org/licenses/mit-license.php]
|
| + */
|
| +
|
| +
|
| +var BinaryFile = function(strData, iDataOffset, iDataLength) {
|
| + var data = strData;
|
| + var dataOffset = iDataOffset || 0;
|
| + var dataLength = 0;
|
| +
|
| + this.getRawData = function() {
|
| + return data;
|
| + }
|
| +
|
| + if (typeof strData == "string") {
|
| + dataLength = iDataLength || data.length;
|
| +
|
| + this.getByteAt = function(iOffset) {
|
| + return data.charCodeAt(iOffset + dataOffset) & 0xFF;
|
| + }
|
| + } else if (typeof strData == "unknown") {
|
| + dataLength = iDataLength || IEBinary_getLength(data);
|
| +
|
| + this.getByteAt = function(iOffset) {
|
| + return IEBinary_getByteAt(data, iOffset + dataOffset);
|
| + }
|
| + }
|
| +
|
| + this.getLength = function() {
|
| + return dataLength;
|
| + }
|
| +
|
| + this.getSByteAt = function(iOffset) {
|
| + var iByte = this.getByteAt(iOffset);
|
| + if (iByte > 127)
|
| + return iByte - 256;
|
| + else
|
| + return iByte;
|
| + }
|
| +
|
| + this.getShortAt = function(iOffset, bBigEndian) {
|
| + var iShort = bBigEndian ?
|
| + (this.getByteAt(iOffset) << 8) + this.getByteAt(iOffset + 1)
|
| + : (this.getByteAt(iOffset + 1) << 8) + this.getByteAt(iOffset)
|
| + if (iShort < 0) iShort += 65536;
|
| + return iShort;
|
| + }
|
| + this.getSShortAt = function(iOffset, bBigEndian) {
|
| + var iUShort = this.getShortAt(iOffset, bBigEndian);
|
| + if (iUShort > 32767)
|
| + return iUShort - 65536;
|
| + else
|
| + return iUShort;
|
| + }
|
| + this.getLongAt = function(iOffset, bBigEndian) {
|
| + var iByte1 = this.getByteAt(iOffset),
|
| + iByte2 = this.getByteAt(iOffset + 1),
|
| + iByte3 = this.getByteAt(iOffset + 2),
|
| + iByte4 = this.getByteAt(iOffset + 3);
|
| +
|
| + var iLong = bBigEndian ?
|
| + (((((iByte1 << 8) + iByte2) << 8) + iByte3) << 8) + iByte4
|
| + : (((((iByte4 << 8) + iByte3) << 8) + iByte2) << 8) + iByte1;
|
| + if (iLong < 0) iLong += 4294967296;
|
| + return iLong;
|
| + }
|
| + this.getSLongAt = function(iOffset, bBigEndian) {
|
| + var iULong = this.getLongAt(iOffset, bBigEndian);
|
| + if (iULong > 2147483647)
|
| + return iULong - 4294967296;
|
| + else
|
| + return iULong;
|
| + }
|
| + this.getStringAt = function(iOffset, iLength) {
|
| + var aStr = [];
|
| + for (var i=iOffset,j=0;i<iOffset+iLength;i++,j++) {
|
| + aStr[j] = String.fromCharCode(this.getByteAt(i));
|
| + }
|
| + return aStr.join("");
|
| + }
|
| +
|
| + this.getCharAt = function(iOffset) {
|
| + return String.fromCharCode(this.getByteAt(iOffset));
|
| + }
|
| + this.toBase64 = function() {
|
| + return window.btoa(data);
|
| + }
|
| + this.fromBase64 = function(strBase64) {
|
| + data = window.atob(strBase64);
|
| + }
|
| +}
|
| +
|
| +
|
| +var BinaryAjax = (function() {
|
| +
|
| + function createRequest() {
|
| + var oHTTP = null;
|
| + if (window.XMLHttpRequest) {
|
| + oHTTP = new XMLHttpRequest();
|
| + } else if (window.ActiveXObject) {
|
| + oHTTP = new ActiveXObject("Microsoft.XMLHTTP");
|
| + }
|
| + return oHTTP;
|
| + }
|
| +
|
| + function getHead(strURL, fncCallback, fncError) {
|
| + var oHTTP = createRequest();
|
| + if (oHTTP) {
|
| + if (fncCallback) {
|
| + if (typeof(oHTTP.onload) != "undefined") {
|
| + oHTTP.onload = function() {
|
| + if (oHTTP.status == "200") {
|
| + fncCallback(this);
|
| + } else {
|
| + if (fncError) fncError();
|
| + }
|
| + oHTTP = null;
|
| + };
|
| + } else {
|
| + oHTTP.onreadystatechange = function() {
|
| + if (oHTTP.readyState == 4) {
|
| + if (oHTTP.status == "200") {
|
| + fncCallback(this);
|
| + } else {
|
| + if (fncError) fncError();
|
| + }
|
| + oHTTP = null;
|
| + }
|
| + };
|
| + }
|
| + }
|
| + oHTTP.open("HEAD", strURL, true);
|
| + oHTTP.send(null);
|
| + } else {
|
| + if (fncError) fncError();
|
| + }
|
| + }
|
| +
|
| + function sendRequest(strURL, fncCallback, fncError, aRange, bAcceptRanges, iFileSize) {
|
| + var oHTTP = createRequest();
|
| + if (oHTTP) {
|
| +
|
| + var iDataOffset = 0;
|
| + if (aRange && !bAcceptRanges) {
|
| + iDataOffset = aRange[0];
|
| + }
|
| + var iDataLen = 0;
|
| + if (aRange) {
|
| + iDataLen = aRange[1]-aRange[0]+1;
|
| + }
|
| +
|
| + if (fncCallback) {
|
| + if (typeof(oHTTP.onload) != "undefined") {
|
| + oHTTP.onload = function() {
|
| +
|
| + if (oHTTP.status == "200" || oHTTP.status == "206") {
|
| + this.binaryResponse = new BinaryFile(this.responseText, iDataOffset, iDataLen);
|
| + this.fileSize = iFileSize || this.getResponseHeader("Content-Length");
|
| + fncCallback(this);
|
| + } else {
|
| + if (fncError) fncError();
|
| + }
|
| + oHTTP = null;
|
| + };
|
| + } else {
|
| + oHTTP.onreadystatechange = function() {
|
| + if (oHTTP.readyState == 4) {
|
| + if (oHTTP.status == "200" || oHTTP.status == "206") {
|
| + this.binaryResponse = new BinaryFile(oHTTP.responseBody, iDataOffset, iDataLen);
|
| + this.fileSize = iFileSize || this.getResponseHeader("Content-Length");
|
| + fncCallback(this);
|
| + } else {
|
| + if (fncError) fncError();
|
| + }
|
| + oHTTP = null;
|
| + }
|
| + };
|
| + }
|
| + }
|
| + oHTTP.open("GET", strURL, true);
|
| +
|
| + if (oHTTP.overrideMimeType) oHTTP.overrideMimeType('text/plain; charset=x-user-defined');
|
| +
|
| + if (aRange && bAcceptRanges) {
|
| + oHTTP.setRequestHeader("Range", "bytes=" + aRange[0] + "-" + aRange[1]);
|
| + }
|
| +
|
| + oHTTP.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 1970 00:00:00 GMT");
|
| +
|
| + oHTTP.send(null);
|
| + } else {
|
| + if (fncError) fncError();
|
| + }
|
| + }
|
| +
|
| + return function(strURL, fncCallback, fncError, aRange) {
|
| +
|
| + if (aRange) {
|
| + getHead(
|
| + strURL,
|
| + function(oHTTP) {
|
| + var iLength = parseInt(oHTTP.getResponseHeader("Content-Length"),10);
|
| + var strAcceptRanges = oHTTP.getResponseHeader("Accept-Ranges");
|
| +
|
| + var iStart, iEnd;
|
| + iStart = aRange[0];
|
| + if (aRange[0] < 0)
|
| + iStart += iLength;
|
| + iEnd = iStart + aRange[1] - 1;
|
| +
|
| + sendRequest(strURL, fncCallback, fncError, [iStart, iEnd], (strAcceptRanges == "bytes"), iLength);
|
| + }
|
| + );
|
| +
|
| + } else {
|
| + sendRequest(strURL, fncCallback, fncError);
|
| + }
|
| + }
|
| +
|
| +}());
|
| +
|
| +
|
| +document.write(
|
| + "<script type='text/vbscript'>\r\n"
|
| + + "Function IEBinary_getByteAt(strBinary, iOffset)\r\n"
|
| + + " IEBinary_getByteAt = AscB(MidB(strBinary,iOffset+1,1))\r\n"
|
| + + "End Function\r\n"
|
| + + "Function IEBinary_getLength(strBinary)\r\n"
|
| + + " IEBinary_getLength = LenB(strBinary)\r\n"
|
| + + "End Function\r\n"
|
| + + "</script>\r\n"
|
| +);
|
| +PK Ô1=#XcÎI I imageinfo/imageinfo/exif.js/*
|
| + * Javascript EXIF Reader 0.1.2
|
| + * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/
|
| + * MIT License [http://www.opensource.org/licenses/mit-license.php]
|
| + */
|
| +
|
| +
|
| +var EXIF = {};
|
| +
|
| +(function() {
|
| +
|
| +var bDebug = false;
|
| +
|
| +EXIF.Tags = {
|
| +
|
| + // version tags
|
| + 0x9000 : "ExifVersion", // EXIF version
|
| + 0xA000 : "FlashpixVersion", // Flashpix format version
|
| +
|
| + // colorspace tags
|
| + 0xA001 : "ColorSpace", // Color space information tag
|
| +
|
| + // image configuration
|
| + 0xA002 : "PixelXDimension", // Valid width of meaningful image
|
| + 0xA003 : "PixelYDimension", // Valid height of meaningful image
|
| + 0x9101 : "ComponentsConfiguration", // Information about channels
|
| + 0x9102 : "CompressedBitsPerPixel", // Compressed bits per pixel
|
| +
|
| + // user information
|
| + 0x927C : "MakerNote", // Any desired information written by the manufacturer
|
| + 0x9286 : "UserComment", // Comments by user
|
| +
|
| + // related file
|
| + 0xA004 : "RelatedSoundFile", // Name of related sound file
|
| +
|
| + // date and time
|
| + 0x9003 : "DateTimeOriginal", // Date and time when the original image was generated
|
| + 0x9004 : "DateTimeDigitized", // Date and time when the image was stored digitally
|
| + 0x9290 : "SubsecTime", // Fractions of seconds for DateTime
|
| + 0x9291 : "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal
|
| + 0x9292 : "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized
|
| +
|
| + // picture-taking conditions
|
| + 0x829A : "ExposureTime", // Exposure time (in seconds)
|
| + 0x829D : "FNumber", // F number
|
| + 0x8822 : "ExposureProgram", // Exposure program
|
| + 0x8824 : "SpectralSensitivity", // Spectral sensitivity
|
| + 0x8827 : "ISOSpeedRatings", // ISO speed rating
|
| + 0x8828 : "OECF", // Optoelectric conversion factor
|
| + 0x9201 : "ShutterSpeedValue", // Shutter speed
|
| + 0x9202 : "ApertureValue", // Lens aperture
|
| + 0x9203 : "BrightnessValue", // Value of brightness
|
| + 0x9204 : "ExposureBias", // Exposure bias
|
| + 0x9205 : "MaxApertureValue", // Smallest F number of lens
|
| + 0x9206 : "SubjectDistance", // Distance to subject in meters
|
| + 0x9207 : "MeteringMode", // Metering mode
|
| + 0x9208 : "LightSource", // Kind of light source
|
| + 0x9209 : "Flash", // Flash status
|
| + 0x9214 : "SubjectArea", // Location and area of main subject
|
| + 0x920A : "FocalLength", // Focal length of the lens in mm
|
| + 0xA20B : "FlashEnergy", // Strobe energy in BCPS
|
| + 0xA20C : "SpatialFrequencyResponse", //
|
| + 0xA20E : "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit
|
| + 0xA20F : "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit
|
| + 0xA210 : "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
|
| + 0xA214 : "SubjectLocation", // Location of subject in image
|
| + 0xA215 : "ExposureIndex", // Exposure index selected on camera
|
| + 0xA217 : "SensingMethod", // Image sensor type
|
| + 0xA300 : "FileSource", // Image source (3 == DSC)
|
| + 0xA301 : "SceneType", // Scene type (1 == directly photographed)
|
| + 0xA302 : "CFAPattern", // Color filter array geometric pattern
|
| + 0xA401 : "CustomRendered", // Special processing
|
| + 0xA402 : "ExposureMode", // Exposure mode
|
| + 0xA403 : "WhiteBalance", // 1 = auto white balance, 2 = manual
|
| + 0xA404 : "DigitalZoomRation", // Digital zoom ratio
|
| + 0xA405 : "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm)
|
| + 0xA406 : "SceneCaptureType", // Type of scene
|
| + 0xA407 : "GainControl", // Degree of overall image gain adjustment
|
| + 0xA408 : "Contrast", // Direction of contrast processing applied by camera
|
| + 0xA409 : "Saturation", // Direction of saturation processing applied by camera
|
| + 0xA40A : "Sharpness", // Direction of sharpness processing applied by camera
|
| + 0xA40B : "DeviceSettingDescription", //
|
| + 0xA40C : "SubjectDistanceRange", // Distance to subject
|
| +
|
| + // other tags
|
| + 0xA005 : "InteroperabilityIFDPointer",
|
| + 0xA420 : "ImageUniqueID" // Identifier assigned uniquely to each image
|
| +};
|
| +
|
| +EXIF.TiffTags = {
|
| + 0x0100 : "ImageWidth",
|
| + 0x0101 : "ImageHeight",
|
| + 0x8769 : "ExifIFDPointer",
|
| + 0x8825 : "GPSInfoIFDPointer",
|
| + 0xA005 : "InteroperabilityIFDPointer",
|
| + 0x0102 : "BitsPerSample",
|
| + 0x0103 : "Compression",
|
| + 0x0106 : "PhotometricInterpretation",
|
| + 0x0112 : "Orientation",
|
| + 0x0115 : "SamplesPerPixel",
|
| + 0x011C : "PlanarConfiguration",
|
| + 0x0212 : "YCbCrSubSampling",
|
| + 0x0213 : "YCbCrPositioning",
|
| + 0x011A : "XResolution",
|
| + 0x011B : "YResolution",
|
| + 0x0128 : "ResolutionUnit",
|
| + 0x0111 : "StripOffsets",
|
| + 0x0116 : "RowsPerStrip",
|
| + 0x0117 : "StripByteCounts",
|
| + 0x0201 : "JPEGInterchangeFormat",
|
| + 0x0202 : "JPEGInterchangeFormatLength",
|
| + 0x012D : "TransferFunction",
|
| + 0x013E : "WhitePoint",
|
| + 0x013F : "PrimaryChromaticities",
|
| + 0x0211 : "YCbCrCoefficients",
|
| + 0x0214 : "ReferenceBlackWhite",
|
| + 0x0132 : "DateTime",
|
| + 0x010E : "ImageDescription",
|
| + 0x010F : "Make",
|
| + 0x0110 : "Model",
|
| + 0x0131 : "Software",
|
| + 0x013B : "Artist",
|
| + 0x8298 : "Copyright"
|
| +}
|
| +
|
| +EXIF.GPSTags = {
|
| + 0x0000 : "GPSVersionID",
|
| + 0x0001 : "GPSLatitudeRef",
|
| + 0x0002 : "GPSLatitude",
|
| + 0x0003 : "GPSLongitudeRef",
|
| + 0x0004 : "GPSLongitude",
|
| + 0x0005 : "GPSAltitudeRef",
|
| + 0x0006 : "GPSAltitude",
|
| + 0x0007 : "GPSTimeStamp",
|
| + 0x0008 : "GPSSatellites",
|
| + 0x0009 : "GPSStatus",
|
| + 0x000A : "GPSMeasureMode",
|
| + 0x000B : "GPSDOP",
|
| + 0x000C : "GPSSpeedRef",
|
| + 0x000D : "GPSSpeed",
|
| + 0x000E : "GPSTrackRef",
|
| + 0x000F : "GPSTrack",
|
| + 0x0010 : "GPSImgDirectionRef",
|
| + 0x0011 : "GPSImgDirection",
|
| + 0x0012 : "GPSMapDatum",
|
| + 0x0013 : "GPSDestLatitudeRef",
|
| + 0x0014 : "GPSDestLatitude",
|
| + 0x0015 : "GPSDestLongitudeRef",
|
| + 0x0016 : "GPSDestLongitude",
|
| + 0x0017 : "GPSDestBearingRef",
|
| + 0x0018 : "GPSDestBearing",
|
| + 0x0019 : "GPSDestDistanceRef",
|
| + 0x001A : "GPSDestDistance",
|
| + 0x001B : "GPSProcessingMethod",
|
| + 0x001C : "GPSAreaInformation",
|
| + 0x001D : "GPSDateStamp",
|
| + 0x001E : "GPSDifferential"
|
| +}
|
| +
|
| +EXIF.StringValues = {
|
| + ExposureProgram : {
|
| + 0 : "Not defined",
|
| + 1 : "Manual",
|
| + 2 : "Normal program",
|
| + 3 : "Aperture priority",
|
| + 4 : "Shutter priority",
|
| + 5 : "Creative program",
|
| + 6 : "Action program",
|
| + 7 : "Portrait mode",
|
| + 8 : "Landscape mode"
|
| + },
|
| + MeteringMode : {
|
| + 0 : "Unknown",
|
| + 1 : "Average",
|
| + 2 : "CenterWeightedAverage",
|
| + 3 : "Spot",
|
| + 4 : "MultiSpot",
|
| + 5 : "Pattern",
|
| + 6 : "Partial",
|
| + 255 : "Other"
|
| + },
|
| + LightSource : {
|
| + 0 : "Unknown",
|
| + 1 : "Daylight",
|
| + 2 : "Fluorescent",
|
| + 3 : "Tungsten (incandescent light)",
|
| + 4 : "Flash",
|
| + 9 : "Fine weather",
|
| + 10 : "Cloudy weather",
|
| + 11 : "Shade",
|
| + 12 : "Daylight fluorescent (D 5700 - 7100K)",
|
| + 13 : "Day white fluorescent (N 4600 - 5400K)",
|
| + 14 : "Cool white fluorescent (W 3900 - 4500K)",
|
| + 15 : "White fluorescent (WW 3200 - 3700K)",
|
| + 17 : "Standard light A",
|
| + 18 : "Standard light B",
|
| + 19 : "Standard light C",
|
| + 20 : "D55",
|
| + 21 : "D65",
|
| + 22 : "D75",
|
| + 23 : "D50",
|
| + 24 : "ISO studio tungsten",
|
| + 255 : "Other"
|
| + },
|
| + Flash : {
|
| + 0x0000 : "Flash did not fire",
|
| + 0x0001 : "Flash fired",
|
| + 0x0005 : "Strobe return light not detected",
|
| + 0x0007 : "Strobe return light detected",
|
| + 0x0009 : "Flash fired, compulsory flash mode",
|
| + 0x000D : "Flash fired, compulsory flash mode, return light not detected",
|
| + 0x000F : "Flash fired, compulsory flash mode, return light detected",
|
| + 0x0010 : "Flash did not fire, compulsory flash mode",
|
| + 0x0018 : "Flash did not fire, auto mode",
|
| + 0x0019 : "Flash fired, auto mode",
|
| + 0x001D : "Flash fired, auto mode, return light not detected",
|
| + 0x001F : "Flash fired, auto mode, return light detected",
|
| + 0x0020 : "No flash function",
|
| + 0x0041 : "Flash fired, red-eye reduction mode",
|
| + 0x0045 : "Flash fired, red-eye reduction mode, return light not detected",
|
| + 0x0047 : "Flash fired, red-eye reduction mode, return light detected",
|
| + 0x0049 : "Flash fired, compulsory flash mode, red-eye reduction mode",
|
| + 0x004D : "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",
|
| + 0x004F : "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",
|
| + 0x0059 : "Flash fired, auto mode, red-eye reduction mode",
|
| + 0x005D : "Flash fired, auto mode, return light not detected, red-eye reduction mode",
|
| + 0x005F : "Flash fired, auto mode, return light detected, red-eye reduction mode"
|
| + },
|
| + SensingMethod : {
|
| + 1 : "Not defined",
|
| + 2 : "One-chip color area sensor",
|
| + 3 : "Two-chip color area sensor",
|
| + 4 : "Three-chip color area sensor",
|
| + 5 : "Color sequential area sensor",
|
| + 7 : "Trilinear sensor",
|
| + 8 : "Color sequential linear sensor"
|
| + },
|
| + SceneCaptureType : {
|
| + 0 : "Standard",
|
| + 1 : "Landscape",
|
| + 2 : "Portrait",
|
| + 3 : "Night scene"
|
| + },
|
| + SceneType : {
|
| + 1 : "Directly photographed"
|
| + },
|
| + CustomRendered : {
|
| + 0 : "Normal process",
|
| + 1 : "Custom process"
|
| + },
|
| + WhiteBalance : {
|
| + 0 : "Auto white balance",
|
| + 1 : "Manual white balance"
|
| + },
|
| + GainControl : {
|
| + 0 : "None",
|
| + 1 : "Low gain up",
|
| + 2 : "High gain up",
|
| + 3 : "Low gain down",
|
| + 4 : "High gain down"
|
| + },
|
| + Contrast : {
|
| + 0 : "Normal",
|
| + 1 : "Soft",
|
| + 2 : "Hard"
|
| + },
|
| + Saturation : {
|
| + 0 : "Normal",
|
| + 1 : "Low saturation",
|
| + 2 : "High saturation"
|
| + },
|
| + Sharpness : {
|
| + 0 : "Normal",
|
| + 1 : "Soft",
|
| + 2 : "Hard"
|
| + },
|
| + SubjectDistanceRange : {
|
| + 0 : "Unknown",
|
| + 1 : "Macro",
|
| + 2 : "Close view",
|
| + 3 : "Distant view"
|
| + },
|
| + FileSource : {
|
| + 3 : "DSC"
|
| + },
|
| +
|
| + Components : {
|
| + 0 : "",
|
| + 1 : "Y",
|
| + 2 : "Cb",
|
| + 3 : "Cr",
|
| + 4 : "R",
|
| + 5 : "G",
|
| + 6 : "B"
|
| + }
|
| +}
|
| +
|
| +function addEvent(oElement, strEvent, fncHandler)
|
| +{
|
| + if (oElement.addEventListener) {
|
| + oElement.addEventListener(strEvent, fncHandler, false);
|
| + } else if (oElement.attachEvent) {
|
| + oElement.attachEvent("on" + strEvent, fncHandler);
|
| + }
|
| +}
|
| +
|
| +
|
| +function imageHasData(oImg)
|
| +{
|
| + return !!(oImg.exifdata);
|
| +}
|
| +
|
| +function getImageData(oImg, fncCallback)
|
| +{
|
| + BinaryAjax(
|
| + oImg.src,
|
| + function(oHTTP) {
|
| + var oEXIF = findEXIFinJPEG(oHTTP.binaryResponse);
|
| + oImg.exifdata = oEXIF || {};
|
| + if (fncCallback) fncCallback();
|
| + }
|
| + )
|
| +}
|
| +
|
| +function findEXIFinJPEG(oFile) {
|
| + var aMarkers = [];
|
| +
|
| + if (oFile.getByteAt(0) != 0xFF || oFile.getByteAt(1) != 0xD8) {
|
| + return false; // not a valid jpeg
|
| + }
|
| +
|
| + var iOffset = 2;
|
| + var iLength = oFile.getLength();
|
| + while (iOffset < iLength) {
|
| + if (oFile.getByteAt(iOffset) != 0xFF) {
|
| + if (bDebug) console.log("Not a valid marker at offset " + iOffset + ", found: " + oFile.getByteAt(iOffset));
|
| + return false; // not a valid marker, something is wrong
|
| + }
|
| +
|
| + var iMarker = oFile.getByteAt(iOffset+1);
|
| +
|
| + // we could implement handling for other markers here,
|
| + // but we're only looking for 0xFFE1 for EXIF data
|
| +
|
| + if (iMarker == 22400) {
|
| + if (bDebug) console.log("Found 0xFFE1 marker");
|
| + return readEXIFData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);
|
| + iOffset += 2 + oFile.getShortAt(iOffset+2, true);
|
| +
|
| + } else if (iMarker == 225) {
|
| + // 0xE1 = Application-specific 1 (for EXIF)
|
| + if (bDebug) console.log("Found 0xFFE1 marker");
|
| + return readEXIFData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);
|
| +
|
| + } else {
|
| + iOffset += 2 + oFile.getShortAt(iOffset+2, true);
|
| + }
|
| +
|
| + }
|
| +
|
| +}
|
| +
|
| +
|
| +function readTags(oFile, iTIFFStart, iDirStart, oStrings, bBigEnd)
|
| +{
|
| + var iEntries = oFile.getShortAt(iDirStart, bBigEnd);
|
| + var oTags = {};
|
| + for (var i=0;i<iEntries;i++) {
|
| + var iEntryOffset = iDirStart + i*12 + 2;
|
| + var strTag = oStrings[oFile.getShortAt(iEntryOffset, bBigEnd)];
|
| + if (!strTag && bDebug) console.log("Unknown tag: " + oFile.getShortAt(iEntryOffset, bBigEnd));
|
| + oTags[strTag] = readTagValue(oFile, iEntryOffset, iTIFFStart, iDirStart, bBigEnd);
|
| + }
|
| + return oTags;
|
| +}
|
| +
|
| +
|
| +function readTagValue(oFile, iEntryOffset, iTIFFStart, iDirStart, bBigEnd)
|
| +{
|
| + var iType = oFile.getShortAt(iEntryOffset+2, bBigEnd);
|
| + var iNumValues = oFile.getLongAt(iEntryOffset+4, bBigEnd);
|
| + var iValueOffset = oFile.getLongAt(iEntryOffset+8, bBigEnd) + iTIFFStart;
|
| +
|
| + switch (iType) {
|
| + case 1: // byte, 8-bit unsigned int
|
| + case 7: // undefined, 8-bit byte, value depending on field
|
| + if (iNumValues == 1) {
|
| + return oFile.getByteAt(iEntryOffset + 8, bBigEnd);
|
| + } else {
|
| + var iValOffset = iNumValues > 4 ? iValueOffset : (iEntryOffset + 8);
|
| + var aVals = [];
|
| + for (var n=0;n<iNumValues;n++) {
|
| + aVals[n] = oFile.getByteAt(iValOffset + n);
|
| + }
|
| + return aVals;
|
| + }
|
| + break;
|
| +
|
| + case 2: // ascii, 8-bit byte
|
| + var iStringOffset = iNumValues > 4 ? iValueOffset : (iEntryOffset + 8);
|
| + return oFile.getStringAt(iStringOffset, iNumValues-1);
|
| + break;
|
| +
|
| + case 3: // short, 16 bit int
|
| + if (iNumValues == 1) {
|
| + return oFile.getShortAt(iEntryOffset + 8, bBigEnd);
|
| + } else {
|
| + var iValOffset = iNumValues > 2 ? iValueOffset : (iEntryOffset + 8);
|
| + var aVals = [];
|
| + for (var n=0;n<iNumValues;n++) {
|
| + aVals[n] = oFile.getShortAt(iValOffset + 2*n, bBigEnd);
|
| + }
|
| + return aVals;
|
| + }
|
| + break;
|
| +
|
| + case 4: // long, 32 bit int
|
| + if (iNumValues == 1) {
|
| + return oFile.getLongAt(iEntryOffset + 8, bBigEnd);
|
| + } else {
|
| + var aVals = [];
|
| + for (var n=0;n<iNumValues;n++) {
|
| + aVals[n] = oFile.getLongAt(iValueOffset + 4*n, bBigEnd);
|
| + }
|
| + return aVals;
|
| + }
|
| + break;
|
| + case 5: // rational = two long values, first is numerator, second is denominator
|
| + if (iNumValues == 1) {
|
| + return oFile.getLongAt(iValueOffset, bBigEnd) / oFile.getLongAt(iValueOffset+4, bBigEnd);
|
| + } else {
|
| + var aVals = [];
|
| + for (var n=0;n<iNumValues;n++) {
|
| + aVals[n] = oFile.getLongAt(iValueOffset + 8*n, bBigEnd) / oFile.getLongAt(iValueOffset+4 + 8*n, bBigEnd);
|
| + }
|
| + return aVals;
|
| + }
|
| + break;
|
| + case 9: // slong, 32 bit signed int
|
| + if (iNumValues == 1) {
|
| + return oFile.getSLongAt(iEntryOffset + 8, bBigEnd);
|
| + } else {
|
| + var aVals = [];
|
| + for (var n=0;n<iNumValues;n++) {
|
| + aVals[n] = oFile.getSLongAt(iValueOffset + 4*n, bBigEnd);
|
| + }
|
| + return aVals;
|
| + }
|
| + break;
|
| + case 10: // signed rational, two slongs, first is numerator, second is denominator
|
| + if (iNumValues == 1) {
|
| + return oFile.getSLongAt(iValueOffset, bBigEnd) / oFile.getSLongAt(iValueOffset+4, bBigEnd);
|
| + } else {
|
| + var aVals = [];
|
| + for (var n=0;n<iNumValues;n++) {
|
| + aVals[n] = oFile.getSLongAt(iValueOffset + 8*n, bBigEnd) / oFile.getSLongAt(iValueOffset+4 + 8*n, bBigEnd);
|
| + }
|
| + return aVals;
|
| + }
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| +function readEXIFData(oFile, iStart, iLength)
|
| +{
|
| + if (oFile.getStringAt(iStart, 4) != "Exif") {
|
| + if (bDebug) console.log("Not valid EXIF data! " + oFile.getStringAt(iStart, 4));
|
| + return false;
|
| + }
|
| +
|
| + var bBigEnd;
|
| +
|
| + var iTIFFOffset = iStart + 6;
|
| +
|
| + // test for TIFF validity and endianness
|
| + if (oFile.getShortAt(iTIFFOffset) == 0x4949) {
|
| + bBigEnd = false;
|
| + } else if (oFile.getShortAt(iTIFFOffset) == 0x4D4D) {
|
| + bBigEnd = true;
|
| + } else {
|
| + if (bDebug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
|
| + return false;
|
| + }
|
| +
|
| + if (oFile.getShortAt(iTIFFOffset+2, bBigEnd) != 0x002A) {
|
| + if (bDebug) console.log("Not valid TIFF data! (no 0x002A)");
|
| + return false;
|
| + }
|
| +
|
| + if (oFile.getLongAt(iTIFFOffset+4, bBigEnd) != 0x00000008) {
|
| + if (bDebug) console.log("Not valid TIFF data! (First offset not 8)", oFile.getShortAt(iTIFFOffset+4, bBigEnd));
|
| + return false;
|
| + }
|
| +
|
| + var oTags = readTags(oFile, iTIFFOffset, iTIFFOffset+8, EXIF.TiffTags, bBigEnd);
|
| +
|
| + if (oTags.ExifIFDPointer) {
|
| + var oEXIFTags = readTags(oFile, iTIFFOffset, iTIFFOffset + oTags.ExifIFDPointer, EXIF.Tags, bBigEnd);
|
| + for (var strTag in oEXIFTags) {
|
| + switch (strTag) {
|
| + case "LightSource" :
|
| + case "Flash" :
|
| + case "MeteringMode" :
|
| + case "ExposureProgram" :
|
| + case "SensingMethod" :
|
| + case "SceneCaptureType" :
|
| + case "SceneType" :
|
| + case "CustomRendered" :
|
| + case "WhiteBalance" :
|
| + case "GainControl" :
|
| + case "Contrast" :
|
| + case "Saturation" :
|
| + case "Sharpness" :
|
| + case "SubjectDistanceRange" :
|
| + case "FileSource" :
|
| + oEXIFTags[strTag] = EXIF.StringValues[strTag][oEXIFTags[strTag]];
|
| + break;
|
| +
|
| + case "ExifVersion" :
|
| + case "FlashpixVersion" :
|
| + oEXIFTags[strTag] = String.fromCharCode(oEXIFTags[strTag][0], oEXIFTags[strTag][1], oEXIFTags[strTag][2], oEXIFTags[strTag][3]);
|
| + break;
|
| +
|
| + case "ComponentsConfiguration" :
|
| + oEXIFTags[strTag] =
|
| + EXIF.StringValues.Components[oEXIFTags[strTag][0]]
|
| + + EXIF.StringValues.Components[oEXIFTags[strTag][1]]
|
| + + EXIF.StringValues.Components[oEXIFTags[strTag][2]]
|
| + + EXIF.StringValues.Components[oEXIFTags[strTag][3]];
|
| + break;
|
| + }
|
| + oTags[strTag] = oEXIFTags[strTag];
|
| + }
|
| + }
|
| +
|
| + if (oTags.GPSInfoIFDPointer) {
|
| + var oGPSTags = readTags(oFile, iTIFFOffset, iTIFFOffset + oTags.GPSInfoIFDPointer, EXIF.GPSTags, bBigEnd);
|
| + for (var strTag in oGPSTags) {
|
| + switch (strTag) {
|
| + case "GPSVersionID" :
|
| + oGPSTags[strTag] = oGPSTags[strTag][0]
|
| + + "." + oGPSTags[strTag][1]
|
| + + "." + oGPSTags[strTag][2]
|
| + + "." + oGPSTags[strTag][3];
|
| + break;
|
| + }
|
| + oTags[strTag] = oGPSTags[strTag];
|
| + }
|
| + }
|
| +
|
| + return oTags;
|
| +}
|
| +
|
| +
|
| +EXIF.getData = function(oImg, fncCallback)
|
| +{
|
| + if (!oImg.complete) return false;
|
| + if (!imageHasData(oImg)) {
|
| + getImageData(oImg, fncCallback);
|
| + } else {
|
| + if (fncCallback) fncCallback();
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +EXIF.getTag = function(oImg, strTag)
|
| +{
|
| + if (!imageHasData(oImg)) return;
|
| + return oImg.exifdata[strTag];
|
| +}
|
| +
|
| +EXIF.pretty = function(oImg)
|
| +{
|
| + if (!imageHasData(oImg)) return "";
|
| + var oData = oImg.exifdata;
|
| + var strPretty = "";
|
| + for (var a in oData) {
|
| + if (oData.hasOwnProperty(a)) {
|
| + if (typeof oData[a] == "object") {
|
| + strPretty += a + " : [" + oData[a].length + " values]\r\n";
|
| + } else {
|
| + strPretty += a + " : " + oData[a] + "\r\n";
|
| + }
|
| + }
|
| + }
|
| + return strPretty;
|
| +}
|
| +
|
| +EXIF.readFromBinaryFile = function(oFile) {
|
| + return findEXIFinJPEG(oFile);
|
| +}
|
| +
|
| +function loadAllImages()
|
| +{
|
| + var aImages = document.getElementsByTagName("img");
|
| + for (var i=0;i<aImages.length;i++) {
|
| + if (aImages[i].getAttribute("exif") == "true") {
|
| + if (!aImages[i].complete) {
|
| + addEvent(aImages[i], "load",
|
| + function() {
|
| + EXIF.getData(this);
|
| + }
|
| + );
|
| + } else {
|
| + EXIF.getData(aImages[i]);
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +addEvent(window, "load", loadAllImages);
|
| +
|
| +})();
|
| +
|
| +PK Ô1=Øì§ÒÆ Æ imageinfo/imageinfo/imageinfo.js/*
|
| + * ImageInfo 0.1.2 - A JavaScript library for reading image metadata.
|
| + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
| + * MIT License [http://www.nihilogic.dk/licenses/mit-license.txt]
|
| + */
|
| +
|
| +
|
| +var ImageInfo = {};
|
| +
|
| +ImageInfo.useRange = false;
|
| +ImageInfo.range = 10240;
|
| +
|
| +(function() {
|
| +
|
| + var files = [];
|
| +
|
| + function readFileData(url, callback) {
|
| + BinaryAjax(
|
| + url,
|
| + function(http) {
|
| + var tags = readInfoFromData(http.binaryResponse);
|
| + var mime = http.getResponseHeader("Content-Type");
|
| +
|
| + tags["mimeType"] = mime;
|
| + tags["byteSize"] = http.fileSize;
|
| +
|
| + files[url] = tags;
|
| + if (callback) callback();
|
| + },
|
| + null,
|
| + ImageInfo.useRange ? [0, ImageInfo.range] : null
|
| + )
|
| + }
|
| +
|
| + function readInfoFromData(data) {
|
| +
|
| + var offset = 0;
|
| +
|
| + if (data.getByteAt(0) == 0xFF && data.getByteAt(1) == 0xD8) {
|
| + return readJPEGInfo(data);
|
| + }
|
| + if (data.getByteAt(0) == 0x89 && data.getStringAt(1, 3) == "PNG") {
|
| + return readPNGInfo(data);
|
| + }
|
| + if (data.getStringAt(0,3) == "GIF") {
|
| + return readGIFInfo(data);
|
| + }
|
| + if (data.getByteAt(0) == 0x42 && data.getByteAt(1) == 0x4D) {
|
| + return readBMPInfo(data);
|
| + }
|
| + if (data.getByteAt(0) == 0x00 && data.getByteAt(1) == 0x00) {
|
| + return readICOInfo(data);
|
| + }
|
| +
|
| + return {
|
| + format : "UNKNOWN"
|
| + };
|
| + }
|
| +
|
| +
|
| + function readPNGInfo(data) {
|
| + var w = data.getLongAt(16,true);
|
| + var h = data.getLongAt(20,true);
|
| +
|
| + var bpc = data.getByteAt(24);
|
| + var ct = data.getByteAt(25);
|
| +
|
| + var bpp = bpc;
|
| + if (ct == 4) bpp *= 2;
|
| + if (ct == 2) bpp *= 3;
|
| + if (ct == 6) bpp *= 4;
|
| +
|
| + var alpha = data.getByteAt(25) >= 4;
|
| +
|
| + return {
|
| + format : "PNG",
|
| + version : "",
|
| + width : w,
|
| + height : h,
|
| + bpp : bpp,
|
| + alpha : alpha,
|
| + exif : {}
|
| + }
|
| + }
|
| +
|
| + function readGIFInfo(data) {
|
| + var version = data.getStringAt(3,3);
|
| + var w = data.getShortAt(6);
|
| + var h = data.getShortAt(8);
|
| +
|
| + var bpp = ((data.getByteAt(10) >> 4) & 7) + 1;
|
| +
|
| + return {
|
| + format : "GIF",
|
| + version : version,
|
| + width : w,
|
| + height : h,
|
| + bpp : bpp,
|
| + alpha : false,
|
| + exif : {}
|
| + }
|
| + }
|
| +
|
| + function readJPEGInfo(data) {
|
| +
|
| + var w = 0;
|
| + var h = 0;
|
| + var comps = 0;
|
| + var len = data.getLength();
|
| + var offset = 2;
|
| + while (offset < len) {
|
| + var marker = data.getShortAt(offset, true);
|
| + offset += 2;
|
| + if (marker == 0xFFC0) {
|
| + h = data.getShortAt(offset + 3, true);
|
| + w = data.getShortAt(offset + 5, true);
|
| + comps = data.getByteAt(offset + 7, true)
|
| + break;
|
| + } else {
|
| + offset += data.getShortAt(offset, true)
|
| + }
|
| + }
|
| +
|
| + var exif = {};
|
| +
|
| + if (typeof EXIF != "undefined" && EXIF.readFromBinaryFile) {
|
| + exif = EXIF.readFromBinaryFile(data);
|
| + }
|
| +
|
| + return {
|
| + format : "JPEG",
|
| + version : "",
|
| + width : w,
|
| + height : h,
|
| + bpp : comps * 8,
|
| + alpha : false,
|
| + exif : exif
|
| + }
|
| + }
|
| +
|
| + function readBMPInfo(data) {
|
| + var w = data.getLongAt(18);
|
| + var h = data.getLongAt(22);
|
| + var bpp = data.getShortAt(28);
|
| + return {
|
| + format : "BMP",
|
| + version : "",
|
| + width : w,
|
| + height : h,
|
| + bpp : bpp,
|
| + alpha : false,
|
| + exif : {}
|
| + }
|
| + }
|
| +
|
| + ImageInfo.loadInfo = function(url, cb) {
|
| + if (!files[url]) {
|
| + readFileData(url, cb);
|
| + } else {
|
| + if (cb) cb();
|
| + }
|
| + }
|
| +
|
| + ImageInfo.getAllFields = function(url) {
|
| + if (!files[url]) return null;
|
| +
|
| + var tags = {};
|
| + for (var a in files[url]) {
|
| + if (files[url].hasOwnProperty(a))
|
| + tags[a] = files[url][a];
|
| + }
|
| + return tags;
|
| + }
|
| +
|
| + ImageInfo.getField = function(url, field) {
|
| + if (!files[url]) return null;
|
| + return files[url][field];
|
| + }
|
| +
|
| +
|
| +})();
|
| +
|
| +PK 7
|
| +>øÐ¶r r imageinfo/imageinfo/readme.txt
|
| ImageInfo - A JavaScript library for reading image metadata.
|
| Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
| MIT License [http://www.nihilogic.dk/licenses/mit-license.txt]
|
|
|
| For detailed information and code samples please refer to the blog post at:
|
| http://blog.nihilogic.dk/2008/07/imageinfo-reading-image-info-with-javascript.html
|
| -PK üy>/¥â imageinfo/NOTICEPK MTP?[u¿E E @ imageinfo/background.htmlPK MTP?àZÚè è ¼ imageinfo/background.jsPK üy>PtYÅk k Ù imageinfo/imageinfo-128.pngPK üy>EA· } imageinfo/imageinfo-16.pngPK üy>ñ ÞÀæ æ U
|
| - imageinfo/imageinfo-19.pngPK üy>ª
|
| -T T s imageinfo/imageinfo-48.pngPK MTP?
|
| -dT2 2 ÿ imageinfo/info.cssPK MTP?óé a imageinfo/info.htmlPK MTP?:Í Í # imageinfo/info.jsPK üy>ѺåPÎ Î 0 imageinfo/loader.gifPK MTP?Ùl
|
| -ä ä ( 2 imageinfo/manifest.json3a61d1ad772ef01e0d3cc01a8bedbe7da452dd0bPK üy>Æ
|
| -<» ! 84 imageinfo/imageinfo/binaryajax.jsPK üy>`ÝÿK ÿK O imageinfo/imageinfo/exif.jsPK üy>Îê| | H imageinfo/imageinfo/imageinfo.jsPK Ýò>øÐ¶r r « imageinfo/imageinfo/readme.txtPK °¬
|
| +PK Ô1=/¥â ¤ imageinfo/NOTICEPK ÎQ?[u¿E E ¤@ imageinfo/background.htmlPK ÎQ?àZÚè è ¤¼ imageinfo/background.jsPK |
|
| +T>PtYÅk k ¤Ù imageinfo/imageinfo-128.pngPK |
|
| +T>EA· ¤} imageinfo/imageinfo-16.pngPK |
|
| +T>ñ ÞÀæ æ ¤U
|
| + imageinfo/imageinfo-19.pngPK |
|
| +T>ª
|
| +T T ¤s imageinfo/imageinfo-48.pngPK ÎQ?
|
| +dT2 2 ¤ÿ imageinfo/info.cssPK ÎQ?óé ¤a imageinfo/info.htmlPK ÎQ?:Í Í ¤# imageinfo/info.jsPK Ô1=ѺåPÎ Î ¤0 imageinfo/loader.gifPK ÎQ?Ùl
|
| +ä ä ( ¤2 imageinfo/manifest.json21aedd7d940b7c5c53486cc8e48f2ce708ff9711PK Ô1=\ ® ® ! ¤84 imageinfo/imageinfo/binaryajax.jsPK Ô1=#XcÎI I ¤%N imageinfo/imageinfo/exif.jsPK Ô1=Øì§ÒÆ Æ ¤ö imageinfo/imageinfo/imageinfo.jsPK 7
|
| +>øÐ¶r r ¤ú¦ imageinfo/imageinfo/readme.txtPK ¨¨
|
|
|