asset_host_core 2.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.markdown +138 -0
- data/Rakefile +11 -0
- data/app/assets/images/asset_host_core/alert-overlay.png +0 -0
- data/app/assets/images/asset_host_core/arrow-left.gif +0 -0
- data/app/assets/images/asset_host_core/arrow-right.gif +0 -0
- data/app/assets/images/asset_host_core/fallback-img-rect.png +0 -0
- data/app/assets/images/asset_host_core/videoplayer-play.png +0 -0
- data/app/assets/images/asset_host_core/x.png +0 -0
- data/app/assets/javascripts/asset_host_core/admin/assets.js.coffee +221 -0
- data/app/assets/javascripts/asset_host_core/application.js +20 -0
- data/app/assets/javascripts/asset_host_core/assetadmin.js.coffee +56 -0
- data/app/assets/javascripts/asset_host_core/assethost.js.coffee.erb +17 -0
- data/app/assets/javascripts/asset_host_core/browserui.js.coffee +139 -0
- data/app/assets/javascripts/asset_host_core/chooserui.js.coffee +381 -0
- data/app/assets/javascripts/asset_host_core/client.js.coffee +29 -0
- data/app/assets/javascripts/asset_host_core/clients/BrightcoveVideo.js.coffee +64 -0
- data/app/assets/javascripts/asset_host_core/clients/templates/brightcove_embed.jst.eco +18 -0
- data/app/assets/javascripts/asset_host_core/clients/templates/vimeo_embed.jst.eco +1 -0
- data/app/assets/javascripts/asset_host_core/clients/templates/youtube_embed.jst.eco +1 -0
- data/app/assets/javascripts/asset_host_core/clients/vimeo_video.js.coffee +21 -0
- data/app/assets/javascripts/asset_host_core/clients/youtube_video.js.coffee +21 -0
- data/app/assets/javascripts/asset_host_core/cmsplugin.js.coffee +235 -0
- data/app/assets/javascripts/asset_host_core/models.js.coffee +586 -0
- data/app/assets/javascripts/asset_host_core/railsCMS.js.coffee +141 -0
- data/app/assets/javascripts/asset_host_core/slideshow.js.coffee +428 -0
- data/app/assets/javascripts/asset_host_core/templates/after_upload_button.jst.eco +3 -0
- data/app/assets/javascripts/asset_host_core/templates/asset_drop_asset.jst.eco +4 -0
- data/app/assets/javascripts/asset_host_core/templates/asset_modal.jst.eco +13 -0
- data/app/assets/javascripts/asset_host_core/templates/asset_preview.jst.eco +35 -0
- data/app/assets/javascripts/asset_host_core/templates/asset_search.jst.eco +2 -0
- data/app/assets/javascripts/asset_host_core/templates/browser_asset.jst.eco +1 -0
- data/app/assets/javascripts/asset_host_core/templates/browser_asset_tip.jst.eco +3 -0
- data/app/assets/javascripts/asset_host_core/templates/edit_modal.jst.eco +40 -0
- data/app/assets/javascripts/asset_host_core/templates/import_help.jst.eco +59 -0
- data/app/assets/javascripts/asset_host_core/templates/pagination_link.jst.eco +1 -0
- data/app/assets/javascripts/asset_host_core/templates/pagination_links.jst.eco +13 -0
- data/app/assets/javascripts/asset_host_core/templates/queued_file.jst.eco +11 -0
- data/app/assets/javascripts/asset_host_core/templates/save_and_close_view.jst.eco +4 -0
- data/app/assets/javascripts/asset_host_core/templates/upload_all_button.jst.eco +4 -0
- data/app/assets/javascripts/asset_host_core/templates/url_input.jst.eco +8 -0
- data/app/assets/stylesheets/asset_host_core/application.css.scss +384 -0
- data/app/assets/stylesheets/asset_host_core/jquery-ui.css +105 -0
- data/app/assets/stylesheets/asset_host_core/public.css.scss +204 -0
- data/app/assets/stylesheets/asset_host_core/slidetest.css.scss +93 -0
- data/app/controllers/asset_host_core/admin/api_users_controller.rb +72 -0
- data/app/controllers/asset_host_core/admin/assets_controller.rb +140 -0
- data/app/controllers/asset_host_core/admin/base_controller.rb +36 -0
- data/app/controllers/asset_host_core/admin/home_controller.rb +13 -0
- data/app/controllers/asset_host_core/admin/outputs_controller.rb +55 -0
- data/app/controllers/asset_host_core/api/assets_controller.rb +110 -0
- data/app/controllers/asset_host_core/api/base_controller.rb +43 -0
- data/app/controllers/asset_host_core/api/outputs_controller.rb +33 -0
- data/app/controllers/asset_host_core/application_controller.rb +43 -0
- data/app/controllers/asset_host_core/public_controller.rb +104 -0
- data/app/models/asset_host_core/api_user.rb +44 -0
- data/app/models/asset_host_core/api_user_permission.rb +6 -0
- data/app/models/asset_host_core/asset.rb +265 -0
- data/app/models/asset_host_core/asset_output.rb +69 -0
- data/app/models/asset_host_core/brightcove_video.rb +20 -0
- data/app/models/asset_host_core/output.rb +52 -0
- data/app/models/asset_host_core/permission.rb +19 -0
- data/app/models/asset_host_core/video.rb +8 -0
- data/app/models/asset_host_core/vimeo_video.rb +17 -0
- data/app/models/asset_host_core/youtube_video.rb +17 -0
- data/app/views/asset_host_core/admin/api_users/_form_fields.html.erb +5 -0
- data/app/views/asset_host_core/admin/api_users/edit.html.erb +26 -0
- data/app/views/asset_host_core/admin/api_users/index.html.erb +31 -0
- data/app/views/asset_host_core/admin/api_users/new.html.erb +17 -0
- data/app/views/asset_host_core/admin/api_users/show.html.erb +23 -0
- data/app/views/asset_host_core/admin/assets/index.html.erb +19 -0
- data/app/views/asset_host_core/admin/assets/metadata.html.erb +24 -0
- data/app/views/asset_host_core/admin/assets/show.html.erb +86 -0
- data/app/views/asset_host_core/admin/home/chooser.html.erb +49 -0
- data/app/views/asset_host_core/admin/outputs/_form_fields.html.erb +5 -0
- data/app/views/asset_host_core/admin/outputs/edit.html.erb +26 -0
- data/app/views/asset_host_core/admin/outputs/index.html.erb +27 -0
- data/app/views/asset_host_core/admin/outputs/new.html.erb +13 -0
- data/app/views/asset_host_core/admin/outputs/show.html.erb +17 -0
- data/app/views/asset_host_core/shared/_footerjs.html.erb +3 -0
- data/app/views/asset_host_core/shared/_navbar.html.erb +28 -0
- data/app/views/kaminari/_first_page.html.erb +3 -0
- data/app/views/kaminari/_gap.html.erb +3 -0
- data/app/views/kaminari/_last_page.html.erb +3 -0
- data/app/views/kaminari/_next_page.html.erb +3 -0
- data/app/views/kaminari/_page.html.erb +3 -0
- data/app/views/kaminari/_paginator.html.erb +17 -0
- data/app/views/kaminari/_prev_page.html.erb +3 -0
- data/app/views/layouts/asset_host_core/application.html.erb +54 -0
- data/app/views/layouts/asset_host_core/full_width.html.erb +32 -0
- data/app/views/layouts/asset_host_core/minimal.html.erb +45 -0
- data/config/initializers/simple_form.rb +142 -0
- data/config/initializers/simple_form_bootstrap.rb +45 -0
- data/config/locales/simple_form.en.yml +26 -0
- data/config/routes.rb +49 -0
- data/lib/asset_host_core.rb +38 -0
- data/lib/asset_host_core/config.rb +39 -0
- data/lib/asset_host_core/engine.rb +94 -0
- data/lib/asset_host_core/loaders.rb +34 -0
- data/lib/asset_host_core/loaders/asset_host.rb +30 -0
- data/lib/asset_host_core/loaders/base.rb +22 -0
- data/lib/asset_host_core/loaders/brightcove.rb +67 -0
- data/lib/asset_host_core/loaders/flickr.rb +114 -0
- data/lib/asset_host_core/loaders/url.rb +59 -0
- data/lib/asset_host_core/loaders/vimeo.rb +76 -0
- data/lib/asset_host_core/loaders/youtube.rb +90 -0
- data/lib/asset_host_core/model_methods.rb +61 -0
- data/lib/asset_host_core/paperclip.rb +4 -0
- data/lib/asset_host_core/paperclip/asset_thumbnail.rb +92 -0
- data/lib/asset_host_core/paperclip/attachment.rb +206 -0
- data/lib/asset_host_core/paperclip/trimmer.rb +33 -0
- data/lib/asset_host_core/resque_job.rb +13 -0
- data/lib/asset_host_core/version.rb +3 -0
- data/lib/tasks/asset_host_core_tasks.rake +4 -0
- data/spec/controllers/admin/api_users_controller_spec.rb +21 -0
- data/spec/controllers/admin/assets_controller_spec.rb +59 -0
- data/spec/controllers/admin/home_controller_spec.rb +4 -0
- data/spec/controllers/admin/outputs_controller_spec.rb +4 -0
- data/spec/controllers/api/assets_controller_spec.rb +133 -0
- data/spec/controllers/api/outputs_controller_spec.rb +51 -0
- data/spec/controllers/public_controller_spec.rb +4 -0
- data/spec/factories.rb +39 -0
- data/spec/features/api_users_spec.rb +78 -0
- data/spec/fixtures/api/brightcove/video.json +137 -0
- data/spec/fixtures/api/flickr/photos_getInfo.json +78 -0
- data/spec/fixtures/api/flickr/photos_getSizes.json +82 -0
- data/spec/fixtures/api/flickr/photos_licenses_getInfo.json +52 -0
- data/spec/fixtures/api/vimeo/video.json +28 -0
- data/spec/fixtures/api/youtube/discovery.json +5190 -0
- data/spec/fixtures/api/youtube/video.json +44 -0
- data/spec/fixtures/images/chipmunk.jpg +0 -0
- data/spec/fixtures/images/dude.jpg +0 -0
- data/spec/fixtures/images/ernie.jpg +0 -0
- data/spec/fixtures/images/fry.png +0 -0
- data/spec/fixtures/images/hat.jpg +0 -0
- data/spec/fixtures/images/spongebob.png +0 -0
- data/spec/fixtures/images/stars.jpg +0 -0
- data/spec/internal/app/controllers/application_controller.rb +16 -0
- data/spec/internal/app/controllers/sessions_controller.rb +24 -0
- data/spec/internal/app/models/user.rb +10 -0
- data/spec/internal/app/views/sessions/new.html.erb +14 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/initializers/assethost_config.rb +57 -0
- data/spec/internal/config/routes.rb +7 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +106 -0
- data/spec/internal/log/test.log +14769 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/internal/public/images/1_27f7745237849975ca90591c1fba5934_original. +0 -0
- data/spec/internal/public/images/1_7d33319deca787d5bb3f62ff06563ad2_original. +0 -0
- data/spec/internal/public/images/1_b6d48c8b1286104ce76649731e09645f_original. +0 -0
- data/spec/internal/public/images/1_b6d48c8b1286104ce76649731e09645f_original.jpg +0 -0
- data/spec/internal/public/images/1_b6d48c8b1286104ce76649731e09645f_original.txt +0 -0
- data/spec/internal/public/images/1_e179cbd27e07cb55042d0db36cdac095_original. +0 -0
- data/spec/internal/public/images/1_e669edd3dfd74be66fc38416e82e3a37_original. +0 -0
- data/spec/lib/asset_host_core/loaders/asset_host_spec.rb +33 -0
- data/spec/lib/asset_host_core/loaders/brightcove_spec.rb +51 -0
- data/spec/lib/asset_host_core/loaders/flickr_spec.rb +72 -0
- data/spec/lib/asset_host_core/loaders/url_spec.rb +42 -0
- data/spec/lib/asset_host_core/loaders/vimeo_spec.rb +51 -0
- data/spec/lib/asset_host_core/loaders/youtube_spec.rb +73 -0
- data/spec/lib/asset_host_core/loaders_spec.rb +4 -0
- data/spec/lib/asset_host_core/model_methods_spec.rb +4 -0
- data/spec/lib/asset_host_core/paperclip/asset_thumbnail_spec.rb +4 -0
- data/spec/lib/asset_host_core/paperclip/attachment_spec.rb +4 -0
- data/spec/lib/asset_host_core/resque_job_spec.rb +4 -0
- data/spec/lib/asset_host_core_spec.rb +4 -0
- data/spec/models/api_user_spec.rb +58 -0
- data/spec/models/asset_output_spec.rb +4 -0
- data/spec/models/asset_spec.rb +4 -0
- data/spec/models/output_spec.rb +4 -0
- data/spec/models/permission_spec.rb +4 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/support/fixture_loader.rb +9 -0
- data/spec/support/param_helper.rb +14 -0
- data/spec/support/permission_matcher.rb +17 -0
- data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_222222_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
- data/vendor/assets/javascripts/backbone.js +1158 -0
- data/vendor/assets/javascripts/backbone.modelbinding.js +475 -0
- data/vendor/assets/javascripts/exif.js +695 -0
- data/vendor/assets/javascripts/jquery-ui.js +5614 -0
- data/vendor/assets/javascripts/simplemodal.js +698 -0
- data/vendor/assets/javascripts/spin.jquery.js +81 -0
- data/vendor/assets/javascripts/spin.min.js +1 -0
- data/vendor/assets/javascripts/underscore.min.js +1 -0
- metadata +658 -0
@@ -0,0 +1,695 @@
|
|
1
|
+
/*
|
2
|
+
* Javascript EXIF Reader 0.1.4
|
3
|
+
* Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/
|
4
|
+
* Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt]
|
5
|
+
*/
|
6
|
+
|
7
|
+
|
8
|
+
var EXIF = {};
|
9
|
+
|
10
|
+
(function() {
|
11
|
+
|
12
|
+
EXIF.BinaryFile = function(strData, iDataOffset, iDataLength) {
|
13
|
+
var data = strData;
|
14
|
+
var dataOffset = iDataOffset || 0;
|
15
|
+
var dataLength = 0;
|
16
|
+
|
17
|
+
this.getRawData = function() {
|
18
|
+
return data;
|
19
|
+
}
|
20
|
+
|
21
|
+
if (typeof strData == "string") {
|
22
|
+
dataLength = iDataLength || data.length;
|
23
|
+
|
24
|
+
this.getByteAt = function(iOffset) {
|
25
|
+
return data.charCodeAt(iOffset + dataOffset) & 0xFF;
|
26
|
+
}
|
27
|
+
} else if (typeof strData == "unknown") {
|
28
|
+
dataLength = iDataLength || IEBinary_getLength(data);
|
29
|
+
|
30
|
+
this.getByteAt = function(iOffset) {
|
31
|
+
return IEBinary_getByteAt(data, iOffset + dataOffset);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
this.getLength = function() {
|
36
|
+
return dataLength;
|
37
|
+
}
|
38
|
+
|
39
|
+
this.getSByteAt = function(iOffset) {
|
40
|
+
var iByte = this.getByteAt(iOffset);
|
41
|
+
if (iByte > 127)
|
42
|
+
return iByte - 256;
|
43
|
+
else
|
44
|
+
return iByte;
|
45
|
+
}
|
46
|
+
|
47
|
+
this.getShortAt = function(iOffset, bBigEndian) {
|
48
|
+
var iShort = bBigEndian ?
|
49
|
+
(this.getByteAt(iOffset) << 8) + this.getByteAt(iOffset + 1)
|
50
|
+
: (this.getByteAt(iOffset + 1) << 8) + this.getByteAt(iOffset)
|
51
|
+
if (iShort < 0) iShort += 65536;
|
52
|
+
return iShort;
|
53
|
+
}
|
54
|
+
this.getSShortAt = function(iOffset, bBigEndian) {
|
55
|
+
var iUShort = this.getShortAt(iOffset, bBigEndian);
|
56
|
+
if (iUShort > 32767)
|
57
|
+
return iUShort - 65536;
|
58
|
+
else
|
59
|
+
return iUShort;
|
60
|
+
}
|
61
|
+
this.getLongAt = function(iOffset, bBigEndian) {
|
62
|
+
var iByte1 = this.getByteAt(iOffset),
|
63
|
+
iByte2 = this.getByteAt(iOffset + 1),
|
64
|
+
iByte3 = this.getByteAt(iOffset + 2),
|
65
|
+
iByte4 = this.getByteAt(iOffset + 3);
|
66
|
+
|
67
|
+
var iLong = bBigEndian ?
|
68
|
+
(((((iByte1 << 8) + iByte2) << 8) + iByte3) << 8) + iByte4
|
69
|
+
: (((((iByte4 << 8) + iByte3) << 8) + iByte2) << 8) + iByte1;
|
70
|
+
if (iLong < 0) iLong += 4294967296;
|
71
|
+
return iLong;
|
72
|
+
}
|
73
|
+
this.getSLongAt = function(iOffset, bBigEndian) {
|
74
|
+
var iULong = this.getLongAt(iOffset, bBigEndian);
|
75
|
+
if (iULong > 2147483647)
|
76
|
+
return iULong - 4294967296;
|
77
|
+
else
|
78
|
+
return iULong;
|
79
|
+
}
|
80
|
+
this.getStringAt = function(iOffset, iLength) {
|
81
|
+
var aStr = [];
|
82
|
+
for (var i=iOffset,j=0;i<iOffset+iLength;i++,j++) {
|
83
|
+
aStr[j] = String.fromCharCode(this.getByteAt(i));
|
84
|
+
}
|
85
|
+
return aStr.join("");
|
86
|
+
}
|
87
|
+
|
88
|
+
this.getCharAt = function(iOffset) {
|
89
|
+
return String.fromCharCode(this.getByteAt(iOffset));
|
90
|
+
}
|
91
|
+
this.toBase64 = function() {
|
92
|
+
return window.btoa(data);
|
93
|
+
}
|
94
|
+
this.fromBase64 = function(strBase64) {
|
95
|
+
data = window.atob(strBase64);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
var bDebug = false;
|
100
|
+
|
101
|
+
EXIF.Tags = {
|
102
|
+
|
103
|
+
// version tags
|
104
|
+
0x9000 : "ExifVersion", // EXIF version
|
105
|
+
0xA000 : "FlashpixVersion", // Flashpix format version
|
106
|
+
|
107
|
+
// colorspace tags
|
108
|
+
0xA001 : "ColorSpace", // Color space information tag
|
109
|
+
|
110
|
+
// image configuration
|
111
|
+
0xA002 : "PixelXDimension", // Valid width of meaningful image
|
112
|
+
0xA003 : "PixelYDimension", // Valid height of meaningful image
|
113
|
+
0x9101 : "ComponentsConfiguration", // Information about channels
|
114
|
+
0x9102 : "CompressedBitsPerPixel", // Compressed bits per pixel
|
115
|
+
|
116
|
+
// user information
|
117
|
+
0x927C : "MakerNote", // Any desired information written by the manufacturer
|
118
|
+
0x9286 : "UserComment", // Comments by user
|
119
|
+
|
120
|
+
// related file
|
121
|
+
0xA004 : "RelatedSoundFile", // Name of related sound file
|
122
|
+
|
123
|
+
// date and time
|
124
|
+
0x9003 : "DateTimeOriginal", // Date and time when the original image was generated
|
125
|
+
0x9004 : "DateTimeDigitized", // Date and time when the image was stored digitally
|
126
|
+
0x9290 : "SubsecTime", // Fractions of seconds for DateTime
|
127
|
+
0x9291 : "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal
|
128
|
+
0x9292 : "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized
|
129
|
+
|
130
|
+
// picture-taking conditions
|
131
|
+
0x829A : "ExposureTime", // Exposure time (in seconds)
|
132
|
+
0x829D : "FNumber", // F number
|
133
|
+
0x8822 : "ExposureProgram", // Exposure program
|
134
|
+
0x8824 : "SpectralSensitivity", // Spectral sensitivity
|
135
|
+
0x8827 : "ISOSpeedRatings", // ISO speed rating
|
136
|
+
0x8828 : "OECF", // Optoelectric conversion factor
|
137
|
+
0x9201 : "ShutterSpeedValue", // Shutter speed
|
138
|
+
0x9202 : "ApertureValue", // Lens aperture
|
139
|
+
0x9203 : "BrightnessValue", // Value of brightness
|
140
|
+
0x9204 : "ExposureBias", // Exposure bias
|
141
|
+
0x9205 : "MaxApertureValue", // Smallest F number of lens
|
142
|
+
0x9206 : "SubjectDistance", // Distance to subject in meters
|
143
|
+
0x9207 : "MeteringMode", // Metering mode
|
144
|
+
0x9208 : "LightSource", // Kind of light source
|
145
|
+
0x9209 : "Flash", // Flash status
|
146
|
+
0x9214 : "SubjectArea", // Location and area of main subject
|
147
|
+
0x920A : "FocalLength", // Focal length of the lens in mm
|
148
|
+
0xA20B : "FlashEnergy", // Strobe energy in BCPS
|
149
|
+
0xA20C : "SpatialFrequencyResponse", //
|
150
|
+
0xA20E : "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit
|
151
|
+
0xA20F : "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit
|
152
|
+
0xA210 : "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
|
153
|
+
0xA214 : "SubjectLocation", // Location of subject in image
|
154
|
+
0xA215 : "ExposureIndex", // Exposure index selected on camera
|
155
|
+
0xA217 : "SensingMethod", // Image sensor type
|
156
|
+
0xA300 : "FileSource", // Image source (3 == DSC)
|
157
|
+
0xA301 : "SceneType", // Scene type (1 == directly photographed)
|
158
|
+
0xA302 : "CFAPattern", // Color filter array geometric pattern
|
159
|
+
0xA401 : "CustomRendered", // Special processing
|
160
|
+
0xA402 : "ExposureMode", // Exposure mode
|
161
|
+
0xA403 : "WhiteBalance", // 1 = auto white balance, 2 = manual
|
162
|
+
0xA404 : "DigitalZoomRation", // Digital zoom ratio
|
163
|
+
0xA405 : "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm)
|
164
|
+
0xA406 : "SceneCaptureType", // Type of scene
|
165
|
+
0xA407 : "GainControl", // Degree of overall image gain adjustment
|
166
|
+
0xA408 : "Contrast", // Direction of contrast processing applied by camera
|
167
|
+
0xA409 : "Saturation", // Direction of saturation processing applied by camera
|
168
|
+
0xA40A : "Sharpness", // Direction of sharpness processing applied by camera
|
169
|
+
0xA40B : "DeviceSettingDescription", //
|
170
|
+
0xA40C : "SubjectDistanceRange", // Distance to subject
|
171
|
+
|
172
|
+
// other tags
|
173
|
+
0xA005 : "InteroperabilityIFDPointer",
|
174
|
+
0xA420 : "ImageUniqueID" // Identifier assigned uniquely to each image
|
175
|
+
};
|
176
|
+
|
177
|
+
EXIF.TiffTags = {
|
178
|
+
0x0100 : "ImageWidth",
|
179
|
+
0x0101 : "ImageHeight",
|
180
|
+
0x8769 : "ExifIFDPointer",
|
181
|
+
0x8825 : "GPSInfoIFDPointer",
|
182
|
+
0xA005 : "InteroperabilityIFDPointer",
|
183
|
+
0x0102 : "BitsPerSample",
|
184
|
+
0x0103 : "Compression",
|
185
|
+
0x0106 : "PhotometricInterpretation",
|
186
|
+
0x0112 : "Orientation",
|
187
|
+
0x0115 : "SamplesPerPixel",
|
188
|
+
0x011C : "PlanarConfiguration",
|
189
|
+
0x0212 : "YCbCrSubSampling",
|
190
|
+
0x0213 : "YCbCrPositioning",
|
191
|
+
0x011A : "XResolution",
|
192
|
+
0x011B : "YResolution",
|
193
|
+
0x0128 : "ResolutionUnit",
|
194
|
+
0x0111 : "StripOffsets",
|
195
|
+
0x0116 : "RowsPerStrip",
|
196
|
+
0x0117 : "StripByteCounts",
|
197
|
+
0x0201 : "JPEGInterchangeFormat",
|
198
|
+
0x0202 : "JPEGInterchangeFormatLength",
|
199
|
+
0x012D : "TransferFunction",
|
200
|
+
0x013E : "WhitePoint",
|
201
|
+
0x013F : "PrimaryChromaticities",
|
202
|
+
0x0211 : "YCbCrCoefficients",
|
203
|
+
0x0214 : "ReferenceBlackWhite",
|
204
|
+
0x0132 : "DateTime",
|
205
|
+
0x010E : "ImageDescription",
|
206
|
+
0x010F : "Make",
|
207
|
+
0x0110 : "Model",
|
208
|
+
0x0131 : "Software",
|
209
|
+
0x013B : "Artist",
|
210
|
+
0x8298 : "Copyright"
|
211
|
+
}
|
212
|
+
|
213
|
+
EXIF.GPSTags = {
|
214
|
+
0x0000 : "GPSVersionID",
|
215
|
+
0x0001 : "GPSLatitudeRef",
|
216
|
+
0x0002 : "GPSLatitude",
|
217
|
+
0x0003 : "GPSLongitudeRef",
|
218
|
+
0x0004 : "GPSLongitude",
|
219
|
+
0x0005 : "GPSAltitudeRef",
|
220
|
+
0x0006 : "GPSAltitude",
|
221
|
+
0x0007 : "GPSTimeStamp",
|
222
|
+
0x0008 : "GPSSatellites",
|
223
|
+
0x0009 : "GPSStatus",
|
224
|
+
0x000A : "GPSMeasureMode",
|
225
|
+
0x000B : "GPSDOP",
|
226
|
+
0x000C : "GPSSpeedRef",
|
227
|
+
0x000D : "GPSSpeed",
|
228
|
+
0x000E : "GPSTrackRef",
|
229
|
+
0x000F : "GPSTrack",
|
230
|
+
0x0010 : "GPSImgDirectionRef",
|
231
|
+
0x0011 : "GPSImgDirection",
|
232
|
+
0x0012 : "GPSMapDatum",
|
233
|
+
0x0013 : "GPSDestLatitudeRef",
|
234
|
+
0x0014 : "GPSDestLatitude",
|
235
|
+
0x0015 : "GPSDestLongitudeRef",
|
236
|
+
0x0016 : "GPSDestLongitude",
|
237
|
+
0x0017 : "GPSDestBearingRef",
|
238
|
+
0x0018 : "GPSDestBearing",
|
239
|
+
0x0019 : "GPSDestDistanceRef",
|
240
|
+
0x001A : "GPSDestDistance",
|
241
|
+
0x001B : "GPSProcessingMethod",
|
242
|
+
0x001C : "GPSAreaInformation",
|
243
|
+
0x001D : "GPSDateStamp",
|
244
|
+
0x001E : "GPSDifferential"
|
245
|
+
}
|
246
|
+
|
247
|
+
EXIF.StringValues = {
|
248
|
+
ExposureProgram : {
|
249
|
+
0 : "Not defined",
|
250
|
+
1 : "Manual",
|
251
|
+
2 : "Normal program",
|
252
|
+
3 : "Aperture priority",
|
253
|
+
4 : "Shutter priority",
|
254
|
+
5 : "Creative program",
|
255
|
+
6 : "Action program",
|
256
|
+
7 : "Portrait mode",
|
257
|
+
8 : "Landscape mode"
|
258
|
+
},
|
259
|
+
MeteringMode : {
|
260
|
+
0 : "Unknown",
|
261
|
+
1 : "Average",
|
262
|
+
2 : "CenterWeightedAverage",
|
263
|
+
3 : "Spot",
|
264
|
+
4 : "MultiSpot",
|
265
|
+
5 : "Pattern",
|
266
|
+
6 : "Partial",
|
267
|
+
255 : "Other"
|
268
|
+
},
|
269
|
+
LightSource : {
|
270
|
+
0 : "Unknown",
|
271
|
+
1 : "Daylight",
|
272
|
+
2 : "Fluorescent",
|
273
|
+
3 : "Tungsten (incandescent light)",
|
274
|
+
4 : "Flash",
|
275
|
+
9 : "Fine weather",
|
276
|
+
10 : "Cloudy weather",
|
277
|
+
11 : "Shade",
|
278
|
+
12 : "Daylight fluorescent (D 5700 - 7100K)",
|
279
|
+
13 : "Day white fluorescent (N 4600 - 5400K)",
|
280
|
+
14 : "Cool white fluorescent (W 3900 - 4500K)",
|
281
|
+
15 : "White fluorescent (WW 3200 - 3700K)",
|
282
|
+
17 : "Standard light A",
|
283
|
+
18 : "Standard light B",
|
284
|
+
19 : "Standard light C",
|
285
|
+
20 : "D55",
|
286
|
+
21 : "D65",
|
287
|
+
22 : "D75",
|
288
|
+
23 : "D50",
|
289
|
+
24 : "ISO studio tungsten",
|
290
|
+
255 : "Other"
|
291
|
+
},
|
292
|
+
Flash : {
|
293
|
+
0x0000 : "Flash did not fire",
|
294
|
+
0x0001 : "Flash fired",
|
295
|
+
0x0005 : "Strobe return light not detected",
|
296
|
+
0x0007 : "Strobe return light detected",
|
297
|
+
0x0009 : "Flash fired, compulsory flash mode",
|
298
|
+
0x000D : "Flash fired, compulsory flash mode, return light not detected",
|
299
|
+
0x000F : "Flash fired, compulsory flash mode, return light detected",
|
300
|
+
0x0010 : "Flash did not fire, compulsory flash mode",
|
301
|
+
0x0018 : "Flash did not fire, auto mode",
|
302
|
+
0x0019 : "Flash fired, auto mode",
|
303
|
+
0x001D : "Flash fired, auto mode, return light not detected",
|
304
|
+
0x001F : "Flash fired, auto mode, return light detected",
|
305
|
+
0x0020 : "No flash function",
|
306
|
+
0x0041 : "Flash fired, red-eye reduction mode",
|
307
|
+
0x0045 : "Flash fired, red-eye reduction mode, return light not detected",
|
308
|
+
0x0047 : "Flash fired, red-eye reduction mode, return light detected",
|
309
|
+
0x0049 : "Flash fired, compulsory flash mode, red-eye reduction mode",
|
310
|
+
0x004D : "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",
|
311
|
+
0x004F : "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",
|
312
|
+
0x0059 : "Flash fired, auto mode, red-eye reduction mode",
|
313
|
+
0x005D : "Flash fired, auto mode, return light not detected, red-eye reduction mode",
|
314
|
+
0x005F : "Flash fired, auto mode, return light detected, red-eye reduction mode"
|
315
|
+
},
|
316
|
+
SensingMethod : {
|
317
|
+
1 : "Not defined",
|
318
|
+
2 : "One-chip color area sensor",
|
319
|
+
3 : "Two-chip color area sensor",
|
320
|
+
4 : "Three-chip color area sensor",
|
321
|
+
5 : "Color sequential area sensor",
|
322
|
+
7 : "Trilinear sensor",
|
323
|
+
8 : "Color sequential linear sensor"
|
324
|
+
},
|
325
|
+
SceneCaptureType : {
|
326
|
+
0 : "Standard",
|
327
|
+
1 : "Landscape",
|
328
|
+
2 : "Portrait",
|
329
|
+
3 : "Night scene"
|
330
|
+
},
|
331
|
+
SceneType : {
|
332
|
+
1 : "Directly photographed"
|
333
|
+
},
|
334
|
+
CustomRendered : {
|
335
|
+
0 : "Normal process",
|
336
|
+
1 : "Custom process"
|
337
|
+
},
|
338
|
+
WhiteBalance : {
|
339
|
+
0 : "Auto white balance",
|
340
|
+
1 : "Manual white balance"
|
341
|
+
},
|
342
|
+
GainControl : {
|
343
|
+
0 : "None",
|
344
|
+
1 : "Low gain up",
|
345
|
+
2 : "High gain up",
|
346
|
+
3 : "Low gain down",
|
347
|
+
4 : "High gain down"
|
348
|
+
},
|
349
|
+
Contrast : {
|
350
|
+
0 : "Normal",
|
351
|
+
1 : "Soft",
|
352
|
+
2 : "Hard"
|
353
|
+
},
|
354
|
+
Saturation : {
|
355
|
+
0 : "Normal",
|
356
|
+
1 : "Low saturation",
|
357
|
+
2 : "High saturation"
|
358
|
+
},
|
359
|
+
Sharpness : {
|
360
|
+
0 : "Normal",
|
361
|
+
1 : "Soft",
|
362
|
+
2 : "Hard"
|
363
|
+
},
|
364
|
+
SubjectDistanceRange : {
|
365
|
+
0 : "Unknown",
|
366
|
+
1 : "Macro",
|
367
|
+
2 : "Close view",
|
368
|
+
3 : "Distant view"
|
369
|
+
},
|
370
|
+
FileSource : {
|
371
|
+
3 : "DSC"
|
372
|
+
},
|
373
|
+
|
374
|
+
Components : {
|
375
|
+
0 : "",
|
376
|
+
1 : "Y",
|
377
|
+
2 : "Cb",
|
378
|
+
3 : "Cr",
|
379
|
+
4 : "R",
|
380
|
+
5 : "G",
|
381
|
+
6 : "B"
|
382
|
+
}
|
383
|
+
}
|
384
|
+
|
385
|
+
function addEvent(oElement, strEvent, fncHandler)
|
386
|
+
{
|
387
|
+
if (oElement.addEventListener) {
|
388
|
+
oElement.addEventListener(strEvent, fncHandler, false);
|
389
|
+
} else if (oElement.attachEvent) {
|
390
|
+
oElement.attachEvent("on" + strEvent, fncHandler);
|
391
|
+
}
|
392
|
+
}
|
393
|
+
|
394
|
+
|
395
|
+
function imageHasData(oImg)
|
396
|
+
{
|
397
|
+
return !!(oImg.exifdata);
|
398
|
+
}
|
399
|
+
|
400
|
+
function getImageData(oImg, fncCallback)
|
401
|
+
{
|
402
|
+
BinaryAjax(
|
403
|
+
oImg.src,
|
404
|
+
function(oHTTP) {
|
405
|
+
var oEXIF = findEXIFinJPEG(oHTTP.binaryResponse);
|
406
|
+
oImg.exifdata = oEXIF || {};
|
407
|
+
if (fncCallback) fncCallback();
|
408
|
+
}
|
409
|
+
)
|
410
|
+
}
|
411
|
+
|
412
|
+
function findEXIFinJPEG(oFile) {
|
413
|
+
var aMarkers = [];
|
414
|
+
|
415
|
+
if (oFile.getByteAt(0) != 0xFF || oFile.getByteAt(1) != 0xD8) {
|
416
|
+
return false; // not a valid jpeg
|
417
|
+
}
|
418
|
+
|
419
|
+
var iOffset = 2;
|
420
|
+
var iLength = oFile.getLength();
|
421
|
+
while (iOffset < iLength) {
|
422
|
+
if (oFile.getByteAt(iOffset) != 0xFF) {
|
423
|
+
if (bDebug) console.log("Not a valid marker at offset " + iOffset + ", found: " + oFile.getByteAt(iOffset));
|
424
|
+
return false; // not a valid marker, something is wrong
|
425
|
+
}
|
426
|
+
|
427
|
+
var iMarker = oFile.getByteAt(iOffset+1);
|
428
|
+
|
429
|
+
// we could implement handling for other markers here,
|
430
|
+
// but we're only looking for 0xFFE1 for EXIF data
|
431
|
+
|
432
|
+
if (iMarker == 22400) {
|
433
|
+
if (bDebug) console.log("Found 0xFFE1 marker");
|
434
|
+
return readEXIFData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);
|
435
|
+
iOffset += 2 + oFile.getShortAt(iOffset+2, true);
|
436
|
+
|
437
|
+
} else if (iMarker == 225) {
|
438
|
+
// 0xE1 = Application-specific 1 (for EXIF)
|
439
|
+
if (bDebug) console.log("Found 0xFFE1 marker");
|
440
|
+
return readEXIFData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);
|
441
|
+
|
442
|
+
} else {
|
443
|
+
iOffset += 2 + oFile.getShortAt(iOffset+2, true);
|
444
|
+
}
|
445
|
+
|
446
|
+
}
|
447
|
+
|
448
|
+
}
|
449
|
+
|
450
|
+
|
451
|
+
function readTags(oFile, iTIFFStart, iDirStart, oStrings, bBigEnd)
|
452
|
+
{
|
453
|
+
var iEntries = oFile.getShortAt(iDirStart, bBigEnd);
|
454
|
+
var oTags = {};
|
455
|
+
for (var i=0;i<iEntries;i++) {
|
456
|
+
var iEntryOffset = iDirStart + i*12 + 2;
|
457
|
+
var strTag = oStrings[oFile.getShortAt(iEntryOffset, bBigEnd)];
|
458
|
+
if (!strTag && bDebug) console.log("Unknown tag: " + oFile.getShortAt(iEntryOffset, bBigEnd));
|
459
|
+
oTags[strTag] = readTagValue(oFile, iEntryOffset, iTIFFStart, iDirStart, bBigEnd);
|
460
|
+
}
|
461
|
+
return oTags;
|
462
|
+
}
|
463
|
+
|
464
|
+
|
465
|
+
function readTagValue(oFile, iEntryOffset, iTIFFStart, iDirStart, bBigEnd)
|
466
|
+
{
|
467
|
+
var iType = oFile.getShortAt(iEntryOffset+2, bBigEnd);
|
468
|
+
var iNumValues = oFile.getLongAt(iEntryOffset+4, bBigEnd);
|
469
|
+
var iValueOffset = oFile.getLongAt(iEntryOffset+8, bBigEnd) + iTIFFStart;
|
470
|
+
|
471
|
+
switch (iType) {
|
472
|
+
case 1: // byte, 8-bit unsigned int
|
473
|
+
case 7: // undefined, 8-bit byte, value depending on field
|
474
|
+
if (iNumValues == 1) {
|
475
|
+
return oFile.getByteAt(iEntryOffset + 8, bBigEnd);
|
476
|
+
} else {
|
477
|
+
var iValOffset = iNumValues > 4 ? iValueOffset : (iEntryOffset + 8);
|
478
|
+
var aVals = [];
|
479
|
+
for (var n=0;n<iNumValues;n++) {
|
480
|
+
aVals[n] = oFile.getByteAt(iValOffset + n);
|
481
|
+
}
|
482
|
+
return aVals;
|
483
|
+
}
|
484
|
+
break;
|
485
|
+
|
486
|
+
case 2: // ascii, 8-bit byte
|
487
|
+
var iStringOffset = iNumValues > 4 ? iValueOffset : (iEntryOffset + 8);
|
488
|
+
return oFile.getStringAt(iStringOffset, iNumValues-1);
|
489
|
+
break;
|
490
|
+
|
491
|
+
case 3: // short, 16 bit int
|
492
|
+
if (iNumValues == 1) {
|
493
|
+
return oFile.getShortAt(iEntryOffset + 8, bBigEnd);
|
494
|
+
} else {
|
495
|
+
var iValOffset = iNumValues > 2 ? iValueOffset : (iEntryOffset + 8);
|
496
|
+
var aVals = [];
|
497
|
+
for (var n=0;n<iNumValues;n++) {
|
498
|
+
aVals[n] = oFile.getShortAt(iValOffset + 2*n, bBigEnd);
|
499
|
+
}
|
500
|
+
return aVals;
|
501
|
+
}
|
502
|
+
break;
|
503
|
+
|
504
|
+
case 4: // long, 32 bit int
|
505
|
+
if (iNumValues == 1) {
|
506
|
+
return oFile.getLongAt(iEntryOffset + 8, bBigEnd);
|
507
|
+
} else {
|
508
|
+
var aVals = [];
|
509
|
+
for (var n=0;n<iNumValues;n++) {
|
510
|
+
aVals[n] = oFile.getLongAt(iValueOffset + 4*n, bBigEnd);
|
511
|
+
}
|
512
|
+
return aVals;
|
513
|
+
}
|
514
|
+
break;
|
515
|
+
case 5: // rational = two long values, first is numerator, second is denominator
|
516
|
+
if (iNumValues == 1) {
|
517
|
+
return oFile.getLongAt(iValueOffset, bBigEnd) / oFile.getLongAt(iValueOffset+4, bBigEnd);
|
518
|
+
} else {
|
519
|
+
var aVals = [];
|
520
|
+
for (var n=0;n<iNumValues;n++) {
|
521
|
+
aVals[n] = oFile.getLongAt(iValueOffset + 8*n, bBigEnd) / oFile.getLongAt(iValueOffset+4 + 8*n, bBigEnd);
|
522
|
+
}
|
523
|
+
return aVals;
|
524
|
+
}
|
525
|
+
break;
|
526
|
+
case 9: // slong, 32 bit signed int
|
527
|
+
if (iNumValues == 1) {
|
528
|
+
return oFile.getSLongAt(iEntryOffset + 8, bBigEnd);
|
529
|
+
} else {
|
530
|
+
var aVals = [];
|
531
|
+
for (var n=0;n<iNumValues;n++) {
|
532
|
+
aVals[n] = oFile.getSLongAt(iValueOffset + 4*n, bBigEnd);
|
533
|
+
}
|
534
|
+
return aVals;
|
535
|
+
}
|
536
|
+
break;
|
537
|
+
case 10: // signed rational, two slongs, first is numerator, second is denominator
|
538
|
+
if (iNumValues == 1) {
|
539
|
+
return oFile.getSLongAt(iValueOffset, bBigEnd) / oFile.getSLongAt(iValueOffset+4, bBigEnd);
|
540
|
+
} else {
|
541
|
+
var aVals = [];
|
542
|
+
for (var n=0;n<iNumValues;n++) {
|
543
|
+
aVals[n] = oFile.getSLongAt(iValueOffset + 8*n, bBigEnd) / oFile.getSLongAt(iValueOffset+4 + 8*n, bBigEnd);
|
544
|
+
}
|
545
|
+
return aVals;
|
546
|
+
}
|
547
|
+
break;
|
548
|
+
}
|
549
|
+
}
|
550
|
+
|
551
|
+
|
552
|
+
function readEXIFData(oFile, iStart, iLength)
|
553
|
+
{
|
554
|
+
if (oFile.getStringAt(iStart, 4) != "Exif") {
|
555
|
+
if (bDebug) console.log("Not valid EXIF data! " + oFile.getStringAt(iStart, 4));
|
556
|
+
return false;
|
557
|
+
}
|
558
|
+
|
559
|
+
var bBigEnd;
|
560
|
+
|
561
|
+
var iTIFFOffset = iStart + 6;
|
562
|
+
|
563
|
+
// test for TIFF validity and endianness
|
564
|
+
if (oFile.getShortAt(iTIFFOffset) == 0x4949) {
|
565
|
+
bBigEnd = false;
|
566
|
+
} else if (oFile.getShortAt(iTIFFOffset) == 0x4D4D) {
|
567
|
+
bBigEnd = true;
|
568
|
+
} else {
|
569
|
+
if (bDebug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
|
570
|
+
return false;
|
571
|
+
}
|
572
|
+
|
573
|
+
if (oFile.getShortAt(iTIFFOffset+2, bBigEnd) != 0x002A) {
|
574
|
+
if (bDebug) console.log("Not valid TIFF data! (no 0x002A)");
|
575
|
+
return false;
|
576
|
+
}
|
577
|
+
|
578
|
+
if (oFile.getLongAt(iTIFFOffset+4, bBigEnd) != 0x00000008) {
|
579
|
+
if (bDebug) console.log("Not valid TIFF data! (First offset not 8)", oFile.getShortAt(iTIFFOffset+4, bBigEnd));
|
580
|
+
return false;
|
581
|
+
}
|
582
|
+
|
583
|
+
var oTags = readTags(oFile, iTIFFOffset, iTIFFOffset+8, EXIF.TiffTags, bBigEnd);
|
584
|
+
|
585
|
+
if (oTags.ExifIFDPointer) {
|
586
|
+
var oEXIFTags = readTags(oFile, iTIFFOffset, iTIFFOffset + oTags.ExifIFDPointer, EXIF.Tags, bBigEnd);
|
587
|
+
for (var strTag in oEXIFTags) {
|
588
|
+
switch (strTag) {
|
589
|
+
case "LightSource" :
|
590
|
+
case "Flash" :
|
591
|
+
case "MeteringMode" :
|
592
|
+
case "ExposureProgram" :
|
593
|
+
case "SensingMethod" :
|
594
|
+
case "SceneCaptureType" :
|
595
|
+
case "SceneType" :
|
596
|
+
case "CustomRendered" :
|
597
|
+
case "WhiteBalance" :
|
598
|
+
case "GainControl" :
|
599
|
+
case "Contrast" :
|
600
|
+
case "Saturation" :
|
601
|
+
case "Sharpness" :
|
602
|
+
case "SubjectDistanceRange" :
|
603
|
+
case "FileSource" :
|
604
|
+
oEXIFTags[strTag] = EXIF.StringValues[strTag][oEXIFTags[strTag]];
|
605
|
+
break;
|
606
|
+
|
607
|
+
case "ExifVersion" :
|
608
|
+
case "FlashpixVersion" :
|
609
|
+
oEXIFTags[strTag] = String.fromCharCode(oEXIFTags[strTag][0], oEXIFTags[strTag][1], oEXIFTags[strTag][2], oEXIFTags[strTag][3]);
|
610
|
+
break;
|
611
|
+
|
612
|
+
case "ComponentsConfiguration" :
|
613
|
+
oEXIFTags[strTag] =
|
614
|
+
EXIF.StringValues.Components[oEXIFTags[strTag][0]]
|
615
|
+
+ EXIF.StringValues.Components[oEXIFTags[strTag][1]]
|
616
|
+
+ EXIF.StringValues.Components[oEXIFTags[strTag][2]]
|
617
|
+
+ EXIF.StringValues.Components[oEXIFTags[strTag][3]];
|
618
|
+
break;
|
619
|
+
}
|
620
|
+
oTags[strTag] = oEXIFTags[strTag];
|
621
|
+
}
|
622
|
+
}
|
623
|
+
|
624
|
+
if (oTags.GPSInfoIFDPointer) {
|
625
|
+
var oGPSTags = readTags(oFile, iTIFFOffset, iTIFFOffset + oTags.GPSInfoIFDPointer, EXIF.GPSTags, bBigEnd);
|
626
|
+
for (var strTag in oGPSTags) {
|
627
|
+
switch (strTag) {
|
628
|
+
case "GPSVersionID" :
|
629
|
+
oGPSTags[strTag] = oGPSTags[strTag][0]
|
630
|
+
+ "." + oGPSTags[strTag][1]
|
631
|
+
+ "." + oGPSTags[strTag][2]
|
632
|
+
+ "." + oGPSTags[strTag][3];
|
633
|
+
break;
|
634
|
+
}
|
635
|
+
oTags[strTag] = oGPSTags[strTag];
|
636
|
+
}
|
637
|
+
}
|
638
|
+
|
639
|
+
return oTags;
|
640
|
+
}
|
641
|
+
|
642
|
+
|
643
|
+
EXIF.getData = function(oImg, fncCallback)
|
644
|
+
{
|
645
|
+
if (!oImg.complete) return false;
|
646
|
+
if (!imageHasData(oImg)) {
|
647
|
+
getImageData(oImg, fncCallback);
|
648
|
+
} else {
|
649
|
+
if (fncCallback) fncCallback();
|
650
|
+
}
|
651
|
+
return true;
|
652
|
+
}
|
653
|
+
|
654
|
+
EXIF.getTag = function(oImg, strTag)
|
655
|
+
{
|
656
|
+
if (!imageHasData(oImg)) return;
|
657
|
+
return oImg.exifdata[strTag];
|
658
|
+
}
|
659
|
+
|
660
|
+
EXIF.getAllTags = function(oImg)
|
661
|
+
{
|
662
|
+
if (!imageHasData(oImg)) return {};
|
663
|
+
var oData = oImg.exifdata;
|
664
|
+
var oAllTags = {};
|
665
|
+
for (var a in oData) {
|
666
|
+
if (oData.hasOwnProperty(a)) {
|
667
|
+
oAllTags[a] = oData[a];
|
668
|
+
}
|
669
|
+
}
|
670
|
+
return oAllTags;
|
671
|
+
}
|
672
|
+
|
673
|
+
|
674
|
+
EXIF.pretty = function(oImg)
|
675
|
+
{
|
676
|
+
if (!imageHasData(oImg)) return "";
|
677
|
+
var oData = oImg.exifdata;
|
678
|
+
var strPretty = "";
|
679
|
+
for (var a in oData) {
|
680
|
+
if (oData.hasOwnProperty(a)) {
|
681
|
+
if (typeof oData[a] == "object") {
|
682
|
+
strPretty += a + " : [" + oData[a].length + " values]\r\n";
|
683
|
+
} else {
|
684
|
+
strPretty += a + " : " + oData[a] + "\r\n";
|
685
|
+
}
|
686
|
+
}
|
687
|
+
}
|
688
|
+
return strPretty;
|
689
|
+
}
|
690
|
+
|
691
|
+
EXIF.readFromBinaryFile = function(oFile) {
|
692
|
+
return findEXIFinJPEG(new EXIF.BinaryFile(oFile));
|
693
|
+
}
|
694
|
+
|
695
|
+
})();
|