| /* |
| * 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); |
| |
| })(); |
| |