exiftool-vendored
Advanced tools
Comparing version 28.3.1 to 28.4.0
import * as bc from "batch-cluster"; | ||
import { ExifToolOptions } from "./ExifToolOptions"; | ||
import { Omit } from "./Omit"; | ||
import { Tags } from "./Tags"; | ||
export declare const ConsoleLogger: bc.Logger; | ||
@@ -10,1 +11,5 @@ /** | ||
export declare const DefaultExifToolOptions: Omit<ExifToolOptions, "processFactory" | "ignoreShebang">; | ||
/** | ||
* @see https://github.com/photostructure/exiftool-vendored.js/issues/215 | ||
*/ | ||
export declare function defaultAdjustTimeZoneIfDaylightSavings(t: Tags): number | undefined; |
@@ -27,4 +27,6 @@ "use strict"; | ||
exports.DefaultExifToolOptions = exports.ConsoleLogger = void 0; | ||
exports.defaultAdjustTimeZoneIfDaylightSavings = defaultAdjustTimeZoneIfDaylightSavings; | ||
const bc = __importStar(require("batch-cluster")); | ||
const node_util_1 = require("node:util"); | ||
const Boolean_1 = require("./Boolean"); | ||
const CapturedAtTagNames_1 = require("./CapturedAtTagNames"); | ||
@@ -109,3 +111,15 @@ const DefaultExiftoolArgs_1 = require("./DefaultExiftoolArgs"); | ||
writeArgs: [], | ||
adjustTimeZoneIfDaylightSavings: defaultAdjustTimeZoneIfDaylightSavings, | ||
}); | ||
/** | ||
* @see https://github.com/photostructure/exiftool-vendored.js/issues/215 | ||
*/ | ||
function defaultAdjustTimeZoneIfDaylightSavings(t) { | ||
// `DaylightSavings` may be "Yes" or `true`: | ||
return true === (0, Boolean_1.toBoolean)(t.DaylightSavings) && | ||
// Daggum Nikon likes "FS-Nikon", "Nikon", "NIKON", and "NIKON CORPORATION" | ||
/\bnikon\b/i.test(String(t.Make)) | ||
? 60 | ||
: undefined; | ||
} | ||
//# sourceMappingURL=DefaultExifToolOptions.js.map |
import * as bc from "batch-cluster"; | ||
import { geoTz } from "./GeoTz"; | ||
import { Maybe } from "./Maybe"; | ||
import { Tags } from "./Tags"; | ||
@@ -264,3 +265,19 @@ /** | ||
writeArgs: string[]; | ||
/** | ||
* The TimeZone tag normally represents the offset from UTC. | ||
* | ||
* Unfortunately, at least for some Nikon cameras, the TimeZone tag **and the | ||
* DaylightSavings tag** must be taken into account to find the UTC offset. | ||
* | ||
* By default, this is a predicate that returns `true` if the `Make` tag is | ||
* `Nikon`. If you find other makes and models that need this treatment, | ||
* please open a ticket on GitHub with example images or videos and we can | ||
* update the default predicate. | ||
* | ||
* The return value is the number of minutes to adjust the timezone by. | ||
* | ||
* @see https://github.com/photostructure/exiftool-vendored.js/issues/215 | ||
*/ | ||
adjustTimeZoneIfDaylightSavings: (tags: Tags, tz: string) => Maybe<number>; | ||
} | ||
export declare function handleDeprecatedOptions<T extends Partial<Pick<ExifToolOptions, "includeImageDataMD5" | "imageHashType">>>(options: T): T; |
import { ExifToolTask } from "./ExifToolTask"; | ||
import { Maybe } from "./Maybe"; | ||
import { Tags } from "./Tags"; | ||
export declare const ReadTaskOptionFields: ["backfillTimezones", "defaultVideosToUTC", "geolocation", "geoTz", "ignoreMinorErrors", "ignoreZeroZeroLatLon", "imageHashType", "includeImageDataMD5", "inferTimezoneFromDatestamps", "inferTimezoneFromDatestampTags", "inferTimezoneFromTimeStamp", "numericTags", "useMWG", "struct", "readArgs"]; | ||
export declare const ReadTaskOptionFields: ["backfillTimezones", "defaultVideosToUTC", "geolocation", "geoTz", "ignoreMinorErrors", "ignoreZeroZeroLatLon", "imageHashType", "includeImageDataMD5", "inferTimezoneFromDatestamps", "inferTimezoneFromDatestampTags", "inferTimezoneFromTimeStamp", "numericTags", "useMWG", "struct", "readArgs", "adjustTimeZoneIfDaylightSavings"]; | ||
export declare function nullish(s: string | undefined): s is undefined; | ||
@@ -21,2 +22,3 @@ export declare const DefaultReadTaskOptions: { | ||
readonly readArgs: string[]; | ||
readonly adjustTimeZoneIfDaylightSavings: (tags: Tags, tz: string) => Maybe<number>; | ||
}; | ||
@@ -23,0 +25,0 @@ export type ReadTaskOptions = Partial<typeof DefaultReadTaskOptions>; |
@@ -36,3 +36,3 @@ "use strict"; | ||
}; | ||
var _ReadTask_instances, _ReadTask_raw, _ReadTask_rawDegrouped, _ReadTask_tags, _ReadTask_lat, _ReadTask_lon, _ReadTask_invalidLatLon, _ReadTask_tz, _ReadTask_tzSource, _ReadTask_isVideo, _ReadTask_defaultToUTC, _ReadTask_tagName, _ReadTask_parseTags, _ReadTask_extractLatLon, _ReadTask_latlon, _ReadTask_geoTz, _ReadTask_extractTzOffset, _ReadTask_parseTag; | ||
var _ReadTask_instances, _ReadTask_raw, _ReadTask_rawDegrouped, _ReadTask_tags, _ReadTask_isVideo, _ReadTask_defaultToUTC, _ReadTask_tagName, _ReadTask_parseTags, _ReadTask_lat, _ReadTask_lon, _ReadTask_tzFromGps, _ReadTask_extractGpsMetadata, _ReadTask_parseLocation, _ReadTask_tz, _ReadTask_extractTzOffset, _ReadTask_parseTag; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -87,2 +87,3 @@ exports.ReadTask = exports.DefaultReadTaskOptions = exports.ReadTaskOptionFields = void 0; | ||
"readArgs", | ||
"adjustTimeZoneIfDaylightSavings", | ||
]; | ||
@@ -111,11 +112,14 @@ const NullIsh = ["undef", "null", "undefined"]; | ||
_ReadTask_rawDegrouped.set(this, {}); | ||
_ReadTask_tags.set(this, {}); | ||
_ReadTask_lat.set(this, void 0); | ||
_ReadTask_lon.set(this, void 0); | ||
_ReadTask_invalidLatLon.set(this, false); | ||
_ReadTask_tz.set(this, void 0); | ||
_ReadTask_tzSource.set(this, void 0); | ||
_ReadTask_extractLatLon.set(this, (0, Lazy_1.lazy)(() => { | ||
var _a, _b; | ||
__classPrivateFieldSet(this, _ReadTask_lat, (_a = __classPrivateFieldGet(this, _ReadTask_lat, "f")) !== null && _a !== void 0 ? _a : __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_latlon).call(this, { | ||
_ReadTask_tags.set(this, {} | ||
/** | ||
* @param sourceFile the file to read | ||
* @param args the full arguments to pass to exiftool that take into account | ||
* the flags in `options` | ||
*/ | ||
); | ||
_ReadTask_lat.set(this, (0, Lazy_1.lazy)(() => { var _a; return (_a = __classPrivateFieldGet(this, _ReadTask_extractGpsMetadata, "f").call(this)) === null || _a === void 0 ? void 0 : _a.lat; })); | ||
_ReadTask_lon.set(this, (0, Lazy_1.lazy)(() => { var _a; return (_a = __classPrivateFieldGet(this, _ReadTask_extractGpsMetadata, "f").call(this)) === null || _a === void 0 ? void 0 : _a.lon; })); | ||
_ReadTask_tzFromGps.set(this, (0, Lazy_1.lazy)(() => { var _a; return (_a = __classPrivateFieldGet(this, _ReadTask_extractGpsMetadata, "f").call(this)) === null || _a === void 0 ? void 0 : _a.tzFromGps; })); | ||
_ReadTask_extractGpsMetadata.set(this, (0, Lazy_1.lazy)(() => { | ||
const lat = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_parseLocation).call(this, { | ||
tagName: "GPSLatitude", | ||
@@ -125,4 +129,4 @@ positiveRef: "N", | ||
maxValid: 90, | ||
}), "f"); | ||
__classPrivateFieldSet(this, _ReadTask_lon, (_b = __classPrivateFieldGet(this, _ReadTask_lon, "f")) !== null && _b !== void 0 ? _b : __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_latlon).call(this, { | ||
}); | ||
const lon = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_parseLocation).call(this, { | ||
tagName: "GPSLongitude", | ||
@@ -132,35 +136,58 @@ positiveRef: "E", | ||
maxValid: 180, | ||
}), "f"); | ||
if (this.options.ignoreZeroZeroLatLon && | ||
__classPrivateFieldGet(this, _ReadTask_lat, "f") === 0 && | ||
__classPrivateFieldGet(this, _ReadTask_lon, "f") === 0) { | ||
__classPrivateFieldSet(this, _ReadTask_invalidLatLon, true, "f"); | ||
} | ||
if (__classPrivateFieldGet(this, _ReadTask_invalidLatLon, "f")) { | ||
__classPrivateFieldSet(this, _ReadTask_lat, __classPrivateFieldSet(this, _ReadTask_lon, undefined, "f"), "f"); | ||
if (this.options.geolocation) { | ||
this.warnings.push("Invalid GPSLatitude or GPSLongitude. Geolocation tags have been deleted."); | ||
for (const key of Object.keys(__classPrivateFieldGet(this, _ReadTask_raw, "f"))) { | ||
const k = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_tagName).call(this, key); | ||
if (k.startsWith("Geolocation")) { | ||
delete __classPrivateFieldGet(this, _ReadTask_raw, "f")[key]; | ||
delete __classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f")[k]; | ||
} | ||
}); | ||
let invalid = lat == null || | ||
lon == null || | ||
(this.options.ignoreZeroZeroLatLon && lat === 0 && lon === 0); | ||
if (this.options.geolocation && invalid) { | ||
this.warnings.push("Invalid GPSLatitude or GPSLongitude. Deleting geolocation tags."); | ||
for (const key of Object.keys(__classPrivateFieldGet(this, _ReadTask_raw, "f"))) { | ||
const k = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_tagName).call(this, key); | ||
if (k.startsWith("Geolocation")) { | ||
delete __classPrivateFieldGet(this, _ReadTask_raw, "f")[key]; | ||
delete __classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f")[k]; | ||
} | ||
} | ||
} | ||
})); | ||
_ReadTask_geoTz.set(this, (0, Lazy_1.lazy)(() => { | ||
__classPrivateFieldGet(this, _ReadTask_extractLatLon, "f").call(this); | ||
if (__classPrivateFieldGet(this, _ReadTask_invalidLatLon, "f") || __classPrivateFieldGet(this, _ReadTask_lat, "f") == null || __classPrivateFieldGet(this, _ReadTask_lon, "f") == null) | ||
return; | ||
try { | ||
const geoTz = this.options.geoTz(__classPrivateFieldGet(this, _ReadTask_lat, "f"), __classPrivateFieldGet(this, _ReadTask_lon, "f")); | ||
return (0, Timezones_1.normalizeZone)(geoTz); | ||
let tzFromGps; | ||
if (!invalid && lat != null && lon != null) { | ||
try { | ||
const geoTz = this.options.geoTz(lat, lon); | ||
tzFromGps = (0, Timezones_1.normalizeZone)(geoTz); | ||
} | ||
catch { | ||
invalid = true; | ||
} | ||
} | ||
catch { | ||
__classPrivateFieldSet(this, _ReadTask_invalidLatLon, true, "f"); | ||
return; | ||
} | ||
return { | ||
lat: invalid ? undefined : lat, | ||
lon: invalid ? undefined : lon, | ||
invalid, | ||
tzFromGps, | ||
}; | ||
})); | ||
_ReadTask_tz.set(this, (0, Lazy_1.lazy)(() => { var _a; return (_a = __classPrivateFieldGet(this, _ReadTask_extractTzOffset, "f").call(this)) === null || _a === void 0 ? void 0 : _a.tz; })); | ||
_ReadTask_extractTzOffset.set(this, (0, Lazy_1.lazy)(() => { | ||
var _a, _b, _c, _d, _e; | ||
// If there is an explicit TimeZone tag (which is rare), defer to that | ||
// before defaulting to UTC for videos: | ||
return (_e = (_d = (_c = (_b = (_a = (0, Timezones_1.extractTzOffsetFromTags)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f"), this.options)) !== null && _a !== void 0 ? _a : (0, Maybe_1.map)(__classPrivateFieldGet(this, _ReadTask_tzFromGps, "f").call(this), (ea) => ({ | ||
tz: ea.name, | ||
src: "GPSLatitude/GPSLongitude", | ||
}))) !== null && _b !== void 0 ? _b : (0, Timezones_1.extractTzOffsetFromDatestamps)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f"), this.options)) !== null && _c !== void 0 ? _c : | ||
// See https://github.com/photostructure/exiftool-vendored.js/issues/113 | ||
// and https://github.com/photostructure/exiftool-vendored.js/issues/156 | ||
// Videos are frequently encoded in UTC, but don't include the | ||
// timezone offset in their datetime stamps. | ||
(__classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_defaultToUTC).call(this) | ||
? { | ||
tz: "UTC", | ||
src: "defaultVideosToUTC", | ||
} | ||
: // not applicable: | ||
undefined)) !== null && _d !== void 0 ? _d : | ||
// This is a last-ditch estimation heuristic: | ||
(0, Timezones_1.extractTzOffsetFromUTCOffset)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f"))) !== null && _e !== void 0 ? _e : | ||
// No, really, this is the even worse than UTC offset heuristics: | ||
(0, Timezones_1.extractTzOffsetFromTimeStamp)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f"), this.options); | ||
})); | ||
// See https://github.com/photostructure/exiftool-vendored.js/issues/147#issuecomment-1642580118 | ||
@@ -228,3 +255,3 @@ this.degroup = this.args.includes("-G"); | ||
exports.ReadTask = ReadTask; | ||
_ReadTask_raw = new WeakMap(), _ReadTask_rawDegrouped = new WeakMap(), _ReadTask_tags = new WeakMap(), _ReadTask_lat = new WeakMap(), _ReadTask_lon = new WeakMap(), _ReadTask_invalidLatLon = new WeakMap(), _ReadTask_tz = new WeakMap(), _ReadTask_tzSource = new WeakMap(), _ReadTask_extractLatLon = new WeakMap(), _ReadTask_geoTz = new WeakMap(), _ReadTask_instances = new WeakSet(), _ReadTask_isVideo = function _ReadTask_isVideo() { | ||
_ReadTask_raw = new WeakMap(), _ReadTask_rawDegrouped = new WeakMap(), _ReadTask_tags = new WeakMap(), _ReadTask_lat = new WeakMap(), _ReadTask_lon = new WeakMap(), _ReadTask_tzFromGps = new WeakMap(), _ReadTask_extractGpsMetadata = new WeakMap(), _ReadTask_tz = new WeakMap(), _ReadTask_extractTzOffset = new WeakMap(), _ReadTask_instances = new WeakSet(), _ReadTask_isVideo = function _ReadTask_isVideo() { | ||
var _a; | ||
@@ -248,8 +275,9 @@ return String((_a = __classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f")) === null || _a === void 0 ? void 0 : _a.MIMEType).startsWith("video/"); | ||
} | ||
__classPrivateFieldGet(this, _ReadTask_extractLatLon, "f").call(this); | ||
__classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_extractTzOffset).call(this); | ||
(0, Maybe_1.map)(__classPrivateFieldGet(this, _ReadTask_tz, "f"), (ea) => (__classPrivateFieldGet(this, _ReadTask_tags, "f").tz = ea)); | ||
(0, Maybe_1.map)(__classPrivateFieldGet(this, _ReadTask_tzSource, "f"), (ea) => (__classPrivateFieldGet(this, _ReadTask_tags, "f").tzSource = ea)); | ||
// avoid casting `this.tags as any` for the rest of the function: | ||
const tags = __classPrivateFieldGet(this, _ReadTask_tags, "f"); | ||
const tzSrc = __classPrivateFieldGet(this, _ReadTask_extractTzOffset, "f").call(this); | ||
if (tzSrc) { | ||
tags.tz = tzSrc.tz; | ||
tags.tzSource = tzSrc.src; | ||
} | ||
for (const [key, value] of Object.entries(__classPrivateFieldGet(this, _ReadTask_raw, "f"))) { | ||
@@ -268,3 +296,3 @@ const k = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_tagName).call(this, key); | ||
return tags; | ||
}, _ReadTask_latlon = function _ReadTask_latlon({ tagName, positiveRef, negativeRef, maxValid, }) { | ||
}, _ReadTask_parseLocation = function _ReadTask_parseLocation({ tagName, positiveRef, negativeRef, maxValid, }) { | ||
const tagValue = __classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f")[tagName]; | ||
@@ -275,8 +303,7 @@ const refKey = tagName + "Ref"; | ||
if (result == null) { | ||
return; | ||
return undefined; | ||
} | ||
else if (Math.abs(result) > maxValid) { | ||
this.warnings.push(`Invalid ${tagName}: ${JSON.stringify(tagValue)}`); | ||
__classPrivateFieldSet(this, _ReadTask_invalidLatLon, true, "f"); | ||
return; | ||
return undefined; | ||
} | ||
@@ -300,31 +327,2 @@ else if ((0, String_1.blank)(ref)) { | ||
} | ||
}, _ReadTask_extractTzOffset = function _ReadTask_extractTzOffset() { | ||
var _a, _b, _c, _d, _e; | ||
const result = | ||
// If there is an explicit TimeZone tag (which is rare), or if defer to that | ||
// before defaulting to UTC for videos: | ||
(_e = (_d = (_c = (_b = (_a = (0, Timezones_1.extractTzOffsetFromTags)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f"))) !== null && _a !== void 0 ? _a : (0, Maybe_1.map)(__classPrivateFieldGet(this, _ReadTask_geoTz, "f").call(this), (ea) => ({ | ||
tz: ea.name, | ||
src: "GPSLatitude/GPSLongitude", | ||
}))) !== null && _b !== void 0 ? _b : (0, Timezones_1.extractTzOffsetFromDatestamps)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f"), this.options)) !== null && _c !== void 0 ? _c : | ||
// See https://github.com/photostructure/exiftool-vendored.js/issues/113 | ||
// and https://github.com/photostructure/exiftool-vendored.js/issues/156 | ||
// Videos are frequently encoded in UTC, but don't include the | ||
// timezone offset in their datetime stamps. | ||
(__classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_defaultToUTC).call(this) | ||
? { | ||
tz: "UTC", | ||
src: "defaultVideosToUTC", | ||
} | ||
: // not applicable: | ||
undefined)) !== null && _d !== void 0 ? _d : | ||
// This is a last-ditch estimation heuristic: | ||
(0, Timezones_1.extractTzOffsetFromUTCOffset)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f"))) !== null && _e !== void 0 ? _e : | ||
// No, really, this is the even worse than UTC offset heuristics: | ||
(0, Timezones_1.extractTzOffsetFromTimeStamp)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f"), this.options); | ||
if (result != null) { | ||
__classPrivateFieldSet(this, _ReadTask_tz, result.tz, "f"); | ||
__classPrivateFieldSet(this, _ReadTask_tzSource, result.src, "f"); | ||
} | ||
return result; | ||
}, _ReadTask_parseTag = function _ReadTask_parseTag(tagName, value) { | ||
@@ -339,6 +337,6 @@ var _a, _b, _c; | ||
if (tagName === "GPSLatitude") { | ||
return __classPrivateFieldGet(this, _ReadTask_lat, "f"); | ||
return __classPrivateFieldGet(this, _ReadTask_lat, "f").call(this); | ||
} | ||
if (tagName === "GPSLongitude") { | ||
return __classPrivateFieldGet(this, _ReadTask_lon, "f"); | ||
return __classPrivateFieldGet(this, _ReadTask_lon, "f").call(this); | ||
} | ||
@@ -369,3 +367,3 @@ if (Array.isArray(value)) { | ||
: this.options.backfillTimezones | ||
? __classPrivateFieldGet(this, _ReadTask_tz, "f") | ||
? __classPrivateFieldGet(this, _ReadTask_tz, "f").call(this) | ||
: undefined; | ||
@@ -383,5 +381,6 @@ // Time-only tags have "time" but not "date" in their name: | ||
: undefined)) !== null && _c !== void 0 ? _c : value; | ||
const defaultTz = __classPrivateFieldGet(this, _ReadTask_tz, "f").call(this); | ||
if (this.options.backfillTimezones && | ||
result != null && | ||
__classPrivateFieldGet(this, _ReadTask_tz, "f") != null && | ||
defaultTz != null && | ||
result instanceof ExifDateTime_1.ExifDateTime && | ||
@@ -391,3 +390,3 @@ __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_defaultToUTC).call(this) && | ||
true === result.inferredZone) { | ||
return result.setZone(__classPrivateFieldGet(this, _ReadTask_tz, "f")); | ||
return result.setZone(defaultTz); | ||
} | ||
@@ -394,0 +393,0 @@ return result; |
@@ -56,2 +56,7 @@ import { Zone } from "luxon"; | ||
* Parse a timezone offset and return the offset minutes | ||
* | ||
* @param opts.stripTZA If false, do not strip off the timezone abbreviation | ||
* (TZA) from the value. Defaults to true. | ||
* | ||
* @return undefined if the value cannot be parsed as a valid timezone offset | ||
*/ | ||
@@ -61,3 +66,4 @@ export declare function extractZone(value: any, opts?: { | ||
}): Maybe<TzSrc>; | ||
export declare function extractTzOffsetFromTags(t: Tags): Maybe<TzSrc>; | ||
export declare function incrementZone(z: string | Zone | number, minutes: number): Maybe<Zone>; | ||
export declare function extractTzOffsetFromTags(t: Tags, opts?: Pick<ExifToolOptions, "adjustTimeZoneIfDaylightSavings">): Maybe<TzSrc>; | ||
export declare function extractTzOffsetFromDatestamps(t: Tags, opts: Partial<Pick<ExifToolOptions, "inferTimezoneFromDatestamps" | "inferTimezoneFromDatestampTags">>): Maybe<TzSrc>; | ||
@@ -64,0 +70,0 @@ export declare function extractTzOffsetFromTimeStamp(t: Tags, opts: Partial<Pick<ExifToolOptions, "inferTimezoneFromTimeStamp" | "inferTimezoneFromDatestampTags">>): Maybe<TzSrc>; |
@@ -11,2 +11,3 @@ "use strict"; | ||
exports.extractZone = extractZone; | ||
exports.incrementZone = incrementZone; | ||
exports.extractTzOffsetFromTags = extractTzOffsetFromTags; | ||
@@ -23,2 +24,3 @@ exports.extractTzOffsetFromDatestamps = extractTzOffsetFromDatestamps; | ||
const CapturedAtTagNames_1 = require("./CapturedAtTagNames"); | ||
const DefaultExifToolOptions_1 = require("./DefaultExifToolOptions"); | ||
const ExifDate_1 = require("./ExifDate"); | ||
@@ -239,2 +241,7 @@ const ExifDateTime_1 = require("./ExifDateTime"); | ||
* Parse a timezone offset and return the offset minutes | ||
* | ||
* @param opts.stripTZA If false, do not strip off the timezone abbreviation | ||
* (TZA) from the value. Defaults to true. | ||
* | ||
* @return undefined if the value cannot be parsed as a valid timezone offset | ||
*/ | ||
@@ -326,12 +333,28 @@ function extractZone(value, opts) { | ||
]; | ||
function extractTzOffsetFromTags(t) { | ||
// We have to iterate twice: if it's from a timezone offset tag, we can | ||
// trust it, even if it's UTC. | ||
function incrementZone(z, minutes) { | ||
const norm = normalizeZone(z); | ||
if (norm == null || true !== norm.isUniversal) | ||
return; | ||
const fixed = norm.offset(Date.now()); // < arg doesn't matter, it's universal | ||
return (0, Number_1.isNumber)(fixed) ? luxon_1.FixedOffsetZone.instance(fixed + minutes) : undefined; | ||
} | ||
function extractTzOffsetFromTags(t, opts) { | ||
var _a; | ||
const adjustFn = (_a = opts === null || opts === void 0 ? void 0 : opts.adjustTimeZoneIfDaylightSavings) !== null && _a !== void 0 ? _a : DefaultExifToolOptions_1.defaultAdjustTimeZoneIfDaylightSavings; | ||
for (const tagName of TimezoneOffsetTagnames) { | ||
if (t[tagName] != null) { | ||
const offset = extractZone(t[tagName]); | ||
if (offset != null) { | ||
return { tz: offset.tz, src: tagName }; | ||
} | ||
const offset = extractZone(t[tagName]); | ||
if (offset == null) | ||
continue; | ||
// UGH. See https://github.com/photostructure/exiftool-vendored.js/issues/215 | ||
const minutes = adjustFn(t, offset.tz); | ||
if (minutes != null) { | ||
const adjustedZone = incrementZone(offset.tz, minutes); | ||
if (adjustedZone != null) | ||
return { | ||
tz: adjustedZone.name, | ||
src: tagName + " (adjusted for DaylightSavings)", | ||
}; | ||
} | ||
// No fancy adjustments needed, just return the extracted zone: | ||
return { tz: offset.tz, src: tagName }; | ||
} | ||
@@ -338,0 +361,0 @@ return; |
{ | ||
"name": "exiftool-vendored", | ||
"version": "28.3.1", | ||
"version": "28.4.0", | ||
"description": "Efficient, cross-platform access to ExifTool", | ||
@@ -109,3 +109,3 @@ "main": "./dist/ExifTool.js", | ||
"tmp": "^0.2.3", | ||
"typedoc": "^0.26.7", | ||
"typedoc": "^0.26.8", | ||
"typescript": "^5.6.2", | ||
@@ -112,0 +112,0 @@ "xpath": "^0.0.34" |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
614566
204
10350