Добавить зависимости и тестовые файлы для ExifTool

This commit is contained in:
Dmitriy Fofanov
2026-09-14 10:03:05 +03:00
parent 15e53fb422
commit 1717db9c93
1246 changed files with 734774 additions and 1 deletions
+31
View File
@@ -0,0 +1,31 @@
# macOS
.DS_Store
# Python virtual environments, bytecode and tool caches
.venv/
venv/
__pycache__/
*.py[cod]
*.so
.pytest_cache/
.mypy_cache/
.ruff_cache/
.coverage
coverage.xml
htmlcov/
# Editor and local tooling files
.idea/
.vscode/
# Generated photo-sort reports and local databases
photo-sort-report-*/
photo-sort-summary-*.md
*.sqlite
*.sqlite-*
*.db
*.db-*
*.jsonl
# Archived one-off script from a completed run
photo_sort_[0-9]*.py
+27
View File
@@ -0,0 +1,27 @@
VENV := .venv
PYTHON := $(VENV)/bin/python
.DEFAULT_GOAL := help
.PHONY: help install run test check clean
help: ## Показать доступные команды
@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_-]+:.*##/ {printf "%-12s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
$(PYTHON): requirements.txt
python3 -m venv $(VENV)
$(PYTHON) -m pip install --upgrade pip
$(PYTHON) -m pip install -r requirements.txt
install: $(PYTHON) ## Создать виртуальную среду и установить зависимости
run: $(PYTHON) ## Запустить интерактивное меню приложения
$(PYTHON) photo_sort.py
test: $(PYTHON) ## Запустить автоматические тесты
$(PYTHON) -m unittest -v test_photo_sort.py
check: test ## Проверить проект (сейчас: тесты)
clean: ## Удалить временные Python-файлы и кэши тестов
rm -rf __pycache__ .pytest_cache .mypy_cache .ruff_cache .coverage htmlcov
find . -maxdepth 1 -type f \( -name '*.pyc' -o -name '*.pyo' \) -delete
+115 -1
View File
@@ -1,2 +1,116 @@
# photo-sort
# Сортировка фотографий
Утилита приводит новые фотографии к единой структуре архива, находит дубли и создаёт **план**, который сначала можно проверить вручную. Файлы не перемещаются во время анализа. Перенос начинается только после отдельного подтверждения.
## Состав проекта
- `Сортировка фото.command` — запуск двойным щелчком в macOS.
- `photo_sort.py` — рабочая программа.
- `test_photo_sort.py` — автоматические проверки алгоритма.
- `vendor/exiftool/` — локальная копия ExifTool для чтения метаданных. Это сторонний компонент, поэтому его исходные тексты и лицензия сохранены на исходном языке.
- `photo-sort-report-20260914/`, `photo_sort_20260914.py` и `photo-sort-summary-20260914.md` — архив первой, уже завершённой обработки. Старый скрипт повторно не запускайте.
## Быстрый запуск на Mac
1. Откройте папку проекта и дважды щёлкните `Сортировка фото.command`.
2. В меню выберите `1` — анализ папки.
3. Введите исходную папку с новой партией, обычно:
```text
/Users/fofanovdmitry/Documents/Pictures/FOTO/BACKUP
```
4. Введите папку архива:
```text
/Users/fofanovdmitry/Documents/Pictures/FOTO
```
5. Оставьте дату пустой, чтобы программа читала дату из фотографии. Введите дату только если она достоверно известна для всех выбранных файлов.
6. Для поиска версий одной фотографии в разном сжатии или разрешении ответьте `д` на вопрос о визуальных дублях.
7. После анализа программа покажет путь к новой папке отчёта. Сначала выберите `2` для ручной проверки, затем `3` для просмотра окончательного списка и только потом `4` для переноса.
8. Для фактического переноса введите `ПЕРЕНЕСТИ`.
В первый раз macOS может спросить разрешение Terminal на доступ к папке «Документы». Его нужно разрешить в «Системные настройки → Конфиденциальность и безопасность → Файлы и папки».
## Ручная проверка
Папка отчёта создаётся в `~/.photo-sort/runs/`. В режиме проверки:
- `o` открывает текущую фотографию;
- `w` открывает выбранную основную версию;
- `t` назначает дату вручную и переводит читаемое фото в сортировку;
- `d` переносит файл в `_DEL`;
- `r` переносит файл в `_RAS`;
- `s` оставляет файл на текущем месте;
- Enter показывает следующую строку;
- `q` сохраняет уже внесённые решения и завершает просмотр.
Также можно открыть `review.csv` в Numbers. Сохраняйте CSV в UTF-8 с запятой как разделителем. Не удаляйте строки и не меняйте `id`, `source`, `reason`, `winner`; разрешено менять только `action` и `date`. Действия в таблице технически записываются как `sort`, `del`, `ras`, `skip`, `keep`: первые три означают сортировать, перенести в `_DEL`, перенести в `_RAS`; последние два оставляют файл на месте.
## Алгоритм работы
1. Программа берёт все файлы из исходной папки и сравнивает их с фотографиями архива, включая `_RAS`. Папки `_DEL` и `BACKUP` не участвуют в сравнении.
2. Для каждого изображения программа пытается полностью его декодировать. Поддерживаемые изображения с ошибкой декодирования считаются повреждёнными и направляются в `_DEL`. Не-фотографии, неподдерживаемые форматы и многостраничные изображения направляются в `_RAS`.
3. У читаемой фотографии считываются встроенные поля даты создания контента: EXIF, XMP и IPTC. Время создания или изменения файла в Finder, имя файла и название папки никогда не используются как дата съёмки.
4. Если во встроенных полях одна согласованная дата, фото получает её. Если даты нет или поля противоречат друг другу, файл направляется в `_RAS`. Дата не наследуется от другой версии фотографии. Назначенная вручную дата сохраняется только для того же файла в постоянном каталоге.
5. Поиск дублей проходит в несколько уровней: точный SHA-256 файла, одинаковые декодированные пиксели, а при включённой опции — строгая визуальная проверка миниатюр. Визуальные совпадения следует просматривать вручную.
6. В каждой группе дублей выбирается один лучший вариант: сначала большее разрешение в пикселях, затем больший размер файла в байтах. При полном равенстве предпочтение получает файл, уже находящийся в архиве.
7. Худшие варианты переносятся в `_DEL`. Если лучшая новая версия должна занять имя старой версии, программа сперва надёжно переносит старую в `_DEL`, затем размещает новую на её месте.
8. Основные фотографии размещаются по пути `ГОД/месяц/ДДММГГГГччммсс.ext`, например `2018/октябрь/15102018093000.jpg`. При совпадении имени добавляется `_dub`, затем `_dub2` и так далее.
9. Перед каждым переносом вычисляется SHA-256. Файл копируется без перезаписи, копия проверяется, и лишь затем удаляется исходник. Поэтому для переноса нужен свободный объём хотя бы с размер копируемого файла.
## Постоянная база и последующие партии
База `~/.photo-sort/cache.sqlite` не удаляется автоматически. В ней хранятся кэш декодирования, пути и хеши известных файлов, группы дублей, ручные даты и история переносов. При следующем анализе `BACKUP` программа сверяет базу с реальным состоянием архива: вручную перемещённые или удалённые файлы не считаются действующими оригиналами.
Если новая версия лучше старой, старая отправляется в `_DEL`, а новая занимает её место. Если новая версия хуже, в `_DEL` попадёт новая. Перемещения записываются в `moves.jsonl`, а таблица `history` в постоянной базе сохраняет историю.
Не удаляйте базу без необходимости: при её удалении программе придётся заново проанализировать весь архив. Изменённый файл всё равно проверяется повторно по размеру, inode, времени изменения и SHA-256.
## Командная строка
Команды выполняются из папки проекта:
```bash
.venv/bin/python photo_sort.py analyze \
--source "/Users/fofanovdmitry/Documents/Pictures/FOTO/BACKUP" \
--dest "/Users/fofanovdmitry/Documents/Pictures/FOTO" \
--visual
.venv/bin/python photo_sort.py review "/путь/к/отчёту" --only unresolved
.venv/bin/python photo_sort.py review "/путь/к/отчёту" --only duplicates
.venv/bin/python photo_sort.py show "/путь/к/отчёту"
.venv/bin/python photo_sort.py apply "/путь/к/отчёту"
```
Для одного выбранного файла с известной датой:
```bash
.venv/bin/python photo_sort.py analyze \
--source "/путь/FOTO/_RAS" \
--dest "/путь/FOTO" \
--select "фото.jpg" \
--date "2025-05-20 10:10:20"
```
Другую постоянную базу можно указать параметром `--database "/путь/catalog.sqlite"`.
## Восстановление среды и проверка
Если папка `.venv` отсутствует или Python был обновлён, выполните:
```bash
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python -m unittest -v test_photo_sort.py
```
ExifTool уже находится в `vendor/exiftool`. На macOS изображение открывается через `open`, на Linux — через `xdg-open`.
## Важные ограничения
- RAW, HEIC и AVIF зависят от доступных декодеров; нечитаемые форматы останутся в `_RAS`.
- Изображения больше 100 мегапикселей требуют ручной проверки. Лимит меняется параметром `--max-megapixels`.
- После изменения файла или `review.csv` создайте новый анализ, если план больше не соответствует файлам.
- Старые планы версии с наследованием даты блокируются. Старые отчёты сохранены, но для новых действий создавайте новый анализ.
+566
View File
@@ -0,0 +1,566 @@
#!/usr/bin/env python3
"""Повторяемая сортировка фотографий: анализ, ручная проверка и отдельный перенос."""
import argparse
import base64
import csv
import datetime as dt
import hashlib
import json
import os
from pathlib import Path
import shlex
import shutil
import sqlite3
import subprocess
import sys
import uuid
import warnings
from collections import Counter
from contextlib import contextmanager
import numpy as np
from PIL import Image, ImageOps, UnidentifiedImageError
MONTHS = 'январь февраль март апрель май июнь июль август сентябрь октябрь ноябрь декабрь'.split()
FIELDS = ['id', 'action', 'date', 'source', 'reason', 'winner']
ACTIONS = {'sort', 'del', 'ras', 'skip', 'keep'}
IMAGE_EXT = {'.jpg', '.jpeg', '.png', '.tif', '.tiff', '.bmp', '.webp', '.gif', '.heic', '.heif', '.avif', '.dng', '.nef', '.cr2', '.cr3', '.arw', '.orf', '.rw2', '.psd'}
READABLE_EXT = {'.jpg', '.jpeg', '.png', '.tif', '.tiff', '.bmp', '.webp', '.gif'}
warnings.simplefilter('error', Image.DecompressionBombWarning)
def digest(path):
h = hashlib.sha256()
with Path(path).open('rb') as f:
for chunk in iter(lambda: f.read(1024 * 1024), b''):
h.update(chunk)
return h.hexdigest()
def date_value(value):
if isinstance(value, bytes):
value = value.decode('ascii', 'ignore')
if not isinstance(value, str):
return ''
for fmt in ('%Y:%m:%d %H:%M:%S', '%Y-%m-%d %H:%M:%S', '%Y-%m-%dT%H:%M:%S'):
try:
date = dt.datetime.strptime(value[:19], fmt)
if 1800 <= date.year <= dt.datetime.now().year:
return date.isoformat()
except ValueError:
pass
return ''
def resolve_dates(row, values):
row['date_candidates'] = {k: date_value(v) for k, v in values.items() if date_value(v)}
dates = set(row['date_candidates'].values())
row['date'] = next(iter(dates)) if len(dates) == 1 else ''
row['reason'] = ('дата создания контента из метаданных' if len(dates) == 1 else
'противоречивые даты контента' if dates else 'нет встроенной даты контента')
def inspect(path, cache):
before = path.stat()
sha = digest(path)
if sha in cache:
result = dict(cache[sha])
else:
result = dict(sha=sha, photo=False, reason='не фото или неподдерживаемый формат', date='', pixels=0, width=0, height=0)
if path.suffix.lower() in IMAGE_EXT:
try:
with Image.open(path) as im:
if getattr(im, 'n_frames', 1) > 1:
result['reason'] = 'многостраничное изображение: ручная проверка'
else:
# Ошибочные метаданные сами по себе не делают читаемую фотографию повреждённой.
try:
exif = im.getexif()
nested = exif.get_ifd(34665) if 34665 in exif else {}
values = {'EXIF:DateTimeOriginal': nested.get(36867) or exif.get(36867),
'EXIF:CreateDate': nested.get(36868) or exif.get(36868)}
resolve_dates(result, values)
except (ValueError, SyntaxError, OSError):
pass
im.load()
try:
upright = ImageOps.exif_transpose(im)
except (ValueError, SyntaxError, OSError):
upright = im.copy()
alpha = 'A' in upright.getbands() or 'transparency' in upright.info
pixels = upright.convert('RGBA' if alpha else 'RGB')
rgb = upright.convert('RGB')
small = np.asarray(rgb.resize((9, 8), Image.Resampling.LANCZOS, reducing_gap=3).convert('L'))
bits = (small[:, 1:] > small[:, :-1]).flat
result.update(photo=True,
width=im.width, height=im.height, pixels=im.width * im.height,
pixelsha=hashlib.sha256(str((pixels.size, pixels.mode)).encode() + pixels.tobytes()).hexdigest(),
dh=sum(int(b) << i for i, b in enumerate(bits)), alpha=alpha,
thumb=rgb.resize((64, 64), Image.Resampling.LANCZOS, reducing_gap=3).tobytes())
result['width'], result['height'] = upright.size
except (Image.DecompressionBombError, Image.DecompressionBombWarning):
result['reason'] = 'превышен лимит размера: ручная проверка'
except (UnidentifiedImageError, OSError, SyntaxError, ValueError) as error:
if isinstance(error, OSError) and error.errno is not None:
raise
result['broken'] = path.suffix.lower() in READABLE_EXT
result['reason'] = 'ошибка декодирования: ' + str(error)
cache[sha] = dict(result)
after = path.stat()
if (before.st_size, before.st_mtime_ns) != (after.st_size, after.st_mtime_ns):
raise RuntimeError('Файл изменился при чтении: ' + str(path))
result.update(source=str(path), size=after.st_size, mtime=after.st_mtime_ns)
return result
def walk(root, excluded=()):
def fail(error):
raise error
for folder, dirs, files in os.walk(root, followlinks=False, onerror=fail):
dirs[:] = sorted(d for d in dirs if d not in excluded and not (Path(folder) / d).is_symlink())
for name in sorted(files):
path = Path(folder) / name
if path.is_file() and not path.is_symlink():
yield path
def fingerprint(path):
st = path.stat()
return json.dumps([3, Image.__version__, Image.MAX_IMAGE_PIXELS, st.st_dev, st.st_ino, st.st_size, st.st_mtime_ns, st.st_ctime_ns])
def database(path):
path = Path(path).expanduser().resolve()
path.parent.mkdir(parents=True, exist_ok=True)
db = sqlite3.connect(path, timeout=60)
db.execute('CREATE TABLE IF NOT EXISTS files (path TEXT PRIMARY KEY, signature TEXT, data TEXT)')
db.execute('CREATE TABLE IF NOT EXISTS catalog (archive TEXT, path TEXT, sha TEXT, group_id TEXT, state TEXT, data TEXT, PRIMARY KEY(archive,path))')
db.execute('CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY, run TEXT, source TEXT, target TEXT, sha TEXT, created TEXT)')
db.commit()
return db
def encoded_row(row):
value = dict(row)
if isinstance(value.get('thumb'), bytes):
value['thumb'] = base64.b64encode(value['thumb']).decode('ascii')
return json.dumps(value, ensure_ascii=False)
def remember(db, archive, row, state):
db.execute('INSERT OR REPLACE INTO catalog VALUES (?, ?, ?, ?, ?, ?)',
(archive, row['source'], row['sha'], row['group_id'], state, encoded_row(row)))
def cached_inspect(path, memory, db):
key = fingerprint(path)
cached = db.execute('SELECT signature, data FROM files WHERE path=?', (str(path),)).fetchone()
if cached and cached[0] == key:
row = json.loads(cached[1])
if 'thumb' in row:
row['thumb'] = base64.b64decode(row['thumb'])
return row
row = inspect(path, memory)
encoded = dict(row)
if 'thumb' in encoded:
encoded['thumb'] = base64.b64encode(encoded['thumb']).decode('ascii')
if fingerprint(path) != key:
raise RuntimeError('Файл изменился при анализе: ' + str(path))
db.execute('INSERT OR REPLACE INTO files VALUES (?, ?, ?)', (str(path), key, json.dumps(encoded, ensure_ascii=False)))
return row
def extra_dates(rows, executable):
groups = {}
for row in rows:
if row['photo'] and not row.get('metadata_checked'):
groups.setdefault(row['sha'], []).append(row)
reps = [g[0] for g in groups.values()]
for start in range(0, len(reps), 100):
batch = reps[start:start+100]
command = [executable, '-json', '-G1', '-EXIF:DateTimeOriginal', '-EXIF:CreateDate',
'-XMP-exif:DateTimeOriginal', '-XMP-xmp:CreateDate', '-XMP-photoshop:DateCreated',
'-IPTC:DateCreated', '-IPTC:TimeCreated']
command += [r['source'] for r in batch]
output = subprocess.run(command, capture_output=True, text=True)
if output.returncode not in (0, 1):
raise RuntimeError(output.stderr)
values = {r['SourceFile']: r for r in json.loads(output.stdout)}
for r in batch:
v = values.get(r['source'], {})
dates = dict(r.get('date_candidates', {}))
dates.update({k: value for k, value in v.items() if k.endswith((':DateTimeOriginal', ':CreateDate'))
or k == 'XMP-photoshop:DateCreated'})
if v.get('IPTC:DateCreated') and v.get('IPTC:TimeCreated'):
dates['IPTC:ContentCreated'] = v['IPTC:DateCreated'] + ' ' + v['IPTC:TimeCreated']
for item in groups[r['sha']]:
resolve_dates(item, dates)
item['metadata_checked'] = True
print(f'Метаданные: {min(start+100, len(reps))}/{len(reps)}', flush=True)
def classify(rows, visual):
exact, decoded, buckets = {}, {}, {}
parents = {}
def group(key):
while key in parents:
key = parents[key]
return key
for r in sorted(rows, key=lambda r: (-r['pixels'], -r['size'], not r['existing'], r['source'])):
r['action'] = 'keep' if r['existing'] else ('del' if r.get('broken') else 'ras')
if not r['photo']:
continue
match = exact.get(r['sha']) or decoded.get(r['pixelsha'])
reason = 'одинаковый файл или декодированные пиксели'
if not match and visual and not r['alpha']:
candidates = {}
for b in range(4):
for other in buckets.get((b, (r['dh'] >> (b*16)) & 65535), []):
candidates[other['source']] = other
for other in candidates.values():
if other['alpha'] or (r['dh'] ^ other['dh']).bit_count() > 2:
continue
if abs(r['width']/r['height'] - other['width']/other['height']) > .002:
continue
a = np.frombuffer(r['thumb'], dtype=np.uint8).astype(np.float32)
b = np.frombuffer(other['thumb'], dtype=np.uint8).astype(np.float32)
if min(a.std(), b.std()) >= 12 and np.sqrt(np.mean((a-b)**2)) <= 1.5 and np.quantile(np.abs(a-b), .99) <= 5:
match, reason = other, 'визуальный дубль: проверьте пару'
break
if match:
r.update(action='del', winner=match['source'], reason=reason)
old, new = group(r['group_id']), group(match['group_id'])
if old != new:
parents[old] = new
r['group_id'] = match['group_id']
else:
r['action'] = 'keep' if r['existing'] and r['date'] else ('sort' if r['date'] else 'ras')
exact[r['sha']] = decoded[r['pixelsha']] = r
for b in range(4):
buckets.setdefault((b, (r['dh'] >> (b*16)) & 65535), []).append(r)
for r in rows:
r['group_id'] = group(r['group_id'])
return {key: group(key) for key in parents}
def write_review(run, rows):
temporary = run / 'review.tmp'
with temporary.open('w', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=FIELDS)
writer.writeheader()
for r in rows:
writer.writerow({key: r.get(key, '') for key in FIELDS})
temporary.replace(run / 'review.csv')
def load_review(run):
plan = json.loads((run / 'plan.json').read_text())
if plan.get('version') != 2:
raise ValueError('План создан по старым правилам даты. Выполните новый анализ; старые отчёты сохранены.')
with (run / 'review.csv').open(encoding='utf-8-sig', newline='') as f:
edited = list(csv.DictReader(f))
if len(edited) != len(plan['rows']) or len({r['id'] for r in edited}) != len(edited):
raise ValueError('В review.csv изменён состав строк')
edits = {r['id']: r for r in edited}
for row in plan['rows']:
edit = edits[row['id']]
if edit['source'] != row['source'] or edit['action'] not in ACTIONS:
raise ValueError('Недопустимый путь или действие в CSV')
row['action'] = edit['action']
original_date = row['date']
row['date'] = date_value(edit['date']) if edit['date'] else ''
if row['date'] and row['date'] != original_date:
row['reason'] = 'дата назначена вручную'
row['manual_date'] = row['date']
if edit['date'] and not row['date']:
raise ValueError('Неверная дата: ' + edit['date'])
if row['action'] == 'sort' and (not row['date'] or not row['photo']):
raise ValueError('Для sort нужны читаемое фото и полная дата: ' + row['source'])
return plan
def analyze(args):
source, dest = Path(args.source).expanduser().resolve(), Path(args.dest).expanduser().resolve()
if not source.is_dir() or not dest.is_dir():
raise ValueError('Исходная папка и архив должны существовать')
run = Path(args.run).expanduser().resolve() if args.run else Path.home()/'.photo-sort'/'runs'/(dt.datetime.now().strftime('%Y%m%d-%H%M%S')+'-'+uuid.uuid4().hex[:6])
if run.is_relative_to(source) or run.is_relative_to(dest):
raise ValueError('Папка отчёта должна быть вне исходной папки и архива')
run.mkdir(parents=True, exist_ok=False)
if args.select:
if any((source / p).is_symlink() for p in args.select):
raise ValueError('Символические ссылки не обрабатываются')
paths = sorted({(source / p).resolve() for p in args.select})
if any(not p.is_relative_to(source) or not p.is_file() or p.is_symlink() for p in paths):
raise ValueError('Выбранные файлы должны находиться в исходной папке')
else:
paths = list(walk(source, ('_DEL', '_RAS')))
selected = set(paths)
if not args.no_compare:
paths += [p for p in walk(dest, ('_DEL', 'BACKUP')) if p not in selected and not p.is_relative_to(source)]
cache, rows = {}, []
Image.MAX_IMAGE_PIXELS = args.max_megapixels * 1_000_000
cache_path = Path(args.database).expanduser().resolve()
with database(cache_path) as db:
known = {p: (sha, gid, json.loads(data)) for p, sha, gid, data in db.execute('SELECT path, sha, group_id, data FROM catalog WHERE archive=?', (str(dest),))}
for i, path in enumerate(paths, 1):
row = cached_inspect(path, cache, db)
old = known.get(str(path))
row.update(existing=path not in selected, id=str(i), winner='',
group_id=old[1] if old and old[0] == row['sha'] else row['sha'])
rows.append(row)
if i % 50 == 0 or i == len(paths):
db.commit()
print(f'Проверено: {i}/{len(paths)}', flush=True)
exiftool = args.exiftool or shutil.which('exiftool')
bundled = Path(__file__).parent / 'vendor' / 'exiftool' / 'exiftool'
if not exiftool and bundled.exists():
exiftool = str(bundled)
if exiftool:
extra_dates(rows, exiftool)
else:
print('ExifTool не найден: доступны только основные метаданные Pillow.')
# Сохраняем метаданные до ручных решений: они не должны попадать в кэш декодирования.
with database(cache_path) as db:
for row in rows:
db.execute('UPDATE files SET data=? WHERE path=?', (encoded_row(row), row['source']))
for row in rows:
prior = known.get(row['source'])
if prior and prior[0] == row['sha'] and prior[2].get('manual_date'):
row.update(date=prior[2]['manual_date'], manual_date=prior[2]['manual_date'], reason='ранее назначенная вручную дата этого файла')
if args.date:
date = date_value(args.date)
if not date:
raise ValueError('Дата должна быть YYYY-MM-DD HH:MM:SS')
for row in rows:
if not row['existing'] and row['photo']:
row.update(date=date, manual_date=date, reason='дата назначена вручную')
merges = classify(rows, args.visual)
with database(cache_path) as db:
for old, new in merges.items():
db.execute('UPDATE catalog SET group_id=? WHERE archive=? AND group_id=?', (new, str(dest), old))
for (path,) in db.execute('SELECT path FROM catalog WHERE archive=? AND state != ?', (str(dest), 'missing')).fetchall():
if not Path(path).is_file():
db.execute('UPDATE catalog SET state=? WHERE archive=? AND path=?', ('missing', str(dest), path))
for row in rows:
remember(db, str(dest), row, 'archive' if row['existing'] else 'incoming')
for row in rows:
row.pop('thumb', None)
(run/'plan.json').write_text(json.dumps(dict(version=2, database=str(cache_path), source=str(source), dest=str(dest), rows=rows), ensure_ascii=False, indent=2))
write_review(run, rows)
print('План:', run)
print(dict(Counter(r['action'] for r in rows)))
print('Файлы не перемещены. Команды: review, show, apply.')
return run
def targets(plan):
dest = Path(plan['dest'])
reserved, counters, operations = set(), {}, []
released = {r['source'] for r in plan['rows'] if r['action'] == 'del' and Path(r['source']).parent != dest/'_DEL'}
for r in plan['rows']:
if r['action'] in ('keep', 'skip'):
continue
src = Path(r['source'])
if r['action'] == 'sort':
date = dt.datetime.fromisoformat(r['date'])
target = dest/str(date.year)/MONTHS[date.month-1]/(date.strftime('%d%m%Y%H%M%S') + src.suffix.lower())
else:
target = dest/('_DEL' if r['action']=='del' else '_RAS')/src.name
if target == src:
continue
base, n = target, counters.get(str(target), 1)
while str(target).casefold() in reserved or (target.exists() and str(target) not in released) or target.is_symlink():
target = base.with_name(base.stem + ('_dub' if n==1 else f'_dub{n}') + base.suffix)
n += 1
counters[str(base)] = n
reserved.add(str(target).casefold())
if not target.resolve().is_relative_to(dest):
raise ValueError('Путь назначения выходит за пределы архива')
operations.append(dict(r, target=str(target)))
return sorted(operations, key=lambda r: r['action'] != 'del')
def show(run):
plan = load_review(run)
ops = targets(plan)
print(dict(Counter(r['action'] for r in plan['rows'])))
print(f'Перемещений: {len(ops)}; из существующего архива: {sum(r["existing"] for r in ops)}')
for r in ops[:20]:
print(r['source'], '->', r['target'])
return ops
@contextmanager
def locked(run):
import fcntl
with (run/'operation.lock').open('a') as f:
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
yield
def emit(log, **record):
log.write(json.dumps(record, ensure_ascii=False)+'\n')
log.flush()
os.fsync(log.fileno())
def apply(run, yes=False):
plan = load_review(run)
lockdir = Path(plan['database']).parent/'locks'/hashlib.sha256(plan['dest'].encode()).hexdigest()
lockdir.mkdir(parents=True, exist_ok=True)
with locked(lockdir):
return apply_locked(run, yes)
def record_move(plan, run, row, src, dst):
with database(plan['database']) as db:
cached = db.execute('SELECT data FROM files WHERE path=?', (str(src),)).fetchone()
if cached:
value = json.loads(cached[0])
value.update(source=str(dst), mtime=dst.stat().st_mtime_ns)
db.execute('INSERT OR REPLACE INTO files VALUES (?, ?, ?)', (str(dst), fingerprint(dst), json.dumps(value, ensure_ascii=False)))
db.execute('UPDATE catalog SET state=? WHERE archive=? AND path=?', ('moved', plan['dest'], str(src)))
remember(db, plan['dest'], dict(row, source=str(dst)), 'del' if row['action']=='del' else 'ras' if row['action']=='ras' else 'archive')
db.execute('INSERT INTO history(run,source,target,sha,created) VALUES (?,?,?,?,?)',
(str(run), str(src), str(dst), row['sha'], dt.datetime.now().isoformat()))
def apply_locked(run, yes=False):
with locked(run):
journal = run/'moves.jsonl'
if journal.exists():
raise RuntimeError('Этот запуск уже применялся. Для новой обработки создайте новый план. При сбое проверьте moves.jsonl; исходники незавершённых копий сохранены.')
plan = load_review(run)
ops = show(run)
if not yes and input('Для выполнения введите ПЕРЕНЕСТИ: ').strip() != 'ПЕРЕНЕСТИ':
print('Отменено')
return
# Проверяем и оставляемые оригиналы, чтобы не применить устаревшее решение о дубле.
for r in plan['rows']:
p = Path(r['source'])
if p.is_symlink() or not p.is_file() or p.stat().st_size != r['size'] or digest(p) != r['sha']:
raise RuntimeError('Файл изменён или отсутствует; нужен новый анализ: '+str(p))
with journal.open('x') as log:
for i, r in enumerate(ops, 1):
src, dst = Path(r['source']), Path(r['target'])
if not dst.resolve().is_relative_to(Path(plan['dest'])):
raise RuntimeError('Изменён путь назначения')
dst.parent.mkdir(parents=True, exist_ok=True)
emit(log, state='intent', source=str(src), target=str(dst), sha=r['sha'])
# Эксклюзивное создание работает и между разными дисками, включая exFAT.
# Исходник удаляется только после проверки копии.
with dst.open('xb') as out, src.open('rb') as inp:
shutil.copyfileobj(inp, out, 1024*1024)
out.flush()
os.fsync(out.fileno())
if digest(dst) != r['sha'] or digest(src) != r['sha']:
raise RuntimeError('Проверка копии не прошла; исходник сохранён: '+str(src))
os.utime(dst, ns=(src.stat().st_atime_ns, src.stat().st_mtime_ns))
emit(log, state='verified', source=str(src), target=str(dst), sha=r['sha'])
src.unlink()
record_move(plan, run, r, src, dst)
emit(log, state='done', source=str(src), target=str(dst), sha=r['sha'])
if i % 50 == 0 or i == len(ops):
print(f'Перемещено: {i}/{len(ops)}', flush=True)
print('Готово. Журнал:', journal)
def review(run, only):
with locked(run):
if (run/'moves.jsonl').exists():
raise ValueError('Этот план уже применялся')
plan = load_review(run)
rows = plan['rows']
for r in rows:
if only == 'unresolved' and r['action'] != 'ras':
continue
if only == 'duplicates' and not r['winner']:
continue
while True:
print('\n', r['id'], r['source'], '\n', r['reason'], '\nДата:', r['date'] or 'нет', 'Действие:', r['action'])
answer = input('[o] открыть, [w] оригинал, [t] дата, [d] _DEL, [r] _RAS, [s] пропустить, Enter далее, [q] выход: ').strip().lower()
if answer in ('o', 'w'):
path = r['source'] if answer == 'o' else r['winner']
if path:
subprocess.run(['open' if sys.platform=='darwin' else 'xdg-open', path], check=False)
elif answer == 't':
value = date_value(input('Дата YYYY-MM-DD HH:MM:SS: '))
if value and r['photo']:
r.update(date=value, action='sort')
write_review(run, rows)
else:
print('Нужны полная дата и читаемое фото.')
elif answer in ('d', 'r', 's'):
r['action'] = {'d':'del','r':'ras','s':'skip'}[answer]
write_review(run, rows)
break
elif answer == 'q':
return
elif not answer:
break
def main(argv=None):
parser = argparse.ArgumentParser(description='Сортировка фото: анализ -> ручная проверка -> перенос. Без удаления содержимого.')
commands = parser.add_subparsers(dest='command', required=True)
p = commands.add_parser('analyze', help='Создать новый план, не перемещая файлы')
p.add_argument('--source', required=True); p.add_argument('--dest', required=True)
p.add_argument('--select', nargs='+', help='Только выбранные файлы внутри source')
p.add_argument('--date', help='Назначить выбранным фото YYYY-MM-DD HH:MM:SS')
p.add_argument('--run', help='Новая папка отчёта вне source и dest')
p.add_argument('--visual', action='store_true', help='Также искать визуальные дубли; затем проверьте review --only duplicates')
p.add_argument('--no-compare', action='store_true', help='Не сравнивать с существующим архивом')
p.add_argument('--exiftool'); p.add_argument('--max-megapixels', type=int, default=100)
p.add_argument('--database', default=str(Path.home()/'.photo-sort'/'cache.sqlite'), help='Постоянная база, не удаляется между запусками')
for name in ('review', 'show', 'apply'):
p = commands.add_parser(name)
p.add_argument('run', type=lambda s: Path(s).expanduser().resolve())
if name=='review': p.add_argument('--only', choices=['unresolved','duplicates','all'], default='unresolved')
if name=='apply': p.add_argument('--yes', action='store_true', help='Подтвердить перенос без вопроса')
args = parser.parse_args(argv)
if args.command=='analyze': return analyze(args)
if args.command=='review': return review(args.run, args.only)
if args.command=='show': return show(args.run)
if args.command=='apply': return apply(args.run, args.yes)
def menu():
while True:
print('\nФото: 1 анализ папки, 2 ручная проверка, 3 показать план, 4 выполнить перенос, 0 выход')
choice = input('> ').strip()
if choice=='0': return
if choice=='1':
source = input('Исходная папка (можно _RAS): ').strip().strip('"\'')
dest = input('Архив FOTO: ').strip().strip('"\'')
date = input('Дата для всех выбранных фото (Enter = метаданные): ').strip()
selected = shlex.split(input('Имена выбранных файлов в кавычках (Enter = вся папка): '))
argv = ['analyze','--source',source,'--dest',dest]
if date: argv += ['--date',date]
if selected: argv += ['--select',*selected]
if input('Искать визуальные дубли? [д/Н]: ').lower()=='д': argv += ['--visual']
elif choice in ('2','3','4'):
run = input('Папка отчёта: ').strip().strip('"\'')
argv = [{'2':'review','3':'show','4':'apply'}[choice],run]
if choice=='2':
group = input('1 без даты/неразобранные, 2 дубли, 3 весь план [1]: ').strip()
argv += ['--only', {'2':'duplicates','3':'all'}.get(group, 'unresolved')]
else:
continue
try:
main(argv)
except (OSError, ValueError, RuntimeError, KeyError) as error:
print('Ошибка:', error)
if __name__ == '__main__':
try:
menu() if len(sys.argv)==1 else main()
except KeyboardInterrupt:
print('\nОстановлено. План и журнал сохранены, если были созданы.')
sys.exit(130)
except EOFError:
print('\nВыход')
except (OSError, ValueError, RuntimeError, KeyError) as error:
print('Ошибка:', error, file=sys.stderr)
sys.exit(1)
+2
View File
@@ -0,0 +1,2 @@
Pillow>=10.0,<13
numpy>=1.24,<3
+206
View File
@@ -0,0 +1,206 @@
import contextlib
import io
import json
from pathlib import Path
import tempfile
import sqlite3
import unittest
from unittest.mock import patch
import numpy as np
from PIL import Image
import photo_sort as s
class SortTests(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
self.base = Path(self.tmp.name).resolve()
self.source = self.base/'incoming'
self.dest = self.base/'archive'
self.source.mkdir(); self.dest.mkdir()
self.run = self.base/'run'
def tearDown(self):
self.tmp.cleanup()
def photo(self, path, seed=1, date=True, size=(160,120)):
image = Image.fromarray(np.random.default_rng(seed).integers(0,256,(size[1],size[0],3),dtype=np.uint8))
exif = Image.Exif()
if date: exif[36867]='2025:05:20 10:10:20'
image.save(path, exif=exif)
def analyze(self, *extra):
with contextlib.redirect_stdout(io.StringIO()):
s.main(['analyze','--source',str(self.source),'--dest',str(self.dest),'--run',str(self.run),'--database',str(self.base/'catalog.sqlite'),*extra])
return s.load_review(self.run)
def apply(self):
with contextlib.redirect_stdout(io.StringIO()):
s.apply(self.run, yes=True)
def test_dry_run_collisions_and_repeat(self):
self.photo(self.source/'one.jpg')
self.photo(self.source/'two.jpg',seed=2)
self.photo(self.source/'copy.jpg')
self.analyze()
self.assertEqual(len(list(self.source.iterdir())),3)
self.apply()
self.assertEqual(len(list(self.source.iterdir())),0)
names={p.name for p in (self.dest/'2025'/'май').iterdir()}
self.assertEqual(names,{'20052025101020.jpg','20052025101020_dub.jpg'})
self.assertEqual(len(list((self.dest/'_DEL').iterdir())),1)
with self.assertRaises(RuntimeError): self.apply()
self.run=self.base/'run2'
plan=self.analyze()
self.assertFalse(s.targets(plan))
def test_stale_source_and_retained_original(self):
self.photo(self.source/'one.jpg')
self.photo(self.dest/'existing.jpg',seed=2)
self.analyze()
(self.dest/'existing.jpg').write_bytes(b'changed')
with self.assertRaises(RuntimeError): self.apply()
self.assertTrue((self.source/'one.jpg').exists())
self.assertFalse((self.run/'moves.jsonl').exists())
def test_manual_date_and_nonphotos(self):
self.photo(self.source/'undated.jpg',date=False)
(self.source/'notes.txt').write_text('hello')
(self.source/'broken.jpg').write_bytes(b'not a valid JPEG')
plan=self.analyze()
row=next(r for r in plan['rows'] if r['photo'])
self.assertEqual(row['action'],'ras')
row.update(action='sort',date='2026-01-02T03:04:05')
s.write_review(self.run,plan['rows'])
self.apply()
self.assertTrue((self.dest/'2026'/'январь'/'02012026030405.jpg').exists())
self.assertTrue((self.dest/'_RAS'/'notes.txt').exists())
self.assertTrue((self.dest/'_DEL'/'broken.jpg').exists())
def test_bigger_resolution_replaces_existing(self):
y,x=np.mgrid[:480,:640]
pixels=np.stack([128+60*np.sin(x/30),128+60*np.cos(y/33),128+60*np.sin((x+y)/45)],axis=2).astype('uint8')
image=Image.fromarray(pixels);exif=Image.Exif();exif[36867]='2025:05:20 10:10:20'
image.save(self.source/'large.jpg',quality=98,exif=exif)
image.resize((320,240)).save(self.dest/'small.jpg',quality=95,exif=exif)
plan=self.analyze('--visual')
small=next(r for r in plan['rows'] if r['existing'])
self.assertEqual(small['action'],'del')
self.assertTrue(small['winner'].endswith('large.jpg'))
self.apply()
self.assertTrue((self.dest/'_DEL'/'small.jpg').exists())
def test_ras_explicit_source_and_selection(self):
self.source=self.dest/'_RAS';self.source.mkdir()
self.photo(self.source/'first.jpg',date=False)
self.photo(self.source/'second.jpg',date=False)
plan=self.analyze('--select','first.jpg','--date','2025-05-20 10:10:20')
self.assertEqual(len(plan['rows']),1)
self.apply()
self.assertTrue((self.source/'second.jpg').exists())
self.assertFalse((self.source/'first.jpg').exists())
def test_alpha_is_not_lost(self):
a=Image.new('RGBA',(20,20),(20,30,40,0))
b=Image.new('RGBA',(20,20),(20,30,40,255))
a.save(self.source/'a.png');b.save(self.source/'b.png')
plan=self.analyze('--visual')
self.assertTrue(all(r['action']=='ras' for r in plan['rows']))
def test_existing_ras_matches_new_batch(self):
ras = self.dest/'_RAS'
ras.mkdir()
self.photo(ras/'original.jpg', date=False)
self.photo(self.source/'duplicate.jpg', date=False)
plan = self.analyze()
incoming = next(r for r in plan['rows'] if not r['existing'])
self.assertEqual(incoming['action'], 'del')
self.assertEqual(incoming['winner'], str(ras/'original.jpg'))
self.apply()
self.assertTrue((ras/'original.jpg').exists())
self.assertTrue((self.dest/'_DEL'/'duplicate.jpg').exists())
def test_new_destination_never_overwrites(self):
self.photo(self.source/'one.jpg')
self.analyze()
d=self.dest/'2025'/'май';d.mkdir(parents=True)
original=d/'20052025101020.jpg';original.write_bytes(b'keep me')
self.apply()
self.assertEqual(original.read_bytes(),b'keep me')
self.assertTrue((d/'20052025101020_dub.jpg').exists())
def test_cache_invalidates_changed_file(self):
path=self.source/'photo.jpg';self.photo(path)
with sqlite3.connect(':memory:') as db:
db.execute('CREATE TABLE files (path TEXT PRIMARY KEY, signature TEXT, data TEXT)')
with patch.object(s,'inspect',wraps=s.inspect) as spy:
first=s.cached_inspect(path,{},db)
second=s.cached_inspect(path,{},db)
self.assertEqual(first['sha'],second['sha'])
self.assertEqual(spy.call_count,1)
self.photo(path,seed=12)
third=s.cached_inspect(path,{},db)
self.assertNotEqual(first['sha'],third['sha'])
self.assertEqual(spy.call_count,2)
def test_no_date_inheritance(self):
self.photo(self.source/'large.jpg', date=False)
# Те же декодированные пиксели, но меньший файл со своей датой.
a=s.inspect(self.source/'large.jpg',{})
b=dict(a,source=str(self.dest/'old.jpg'),size=a['size']-1,date='2012-01-01T12:00:00',sha='different')
a.update(existing=False,id='1',group_id='new',winner='')
b.update(existing=True,id='2',group_id='old',winner='')
s.classify([a,b],True)
self.assertEqual(a['date'],'')
self.assertEqual(a['action'],'ras')
self.assertEqual(b['action'],'del')
self.assertEqual(a['group_id'],b['group_id'])
def test_conflicting_embedded_dates(self):
row={}
s.resolve_dates(row,{'EXIF:CreateDate':'2018:10:15 09:30:16','EXIF:DateTimeOriginal':'2012:08:28 18:47:41'})
self.assertEqual(row['date'],'')
self.assertEqual(len(row['date_candidates']),2)
def test_replacement_updates_catalog_and_reuses_name(self):
self.photo(self.source/'first.jpg')
self.analyze(); self.apply()
original=self.dest/'2025'/'май'/'20052025101020.jpg'
original_sha=s.digest(original)
# Дополнительные байты не меняют пиксели JPEG, но увеличивают входящий файл.
(self.source/'better.jpg').write_bytes(original.read_bytes()+b'extra bytes')
self.run=self.base/'run2';plan=self.analyze()
ops=s.targets(plan)
self.assertEqual(ops[-1]['target'],str(original))
self.apply()
self.assertNotEqual(s.digest(original),original_sha)
self.assertTrue((self.dest/'_DEL'/'20052025101020.jpg').exists())
with sqlite3.connect(self.base/'catalog.sqlite') as db:
live=db.execute("SELECT path,group_id,state FROM catalog WHERE state IN ('archive','del')").fetchall()
self.assertEqual(len({r[1] for r in live}),1)
self.assertEqual(db.execute('SELECT count(*) FROM history').fetchone()[0],3)
self.assertEqual(db.execute('SELECT sha FROM catalog WHERE path=?',(str(original),)).fetchone()[0],s.digest(original))
def test_manually_moved_original_is_reconciled(self):
self.photo(self.source/'first.jpg');self.analyze();self.apply()
original=self.dest/'2025'/'май'/'20052025101020.jpg'
renamed=original.with_name('manual.jpg');original.rename(renamed)
(self.source/'copy.jpg').write_bytes(renamed.read_bytes())
self.run=self.base/'run2';plan=self.analyze()
incoming=next(r for r in plan['rows'] if not r['existing'])
self.assertEqual(incoming['action'],'del')
self.assertEqual(incoming['winner'],str(renamed))
renamed.unlink()
self.run=self.base/'run3';plan=self.analyze()
self.assertEqual(plan['rows'][0]['action'],'sort')
def test_catalog_matches_ras_and_retains_manual_date(self):
self.photo(self.source/'first.jpg',date=False)
self.analyze('--date','2018-10-15 09:30:16');self.apply()
self.run=self.base/'run2';plan=self.analyze()
self.assertEqual(plan['rows'][0]['date'],'2018-10-15T09:30:16')
self.assertEqual(plan['rows'][0]['action'],'keep')
if __name__=='__main__': unittest.main()
+11998
View File
File diff suppressed because it is too large Load Diff
+1240
View File
File diff suppressed because it is too large Load Diff
+55
View File
@@ -0,0 +1,55 @@
{
"abstract" : "Read and write meta information",
"author" : [
"Phil Harvey (philharvey66 at gmail.com)"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter version 2.150010",
"license" : [
"perl_5"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : 2
},
"name" : "Image-ExifTool",
"no_index" : {
"directory" : [
"t",
"inc"
]
},
"prereqs" : {
"build" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
"recommends" : {
"Archive::Zip" : "0",
"Compress::Raw::Lzma" : "0",
"Compress::Zlib" : "0",
"Digest::MD5" : "0",
"Digest::SHA" : "0",
"IO::Compress::Brotli" : "0",
"IO::Compress::RawDeflate" : "0",
"IO::Uncompress::Brotli" : "0",
"IO::Uncompress::RawInflate" : "0",
"POSIX::strptime" : "0",
"Time::HiRes" : "0"
},
"requires" : {
"perl" : "5.004"
}
}
},
"release_status" : "stable",
"version" : "13.59",
"x_serialization_backend" : "JSON::PP version 4.06"
}
+35
View File
@@ -0,0 +1,35 @@
---
abstract: 'Read and write meta information'
author:
- 'Phil Harvey (philharvey66 at gmail.com)'
build_requires:
ExtUtils::MakeMaker: '0'
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter version 2.150010'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: '1.4'
name: Image-ExifTool
no_index:
directory:
- t
- inc
recommends:
Archive::Zip: '0'
Compress::Raw::Lzma: '0'
Compress::Zlib: '0'
Digest::MD5: '0'
Digest::SHA: '0'
IO::Compress::Brotli: '0'
IO::Compress::RawDeflate: '0'
IO::Uncompress::Brotli: '0'
IO::Uncompress::RawInflate: '0'
POSIX::strptime: '0'
Time::HiRes: '0'
requires:
perl: '5.004'
version: '13.59'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
+59
View File
@@ -0,0 +1,59 @@
use ExtUtils::MakeMaker;
use File::Spec;
my $ExifTool_pm = File::Spec->catfile('lib', 'Image', 'ExifTool.pm');
my $ExifTool_pod = File::Spec->catfile('lib', 'Image', 'ExifTool.pod');
WriteMakefile(
NAME => 'Image::ExifTool',
VERSION_FROM => $ExifTool_pm,
PREREQ_PM => { },
(($ExtUtils::MakeMaker::VERSION gt '6.31' and
$ExtUtils::MakeMaker::VERSION lt '6.46') ?
(EXTRA_META => "recommends:\n" .
" Archive::Zip: 0\n" .
" Compress::Zlib: 0\n" .
" Digest::MD5: 0\n" .
" Digest::SHA: 0\n" .
" Time::HiRes: 0\n" .
" POSIX::strptime: 0\n" .
" Compress::Raw::Lzma: 0\n" .
" IO::Compress::RawDeflate: 0\n" .
" IO::Uncompress::RawInflate: 0\n" .
" IO::Compress::Brotli: 0\n" .
" IO::Uncompress::Brotli: 0\n",
# (not worth recommending -- only for column alignment of some languages)
# " Unicode::LineBreak: 0\n",
# (not worth recommending -- only for Rawzor files)
# " IO::Compress::Bzip2: 0\n",
) : ()),
($ExtUtils::MakeMaker::VERSION ge '6.46' ?
(META_MERGE => {
recommends => {
'Archive::Zip' => 0,
'Compress::Zlib' => 0,
'Digest::MD5' => 0,
'Digest::SHA' => 0,
'Time::HiRes' => 0,
'POSIX::strptime' => 0,
'Compress::Raw::Lzma' => 0,
'IO::Compress::RawDeflate' => 0,
'IO::Uncompress::RawInflate' => 0,
'IO::Compress::Brotli' => 0,
'IO::Uncompress::Brotli' => 0,
# 'Unicode::LineBreak' => 0,
# 'IO::Compress::Bzip2' => 0,
},
} ) : ()),
clean => { FILES => 't/*.tmp' },
dist => { TAR => 'gtar' },
EXE_FILES => [ 'exiftool' ],
($] >= 5.005 ?
(ABSTRACT_FROM => $ExifTool_pod,
AUTHOR => 'Phil Harvey (philharvey66 at gmail.com)',
) : ()),
(($ExtUtils::MakeMaker::VERSION gt '6.30') ?
(LICENSE => 'perl') : ()),
(($ExtUtils::MakeMaker::VERSION ge '6.47') ?
(MIN_PERL_VERSION => '5.004') : ()),
);
+270
View File
@@ -0,0 +1,270 @@
ExifTool by Phil Harvey (philharvey66 at gmail.com)
----------------------------------------------------------------------------
ExifTool is a customizable set of Perl modules plus a full-featured
command-line application for reading and writing meta information in a wide
variety of files, including the maker note information of many digital
cameras by various manufacturers such as Canon, Casio, DJI, FLIR, FujiFilm,
GE, HP, JVC/Victor, Kodak, Leaf, Minolta/Konica-Minolta, Nikon, Nintendo,
Olympus/Epson, Panasonic/Leica, Pentax/Asahi, Phase One, Reconyx, Ricoh,
Samsung, Sanyo, Sigma/Foveon and Sony.
Below is a list of file types and meta information formats currently
supported by ExifTool (r = read, w = write, c = create):
File Types
------------+-------------+-------------+-------------+------------
360 r/w | DR4 r/w/c | JNG r/w | ODP r | RTF r
3FR r | DSF r | JP2 r/w | ODS r | RW2 r/w
3G2 r/w | DSS r | JPEG r/w | ODT r | RWL r/w
3GP r/w | DV r | JSON r | OFR r | RWZ r
7Z r | DVB r/w | JXL r/w | OGG r | RM r
A r | DVR-MS r | K25 r | OGV r | SEQ r
AA r | DYLIB r | KDC r | ONP r | SKETCH r
AAC r | EIP r | KEY r | OPUS r | SO r
AAE r | EPS r/w | KVAR r | ORF r/w | SR2 r/w
AAX r/w | EPUB r | LA r | ORI r/w | SRF r
ACR r | ERF r/w | LFP r | OTF r | SRW r/w
AFM r | EXE r | LIF r | PAC r | SVG r
AI r/w | EXIF r/w/c | LNK r | PAGES r | SWF r
AIFF r | EXR r | LRV r/w | PBM r/w | THM r/w
APE r | EXV r/w/c | M2TS r | PCAP r | TIFF r/w
ARQ r/w | F4A/V r/w | M4A/V r/w | PCAPNG r | TNEF r
ARW r/w | FFF r/w | MACOS r | PCD r | TORRENT r
ASF r | FIT r | MAX r | PCX r | TTC r
AVI r | FITS r | MEF r/w | PDB r | TTF r
AVIF r/w | FLA r | MIE r/w/c | PDF r/w | TXT r
AZW r | FLAC r | MIFF r | PEF r/w | URL r
BMP r | FLIF r/w | MKA r | PFA r | VCF r
BPG r | FLV r | MKS r | PFB r | VNT r
BTF r | FPF r | MKV r | PFM r | VRD r/w/c
C2PA r | FPX r | MNG r/w | PGF r | VSD r
CHM r | GIF r/w | MOBI r | PGM r/w | VSDX r
COS r | GLV r/w | MODD r | PLIST r | WAV r
CR2 r/w | GPR r/w | MOI r | PICT r | WDP r/w
CR3 r/w | GZ r | MOS r/w | PMP r | WEBP r/w
CRM r/w | HDP r/w | MOV r/w | PNG r/w | WEBM r
CRW r/w | HDR r | MP3 r | PPM r/w | WMA r
CS1 r/w | HEIC r/w | MP4 r/w | PPT r | WMV r
CSV r | HEIF r/w | MPC r | PPTX r | WOFF r
CUR r | HTML r | MPG r | PS r/w | WOFF2 r
CZI r | ICC r/w/c | MPO r/w | PSB r/w | WPG r
DCM r | ICO r | MQV r/w | PSD r/w | WTV r
DCP r/w | ICS r | MRC r | PSP r | WV r
DCR r | IDML r | MRW r/w | QTIF r/w | X3F r/w
DFONT r | IIQ r/w | MXF r | R3D r | XCF r
DIVX r | IND r/w | NEF r/w | RA r | XISF r
DJVU r | INSP r/w | NKA r | RAF r/w | XLS r
DLL r | INSV r | NKSC r/w | RAM r | XLSX r
DNG r/w | INX r | NRW r/w | RAR r | XMP r/w/c
DOC r | ISO r | NUMBERS r | RAW r/w | ZIP r
DOCX r | ITC r | NXD r | RIFF r |
DPX r | J2C r | O r | RSRC r |
Meta Information
----------------------+----------------------+---------------------
EXIF r/w/c | CIFF r/w | Ricoh RMETA r
GPS r/w/c | AFCP r/w | Picture Info r
IPTC r/w/c | Kodak Meta r/w | Adobe APP14 r
XMP r/w/c | FotoStation r/w | MPF r
MakerNotes r/w/c | PhotoMechanic r/w | Stim r
Photoshop IRB r/w/c | JPEG 2000 r | DPX r
ICC Profile r/w/c | DICOM r | APE r
MIE r/w/c | Flash r | Vorbis r
JFIF r/w/c | FlashPix r | SPIFF r
Ducky APP12 r/w/c | QuickTime r | DjVu r
PDF r/w/c | Matroska r | M2TS r
PNG r/w/c | MXF r | PE/COFF r
Canon VRD r/w/c | PrintIM r | AVCHD r
Nikon Capture r/w/c | FLAC r | ZIP r
GeoTIFF r/w/c | ID3 r | (and more)
See html/index.html for more details about ExifTool features.
ExifTool can be downloaded from
https://exiftool.org/
RUNNING
The exiftool script can be run right away without the need to install
Image::ExifTool. For example, from within the exiftool directory you can
extract the information from one of the included test files by typing:
./exiftool t/images/ExifTool.jpg
If you move the exiftool script to a different directory, you must also
either move the contents of the lib directory or install the Image::ExifTool
package so the script can find the necessary libraries.
Note: If you are using the Windows cmd shell, you may need to rename
'exiftool' to 'exiftool.pl' to run it directly from the command line.
Alternatively, you can run exiftool with the command 'perl exiftool'.
IF YOU ARE STILL CONFUSED
The exiftool script is a command line application. You run it by typing
commands in a terminal window. The first step is to determine the name of
the directory where you downloaded the ExifTool distribution package.
Assuming, for example, you downloaded it to a folder called "Desktop" in
your home directory, then you would type the following commands in a
terminal window to extract and run ExifTool:
cd ~/Desktop
gzip -dc Image-ExifTool-13.59.tar.gz | tar -xf -
cd Image-ExifTool-13.59
./exiftool t/images/ExifTool.jpg
Note: These commands extract meta information from one of the test images.
To use one of your images instead, enter the full path name of your file in
place of "t/images/ExifTool.jpg".
INSTALLATION
You can install the Image::ExifTool package to make it available for use by
other Perl scripts by typing the following:
perl Makefile.PL
make
make test
make install
Notes:
i) You need root access for the last step above.
ii) Some Perl installations (like the standard OSX installation) may not
contain the necessary files to complete the first step above. But no
worries: You can install ExifTool manually by moving 'exiftool' and the
'lib' directory to any directory in your current PATH (ie. /usr/bin).
iii) In Windows, "dmake" or "nmake" may be used if "make" is not
available.
(Also see html/install.html for more help with installation.)
DEPENDENCIES
Requires Perl version 5.004 or later. No other special libraries are
required, however the following modules are recommended for decoding
compressed and/or encrypted information from the indicated file types, and
for calculating digest values and providing other features listed below:
Archive::Zip (ZIP, DOCX, PPTX, XLSX, ODP, ODS, ODT, EIP, iWork)
Compress::Zlib (DNG, PNG, PDF, DCM, MIE and SWF files)
Digest::MD5 (PDF files, IPTC information, and JPG Extended XMP)
Digest::SHA (PDF with AES-256 encryption)
IO::Compress::Bzip2 (RWZ files)
Time::HiRes (for generating ProcessingTime tag)
POSIX::strptime (for inverse date/time conversion)
Time::Piece (alternative to POSIX::strptime)
Unicode::LineBreak (for column alignment of alternate-language output)
Win32::API (for proper handling of Windows file names/times)
Win32::FindFile (for Windows Unicode directory support, app only)
Win32API::File (for Windows Unicode file names and file times)
File::StatX (for reading FileCreateDate on Linux systems)
Compress::Raw::Lzma (for reading encoded 7z files)
IO::Compress::RawDeflate (for writing FLIF images)
IO::Uncompress::RawInflate (for reading FLIF images)
IO::Compress::Brotli (for writing compressed JXL metadata)
IO::Uncompress::Brotli (for reading compressed JXL metadata)
COPYRIGHT AND LICENSE
Copyright 2003-2026, Phil Harvey
This is free software; you can redistribute it and/or modify it under the
same terms as Perl itself (either the Perl Artistic License or GPL).
DISTRIBUTION FILES
Below is a list of the files/directories included in the full ExifTool
distribution package:
Changes - Revision history
MANIFEST - Full list of distribution files
META.json - Standard CPAN dependency file (JSON format)
META.yml - Standard CPAN dependency file (YAML format)
Makefile.PL - Makefile for installation
README - This file
arg_files/ - Argument files to convert metadata formats:
exif2iptc.args - Arguments for converting EXIF to IPTC
exif2xmp.args - Arguments for converting EXIF to XMP
gps2xmp.args - Arguments for converting GPS to XMP
iptc2exif.args - Arguments for converting IPTC to EXIF
iptc2xmp.args - Arguments for converting IPTC to XMP
iptcCore.args - Complete list of IPTC Core XMP tags
pdf2xmp.args - Arguments for converting PDF to XMP
xmp2exif.args - Arguments for converting XMP to EXIF
xmp2gps.args - Arguments for converting XMP to GPS
xmp2iptc.args - Arguments for converting XMP to IPTC
xmp2pdf.args - Arguments for converting XMP to PDF
build_geolocation - Build custom Geolocation database
config_files/ - Sample ExifTool configuration files:
acdsee.config - Definitions for writing ACDSee XMP regions
age.config - Calculate Age of person in photo
bibble.config - Definitions for writing Bibble XMP tags
convert_regions.config - Convert between MWG, MP and IPTC regions
cuepointlist.config - Extract cue points and labels as a list
depthmap.config - Extract Google DepthMap images
example.config - General example showing config features
fotoware.config - Definitions for writing Fotoware XMP tags
frameCount.config - Extract FrameCount from MP4 videos
gps2utm.config - Generate UTM coordinate tags from GPS info
guano.config - Decode individual tags from Guano metadata
local_time.config - Determine local time from GPS information
nksc.config - Decode tags in Nikon ViewNX NKSC files
novelty.config - Definitions for XMP Novelty Theory tags
onone.config - Definitions for writing On1 XMP tags
photoshop_paths.config - For extracting or copying Photoshop paths
picasa_faces.config - Convert from Picasa to MWG/MP face regions
pix4d.config - Definitions for writing Pix4D XMP tags
rotate_regions.config - Rotate MWG and MP region tags
tiff_version.config - Determine the version of a TIFF file
time_zone.config - Calculate time zone from EXIF tags
exiftool - The exiftool application (Perl script)
fmt_files/ - Output formatting example files:
gpx.fmt - Format file for creating GPX track
gpx_wpt.fmt - Format file for creating GPX waypoints
kml.fmt - Format file for creating KML placemarks
kml_track.fmt - Format file for creating KML track
html/ - HTML documentation
html/TagNames/ - HTML tag name documentation
lib/ - ExifTool Perl library modules
perl-Image-ExifTool.spec - Red Hat Packaging Manager specification file
t/ - Verification test code
t/images/ - Verification test images
ADDITIONAL INFORMATION
Read the following files included in the full distribution for more
information:
html/index.html - Main ExifTool documentation
html/install.html - Installation instructions
html/history.html - Revision history
html/ExifTool.html - API documentation
html/TagNames/index.html - Tag name documentation
html/geotag.html - Geotag feature
html/geolocation.html - Geolocation feature
html/faq.html - Frequently asked questions
html/filename.html - Renaming/moving files
html/metafiles.html - Working with metadata sidecar files
html/struct.html - Working with structured XMP information
lib/Image/ExifTool/README - ExifTool library modules documentation
and if you have installed Image::ExifTool, you can also consult perldoc or
the man pages:
perldoc exiftool
perldoc Image::ExifTool
perldoc Image::ExifTool::TagNames
man exiftool
man Image::ExifTool
man Image::ExifTool::TagNames
Note: If the man pages don't work, it is probably because your man path is
not set to include the installed documentation. See "man man" for
information about how to set the man path.
----------------------------------------------------------------------------
+31
View File
@@ -0,0 +1,31 @@
#------------------------------------------------------------------------------
# File: exif2iptc.args
#
# Description: Tag name translations for converting EXIF to IPTC
#
# Usage: exiftool -tagsFromFile SRCFILE -@ exif2iptc.args DSTFILE
#
# Requires: ExifTool version 6.51 or later
#
# Revisions: 2011/09/13 - P. Harvey Created
# 2017/07/06 - PH Set time zone from new EXIF OffsetTime tags
#
# Notes: 1) IPTC requires a timezone but EXIF does not support one, so
# the local timezone is assumed when writing the IPTC times
#
# 2) These arguments will not delete existing IPTC tags which are
# missing from the EXIF. The IPTC tags should be deleted
# beforehand if required.
#------------------------------------------------------------------------------
-IPTC:By-line < EXIF:Artist
-IPTC:CopyrightNotice < EXIF:Copyright
-IPTC:Caption-Abstract < EXIF:ImageDescription
# the inverse IPTC date and time conversions automagically pull the
# appropriate date or time part out of the EXIF date/time value
-IPTC:DateCreated < EXIF:DateTimeOriginal
-IPTC:TimeCreated < EXIF:DateTimeOriginal
-IPTC:TimeCreated < Composite:SubSecDateTimeOriginal
-IPTC:DigitalCreationDate < EXIF:CreateDate
-IPTC:DigitalCreationTime < EXIF:CreateDate
-IPTC:DigitalCreationTime < Composite:SubSecCreateDate
# end
+62
View File
@@ -0,0 +1,62 @@
#------------------------------------------------------------------------------
# File: exif2xmp.args
#
# Description: Tag name translations for converting EXIF to XMP
#
# Usage: exiftool -tagsFromFile SRCFILE -@ exif2xmp.args DSTFILE
#
# Requires: ExifTool version 10.96 or later
#
# Revisions: 2009/01/20 - P. Harvey Created
# 2011/06/22 - PH Copy flash information via Composite:Flash
# 2013/06/12 - PH Additions for the Exif 2.3 for XMP spec
# 2015/01/12 - PH Avoid copying to non-standard namespaces
# 2018/05/07 - PH Added support for GPSDestXxxRef tags
# 2022/03/31 - PH IPTC Photometadata Mapping Guidelines 2202.1 update
# 2024/10/24 - PH Additions for the 2024 EXIF for XMP spec
# 2025/01/16 - PH Copy Composite SubSec tags to XMP-exif
# 2025-04-22 - PH Fixed DigitalImageGUID source tag
#
# References: http://www.metadataworkinggroup.org/specs/
# https://iptc.org/std/photometadata/documentation/mappingguidelines/
#
# Notes: 1) The first three arguments copy most of the EXIF and GPS tags to
# XMP-exif/XMP-tiff, and the remaining arguments handle tags
# which have different names and/or formats in EXIF and XMP.
#
# 2) These arguments will not delete existing XMP tags which are
# missing from the EXIF. The XMP tags should be deleted
# beforehand if required.
#
# 3) EXIF:SubjectArea is not currently mapped into XMP-iptcExt:ImageRegion
#------------------------------------------------------------------------------
-XMP-exif:all < EXIF:all
-XMP-exifEX:all < EXIF:all
-XMP-tiff:all < EXIF:all
-XMP-dc:Description < EXIF:ImageDescription
# overwrite date/time values to include sub-second information if available
-XMP-photoshop:DateCreated < EXIF:DateTimeOriginal
-XMP-photoshop:DateCreated < Composite:SubSecDateTimeOriginal
-XMP-xmp:CreateDate < EXIF:CreateDate
-XMP-xmp:CreateDate < Composite:SubSecCreateDate
-XMP-xmp:ModifyDate < EXIF:ModifyDate
-XMP-xmp:ModifyDate < Composite:SubSecModifyDate
-XMP-xmp:CreatorTool < EXIF:Software
-XMP-dc:Rights < EXIF:Copyright
-XMP-dc:Creator < EXIF:Artist
-XMP-iptcExt:DigitalImageGUID < EXIF:ImageUniqueID
# XMP flash information is translated by the Composite Flash tag
-Composite:Flash < EXIF:Flash
# overwrite GPS tags which have different formats in XMP
-XMP:GPSLatitude < Composite:GPSLatitude
-XMP:GPSLongitude < Composite:GPSLongitude
-XMP:GPSDestLatitude < Composite:GPSDestLatitude
-XMP:GPSDestLongitude < Composite:GPSDestLongitude
-XMP:GPSDateTime < Composite:GPSDateTime
# new for the 2024 EXIF for XMP specification
-XMP-exifEX:PhotographicSensitivity < EXIF:ISO
-XMP-exif:DateTimeDigitized < EXIF:CreateDate
# add sub-seconds and time-zone to XMP-exif tags if available
-XMP-exif:DateTimeOriginal < Composite:SubSecDateTimeOriginal
-XMP-exif:DateTimeDigitized < Composite:SubSecCreateDate
# end
+27
View File
@@ -0,0 +1,27 @@
#------------------------------------------------------------------------------
# File: gps2xmp.args
#
# Description: Argument file for copying GPS information from EXIF to XMP
#
# Usage: exiftool -tagsFromFile SRCFILE -@ gps2xmp.args DSTFILE
#
# Requires: ExifTool version 10.96 or later
#
# Revisions: 2009/01/09 - P. Harvey Created
# 2018/05/07 - PH Handle GPSDestLatitude/LongitudeRef tags
#
# Notes: 1) Most of the GPS tags are copied by the first argument, but
# the XMP GPS coordinate and date/time tags are composites of
# more than one EXIF GPS tag, so they are handled separately.
#
# 2) These arguments will not delete existing XMP tags which are
# missing from the GPS. The XMP GPS tags should be deleted
# first with "-xmp:gps*=" if required.
#------------------------------------------------------------------------------
-XMP:all < GPS:all
-XMP:GPSLatitude < Composite:GPSLatitude
-XMP:GPSLongitude < Composite:GPSLongitude
-XMP:GPSDestLatitude < Composite:GPSDestLatitude
-XMP:GPSDestLongitude < Composite:GPSDestLongitude
-XMP:GPSDateTime < Composite:GPSDateTime
# end
+24
View File
@@ -0,0 +1,24 @@
#------------------------------------------------------------------------------
# File: iptc2exif.args
#
# Description: Tag name translations for converting IPTC to EXIF
#
# Usage: exiftool -tagsFromFile SRCFILE -@ iptc2exif.args DSTFILE
#
# Requires: ExifTool version 7.98 or later
#
# Revisions: 2011/09/13 - P. Harvey Created
# 2017/07/06 - PH Set new EXIF OffsetTime tags
#
# Notes: These arguments will not delete existing EXIF tags which are
# missing from the IPTC. The EXIF tags should be deleted
# beforehand if required.
#------------------------------------------------------------------------------
-EXIF:Artist < IPTC:By-line
-EXIF:Copyright < IPTC:CopyrightNotice
-EXIF:ImageDescription < IPTC:Caption-Abstract
-EXIF:DateTimeOriginal < Composite:DateTimeCreated
-EXIF:CreateDate < Composite:DigitalCreationDateTime
-EXIF:OffsetTimeOriginal < IPTC:TimeCreated
-EXIF:OffsetTimeDigitized < IPTC:DigitalCreationTime
# end
+57
View File
@@ -0,0 +1,57 @@
#------------------------------------------------------------------------------
# File: iptc2xmp.args
#
# Description: Tag name translations for converting from IPTC to XMP
#
# Usage: exiftool -tagsFromFile SRCFILE -@ iptc2xmp.args DSTFILE
#
# Requires: ExifTool version 7.45 or later
#
# Revisions: 2005/05/14 - P. Harvey Created
# 2008/03/04 - PH Changed Location translation and added
# IntellectualGenre and SubjectCode
# 2008/09/30 - PH Added writing of Photoshop:IPTCDigest
# 2009/01/20 - PH Updated to conform with MWG spec
# 2009/10/21 - PH Write XMP-xmp:CreateDate as per MWG 1.01 spec
#
# References: http://www.iptc.org/IPTC4XMP/
# http://www.iptc.org/IIM/
# http://www.adobe.com/products/xmp/pdfs/xmpspec.pdf
# http://www.metadataworkinggroup.org/specs/
#
# Notes: 1) Also updates Photoshop:IPTCDigest as per MWG recommendation.
#
# 2) These arguments will not delete existing XMP tags which are
# missing from the IPTC. The XMP tags should be deleted
# beforehand if required.
#------------------------------------------------------------------------------
-XMP-dc:Creator < IPTC:By-line
-XMP-dc:Description < IPTC:Caption-Abstract
-XMP-dc:Rights < IPTC:CopyrightNotice
-XMP-dc:Subject < IPTC:Keywords
-XMP-dc:Title < IPTC:ObjectName
-XMP-photoshop:AuthorsPosition < IPTC:By-lineTitle
-XMP-photoshop:CaptionWriter < IPTC:Writer-Editor
-XMP-photoshop:Category < IPTC:Category
-XMP-photoshop:City < IPTC:City
-XMP-photoshop:Country < IPTC:Country-PrimaryLocationName
-XMP-photoshop:Credit < IPTC:Credit
-XMP-photoshop:DateCreated < IPTC:DateCreated
# overwrite XMP DateCreated to include date and time if available
-XMP-photoshop:DateCreated < Composite:DateTimeCreated
-XMP-photoshop:Headline < IPTC:Headline
-XMP-photoshop:Instructions < IPTC:SpecialInstructions
-XMP-photoshop:Source < IPTC:Source
-XMP-photoshop:State < IPTC:Province-State
-XMP-photoshop:SupplementalCategories < IPTC:SupplementalCategories
-XMP-photoshop:TransmissionReference < IPTC:OriginalTransmissionReference
-XMP-photoshop:Urgency < IPTC:Urgency
-XMP-iptcCore:CountryCode < IPTC:Country-PrimaryLocationCode
-XMP-iptcCore:Location < IPTC:Sub-location
-XMP-xmp:CreateDate < IPTC:DigitalCreationDate
-XMP-xmp:CreateDate < Composite:DigitalCreationDateTime
# these tags are not free-form text, and may need special handling:
#-XMP-iptcCore:IntellectualGenre < IPTC:ObjectAttributeReference
#-XMP-iptcCore:SubjectCode < IPTC:SubjectReference
-Photoshop:IPTCDigest=new
# end
+241
View File
@@ -0,0 +1,241 @@
#------------------------------------------------------------------------------
# File: iptcCore.args
#
# Description: ExifTool arguments for IPTC Core and Extension tags
#
# Usage: exiftool -@ iptcCore.args FILE
#
# Requires: ExifTool version 8.44 or later
#
# Revisions: 2011/12/28 - P. Harvey Created (IPTC Core version 1.1)
# 2015/04/21 - PH Updated to IPTC Extension version 1.2
# 2017/06/02 - PH Updated to IPTC Extension version 1.3
# 2018/08/20 - PH Updated to IPTC Extension version 1.4
#
# References: http://www.iptc.org/IPTC4XMP/
#
# Notes: Both flattened and structured tags are included
#------------------------------------------------------------------------------
#
# dc schema
#
-XMP-dc:Creator
-XMP-dc:Description
-XMP-dc:Rights
-XMP-dc:Subject
-XMP-dc:Title
#
# photoshop schema
#
-XMP-photoshop:AuthorsPosition
-XMP-photoshop:CaptionWriter
-XMP-photoshop:City
-XMP-photoshop:Country
-XMP-photoshop:Credit
-XMP-photoshop:DateCreated
-XMP-photoshop:Headline
-XMP-photoshop:Instructions
-XMP-photoshop:Source
-XMP-photoshop:State
-XMP-photoshop:TransmissionReference
#
# xmp schema
#
-XMP-xmp:Rating
#
# xmpRights schema
#
-XMP-xmpRights:UsageTerms
-XMP-xmpRights:WebStatement
#
# Iptc4xmpCore schema
#
-XMP-iptcCore:CountryCode
# ContactInfo struct
-XMP-iptcCore:CreatorContactInfo
-XMP-iptcCore:CreatorAddress
-XMP-iptcCore:CreatorCity
-XMP-iptcCore:CreatorCountry
-XMP-iptcCore:CreatorPostalCode
-XMP-iptcCore:CreatorRegion
-XMP-iptcCore:CreatorWorkEmail
-XMP-iptcCore:CreatorWorkTelephone
-XMP-iptcCore:CreatorWorkURL
-XMP-iptcCore:IntellectualGenre
-XMP-iptcCore:Location
-XMP-iptcCore:Scene
-XMP-iptcCore:SubjectCode
#
# Iptc4xmpExt schema
#
-XMP-iptcExt:AdditionalModelInformation
# CVTermDetails struct
-XMP-iptcExt:AboutCvTerm
-XMP-iptcExt:AboutCvTermCvId
-XMP-iptcExt:AboutCvTermId
-XMP-iptcExt:AboutCvTermName
-XMP-iptcExt:AboutCvTermRefinedAbout
# ArtworkOrObjectDetails struct
-XMP-iptcExt:ArtworkOrObject
-XMP-iptcExt:ArtworkCopyrightNotice
-XMP-iptcExt:ArtworkCreator
-XMP-iptcExt:ArtworkDateCreated
-XMP-iptcExt:ArtworkSource
-XMP-iptcExt:ArtworkSourceInventoryNo
-XMP-iptcExt:ArtworkTitle
-XMP-iptcExt:ArtworkCopyrightOwnerName
-XMP-iptcExt:ArtworkCopyrightOwnerID
-XMP-iptcExt:ArtworkLicensorName
-XMP-iptcExt:ArtworkLicensorID
-XMP-iptcExt:ArtworkCreatorID
-XMP-iptcExt:ArtworkCircaDateCreated
-XMP-iptcExt:ArtworkStylePeriod
-XMP-iptcExt:ArtworkSourceInvURL
-XMP-iptcExt:ArtworkContentDescription
-XMP-iptcExt:ArtworkContributionDescription
-XMP-iptcExt:ArtworkPhysicalDescription
-XMP-iptcExt:ControlledVocabularyTerm
-XMP-iptcExt:DigitalImageGUID
-XMP-iptcExt:DigitalSourcefileType
-XMP-iptcExt:DigitalSourceType
# EEREDetails struct
-XMP-iptcExt:EmbdEncRightsExpr
-XMP-iptcExt:EmbeddedEncodedRightsExpr
-XMP-iptcExt:EmbeddedEncodedRightsExprType
-XMP-iptcExt:EmbeddedEncodedRightsExprLangID
-XMP-iptcExt:Event
-XMP-iptcExt:IPTCLastEdited
# LEREDetails struct
-XMP-iptcExt:LinkedEncRightsExpr
-XMP-iptcExt:LinkedEncodedRightsExpr
-XMP-iptcExt:LinkedEncodedRightsExprType
-XMP-iptcExt:LinkedEncodedRightsExprLangID
# LocationDetails struct
-XMP-iptcExt:LocationCreated
-XMP-iptcExt:LocationCreatedCity
-XMP-iptcExt:LocationCreatedCountryCode
-XMP-iptcExt:LocationCreatedCountryName
-XMP-iptcExt:LocationCreatedProvinceState
-XMP-iptcExt:LocationCreatedSublocation
-XMP-iptcExt:LocationCreatedWorldRegion
-XMP-iptcExt:LocationCreatedLocationId
# LocationDetails struct
-XMP-iptcExt:LocationShown
-XMP-iptcExt:LocationShownCity
-XMP-iptcExt:LocationShownCountryCode
-XMP-iptcExt:LocationShownCountryName
-XMP-iptcExt:LocationShownProvinceState
-XMP-iptcExt:LocationShownSublocation
-XMP-iptcExt:LocationShownWorldRegion
-XMP-iptcExt:LocationShownLocationId
-XMP-iptcExt:MaxAvailHeight
-XMP-iptcExt:MaxAvailWidth
-XMP-iptcExt:ModelAge
-XMP-iptcExt:OrganisationInImageCode
-XMP-iptcExt:OrganisationInImageName
-XMP-iptcExt:PersonInImage
# PersonDetails struct
-XMP-iptcExt:PersonInImageWDetails
-XMP-iptcExt:PersonInImageId
-XMP-iptcExt:PersonInImageName
-XMP-iptcExt:PersonInImageDescription
# CVTermDetails struct
#-XMP-iptcExt:PersonInImageCharacteristic
-XMP-iptcExt:PersonInImageCvTermCvId
-XMP-iptcExt:PersonInImageCvTermId
-XMP-iptcExt:PersonInImageCvTermName
-XMP-iptcExt:PersonInImageCvTermRefinedAbout
# ProductDetails struct
-XMP-iptcExt:ProductInImage
-XMP-iptcExt:ProductInImageName
-XMP-iptcExt:ProductInImageGTIN
-XMP-iptcExt:ProductInImageDescription
# RegistryEntryDetails struct
-XMP-iptcExt:RegistryID
-XMP-iptcExt:RegistryItemID
-XMP-iptcExt:RegistryOrganisationID
-XMP-iptcExt:RegistryEntryRole
# Genre struct
-XMP-iptcExt:Genre
-XMP-iptcExt:GenreCvId
-XMP-iptcExt:GenreCvTermId
-XMP-iptcExt:GenreCvTermName
-XMP-iptcExt:GenreCvTermRefinedAbout
#
# plus schema
#
# CopyrightOwnerDetail struct
-XMP-plus:CopyrightOwner
-XMP-plus:CopyrightOwnerID
-XMP-plus:CopyrightOwnerImageID
-XMP-plus:CopyrightOwnerName
# ImageCreatorDetail struct
-XMP-plus:ImageCreator
-XMP-plus:ImageCreatorID
-XMP-plus:ImageCreatorImageID
-XMP-plus:ImageCreatorName
# ImageSupplierDetail struct
-XMP-plus:ImageSupplier
-XMP-plus:ImageSupplierID
-XMP-plus:ImageSupplierImageID
-XMP-plus:ImageSupplierName
# LicensorDetail struct
-XMP-plus:Licensor
-XMP-plus:LicensorCity
-XMP-plus:LicensorCountry
-XMP-plus:LicensorEmail
-XMP-plus:LicensorExtendedAddress
-XMP-plus:LicensorID
-XMP-plus:LicensorImageID
-XMP-plus:LicensorName
-XMP-plus:LicensorNotes
-XMP-plus:LicensorPostalCode
-XMP-plus:LicensorRegion
-XMP-plus:LicensorStreetAddress
-XMP-plus:LicensorTelephone1
-XMP-plus:LicensorTelephone2
-XMP-plus:LicensorTelephoneType1
-XMP-plus:LicensorTelephoneType2
-XMP-plus:LicensorTransactionID
-XMP-plus:LicensorURL
-XMP-plus:MinorModelAgeDisclosure
-XMP-plus:ModelReleaseID
-XMP-plus:ModelReleaseStatus
-XMP-plus:PLUSVersion
-XMP-plus:PropertyReleaseID
-XMP-plus:PropertyReleaseStatus
# end
+27
View File
@@ -0,0 +1,27 @@
#------------------------------------------------------------------------------
# File: pdf2xmp.args
#
# Description: Tag name translations for converting from PDF DocInfo to XMP
#
# Usage: exiftool -tagsFromFile SRCFILE -@ pdf2xmp.args DSTFILE
#
# Requires: ExifTool version 7.07 or later
#
# Revisions: 2011/01/23 - P. Harvey Created
#
# References: http://www.adobe.com/devnet/xmp/
#
# Notes: These arguments will not delete existing XMP tags which are
# missing from the PDF. The XMP tags should be deleted
# beforehand if required.
#------------------------------------------------------------------------------
-XMP-dc:Title < PDF:Title
-XMP-dc:Creator < PDF:Author
-XMP-dc:Description < PDF:Subject
-XMP-pdf:Keywords < PDF:Keywords
-XMP-xmp:CreatorTool < PDF:Creator
-XMP-pdf:Producer < PDF:Producer
-XMP-xmp:CreateDate < PDF:CreateDate
-XMP-xmp:ModifyDate < PDF:ModifyDate
-XMP-pdf:Trapped < PDF:Trapped
# end
+65
View File
@@ -0,0 +1,65 @@
#------------------------------------------------------------------------------
# File: xmp2exif.args
#
# Description: Tag name translations for converting XMP to EXIF
#
# Usage: exiftool -tagsFromFile SRCFILE -@ xmp2exif.args DSTFILE
#
# Requires: ExifTool version 10.96 or later
#
# Revisions: 2009/01/20 - P. Harvey Created
# 2011/06/22 - PH Copy flash information via Composite:Flash
# 2013/06/12 - PH Additions for the Exif 2.3 for XMP spec
# 2015/01/12 - PH Avoid copying from non-standard namespaces
# 2016/09/26 - PH Write Composite SubSec tags
# 2018/05/07 - PH Added support for GPSDestXxxRef tags
# 2021/09/30 - PH Removed erroneous "-" when copying CreatorTool
# 2022/03/31 - PH IPTC Photometadata Mapping Guidelines 2202.1 update
# 2023/01/30 - PH Also write Composite:SubSecDateTimeOriginal from
# XMP-exif:DateTimeOriginal
# 2024/10/24 - PH Additions for the 2024 EXIF for XMP spec
# 2025/01/16 - PH Write Composite:SubSecCreateDate from XMP-exif
# 2025-04-22 - PH Fixed DigitalImageGUID translation
#
# References: http://www.metadataworkinggroup.org/specs/
# https://iptc.org/std/photometadata/documentation/mappingguidelines/
#
# Notes: 1) The first three arguments copy the bulk of the EXIF and GPS
# information, and the remaining arguments handle the tags
# which have different names and/or formats in XMP and EXIF.
#
# 2) These arguments will not delete existing EXIF tags which are
# missing from the XMP. The EXIF tags should be deleted
# beforehand if required.
#
# 3) XMP-iptcExt:ImageRegion is not currently mapped into EXIF:SubjectArea
#------------------------------------------------------------------------------
-EXIF:all < XMP-exif:all
-EXIF:all < XMP-exifEX:all
-EXIF:all < XMP-tiff:all
-EXIF:ImageDescription < XMP-dc:Description
-EXIF:DateTimeOriginal < XMP-photoshop:DateCreated
# new for the 2024 EXIF for XMP specification
-EXIF:ISO < XMP-exifEX:PhotographicSensitivity
# the following SubSec tags also write/delete the corresponding EXIF
# SubSecTime and OffsetTime tags as appropriate
-Composite:SubSecDateTimeOriginal < XMP-exif:DateTimeOriginal
-Composite:SubSecDateTimeOriginal < XMP-photoshop:DateCreated
-Composite:SubSecCreateDate < XMP-exif:DateTimeDigitized
-Composite:SubSecCreateDate < XMP-xmp:CreateDate
-Composite:SubSecModifyDate < XMP-xmp:ModifyDate
-EXIF:Software < XMP-xmp:CreatorTool
-EXIF:Copyright < XMP-dc:Rights
-EXIF:Artist < XMP-plus:ImageCreatorName
-EXIF:Artist < XMP-dc:Creator
-EXIF:ImageUniqueID < XMP-iptcExt:DigitalImageGUID
# XMP flash information is translated by the Composite Flash tag
-EXIF:Flash < Composite:Flash
# generate GPS tags which have been combined into other XMP tags
-GPS:GPSLatitudeRef < Composite:GPSLatitudeRef
-GPS:GPSLongitudeRef < Composite:GPSLongitudeRef
-GPS:GPSDestLatitudeRef < Composite:GPSDestLatitudeRef
-GPS:GPSDestLongitudeRef < Composite:GPSDestLongitudeRef
-GPS:GPSDatestamp < XMP-exif:GPSDateTime
-GPS:GPSTimestamp < XMP-exif:GPSDateTime
# end
+31
View File
@@ -0,0 +1,31 @@
#------------------------------------------------------------------------------
# File: xmp2gps.args
#
# Description: Argument file for copying GPS information from XMP to EXIF
#
# Usage: exiftool -tagsFromFile SRCFILE -@ xmp2gps.args DSTFILE
#
# Requires: ExifTool version 10.96 or later
#
# Revisions: 2009/01/09 - P. Harvey Created
# 2018/05/07 - PH Handle GPSDestLatitude/LongitudeRef tags
#
# Notes: 1) Most of the GPS tags are copied by the first argument, but
# the coordinate references and date/time values are stored
# separately in EXIF, so they must be handled separately.
# A bit of magic is employed by ExifTool to extract the date
# and time parts respectively when writing date-only and
# time-only tags with a date/time value.
#
# 2) These arguments will not delete existing GPS tags which are
# missing from the XMP. The GPS tags should be deleted with
# "-gps:all=" first if required.
#------------------------------------------------------------------------------
-GPS:all < XMP-exif:all
-GPS:GPSLatitudeRef < Composite:GPSLatitudeRef
-GPS:GPSLongitudeRef < Composite:GPSLongitudeRef
-GPS:GPSDestLatitudeRef < Composite:GPSDestLatitudeRef
-GPS:GPSDestLongitudeRef < Composite:GPSDestLongitudeRef
-GPS:GPSDateStamp < XMP-exif:GPSDateTime
-GPS:GPSTimeStamp < XMP-exif:GPSDateTime
# end
+66
View File
@@ -0,0 +1,66 @@
#------------------------------------------------------------------------------
# File: xmp2iptc.args
#
# Description: Tag name translations for converting from XMP to IPTC
#
# Usage: exiftool -tagsFromFile SRCFILE -@ xmp2iptc.args DSTFILE
#
# Requires: ExifTool version 7.45 or later
#
# Revisions: 2005/05/14 - P. Harvey Created
# 2008/03/04 - PH Changed Location translation and added
# IntellectualGenre and SubjectCode
# 2008/09/30 - PH Added writing of Photoshop:IPTCDigest
# 2009/01/20 - PH Updated to conform with MWG spec
# 2009/10/21 - PH Write IPTC:DigitalCreationDate/Time tags
#
# References: http://www.iptc.org/IPTC4XMP/
# http://www.iptc.org/IIM/
# http://www.adobe.com/products/xmp/pdfs/xmpspec.pdf
# http://www.metadataworkinggroup.org/specs/
#
# Notes: 1) Also updates Photoshop:IPTCDigest as per MWG recommendation.
#
# 2) For special characters in the XMP to be preserved, the IPTC
# encoding must be UTF-8: Either IPTC:CodedCharacterSet must
# already be "UTF8", or it must be set to "UTF8" when copying the
# XMP. This is not done automatically by this argfile because it
# could invalidate the encoding of existing IPTC if there were
# any values containing special characters. See FAQ number 10
# for more information about converting the IPTC encoding:
# https://exiftool.org/faq.html#Q10
#
# 3) These arguments will not delete existing IPTC tags which are
# missing from the XMP. The IPTC tags should be deleted
# beforehand if required.
#------------------------------------------------------------------------------
-IPTC:By-line < XMP-dc:Creator
-IPTC:Caption-Abstract < XMP-dc:Description
-IPTC:CopyrightNotice < XMP-dc:Rights
-IPTC:Keywords < XMP-dc:Subject
-IPTC:ObjectName < XMP-dc:Title
-IPTC:By-lineTitle < XMP-photoshop:AuthorsPosition
-IPTC:Writer-Editor < XMP-photoshop:CaptionWriter
-IPTC:Category < XMP-photoshop:Category
-IPTC:City < XMP-photoshop:City
-IPTC:Country-PrimaryLocationName < XMP-photoshop:Country
-IPTC:Credit < XMP-photoshop:Credit
-IPTC:DateCreated < XMP-photoshop:DateCreated
# magically extracts time from a date/time value
-IPTC:TimeCreated < XMP-photoshop:DateCreated
-IPTC:Headline < XMP-photoshop:Headline
-IPTC:SpecialInstructions < XMP-photoshop:Instructions
-IPTC:Source < XMP-photoshop:Source
-IPTC:Province-State < XMP-photoshop:State
-IPTC:SupplementalCategories < XMP-photoshop:SupplementalCategories
-IPTC:OriginalTransmissionReference < XMP-photoshop:TransmissionReference
-IPTC:Urgency < XMP-photoshop:Urgency
-IPTC:Country-PrimaryLocationCode < XMP-iptcCore:CountryCode
-IPTC:Sub-location < XMP-iptcCore:Location
-IPTC:DigitalCreationDate < XMP-xmp:CreateDate
-IPTC:DigitalCreationTime < XMP-xmp:CreateDate
# these tags are not free-form text, and may need special handling:
#-IPTC:ObjectAttributeReference < XMP-iptcCore:IntellectualGenre
#-IPTC:SubjectReference < XMP-iptcCore:SubjectCode
-Photoshop:IPTCDigest=new
# end
+27
View File
@@ -0,0 +1,27 @@
#------------------------------------------------------------------------------
# File: xmp2pdf.args
#
# Description: Tag name translations for converting from XMP to PDF DocInfo
#
# Usage: exiftool -tagsFromFile SRCFILE -@ xmp2pdf.args DSTFILE
#
# Requires: ExifTool version 7.07 or later
#
# Revisions: 2011/01/23 - P. Harvey Created
#
# References: http://www.adobe.com/devnet/xmp/
#
# Notes: These arguments will not delete existing PDF tags which are
# missing from the XMP. The PDF tags should be deleted
# beforehand if required.
#------------------------------------------------------------------------------
-PDF:Title < XMP-dc:Title
-PDF:Author < XMP-dc:Creator
-PDF:Subject < XMP-dc:Description
-PDF:Keywords < XMP-pdf:Keywords
-PDF:Creator < XMP-xmp:CreatorTool
-PDF:Producer < XMP-pdf:Producer
-PDF:CreateDate < XMP-xmp:CreateDate
-PDF:ModifyDate < XMP-xmp:ModifyDate
-PDF:Trapped < XMP-pdf:Trapped
# end
+952
View File
@@ -0,0 +1,952 @@
#!/usr/bin/env perl
#-------------------------------------------------------------------------------
# File: build_geolocation
#
# Description: Parse geonames files to create ExifTool geolocation database
#
# Syntax: build_geolocation [OPTIONS] [DBFILE] ...
#
# Options: (see -h output)
#
# Created: 2024-03-03 - P. Harvey
# 2024-04-15 - PH Clean up and add options for public release
# 2024-04-22 - PH Increased number of possible feature codes from
# 32 to 64. Convert backslashes in directory names
# 2024-04-24 - PH Fixed problem with population exponent when run
# under ActivePerl
# 2024-04-29 - PH Added feature types and default to db v1.03
# 2024-06-13 - PH Tweaked case of imported feature types
# 2025-09-11 - PH Changed priority of alternate-language names to
# use the preferred name if available and fixed
# flag counts in verbose output
#
# Notes: Requires these files from https://download.geonames.org/export/
#
# allCountries.txt (or other input database if specified)
# countryInfo.txt
# admin1CodesASCII.txt
# admin2Codes.txt
# featureCodes_XX.txt (optional)
# alternateNamesV2.txt (optional)
#
# Output datbase format (Geolocation.dat):
#
# Header:
# "GeolocationV.VV\tNNNN\n" (V.VV=version, NNNN=num city entries)
# "# <comment>\n"
# NNNN City entries:
# Offset Format Description
# 0 int16u - latitude high 16 bits (converted to 0-0x100000 range)
# 2 int8u - latitude low 4 bits, longitude low 4 bits
# 3 int16u - longitude high 16 bits
# 5 int8u - index of country in country list
# 6 int8u - 0xf0 = population E exponent (in format "N.Fe+0E"), 0x0f = population N digit
# 7 int16u - 0xf000 = population F digit, 0x0fff = index in region list (admin1)
# 9 int16u - v1.02: 0x7fff = index in subregion (admin2), 0x8000 = high bit of time zone
# 9 int16u - v1.03: index in subregion list (admin2)
# 11 int8u - low byte of time zone index
# 12 int8u - 0x3f = feature code index (see below), v1.03: 0x80 = high bit of time zone
# 13 string - UTF8 City name, terminated by newline
# "\0\0\0\0\x01"
# Country entries:
# 1. 2-character country code
# 2. Country name, terminated by newline
# "\0\0\0\0\x02"
# Region entries:
# 1. Region name, terminated by newline
# "\0\0\0\0\x03"
# Subregion entries:
# 1. Subregion name, terminated by newline
# "\0\0\0\0\x04"
# Time zone entries:
# 1. Time zone name, terminated by newline
# "\0\0\0\0\x05" (feature codes added in v1.03)
# Feature codes:
# 1. Feature code, optional space-followed-by-feature-name, then newline
# "\0\0\0\0\0"
#
# Feature Codes v1.02: (see http://www.geonames.org/export/codes.html#P for descriptions)
#
# 0. Other 3. PPLA2 6. PPLA5 9. PPLF 12. PPLR 15. PPLX
# 1. PPL 4. PPLA3 7. PPLC 10. PPLG 13. PPLS
# 2. PPLA 5. PPLA4 8. PPLCH 11. PPLL 14. STLMT
#
# Feature Codes v1.03 and later are listed at the end of the database
#-------------------------------------------------------------------------------
use strict;
my $dbVer = '1.03'; # default output database version
my $dbFile = 'allCountries.txt'; # default database file
my $countryFile = 'countryInfo.txt'; # mandatory country names file
my $regionFile = 'admin1CodesASCII.txt'; # mandatory region names file
my $admin2File = 'admin2Codes.txt'; # mandatory subregion names file
my $featureFile = 'featureCodes_en.txt'; # optional feature names file
my $altNamesFile = 'alternateNamesV2.txt'; # optional alternate names file
my $outFile = 'Geolocation.dat'; # output ExifTool database file
my $outAltNames = 'AltNames.dat'; # output alternate names file
my $outDirName = 'Geolocation_out'; # output directory for database files
my $geoLang = 'GeoLang'; # output directory for language files
my %defaults = (
file => $dbFile,
minpop => 2000,
def_codes => 'PPLA,PPLA2',
def_codesp => 'PPL,PPLA,PPLA2,PPLA3,PPLA4,PPLA5,PPLC,PPLCH,PPLF,PPLG,PPLH,PPLL,PPLQ,PPLR,PPLS,PPLW,PPLX,STLMT',
);
# languages to read from geonames database
my @languages = qw(cs de en en-ca en-gb es fi fr it ja ko nl pl ru sk sv tr zh zh-cn zh-tw);
# indices of feature codes (v1.02 is hard-coded in ExifTool)
my @fc102 = qw(
Other PPL PPLA PPLA2 PPLA3 PPLA4 PPLA5 PPLC PPLCH
PPLF PPLG PPLL PPLR PPLS STLMT PPLX
);
# base features for v1.03+
my @fc103 = qw(
Other PPL PPLA PPLA2 PPLA3 PPLA4 PPLA5 PPLC PPLCH
PPLF PPLG PPLH PPLL PPLQ PPLR PPLS PPLW PPLX STLMT
);
my $i = 0;
my @featureCodes = $dbVer eq '1.02' ? @fc102 : @fc103;
my %featureCodes = map { $_ => $i++ } @featureCodes;
my %featureNames;
my ($dbfile, @dbfiles, $outDir, $verbose, $noLang, %needRgn);
my %optArgs = ( p => 1, c => 1, cp => 1, l => 1, o => 1, ver => 1 );
# process command-line arguments
my $opts = { };
while (@ARGV) {
my $opt = shift;
if (not $opt =~ s/^-//) {
$opt = '.' unless length $opt;
$opt =~ tr(\\)(/); # use forward slashes
$opt =~ s(/$)(); # remove trailing slash
$opt = "$opt/$defaults{file}" if -d $opt;
-e $opt or die "Error opening database $opt\n";
push @dbfiles, { %defaults, %$opts, file => $opt };
$opts = { };
next;
}
my $arg;
if ($optArgs{$opt}) {
$arg = shift;
defined $arg or die "Expecting argument for -$opt option\n";
}
if ($opt eq 'p') {
$arg = uc $arg;
if ($arg =~ /=/) {
my ($cc, $mp) = split /=/, $arg;
$mp =~ /^\d+$/ or die "Expecting number on rhs of '=' for -p option\n";
my @cc = split /,/, $cc;
foreach $cc (@cc) {
$cc =~ /^([A-Z]{2})(\..+)?$/ or die "Invalid country/region '$cc' for -p option\n";
$needRgn{$1} = $needRgn{$cc} = 1 if length $cc > 2;
$$opts{cc_minpop}{$cc} = $mp;
}
} else {
$arg =~ /^\d+$/ or die "Expecting number for -p option\n";
$$opts{minpop} = $arg;
}
} elsif ($opt =~ /^c(p?)$/) {
my $p = $1;
$arg = uc $arg;
my ($cc, $co);
if ($arg =~ /=/) {
($cc, $co) = split /=/, $arg;
} else {
($cc, $co) = ('??', $arg);
}
my $sign = $co =~ s/^([-+])// ? $1 : '';
my @co = split /,/, $co;
my @cc = split /,/, $cc;
# store lookup for features to keep for each country ('??' = any country)
foreach $cc (@cc) {
$cc =~ /^([A-Z]{2}|\?\?)(\..+)?$/ or die "Invalid country/region '$cc' for -$opt option\n";
$needRgn{$1} = $needRgn{$cc} = 1 if length $cc > 2;
if (not $sign) {
$$opts{"keep$p"}{$cc} = { };
} elsif (not $$opts{"keep$p"}{$cc}) {
# start from defaults
my %codes = map { $_ => 1 } split /,/, $defaults{"def_codes$p"};
$$opts{"keep$p"}{$cc} = \%codes;
}
foreach $co (@co) {
if ($sign eq '-') {
delete $$opts{"keep$p"}{$cc}{$co};
} else {
$$opts{"keep$p"}{$cc}{$co} = 1;
}
}
}
} elsif ($opt eq 'l') {
$arg = lc $arg;
my @langs = split ',', $arg;
if (not @langs) {
undef @languages;
$noLang = 1;
} elsif ($langs[0] =~ s/^-//) {
@languages = grep !/^$langs[0]$/, @languages foreach @langs;
} else {
@languages = @langs;
}
} elsif ($opt eq 'o') {
$outDir = $arg;
} elsif ($opt eq 'ver') {
$dbVer = $arg;
$dbVer =~ /^1\.0[23]$/ or die "Unsupported version number $dbVer\n";
} elsif ($opt eq 'v') {
$verbose = 1;
} elsif ($opt eq 'h') {
my $defcp = $defaults{def_codesp};
$defcp =~ s/(PPLG,)/\n $1/;
my $defLang = join ',', @languages;
$defLang =~ s/(ja,)/\n $1/;
print <<"END";
Description: Build ExifTool Geolocation database.
Syntax: build_geolocation [OPTIONS] [DBFILE] ...
Options:
DBFILE - Input database file name or directory. Multiple input database
files may be specified. The -p, -c and -cp options apply to
the database that comes after them on the command line. The
other input files are assumed to be in the same directory as
the first database file. Default is "$dbFile".
-p POP - Minimum population for cities to include. POP may be a number
or be of the form "CC[,C2...]=###" to set different limits for
specific countries/regions, where CC and C2 are country codes
with optional region name or code appended after a period (eg.
"CA.Ontario,US=500" sets the minimum population to 500 for
cities on Ontario Canada or the U.S.). If a region is
specified, either the full name or the geonames admin1 code may
be used, and case and spaces are not significant. May be
multiple -p options for each input DBFILE. Default is "$defaults{minpop}".
-c CODE - Feature codes to always include, regardless of population. CODE
is a comma-separated list of feature codes, with an optional
leading comma-separated list of country/region codes followed
by an equals sign to apply only to specific countries. The
feature-code list may begin with a dash to remove entries from
the default list, or a plus sign to add entries. May be
multiple -c options for each intput DBFILE. Country/region and
feature names are case insensitive. Default is "$defaults{def_codes}".
-cp CODE - Additional features to include if above minimum population.
Default is "$defcp".
-l LANG - Alternate languages to read from $altNamesFile if
available. These are used to generate $outAltNames an the
$geoLang files. LANG is a comma-separated list of language
codes, starting with a dash to remove items from the default
list. May be set to an empty string to disable generation
of alternate language files even if $altNamesFile
exists. The same set of languages applies to all input
database files. Default is "$defLang".
-o OUTDIR - Output directory name. Default is the same directory as the
first input database file. A directory named $outDirName
containing the output files will be created in this directory.
-ver VER - Version for output geolocation database (default is $dbVer).
-v - Verbose messages.
-h - Show this help.
Input files (download from https://download.geonames.org/export/dump/):
$dbFile - default database file (smaller files with names
like "cities###.txt" may be specified instead)
$countryFile - mandatory country names file
$regionFile - mandatory region names file
$admin2File - mandatory subregion names file
$featureFile - optional feature codes file(s)
$altNamesFile - optional alternate names file (must exist to
to generate $outAltNames and $geoLang files)
Output files:
$outDirName - default output directory name
$outFile - ExifTool database file
$outAltNames - alternate names file
$geoLang - directory for alternate language files
Author:
Copyright 2024, Phil Harvey
This is free software; you can redistribute it and/or modify it under the
same terms as Perl itself.
END
exit 0;
} else {
die "Unknown option '-$opt'\n";
}
}
if (@dbfiles) {
# apply any remaining options to last database file
$dbfiles[-1]{$_} = $$opts{$_} foreach keys %$opts;
} else {
# use default database file if none specified
push @dbfiles, { %defaults, %$opts };
unless (-e $dbfiles[0]{file}) {
# also look in script directory
if ($0 =~ m{(.*)/} and -e "$1/$dbfiles[0]{file}") {
$dbfiles[0]{file} = "$1/$dbfiles[0]{file}";
} else {
die qq(Database "$dbfiles[0]{file}" not found. Use -h option for help.\n);
}
}
}
# determine our working directory
my $dbdir = $dbfiles[0]{file};
$dbdir = '.' unless $dbdir =~ s(/[^/]*$)();
# add default feature code lookups if necessary
foreach $dbfile (@dbfiles) {
my $p;
foreach $p ('', 'p') {
next if $$dbfile{"keep$p"}{'??'};
my %codes = map { $_ => 1 } split /,/, $defaults{"def_codes$p"};
$$dbfile{"keep$p"}{'??'} = \%codes;
}
}
# pre-read region file if necessary
if (%needRgn) {
open REGION, '<', "$dbdir/$regionFile" or die "Error opening $dbdir/$regionFile\n";
while (<REGION>) {
my @items = split /\t/;
my $rgn = $items[0];
my ($cc) = split /\./, $rgn;
next unless $needRgn{$cc};
unless ($needRgn{$rgn}) { # allow region code to be used
$rgn = $cc . '.' . uc$items[1]; # also support full region name
unless ($needRgn{$rgn}) {
$rgn =~ tr/ //d;
next unless $needRgn{$rgn}; # also allow no spaces
}
}
$needRgn{$rgn} = [$items[0], "$cc.$items[1]"];
}
close REGION;
foreach (sort keys %needRgn) {
next if length == 2;
die "No matching region for $_\n" unless ref $needRgn{$_};
}
}
if ($verbose) {
my $langs = join ',', @languages;
$langs or $langs = '<none>';
print "Languages to read from input database(s):\n $langs\n";
foreach $dbfile (@dbfiles) {
print "Parameters for reading $$dbfile{file}:\n";
print " Minimum populations (??=any country):\n";
print " ??=$$dbfile{minpop}\n";
foreach (reverse sort keys %{$$dbfile{cc_minpop}}) {
my $cc = ref $needRgn{$_} ? $needRgn{$_}[1] : $_;
print " $cc=$$dbfile{cc_minpop}{$_}\n";
}
print " Features to keep regardless of population:\n";
foreach (reverse sort keys %{$$dbfile{keep}}) {
my $cc = ref $needRgn{$_} ? $needRgn{$_}[1] : $_;
print " $cc=",join(',', sort keys %{$$dbfile{keep}{$_}}), "\n";
}
print " Features to keep for population >= minimum:\n";
foreach (reverse sort keys %{$$dbfile{keepp}}) {
my $cc = ref $needRgn{$_} ? $needRgn{$_}[1] : $_;
print " $_=",join(',', sort keys %{$$dbfile{keepp}{$_}}), "\n";
}
}
}
# translate option region arguments to region codes
foreach $dbfile (@dbfiles) {
my ($type, $cc);
foreach $type (qw(cc_minpop keep keepp)) {
my @cc = keys %{$$dbfile{$type}};
foreach $cc (@cc) {
next unless ref $needRgn{$cc};
my $tmp = $$dbfile{$type}{$cc};
delete $$dbfile{$type}{$cc};
$$dbfile{$type}{$needRgn{$cc}[0]} = $tmp;
}
}
}
$outDir = "$dbdir/$outDirName" unless defined $outDir;
-d $outDir or mkdir $outDir, 0777 or die "Error creating output directory '$outDir'\n";
-e "$dbdir/$_" or die "Missing input file $dbdir/$_\n" foreach $countryFile, $regionFile, $admin2File;
# order of country codes, region names and subregions in database
my (%orderCC, %orderRgn, %orderSub);
# languages to read from geonames database (converted to lower case)
my %languages = map { $_ => 1 } @languages;
# language codes supported by ExifTool
my @supportedLangs = qw(cs de en-ca en-gb es fi fr it ja ko nl pl ru sk sv tr zh-cn zh-tw);
# supported country-specific languages
my %ccLang = ( TW => 'zh', CN => 'zh', CA => 'en', GB => 'en' );
my (%lang, %featureLang, %haveCountry, %cityFlags, %rgnFlags, %subFlags, %ccFlags, %flags);
my (%haveRegion, %haveSubRgn, $filesize, $percent);
sub GetFileSize($)
{
my $file = shift;
seek $file, 0, 2 or die "Seek error\n";
my $size = tell $file;
seek $file, 0, 0 or die "Seek error\n";
return $size;
}
# pre-scan database to determine which countries, regions subregions and
# feature codes we will be using
foreach $dbfile (@dbfiles) {
my $database = $$dbfile{file};
my $upgraded;
print "Reading $database... 0%";
flush STDOUT;
# pre-read the files to initialize necessary variables
open INFILE, '<', $database or die "Error opening $database\n";
$filesize = GetFileSize(\*INFILE);
open OUTFILE, '>', "$outDir/$outFile" or die "Error creating $outFile in $outDir\n";
binmode(OUTFILE);
$$dbfile{kept} = [ ];
$percent = -1;
while (<INFILE>) {
my $p = int(100 * tell(INFILE) / $filesize + 0.5);
if ($percent != $p) {
printf("\b\b\b\b%3d%%", $percent = $p);
flush STDOUT;
}
my @items = split /\t/;
my ($dbnum, $code, $cc, $rgn, $sub, $pop) = @items[0,7,8,10,11,14];
next unless @items > 17 and $cc =~ /^[A-Z]{2}$/;
my ($minpop, $keep);
if ($needRgn{$cc} and defined $$dbfile{cc_minpop}{"$cc$rgn"}) {
$minpop = $$dbfile{cc_minpop}{"$cc$rgn"};
} elsif (defined $$dbfile{cc_minpop}{$cc}) {
$minpop = $$dbfile{cc_minpop}{$cc};
} else {
$minpop = $$dbfile{minpop};
}
# keep regardless of population
if ($needRgn{$cc} and $$dbfile{keep}{"$cc$rgn"}) {
$keep = $$dbfile{keep}{"$cc$rgn"}{$code};
} elsif ($$dbfile{keep}{$cc}) {
$keep = $$dbfile{keep}{$cc}{$code};
} else {
$keep = $$dbfile{keep}{'??'}{$code};
}
if ($pop < $minpop) {
next unless $keep;
} elsif ($needRgn{$cc} and $$dbfile{keepp}{"$cc$rgn"}) {
next unless $$dbfile{keepp}{"$cc$rgn"}{$code};
} elsif ($$dbfile{keepp}{$cc}) {
next unless $$dbfile{keepp}{$cc}{$code};
} else {
next unless $$dbfile{keepp}{'??'}{$code};
}
push @{$$dbfile{kept}}, $_;
$lang{$dbnum} = { alt => [ ] };
$haveCountry{$cc} = 1;
$haveRegion{"$cc$rgn"} = 1;
$haveSubRgn{"$cc$rgn.$sub"} = 1;
# add new feature codes (up to maximum index of 0x3f)
unless ($featureCodes{$code} or @featureCodes > 0x3f) {
if ($dbVer eq '1.02') {
next if $code =~ /^(PPLH|PPLQ|PPLW)$/; # (stored as "Other" in v1.02)
$dbVer = '1.03';
$upgraded = 1; # print upgrade warning
@featureCodes = @fc103;
my $i = 0;
%featureCodes = map { $_ => $i++ } @featureCodes;
next if $featureCodes{$code};
}
push @featureCodes, $code;
$featureCodes{$code} = $#featureCodes;
}
}
close INFILE;
print "\b\b\b\bDone.\n";
warn "Some feature codes not supported by version 1.02, writing as 1.03 instead.\n" if $upgraded;
}
# read feature names
if (open INFILE, '<', "$dbdir/$featureFile") {
print "Reading $dbdir/$featureFile\n";
while (<INFILE>) {
my @items = split /\t/;
$items[0] =~ s/^.\.//; # remove feature group and "." separator
next unless $featureCodes{$items[0]};
my $name = ucfirst $items[1];
$name =~ s/ ([a-z])/ \U$1/g;
$name =~ s/(.)\b(Of|Or|A|An|On|In|The|By|For|And)\b/$1\L$2/g;
$featureNames{$items[0]} = $name;
}
close INFILE;
} else {
print "Not found: $dbdir/$featureFile\n";
print "--> Not storing feature type names\n";
}
# read country names
$i = 0;
open INFILE, '<', "$dbdir/$countryFile" or die "Error opening $dbdir/$countryFile\n";
print "Reading $dbdir/$countryFile\n";
while (<INFILE>) {
next if /^#/;
my @items = split /\t/;
next unless $haveCountry{$items[0]};
$lang{$items[16]} = { alt => [ ] }; # reference lookup by db number
$orderCC{$items[0]} = $i++; # (entry 0 is the first country)
}
close INFILE;
printf " %.6d countries (0x%.4x)\n",$i,$i if $verbose;
die "Too many countries!\n" if $i > 0x100; # (no default 0 entry)
# read region (admin1) names
$i = 0;
open REGION, '<', "$dbdir/$regionFile" or die "Error opening $dbdir/$regionFile\n";
print "Reading $dbdir/$regionFile\n";
while (<REGION>) {
chomp;
my @items = split /\t/;
$items[0] =~ tr/.//d; # (remove "." separator)
next unless $haveRegion{$items[0]};
$lang{$items[3]} = { alt => [ ] }; # reference lookup by db number
$orderRgn{$items[0]} = ++$i; # (entry 0 is default "" region)
}
close REGION;
printf " %.6d regions (0x%.4x)\n",$i,$i if $verbose;
die "Too many regions!\n" if $i > 0x0fff; # (account for default 0 entry)
# read subregion (admin2) names
$i = 0;
open ADMIN2, '<', "$dbdir/$admin2File" or die "Error opening $dbdir/$admin2File\n";
print "Reading $dbdir/$admin2File\n";
while (<ADMIN2>) {
chomp;
my @items = split /\t/;
$items[0] =~ s/\.//; # (remove first "." separator)
next unless $haveSubRgn{$items[0]};
$lang{$items[3]} = { alt => [ ] }; # reference lookup by db number
$orderSub{$items[0]} = ++$i; # (entry 0 is default "" subregion)
}
close ADMIN2;
printf " %.6d subregions (0x%.4x)\n",$i,$i if $verbose;
if ($i > ($dbVer eq '1.02' ? 0x7fff : 0xffff)) {
die "Too many subregions!\n" if $i > 0xffff;
$dbVer = '1.03';
warn "Too many subregions for version 1.02, writing as 1.03 instead.\n";
}
# read alternate names file if available
if (not $noLang and open INFILE, '<', "$dbdir/$altNamesFile") {
$filesize = GetFileSize(\*INFILE);
print "Reading $dbdir/$altNamesFile... 0%";
my %bestPri;
while (<INFILE>) {
my $p = int(100 * tell(INFILE) / $filesize + 0.5);
if ($percent != $p) {
printf("\b\b\b\b%3d%%", $percent = $p);
flush STDOUT;
}
# items: 0=altID,1=geoID,2=lang,3=alt name,4=preferred,5=short,6=colloquial,7=historic
my @items = split /\t/;
my $lkup = $lang{$items[1]} or next;
my $altList = $lang{$items[1]}{alt};
my $lng = lc $items[2];
next if $lng and not $languages{$lng};
push @$altList, $items[3] unless grep /^\Q$items[3]\E$/i, @$altList;
next unless $lng;
my $flags = 0;
# keep only the best translation for this name for each language
$items[$_] and $flags |= (1<<($_-4)) foreach 4,5,6,7;
$flags{$items[1]} = ( $flags{$items[1]} || 0 ) | $flags;
next if $items[6] or $items[7]; # ignore colloquial and historic names
# give more weight to preferred name and less weight to short name
my $pri = ($items[4] ? 2 : 0) + ($items[5] ? 0 : 1);
my $langPri = $bestPri{$lng};
$langPri or $langPri = $bestPri{$lng} = { };
next if $$langPri{$items[1]} and $$langPri{$items[1]} > $pri;
$$langPri{$items[1]} = $pri;
# save language-specific name for this feature, removing commas
($$lkup{$lng} = $items[3]) =~ tr/,//d;
}
print "\b\b\b\bDone.\n";
close INFILE;
# read alternate feature names
if (%featureNames) {
my $lng;
foreach $lng (@languages) {
next if $lng eq 'en' or not $languages{$lng};
my $file = "$dbdir/$featureFile";
$file =~ s/_en\./_$lng./ or next;
next unless open INFILE, '<', $file;
print "Reading $file\n";
while (<INFILE>) {
my @items = split /\t/;
$items[0] =~ s/^.\.//; # remove feature group and "." separator
next unless $featureNames{$items[0]};
utf8::decode($items[1]);
my $name = ucfirst $items[1];
$name =~ s/ (.)/ \U$1/g;
# change $name back to byte string
if ($] >= 5.006 and (eval { require Encode; Encode::is_utf8($name) } or $@)) {
$name = $@ ? pack('C*',unpack($] < 5.010000 ? 'U0C*' : 'C0C*',$name)) : Encode::encode('utf8',$name);
}
next if $name eq $featureNames{$items[0]};
$featureLang{$lng}{$items[0]} = $name;
}
close INFILE;
}
}
} else {
print "Not found: $dbdir/$altNamesFile\n--> " unless $noLang;
print "Not writing alternate languages\n";
$noLang = 1;
}
my (%coords, %langLookups);
foreach $dbfile (@dbfiles) {
my $database = $$dbfile{file};
print "Processing database entries... 0%";
my $i = 0;
my $num = scalar @{$$dbfile{kept}};
foreach (@{$$dbfile{kept}}) {
my @items = split /\t/;
my ($lat, $lon) = @items[4,5];
$lat = int(($lat + 90) / 180 * 0x100000 + 0.5) & 0xfffff;
$lon = int(($lon + 180) / 360 * 0x100000 + 0.5) & 0xfffff;
my $coord = pack('nCn',$lat>>4,(($lat&0x0f)<<4)|($lon&0x0f),$lon>>4);;
# take the city with the highest population if there are
# multiple cities with the same reduced coordinates
if ($coords{$coord} and $coords{$coord}[6] >= $items[14]) {
next;
}
# coords=(0.lat,1.lon,2.city,3.cc,4.rgn,5.admin2,6.population,7.timezone,8.feature code,9.alt names)
my ($altList, $alt);
die "Internal error\n" unless $lang{$items[0]} and $altList = $lang{$items[0]}{alt};
if (@$altList) {
tr/,//d foreach @$altList;
$alt = join ',', sort @$altList;
} else {
$alt = '';
}
$coords{$coord} = [ @items[4,5,1,8,10,11,14,17,7] ];
$coords{$coord}[9] = $alt;
my $lkup = $lang{$items[0]}; # 0=geoID
my $key = $items[1]; # 1=city
$lkup or die "Missing language for geoID $items[0]\n";
$cityFlags{$flags{$items[0]}} = ($cityFlags{$flags{$items[0]}} || 0) + 1 if defined $flags{$items[0]};
my $ccLang = $ccLang{$items[8]}; # get country-specific language
if ($ccLang and $$lkup{$ccLang}) {
my $lc = $ccLang . '-' . lc($items[8]); # eg. zh-cn
# add country suffix for this language in this country
$$lkup{$lc} = $$lkup{$ccLang} unless $$lkup{$lc};
}
foreach (@supportedLangs) {
next unless $$lkup{$_} and $$lkup{$_} ne $key; # (ignore if same)
$langLookups{$_}{$key} or $langLookups{$_}{$key} = [ ];
push @{$langLookups{$_}{$key}}, "$items[8]$items[10].$items[11],$$lkup{$_}";
}
my $p = int(100 * ++$i / $num + 0.5);
next if $percent == $p;
printf("\b\b\b\b%3d%%", $percent = $p);
flush STDOUT;
}
print "\b\b\b\bDone.\n";
}
# write city database
my $str = $noLang ? '' : " and $outAltNames";
my @t = localtime;
my $date = sprintf('%.4d-%.2d-%.2d', $t[5]+1900, $t[4]+1, $t[3]);
print "Writing $outDir/$outFile (version $dbVer)$str...\n";
print OUTFILE "Geolocation$dbVer\t",scalar(keys %coords),"\n";
print OUTFILE "# $date Cities with population $dbfiles[0]{minpop} or greater from geonames.org with a Creative Commons license\n";
if ($noLang) {
unlink "$outDir/$outAltNames";
} else {
open ALTOUT, ">$outDir/$outAltNames";
binmode ALTOUT;
}
my (%tz, @tz, %fcodes);
my $tzNum = 0;
foreach (sort { $a cmp $b } keys %coords) {
my $items = $coords{$_};
# @$items=(0.lat,1.lon,2.city,3.cc,4.rgn,5.admin2,6.population,7.timezone,8.feature code,9.alt names)
my $iCC = $orderCC{$$items[3]};
defined $iCC or warn("Unknown country code $$items[3]\n"), next;
my $iRgn = $orderRgn{"$$items[3]$$items[4]"} || 0;
my $iSub = $orderSub{"$$items[3]$$items[4].$$items[5]"} || 0;
my $tn = $tz{$$items[7]};
unless ($tn) {
push @tz, $$items[7];
$tn = $tz{$$items[7]} = $tzNum++;
}
# convert population to our binary format
# Note: format in ActivePerl is "3.1e+004", but "3.1+04" in other Perls,
# but other Perls will round 34500 to "3.4e+04", so add 1 to get "3.5e+04"
$$items[6] += 1 if $$items[6] > 100 and not $$items[6] % 10;
my $pop = sprintf('%.1e',$$items[6]);
# pack CC, population and region index into a 32-bit integer
my $code = ($iCC << 24) | (substr($pop,-1,1)<<20) | (substr($pop,0,1)<<16) | (substr($pop,2,1)<<12) | $iRgn;
$fcodes{$$items[8]} = ($fcodes{$$items[8]} || 0) + 1;
my $fc = $featureCodes{$$items[8]} || 0;
# store high bit of timezone index
if ($tn > 255) {
if ($dbVer eq '1.02') {
$iSub |= 0x8000;
$tn -= 256;
} else {
$fc |= 0x80;
$tn -= 256;
}
}
my $pt = pack('NnCC', $code, $iSub, $tn, $fc);
$$items[2] =~ tr/,//d; # remove any commas
print OUTFILE "$_$pt$$items[2]\n";
next if $noLang;
$$items[9] =~ tr/,/\n/;
print ALTOUT $$items[9],"\0";
}
my $altSize = 0;
unless ($noLang) {
$altSize = tell ALTOUT;
close ALTOUT;
}
print OUTFILE "\0\0\0\0\x01\n"; # section terminator
die "Too many time zones!\n" if $tzNum > 0x01ff;
if ($verbose) {
$i = 0;
print "Features kept:\n";
foreach (sort keys %fcodes) {
my $fc = $featureCodes{$_} || 0;
printf "%6d (%2d) %s\n", $fcodes{$_}, $fc, $_;
}
}
# write country codes
open COUNTRY, '<', "$dbdir/$countryFile" or die "Error opening $dbdir/$countryFile\n";
my %cc;
while (<COUNTRY>) {
next if /^#/;
my @items = split /\t/;
next unless $haveCountry{$items[0]};
$cc{$items[4]} = $items[0];
die "country code error\n" if length $items[0] != 2;
$items[4] =~ tr/,//d; # remove any commas
print OUTFILE "$items[0]$items[4]\n";
if ($lang{$items[16]}) { # (16=geoID)
my $lkup = $lang{$items[16]};
my $key = $items[4]; # country name
$ccFlags{$flags{$items[16]}} = ($ccFlags{$flags{$items[16]}} || 0) + 1 if defined $flags{$items[16]};
foreach (@supportedLangs) {
next unless $$lkup{$_} and $$lkup{$_} ne $key; # (ignore if same)
$langLookups{$_}{$key} or $langLookups{$_}{$key} = [ ];
push @{$langLookups{$_}{$key}}, ",$$lkup{$_}";
}
}
}
close COUNTRY;
print OUTFILE "\0\0\0\0\x02\n"; # section terminator
# write regions
print OUTFILE "\n"; # (null region)
open REGION, '<', "$dbdir/$regionFile" or die "Error opening $dbdir/$regionFile\n";
my %region;
while (<REGION>) {
chomp;
my @items = split /\t/;
#items: 0=region code, 1=name, 2=ascii, 3=geoID
$items[0] =~ tr/.//d; # (remove "." separator)
next unless $haveRegion{$items[0]};
$region{$items[0]} = $items[1];
$items[1] =~ tr/,//d; # remove any commas
print OUTFILE "$items[1]\n";
if ($lang{$items[3]}) { # (3=geoID)
my $lkup = $lang{$items[3]};
my $key = $items[1]; # region name
my $cc = substr($items[0], 0, 2);
$rgnFlags{$flags{$items[3]}} = ($rgnFlags{$flags{$items[3]}} || 0) + 1 if defined $flags{$items[3]};
foreach (@supportedLangs) {
next unless $$lkup{$_} and $$lkup{$_} ne $key; # (ignore if same)
$langLookups{$_}{$key} or $langLookups{$_}{$key} = [ ];
push @{$langLookups{$_}{$key}}, "$cc,$$lkup{$_}";
}
}
}
close REGION;
print OUTFILE "\0\0\0\0\x03\n"; # section terminator
# write subregions
print OUTFILE "\n"; # (null admin2)
open ADMIN2, '<', "$dbdir/$admin2File" or die "Error opening $dbdir/$admin2File\n";
my %subregion;
while (<ADMIN2>) {
chomp;
my @items = split /\t/;
#items: 0=admin2 code, 1=name, 2=ascii, 3=geoID
$items[0] =~ s/\.//; # (remove first "." separator)
next unless $haveSubRgn{$items[0]};
$subregion{$items[0]} = $items[1];
$items[1] =~ tr/,//d; # remove any commas
print OUTFILE "$items[1]\n";
if ($lang{$items[3]}) { # (3=geoID)
my $lkup = $lang{$items[3]};
my $key = $items[1]; # region name
$subFlags{$flags{$items[3]}} = ($subFlags{$flags{$items[3]}} || 0) + 1 if defined $flags{$items[3]};
my $rc = $items[0];
$rc =~ s/\..*//; # (remove subregion code)
foreach (@supportedLangs) {
next unless $$lkup{$_} and $$lkup{$_} ne $key; # (ignore if same)
$langLookups{$_}{$key} or $langLookups{$_}{$key} = [ ];
push @{$langLookups{$_}{$key}}, "$rc,$$lkup{$_}";
}
}
}
close ADMIN2;
print OUTFILE "\0\0\0\0\x04\n"; # section terminator
# write timezones
print OUTFILE $_,"\n" foreach @tz;
print OUTFILE "\0\0\0\0\x05\n"; # section terminator
# write feature codes and optional names
foreach (@featureCodes) {
print OUTFILE $_;
print OUTFILE ' ', $featureNames{$_} if $featureNames{$_};
print OUTFILE "\n";
}
# write terminator and close Geolocation.dat
print OUTFILE "\0\0\0\0\0\n"; # file terminator
my $outSize = tell OUTFILE;
close OUTFILE;
# write language lookups
my $langSize = 0;
my $langDir = "$outDir/$geoLang";
# delete existing languages
unlink <"$langDir/*.pm">;
if ($noLang) {
rmdir $langDir;
} else {
my $n = scalar(keys %langLookups);
print "Writing $n language files to $outDir/$geoLang...\n";
mkdir $langDir, 0777;
my ($lng, $key, $str, $nm, $alt);
foreach $lng (sort keys %langLookups) { # ($lng = language code)
my $myLng = $lng;
$myLng =~ tr/-/_/;
my $lkup = $langLookups{$lng};
my $file = "$myLng.pm";
open OUT, ">$langDir/$file" or die "Error creating $file\n";
binmode OUT;
print OUT "# Geolocation language translations for $myLng\n";
print OUT "#\n# Based on Creative Commons database from geonames.org\n\n";
print OUT "%Image::ExifTool::GeoLang::${myLng}::Translate = (\n";
foreach $key (sort keys %$lkup) {
($nm = $key) =~ s/'/\\'/g;
# count entries and use the most common one, then add others with country+region ID's
# (entries in @$li are of the form: City:"CCRc,Sc,Alt", Sub:"CCRc,Alt", Rgn:"CC,Alt", Country:",Alt")
# (Rc = region code, Sc = subregion code)
my $li = $$lkup{$key};
my %count;
# sort by popularity of alternate name
foreach (@$li) {
my $val = $_;
$val =~ s/.*?,//;
$count{$val} = ($count{$val} || 0) + 1;
}
my @order = sort { $count{$b} <=> $count{$a} or length($a) <=> length($b) or $a cmp $b } keys %count;
my $first = 1;
foreach $alt (@order) {
foreach (sort @$li) {
my ($code,$val) = split ',', $_, 2;
# ($code will be empty for a country name, and 2 characters for a region name,
# and contain a "." for a city name)
next unless $val eq $alt; # don't add if alternate name is the same
die "Backslash in translated name" if $val =~ /\\/;
$val =~ s/'/\\'/g; # escape single quotes
if ($first and $val !~ /\(/) { # (don't add general translation if name is qualified with brackets)
print OUT "\t'$nm' => '$val',\n";
undef $first;
last;
}
# format for keys in language table
# City: "CCRgn,Subregion,City", "CCRgn,,City", "CC,City", ",City"
# Subregion: "CCRgn,Subregion,", "CCRgn,,"
# Region: "CCRgn,"
# Country: "CC,"
# Any: "Name"
if (not $code) {
# this is a country
$code = $cc{$key};
printf OUT "\t'$code,' => '$val',\n";
} elsif ($code !~ /\./) {
# this is a region or subregion
print OUT "\t'$code$nm,' => '$val',\n";
} else {
# this is a city
# use region/subregions name instead of code
my $sub = $subregion{$code} || '';
$sub =~ s/'/\\'/g;
$code =~ s/\..*//;
$code = substr($code,0,2) . $region{$code} if $region{$code};
$code =~ s/'/\\'/g;
print OUT "\t'$code,$sub,$nm' => '$val',\n";
}
}
}
}
if ($featureLang{$lng}) {
print OUT "\n\t# feature types\n";
foreach (sort keys %{$featureLang{$lng}}) {
my $ftype = $featureLang{$lng}{$_};
$ftype =~ s/'/\\'/g;
print OUT "\t$_ => '$ftype',\n"
}
}
print OUT ");\n\n1; #end\n";
$langSize += tell OUT;
close OUT;
}
if ($verbose) {
my @type = ( City => \%cityFlags, Region => \%rgnFlags, Subregion => \%subFlags, Country => \%ccFlags );
for (;;) {
my $type = shift @type or last;
my $flags = shift @type;
print "$type flags:\n";
printf(" 0x%.2x - %d\n", 0, $$flags{0} || 0);
my @label = qw(preferred short colloquial historic);
foreach my $bit (0..3) {
my $n = 0;
$_ & (1<<$bit) and $n += $$flags{$_} foreach keys %$flags;
printf(" 0x%.2x - %d (%s)\n", (1<<$bit), $n, shift(@label)) if $n;
}
}
}
}
print "Output file size(s):\n";
printf "%8.2f MB %s (%d entries)\n", $outSize / 1e6, $outFile, scalar(keys %coords);
printf "%8.2f MB %s\n", $altSize / 1e6, $outAltNames if $altSize;
printf "%8.2f MB %s/*.pm\n", $langSize / 1e6, $geoLang if $langSize;
printf "%8.2f MB Total\n", ($outSize + $altSize + $langSize) / 1e6 if $altSize or $langSize;
# end
+239
View File
@@ -0,0 +1,239 @@
#------------------------------------------------------------------------------
# File: acdsee.config
#
# Description: This config file defines ACDSee XMP region tags for writing.
# The following tags are created in the XMP-acdsee-rs group
#
# RegionInfoACDSee : The structured tag for the ACDSee regions
# (similar to XMP-mwg-rs:RegionInfo)
#
# The following tags are the width, height, and unit of the
# image at the time of processing when storing image region
# metadata. They are similar to the AppliedToDimensions tags
# of the MWG regions.
# ACDSeeRegionAppliedToDimensionsH : Height of the image
# ACDSeeRegionAppliedToDimensionsUnit : Unit of the image
# ACDSeeRegionAppliedToDimensionsW : Width of the image
#
# Actual region data, stored in an array. These flattened tags
# are treated as List Type tags. There are two region types,
# the ALYArea and the DLYArea. The ALYArea tags tags assigned
# by ACDSee and are usually square in dimensions. The DLYArea
# tags are both the tags assigned by ACDSee (but possibly
# rectangular instead of square) as well as any manual
# assigned tags. They are similar to the area tags of the MWG
# regions.
# ACDSeeRegionDLYAreaH : Height of DLY region
# ACDSeeRegionDLYAreaW : Width of DLY region
# ACDSeeRegionDLYAreaX : X centerpoint of DLY region
# ACDSeeRegionDLYAreaY : Y centerpoint of DLY region
# ACDSeeRegionALYAreaH : Height of ALY region
# ACDSeeRegionALYAreaW : Width of ALY region
# ACDSeeRegionALYAreaX : X centerpoint of ALY region
# ACDSeeRegionALYAreaY : Y centerpoint of ALY region
# ACDSeeRegionName : Name of region
# ACDSeeRegionType : Type of region
# ACDSeeRegionNameAssignType : How the type was assigned.
# "Manual" is the only known
# entry at this time
#
# Conversion tags. These tags can be used to convert other region
# type tags to ACDSee regions.
# MPRegion2ACDSeeRegion : Converts a Microsoft RegionInfoMP
# IPTCRegion2ACDSeeRegion : Converts an IPTC ImageRegion
# MWGRegion2ACDSeeRegion : Converts from a MWG RegionInfo
# ACDSeeRegion2MWGRegion : Converts to a MWG RegionInfo
#
# Usage: To set individual tags
# exiftool -config acdsee.config -ACDSEETAG=VALUE FILE ...
#
# To convert Microsoft Regions to ACDSee regions
# exiftool -config acdsee.config "-RegionInfoACDSee<MPRegion2ACDSeeRegion" File ...
# To convert IPTC regions to ACDSee regions
# exiftool -config acdsee.config "-RegionInfoACDSee<IPTCRegion2ACDSeeRegion" File ...
# To convert MWG Regions to ACDSee regions
# exiftool -config acdsee.config "-RegionInfoACDSee<MWGRegion2ACDSeeRegion" File ...
# To convert ACDSee Regions to MWG regions
# exiftool -config acdsee.config "-RegionInfo<ACDSeeRegion2MWGRegion" File ...
#
# Requires: ExifTool version 10.28 or later
#
# Revisions: 2020/01/28 - Bryan K. Williams (aka StarGeek) Created
# 2021/04/08 - BKW Added tags to convert from Microsoft, IPTC,
# and MWG regions to ACDSee regions based upon
# convert_regions.config. Expanded docs.
# Shortened ADCSee tag names and added shortcuts
# from original names to new names, for example
# "RegionInfoACDSeeAppliedToDimensions*" -> "ACDSeeRegionAppliedToDimensions*"
# "RegionInfoACDSeeRegionList* -> "ACDSeeRegion*"
# 2022/10/03 - PH Set group name properly to XMP-acdsee-rs
# 2024/03/19 - PH Moved XMP-acdsee-rs tags into the standard distribution,
# and added ACDSeeRegion2MWGRegion conversion
#------------------------------------------------------------------------------
use Data::Dumper;
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
# create an ACDSee RegionInfo structure from a Microsoft RegionInfoMP structure
MPRegion2ACDSeeRegion => {
Require => {
0 => 'RegionInfoMP',
1 => 'ImageWidth',
2 => 'ImageHeight',
},
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{Regions}}) {
my $name = $$rgn{PersonDisplayName};
next unless $$rgn{Rectangle} or defined $name;
my %newRgn = ( Type => 'Face' );
if (defined $name) {
# don't add ignored faces
next if $name eq 'ffffffffffffffff';
$newRgn{Name} = $name;
}
if ($$rgn{Rectangle}) {
my @rect = split /\s*,\s*/, $$rgn{Rectangle};
$newRgn{DLYArea} = {
X => $rect[0] + $rect[2]/2,
Y => $rect[1] + $rect[3]/2,
W => $rect[2],
H => $rect[3],
} if @rect == 4;
}
push @newRgns, \%newRgn;
}
return {
AppliedToDimensions => { W => $val[1], H => $val[2], Unit => 'pixel' },
RegionList => \@newRgns,
};
},
},
# create an ACDSee RegionInfo structure from an IPTC ImageRegion list
IPTCRegion2ACDSeeRegion => {
Require => {
0 => 'ImageRegion',
1 => 'ImageWidth',
2 => 'ImageHeight',
},
ValueConv => q{
my ($rgn, @newRgns);
my $rgns = ref $val[0] eq 'ARRAY' ? $val[0] : [ $val[0] ];
foreach $rgn (@$rgns) {
my %newRgn = ( Type => 'Face' );
if ($$rgn{RegionBoundary} and $$rgn{RegionBoundary}{RbShape} eq 'rectangle') {
my @rect = @{$$rgn{RegionBoundary}}{'RbX','RbY','RbW','RbH'};
if ($$rgn{RegionBoundary}{RbUnit} eq 'pixel') {
$rect[0] /= $val[1], $rect[2] /= $val[1];
$rect[1] /= $val[2]; $rect[3] /= $val[2];
}
$newRgn{'DLYArea'} = {
X => $rect[0] + $rect[2]/2,
Y => $rect[1] + $rect[3]/2,
W => $rect[2],
H => $rect[3],
};
} else {
next unless defined $$rgn{Name};
}
$newRgn{Name} = $$rgn{Name} if defined $$rgn{Name};
push @newRgns, \%newRgn;
}
return {
AppliedToDimensions => { 'W' => $val[1], 'H' => $val[2], 'Unit' => 'pixel' },
RegionList => \@newRgns,
};
},
},
# create an ACDSee RegionInfo structure from an MWG RegionInfo structure
MWGRegion2ACDSeeRegion => {
Require => {
0 => 'RegionInfo',
1 => 'ImageWidth',
2 => 'ImageHeight',
},
ValueConv => q{
my ($rgn, @newRgns);
my %newRgn;
foreach $rgn (@{$val[0]{RegionList}}) {
next unless $$rgn{Area} or defined $$rgn{Name};
my %newRgn;
if ($$rgn{Area}) {
$newRgn{'DLYArea'} = {
'X' => $$rgn{Area}{'X'},
'Y' => $$rgn{Area}{'Y'},
'W' => $$rgn{Area}{'W'},
'H' => $$rgn{Area}{'H'},
};
};
$newRgn{Name} = $$rgn{Name} if defined $$rgn{Name};
$newRgn{'Type'} = $$rgn{'Type'} if defined $$rgn{'Type'};
push @newRgns, \%newRgn;
}
return {
'AppliedToDimensions' => $val[0]{'AppliedToDimensions'},
RegionList => \@newRgns,
}
},
},
# create an MWG RegionInfo structure from an ACDSee RegionInfo
ACDSeeRegion2MWGRegion => {
Require => {
0 => 'RegionInfoACDSee',
1 => 'ImageWidth',
2 => 'ImageHeight',
},
ValueConv => q{
my ($rgn, @newRgns);
my %newRgn;
foreach $rgn (@{$val[0]{RegionList}}) {
next unless $$rgn{Area} or defined $$rgn{Name};
my %newRgn;
if ($$rgn{DLYArea}) {
$newRgn{Area} = {
'X' => $$rgn{DLYArea}{'X'},
'Y' => $$rgn{DLYArea}{'Y'},
'W' => $$rgn{DLYArea}{'W'},
'H' => $$rgn{DLYArea}{'H'},
};
};
$newRgn{Name} = $$rgn{Name} if defined $$rgn{Name};
$newRgn{'Type'} = $$rgn{'Type'} if defined $$rgn{'Type'};
push @newRgns, \%newRgn;
}
return {
'AppliedToDimensions' => $val[0]{'AppliedToDimensions'},
RegionList => \@newRgns,
}
},
},
####
},
);
# Shortcuts to old names added so as not to break previously used commands
%Image::ExifTool::UserDefined::Shortcuts = (
RegionInfoACDSeeAppliedToDimensionsH => 'ACDSeeRegionAppliedToDimensionsH',
RegionInfoACDSeeAppliedToDimensionsUnit => 'ACDSeeRegionAppliedToDimensionsUnit',
RegionInfoACDSeeAppliedToDimensionsW => 'ACDSeeRegionAppliedToDimensionsW',
RegionInfoACDSeeRegionListDLYAreaH => 'ACDSeeRegionDLYAreaH',
RegionInfoACDSeeRegionListDLYAreaW => 'ACDSeeRegionDLYAreaW',
RegionInfoACDSeeRegionListDLYAreaX => 'ACDSeeRegionDLYAreaX',
RegionInfoACDSeeRegionListDLYAreaY => 'ACDSeeRegionDLYAreaY',
RegionInfoACDSeeRegionListALGAreaH => 'ACDSeeRegionALGAreaH',
RegionInfoACDSeeRegionListALGAreaW => 'ACDSeeRegionALGAreaW',
RegionInfoACDSeeRegionListALGAreaX => 'ACDSeeRegionALGAreaX',
RegionInfoACDSeeRegionListALGAreaY => 'ACDSeeRegionALGAreaY',
RegionInfoACDSeeRegionListName => 'ACDSeeRegionName',
RegionInfoACDSeeRegionListType => 'ACDSeeRegionType',
RegionInfoACDSeeRegionListNameAssignType => 'ACDSeeRegionNameAssignType',
);
# Forced -struct option during debugging
#%Image::ExifTool::UserDefined::Options = (
# Struct => 1,
#);
#------------------------------------------------------------------------------
1; #end
+84
View File
@@ -0,0 +1,84 @@
#------------------------------------------------------------------------------
# File: age.config
#
# Description: Definition for a Composite "Age" tag to calculate age of person
# in image based on their birthday and the DateTimeOriginal or
# CreateDate of the image.
#
# Notes: The birthday date is set via the -userParam option, and is a
# string containing year, month, day, hour, minute and second.
# Only the year is required. By default the format of the
# returned Age value is exactly the same as the input birthday,
# with 2 digits for each parameter, however an AgeFormat user
# parameter may be used to define a printf-style format string
# for any desired output format (see fourth example below).
#
# If the specified birthday comes after the image date/time
# then the returned result is enclosed in brackets to indicate
# a negative time difference (see last example below).
#
# If birthday is not given, then the current date/time is assumed
# (in which case Age returns the age of the photo).
#
# Examples: (based on a DateTimeOriginal of "2005:08:27 18:21:00")
#
# > exiftool -config age.config -userparam birthday=1990:09:31 -age a.jpg
# Age : 14:10:26
#
# > exiftool -config age.config -userparam birthday=1990Y09M31D -age a.jpg
# Age : 14Y10M26D
#
# > exiftool -config age.config -userparam birthday="2000:01:02 03:45" -age a.jpg
# Age : 05:07:25 14:36
#
# > exiftool -config age.config -userparam birthday=2000:01:02 \
# -userparam ageformat="%d years" -age a.jpg
# Age : 5 years
#
# > exiftool -config age.config -userparam birthday=2005:09:26 -age a.jpg
# Age : (00:00:30)
#
# Requires: ExifTool version 9.90 or later
#
# Revisions: 2017/01/24 - P. Harvey Created
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
Age => {
Desire => {
0 => 'DateTimeOriginal',
1 => 'CreateDate',
},
ValueConv => q{
my $bday = $self->Options(UserParam => 'Birthday');
$bday or ($bday = TimeNow()) =~ s/[-+].*//;
my $date = $val[0] || $val[1] or return undef;
my @t0 = ($bday =~ /\d+/g);
my @t1 = ($date =~ /\d+/g);
return '<invalid birthday date>' unless $t0[0];
my ($i, @diff, $sign);
for ($i=0; $i<6; ++$i) {
last unless defined $t0[$i];
my $dt = $t1[$i] - $t0[$i];
$sign or $sign = ($dt <=> 0);
push @diff, $dt * $sign;
}
require 'Image/ExifTool/Shift.pl';
my $base = $sign < 0 ? \@t1 : \@t0;
my @wrap = (0, 12, DaysInMonth($$base[1]||1,$$base[0]), 24, 60, 60);
for ($i=$#diff; $i>0; --$i) {
$diff[$i] < 0 and $diff[$i] += $wrap[$i], --$diff[$i-1];
}
$bday =~ s/\d+/sprintf '%.2d', shift @diff/ge;
return $sign < 0 ? "($bday)" : $bday;
},
PrintConv => q{
my $fmt = $self->Options(UserParam => 'AgeFormat') or return $val;
sprintf($fmt, $val =~ /\d+/g);
},
},
},
);
1; #end
+520
View File
@@ -0,0 +1,520 @@
#------------------------------------------------------------------------------
# File: bibble.config
#
# Description: This config file defines Bibble XMP tags for writing.
#
# Usage: exiftool -config bibble.config -BIBBLETAG=VALUE FILE ...
#
# Requires: ExifTool version 10.28 or later
#
# Revisions: 2016/09/25 - P. Harvey Created
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
dmf => {
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::dmf' },
},
},
);
%Image::ExifTool::UserDefined::dmf = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-dmf', 2 => 'Image' },
NAMESPACE => { 'dmf' => 'http://www.bibblelabs.com/DigitalMasterFile/1.0/' },
WRITABLE => 'string',
versionCount => {
Name => 'DMFCount',
Writable => 'integer',
},
versions => {
Name => 'DMF',
List => 'Seq',
Struct => {
NAMESPACE => { 'dmfversion' => 'http://www.bibblelabs.com/DigitalMasterFileVersion/1.0/' },
software => { },
softwareVersion => { },
versionName => { },
settings => {
Struct => {
NAMESPACE => { 'bset' => 'http://www.bibblelabs.com/BibbleSettings/5.0/' },
settingsVersion => { },
respectsTransform => { },
curLayer => { },
layers => {
List => 'Seq',
Struct => {
NAMESPACE => { 'blay' => 'http://www.bibblelabs.com/BibbleLayers/5.0/' },
layerId => { },
layerPos => { },
name => { },
enabled => { },
options => {
Struct => {
NAMESPACE => { 'bopt' => 'http://www.bibblelabs.com/BibbleOpt/5.0/' },
'optionchanged' => { },
'hasSettings' => { },
'metaDirty' => { },
'version' => { },
'colormode' => { },
'colormode' => { },
'workingspace' => { },
'whiteauto' => { },
'whitetype' => { },
'lwhitetype' => { },
'lmr' => { },
'lmb' => { },
'whitered' => { },
'whitegreen' => { },
'whiteblue' => { },
'whiteowbr' => { },
'whiteowbb' => { },
'autolevel' => { },
'shadowval' => { },
'highlightval' => { },
'exposureval' => { },
'highlightrecval' => { },
'highlightrange' => { },
'blackPoint' => { },
'fillamount' => { },
'fillrange' => { },
'autorotate' => { },
'rotateangle' => { },
'sharpensense' => { },
'newsharpen' => { },
'sharpenon' => { },
'pcenabled' => { },
'pctintmeta' => { },
'PCNOn' => { },
'PCNPreset' => { },
'PCNStrength' => { },
'PCNDetail' => { },
'red' => { },
'green' => { },
'blue' => { },
'sat' => { },
'cont' => { },
'hue' => { },
'vibe' => { },
'useHSL' => { },
'useHSV' => { },
'invertRegions' => { },
'layerOpacity' => { },
'selective_color' => { },
'curveson' => { },
'curves_m_cn' => { },
'curves_m_cy' => { },
'curves_m_cx' => { },
'curves_m_imid' => { },
'curves_m_olo' => { },
'curves_m_ilo' => { },
'curves_m_ihi' => { },
'curves_m_ohi' => { },
'kelvin' => { },
'tint' => { },
'okelvin' => { },
'otint' => { },
'lkelvin' => { },
'ltint' => { },
'ckelvin' => { },
'ctint' => { },
'cropon' => { },
'croplocked' => { },
'cropstyle' => { },
'cropleft' => { },
'croptop' => { },
'cropheight' => { },
'cropwidth' => { },
'cropdpi' => { },
'cropstickydpi' => { },
'cropstickyx' => { },
'cropstickyy' => { },
'cropmenuitem' => { },
'croppercent' => { },
'Date' => { },
'DigitizedDateTime' => { },
'title' => { },
'Priority' => { },
'Category' => { },
'SupplementalCategory' => { },
'creator' => { },
'AuthorsPosition' => { },
'rights' => { },
'Credit' => { },
'description' => { },
'CaptionWriter' => { },
'City' => { },
'State' => { },
'Country' => { },
'CountryCode' => { },
'Headline' => { },
'Instructions' => { },
'TransmissionReference' => { },
'Source' => { },
'subject' => { },
'IntellectualGenre' => { },
'CiAdrCity' => { },
'CiAdrCtry' => { },
'CiAdrExtadr' => { },
'CiAdrPcode' => { },
'CiAdrRegion' => { },
'CiEmailWork' => { },
'CiTelWork' => { },
'CiUrlWork' => { },
'UsageTerms' => { },
'Location' => { },
'SubjectCode' => { },
'Scene' => { },
'tag' => { },
'keywordlist' => { },
'rating' => { },
'label' => { },
'warpon' => { },
'warpa' => { },
'warpb' => { },
'warpc' => { },
'warpresize' => { },
'warpfocal' => { },
'warpcaon' => { },
'warpcarc' => { },
'warpcaby' => { },
'vignetteon' => { },
'vignetterad' => { },
'vignetteamt' => { },
'profilemake' => { },
'profilemodel' => { },
'profilelens' => { },
'lens' => { },
'GPSVersionID' => { },
'GPSLatitude' => { },
'GPSLongitude' => { },
'GPSAltitudeRef' => { },
'GPSAltitude' => { },
'GPSTimeStamp' => { },
'GPSSatellites' => { },
'GPSStatus' => { },
'GPSMeasureMode' => { },
'GPSDateStamp' => { },
'GPSMapDatum' => { },
'GPSAreaInformation' => { },
'GPSProcessingMethod' => { },
'bMirrorOn' => { },
'bInvertOn' => { },
'rn_enabled' => { },
'rn_smooth_enabled' => { },
'rn_threshold' => { },
'rn_limit' => { },
'lc_enabled' => { },
'lc_radius' => { },
'lc_strength' => { },
'lc_debug' => { },
'enableInputProfile' => { },
'inputProfile' => { },
'redeyeSize' => { },
'redeyeTrack' => { },
'redeyeTrackStra' => { },
'redeyeTrackCrop' => { },
'redeyeEnable' => { },
'watermark_mode' => { },
'watermark_imageFilename' => { },
'watermark_text' => { },
'watermark_fontName' => { },
'watermark_fontColor' => { },
'watermark_fontItalic' => { },
'watermark_fontUnderline' => { },
'watermark_fontBold' => { },
'watermark_fontStrikeout' => { },
'watermark_alignment' => { },
'watermark_basesize' => { },
'watermark_rotation' => { },
'watermark_size' => { },
'watermark_hpos' => { },
'watermark_vpos' => { },
'watermark_opacity' => { },
'watermark_hskew' => { },
'watermark_vskew' => { },
'watermark_hproject' => { },
'watermark_vproject' => { },
'watermark_hstretch' => { },
'watermark_vstretch' => { },
'watermark_enabled' => { },
'ferd.bez_enabled' => { },
'ferd.bez_Early' => { },
'ferd.bez_HCL' => { },
'ferd.bez_opacity' => { },
'ferd.bez_saturation' => { },
'ferd.bez_lighten' => { },
'ferd.bez_lightengamma' => { },
'ferd.bez_midi' => { },
'ferd.bez_sigcontrast' => { },
'ferd.bez_sigmiddle' => { },
'ferd.bez_shadows' => { },
'ferd.bez_lowmids' => { },
'ferd.bez_greys' => { },
'ferd.bez_highmids' => { },
'ferd.bez_highlights' => { },
'ferd.bez_shadows4' => { },
'ferd.bez_lowmids4' => { },
'ferd.bez_highmids4' => { },
'ferd.bez_highlights4' => { },
'ferd.ferd_bez_enabled' => { },
'ferd.ferd_bez_RGB' => { },
'ferd.ferd_bez_BW' => { },
'ferd.ferd_bez_lighten' => { },
'ferd.ferd_bez_lightengamma' => { },
'ferd.ferd_bez_midi' => { },
'ferd.ferd_bez_blak' => { },
'ferd.ferd_bez_sigcontrast' => { },
'ferd.ferd_bez_sigmiddle' => { },
'ferd.ferd_bez_contrast' => { },
'ferd.ferd_bez_centre' => { },
'ferd.ferd_bez_shadows' => { },
'ferd.ferd_bez_lowmids' => { },
'ferd.ferd_bez_greys' => { },
'ferd.ferd_bez_highmids' => { },
'ferd.ferd_bez_highlights' => { },
'ferd.ferd_bez_shadows4' => { },
'ferd.ferd_bez_lowmids4' => { },
'ferd.ferd_bez_highmids4' => { },
'ferd.ferd_bez_highlights4' => { },
'Grid_kb.thirds' => { },
'Grid_kb.goldenrat' => { },
'Grid_kb.goldenspir' => { },
'Grid_kb.squaregrid' => { },
'Grid_kb.spiralcenter' => { },
'Grid_kb.gridsize' => { },
'Grid_kb.gridxcenter' => { },
'Grid_kb.gridycenter' => { },
'Mix3.mix3_enabled' => { },
'Mix3.mix3_early' => { },
'Mix3.mix3_exposure' => { },
'Mix3.mix3_red' => { },
'Mix3.mix3_green' => { },
'Mix3.mix3_blue' => { },
'SiliconBonk.SiliconBonkOn' => { },
'SiliconBonk.SiliconBonkHighlights' => { },
'SiliconBonk.SiliconBonkH' => { },
'SiliconBonk.SiliconBonkL' => { },
'SiliconBonk.SiliconBonkContrast' => { },
'SiliconBonk.SiliconBonkMid' => { },
'SiliconBonk.SiliconBonkSat' => { },
'SiliconBonk.SiliconBonkC0L' => { },
'SiliconBonk.SiliconBonkC1L' => { },
'SiliconBonk.SiliconBonkC2L' => { },
'SiliconBonk.SiliconBonkC3L' => { },
'SiliconBonk.SiliconBonkC4L' => { },
'SiliconBonk.SiliconBonkC5L' => { },
'Vigne_kb.kbv_enabled' => { },
'Vigne_kb.kbv_size' => { },
'Vigne_kb.kbv_strength' => { },
'Vigne_kb.kbv_ccol' => { },
'Vigne_kb.kbv_falloff' => { },
'Vigne_kb.kbv_shape' => { },
'Vigne_kb.kbv_horzcenter' => { },
'Vigne_kb.kbv_vertcenter' => { },
'Vigne_kb.kbv_factor' => { },
'Vigne_kb.kbv_trans' => { },
'Vigne_kb.kbv_adjustcrop' => { },
'Vigne_kb.kbv_colenabled' => { },
'Vigne_kb.kbv_col' => { },
'Vigne_kb.kbv_preview' => { },
'Vigne_kb.kbv_desat' => { },
'Vigne_kb.kbv_desaturate' => { },
'WaveletDenoise2.bSphWaveletDenoiseon' => { },
'WaveletDenoise2.bSphWaveletDenoiseThresL' => { },
'WaveletDenoise2.bSphWaveletDenoiseLowL' => { },
'WaveletDenoise2.bSphWaveletDenoiseThresC' => { },
'WaveletDenoise2.bSphWaveletDenoiseLowC' => { },
'WaveletDenoise2.bSphWaveletDenoiseDePepper' => { },
'WaveletDenoise2.bSphWaveletDenoiseShowEdge' => { },
'WaveletSharpen2.bSphWaveletUsmon' => { },
'WaveletSharpen2.bSphWaveletUsmRadius' => { },
'WaveletSharpen2.bSphWaveletUsmAmount' => { },
'WaveletSharpen2.bSphWaveletUsmThreshold' => { },
'WaveletSharpen2.bSphWaveletUsmClarity' => { },
'WaveletSharpen2.bSphWaveletLLenable' => { },
'WaveletSharpen2.bSphWaveletLLStrength' => { },
'WaveletSharpen2.bSphWaveletLLiter' => { },
'WaveletSharpen2.bSphWaveletMCStrength' => { },
'WaveletSharpen2.bSphWaveleton' => { },
'WaveletSharpen2.bSphWaveletAmount' => { },
'WaveletSharpen2.bSphWaveletRadius' => { },
'WaveletSharpen2.bSphWaveletSharpenDePepper' => { },
'WaveletSharpen2.bSphWaveletEdge' => { },
'WaveletSharpen2.bSphWaveletSharpenClarity' => { },
'WaveletSharpen2.bSphWaveleton2' => { },
'WaveletSharpen2.bSphWaveletAmount2' => { },
'WaveletSharpen2.bSphWaveletRadius2' => { },
'WaveletSharpen2.bSphWaveletSharpenDePepper2' => { },
'WaveletSharpen2.bSphWaveletEdge2' => { },
'WaveletSharpen2.bSphWaveletSharpenClarity2' => { },
'zChannelMixerGroup.zcmEnable' => { },
'zChannelMixerGroup.zcmbw' => { },
'zChannelMixerGroup.zcmbwa' => { },
'zChannelMixerGroup.zcmlockbw' => { },
'zChannelMixerGroup.zcmlockcolor' => { },
'zChannelMixerGroup.zcmrr' => { },
'zChannelMixerGroup.zcmrg' => { },
'zChannelMixerGroup.zcmrb' => { },
'zChannelMixerGroup.zcmgr' => { },
'zChannelMixerGroup.zcmgg' => { },
'zChannelMixerGroup.zcmgb' => { },
'zChannelMixerGroup.zcmbr' => { },
'zChannelMixerGroup.zcmbg' => { },
'zChannelMixerGroup.zcmbb' => { },
'zFramePlug.zframeSize1' => { },
'zFramePlug.zframeColor1' => { },
'zFramePlug.zframeSize2' => { },
'zFramePlug.zframeColor2' => { },
'zFramePlug.zframeSize3' => { },
'zFramePlug.zframeColor3' => { },
'zFramePlug.zframeSize4' => { },
'zFramePlug.zframeColor4' => { },
'zFramePlug.zframeSize5' => { },
'zFramePlug.zframeColor5' => { },
'zFramePlug.zframeDummy' => { },
'zFramePlug.zframeEnable' => { },
'zFramePlug.zframeEnable1' => { },
'zFramePlug.zframeEnable2' => { },
'zFramePlug.zframeEnable3' => { },
'zFramePlug.zframeEnable4' => { },
'zFramePlug.zframeEnable5' => { },
'zFramePlug.zframeCalibration' => { },
'zFramePlug.zframeRatio1' => { },
'zFramePlug.zframeRatio2' => { },
'zFramePlug.zframeRatio3' => { },
'zFramePlug.zframeRatio4' => { },
'zFramePlug.zframeRatio5' => { },
'zFramePlug.xPos1' => { },
'zFramePlug.yPos1' => { },
'zFramePlug.xPos2' => { },
'zFramePlug.yPos2' => { },
'zFramePlug.xPos3' => { },
'zFramePlug.yPos3' => { },
'zFramePlug.xPos4' => { },
'zFramePlug.yPos4' => { },
'zFramePlug.xPos5' => { },
'zFramePlug.yPos5' => { },
'zFramePlug.relativeTo' => { },
'zFramePlug.place' => { },
'Zone_kb.kbz_enabled' => { },
'Zone_kb.kbz_highlight' => { },
'zPerspectorPlug.zpersEnable' => { },
'zPerspectorPlug.zpersRotate' => { },
'zPerspectorPlug.zpersGridEnable' => { },
'zPerspectorPlug.zpersGrid' => { },
'zPerspectorPlug.zpersTopLeft' => { },
'zPerspectorPlug.zpersTopRight' => { },
'zPerspectorPlug.zpersLeftTop' => { },
'zPerspectorPlug.zpersRightTop' => { },
'zPerspectorPlug.zpersBottomLeft' => { },
'zPerspectorPlug.zpersBottomRight' => { },
'zPerspectorPlug.zpersLeftBottom' => { },
'zPerspectorPlug.zpersRightBottom' => { },
'zPerspectorPlug.zpersmirror' => { },
'zPerspectorPlug.zpersMirrorOffset' => { },
'zPerspectorPlug.zpersCanvasResize' => { },
'zShadowPlug.direction' => { },
'zShadowPlug.zshadowEnable' => { },
'zShadowPlug.dummy' => { },
'zShadowPlug.size' => { },
'zShadowPlug.scale' => { },
'zShadowPlug.edge' => { },
'zShadowPlug.sizeBg' => { },
'zShadowPlug.color' => { },
'zShadowPlug.colorBg' => { },
'zShadowPlug.relativeTo' => { },
'zShadowPlug.xPos' => { },
'zShadowPlug.yPos' => { },
'zSoftenPlug.softenEnable' => { },
'zSoftenPlug.softenradius' => { },
'zSoftenPlug.softenorton' => { },
'zSoftenPlug.softencombo' => { },
'zSoftenPlug.softenVignette' => { },
'zSoftenPlug.softenProof' => { },
'zSoftenPlug.softenvigSize' => { },
'zSoftenPlug.softenvigShape' => { },
'zSoftenPlug.softenvigFeather' => { },
'zSoftenPlug.softenvigXpos' => { },
'zSoftenPlug.softenvigYpos' => { },
'zSoftenPlug.softenvigRotate' => { },
'zTextPlug.zTextOn' => { },
'zTextPlug.italic' => { },
'zTextPlug.bold' => { },
'zTextPlug.underline' => { },
'zTextPlug.strikeout' => { },
'zTextPlug.overline' => { },
'zTextPlug.size' => { },
'zTextPlug.xpos' => { },
'zTextPlug.ypos' => { },
'zTextPlug.rotate' => { },
'zTextPlug.font' => { },
'zTextPlug.text' => { },
'zTextPlug.opacity' => { },
'zTextPlug.stretch' => { },
'zTextPlug.color' => { },
'zTextPlug.shearv' => { },
'zTextPlug.shearh' => { },
'zTextPlug.scalev' => { },
'zTextPlug.scaleh' => { },
'zTextPlug.projectv' => { },
'zTextPlug.projecth' => { },
'zTextPlug.basesize' => { },
'zTextPlug.textalign' => { },
'zTextPlug.textposh' => { },
'zTextPlug.textposv' => { },
'zTextPlug.shadowEnable' => { },
'zTextPlug.shadowDirection' => { },
'zTextPlug.shadowShift' => { },
'zTextPlug.shadowIntensity' => { },
'zTextPlug.shadowColor' => { },
'blplug.bbwenabled' => { },
'blplug.bbwspotA' => { },
'blplug.bbwspotB' => { },
'blplug.bbwhueA' => { },
'blplug.bbwfuzzyA' => { },
'blplug.bbwcolorA' => { },
'blplug.bbwhueB' => { },
'blplug.bbwcolorB' => { },
'blplug.bbwfuzzyB' => { },
'blplug.bbwmode' => { },
'Equalizer_kb.kbs_enabled' => { },
'Equalizer_kb.kbs_bw' => { },
'Equalizer_kb.kbs_redlum' => { },
'Equalizer_kb.kbs_yellowlum' => { },
'Equalizer_kb.kbs_orangelum' => { },
'Equalizer_kb.kbs_greenlum' => { },
'Equalizer_kb.kbs_cyanlum' => { },
'Equalizer_kb.kbs_bluelum' => { },
'Equalizer_kb.kbs_magentalum' => { },
'Equalizer_kb.kbs_redhue' => { },
'Equalizer_kb.kbs_yellowhue' => { },
'Equalizer_kb.kbs_orangehue' => { },
'Equalizer_kb.kbs_greenhue' => { },
'Equalizer_kb.kbs_cyanhue' => { },
'Equalizer_kb.kbs_bluehue' => { },
'Equalizer_kb.kbs_magentahue' => { },
'Equalizer_kb.kbs_redsat' => { },
'Equalizer_kb.kbs_yellowsat' => { },
'Equalizer_kb.kbs_orangesat' => { },
'Equalizer_kb.kbs_greensat' => { },
'Equalizer_kb.kbs_cyansat' => { },
'Equalizer_kb.kbs_bluesat' => { },
'Equalizer_kb.kbs_magentasat' => { },
'Equalizer_kb.kbs_redvib' => { },
'Equalizer_kb.kbs_yellowvib' => { },
'Equalizer_kb.kbs_orangevib' => { },
'Equalizer_kb.kbs_greenvib' => { },
'Equalizer_kb.kbs_cyanvib' => { },
'Equalizer_kb.kbs_bluevib' => { },
'Equalizer_kb.kbs_magentavib' => { },
},
},
},
},
},
},
},
},
);
1; #end
+234
View File
@@ -0,0 +1,234 @@
#------------------------------------------------------------------------------
# File: convert_regions.config
#
# Description: User-defined Composite tag definitions to allow conversion of
# face regions between Microsoft Windows Live Photo Gallery (WLPG),
# Metadata Working Group (MWG), and IPTC Extension formats
#
# Usage: 1) Convert from MP WLPG or IPTC regions to MWG regions:
#
# exiftool -config convert_regions.config "-RegionInfo<MPRegion2MWGRegion" FILE
#
# 2) Convert from MWG or IPTC to MP WLPG regions:
#
# exiftool -config convert_regions.config "-RegionInfoMP<MWGRegion2MPRegion" FILE
#
# 3) Convert from MWG or MP WLPG to IPTC regions:
#
# exiftool -config convert_regions.config "-ImageRegion<MWGRegion2IPTCRegion" FILE
#
# Requires: ExifTool version 11.74 or later
#
# Revisions: 2012/12/27 - P. Harvey Created
# 2013/02/20 - PH Don't add ignored MP faces
# 2017/02/13 - PH Handle MP regions without Rectangle or Name entries
# 2019/10/26 - PH Added support for the new IPTC ImageRegion
# 2021/05-27 - PH Changed a few tag names and added shortcuts for
# backward compatibility
#
# References: http://www.metadataworkinggroup.org/specs/
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
# create an MWG RegionInfo structure from a Microsoft RegionInfoMP structure
MPRegion2MWGRegion => {
Require => {
0 => 'RegionInfoMP',
1 => 'ImageWidth',
2 => 'ImageHeight',
},
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{Regions}}) {
my $name = $$rgn{PersonDisplayName};
next unless $$rgn{Rectangle} or defined $name;
my %newRgn = ( Type => 'Face' );
if (defined $name) {
# don't add ignored faces
next if $name eq 'ffffffffffffffff';
$newRgn{Name} = $name;
}
if ($$rgn{Rectangle}) {
my @rect = split /\s*,\s*/, $$rgn{Rectangle};
$newRgn{Area} = {
X => $rect[0] + $rect[2]/2,
Y => $rect[1] + $rect[3]/2,
W => $rect[2],
H => $rect[3],
Unit => 'normalized',
} if @rect == 4;
}
push @newRgns, \%newRgn;
}
return {
AppliedToDimensions => { W => $val[1], H => $val[2], Unit => 'pixel' },
RegionList => \@newRgns,
};
},
},
# create an MWG RegionInfo structure from an IPTC ImageRegion list
IPTCRegion2MWGRegion => {
Name => 'MPRegion2MWGRegion',
Require => {
0 => 'ImageRegion',
1 => 'ImageWidth',
2 => 'ImageHeight',
},
ValueConv => q{
my ($rgn, @newRgns);
my $rgns = ref $val[0] eq 'ARRAY' ? $val[0] : [ $val[0] ];
foreach $rgn (@$rgns) {
my %newRgn = ( Type => 'Face' );
if ($$rgn{RegionBoundary} and $$rgn{RegionBoundary}{RbShape} eq 'rectangle') {
my @rect = @{$$rgn{RegionBoundary}}{'RbX','RbY','RbW','RbH'};
if ($$rgn{RegionBoundary}{RbUnit} eq 'pixel') {
$rect[0] /= $val[1], $rect[2] /= $val[1];
$rect[1] /= $val[2]; $rect[3] /= $val[2];
}
$newRgn{Area} = {
X => $rect[0] + $rect[2]/2,
Y => $rect[1] + $rect[3]/2,
W => $rect[2],
H => $rect[3],
Unit => 'normalized',
};
} else {
next unless defined $$rgn{Name};
}
$newRgn{Name} = $$rgn{Name} if defined $$rgn{Name};
push @newRgns, \%newRgn;
}
return {
AppliedToDimensions => { W => $val[1], H => $val[2], Unit => 'pixel' },
RegionList => \@newRgns,
};
},
},
# create a Microsoft RegionInfoMP structure from an MWG RegionInfo structure
MWGRegion2MPRegion => {
Require => 'RegionInfo',
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{RegionList}}) {
next unless $$rgn{Area} or defined $$rgn{Name};
my %newRgn;
if ($$rgn{Area}) {
my @rect = @{$$rgn{Area}}{'X','Y','W','H'};
$rect[0] -= $rect[2]/2;
$rect[1] -= $rect[3]/2;
$newRgn{Rectangle} = join(', ', @rect);
}
$newRgn{PersonDisplayName} = $$rgn{Name} if defined $$rgn{Name};
push @newRgns, \%newRgn;
}
return { Regions => \@newRgns };
},
},
# create a Microsoft RegionInfoMP structure from an IPTC ImageRegion list
IPTCRegion2MPRegion => {
Name => 'MWGRegion2MPRegion',
Require => {
0 => 'ImageRegion',
1 => 'ImageWidth',
2 => 'ImageHeight',
},
ValueConv => q{
my ($rgn, @newRgns);
my $rgns = ref $val[0] eq 'ARRAY' ? $val[0] : [ $val[0] ];
foreach $rgn (@$rgns) {
my %newRgn;
if ($$rgn{RegionBoundary} and $$rgn{RegionBoundary}{RbShape} eq 'rectangle') {
my @rect = @{$$rgn{RegionBoundary}}{'RbX','RbY','RbW','RbH'};
if ($$rgn{RegionBoundary}{RbUnit} eq 'pixel') {
$rect[0] /= $val[1], $rect[2] /= $val[1];
$rect[1] /= $val[2]; $rect[3] /= $val[2];
}
$newRgn{Rectangle} = join(', ', @rect);
} else {
next unless defined $$rgn{Name};
}
$newRgn{PersonDisplayName} = $$rgn{Name} if defined $$rgn{Name};
push @newRgns, \%newRgn;
}
return { Regions => \@newRgns };
},
},
# create an IPTC ImageRegion list from an MWG RegionInfo structure
MWGRegion2IPTCRegion => {
Require => 'RegionInfo',
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{RegionList}}) {
next unless $$rgn{Area} or defined $$rgn{Name};
my %newRgn;
if ($$rgn{Area}) {
my @rect = @{$$rgn{Area}}{'X','Y','W','H'};
$rect[0] -= $rect[2]/2;
$rect[1] -= $rect[3]/2;
$newRgn{RegionBoundary} = {
RbShape => 'rectangle',
RbUnit => 'relative',
RbX => $rect[0],
RbY => $rect[1],
RbW => $rect[2],
RbH => $rect[3],
};
}
$newRgn{Name} = $$rgn{Name} if defined $$rgn{Name};
push @newRgns, \%newRgn;
}
return \@newRgns;
},
},
# create an IPTC ImageRegion list from a Microsoft RegionInfoMP structure
MPRegion2IPTCRegion => {
Name => 'MWGRegion2IPTCRegion',
Require => 'RegionInfoMP',
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{Regions}}) {
my $name = $$rgn{PersonDisplayName};
next unless $$rgn{Rectangle} or defined $name;
my %newRgn;
if (defined $name) {
# don't add ignored faces
next if $name eq 'ffffffffffffffff';
$newRgn{Name} = $name;
}
if ($$rgn{Rectangle}) {
my @rect = split /\s*,\s*/, $$rgn{Rectangle};
$newRgn{RegionBoundary} = {
RbShape => 'rectangle',
RbUnit => 'relative',
RbX => $rect[0],
RbY => $rect[1],
RbW => $rect[2],
RbH => $rect[3],
} if @rect == 4;
}
push @newRgns, \%newRgn;
}
return \@newRgns;
},
},
},
);
%Image::ExifTool::UserDefined::Shortcuts = (
MyRegion => 'MPRegion2MWGRegion',
MyRegion2 => 'IPTCRegion2MWGRegion',
MyRegionMP => 'MWGRegion2MPRegion',
MyRegionMP2 => 'IPTCRegion2MPRegion',
MyRegionIPTC => 'MWGRegion2IPTCRegion',
MyRegionIPTC2 => 'MPRegion2IPTCRegion',
);
1; #end
+70
View File
@@ -0,0 +1,70 @@
#------------------------------------------------------------------------------
# File: cuepointlist.config
#
# Description: ExifTool config file to generate list of cue points and labels
# in WAV audio files
#
# Usage: exiftool -config cuepointlist.config -cuepointlist -b FILE
#
# Requires: ExifTool version 12.25 or later
#
# Revisions: 2021-04-20 - P. Harvey Created
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
CuePointList => {
Require => {
0 => 'CuePoints',
1 => 'SampleRate',
},
Desire => {
2 => 'CuePointLabel',
3 => 'CuePointNotes',
4 => 'LabeledText',
},
ValueConv => q{
SetByteOrder('II');
my (%lbl, %rgn, %rtyp, %rlbl, %note, $pos, $i);
# get labels if available
for ($i=1; defined $val[2]; ++$i) {
$lbl{$1} = $2 if $val[2] =~ /^(\d+) (.*)/ and length $2;
$val[2] = $self->GetValue("CuePointLabel ($i)");
}
# get notes if available
for ($i=1; defined $val[3]; ++$i) {
$note{$1} = $2 if $val[3] =~ /^(\d+) (.*)/ and length $2;
$val[3] = $self->GetValue("CuePointNotes ($i)");
}
# get regions if available
for ($i=1; defined $val[4]; ++$i) {
if ($val[4] =~ /^(\d+) (\d+) '(.*)' \d+ \d+ \d+ \d+ (.*)/) {
$rgn{$1} = $2;
$rtyp{$1} = $3;
$rlbl{$1} = $4;
}
$val[4] = $self->GetValue("LabeledText ($i)");
}
my $buff = "Cue\tStart\tEnd\tLabel\tPurpose\tText\tNotes\n";
for ($pos=4; $pos+24<=length(${$val[0]}); $pos+=24) {
my $n = Get32u($val[0], $pos);
my $start = Get32u($val[0], $pos + 4);
my (@lbl, $lbl);
push @lbl, $lbl{$n} if defined $lbl{$n};
push @lbl, $rlbl{$n} if defined $rlbl{$n};
push @lbl, '-', $note{$n} if defined $note{$n};
my $lbl = join ' ', @lbl;
$buff .= sprintf("%d\t%.3f\t%.3f\t%s\t%s\t%s\t%s\n",
$n, $start/$val[1], ($start+($rgn{$n}||0))/$val[1],
defined($lbl{$n}) ? $lbl{$n} : '',
defined($rtyp{$n}) ? $rtyp{$n} : '',
defined($rlbl{$n}) ? $rlbl{$n} : '',
defined($note{$n}) ? $note{$n} : '');
}
return $buff;
},
},
},
);
1; # end
+56
View File
@@ -0,0 +1,56 @@
#------------------------------------------------------------------------------
# File: depthmap.config
#
# Description: Composite tag definitions to extract DepthMap and ConfidenceMap
# images from Google Dynamic-depth images
#
# Usage: exiftool -config depthmap.config -W %d%f_%t.%s -depthmap -confidencemap -b DIR
#
# Requires: ExifTool version 11.88 or later
#
# Revisions: 2020/02/20 - P. Harvey Created
#------------------------------------------------------------------------------
sub GetTrailerImage($$)
{
my ($val, $type) = @_;
my @uri = ref $$val[1] ? @{$$val[1]} : $$val[1];
my @len = ref $$val[2] ? @{$$val[2]} : $$val[2];
my $start = 0;
for (my $i=0; $i<@uri; ++$i) {
if ($uri[$i] =~ /$type/) {
my $img = substr(${$$val[0]}, $start, $len[$i]);
return \$img;
}
$start += $len[$i];
}
return undef;
}
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
DepthMap => {
Require => {
0 => 'Trailer',
1 => 'ContainerDirectoryItemDataURI',
2 => 'ContainerDirectoryItemLength',
},
ValueConv => 'GetTrailerImage(\@val, "depthmap")',
},
ConfidenceMap => {
Require => {
0 => 'Trailer',
1 => 'ContainerDirectoryItemDataURI',
2 => 'ContainerDirectoryItemLength',
},
ValueConv => 'GetTrailerImage(\@val, "confidencemap")',
},
},
);
%Image::ExifTool::UserDefined::Options = (
RequestTags => 'Trailer',
);
#------------------------------------------------------------------------------
1; #end
+381
View File
@@ -0,0 +1,381 @@
#------------------------------------------------------------------------------
# File: example.config --> ~/.ExifTool_config
#
# Description: Sample user configuration file for Image::ExifTool
#
# Notes: This example file shows how to define your own shortcuts and
# add new EXIF, IPTC, XMP, PNG, MIE and Composite tags, as well
# as how to specify preferred lenses for the LensID tag, and
# define new file types and default ExifTool API options and
# command-line arguments.
#
# Note that unknown tags may be extracted even if they aren't
# defined, but tags must be defined to be written. Also note
# that it is possible to override an existing tag definition
# with a user-defined tag.
#
# To activate this file, rename it to ".ExifTool_config" and
# place it in your home directory or the exiftool application
# directory. (On Mac and some Windows systems this must be done
# via the command line since the GUI's may not allow filenames to
# begin with a dot. Use the "rename" command in Windows or "mv"
# on the Mac.) This causes ExifTool to automatically load the
# file when run. Your home directory is determined by the first
# defined of the following environment variables:
#
# 1. EXIFTOOL_HOME
# 2. HOME
# 3. HOMEDRIVE + HOMEPATH
# 4. (the current directory)
#
# Alternatively, the -config option of the exiftool application
# may be used to load a specific configuration file (note that
# this must be the first option on the command line):
#
# exiftool -config example.config ...
#
# This example file defines the following 16 new tags as well as
# a number of Shortcut and Composite tags:
#
# 1. EXIF:NewEXIFTag
# 2. GPS:GPSPitch
# 3. GPS:GPSRoll
# 4. IPTC:NewIPTCTag
# 5. XMP-xmp:NewXMPxmpTag
# 6. XMP-exif:GPSPitch
# 7. XMP-exif:GPSRoll
# 8. XMP-xxx:NewXMPxxxTag1
# 9. XMP-xxx:NewXMPxxxTag2
# 10. XMP-xxx:NewXMPxxxTag3
# 11. XMP-xxx:NewXMPxxxStruct
# 12. PNG:NewPngTag1
# 13. PNG:NewPngTag2
# 14. PNG:NewPngTag3
# 15. MIE-Meta:NewMieTag1
# 16. MIE-Test:NewMieTag2
#
# For detailed information on the definition of tag tables and
# tag information hashes, see lib/Image/ExifTool/README.
#------------------------------------------------------------------------------
# Shortcut tags are used when extracting information to simplify
# commonly used commands. They can be used to represent groups
# of tags, or to provide an alias for a tag name.
%Image::ExifTool::UserDefined::Shortcuts = (
MyShortcut => ['exif:createdate','exposuretime','aperture'],
MyAlias => 'FocalLengthIn35mmFormat',
);
# NOTE: All tag names used in the following tables are case sensitive.
# The %Image::ExifTool::UserDefined hash defines new tags to be added
# to existing tables.
%Image::ExifTool::UserDefined = (
# All EXIF tags but GPS are added to the Main table, and WriteGroup is
# used to specify where the tag is written (defaulting to ExifIFD). Note
# that when reading custom EXIF tags, the same config file must be used
# to be able to see them with the given names. Without the config file
# they may only be seen as unknown tags with the -u option.
'Image::ExifTool::Exif::Main' => {
# Example 1. EXIF:NewEXIFTag
0xd000 => {
Name => 'NewEXIFTag',
Writable => 'int16u',
WriteGroup => 'IFD0',
},
# add more user-defined EXIF tags here...
},
# the Geotag feature writes GPSPitch and GPSRoll tags, but these
# aren't standard EXIF so we define custom tags here:
'Image::ExifTool::GPS::Main' => {
# Example 2. GPS:GPSPitch
0xd000 => {
Name => 'GPSPitch',
Writable => 'rational64s',
},
# Example 3. GPS:GPSRoll
0xd001 => {
Name => 'GPSRoll',
Writable => 'rational64s',
},
},
# IPTC tags are added to a specific record type (eg. application record):
# (Note: IPTC tag ID's are limited to the range 0-255)
'Image::ExifTool::IPTC::ApplicationRecord' => {
# Example 4. IPTC:NewIPTCTag
160 => {
Name => 'NewIPTCTag',
Format => 'string[0,16]',
},
# add more user-defined IPTC ApplicationRecord tags here...
},
# XMP tags may be added to existing namespaces:
'Image::ExifTool::XMP::xmp' => {
# Example 5. XMP-xmp:NewXMPxmpTag
NewXMPxmpTag => { Groups => { 2 => 'Author' } },
# add more user-defined XMP-xmp tags here...
},
# special Geotag tags for XMP-exif:
'Image::ExifTool::XMP::exif' => {
# Example 6. XMP-exif:GPSPitch
GPSPitch => { Writable => 'rational', Groups => { 2 => 'Location' } },
# Example 7. XMP-exif:GPSRoll
GPSRoll => { Writable => 'rational', Groups => { 2 => 'Location' } },
},
# new XMP namespaces (eg. xxx) must be added to the Main XMP table:
'Image::ExifTool::XMP::Main' => {
# namespace definition for examples 8 to 11
xxx => { # <-- must be the same as the NAMESPACE prefix
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::xxx',
# (see the definition of this table below)
},
},
# add more user-defined XMP namespaces here...
},
# new PNG tags are added to the PNG::TextualData table:
'Image::ExifTool::PNG::TextualData' => {
# Example 12. PNG:NewPngTag1
NewPngTag1 => { }, # (Writable is 'string' by default for XMP tags)
# Example 13. PNG:NewPngTag2
NewPngTag2 => { iTXt => 1 }, # (force this tag to be written as iTXt)
# Example 14. PNG:NewPngTag3
NewPngTag3 => { },
},
# add a new MIE tag (NewMieTag1) and group (MIE-Test) to MIE-Meta
# (Note: MIE group names must NOT end with a number)
'Image::ExifTool::MIE::Meta' => {
# Example 15. MIE-Meta:NewMieTag1
NewMieTag1 => {
Writable => 'rational64u',
Units => [ 'cm', 'in' ],
},
# new MIE "Test" group for example 16
Test => {
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::MIETest',
DirName => 'MIE-Test',
},
},
},
# Composite tags are added to the Composite table:
'Image::ExifTool::Composite' => {
# Composite tags have values that are derived from the values of
# other tags. The Require/Desire elements below specify constituent
# tags that must/may exist, and the keys of these hashes are used as
# indices in the @val array of the ValueConv expression to access the
# numerical (-n) values of these tags. Print-converted values are
# accessed via the @prt array. All Require'd tags must exist for
# the Composite tag to be evaluated. If no Require'd tags are
# specified, then at least one of the Desire'd tags must exist. See
# the Composite table in Image::ExifTool::Exif for more examples,
# and lib/Image/ExifTool/README for all of the details.
# The first few examples demonstrate simplifications which may be
# used if only one tag is Require'd or Desire'd:
# 1) the Require lookup may be replaced with a simple tag name
# 2) "$val" may be used to represent "$val[0]" in the expression
FileExtension => {
Require => 'FileName',
ValueConv => '$val=~/\.([^.]*)$/; $1',
},
# override CircleOfConfusion tag to use D/1750 instead of D/1440
CircleOfConfusion => {
Require => 'ScaleFactor35efl',
Groups => { 2 => 'Camera' },
ValueConv => 'sqrt(24*24+36*36) / ($val * 1750)',
# an optional PrintConv may be used to format the value
PrintConv => 'sprintf("%.3f mm",$val)',
},
# generate a description for this file type
FileTypeDescription => {
Require => 'FileType',
ValueConv => 'GetFileType($val,1) || $val',
},
# calculate physical image size based on resolution
PhysicalImageSize => {
Require => {
0 => 'ImageWidth',
1 => 'ImageHeight',
2 => 'XResolution',
3 => 'YResolution',
4 => 'ResolutionUnit',
},
ValueConv => '$val[0]/$val[2] . " " . $val[1]/$val[3]',
# (the @prt array contains print-formatted values)
PrintConv => 'sprintf("%.1fx%.1f $prt[4]", split(" ",$val))',
},
# [advanced] select largest JPEG preview image
BigImage => {
Groups => { 2 => 'Preview' },
Desire => {
0 => 'JpgFromRaw',
1 => 'PreviewImage',
2 => 'OtherImage',
# (DNG and A100 ARW may be have 2 PreviewImage's)
3 => 'PreviewImage (1)',
# (if the MPF has 2 previews, MPImage3 could be the larger one)
4 => 'MPImage3',
5 => 'JpgFromRaw2', # in RW2 from newer Panasonic models
},
# ValueConv may also be a code reference
# Inputs: 0) reference to list of values, 1) ExifTool object
ValueConv => sub {
my $val = shift;
my ($image, $bigImage, $len, $bigLen);
foreach $image (@$val) {
next unless ref $image eq 'SCALAR';
# check for JPEG image (or "Binary data" if -b not used)
next unless $$image =~ /^(\xff\xd8\xff|Binary data (\d+))/;
$len = $2 || length $$image; # get image length
# save largest image
next if defined $bigLen and $bigLen >= $len;
$bigLen = $len;
$bigImage = $image;
}
return $bigImage;
},
},
# **** ADD ADDITIONAL COMPOSITE TAG DEFINITIONS HERE ****
},
);
# This is a basic example of the definition for a new XMP namespace.
# This table is referenced through a SubDirectory tag definition
# in the %Image::ExifTool::UserDefined definition above.
# The namespace prefix for these tags is 'xxx', which corresponds to
# an ExifTool family 1 group name of 'XMP-xxx'.
%Image::ExifTool::UserDefined::xxx = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-xxx', 2 => 'Image' },
NAMESPACE => { 'xxx' => 'http://ns.myname.com/xxx/1.0/' },
WRITABLE => 'string', # (default to string-type tags)
# Example 8. XMP-xxx:NewXMPxxxTag1 (an alternate-language tag)
# - replace "NewXMPxxxTag1" with your own tag name (eg. "MyTag")
NewXMPxxxTag1 => { Writable => 'lang-alt' },
# Example 9. XMP-xxx:NewXMPxxxTag2 (a string tag in the Author category)
NewXMPxxxTag2 => { Groups => { 2 => 'Author' } },
# Example 10. XMP-xxx:NewXMPxxxTag3 (an unordered List-type tag)
NewXMPxxxTag3 => { List => 'Bag' },
# Example 11. XMP-xxx:NewXMPxxxStruct (a structured tag)
# - example structured XMP tag
NewXMPxxxStruct => {
# the "Struct" entry defines the structure fields
Struct => {
# optional namespace prefix and URI for structure fields
# (required only if different than NAMESPACE above)
# --> multiple entries may exist in this namespace lookup,
# with the last one alphabetically being the default for
# the fields, but each field may have a "Namespace"
# element to specify which prefix to use
NAMESPACE => { 'test' => 'http://x.y.z/test/' },
# optional structure name (used for warning messages only)
STRUCT_NAME => 'MyStruct',
# optional rdf:type property for the structure
TYPE => 'http://x.y.z/test/xystruct',
# structure field definitions (very similar to tag definitions)
X => { Writable => 'integer' },
Y => { Writable => 'integer' },
# a nested structure...
Things => {
List => 'Bag',
Struct => {
NAMESPACE => { thing => 'http://x.y.z/thing/' },
What => { },
Where => { },
},
},
},
List => 'Seq', # structures may also be elements of a list
},
# Each field in the structure has a corresponding flattened tag that is
# generated automatically with an ID made from a concatenation of the
# original structure tag ID and the field name (after capitalizing the
# first letter of the field name if necessary). The Name and/or
# Description of these flattened tags may be changed if desired, but all
# other tag properties are taken from the structure field definition.
# The "Flat" flag must be used when setting the Name or Description of a
# flattened tag. For example:
NewXMPxxxStructX => { Name => 'SomeOtherName', Flat => 1 },
);
# the namespace may be registered so ExifTool generates the expected family 1
# group names when reading if the UserDefined namespace uses a different prefix
require Image::ExifTool::XMP;
Image::ExifTool::XMP::RegisterNamespace(\%Image::ExifTool::UserDefined::xxx);
# Adding a new MIE group requires a few extra definitions
use Image::ExifTool::MIE;
%Image::ExifTool::UserDefined::MIETest = (
%Image::ExifTool::MIE::tableDefaults, # default MIE table entries
GROUPS => { 0 => 'MIE', 1 => 'MIE-Test', 2 => 'Document' },
WRITE_GROUP => 'MIE-Test',
# Example 16. MIE-Test:NewMieTag2
NewMieTag2 => { }, # new user-defined tag in MIE-Test group
);
# A special 'Lenses' list can be defined to give priority to specific lenses
# in the logic to determine a lens model for the Composite:LensID tag
@Image::ExifTool::UserDefined::Lenses = (
'Sigma AF 10-20mm F4-5.6 EX DC',
'Tokina AF193-2 19-35mm f/3.5-4.5',
);
# User-defined file types to recognize
%Image::ExifTool::UserDefined::FileTypes = (
XXX => { # <-- the extension of the new file type (case insensitive)
# BaseType specifies the format upon which this file is based (case
# sensitive). If BaseType is defined, then the file will be fully
# supported, and in this case the Magic pattern should not be defined
BaseType => 'TIFF',
MIMEType => 'image/x-xxx',
Description => 'My XXX file type',
# if the BaseType is writable by ExifTool, then the new file type
# will also be writable unless otherwise specified, like this:
Writable => 0,
},
YYY => {
# without BaseType, the file will be recognized but not supported
Magic => '0123abcd', # regular expression to match at start of file
MIMEType => 'application/test',
Description => 'My YYY file type',
},
ZZZ => {
# if neither BaseType nor Magic are defined, the file will be
# recognized by extension only. MIMEType will be application/unknown
# unless otherwise specified
Description => 'My ZZZ file type',
},
# if only BaseType is specified, then the following simplified syntax
# may be used. In this example, files with extension "TTT" will be
# processed as JPEG files
TTT => 'JPEG',
);
# Change default location for writing QuickTime tags so Keys is preferred
# (by default, the PREFERRED levels are: ItemList=2, UserData=1, Keys=0)
use Image::ExifTool::QuickTime;
$Image::ExifTool::QuickTime::Keys{PREFERRED} = 3;
# Specify default ExifTool API options
# (see the Options function documentation for available options)
%Image::ExifTool::UserDefined::Options = (
CoordFormat => '%.6f', # change default GPS coordinate format
Duplicates => 1, # make -a default for the exiftool app
GeoMaxHDOP => 4, # ignore GPS fixes with HDOP > 4
RequestAll => 3, # request additional tags not normally generated
);
# Specify default exiftool command-line arguments
# - inserted before all other options except -config
# - applies to all -execute'd commands
@Image::ExifTool::UserDefined::Arguments = (
'-i', 'HIDDEN', # ignore hidden files by default (names beginning with ".")
);
# Add user-defined cities to the Geolocation lookup
@Image::ExifTool::UserDefined::Geolocation = (
# (city,region,subregion,country_code,country,timezone,feature_code,population,lat,lon)
['Sinemorets','Burgas','Obshtina Tsarevo','BG','','Europe/Sofia','PPL',400,42.06115,27.97833],
);
#------------------------------------------------------------------------------
1; #end
+114
View File
@@ -0,0 +1,114 @@
#------------------------------------------------------------------------------
# File: fotoware.config
#
# Description: This config file defines Fotoware XMP tags for writing.
#
# Notes: Length limits are imposed according to Fotoware limitations when
# writing string values, but these may be disabled with the -n
# option or by adding a "#" to the tag name. However, beware that
# longer strings may cause unpredictable results in Fotoware
# software.
#
# Use of this file will not bring full Fotoware 'experience'.
# Fotostation writes these tags not only into XMP but also in IIM
# and even Exif spaces. Communication with older Fotoware systems
# may be broken when using only XMP.
#
# Also note that there are potential problems with character
# encoding on systems with mixed environments, depending on
# Fotoware software settings.
#
# Usage: exiftool -config fotoware.config -FOTOWARETAG=VALUE FILE ...
#
# Requires: ExifTool version 7.00 or later
#
# Revisions: 2012/09/19 - P. Harvey Created
# 2016/09/24 - Mikolaj Machowski updated with new Fotostation tags
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
fwl => {
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::fwl' },
},
fwr => {
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::fwr' },
},
fwc => {
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::fwc' },
},
fwu => {
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::fwu' },
},
},
);
%Image::ExifTool::UserDefined::fwl = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-fwl', 2 => 'Image' },
NAMESPACE => { 'fwl' => 'http://ns.fotoware.com/iptcxmp-legacy/1.0/' },
WRITABLE => 'string',
# limit maximum lengths of string values
CreatedTime => { PrintConvInv => 'substr($val,0,16)' },
EditStatus => { PrintConvInv => 'substr($val,0,64)' },
FixtureIdentifier=> { PrintConvInv => 'substr($val,0,1024)' },
LocalCaption => { PrintConvInv => 'substr($val,0,2000)' },
ObjectCycle => { PrintConvInv => 'substr($val,0,32)' },
ProgramVersion => { PrintConvInv => 'substr($val,0,10)' },
ReferenceNumber => { PrintConvInv => 'substr($val,0,256)' },
ReferenceService => { PrintConvInv => 'substr($val,0,256)' },
ReferenceDate => {
Groups => { 2 => 'Time' },
Writable => 'date',
Shift => 'Time',
PrintConv => '$self->ConvertDateTime($val)',
PrintConvInv => '$self->InverseDateTime($val,undef,1)',
},
ReleaseDate => {
Groups => { 2 => 'Time' },
Writable => 'date',
Shift => 'Time',
PrintConv => '$self->ConvertDateTime($val)',
PrintConvInv => '$self->InverseDateTime($val,undef,1)',
},
ReleaseTime => { PrintConvInv => 'substr($val,0,16)' },
);
%Image::ExifTool::UserDefined::fwr = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-fwr', 2 => 'Image' },
NAMESPACE => { 'fwr' => 'http://ns.fotoware.com/iptcxmp-reserved/1.0/' },
WRITABLE => 'string',
Classify => { PrintConvInv => 'substr($val,0,256)' },
DocumentText => { PrintConvInv => 'substr($val,0,2000)' },
Exif => { PrintConvInv => 'substr($val,0,1024)' },
History => { PrintConvInv => 'substr($val,0,256)' },
ImageNotes => { PrintConvInv => 'substr($val,0,256)' },
JobId => { PrintConvInv => 'substr($val,0,256)' },
OwnerId => { PrintConvInv => 'substr($val,0,256)' },
ShortUniqeId => { PrintConvInv => 'substr($val,0,256)' },
ContentValue => { PrintConvInv => 'substr($val,0,256)' },
UniqueId => { PrintConvInv => 'substr($val,0,256)' },
MasterDocumentId => { PrintConvInv => 'substr($val,0,256)' },
);
%Image::ExifTool::UserDefined::fwc = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-fwc', 2 => 'Image' },
NAMESPACE => { 'fwc' => 'http://ns.fotoware.com/iptcxmp-custom/1.0/' },
WRITABLE => 'string',
# generate CustomField1 through CustomField20 tags
map { 'CustomField' . $_ => {
PrintConvInv => 'substr($val,0,256)',
} } (1 .. 20),
);
%Image::ExifTool::UserDefined::fwu = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-fwu', 2 => 'Image' },
NAMESPACE => { 'fwu' => 'http://ns.fotoware.com/iptcxmp-user/1.0/' },
WRITABLE => 'string',
# generate UserDefined1 through UserDefined255 tags
map { 'UserDefined' . $_ => {
PrintConvInv => 'substr($val,0,256)',
} } (1 .. 255),
);
1; #end
+56
View File
@@ -0,0 +1,56 @@
#------------------------------------------------------------------------------
# File: frameCount.config
#
# Description: ExifTool config file to extract MP4 video FrameCount
#
# Usage: exiftool -config frameCount.config -frameCount FILE
#
# Requires: ExifTool version 7.99 or later
#
# Revisions: 2022-09-22 - P. Harvey Created
#
# Notes: Enables Unknown option to extract the required SampleSizes atom
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
'FrameCount' => {
Require => {
0 => 'HandlerType',
},
Desire => {
1 => 'SampleSizes',
2 => 'CompactSampleSizes',
},
Groups => { 2 => 'Video' },
ValueConv => q{
my ($i, $tag, $ptr);
my $key = 'HandlerType';
# find video track number
for ($i=1; defined $val[0]; ++$i) {
last if $val[0] eq 'Video Track';
$key = "HandlerType ($i)";
$val[0] = $self->GetValue($key);
}
my $trk = $self->GetGroup($key, 1);
# search for SampleSizes or CompactSampleSizes for this track
foreach $tag ('SampleSizes', 'CompactSampleSizes') {
$key = $tag;
for ($i=1; ; ++$i) {
$ptr = $self->GetValue($key);
last unless $ptr;
last if $self->GetGroup($key, 1) eq $trk;
$key = "$tag ($i)";
}
last if $ptr;
}
return undef unless $ptr;
return unpack('x8N', $$ptr);
},
},
},
);
%Image::ExifTool::UserDefined::Options = (
Unknown => 1, # (otherwise SampleSizes won't be extracted)
);
+256
View File
@@ -0,0 +1,256 @@
#------------------------------------------------------------------------------
# File: gps2utm.config
#
# Description: Generate UTM tags from GPS information
#
# Requires: ExifTool version 7.00 or later
#
# Notes: Uses GPSMapDatum, GPSLatitude and GPSLongitude to generate
# UTMCoordinates, UTMZone, UTMEasting and UTMNorthing. If
# GPSMapDatum is not available then "WGS84" is assumed.
#
# Example: > exiftool -config gps2utm.config "-utm*" t/images/GPS.jpg
# UTM Coordinates : 30U 569475.596m E 6094180.754m N
# UTM Easting : 569475.595558165
# UTM Northing : 6094180.75443061
# UTM Zone : 30U
#
# Caveats: When used to convert EXIF GPS coordinates, the reference
# direction tags (GPSLatitudeRef/GPSLongitudeRef) must exist or
# the calculated UTM coordinates may be in the wrong hemisphere
#
# Revisions: 2016/03/08 - Bryan K. Williams (aka StarGeek) Created
# 2016/03/09 - PH removed library dependency and re-organized
#------------------------------------------------------------------------------
my $deg2rad = 3.14159265358979 / 180;
sub tan($)
{
return sin($_[0]) / cos($_[0]);
}
#===============================================================================
# the following code is by Graham Crookham:
# http://search.cpan.org/~grahamc/Geo-Coordinates-UTM/ (version 0.11)
# remove all markup from an ellipsoid name, to increase the chance
# that a match is found.
sub _cleanup_name($)
{ my $copy = lc(shift);
for($copy)
{ s/\([^)]+\)//g; # remove text between parentheses
s/[\s-]//g; # no blanks or dashes
}
$copy;
}
# Ellipsoid array (name,equatorial radius,square of eccentricity)
# Same data also as hash with key eq name (in variations)
my (@Ellipsoid, %Ellipsoid);
BEGIN { # Initialize this before other modules get a chance
@Ellipsoid =
( [ "Airy", 6377563, 0.00667054]
, [ "Australian National", 6378160, 0.006694542]
, [ "Bessel 1841", 6377397, 0.006674372]
, [ "Bessel 1841 Nambia", 6377484, 0.006674372]
, [ "Clarke 1866", 6378206, 0.006768658]
, [ "Clarke 1880", 6378249, 0.006803511]
, [ "Everest 1830 India", 6377276, 0.006637847]
, [ "Fischer 1960 Mercury", 6378166, 0.006693422]
, [ "Fischer 1968", 6378150, 0.006693422]
, [ "GRS 1967", 6378160, 0.006694605]
, [ "GRS 1980", 6378137, 0.00669438]
, [ "Helmert 1906", 6378200, 0.006693422]
, [ "Hough", 6378270, 0.00672267]
, [ "International", 6378388, 0.00672267]
, [ "Krassovsky", 6378245, 0.006693422]
, [ "Modified Airy", 6377340, 0.00667054]
, [ "Modified Everest", 6377304, 0.006637847]
, [ "Modified Fischer 1960", 6378155, 0.006693422]
, [ "South American 1969", 6378160, 0.006694542]
, [ "WGS 60", 6378165, 0.006693422]
, [ "WGS 66", 6378145, 0.006694542]
, [ "WGS-72", 6378135, 0.006694318]
, [ "WGS-84", 6378137, 0.00669438 ]
, [ "Everest 1830 Malaysia", 6377299, 0.006637847]
, [ "Everest 1956 India", 6377301, 0.006637847]
, [ "Everest 1964 Malaysia and Singapore", 6377304, 0.006637847]
, [ "Everest 1969 Malaysia", 6377296, 0.006637847]
, [ "Everest Pakistan", 6377296, 0.006637534]
, [ "Indonesian 1974", 6378160, 0.006694609]
, [ "Arc 1950", 6378249.145,0.006803481]
, [ "NAD 27",6378206.4,0.006768658]
, [ "NAD 83",6378137,0.006694384]
);
# calc ecc as
# a = semi major axis
# b = semi minor axis
# e^2 = (a^2-b^2)/a^2
# For clarke 1880 (Arc1950) a=6378249.145 b=6356514.966398753
# e^2 (40682062155693.23 - 40405282518051.34) / 40682062155693.23
# e^2 = 0.0068034810178165
foreach my $el (@Ellipsoid)
{ my ($name, $eqrad, $eccsq) = @$el;
$Ellipsoid{$name} = $el;
$Ellipsoid{_cleanup_name $name} = $el;
}
}
# Returns "official" name, equator radius and square eccentricity
# The specified name can be numeric (for compatibility reasons) or
# a more-or-less exact name
# Examples: my($name, $r, $sqecc) = ellipsoid_info 'wgs84';
# my($name, $r, $sqecc) = ellipsoid_info 'WGS 84';
# my($name, $r, $sqecc) = ellipsoid_info 'WGS-84';
# my($name, $r, $sqecc) = ellipsoid_info 'WGS-84 (new specs)';
# my($name, $r, $sqecc) = ellipsoid_info 22;
sub ellipsoid_info($)
{ my $id = shift;
my $el = $id !~ m/\D/
? $Ellipsoid[$id-1] # old system counted from 1
: $Ellipsoid{$id} || $Ellipsoid{_cleanup_name $id};
defined $el ? @$el : ();
}
# Expects Ellipsoid Number or name, Latitude, Longitude
# (Latitude and Longitude in decimal degrees)
# Returns UTM Zone, UTM Easting, UTM Northing
sub latlon_to_utm(@)
{ my ($ellips, $latitude, $longitude) = @_;
die("Longitude value ($longitude) invalid\n")
if $longitude < -180 || $longitude > 180;
my $long2 = $longitude - int(($longitude + 180)/360) * 360;
my $zone = _latlon_zone_number($latitude, $long2);
_latlon_to_utm($ellips || 'WGS84', $zone, $latitude, $long2);
}
sub _latlon_zone_number
{ my ($latitude, $long2) = @_;
my $zone = int( ($long2 + 180)/6) + 1;
if($latitude >= 56.0 && $latitude < 64.0 && $long2 >= 3.0 && $long2 < 12.0)
{ $zone = 32;
}
if($latitude >= 72.0 && $latitude < 84.0) {
$zone = ($long2 >= 0.0 && $long2 < 9.0) ? 31
: ($long2 >= 9.0 && $long2 < 21.0) ? 33
: ($long2 >= 21.0 && $long2 < 33.0) ? 35
: ($long2 >= 33.0 && $long2 < 42.0) ? 37
: $zone;
}
return $zone;
}
sub _latlon_to_utm
{ my ($ellips, $zone, $latitude, $long2) = @_;
my ($name, $radius, $eccentricity) = ellipsoid_info $ellips
or die("Ellipsoid value ($ellips) invalid\n");
my $lat_radian = $deg2rad * $latitude;
my $long_radian = $deg2rad * $long2;
my $k0 = 0.9996; # scale
my $longorigin = ($zone - 1)*6 - 180 + 3;
my $longoriginradian = $deg2rad * $longorigin;
my $eccentprime = $eccentricity/(1-$eccentricity);
my $N = $radius / sqrt(1-$eccentricity * sin($lat_radian)*sin($lat_radian));
my $T = tan($lat_radian) * tan($lat_radian);
my $C = $eccentprime * cos($lat_radian)*cos($lat_radian);
my $A = cos($lat_radian) * ($long_radian - $longoriginradian);
my $M = $radius
* ( ( 1 - $eccentricity/4 - 3 * $eccentricity * $eccentricity/64
- 5 * $eccentricity * $eccentricity * $eccentricity/256
) * $lat_radian
- ( 3 * $eccentricity/8 + 3 * $eccentricity * $eccentricity/32
+ 45 * $eccentricity * $eccentricity * $eccentricity/1024
) * sin(2 * $lat_radian)
+ ( 15 * $eccentricity * $eccentricity/256 +
45 * $eccentricity * $eccentricity * $eccentricity/1024
) * sin(4 * $lat_radian)
- ( 35 * $eccentricity * $eccentricity * $eccentricity/3072
) * sin(6 * $lat_radian)
);
my $utm_easting = $k0*$N*($A+(1-$T+$C)*$A*$A*$A/6
+ (5-18*$T+$T*$T+72*$C-58*$eccentprime)*$A*$A*$A*$A*$A/120)
+ 500000.0;
my $utm_northing= $k0 * ( $M + $N*tan($lat_radian) * ( $A*$A/2+(5-$T+9*$C+4*$C*$C)*$A*$A*$A*$A/24 + (61-58*$T+$T*$T+600*$C-330*$eccentprime) * $A*$A*$A*$A*$A*$A/720));
$utm_northing += 10000000.0 if $latitude < 0;
my $utm_letter
= ( 84 >= $latitude && $latitude >= 72) ? 'X'
: ( 72 > $latitude && $latitude >= 64) ? 'W'
: ( 64 > $latitude && $latitude >= 56) ? 'V'
: ( 56 > $latitude && $latitude >= 48) ? 'U'
: ( 48 > $latitude && $latitude >= 40) ? 'T'
: ( 40 > $latitude && $latitude >= 32) ? 'S'
: ( 32 > $latitude && $latitude >= 24) ? 'R'
: ( 24 > $latitude && $latitude >= 16) ? 'Q'
: ( 16 > $latitude && $latitude >= 8) ? 'P'
: ( 8 > $latitude && $latitude >= 0) ? 'N'
: ( 0 > $latitude && $latitude >= -8) ? 'M'
: ( -8 > $latitude && $latitude >= -16) ? 'L'
: (-16 > $latitude && $latitude >= -24) ? 'K'
: (-24 > $latitude && $latitude >= -32) ? 'J'
: (-32 > $latitude && $latitude >= -40) ? 'H'
: (-40 > $latitude && $latitude >= -48) ? 'G'
: (-48 > $latitude && $latitude >= -56) ? 'F'
: (-56 > $latitude && $latitude >= -64) ? 'E'
: (-64 > $latitude && $latitude >= -72) ? 'D'
: (-72 > $latitude && $latitude >= -80) ? 'C'
: die("Latitude ($latitude) out of UTM range\n");
$zone .= $utm_letter;
($zone, $utm_easting, $utm_northing);
}
# End Graham Crookham code
#===============================================================================
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
UTMCoordinates => {
Desire => {
0 => 'GPSMapDatum',
},
Require => {
1 => 'GPSLatitude',
2 => 'GPSLongitude',
},
ValueConv => 'join " ", latlon_to_utm(@val)',
PrintConv => 'sprintf("%s %.3fm E %.3fm N", split(" ", $val))',
},
UTMZone => {
Require => 'UTMCoordinates',
ValueConv => 'my @a=split(" ",$val); $a[0]',
},
UTMEasting => {
Require => 'UTMCoordinates',
ValueConv => 'my @a=split(" ",$val); $a[1]',
},
UTMNorthing => {
Require => 'UTMCoordinates',
ValueConv => 'my @a=split(" ",$val); $a[2]',
},
},
);
#------------------------------------------------------------------------------
1; #end
+161
View File
@@ -0,0 +1,161 @@
#------------------------------------------------------------------------------
# File: Guano.config
#
# Description: User-defined Composite tag definitions to extract individual entries
# from the RIFF:Guano text block.
#
# Requires exiftool version 12.63+
#
# See GUANO - Grand Unified Acoustic Notation Ontology
# https://github.com/riggsd/guano-spec/blob/master/guano_specification.md
#
# The code itself is simply a regex match. If other entries are needed,
# then all that needs to be done is to copy/paste one of the blocks, change
# the name and edit the regex
#
# Examples:
# This will list the Make and Model from the Guano text block, if they exist
# exiftool -config Guano.config -GuanoModel -GuanoMake /path/to/files/
#
# Lists all the Guano entries in the Guano text block
# exiftool -config Guano.config -Guano* /path/to/files/
#
# Revisions: 2023/06/09 - Bryan K. Williams (aka StarGeek) Created
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
GuanoVersion => {
Require => 'Guano',
ValueConv => '$val =~ /GUANO\|Version:\s+(.*)/m ? $1 : undef',
},
GuanoMake => {
Require => 'Guano',
ValueConv => '$val =~ /Make:\s+(.*)/m ? $1 : undef',
},
GuanoModel => {
Require => 'Guano',
ValueConv => '$val =~ /Model:\s+(.*)/m ? $1 : undef',
},
GuanoFirmwareVersion => {
Require => 'Guano',
ValueConv => '$val =~ /Firmware Version:\s+(.*)/m ? $1 : undef',
},
GuanoSerial => {
Require => 'Guano',
ValueConv => '$val =~ /Serial:\s+(.*)/m ? $1 : undef',
},
GuanoTimestamp => {
Require => 'Guano',
Groups => { 2 => 'Time' },
ValueConv => '$val =~ /Timestamp:\s+(.*)/m ? $1 : undef',
PrintConv => '$self->ConvertDateTime($val)',
},
GuanoLocPosition => {
Require => 'Guano',
Groups => { 2 => 'Location' },
ValueConv => '$val =~ /Loc Position:\s+(.*)/m ? $1 : undef',
PrintConv => q{
require Image::ExifTool::GPS;
my @v = split ' ', $val;
return Image::ExifTool::GPS::ToDMS($self, $v[0], 1, "N") . ', ' .
Image::ExifTool::GPS::ToDMS($self, $v[1], 1, "E");
},
},
GuanoLocElevation => {
Require => 'Guano',
Groups => { 2 => 'Location' },
ValueConv => '$val =~ /Loc Elevation:\s+(.*)/m ? $1 : undef',
},
GuanoTemperatureInt => {
Require => 'Guano',
ValueConv => '$val =~ /Temperature Int:\s+(.*)/m ? $1 : undef',
},
GuanoFilterHP => {
Require => 'Guano',
ValueConv => '$val =~ /^Filter HP:\s+(.*)/m ? $1 : undef',
},
GuanoAnabatBatteryVoltage => {
Require => 'Guano',
ValueConv => '$val =~ /Anabat\|Battery voltage:\s+(.*)/m ? $1 : undef',
},
GuanoAnabatMicrophone => {
Require => 'Guano',
ValueConv => '$val =~ /Anabat\|Microphone:\s+(.*)/m ? $1 : undef',
},
GuanoAnabatActivation => {
Require => 'Guano',
ValueConv => '$val =~ /Anabat\|Activation:\s+(.*)/m ? $1 : undef',
},
GuanoAnabatZcSensitivity => {
Require => 'Guano',
ValueConv => '$val =~ /Anabat\|Zc Sensitivity:\s+(.*)/m ? $1 : undef',
},
GuanoAnabatTriggerMinFreq => {
Require => 'Guano',
ValueConv => '$val =~ /Anabat\|Trigger min freq:\s+(.*)/m ? $1 : undef',
},
GuanoAnabatTriggerMaxFreq => {
Require => 'Guano',
ValueConv => '$val =~ /Anabat\|Trigger max freq:\s+(.*)/m ? $1 : undef',
},
GuanoAnabatMinEvent => {
Require => 'Guano',
ValueConv => '$val =~ /Anabat\|Min event:\s+(.*)/m ? $1 : undef',
},
GuanoAnabatTriggerWindow => {
Require => 'Guano',
ValueConv => '$val =~ /Anabat\|Trigger Window:\s+(.*)/m ? $1 : undef',
},
GuanoAnabatMaximumFileDuration => {
Require => 'Guano',
ValueConv => '$val =~ /Anabat\|Maximum File Duration:\s+(.*)/m ? $1 : undef',
},
GuanoSBVersion => {
Require => 'Guano',
ValueConv => '$val =~ /SB\|Version:\s+(.*)/m ? $1 : undef',
},
GuanoSBSpeciesAutoID => {
Require => 'Guano',
ValueConv => '$val =~ /SB\|Species Auto ID:\s+(.*)/m ? $1 : undef',
},
GuanoSpeciesAutoID => {
Require => 'Guano',
ValueConv => '$val =~ /Species Auto ID:\s+(.*)/m ? $1 : undef',
},
GuanoSpeciesManualID => {
Require => 'Guano',
ValueConv => '$val =~ /Species Manual ID:\s+(.*)/m ? $1 : undef',
},
GuanoSampleRate => {
Require => 'Guano',
ValueConv => '$val =~ /Samplerate:\s+(.*)/m ? $1 : undef',
},
GuanoLength => {
Require => 'Guano',
ValueConv => '$val =~ /Length:\s+(.*)/m ? $1 : undef',
},
GuanoTE => {
Require => 'Guano',
ValueConv => '$val =~ /TE:\s+(.*)/m ? $1 : undef',
},
GuanoSBFilterHP => {
Require => 'Guano',
ValueConv => '$val =~ /SB\|Filter HP:\s+(.*)/m ? $1 : undef',
},
GuanoNote => {
Require => 'Guano',
ValueConv => '$val =~ /Note:\s+(.*)/m ? $1 : undef',
},
GuanoSBRegion => {
Require => 'Guano',
ValueConv => '$val =~ /SB\|Region:\s+(.*)/m ? $1 : undef',
},
GuanoSBClassifier => {
Require => 'Guano',
ValueConv => '$val =~ /SB\|Classifier:\s+(.*)/m ? $1 : undef',
},
},
);
#------------------------------------------------------------------------------
1; #end
+79
View File
@@ -0,0 +1,79 @@
#------------------------------------------------------------------------------
# File: local_time.config
#
# Description: Determine local time based on GPS location and GPSDateTime
#
# Notes: 1. Requires that the API TimeZone option functions properly
# using an IANA time zone name (like "America/New_York"), so
# this may not work on Windows systems.
#
# 2. Time is based on GPSDateTime preferentially, otherwise
# DateTimeOriginal then CreateDate assuming the system time
# zone unless the corresponding OffsetTime tag exists.
#
# Usage: exiftool -config local_time.config -localtime FILE
#
# Options: The user parameter LocalTag may be set to the name of the
# date/time tag to use, case insensitive with optional group
# name(s). For example add this to the command to use
# SubSecDateTimeOriginal as the basis for LocalTime:
#
# -userparam localtag=subsecdatetimeoriginal
#
# Requires: ExifTool version 13.56 or later
#
# Revisions: 2025-10-19 - P. Harvey Created
# 2026-04-02 - PH Preserve decimal seconds up to 6 digits
# 2026-04-08 - PH Added LocalTag feature
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
LocalTime => {
Groups => { 2 => 'Time' },
Require => {
0 => 'GPSLatitude',
1 => 'GPSLongitude',
},
Desire => {
2 => 'GPSDateTime',
3 => 'SubSecDateTimeOriginal',
4 => 'SubSecCreateDate',
5 => 'DateTimeOriginal',
6 => 'CreateDate',
},
ValueConv => q{
require Image::ExifTool::Geolocation;
my ($loc) = Image::ExifTool::Geolocation::Geolocate("$val[0],$val[1]");
return undef unless $loc;
my $pref = $self->Options(UserParam => 'LocalTag');
my $time;
if ($pref) {
my $num = { gpsdatetime => 2,
subsecdatetimeoriginal => 3,
subseccreatedate => 4,
datetimeoriginal => 5,
createdate => 6 }->{lc $pref};
if ($num) {
$time = $val[$num];
} else {
$time = $self->GetValue($pref);
}
} else {
$time = $val[2] || $val[3] || $val[4] || $val[5] || $val[6];
}
return undef unless $time;
my $secs = Image::ExifTool::GetUnixTime($time, 1);
return undef unless $secs;
my @info = Image::ExifTool::Geolocation::GetEntry($$loc[0]);
$self->Options(TimeZone => $info[5]);
my $localTime = Image::ExifTool::ConvertUnixTime($secs, 1, -6);
$self->Options(TimeZone => undef);
return $localTime;
},
},
},
);
1; #end
+146
View File
@@ -0,0 +1,146 @@
#------------------------------------------------------------------------------
# File: nksc.config
#
# Description: This config file contains tag definitions to extract metadata
# from RDF/XML-based Nikon ViewNX NKSC sidecar files
#
# Usage: exiftool -config nksc.config -ext nksc DIR
#
# Requires: ExifTool version 11.38 or later
#
# Revisions: 2019/04/24 - P. Harvey Created
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
ast => {
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::ast' },
},
sdc => {
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::sdc' },
},
nine => {
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::nine' },
},
},
'Image::ExifTool::Composite' => {
GPSLatitude => {
Require => {
0 => 'XMP-ast:GPSLatitude',
1 => 'XMP-ast:GPSLatitudeRef',
},
ValueConv => '$prt[1] =~ /^S/i ? -$val[0] : $val[0]',
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
},
GPSLongitude => {
Require => {
0 => 'XMP-ast:GPSLongitude',
1 => 'XMP-ast:GPSLongitudeRef',
},
ValueConv => '$prt[1] =~ /^W/i ? -$val[0] : $val[0]',
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
},
},
);
%Image::ExifTool::UserDefined::ast = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-ast', 2 => 'Location' },
NAMESPACE => { 'ast' => 'http://ns.nikon.com/asteroid/1.0/' },
about => { Groups => { 2 => 'Image' } },
version => { Groups => { 2 => 'Image' } },
GPSVersionID => {
ValueConv => q{
my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
SetByteOrder('II');
ReadValue($valPt, 0, 'int8u', 4, length($$valPt));
},
PrintConv => '$val =~ tr/ /./; $val',
},
GPSLatitude => {
ValueConv => q{
my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
SetByteOrder('II');
$val = ReadValue($valPt, 0, 'double', 3, length($$valPt));
Image::ExifTool::GPS::ToDegrees($val);
},
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val)',
},
GPSLatitudeRef => {
ValueConv => q{
my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
SetByteOrder('II');
ReadValue($valPt, 0, 'int32u', 3, length($$valPt));
},
PrintConv => { 0 => 'North', 1 => 'South' },
},
GPSLongitude => {
ValueConv => q{
my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
SetByteOrder('II');
$val = ReadValue($valPt, 0, 'double', 3, length($$valPt));
Image::ExifTool::GPS::ToDegrees($val);
},
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val)',
},
GPSLongitudeRef => {
ValueConv => q{
my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
SetByteOrder('II');
ReadValue($valPt, 0, 'int32u', 3, length($$valPt));
},
PrintConv => { 2 => 'East', 3 => 'West' },
},
GPSAltitude => {
ValueConv => q{
my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
SetByteOrder('II');
ReadValue($valPt, 0, 'double');
},
PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "$val m"',
},
GPSAltitudeRef => {
ValueConv => q{
my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
ReadValue($valPt, 0, 'int8u');
},
PrintConv => {
0 => 'Above Sea Level',
1 => 'Below Sea Level',
},
},
GPSMapDatum => { },
XMLPackets => {
Name => 'XMP',
Groups => { 2 => 'Image' },
RawConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
},
IPTC => {
Name => 'IPTC',
Groups => { 2 => 'Image' },
RawConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
SubDirectory => { TagTable => 'Image::ExifTool::IPTC::Main' },
},
);
%Image::ExifTool::UserDefined::sdc = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-sdc', 2 => 'Image' },
NAMESPACE => { 'sdc' => 'http://ns.nikon.com/sdc/1.0/' },
about => { },
version => { },
appversion => { },
appname => { },
);
%Image::ExifTool::UserDefined::nine = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-nine', 2 => 'Image' },
NAMESPACE => { 'nine' => 'http://ns.nikon.com/nine/1.0/' },
about => { },
version => { },
NineEdits => { Binary => 1 },
Label => { },
Rating => { },
Trim => { ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)' },
);
1; #end
+51
View File
@@ -0,0 +1,51 @@
#------------------------------------------------------------------------------
# File: novelty.config
#
# Description: This config file defines Novelty Theory XMP tags for writing.
#
# Notes: Tags for annotating timestamped media (video, photo, audio)
# with metadata in the context of Terence McKenna's Novelty
# Theory framework (see The Invisible Landscape, 1975).
# Published and maintained at http://hexart.pl/novelty/1.0/
# for use by archival projects documenting media against the
# McKenna timewave.
#
# Requires: ExifTool version 7.00 or later
#
# Revisions: 2026-05-27 - P. Harvey Created (from github #422)
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
novelty => {
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::novelty' },
},
},
);
# Novelty Theory XMP namespace (http://hexart.pl/novelty/1.0/)
%Image::ExifTool::UserDefined::novelty = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-novelty', 2 => 'Other' },
NAMESPACE => { novelty => 'http://hexart.pl/novelty/1.0/' },
WRITABLE => 'string',
NoveltyIndex => { Writable => 'real' },
TimewavePosition => { },
Concrescence => { },
EschatonCoordinates => { },
StrangeAttractor => { },
HabitNoveltyRatio => { },
WaveformType => { },
Protocol => { },
Operator => { },
Intent => { },
Witness => { },
CosmicSign => { },
Frequency => { },
SacredGeometry => { },
Dimension => { },
Lineage => { },
Mantra => { },
Seal => { Avoid => 1 }, # avoid conflict with XMP-seal:Seal
);
1; #end
+28
View File
@@ -0,0 +1,28 @@
#------------------------------------------------------------------------------
# File: onone.config
#
# Description: This config file defines On1 XMP tags for writing.
#
# Usage: exiftool -config onone.config -UserFlag=VALUE FILE ...
#
# Requires: ExifTool version 10.28 or later
#
# Revisions: 2024/07/10 - P. Harvey Created
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
onone => {
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::onone' },
},
},
);
%Image::ExifTool::UserDefined::onone = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-onone', 2 => 'Other' },
NAMESPACE => { 'onone' => 'http://www.ononesoftware.com/vcb/1.0/' },
WRITABLE => 'string',
UserFlag => { },
);
1; #end
+221
View File
@@ -0,0 +1,221 @@
#------------------------------------------------------------------------------
# File: photoshop_paths.config
#
# Description: This config file generates user-defined tags for Photoshop
# paths, and may be used to extract path names and/or Bezier knot
# anchor points, or copy path information from one file to
# another.
#
# The anchor points may be extracted along with the path names by
# setting the "Anchor" user parameter (ie. "-userparam anchor"),
# or by themselves with "AnchorOnly".
#
# An "AllPaths" shortcut tag is also provided represent all
# Photoshop path tags. This shortcut must be used when copying
# because these tags are marked as "Protected" so they won't be
# copied by default (also see the notes below).
#
# Path anchor points are converted to pixel coordinates by the
# Composite PathPixXXX tags, and an "AllPathPix" shortcut is
# provided to represent these tags.
#
# Finally, a Composite PathCount tag is provided to return the
# number of paths in an image, and a TotalPathPoints tag counts
# the total number of path anchor points.
#
# Notes: 1) Print conversion must be disabled to be able to copy the paths
# (via either the -n option, or by adding a "#" to the tag name,
# eg. "-tagsfromfile SRC -allpaths#").
#
# 2) When copying the paths, OriginPathInfo must also be copied
# (otherwise Photoshop may give a "program error" and refuse to
# load the image).
#
# Usage:
#
# 1) Extract Photoshop path names:
#
# exiftool -config photoshop_paths.config -allpaths FILE
#
# 2) Extract Photoshop path names and anchor points:
#
# exiftool -config photoshop_paths.config -userparam anchor -allpaths FILE
#
# 3) Extract Photoshop path anchor points only:
#
# exiftool -config photoshop_paths.config -userparam anchoronly -allpaths FILE
#
# 4) Copy all Photoshop paths from one file (SRC) to another (DST):
# (note that OriginPathInfo must also be copied when copying all paths)
#
# exiftool -config photoshop_paths.config -tagsfromfile SRC -allpaths# -originpathinfo DST
#
# 5) Extract path names and anchor points in pixel coordinates:
#
# exiftool -config photoshop_paths.config -allpathpix FILE
#
# Requires: ExifTool version 9.95 or later
#
# Notes: A "-" before a set of Bezier path points indicates a closed subpath,
# and a "+ indicates the start of an open subpath.
#
# Revisions: 2015/05/07 - P. Harvey Created
# 2016/09/14 - PH Added feature to allow extracting anchor points
# 2017/01/24 - PH Added PathCount and PathPix Composite tags
# 2017/02/02 - PH Added support for copying OriginPathInfo
# 2017/02/22 - PH Fixed problem printing some paths
# 2017/03/19 - PH Added "-" or "+" at the start of closed or open
# subpath respectively
# 2017/06/03 - PH Added TotalPathPoints
# 2017/07/17 - PH Added UniquePathPoints
# 2022/02/03 - PH Added WorkingPath and WorkingPathPix
#
# References: https://exiftool.org/forum/index.php/topic,1621.0.html
# https://exiftool.org/forum/index.php/topic,3910.0.html
# https://exiftool.org/forum/index.php/topic,6647.0.html
#------------------------------------------------------------------------------
# Print Photoshop path name and/or anchor points
# Inputs: 0) reference to Photoshop path data, 1) ExifTool object reference
# 2-3) optional image width/height to convert anchor points to pixels
# 4) optional path name
# Returns: String with name and/or Bezier knot anchor points
sub PrintPath($$;$$$)
{
my ($val, $et, $w, $h, $nm) = @_;
my ($pos, $name, @rtn);
my $len = length($$val) - 26;
# recover exiftool-added path name if it exists
if ($$val =~ m{.*/#(.{0,255})#/$}s) {
$name = $1;
$len -= length($1) + 4;
$name = $nm if defined $nm and not length $name;
} else {
$name = defined $nm ? $nm : '<none>';
}
my $anchorOnly = $et->Options(UserParam => 'AnchorOnly');
push @rtn, $name unless $anchorOnly;
# loop through path points and extract anchor points if specified
if ($anchorOnly or $et->Options(UserParam => 'Anchor') or defined $w) {
SetByteOrder('MM');
for ($pos=0; $pos<=$len; $pos+=26) {
my $type = Get16u($val, $pos);
$type == 0 and push(@rtn, '-'), next;
$type == 3 and push(@rtn, '+'), next;
# Bezier knot records are types 1, 2, 4 and 5
next unless {1=>1,2=>1,4=>1,5=>1}->{$type};
# the anchor point is at offset 10 in the Bezier knot record
# (fixed-point values with 24-bits after the decimal point)
my $y = Get32s($val, $pos+10) / 0x1000000; # (vertical component first)
my $x = Get32s($val, $pos+14) / 0x1000000;
if (defined $w and defined $h) {
push @rtn, sprintf('(%g,%g)', $x * $w, $y * $h);
} else {
push @rtn, sprintf('(%g,%g)', $x, $y);
}
}
}
return join ' ', @rtn;
}
%Image::ExifTool::Shortcuts::UserDefined = (
# create "AllPaths" shortcut for all Photoshop path tags (except WorkingPath)
AllPaths => [
map { sprintf "Path%x", $_ } (0x7d0 .. 0xbb5),
],
AllPathPix => [
map { sprintf "PathPix%x", $_ } (0x7d0 .. 0xbb5),
],
);
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Photoshop::Main' => {
0xbb8 => {
Name => 'OriginPathInfo',
Flags => [ qw(Writable Protected Binary SetResourceName) ],
},
0x401 => {
Name => 'WorkingPath',
Flags => [ qw(Writable Protected Binary ConvertBinary SetResourceName) ],
PrintConv => sub {
my ($val, $et) = @_;
PrintPath($val, $et, undef, undef, 'Work Path');
},
},
# generate tags for each of the 998 possible Photoshop paths
map { $_ => {
Name => sprintf('Path%x', $_),
Description => sprintf('Path %x', $_),
Flags => [ qw(Writable Protected Binary ConvertBinary SetResourceName) ],
PrintConv => \&PrintPath,
} } (0x7d0 .. 0xbb5),
},
'Image::ExifTool::Composite' => {
PathCount => {
# (PathCount statistics do not include WorkingPath)
Desire => {
map { $_-0x7d0 => sprintf('Path%x', $_) } (0x7d0 .. 0xbb5),
},
ValueConv => sub {
my ($val, $self) = @_;
my $count = 0;
my $pts = 0;
my $uniq = 0;
my %uniq;
foreach (@$val) {
next unless defined $_;
++$count;
# determine the total number of path anchor points
my $len = length($$_) - 26;
for ($pos=0; $pos<=$len; $pos+=26) {
SetByteOrder('MM');
my $type = Get16u($_, $pos);
last if $type == 0x2f23; # (start of path name added by ExifTool)
next unless {1=>1,2=>1,4=>1,5=>1}->{$type};
my $pt = substr($$_, $pos+10, 8);
$uniq{$pt} or ++$uniq, $uniq{$pt} = 1;
++$pts;
}
}
$$self{TotalPathPoints} = $pts;
$$self{UniquePathPoints} = $uniq;
return $count;
},
},
UniquePathPoints => {
Require => 'PathCount',
ValueConv => '$$self{UniquePathPoints}',
},
TotalPathPoints => {
Require => 'PathCount',
ValueConv => '$$self{TotalPathPoints}',
},
WorkingPathPix => {
Require => {
0 => 'ImageWidth',
1 => 'ImageHeight',
2 => 'WorkingPath',
},
ValueConv => sub {
my ($val, $et) = @_;
PrintPath($$val[2], $et, $$val[0], $$val[1], 'Work Path');
},
},
map { sprintf('PathPix%x', $_) => {
Require => {
0 => 'ImageWidth',
1 => 'ImageHeight',
2 => sprintf('Path%x', $_),
},
Description => sprintf('Path Pix %x', $_),
ValueConv => sub {
my ($val, $et) = @_;
PrintPath($$val[2], $et, $$val[0], $$val[1]);
},
} } (0x7d0 .. 0xbb5),
},
);
1; #end
+382
View File
@@ -0,0 +1,382 @@
#------------------------------------------------------------------------------
# File: picasa_faces.config
#
# Description: User-defined Composite tag definitions to convert face regions
# in .picasa.ini files to MWG region tags (Metadata Working Group
# region, used by Picasa) and MP region tags (used by Microsoft
# Photo Library).
#
# Tag definitions and examples:
#
# PicasaToMWGRegion
# This will create the MWG region tag but will filter out the regions
# that are still unnamed in Picasa. Picasa defaults to naming these
# regions 'ffffffffffffffff' but normally will not save these to file.
# Example:
# exiftool -config picasa_faces.config "-RegionInfo<PicasaToMWGRegion" FILE
#
# PicasaToMPRegion
# This will create the MP region tag but will filter out the regions that
# are still unnamed in Picasa. Picasa defaults to naming these regions
# 'ffffffffffffffff' but normally will not save these to file.
# Example:
# exiftool -config picasa_faces.config "-RegionInfoMP<PicasaToMPRegion" FILE
#
# PicasaRegionNames
# Returns a list of the region names associated with the file. This
# allows copying of the region names to XMP:Subject and/or IPTC:Keywords.
# It also allows checking to see if regions need to be updated.
# Example:
# exiftool -config picasa_faces.config "-XMP:Subject<PicasaRegionNames" FILE
#
# PicasaToMWGRegionUnfiltered
# This will create the MWG region tag. This version does not filter out
# the unnamed regions. Picasa normally will filter out unnamed regions
# when it saves regions in the file.
# Example:
# exiftool -config picasa_faces.config "-RegionInfo<PicasaToMWGRegionUnfiltered" FILE
#
# PicasaToMPRegionUnfiltered
# This will create the MP region tag. This version does not filter out
# the unnamed regions. Picasa normally will filter out unnamed regions
# when it saves regions in the file.
# Example:
# exiftool -config picasa_faces.config "-RegionInfoMP<PicasaToMPRegionUnfiltered" FILE
#
# Notes: The face names are loaded from the Picasa contacts file, which
# defaults to:
#
# C:/Users/MainUser/AppData/Local/PicasaData/Google/Picasa2/contacts/contacts.xml
#
# The default contacts file may be changed by editing the value
# of $contactXML below, or on the command line with ExifTool 9.90
# or later via the -userParam option, eg:
# -userparam PicasaContactsFile=/path/to/contacts.xml
#
# Requires: ExifTool version 8.82 or later (9.90 or later for -userparam)
#
# Revisions: 2015/03/07 - Bryan K. Williams (aka StarGeek) Created
# 2015/03/12 - PH Minor changes, optimizations and reformatting
# 2015/05/11 - BKW Fix bug where Picasa writes region data for
# rotated NEF and CR2 images as if the orientation
# is not rotated.
# 2015/05/12 - PH Minor code tweaks
# 2015/10/26 - BKW Round off area sizes to 7 decimal places
# 2016/01/18 - BKW Improved rounding algorithm
# 2016/05/14 - BKW Increased rounding to 9 decimal places (Max Picasa accepts),
# moved rounding operation to subroutine
#
# References: https://exiftool.org/forum/index.php/topic,6354.0.html
#------------------------------------------------------------------------------
# Picasa contacts file name
my $contactXML = 'C:/Users/MainUser/AppData/Local/PicasaData/Google/Picasa2/contacts/contacts.xml';
# local variables
my $lastIniFile = ''; # path of last .picasa.ini file loaded
my $lastContactFile = ''; # path of last contacts.xml file loaded
# raw file types that need additional processing to get regions correct
my %isRawFile = map { $_ => 1 } qw(
3FR ARW CR2 CRW CS1 DCR DNG EIP ERF IIQ K25 KDC MEF MOS MRW NEF NRW
ORF PEF RAF RAW RW2 RWL SR2 SRF SRW X3F), 'Canon 1D RAW';
my %contactHash; # lookup for loaded contacts.xml entries
my %fileHash; # lookup for loaded .picasa.ini entries
#------------------------------------------------------------------------------
# Load Picasa's contacts.xml and .picasa.ini files.
# Inputs: 0) ExifTool object reference, 1) .picasa.ini directory
# Returns: 1 if files were loaded and parsed, undef on error
# Notes: If file has already been loaded, it isn't reloaded
sub LoadPicasaFiles($$)
{
local (*CONTACTS, *INI);
my ($et, $iniDir) = @_;
# check ExifTool version to see if there might be
# a command line setting for the contact file
my $contactFile = ($Image::ExifTool::VERSION >= 9.89 and
defined($et->Options(UserParam => 'PicasaContactsFile'))) ?
$et->Options(UserParam => 'PicasaContactsFile') : $contactXML;
# load Picasa contacts.xml file unless done already
unless ($contactFile eq $lastContactFile) {
$lastContactFile = $contactFile;
undef %contactHash;
# Picasa's default setting for unnamed faces.
$contactHash{'ffffffffffffffff'} = 'unnamed';
if (open(CONTACTS, $contactFile)) {
require Image::ExifTool::HTML;
while (<CONTACTS>) {
/name="(.*?)"/ or next;
my $name = $1;
/id="([a-f0-9]+)"/ or next;
my $id = $1;
$contactHash{$id} = Image::ExifTool::HTML::UnescapeHTML($name);
}
close(CONTACTS);
} else {
local $SIG{'__WARN__'} = undef; # stop ExifTool from catching the warning
warn "Error reading contacts file $contactFile\n";
}
}
# load .picasa.ini file from the specified directory
my $iniFile = "$iniDir/.picasa.ini";
if ($iniFile eq $lastIniFile) {
return %fileHash ? 1 : undef;
}
$lastIniFile = $iniFile;
open(INI, $iniFile) or return undef;
my $section = '';
while (<INI>) {
# Process New Section
/^\s*\[(.+)\][\n\r]*$/ and $section = $1, next;
# process entry (all we care about are the "faces" lines)
/^faces=(.*)$/ or next;
my @temp = split /;/, $1;
foreach (@temp) {
/rect64\(([\da-f]{1,16})\),([\da-f]{1,16})/ or next;
# the string in parens after "rect64" is a 64 bit number in hex,
# but Picasa doesn't add leading zeroes, so the length of the string
# cannot be assumed to be 16 bytes. Handle this as two 32-bit numbers
# for compatibility with 32-bit systems.
my $hi = hex(substr($1, 0, -8));
my $lo = hex(substr($1, -8));
my $x0 = ($hi >> 16) /65535;
my $y0 = ($hi & 0xffff)/65535;
my $x1 = ($lo >> 16) /65535;
my $y1 = ($lo & 0xffff)/65535;
push @{ $fileHash{$section} }, {
ContactID => $2,
X => $x0,
Y => $y0,
W => $x1 - $x0,
H => $y1 - $y0,
};
}
}
close(INI);
return %fileHash ? 1 : undef;
}
#------------------------------------------------------------------------------
# Rotate region to specified orientation (for RAW file types only)
# Input: 0) rectangle array ref (x,y,w,h), 1) EXIF orientation value, 2) file type
sub RotateRegion($$$)
{
my ($rect, $orientation, $fileType) = @_;
if ($orientation and $fileType and $isRawFile{$fileType}) {
my ($x,$y,$w,$h) = @$rect;
if ($orientation == 8) { # CW 90
@$rect = (1-$h-$y, $x, $h, $w);
} elsif ($orientation == 3) { # CW 180
@$rect = (1-$x-$w, 1-$y-$h, $w, $h);
} elsif ($orientation == 6) { # CW 270
@$rect = ($y, 1-$x-$w, $h, $w);
}
}
}
#------------------------------------------------------------------------------
# Rounds number to 9 decimal places, which is the limit to the number of decimal places that Picasa can read.
sub Rounded
{
my $DecAcc = 10**9;
return(int($_[0]*$DecAcc+.5)/$DecAcc);
}
#------------------------------------------------------------------------------
# User-defined tag definitions
#
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
#
# Versions that filter out unnamed regions (ContactID=ffffffffffffffff)
#
PicasaToMWGRegion => {
Require => {
0 => 'Directory',
1 => 'FileName',
2 => 'ImageWidth',
3 => 'ImageHeight',
},
Desire => {
4 => 'Orientation',
5 => 'FileType',
},
ValueConv => sub {
my ($val, $et) = @_;
LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
my $filename = $$val[1];
my @regList;
# convert to local variables for readability, and make
# sure there is a region associated with the current file
my $contactHashRef = \%contactHash;
my $tempArrayRef = $fileHash{$filename} or return undef;
foreach my $tempHash (@$tempArrayRef) {
next if $$tempHash{ContactID} eq 'ffffffffffffffff';
my $name = $$contactHashRef{$$tempHash{ContactID}};
next unless defined $name;
my @rect = @$tempHash{'X','Y','W','H'};
RotateRegion(\@rect, $$val[4], $$val[5]);
push @regList, {
Area => {
X => Rounded($rect[0] + $rect[2] / 2),
Y => Rounded($rect[1] + $rect[3] / 2),
W => Rounded($rect[2]),
H => Rounded($rect[3]),
Unit => 'normalized',
},
Name => $name,
Type => 'Face',
};
}
# make sure a region exists, otherwise return undef
return @regList ? {
AppliedToDimensions => { W => $$val[2], H => $$val[3], Unit => 'pixel' },
RegionList => \@regList,
} : undef;
},
},
PicasaToMPRegion => {
Require => {
0 => 'Directory',
1 => 'FileName',
},
Desire => {
2 => 'Orientation',
3 => 'FileType',
},
ValueConv => sub {
my ($val, $et) = @_;
LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
my $filename = $$val[1];
my @regList;
# convert to local variables for readability, and make
# sure there is a region associated with the current file
my $contactHashRef = \%contactHash;
my $tempArrayRef = $fileHash{$filename} or return undef;
foreach my $tempHash (@$tempArrayRef) {
next if $$tempHash{ContactID} eq 'ffffffffffffffff';
my $name = $$contactHashRef{$$tempHash{ContactID}};
next unless defined $name;
my @rect = @$tempHash{'X','Y','W','H'};
RotateRegion(\@rect, $$val[2], $$val[3]);
@rect = map {Rounded($_)} @rect;
push @regList, {
PersonDisplayName => $name,
Rectangle => join(', ', @rect),
};
}
# make sure a region exists, otherwise return undef
return @regList ? { Regions => \@regList } : undef;
},
},
PicasaRegionNames => {
Require => {
0 => 'Directory',
1 => 'FileName',
},
ValueConv => sub {
my ($val, $et) = @_;
LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
my $filename = $$val[1];
my @regList;
# convert to local variables for readability, and make
# sure there is a region associated with the current file
my $contactHashRef = \%contactHash;
my $tempArrayRef = $fileHash{$filename} or return undef;
foreach my $tempHash (@$tempArrayRef) {
next if $$tempHash{ContactID} eq 'ffffffffffffffff';
my $name = $$contactHashRef{$$tempHash{ContactID}};
push @regList, $name if defined $name;
}
# make sure a region exists, otherwise return undef
return @regList ? \@regList : undef;
},
},
#
# Versions that do not filter out unnamed regions (ContactID=ffffffffffffffff)
# Picasa normally does not add these regions when it saves names to the file.
#
PicasaToMWGRegionUnfiltered => {
Require => {
0 => 'Directory',
1 => 'FileName',
2 => 'ImageWidth',
3 => 'ImageHeight',
},
Desire => {
4 => 'Orientation',
5 => 'FileType',
},
ValueConv => sub {
my ($val, $et) = @_;
LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
my $filename = $$val[1];
my @regList;
# convert to local variables for readability, and make
# sure there is a region associated with the current file
my $contactHashRef = \%contactHash;
my $tempArrayRef = $fileHash{$filename} or return undef;
foreach my $tempHash (@$tempArrayRef) {
my @rect = @$tempHash{'X','Y','W','H'};
RotateRegion(\@rect, $$val[4], $$val[5]);
push @regList, {
Area => {
X => Rounded($rect[0] + $rect[2] / 2),
Y => Rounded($rect[1] + $rect[3] / 2),
W => Rounded($rect[2]),
H => Rounded($rect[3]),
Unit => 'normalized',
},
Name => $$contactHashRef{$$tempHash{ContactID}} || 'unnamed',
Type => 'Face',
};
}
# make sure a region exists, otherwise return undef
return @regList ? {
AppliedToDimensions => { W => $$val[2], H => $$val[3], Unit => 'pixel' },
RegionList => \@regList,
} : undef;
},
},
PicasaToMPRegionUnfiltered => {
Require => {
0 => 'Directory',
1 => 'FileName',
},
Desire => {
2 => 'Orientation',
3 => 'FileType',
},
ValueConv => sub {
my ($val, $et) = @_;
LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
my $filename = $$val[1];
my @regList;
# convert to local variables for readability, and make
# sure there is a region associated with the current file
my $contactHashRef = \%contactHash;
my $tempArrayRef = $fileHash{$filename} or return undef;
foreach my $tempHash (@$tempArrayRef) {
my @rect = @$tempHash{'X','Y','W','H'};
RotateRegion(\@rect, $$val[2], $$val[3]);
@rect = map {Rounded($_)} @rect;
push @regList, {
PersonDisplayName => $$contactHashRef{$$tempHash{ContactID}} || 'unnamed',
Rectangle => join(', ', @rect),
}
}
# make sure a region exists, otherwise return undef
return @regList ? { Regions => \@regList } : undef;
},
},
},
);
#------------------------------------------------------------------------------
1; #end
+100
View File
@@ -0,0 +1,100 @@
#------------------------------------------------------------------------------
# File: pix4d.config
#
# Description: This config file contains tag definitions needed to be able
# to write Pix4D XMP-Camera tags
#
# Usage: exiftool -config pix4d.config -XMP-camera:TAG=VAL ...
#
# Requires: ExifTool version 7.00 or later
#
# References: 1) https://support.pix4d.com/hc/en-us/articles/360016450032
#
# Revisions: 2017/12/08 - P. Harvey Created
# 2020/04/02 - PH Updated to current specification
# 2025/05/01 - PH Changed some Writable types to match the spec
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
Camera => {
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::Camera',
},
},
},
);
%Image::ExifTool::UserDefined::Camera = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-Camera', 2 => 'Camera' },
NAMESPACE => { 'Camera' => 'http://pix4d.com/camera/1.0/' },
WRITABLE => 'string',
Yaw => { Writable => 'real' },
Pitch => { Writable => 'real' },
Roll => { Writable => 'real' },
IMUSampleSize => { Writable => 'integer' },
IMUTimeOffset => { Writable => 'integer' },
LineReadoutTime => { Writable => 'integer' },
IMUFrequency => { Writable => 'real' },
PrincipalPoint => { },
ModelType => { },
PerspectiveFocalLength => { Writable => 'real' },
PerspectiveDistortion => { },
IMULinearVelocity => { },
GPSXYAccuracy => { Writable => 'rational' },
GPSZAccuracy => { Writable => 'rational' },
FlightUUID => { },
CentralWaveLength => { },
BandName => { List => 'Seq' },
RigName => { },
RigCameraIndex => { Writable => 'integer' },
BandName => { List => 'Seq' },
IMUAngularVelocity => {
Binary => 1,
ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
},
# added 2020/04/02 (ref 1)
FisheyeAffineMatrix => { },
FisheyeAffineSymmetric => { },
FisheyePolynomial => { },
RigRelatives => { },
PerspectiveFocalLengthUnits => { },
CaptureUUID => { },
CentralWavelength => { List => 'Seq' },
WavelengthFWHM => { List => 'Seq' },
BlackCurrent => { List => 'Seq' },
BandSensitivity => { List => 'Seq' },
SunSensor => { List => 'Seq' },
SunSensorExposureTime => { List => 'Seq' },
SunSensorSensitivity => { List => 'Seq' },
InvalidPixel => { List => 'Seq' },
VignettingPolynomial => { List => 'Seq' },
VignettingCenter => { List => 'Seq' },
VignettingPolynomial2DName => { List => 'Seq' },
VignettingPolynomial2D => { List => 'Seq' },
ColorTransform => { List => 'Seq' },
IsNormalized => { },
Albedo => { List => 'Seq' },
ReflectArea => { List => 'Seq' },
CalibrationPicture => { Writable => 'integer' },
GyroRate => { Writable => 'rational' },
IMUPitchAccuracy => { Writable => 'rational' },
IMURollAccuracy => { Writable => 'rational' },
IMUYawAccuracy => { Writable => 'rational' },
NominalCameraDistance => { Writable => 'rational' },
AboveGroundAltitude => { Writable => 'real' },
SunSensorYaw => { Writable => 'real' },
SunSensorPitch => { Writable => 'real' },
SunSensorRoll => { Writable => 'real' },
SunSensorRelativeRotation => { Writable => 'real', List => 'Seq' },
TransformAlpha => { List => 'Seq' },
TransformBeta => { List => 'Seq' },
TransformGamma => { List => 'Seq' },
SensorBitDepth => { Writable => 'integer' },
SensorTemperature => { Writable => 'real' },
# (ref https://community.pix4d.com/t/camera-sun-irradiance-and-sun-angle-in-red-text/3290)
IrradianceRelativeRotation => { },
);
1; #end
+173
View File
@@ -0,0 +1,173 @@
#------------------------------------------------------------------------------
# File: rotate_regions.config
#
# Description: User-defined Composite tag definitions to rotate MWG region tags
# (Metadata Working Group region, used by Picasa) and MP region tags
# (used by Microsoft Photo Library).
#
# Tag definitions and examples:
#
# RotateMWGRegionCW90
# RotateMWGRegionCW180
# RotateMWGRegionCW270
# These tags will rotate a MWG Region clockwise 90, 180, or 270 degrees.
# Example:
# exiftool -config rotate_regions.config "-RegionInfo<RotateMWGRegionCW90" FILE
#
# RotateMPRegionCW90
# RotateMPRegionCW180
# RotateMPRegionCW270
# These tags will rotate an MP Region clockwise 90, 180, or 270 degrees.
# Example:
# exiftool -config rotate_regions.config "-RegionInfoMP<RotateMPRegionCW90" FILE
#
# Revisions: 2015/05/08 - Bryan K. Williams AKA StarGeek Created
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
RotateMWGRegionCW90 =>{
Require => 'RegionInfo',
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{RegionList}}) {
my @rect = @{$$rgn{Area}}{'X','Y','W','H'};
my %newRgn = (
Area => {
X => 1-$rect[1],
Y => $rect[0],
W => $rect[3],
H => $rect[2],
Unit => 'normalized',
},
Name => $$rgn{Name},
Type => 'Face',
);
push @newRgns, \%newRgn;
}
return {
AppliedToDimensions => {
W => $val[0]{AppliedToDimensions}{W},
H => $val[0]{AppliedToDimensions}{H},
Unit => $val[0]{AppliedToDimensions}{Unit},
},
RegionList => \@newRgns,
};
},
}, #End RotateMWGRegionCW90
RotateMWGRegionCW180 =>{
Require => 'RegionInfo',
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{RegionList}}) {
my @rect = @{$$rgn{Area}}{'X','Y','W','H'};
my %newRgn = (
Area => {
X => 1-$rect[0],
Y => 1-$rect[1],
W => $rect[2],
H => $rect[3],
Unit => 'normalized',
},
Name => $$rgn{Name},
Type => 'Face',
);
push @newRgns, \%newRgn;
}
return {
AppliedToDimensions => {
W => $val[0]{AppliedToDimensions}{W},
H => $val[0]{AppliedToDimensions}{H},
Unit => $val[0]{AppliedToDimensions}{Unit},
},
RegionList => \@newRgns,
};
},
}, #End RotateMWGRegionCW180
RotateMWGRegionCW270 =>{
Require => 'RegionInfo',
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{RegionList}}) {
my @rect = @{$$rgn{Area}}{'X','Y','W','H'};
my %newRgn = (
Area => {
X => $rect[1],
Y => 1-$rect[0],
W => $rect[3],
H => $rect[2],
Unit => 'normalized',
},
Name => $$rgn{Name},
Type => 'Face',
);
push @newRgns, \%newRgn;
}
return {
AppliedToDimensions => {
W => $val[0]{AppliedToDimensions}{W},
H => $val[0]{AppliedToDimensions}{H},
Unit => $val[0]{AppliedToDimensions}{Unit},
},
RegionList => \@newRgns,
};
},
}, #End RotateMWGRegionCW270
RotateMPRegionCW90=>{
Require => 'RegionInfoMP',
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{Regions}}) {
my @rect = split /\s*,\s*/, $$rgn{Rectangle};
my $temp = $rect[0];
$rect[0] = 1-$rect[1]-$rect[3];
$rect[1] = $temp;
($rect[2], $rect[3]) = ($rect[3],$rect[2]); #Swap W and H
push @newRgns, {
PersonDisplayName => $$rgn{PersonDisplayName},
Rectangle => join(', ', @rect),
};
}
return { Regions => \@newRgns };
}
}, #end RotateMPRegionCW90
RotateMPRegionCW180=>{
Require => 'RegionInfoMP',
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{Regions}}) {
my @rect = split /\s*,\s*/, $$rgn{Rectangle};
my $tempX = $rect[0];
my $tempY = $rect[1];
$rect[0] = 1-$tempX-$rect[2];
$rect[1] = 1-$tempY-$rect[3];
push @newRgns, {
PersonDisplayName => $$rgn{PersonDisplayName},
Rectangle => join(', ', @rect),
};
}
return { Regions => \@newRgns };
}
}, #end RotateMPRegionCW180
RotateMPRegionCW270=>{
Require => 'RegionInfoMP',
ValueConv => q{
my ($rgn, @newRgns);
foreach $rgn (@{$val[0]{Regions}}) {
my @rect = split /\s*,\s*/, $$rgn{Rectangle};
my $temp = $rect[1];
$rect[1] = 1-$rect[0]-$rect[2];
$rect[0] = $temp;
($rect[2], $rect[3]) = ($rect[3],$rect[2]); #Swap W and H
push @newRgns, {
PersonDisplayName => $$rgn{PersonDisplayName},
Rectangle => join(', ', @rect),
};
}
return { Regions => \@newRgns };
}
}, #end RotateMPRegionCW270
},
);
1; #end
+121
View File
@@ -0,0 +1,121 @@
#------------------------------------------------------------------------------
# File: tiff_version.config
#
# Description: This config file contains the definition for a Composite
# TIFFVersion tag used to determine the version of a TIFF file
#
# Usage: exiftool -config tiff_version.config -tiffversion DIR
#
# Requires: ExifTool version 11.50 or later
#
# Revisions: 2019/06/06 - Bryan K. Williams (aka StarGeek) Created
# 2019/06/07 - P. Harvey added test of TIFF format types
#
# References: http://jhove.openpreservation.org/modules/tiff/#profiles
#------------------------------------------------------------------------------
# Checks if at least one the values passed are defined.
sub has_defined {
for my $i ( @_ ) {
return 1 if defined $i;
}
return 0;
}
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
TIFFVersion => {
Require => {
0 => 'FileType'
},
Desire => {
# Version 5
1 => 'EXIF:Artist', # Artist (315/0x013b)
2 => 'EXIF:ColorMap', # ColorMap (320/0x0140)
3 => 'EXIF:ModifyDate', # DateTime (306/0x0132) Called DateTime by EXIF spec, ModifyDate by exiftool
4 => 'EXIF:HostComputer', # HostComputer (316/0x013c)
5 => 'EXIF:SubfileType', # NewSubfileType (254/0x00fe) Called NewSubfileType by TIFF spec, SubfileType by exiftool
6 => 'EXIF:Predictor', # Predictor (317/0x013d)
7 => 'EXIF:PrimaryChromaticities', # PrimaryChromaticities (319/0x013f)
8 => 'EXIF:Software', # Software (305/0x0131)
9 => 'EXIF:WhitePoint', # WhitePoint (318/0x013e)
# Version 6
10 => 'EXIF:Copyright', # Copyright (33432/0x8298)
11 => 'EXIF:DotRange', # DotRange (336/0x0150)
12 => 'EXIF:ExtraSamples', # ExtraSamples (338/0x0152)
13 => 'EXIF:HalftoneHints', # HalftoneHints (321/0x0141)
14 => 'EXIF:InkNames', # InkNames (333/0x014d)
15 => 'EXIF:InkSet', # InkSet (332/0x014c)
16 => 'EXIF:JPEGACTables', # JPEGACTables (521/0x0209)
17 => 'EXIF:JPEGDCTables', # JPEGDCTables (520/0x0208)
18 => 'EXIF:ThumbnailOffset', # JPEGInterchangeFormat (513/0x0201)
19 => 'EXIF:ThumbnailLength ', # JPEGInterchangeFormatLength (514/0x0202)
20 => 'EXIF:JPEGLosslessPredictors', # JPEGLosslessPredictors (517/0x0205)
21 => 'EXIF:JPEGPointTransforms', # JPEGPointTransforms (518/0x0206)
22 => 'EXIF:JPEGProc', # JPEGProc (512/0x0200)
23 => 'EXIF:JPEGRestartInterval', # JPEGRestartInterval (515/0x0203)
24 => 'EXIF:JPEGQTables', # JPEGQTables (519/0x0207)
25 => 'EXIF:NumberofInks', # NumberOfInks (334/0x014e)
26 => 'EXIF:ReferenceBlackWhite', # ReferenceBlackWhite (532/0x0214)
27 => 'EXIF:SampleFormat', # SampleFormat (339/0x0153)
28 => 'EXIF:SMinSampleValue', # SMinSampleValue (340/0x0154)
29 => 'EXIF:SMaxSampleValue', # SMaxSampleValue (341/0x0155)
30 => 'EXIF:TargetPrinter', # TargetPrinter (337/0x0151)
31 => 'EXIF:TileLength', # TileLength (323/0x0143)
32 => 'EXIF:TileOffsets', # TileOffsets (324/0x0144)
33 => 'EXIF:TileWidth', # TileWidth (322/0x0142)
34 => 'EXIF:TileByteCounts', # TileByteCounts (325/0x0145)
35 => 'EXIF:TransferRange', # TransferRange (342/0x0156)
36 => 'EXIF:YCbCrCoefficients', # YCbCrCoefficients (529/0x0211)
37 => 'EXIF:YCbCrPositioning', # YCbCrPositioning (531/0x0213)
38 => 'EXIF:YCbCrSubSampling', # YCbCrSubSampling (530/0x0212)
# Other tags to check
39 => 'EXIF:PhotometricInterpretation', # PhotometricInterpretation (262/0x0106)
40 => 'EXIF:Compression', # Compression (259/0x0103)
},
ValueConv => q{
if ($val[0] ne 'TIFF') {
return undef;
}
unless ($$self{SaveFormat}) {
return '<you must use the API SaveFormat option and ExifTool 11.50 or later>';
}
foreach (qw(int8s undef int16s int32s rational64s float double)) {
return '6.0' if $$self{SaveFormat}{$_};
}
if ( $val[39]=~/^(?:C(?:IELab|MYK)|YCbCr)$/ or $val[40] eq 'JPEG (old-style)' or has_defined(@val[10..38]) ) {
return '6.0';
}
if ($val[39]=~/^(?:Transparency Mask|RGB Palette)$/ or $val[40] eq 'LZW' or has_defined(@val[1..9]) ) {
return '5.0';
}
return '4.0';
},
},
},
);
# A couple of shortcuts to test for the existence of certain tags
%Image::ExifTool::UserDefined::Shortcuts = (
TiffVersion5Tags => [
'EXIF:Artist', 'EXIF:ColorMap', 'EXIF:ModifyDate', 'EXIF:HostComputer', 'EXIF:SubfileType',
'EXIF:Predictor', 'EXIF:PrimaryChromaticities', 'EXIF:Software', 'EXIF:WhitePoint',
],
TiffVersion6Tags => [
'EXIF:Copyright', 'EXIF:DotRange', 'EXIF:ExtraSamples', 'EXIF:HalftoneHints',
'EXIF:InkNames', 'EXIF:InkSet', 'EXIF:JPEGACTables', 'EXIF:JPEGDCTables',
'EXIF:ThumbnailOffset', 'EXIF:ThumbnailLength ', 'EXIF:JPEGLosslessPredictors',
'EXIF:JPEGPointTransforms', 'EXIF:JPEGProc', 'EXIF:JPEGRestartInterval',
'EXIF:JPEGQTables', 'EXIF:NumberofInks', 'EXIF:ReferenceBlackWhite', 'EXIF:SampleFormat',
'EXIF:SMinSampleValue', 'EXIF:SMaxSampleValue', 'EXIF:TargetPrinter', 'EXIF:TileLength',
'EXIF:TileOffsets', 'EXIF:TileWidth', 'EXIF:TileByteCounts', 'EXIF:TransferRange',
'EXIF:YCbCrCoefficients', 'EXIF:YCbCrPositioning', 'EXIF:YCbCrSubSampling',
],
);
# Must set SaveFormat option to provide access to the tag format types
%Image::ExifTool::UserDefined::Options = (
SaveFormat => 1,
);
1; #end
+96
View File
@@ -0,0 +1,96 @@
#------------------------------------------------------------------------------
# File: time_zone.config
#
# Description: ExifTool config file to return time zone from an image
#
# Notes: The Composite:TimeZone tag defined here attempts to determine
# the time zone for an image. If possible, the camera time zone
# is used, if that does not exist, the time zone for
# DateTimeOriginal is returned, but if this can't be determined
# then the time zone for CreateDate and then ModifyDate are used.
# If this all does not result in a time zone, the timezone of the
# TimeCreated tag is used
#
# Usage: exiftool -config time_zone.config -timezone FILE
#
# Requires: ExifTool version 7.74 or later
#
# Revisions: 2016/10/03 - P. Harvey Created
# 2016/12/12 - H. Baan Corrected tag name, added support for
# camera time zone/daylight savings info in
# MakerNotes
# 2017/01/05 - H. Baan Handle case were GPSDateStamp is missing
# 2017/01/06 - H. Baan Use QuickTime:CreationDate if available
# 2017/03/12 - H. Baan Added QuickTime:TimeZone, reordered
# Desired tags according to precedence, added
# comments
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
# Calculate the TimeZone of the picture taken
TimeZone => {
Desire => {
# TimeZone information tags ordered by precedence
0 => 'MakerNotes:TimeZone',
1 => 'MakerNotes:DaylightSavings',
2 => 'QuickTime:TimeZone',
3 => 'OffsetTimeOriginal',
4 => 'OffsetTimeDigitized',
5 => 'OffsetTime',
6 => 'TimeZoneOffset',
7 => 'GPSDateStamp',
8 => 'GPSTimeStamp',
9 => 'DateTimeOriginal',
10 => 'DateTimeDigitized',
11 => 'CreateDate',
12 => 'ModifyDate',
13 => 'QuickTime:CreationDate',
14 => 'TimeCreated',
},
RawConv => q{
# TimeZone from MakeNotes (camera setting)
return TimeZoneString($val[0] + ($val[1] ? 60 : 0)) if defined $val[0];
# TimeZone from QuickTime (camera setting)
return TimeZoneString($val[2]) if $val[2];
# TimeZone from offset fields
return $val[3] if $val[3]; # DateTimeOriginal
return $val[4] if $val[4]; # DateTimeDigitized
return $val[5] if $val[5]; # (ModifyDate)
if (defined $val[6]) { # (ModifyDate)
my $tzh = $val[6];
$tzh =~ s/ .*//;
return TimeZoneString($tzh * 60);
}
# Difference between GPS and local time as TimeZone
if (defined $val[8]) {
my $loc = $val[9] || $val[10] || $val[11] || $val[12];
if ($loc) {
my @loc = split /[: ]/, $loc;
my @gmt = split /[: ]/, ($val[7]||"$loc[0]:$loc[1]:$loc[2]") . " $val[8]";
my $tzm = 15 * sprintf("%.0f", (GetTimeZone([@loc[5,4,3,2]], [@gmt[5,4,3,2]])) / 15);
$tzm -= 1440 if $tzm > 840;
$tzm += 1440 if $tzm < -720;
return TimeZoneString($tzm);
}
}
# TimeZone from QuickTime Creation Date
if ($val[13] && $val[13] =~ /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}([+-]\d{2})(\d{2})/) {
return TimeZoneString($1 * 60 + $2);
}
# Time Created
if ($val[14] && $val[14] =~ /\d{6}([+-]\d{2})(\d{2})/) {
return TimeZoneString($1 * 60 + $2);
}
return undef;
},
},
},
);
1; #end
Vendored Executable
+8155
View File
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
#------------------------------------------------------------------------------
# File: gpx.fmt
#
# Description: Example ExifTool print format file to generate a GPX track log
#
# Usage: exiftool -p gpx.fmt -ee3 FILE [...] > out.gpx
#
# Requires: ExifTool version 10.49 or later
#
# Revisions: 2010/02/05 - P. Harvey created
# 2018/01/04 - PH Added IF to be sure position exists
# 2018/01/06 - PH Use DateFmt function instead of -d option
# 2019/10/24 - PH Preserve sub-seconds in GPSDateTime value
# 2024/04/11 - PH Use %f feature in GPSDateTime formatting
#
# Notes: 1) Input file(s) must contain GPSLatitude and GPSLongitude.
# 2) The -ee3 option is to extract the full track from video files.
# 3) The -fileOrder option may be used to control the order of the
# generated track points when processing multiple files.
# 4) Coordinates are written at full resolution. To change this,
# remove the "#" from the GPSLatitude/Longitude tag names below
# and use the -c option to set the desired precision.
#------------------------------------------------------------------------------
#[HEAD]<?xml version="1.0" encoding="utf-8"?>
#[HEAD]<gpx version="1.0"
#[HEAD] creator="ExifTool $ExifToolVersion"
#[HEAD] xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
#[HEAD] xmlns="http://www.topografix.com/GPX/1/0"
#[HEAD] xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
#[HEAD]<trk>
#[HEAD]<number>1</number>
#[HEAD]<trkseg>
#[IF] $gpslatitude $gpslongitude
#[BODY]<trkpt lat="$gpslatitude#" lon="$gpslongitude#">
#[BODY] <ele>$gpsaltitude#</ele>
#[BODY] <time>${gpsdatetime#;DateFmt("%Y-%m-%dT%H:%M:%S%fZ")}</time>
#[BODY]</trkpt>
#[TAIL]</trkseg>
#[TAIL]</trk>
#[TAIL]</gpx>
+44
View File
@@ -0,0 +1,44 @@
#------------------------------------------------------------------------------
# File: gpx_wpt.fmt
#
# Description: Example ExifTool print format file to generate GPX waypoints
# with pictures
#
# Usage: exiftool -p gpx_wpt.fmt -ee3 FILE [...] > out.gpx
#
# Requires: ExifTool version 10.49 or later
#
# Revisions: 2010/03/13 - Peter Grimm created
# 2018/01/04 - PH Added IF to be sure position exists
# 2018/01/06 - PH Use DateFmt function instead of -d option
# 2019/10/24 - PH Preserve sub-seconds in GPSDateTime value
# 2024/04/11 - PH Use %f feature in GPSDateTime formatting
#
# Notes: 1) Input file(s) must contain GPSLatitude and GPSLongitude.
# 2) The -ee3 option is to extract the full track from video files.
# 3) The -fileOrder option may be used to control the order of the
# generated track points when processing multiple files.
# 4) Coordinates are written at full resolution. To change this,
# remove the "#" from the GPSLatitude/Longitude tag names below
# and use the -c option to set the desired precision.
#------------------------------------------------------------------------------
#[HEAD]<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
#[HEAD]<gpx version="1.1"
#[HEAD] creator="ExifTool $ExifToolVersion"
#[HEAD] xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
#[HEAD] xmlns="http://www.topografix.com/GPX/1/1"
#[HEAD] xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
#[IF] $gpslatitude $gpslongitude
#[BODY]<wpt lat="$gpslatitude#" lon="$gpslongitude#">
#[BODY] <ele>$gpsaltitude#</ele>
#[BODY] <time>${gpsdatetime#;DateFmt("%Y-%m-%dT%H:%M:%S%fZ")}</time>
#[BODY] <name>$filename</name>
#[BODY] <link href="$directory/$filename"/>
#[BODY] <sym>Scenic Area</sym>
#[BODY] <extensions>
#[BODY] <gpxx:WaypointExtension xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3">
#[BODY] <gpxx:DisplayMode>SymbolAndName</gpxx:DisplayMode>
#[BODY] </gpxx:WaypointExtension>
#[BODY] </extensions>
#[BODY]</wpt>
#[TAIL]</gpx>
+62
View File
@@ -0,0 +1,62 @@
#------------------------------------------------------------------------------
# File: kml.fmt
#
# Description: Example ExifTool print format file for generating a
# Google Earth KML file from a collection of geotagged images
#
# Usage: exiftool -p kml.fmt -r DIR [...] > out.kml
#
# Requires: ExifTool version 10.41 or later
#
# Revisions: 2010/02/05 - P. Harvey created
# 2013/02/05 - PH Fixed camera icon to work with new Google Earth
# 2017/02/02 - PH Organize into folders based on file directory
# 2018/01/04 - PH Added IF to be sure position exists
# 2020/01/11 - F. Kotov Limited image preview size to 500px
#
# Notes: 1) Input files must contain GPSLatitude and GPSLongitude.
# 2) Add the -ee3 option to extract the full track from video files.
# 3) For Google Earth to be able to find the images, the input
# images must be specified using relative paths, and "out.kml"
# must stay in the same directory as where the command was run.
# 4) Google Earth is picky about the case of the image file extension,
# and may not be able to display the image if an upper-case
# extension is used.
# 5) The -fileOrder option may be used to control the order of the
# generated placemarks when processing multiple files.
# 6) The "0" in the coordinates line may be changed to "$gpsaltitude#"
# and the altitudeMode may be changed to "absolute" to store
# altitude information if it exists in the track log.
#------------------------------------------------------------------------------
#[HEAD]<?xml version="1.0" encoding="UTF-8"?>
#[HEAD]<kml xmlns="http://earth.google.com/kml/2.0">
#[HEAD] <Document>
#[HEAD] <name>My Photos</name>
#[HEAD] <open>1</open>
#[HEAD] <Style id="Photo">
#[HEAD] <IconStyle>
#[HEAD] <Icon>
#[HEAD] <href>http://maps.google.com/mapfiles/kml/pal4/icon38.png</href>
#[HEAD] <scale>1.0</scale>
#[HEAD] </Icon>
#[HEAD] </IconStyle>
#[HEAD] </Style>
#[SECT] <Folder>
#[SECT] <name>$main:directory</name>
#[SECT] <open>0</open>
#[IF] $gpslatitude $gpslongitude
#[BODY] <Placemark>
#[BODY] <description><![CDATA[<img src='$main:directory/$main:filename'
#[BODY] style='max-width:500px;max-height:500px;'> ]]>
#[BODY] </description>
#[BODY] <Snippet/>
#[BODY] <name>$filename</name>
#[BODY] <styleUrl>#Photo</styleUrl>
#[BODY] <Point>
#[BODY] <altitudeMode>clampedToGround</altitudeMode>
#[BODY] <coordinates>$gpslongitude#,$gpslatitude#,0</coordinates>
#[BODY] </Point>
#[BODY] </Placemark>
#[ENDS] </Folder>
#[TAIL] </Document>
#[TAIL]</kml>
+49
View File
@@ -0,0 +1,49 @@
#------------------------------------------------------------------------------
# File: kml_track.fmt
#
# Description: Example ExifTool print format file for generating a
# track in Google Earth KML format from a collection of
# geotagged images or timed GPS from video files
#
# Usage: From a collection of images:
#
# exiftool -p kml_track.fmt -r DIR [...] > out.kml
#
# From video files:
#
# exiftool -p kml_track.fmt -ee3 FILEorDIR [...] > out.kml
#
# Requires: ExifTool version 10.41 or later
#
# Revisions: 2019/10/29 - P. Harvey created
#
# Notes: 1) Input files must contain GPSLatitude and GPSLongitude.
# 2) The -fileOrder option may be used to control the order of the
# waypoints when processing multiple still-image files, or the
# order of the tracks when processing multiple video files.
# 3) The "0" in the BODY line below may be changed to "$gpsaltitude#"
# and the altitudeMode may be changed to "absolute" to store
# altitude information if it exists in the track log.
#------------------------------------------------------------------------------
#[HEAD]<?xml version="1.0" encoding="UTF-8"?>
#[HEAD]<kml xmlns="http://earth.google.com/kml/2.0">
#[HEAD] <Document>
#[HEAD] <name>My Track</name>
#[HEAD] <open>1</open>
#[SECT] <Placemark>
#[SECT] <name>${main:directory;$_=$self->GetValue('FileName') if $self->Options('ExtractEmbedded')}</name>
#[SECT] <Style>
#[SECT] <LineStyle>
#[SECT] <color>#ff4499ff</color>
#[SECT] <width>3</width>
#[SECT] </LineStyle>
#[SECT] </Style>
#[SECT] <LineString>
#[SECT] <altitudeMode>clampToGround</altitudeMode>
#[SECT] <coordinates>
#[BODY]$gpslongitude#,$gpslatitude#,0
#[ENDS] </coordinates>
#[ENDS] </LineString>
#[ENDS] </Placemark>
#[TAIL] </Document>
#[TAIL]</kml>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

+2585
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+183
View File
@@ -0,0 +1,183 @@
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ExifTool Date/Time Shift Module</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rev="made" href="mailto:root@66b96.p1s.plx.sd.apple.com" />
<style type='text/css'><!-- pre { margin-left: 2em } --></style></head>
<body>
<table border="0" width="100%" cellspacing="0" cellpadding="3">
<tr><td class="_podblock_" style="background-color: #cccccc; color: #000" valign="middle">
<big><strong><span class="_podblock_">&nbsp;ExifTool Date/Time Shift Module</span></strong></big>
</td></tr>
</table>
<ul id="index">
<li><a href="#NAME">NAME</a></li>
<li><a href="#DESCRIPTION">DESCRIPTION</a></li>
<li><a href="#METHODS">METHODS</a>
<ul>
<li><a href="#ShiftTime">ShiftTime</a></li>
</ul>
</li>
<li><a href="#SHIFT-STRING">SHIFT STRING</a></li>
<li><a href="#NOTES">NOTES</a></li>
<li><a href="#TRICKY">TRICKY</a></li>
<li><a href="#BUGS">BUGS</a></li>
<li><a href="#AUTHOR">AUTHOR</a></li>
<li><a href="#SEE-ALSO">SEE ALSO</a></li>
</ul>
<h1 id="NAME">NAME</h1>
<p>Image::ExifTool::Shift.pl - ExifTool time shifting routines</p>
<h1 id="DESCRIPTION">DESCRIPTION</h1>
<p>This module contains routines used by ExifTool to shift date and time values.</p>
<h1 id="METHODS">METHODS</h1>
<h2 id="ShiftTime">ShiftTime</h2>
<p>Shift date/time value</p>
<pre><code>use Image::ExifTool;
$err = Image::ExifTool::ShiftTime($dateTime, $shift);</code></pre>
<dl>
<dt id="Inputs">Inputs:</dt>
<dd>
<p>0) Date/time string in EXIF format (eg. <code>2016:01:30 11:45:00</code>).</p>
<p>1) Shift string (see below) with optional leading sign for shift direction.</p>
<p>2) [optional] Direction of shift (-1 or +1), or 0 or undef to use the sign from the shift string.</p>
<p>3) [optional] Reference to time-shift hash -- filled in by first call to <b>ShiftTime</b>, and used in subsequent calls to shift date/time values by the same relative amount (see <a href="#TRICKY">&quot;TRICKY&quot;</a> section below).</p>
<p>or</p>
<p>0) Shift string (and $_ contains the input date/time string).</p>
</dd>
<dt id="Return-value">Return value:</dt>
<dd>
<p>Error string, or undef on success and the input date/time string is shifted by the specified amount.</p>
</dd>
</dl>
<h1 id="SHIFT-STRING">SHIFT STRING</h1>
<p>Time shifts are applied to standard EXIF-formatted date/time values (eg. <code>2005:03:14 18:55:00</code>). Date-only and time-only values may also be shifted, and an optional timezone (eg. <code>-05:00</code>) is also supported. Here are some general rules and examples to explain how shift strings are interpreted:</p>
<p>Date-only values are shifted using the following formats:</p>
<pre><code>&#39;Y:M:D&#39; - shift date by &#39;Y&#39; years, &#39;M&#39; months and &#39;D&#39; days
&#39;M:D&#39; - shift months and days only
&#39;D&#39; - shift specified number of days</code></pre>
<p>Time-only values are shifted using the following formats:</p>
<pre><code>&#39;h:m:s&#39; - shift time by &#39;h&#39; hours, &#39;m&#39; minutes and &#39;s&#39; seconds
&#39;h:m&#39; - shift hours and minutes only
&#39;h&#39; - shift specified number of hours</code></pre>
<p>Timezone shifts are specified in the following formats:</p>
<pre><code>&#39;+h:m&#39; - shift timezone by &#39;h&#39; hours and &#39;m&#39; minutes
&#39;-h:m&#39; - negative shift of timezone hours and minutes
&#39;+h&#39; - shift timezone hours only
&#39;-h&#39; - negative shift of timezone hours only</code></pre>
<p>A valid shift value consists of one or two arguments, separated by a space. If only one is provided, it is assumed to be a time shift when applied to a time-only or a date/time value, or a date shift when applied to a date-only value. For example:</p>
<pre><code>&#39;1&#39; - shift by 1 hour if applied to a time or date/time
value, or by one day if applied to a date value
&#39;2:0&#39; - shift 2 hours (time, date/time), or 2 months (date)
&#39;5:0:0&#39; - shift 5 hours (time, date/time), or 5 years (date)
&#39;0:0:1&#39; - shift 1 s (time, date/time), or 1 day (date)</code></pre>
<p>If two arguments are given, the date shift is first, followed by the time shift:</p>
<pre><code>&#39;3:0:0 0&#39; - shift date by 3 years
&#39;0 15:30&#39; - shift time by 15 hours and 30 minutes
&#39;1:0:0 0:0:0+5:0&#39; - shift date by 1 year and timezone by 5 hours</code></pre>
<p>A date shift is simply ignored if applied to a time value or visa versa.</p>
<p>Numbers specified in shift fields may contain a decimal point:</p>
<pre><code>&#39;1.5&#39; - 1 hour 30 minutes (time, date/time), or 1 day (date)
&#39;2.5 0&#39; - 2 days 12 hours (date/time), 12 hours (time) or
2 days (date)</code></pre>
<p>And to save typing, a zero is assumed for any missing numbers:</p>
<pre><code>&#39;1::&#39; - shift by 1 hour (time, date/time) or 1 year (date)
&#39;26:: 0&#39; - shift date by 26 years
&#39;+:30&#39; - shift timezone by 30 minutes</code></pre>
<p>Below are some specific examples applied to real date and/or time values (&#39;Dir&#39; is the applied shift direction: &#39;+&#39; is positive, &#39;-&#39; is negative):</p>
<pre><code> Original Value Shift Dir Shifted Value
--------------------- ------- --- ---------------------
&#39;20:30:00&#39; &#39;5&#39; + &#39;01:30:00&#39;
&#39;2005:01:27&#39; &#39;5&#39; + &#39;2005:02:01&#39;
&#39;2005:01:27 20:30:00&#39; &#39;5&#39; + &#39;2005:01:28 01:30:00&#39;
&#39;11:54:00&#39; &#39;2.5 0&#39; - &#39;23:54:00&#39;
&#39;2005:11:02&#39; &#39;2.5 0&#39; - &#39;2005:10:31&#39;
&#39;2005:11:02 11:54:00&#39; &#39;2.5 0&#39; - &#39;2005:10:30 23:54:00&#39;
&#39;2004:02:28 08:00:00&#39; &#39;1 1.3&#39; + &#39;2004:02:29 09:18:00&#39;
&#39;07:00:00&#39; &#39;-5&#39; + &#39;07:00:00&#39;
&#39;07:00:00+01:00&#39; &#39;-5&#39; + &#39;07:00:00-04:00&#39;
&#39;07:00:00Z&#39; &#39;+2:30&#39; - &#39;07:00:00-02:30&#39;
&#39;1970:01:01&#39; &#39;35::&#39; + &#39;2005:01:01&#39;
&#39;2005:01:01&#39; &#39;400&#39; + &#39;2006:02:05&#39;
&#39;10:00:00.00&#39; &#39;::1.33&#39; - &#39;09:59:58.67&#39;</code></pre>
<h1 id="NOTES">NOTES</h1>
<p>The format of the original date/time value is not changed when the time shift is applied. This means that the length of the date/time string will not change, and only the numbers in the string will be modified. The only exception to this rule is that a &#39;Z&#39; timezone is changed to &#39;+00:00&#39; notation if a timezone shift is applied. A timezone will not be added to the date/time string.</p>
<h1 id="TRICKY">TRICKY</h1>
<p>This module is perhaps more complicated than it needs to be because it is designed to be very flexible in the way time shifts are specified and applied...</p>
<p>The ability to shift dates by Y years, M months, etc, conflicts with the design goal of maintaining a constant shift for all time values when applying a batch shift. This is because shifting by 1 month can be equivalent to anything from 28 to 31 days, and 1 year can be 365 or 366 days, depending on the starting date.</p>
<p>The inconsistency is handled by shifting the first tag found with the actual specified shift, then calculating the equivalent time difference in seconds for this shift and applying this difference to subsequent tags in a batch conversion. So if it works as designed, the behaviour should be both intuitive and mathematically correct, and the user shouldn&#39;t have to worry about details such as this (in keeping with Perl&#39;s &quot;do the right thing&quot; philosophy).</p>
<h1 id="BUGS">BUGS</h1>
<p>Due to the use of the standard time library functions, dates are typically limited to the range 1970 to 2038 on 32-bit systems.</p>
<h1 id="AUTHOR">AUTHOR</h1>
<p>Copyright 2003-2026, Phil Harvey (philharvey66 at gmail.com)</p>
<p>This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.</p>
<h1 id="SEE-ALSO">SEE ALSO</h1>
<p><a>Image::ExifTool(3pm)</a></p>
<table border="0" width="100%" cellspacing="0" cellpadding="3">
<tr><td class="_podblock_" style="background-color: #cccccc; color: #000" valign="middle">
<big><strong><span class="_podblock_">&nbsp;ExifTool Date/Time Shift Module</span></strong></big>
</td></tr>
</table>
</body>
</html>
+55
View File
@@ -0,0 +1,55 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>AAC Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>AAC Tags</h2>
<p>Tags extracted from Advanced Audio Coding (AAC) files.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'Bit016-017'</td>
<td>ProfileType</td>
<td class=c>no</td>
<td><span class=s>0 = Main
<br>1 = Low Complexity
<br>2 = Scalable Sampling Rate</span></td></tr>
<tr class=b>
<td>'Bit018-021'</td>
<td>SampleRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Bit023-025'</td>
<td>Channels</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = ?
<br>1 = 1
<br>2 = 2
<br>3 = 3</td><td>&nbsp;&nbsp;</td>
<td>4 = 4
<br>5 = 5
<br>6 = 5+1
<br>7 = 7+1</td></tr></table>
</td></tr>
<tr class=b>
<td>'Encoder'</td>
<td>Encoder</td>
<td class=c>no</td>
<td><span class=s><span class=n>(taken from filler payload of first frame)</span></span></td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Jan 10, 2024</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+54
View File
@@ -0,0 +1,54 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>AFCP Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>AFCP Tags</h2>
<p>AFCP stands for AXS File Concatenation Protocol, and is a poorly designed
protocol for appending information to the end of files. This can be used as
an auxiliary technique to store IPTC information in images, but is
incompatible with some file formats.</p>
<p>ExifTool will read and write (but not create) AFCP IPTC information in JPEG
and TIFF images.</p>
<p>See
<a href="http://web.archive.org/web/20080828211305/http://www.tocarte.com/media/axs_afcp_spec.pdf">http://web.archive.org/web/20080828211305/http://www.tocarte.com/media/axs_afcp_spec.pdf</a>
for the AFCP specification.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'IPTC'</td>
<td>IPTC</td>
<td class=c>-</td>
<td>--&gt; <a href='IPTC.html'>IPTC Tags</a></td></tr>
<tr class=b>
<td>'Nail'</td>
<td>ThumbnailImage</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'PrVw'</td>
<td>PreviewImage</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'TEXT'</td>
<td>Text</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Jul 3, 2013</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+160
View File
@@ -0,0 +1,160 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>AIFF Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>AIFF Tags</h2>
<p>Tags extracted from Audio Interchange File Format (AIFF) files. See
<a href="http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html">http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html</a> for
the AIFF specification.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'(c) '</td>
<td>Copyright</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ANNO'</td>
<td>Annotation</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'APPL'</td>
<td>ApplicationData</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'AUTH'</td>
<td>Author</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'COMM'</td>
<td>Common</td>
<td class=c>-</td>
<td>--&gt; <a href='AIFF.html#Common'>AIFF Common Tags</a></td></tr>
<tr class=b>
<td>'COMT'</td>
<td>Comment</td>
<td class=c>-</td>
<td>--&gt; <a href='AIFF.html#Comment'>AIFF Comment Tags</a></td></tr>
<tr>
<td>'FVER'</td>
<td>FormatVersion</td>
<td class=c>-</td>
<td>--&gt; <a href='AIFF.html#FormatVers'>AIFF FormatVers Tags</a></td></tr>
<tr class=b>
<td>'ID3 '</td>
<td>ID3</td>
<td class=c>-</td>
<td>--&gt; <a href='ID3.html'>ID3 Tags</a></td></tr>
<tr>
<td>'NAME'</td>
<td>Name</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Common'>AIFF Common Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index2</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>NumChannels</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>NumSampleFrames</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='3 = 0x3'>3</td>
<td>SampleSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4</td>
<td>SampleRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='9 = 0x9'>9</td>
<td>CompressionType</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>&#39;ACE2&#39; = ACE 2-to-1
<br>&#39;ACE8&#39; = ACE 8-to-3
<br>&#39;ALAW&#39; = A-law
<br>&#39;G722&#39; = G722
<br>&#39;G726&#39; = G726
<br>&#39;G728&#39; = G728
<br>&#39;GSM &#39; = GSM
<br>&#39;MAC3&#39; = MAC 3-to-1
<br>&#39;MAC6&#39; = MAC 6-to-1
<br>&#39;NONE&#39; = None
<br>&#39;ULAW&#39; = Mu-law
<br>&#39;alaw&#39; = a-law
<br>&#39;sowt&#39; = Little-endian, no compression
<br>&#39;ulaw&#39; = mu-law</td></tr></table>
</td></tr>
<tr class=b>
<td class=r title='11 = 0xb'>11</td>
<td>CompressorName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Comment'>AIFF Comment Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0000 = 0'>0x0000</td>
<td>CommentTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0001 = 1'>0x0001</td>
<td>MarkerID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0002 = 2'>0x0002</td>
<td>Comment</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='FormatVers'>AIFF FormatVers Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>FormatVersionTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Aug 24, 2020</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+155
View File
@@ -0,0 +1,155 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>APE Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>APE Tags</h2>
<p>Tags found in Monkey&#39;s Audio (APE) information. Only a few common tags are
listed below, but ExifTool will extract any tag found. ExifTool supports
APEv1 and APEv2 tags, as well as ID3 information in APE files, and will also
read APE metadata from MP3 and MPC files.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'Album'</td>
<td>Album</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Artist'</td>
<td>Artist</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'DURATION'</td>
<td>Duration</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Genre'</td>
<td>Genre</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Title'</td>
<td>Title</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Tool Name'</td>
<td>ToolName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Tool Version'</td>
<td>ToolVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Track'</td>
<td>Track</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Year'</td>
<td>Year</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='NewHeader'>APE NewHeader Tags</a></h2>
<p>APE MAC audio header for version 3.98 or later.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index2</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>CompressionLevel</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='2 = 0x2'>2</td>
<td>BlocksPerFrame</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>FinalFrameBlocks</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>TotalFrames</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='8 = 0x8'>8</td>
<td>BitsPerSample</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='9 = 0x9'>9</td>
<td>Channels</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='10 = 0xa'>10</td>
<td>SampleRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='OldHeader'>APE OldHeader Tags</a></h2>
<p>APE MAC audio header for version 3.97 or earlier.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index2</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>APEVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>CompressionLevel</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='3 = 0x3'>3</td>
<td>Channels</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4</td>
<td>SampleRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='10 = 0xa'>10</td>
<td>TotalFrames</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='12 = 0xc'>12</td>
<td>FinalFrameBlocks</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Sep 24, 2025</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+189
View File
@@ -0,0 +1,189 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>APP12 Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top><a name='PictureInfo'>APP12 PictureInfo Tags</a></h2>
<p>The JPEG APP12 &quot;Picture Info&quot; segment was used by some older cameras, and
contains ASCII-based meta information. Below are some tags which have been
observed Agfa and Polaroid images, however ExifTool will extract information
from any tags found in this segment.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'Aperture'</td>
<td>Aperture</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ColorMode'</td>
<td>ColorMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ContTake'</td>
<td>ContTake</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ExpBias'</td>
<td>ExposureCompensation</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'FNumber'</td>
<td>FNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'FWare'</td>
<td>FirmwareVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Flash'</td>
<td>Flash</td>
<td class=c>no</td>
<td><span class=s>0 = Off
<br>1 = On</span></td></tr>
<tr class=b>
<td>'FocusMode'</td>
<td>FocusMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'FocusPos'</td>
<td>FocusPos</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ID'</td>
<td>ID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ImageSize'</td>
<td>ImageSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'LightS'</td>
<td>LightS</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Macro'</td>
<td>Macro</td>
<td class=c>no</td>
<td><span class=s>0 = Off
<br>1 = On</span></td></tr>
<tr class=b>
<td>'Protect'</td>
<td>Protect</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Quality'</td>
<td>Quality</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Resolution'</td>
<td>Resolution</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Serial#'</td>
<td>SerialNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Shutter'</td>
<td>ExposureTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'StrobeTime'</td>
<td>StrobeTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'TimeDate'</td>
<td>DateTimeOriginal</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Type'</td>
<td>CameraType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Version'</td>
<td>Version</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Ytarget'</td>
<td>YTarget</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Zoom'</td>
<td>Zoom</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ZoomPos'</td>
<td>ZoomPos</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'shtr'</td>
<td>ExposureTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ylevel'</td>
<td>YLevel</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Ducky'>APP12 Ducky Tags</a></h2>
<p>Photoshop uses the JPEG APP12 &quot;Ducky&quot; segment to store some information in
&quot;Save for Web&quot; images.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0001 = 1'>0x0001</td>
<td>Quality</td>
<td class=c title=' / = Avoid'>int32u/</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0002 = 2'>0x0002</td>
<td>Comment</td>
<td class=c title=' / = Avoid'>string/</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0003 = 3'>0x0003</td>
<td>Copyright</td>
<td class=c title=' / = Avoid'>string/</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Oct 15, 2024</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff
+281
View File
@@ -0,0 +1,281 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>Apple Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>Apple Tags</h2>
<p>Tags extracted from the maker notes of iPhone images.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0001 = 1'>0x0001</td>
<td>MakerNoteVersion</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0002 = 2'>0x0002</td>
<td>AEMatrix?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0003 = 3'>0x0003</td>
<td>RunTime</td>
<td class=c>-</td>
<td>--&gt; <a href='Apple.html#RunTime'>Apple RunTime Tags</a></td></tr>
<tr class=b>
<td title='0x0004 = 4'>0x0004</td>
<td>AEStable</td>
<td class=c>int32s</td>
<td><span class=s>0 = No
<br>1 = Yes</span></td></tr>
<tr>
<td title='0x0005 = 5'>0x0005</td>
<td>AETarget</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0006 = 6'>0x0006</td>
<td>AEAverage</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0007 = 7'>0x0007</td>
<td>AFStable</td>
<td class=c>int32s</td>
<td><span class=s>0 = No
<br>1 = Yes</span></td></tr>
<tr class=b>
<td title='0x0008 = 8'>0x0008</td>
<td>AccelerationVector</td>
<td class=c>rational64s[3]</td>
<td><span class=s><span class=n>(XYZ coordinates of the acceleration vector in units of g. As viewed from
the front of the phone, positive X is toward the left side, positive Y is
toward the bottom, and positive Z points into the face of the phone)</span></span></td></tr>
<tr>
<td title='0x000a = 10'>0x000a</td>
<td>HDRImageType</td>
<td class=c>int32s</td>
<td><span class=s>3 = HDR Image
<br>4 = Original Image</span></td></tr>
<tr class=b>
<td title='0x000b = 11'>0x000b</td>
<td>BurstUUID</td>
<td class=c>string</td>
<td><span class=s><span class=n>(unique ID for all images in a burst)</span></span></td></tr>
<tr>
<td title='0x000c = 12'>0x000c</td>
<td>FocusDistanceRange</td>
<td class=c>rational64s[2]</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x000f = 15'>0x000f</td>
<td>OISMode</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0011 = 17'>0x0011</td>
<td>ContentIdentifier</td>
<td class=c>string</td>
<td><span class=s><span class=n>(called MediaGroupUUID when it appears as an XAttr)</span></span></td></tr>
<tr class=b>
<td title='0x0014 = 20'>0x0014</td>
<td>ImageCaptureType</td>
<td class=c>int32s</td>
<td><span class=s>1 = ProRAW
<br>2 = Portrait
<br>10 = Photo
<br>11 = Manual Focus
<br>12 = Scene</span></td></tr>
<tr>
<td title='0x0015 = 21'>0x0015</td>
<td>ImageUniqueID</td>
<td class=c>string</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0017 = 23'>0x0017</td>
<td>LivePhotoVideoIndex</td>
<td class=c>yes</td>
<td><span class=s><span class=n>(divide by RunTimeScale to get time in seconds)</span></span></td></tr>
<tr>
<td title='0x0019 = 25'>0x0019</td>
<td>ImageProcessingFlags?</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x001a = 26'>0x001a</td>
<td>QualityHint?</td>
<td class=c>string</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x001d = 29'>0x001d</td>
<td>LuminanceNoiseAmplitude</td>
<td class=c>rational64s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x001f = 31'>0x001f</td>
<td>PhotosAppFeatureFlags</td>
<td class=c>int32s</td>
<td><span class=s><span class=n>(set if person or pet detected in image)</span></span></td></tr>
<tr>
<td title='0x0020 = 32'>0x0020</td>
<td>ImageCaptureRequestID?</td>
<td class=c>string</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0021 = 33'>0x0021</td>
<td>HDRHeadroom</td>
<td class=c>rational64s</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0023 = 35'>0x0023</td>
<td>AFPerformance</td>
<td class=c>int32s[2]</td>
<td><span class=s><span class=n>(first number maybe related to focus distance, last number maybe related to
focus accuracy)</span></span></td></tr>
<tr class=b>
<td title='0x0025 = 37'>0x0025</td>
<td>SceneFlags?</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0026 = 38'>0x0026</td>
<td>SignalToNoiseRatioType?</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0027 = 39'>0x0027</td>
<td>SignalToNoiseRatio</td>
<td class=c>rational64s</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x002b = 43'>0x002b</td>
<td>PhotoIdentifier</td>
<td class=c>string</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x002d = 45'>0x002d</td>
<td>ColorTemperature</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x002e = 46'>0x002e</td>
<td>CameraType</td>
<td class=c>int32s</td>
<td><span class=s>0 = Back Wide Angle
<br>1 = Back Normal
<br>6 = Front</span></td></tr>
<tr class=b>
<td title='0x002f = 47'>0x002f</td>
<td>FocusPosition</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0030 = 48'>0x0030</td>
<td>HDRGain</td>
<td class=c>rational64s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0038 = 56'>0x0038</td>
<td>AFMeasuredDepth</td>
<td class=c>int32s</td>
<td><span class=s><span class=n>(from the time-of-flight-assisted auto-focus estimator)</span></span></td></tr>
<tr>
<td title='0x003d = 61'>0x003d</td>
<td>AFConfidence</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x003e = 62'>0x003e</td>
<td>ColorCorrectionMatrix?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x003f = 63'>0x003f</td>
<td>GreenGhostMitigationStatus?</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0040 = 64'>0x0040</td>
<td>SemanticStyle</td>
<td class=c>no</td>
<td><span class=s><span class=n>(_1=Tone, _2=Warm, _3=1.Std,2.Vibrant,3.Rich Contrast,4.Warm,5.Cool)</span></span></td></tr>
<tr>
<td title='0x0041 = 65'>0x0041</td>
<td>SemanticStyleRenderingVer</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0042 = 66'>0x0042</td>
<td>SemanticStylePreset</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x004e = 78'>0x004e</td>
<td>Apple_0x004e?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x004f = 79'>0x004f</td>
<td>Apple_0x004f?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0054 = 84'>0x0054</td>
<td>Apple_0x0054?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x005a = 90'>0x005a</td>
<td>Apple_0x005a?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='RunTime'>Apple RunTime Tags</a></h2>
<p>This PLIST-format information contains the elements of a CMTime structure
representing the amount of time the phone has been running since the last
boot, not including standby time.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'epoch'</td>
<td>RunTimeEpoch</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'flags'</td>
<td>RunTimeFlags</td>
<td class=c>no</td>
<td><span class=s>Bit 0 = Valid
<br>Bit 1 = Has been rounded
<br>Bit 2 = Positive infinity
<br>Bit 3 = Negative infinity
<br>Bit 4 = Indefinite</span></td></tr>
<tr>
<td>'timescale'</td>
<td>RunTimeScale</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'value'</td>
<td>RunTimeValue</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Mar 11, 2025</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+178
View File
@@ -0,0 +1,178 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>Audible Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>Audible Tags</h2>
<p>ExifTool will extract any information found in the metadata dictionary of
Audible .AA files, even if not listed in the table below.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'_chapter_count'</td>
<td>ChapterCount</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'_cover_art'</td>
<td>CoverArt</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'author'</td>
<td>Author</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'copyright'</td>
<td>Copyright</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'pub_date_start'</td>
<td>PublishDateStart</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'pubdate'</td>
<td>PublishDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='tags'>Audible tags Tags</a></h2>
<p>Information found in &quot;tags&quot; atom of Audible M4B audio books.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'cvrx'</td>
<td>Audible_cvrx</td>
<td class=c>-</td>
<td>--&gt; <a href='Audible.html#cvrx'>Audible cvrx Tags</a></td></tr>
<tr class=b>
<td>'meta'</td>
<td>Audible_meta</td>
<td class=c>-</td>
<td>--&gt; <a href='Audible.html#meta'>Audible meta Tags</a></td></tr>
<tr>
<td>'tseg'</td>
<td>Audible_tseg</td>
<td class=c>-</td>
<td>--&gt; <a href='Audible.html#tseg'>Audible tseg Tags</a></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='cvrx'>Audible cvrx Tags</a></h2>
<p>Audible cover art information in M4B audio books.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>CoverArt</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>CoverArtType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='meta'>Audible meta Tags</a></h2>
<p>Information found in Audible M4B &quot;meta&quot; atom.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'ALBUMARTIST'</td>
<td>AlbumArtist</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Album'</td>
<td>Album</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Artist'</td>
<td>Artist</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Comment'</td>
<td>Comment</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Genre'</td>
<td>Genre</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'SUBTITLE'</td>
<td>Subtitle</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'TOOL'</td>
<td>CreatorTool</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Title'</td>
<td>Title</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Year'</td>
<td>Year</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'itunesmediatype'</td>
<td>iTunesMediaType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'track'</td>
<td>ChapterName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='tseg'>Audible tseg Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'meta'</td>
<td>Audible_meta2</td>
<td class=c>-</td>
<td>--&gt; <a href='Audible.html#meta'>Audible meta Tags</a></td></tr>
<tr class=b>
<td>'tshd'</td>
<td>ChapterNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Mar 24, 2025</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+234
View File
@@ -0,0 +1,234 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>BMP Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>BMP Tags</h2>
<p>There really isn&#39;t much meta information in a BMP file as such, just a bit
of image related information.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>BMPVersion</td>
<td class=c>no</td>
<td><span class=s><span class=n>(this is actually the size of the BMP header, but used to determine the BMP
version)</span>
<br>40 = Windows V3
<br>68 = AVI BMP structure?
<br>108 = Windows V4
<br>124 = Windows V5</span></td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='8 = 0x8'>8</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='12 = 0xc'>12</td>
<td>Planes</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='14 = 0xe'>14</td>
<td>BitDepth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='16 = 0x10'>16</td>
<td>Compression</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = None
<br>1 = 8-Bit RLE
<br>2 = 4-Bit RLE</td><td>&nbsp;&nbsp;</td>
<td>3 = Bitfields
<br>4 = JPEG
<br>5 = PNG</td></tr></table>
</td></tr>
<tr>
<td class=r title='20 = 0x14'>20</td>
<td>ImageLength</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='24 = 0x18'>24</td>
<td>PixelsPerMeterX</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='28 = 0x1c'>28</td>
<td>PixelsPerMeterY</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='32 = 0x20'>32</td>
<td>NumColors</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='36 = 0x24'>36</td>
<td>NumImportantColors</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='40 = 0x28'>40</td>
<td>RedMask</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='44 = 0x2c'>44</td>
<td>GreenMask</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='48 = 0x30'>48</td>
<td>BlueMask</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='52 = 0x34'>52</td>
<td>AlphaMask</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='56 = 0x38'>56</td>
<td>ColorSpace</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = Calibrated RGB
<br>1 = Device RGB
<br>2 = Device CMYK
<br>&#39;LINK&#39; = Linked Color Profile
<br>&#39;MBED&#39; = Embedded Color Profile
<br>&#39;Win &#39; = Windows Color Space
<br>&#39;sRGB&#39; = sRGB</td></tr></table>
</td></tr>
<tr>
<td class=r title='60 = 0x3c'>60</td>
<td>RedEndpoint</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='72 = 0x48'>72</td>
<td>GreenEndpoint</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='84 = 0x54'>84</td>
<td>BlueEndpoint</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='96 = 0x60'>96</td>
<td>GammaRed</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='100 = 0x64'>100</td>
<td>GammaGreen</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='104 = 0x68'>104</td>
<td>GammaBlue</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='108 = 0x6c'>108</td>
<td>RenderingIntent</td>
<td class=c>no</td>
<td><span class=s>1 = Graphic (LCS_GM_BUSINESS)
<br>2 = Proof (LCS_GM_GRAPHICS)
<br>4 = Picture (LCS_GM_IMAGES)
<br>8 = Absolute Colorimetric (LCS_GM_ABS_COLORIMETRIC)</span></td></tr>
<tr class=b>
<td class=r title='112 = 0x70'>112</td>
<td>ProfileDataOffset</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='116 = 0x74'>116</td>
<td>ProfileSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='OS2'>BMP OS2 Tags</a></h2>
<p>Information extracted from OS/2-format BMP images.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>BMPVersion</td>
<td class=c>no</td>
<td><span class=s><span class=n>(again, the header size is used to determine the BMP version)</span>
<br>12 = OS/2 V1
<br>64 = OS/2 V2</span></td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='6 = 0x6'>6</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='8 = 0x8'>8</td>
<td>Planes</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='10 = 0xa'>10</td>
<td>BitDepth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Extra'>BMP Extra Tags</a></h2>
<p>Extra information extracted from some BMP images.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>EmbeddedJPG</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>EmbeddedPNG</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>ICC_Profile</td>
<td class=c>-</td>
<td>--&gt; <a href='ICC_Profile.html'>ICC_Profile Tags</a></td></tr>
<tr class=b>
<td>LinkedProfileName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Dec 7, 2016</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+119
View File
@@ -0,0 +1,119 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>BPG Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>BPG Tags</h2>
<p>The information listed below is extracted from BPG (Better Portable
Graphics) images. See <a href="http://bellard.org/bpg/">http://bellard.org/bpg/</a> for the specification.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>PixelFormat</td>
<td class=c>no</td>
<td><span class=s>[val &gt;&gt; 13 &amp; 0x7]</span><table class=cols><tr>
<td>0 = Grayscale
<br>1 = 4:2:0 (chroma at 0.5, 0.5)
<br>2 = 4:2:2 (chroma at 0.5, 0)
<br>3 = 4:4:4
<br>4 = 4:2:0 (chroma at 0, 0.5)
<br>5 = 4:2:2 (chroma at 0, 0)</td></tr></table>
</td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4.1</td>
<td>Alpha</td>
<td class=c>no</td>
<td><span class=s>[val &amp; 0x1004]
<br>0x0 = No Alpha Plane
<br>0x4 = Alpha Exists (W color component)
<br>0x1000 = Alpha Exists (color not premultiplied)
<br>0x1004 = Alpha Exists (color premultiplied)</span></td></tr>
<tr>
<td class=r title='4 = 0x4'>4.2</td>
<td>BitDepth</td>
<td class=c>no</td>
<td><span class=s>[val &gt;&gt; 8 &amp; 0xf]</span></td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4.3</td>
<td>ColorSpace</td>
<td class=c>no</td>
<td><span class=s>[val &gt;&gt; 4 &amp; 0xf]</span><table class=cols><tr>
<td>0 = YCbCr (BT 601)
<br>1 = RGB
<br>2 = YCgCo
<br>3 = YCbCr (BT 709)
<br>4 = YCbCr (BT 2020)
<br>5 = BT 2020 Constant Luminance</td></tr></table>
</td></tr>
<tr>
<td class=r title='4 = 0x4'>4.4</td>
<td>Flags</td>
<td class=c>no</td>
<td><span class=s>[val &amp; 0xb]
<br>Bit 0 = Animation
<br>Bit 1 = Limited Range
<br>Bit 3 = Extension Present</span></td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='7 = 0x7'>7</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='8 = 0x8'>8</td>
<td>ImageLength</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Extensions'>BPG Extensions Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0001 = 1'>0x0001</td>
<td>EXIF</td>
<td class=c>-</td>
<td>--&gt; <a href='EXIF.html'>EXIF Tags</a></td></tr>
<tr class=b>
<td title='0x0002 = 2'>0x0002</td>
<td>ICC_Profile</td>
<td class=c>-</td>
<td>--&gt; <a href='ICC_Profile.html'>ICC_Profile Tags</a></td></tr>
<tr>
<td title='0x0003 = 3'>0x0003</td>
<td>XMP</td>
<td class=c>-</td>
<td>--&gt; <a href='XMP.html'>XMP Tags</a></td></tr>
<tr class=b>
<td title='0x0004 = 4'>0x0004</td>
<td>ThumbnailBPG</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0005 = 5'>0x0005</td>
<td>AnimationControl?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Oct 24, 2018</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+62
View File
@@ -0,0 +1,62 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>CBOR Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>CBOR Tags</h2>
<p>The tags below are extracted from CBOR (Concise Binary Object
Representation) metadata. The C2PA specification uses this format for some
metadata. As well as these tags, ExifTool will read any existing tags.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>AuthorIdentifier</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>AuthorName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>DocumentID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Format</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>InstanceID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Relationship</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>ThumbnailHash</td>
<td class=c title=' + = List'>no+</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ThumbnailURL</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>Title</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Sep 30, 2021</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+569
View File
@@ -0,0 +1,569 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>CanonRaw Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>CanonRaw Tags</h2>
<p>
These tags apply to CRW-format Canon RAW files and information in the APP0
&quot;CIFF&quot; segment of JPEG images. When writing CanonRaw/CIFF information, the
length of the information is preserved (and the new information is truncated
or padded as required) unless <b>Writable</b> is <code>resize</code>. Currently, only
JpgFromRaw and ThumbnailImage are allowed to change size. See
<a href="../canon_raw.html">canon_raw.html</a> for a description of the Canon CRW
format.</p>
<p>CRW images also support the addition of a CanonVRD trailer, which in turn
supports XMP. This trailer is created automatically if necessary when
ExifTool is used to write XMP to a CRW image.
</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0000 = 0'>0x0000</td>
<td>NullRecord</td>
<td class=c>undef</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0001 = 1'>0x0001</td>
<td>FreeBytes</td>
<td class=c>undef</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0032 = 50'>0x0032</td>
<td>CanonColorInfo1</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0805 = 2053'>0x0805</td>
<td>CanonFileDescription
<br>UserComment</td>
<td class=c>string[32]<br>string[256]</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x080a = 2058'>0x080a</td>
<td>CanonRawMakeModel</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html#MakeModel'>CanonRaw MakeModel Tags</a></td></tr>
<tr class=b>
<td title='0x080b = 2059'>0x080b</td>
<td>CanonFirmwareVersion</td>
<td class=c>string[32]</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x080c = 2060'>0x080c</td>
<td>ComponentVersion</td>
<td class=c>string</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x080d = 2061'>0x080d</td>
<td>ROMOperationMode</td>
<td class=c>string[8]</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0810 = 2064'>0x0810</td>
<td>OwnerName</td>
<td class=c>string[32]</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0815 = 2069'>0x0815</td>
<td>CanonImageType</td>
<td class=c>string[32]</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0816 = 2070'>0x0816</td>
<td>OriginalFileName</td>
<td class=c>string[32]</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0817 = 2071'>0x0817</td>
<td>ThumbnailFileName</td>
<td class=c>string[32]</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x100a = 4106'>0x100a</td>
<td>TargetImageType</td>
<td class=c>int16u</td>
<td><span class=s>0 = Real-world Subject
<br>1 = Written Document</span></td></tr>
<tr class=b>
<td title='0x1010 = 4112'>0x1010</td>
<td>ShutterReleaseMethod</td>
<td class=c>int16u</td>
<td><span class=s>0 = Single Shot
<br>2 = Continuous Shooting</span></td></tr>
<tr>
<td title='0x1011 = 4113'>0x1011</td>
<td>ShutterReleaseTiming</td>
<td class=c>int16u</td>
<td><span class=s>0 = Priority on shutter
<br>1 = Priority on focus</span></td></tr>
<tr class=b>
<td title='0x1016 = 4118'>0x1016</td>
<td>ReleaseSetting</td>
<td class=c>int16u</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x101c = 4124'>0x101c</td>
<td>BaseISO</td>
<td class=c>int16u</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x1028 = 4136'>0x1028</td>
<td>CanonFlashInfo?</td>
<td class=c>int16u[4]</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x1029 = 4137'>0x1029</td>
<td>CanonFocalLength</td>
<td class=c>-</td>
<td>--&gt; <a href='Canon.html#FocalLength'>Canon FocalLength Tags</a></td></tr>
<tr class=b>
<td title='0x102a = 4138'>0x102a</td>
<td>CanonShotInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='Canon.html#ShotInfo'>Canon ShotInfo Tags</a></td></tr>
<tr>
<td title='0x102c = 4140'>0x102c</td>
<td>CanonColorInfo2</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x102d = 4141'>0x102d</td>
<td>CanonCameraSettings</td>
<td class=c>-</td>
<td>--&gt; <a href='Canon.html#CameraSettings'>Canon CameraSettings Tags</a></td></tr>
<tr>
<td title='0x1030 = 4144'>0x1030</td>
<td>WhiteSample</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html#WhiteSample'>CanonRaw WhiteSample Tags</a></td></tr>
<tr class=b>
<td title='0x1031 = 4145'>0x1031</td>
<td>SensorInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='Canon.html#SensorInfo'>Canon SensorInfo Tags</a></td></tr>
<tr>
<td title='0x1033 = 4147'>0x1033</td>
<td>CustomFunctions10D
<br>CustomFunctionsD30
<br>CustomFunctionsD60
<br>CustomFunctionsUnknown</td>
<td class=c>-<br>-<br>-<br>-</td>
<td>--&gt; <a href='CanonCustom.html#Functions10D'>CanonCustom Functions10D Tags</a>
<br>--&gt; <a href='CanonCustom.html#FunctionsD30'>CanonCustom FunctionsD30 Tags</a>
<br>--&gt; <a href='CanonCustom.html#FunctionsD30'>CanonCustom FunctionsD30 Tags</a>
<br>--&gt; <a href='CanonCustom.html#FuncsUnknown'>CanonCustom FuncsUnknown Tags</a></td></tr>
<tr class=b>
<td title='0x1038 = 4152'>0x1038</td>
<td>CanonAFInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='Canon.html#AFInfo'>Canon AFInfo Tags</a></td></tr>
<tr>
<td title='0x1093 = 4243'>0x1093</td>
<td>CanonFileInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='Canon.html#FileInfo'>Canon FileInfo Tags</a></td></tr>
<tr class=b>
<td title='0x10a9 = 4265'>0x10a9</td>
<td>ColorBalance</td>
<td class=c>-</td>
<td>--&gt; <a href='Canon.html#ColorBalance'>Canon ColorBalance Tags</a></td></tr>
<tr>
<td title='0x10ae = 4270'>0x10ae</td>
<td>ColorTemperature</td>
<td class=c>int16u</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x10b4 = 4276'>0x10b4</td>
<td>ColorSpace</td>
<td class=c>int16u</td>
<td><span class=s>1 = sRGB
<br>2 = Adobe RGB
<br>65535 = Uncalibrated</span></td></tr>
<tr>
<td title='0x10b5 = 4277'>0x10b5</td>
<td>RawJpgInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html#RawJpgInfo'>CanonRaw RawJpgInfo Tags</a></td></tr>
<tr class=b>
<td title='0x1803 = 6147'>0x1803</td>
<td>ImageFormat</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html#ImageFormat'>CanonRaw ImageFormat Tags</a></td></tr>
<tr>
<td title='0x1804 = 6148'>0x1804</td>
<td>RecordID</td>
<td class=c>int32u</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x1806 = 6150'>0x1806</td>
<td>SelfTimerTime</td>
<td class=c>int32u</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x1807 = 6151'>0x1807</td>
<td>TargetDistanceSetting</td>
<td class=c>float</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x180b = 6155'>0x180b</td>
<td>SerialNumber
<br>UnknownNumber?</td>
<td class=c>int32u<br>yes</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x180e = 6158'>0x180e</td>
<td>TimeStamp</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html#TimeStamp'>CanonRaw TimeStamp Tags</a></td></tr>
<tr class=b>
<td title='0x1810 = 6160'>0x1810</td>
<td>ImageInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html#ImageInfo'>CanonRaw ImageInfo Tags</a></td></tr>
<tr>
<td title='0x1813 = 6163'>0x1813</td>
<td>FlashInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html#FlashInfo'>CanonRaw FlashInfo Tags</a></td></tr>
<tr class=b>
<td title='0x1814 = 6164'>0x1814</td>
<td>MeasuredEV</td>
<td class=c>float</td>
<td><span class=s><span class=n>(this is the Canon name for what could better be called MeasuredLV, and
should be close to the calculated LightValue for a proper exposure with most
models)</span></span></td></tr>
<tr>
<td title='0x1817 = 6167'>0x1817</td>
<td>FileNumber</td>
<td class=c>int32u</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x1818 = 6168'>0x1818</td>
<td>ExposureInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html#ExposureInfo'>CanonRaw ExposureInfo Tags</a></td></tr>
<tr>
<td title='0x1834 = 6196'>0x1834</td>
<td>CanonModelID</td>
<td class=c>int32u</td>
<td>--&gt; <a href='Canon.html#CanonModelID'>Canon CanonModelID Values</a>
<br><span class='n s'>(this is the complete list of model ID numbers, but note that many of these
models do not produce CRW images)</span></td></tr>
<tr class=b>
<td title='0x1835 = 6197'>0x1835</td>
<td>DecoderTable</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html#DecoderTable'>CanonRaw DecoderTable Tags</a></td></tr>
<tr>
<td title='0x183b = 6203'>0x183b</td>
<td>SerialNumberFormat</td>
<td class=c>int32u</td>
<td><span class=s>0x90000000 = Format 1
<br>0xa0000000 = Format 2</span></td></tr>
<tr class=b>
<td title='0x2005 = 8197'>0x2005</td>
<td>RawData</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x2007 = 8199'>0x2007</td>
<td>JpgFromRaw</td>
<td class=c title=' ^ = Deletable'>resize^</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x2008 = 8200'>0x2008</td>
<td>ThumbnailImage</td>
<td class=c title=' ^ = Deletable'>resize^</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x2804 = 10244'>0x2804</td>
<td>ImageDescription</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html'>CanonRaw Tags</a></td></tr>
<tr class=b>
<td title='0x2807 = 10247'>0x2807</td>
<td>CameraObject</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html'>CanonRaw Tags</a></td></tr>
<tr>
<td title='0x3002 = 12290'>0x3002</td>
<td>ShootingRecord</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html'>CanonRaw Tags</a></td></tr>
<tr class=b>
<td title='0x3003 = 12291'>0x3003</td>
<td>MeasuredInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html'>CanonRaw Tags</a></td></tr>
<tr>
<td title='0x3004 = 12292'>0x3004</td>
<td>CameraSpecification</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html'>CanonRaw Tags</a></td></tr>
<tr class=b>
<td title='0x300a = 12298'>0x300a</td>
<td>ImageProps</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html'>CanonRaw Tags</a></td></tr>
<tr>
<td title='0x300b = 12299'>0x300b</td>
<td>ExifInformation</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html'>CanonRaw Tags</a></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='MakeModel'>CanonRaw MakeModel Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>Make</td>
<td class=c>string[6]</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>Model</td>
<td class=c>string</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='WhiteSample'>CanonRaw WhiteSample Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index2</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='1 = 0x1'>1</td>
<td>WhiteSampleWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='2 = 0x2'>2</td>
<td>WhiteSampleHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='3 = 0x3'>3</td>
<td>WhiteSampleLeftBorder</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4</td>
<td>WhiteSampleTopBorder</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='5 = 0x5'>5</td>
<td>WhiteSampleBits</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='55 = 0x37'>55</td>
<td>BlackLevels</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='RawJpgInfo'>CanonRaw RawJpgInfo Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index2</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='1 = 0x1'>1</td>
<td>RawJpgQuality</td>
<td class=c>int16u</td>
<td><span class=s>1 = Economy
<br>2 = Normal
<br>3 = Fine
<br>5 = Superfine</span></td></tr>
<tr class=b>
<td class=r title='2 = 0x2'>2</td>
<td>RawJpgSize</td>
<td class=c>int16u</td>
<td><span class=s>0 = Large
<br>1 = Medium
<br>2 = Small</span></td></tr>
<tr>
<td class=r title='3 = 0x3'>3</td>
<td>RawJpgWidth</td>
<td class=c>int16u</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4</td>
<td>RawJpgHeight</td>
<td class=c>int16u</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='ImageFormat'>CanonRaw ImageFormat Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>FileFormat</td>
<td class=c>int32u</td>
<td><span class=s>0x10000 = JPEG (lossy)
<br>0x10002 = JPEG (non-quantization)
<br>0x10003 = JPEG (lossy/non-quantization toggled)
<br>0x20001 = CRW</span></td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>TargetCompressionRatio</td>
<td class=c>float</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='TimeStamp'>CanonRaw TimeStamp Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>DateTimeOriginal</td>
<td class=c>int32u</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>TimeZoneCode</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>TimeZoneInfo</td>
<td class=c>int32u</td>
<td><span class=s><span class=n>(set to 0x80000000 if TimeZoneCode is valid)</span></span></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='ImageInfo'>CanonRaw ImageInfo Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>PixelAspectRatio</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>Rotation</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>ComponentBitDepth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='5 = 0x5'>5</td>
<td>ColorBitDepth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='6 = 0x6'>6</td>
<td>ColorBW</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='FlashInfo'>CanonRaw FlashInfo Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>FlashGuideNumber</td>
<td class=c>float</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>FlashThreshold</td>
<td class=c>float</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='ExposureInfo'>CanonRaw ExposureInfo Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>ExposureCompensation</td>
<td class=c>float</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>ShutterSpeedValue</td>
<td class=c>float</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>ApertureValue</td>
<td class=c>float</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='DecoderTable'>CanonRaw DecoderTable Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>DecoderTableNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='2 = 0x2'>2</td>
<td>CompressedDataOffset</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='3 = 0x3'>3</td>
<td>CompressedDataLength</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Feb 6, 2026</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+866
View File
@@ -0,0 +1,866 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>Composite Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>Composite Tags</h2>
<p>
The values of the composite tags are <b>Derived From</b> the values of other
tags. These are convenience tags which are calculated after all other
information is extracted. Only a few of these tags are writable directly,
the others are changed by writing the corresponding <b>Derived From</b> tags.
User-defined Composite tags, also useful for custom-formatting of tag
values, may created via the <a href="../config.html">ExifTool configuration file</a>.
</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag Name</th>
<th>Writable</th><th>Derived From</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>AdvancedSceneMode</td>
<td class=c>no</td>
<td class=n>Model
<br>SceneMode
<br>AdvancedSceneType</td>
<td>--&gt; <a href='Panasonic.html#AdvancedSceneMode'>Panasonic AdvancedSceneMode Values</a></td></tr>
<tr class=b>
<td>Aperture</td>
<td class=c>no</td>
<td class=n>FNumber
<br>ApertureValue</td>
<td>&nbsp;</td></tr>
<tr>
<td>AudioBitrate</td>
<td class=c>no</td>
<td class=n>MPEG:MPEGAudioVersion
<br>MPEG:SampleRate
<br>MPEG:VBRBytes
<br>MPEG:VBRFrames</td>
<td><span class=s><span class=n>(calculated for variable-bitrate MPEG audio)</span></span></td></tr>
<tr class=b>
<td>AutoFocus</td>
<td class=c>no</td>
<td class=n>Nikon:FocusMode</td>
<td><span class=s>0 = Off
<br>1 = On</span></td></tr>
<tr>
<td>AvgBitrate</td>
<td class=c>no</td>
<td class=n>QuickTime::MediaDataSize
<br>QuickTime::Duration</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>BlueBalance</td>
<td class=c>no</td>
<td class=n>WB_RGGBLevels
<br>WB_RGBGLevels
<br>WB_RBGGLevels
<br>WB_GRBGLevels
<br>WB_GRGBLevels
<br>WB_GBRGLevels
<br>WB_RGBLevels
<br>WB_GRBLevels
<br>WB_RBLevels
<br>WBBlueLevel
<br>WBGreenLevel</td>
<td>&nbsp;</td></tr>
<tr>
<td>CDDBDiscPlayTime</td>
<td class=c>no</td>
<td class=n>CDDB1Info</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>CDDBDiscTracks</td>
<td class=c>no</td>
<td class=n>CDDB1Info</td>
<td>&nbsp;</td></tr>
<tr>
<td>CFAPattern</td>
<td class=c>no</td>
<td class=n>CFARepeatPatternDim
<br>CFAPattern2</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>CircleOfConfusion</td>
<td class=c>no</td>
<td class=n>ScaleFactor35efl</td>
<td><span class=s><span class=n>(calculated as D/1440, where D is the focal plane diagonal in mm. This value
may be incorrect if the image has been resized)</span></span></td></tr>
<tr>
<td>ConditionalFEC</td>
<td class=c>no</td>
<td class=n>FlashExposureComp
<br>FlashBits</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ContrastDetectAF</td>
<td class=c>no</td>
<td class=n>Nikon:FocusMode
<br>Nikon:AFDetectionMethod</td>
<td><span class=s>0 = Off
<br>1 = On</span></td></tr>
<tr>
<td>DOF</td>
<td class=c>no</td>
<td class=n>FocalLength
<br>Aperture
<br>CircleOfConfusion
<br>FocusDistance
<br>SubjectDistance
<br>ObjectDistance
<br>ApproximateFocusDistance
<br>FocusDistanceLower
<br>FocusDistanceUpper</td>
<td><span class=s><span class=n>(this value may be incorrect if the image has been resized)</span></span></td></tr>
<tr class=b>
<td>DateCreated</td>
<td class=c>no</td>
<td class=n>Kodak:YearCreated
<br>Kodak:MonthDayCreated</td>
<td>&nbsp;</td></tr>
<tr>
<td>DateTimeCreated</td>
<td class=c>no</td>
<td class=n>IPTC:DateCreated
<br>IPTC:TimeCreated</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>DateTimeOriginal</td>
<td class=c>no</td>
<td class=n>DateTimeCreated
<br>DateCreated
<br>TimeCreated</td>
<td>&nbsp;</td></tr>
<tr>
<td>DateTimeOriginal</td>
<td class=c>no</td>
<td class=n>ID3:RecordingTime
<br>ID3:Year
<br>ID3:Date
<br>ID3:Time</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>DepthMapTiff</td>
<td class=c>no</td>
<td class=n>DepthMapData
<br>DepthMapWidth
<br>DepthMapHeight</td>
<td>&nbsp;</td></tr>
<tr>
<td>DigitalCreationDateTime</td>
<td class=c>no</td>
<td class=n>IPTC:DigitalCreationDate
<br>IPTC:DigitalCreationTime</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>DigitalZoom</td>
<td class=c>no</td>
<td class=n>Canon:ZoomSourceWidth
<br>Canon:ZoomTargetWidth
<br>Canon:DigitalZoom</td>
<td>&nbsp;</td></tr>
<tr>
<td>DriveMode</td>
<td class=c>no</td>
<td class=n>ContinuousDrive
<br>SelfTimer</td>
<td><span class=s>0 = Continuous Shooting
<br>1 = Self-timer Operation
<br>2 = Single-frame Shooting</span></td></tr>
<tr class=b>
<td>Duration</td>
<td class=c>no</td>
<td class=n>AIFF:SampleRate
<br>AIFF:NumSampleFrames</td>
<td>&nbsp;</td></tr>
<tr>
<td>Duration</td>
<td class=c>no</td>
<td class=n>APE:SampleRate
<br>APE:TotalFrames
<br>APE:BlocksPerFrame
<br>APE:FinalFrameBlocks</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Duration</td>
<td class=c>no</td>
<td class=n>FLAC:SampleRate
<br>FLAC:TotalSamples</td>
<td>&nbsp;</td></tr>
<tr>
<td>Duration</td>
<td class=c>no</td>
<td class=n>FileSize
<br>ID3Size
<br>MPEG:AudioBitrate
<br>MPEG:VideoBitrate
<br>MPEG:VBRFrames
<br>MPEG:SampleRate
<br>MPEG:MPEGAudioVersion</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Duration</td>
<td class=c>no</td>
<td class=n>RIFF:FrameRate
<br>RIFF:FrameCount
<br>VideoFrameRate
<br>VideoFrameCount</td>
<td>&nbsp;</td></tr>
<tr>
<td>Duration</td>
<td class=c>no</td>
<td class=n>RIFF:AvgBytesPerSec
<br>FileSize
<br>FrameCount
<br>VideoFrameCount</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Duration</td>
<td class=c>no</td>
<td class=n>Vorbis:NominalBitrate
<br>FileSize</td>
<td>&nbsp;</td></tr>
<tr>
<td>ExtenderStatus</td>
<td class=c>no</td>
<td class=n>Olympus:Extender
<br>Olympus:LensType
<br>MaxApertureValue</td>
<td><span class=s><span class=n>(Olympus cameras have the quirk that they may retain the extender settings
after the extender is removed until the camera is powered off. This tag is
an attempt to represent the actual status of the extender.)</span>
<br>0 = Not attached
<br>1 = Attached
<br>2 = Removed</span></td></tr>
<tr class=b>
<td>FOV</td>
<td class=c>no</td>
<td class=n>FocalLength
<br>ScaleFactor35efl
<br>FocusDistance</td>
<td><span class=s><span class=n>(calculated for the long image dimension. This value may be incorrect for
fisheye lenses, or if the image has been resized)</span></span></td></tr>
<tr>
<td>FileNumber</td>
<td class=c>yes</td>
<td class=n>DirectoryIndex
<br>FileIndex</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Flash</td>
<td class=c>yes</td>
<td class=n>XMP:FlashFired
<br>XMP:FlashReturn
<br>XMP:FlashMode
<br>XMP:FlashFunction
<br>XMP:FlashRedEyeMode
<br>XMP:Flash</td>
<td>--&gt; <a href='EXIF.html#Flash'>EXIF Flash Values</a>
<br><span class='n s'>(facilitates copying camera flash information between XMP and EXIF)</span></td></tr>
<tr>
<td>FlashType</td>
<td class=c>no</td>
<td class=n>FlashBits</td>
<td><span class=s><span class=n>(may report &quot;Built-in Flash&quot; for some Canon cameras with external flash in
manual mode)</span>
<br>0 = Built-In Flash
<br>1 = External</span></td></tr>
<tr class=b>
<td>FocalLength35efl</td>
<td class=c>no</td>
<td class=n>FocalLength
<br>ScaleFactor35efl</td>
<td><span class=s><span class=n>(this value may be incorrect if the image has been resized)</span></span></td></tr>
<tr>
<td>FocusDistance</td>
<td class=c>no</td>
<td class=n>Sony:FocusPosition
<br>FocalLength</td>
<td><span class=s><span class=n>(distance in metres = FocusPosition * FocalLength / 1000)</span></span></td></tr>
<tr class=b>
<td>FocusDistance2</td>
<td class=c>no</td>
<td class=n>Sony:FocusPosition2
<br>FocalLengthIn35mmFormat</td>
<td>&nbsp;</td></tr>
<tr>
<td>GPSAltitude</td>
<td class=c>no</td>
<td class=n>GPS:GPSAltitude
<br>GPS:GPSAltitudeRef
<br>XMP:GPSAltitude
<br>XMP:GPSAltitudeRef</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSAltitude</td>
<td class=c>no</td>
<td class=n>QuickTime:GPSCoordinates</td>
<td>&nbsp;</td></tr>
<tr>
<td>GPSAltitude</td>
<td class=c>no</td>
<td class=n>QuickTime:LocationInformation</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSAltitudeRef</td>
<td class=c>no</td>
<td class=n>QuickTime:GPSCoordinates</td>
<td><span class=s>0 = Above Sea Level
<br>1 = Below Sea Level</span></td></tr>
<tr>
<td>GPSAltitudeRef</td>
<td class=c>no</td>
<td class=n>QuickTime:LocationInformation</td>
<td><span class=s>0 = Above Sea Level
<br>1 = Below Sea Level</span></td></tr>
<tr class=b>
<td>GPSDateTime</td>
<td class=c>no</td>
<td class=n>GPS:GPSDateStamp
<br>GPS:GPSTimeStamp</td>
<td>&nbsp;</td></tr>
<tr>
<td>GPSDateTime</td>
<td class=c>no</td>
<td class=n>Parrot:GPSLatitude
<br>Main:CreateDate
<br>SampleTime</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSDateTime</td>
<td class=c>no</td>
<td class=n>Sony:GPSDateStamp
<br>Sony:GPSTimeStamp</td>
<td>&nbsp;</td></tr>
<tr>
<td>GPSDestLatitude</td>
<td class=c>no</td>
<td class=n>GPS:GPSDestLatitude
<br>GPS:GPSDestLatitudeRef</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSDestLatitudeRef</td>
<td class=c>no</td>
<td class=n>XMP-exif:GPSDestLatitude</td>
<td><span class=s>&#39;N&#39; = North
<br>&#39;S&#39; = South</span></td></tr>
<tr>
<td>GPSDestLongitude</td>
<td class=c>no</td>
<td class=n>GPS:GPSDestLongitude
<br>GPS:GPSDestLongitudeRef</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSDestLongitudeRef</td>
<td class=c>no</td>
<td class=n>XMP-exif:GPSDestLongitude</td>
<td><span class=s>&#39;E&#39; = East
<br>&#39;W&#39; = West</span></td></tr>
<tr>
<td>GPSLatitude</td>
<td class=c title=' / = Avoid'>yes/</td>
<td class=n>GPS:GPSLatitude
<br>GPS:GPSLatitudeRef</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSLatitude</td>
<td class=c>no</td>
<td class=n>QuickTime:GPSCoordinates</td>
<td>&nbsp;</td></tr>
<tr>
<td>GPSLatitude</td>
<td class=c>no</td>
<td class=n>QuickTime:LocationInformation</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSLatitude</td>
<td class=c>no</td>
<td class=n>Sony:GPSLatitude
<br>Sony:GPSLatitudeRef</td>
<td>&nbsp;</td></tr>
<tr>
<td>GPSLatitudeRef</td>
<td class=c>no</td>
<td class=n>XMP-exif:GPSLatitude</td>
<td><span class=s>&#39;N&#39; = North
<br>&#39;S&#39; = South</span></td></tr>
<tr class=b>
<td>GPSLongitude</td>
<td class=c title=' / = Avoid'>yes/</td>
<td class=n>GPS:GPSLongitude
<br>GPS:GPSLongitudeRef</td>
<td>&nbsp;</td></tr>
<tr>
<td>GPSLongitude</td>
<td class=c>no</td>
<td class=n>QuickTime:GPSCoordinates</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSLongitude</td>
<td class=c>no</td>
<td class=n>QuickTime:LocationInformation</td>
<td>&nbsp;</td></tr>
<tr>
<td>GPSLongitude</td>
<td class=c>no</td>
<td class=n>Sony:GPSLongitude
<br>Sony:GPSLongitudeRef</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSLongitudeRef</td>
<td class=c>no</td>
<td class=n>XMP-exif:GPSLongitude</td>
<td><span class=s>&#39;E&#39; = East
<br>&#39;W&#39; = West</span></td></tr>
<tr>
<td>GPSPosition</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=n>GPSLatitude
<br>GPSLongitude</td>
<td><span class=s><span class=n>(when written, writes GPSLatitude, GPSLatitudeRef, GPSLongitude and
GPSLongitudeRef. This tag may be written using the same coordinate
format as provided by Google Maps when right-clicking on a location)</span></span></td></tr>
<tr class=b>
<td>HiddenData</td>
<td class=c>no</td>
<td class=n>Sony:HiddenDataOffset
<br>Sony:HiddenDataLength</td>
<td><span class=s><span class=n>(hidden data in some Sony JPG and ARW images, extracted only if specifically
requested)</span></span></td></tr>
<tr>
<td>HyperfocalDistance</td>
<td class=c>no</td>
<td class=n>FocalLength
<br>Aperture
<br>CircleOfConfusion</td>
<td><span class=s><span class=n>(this value may be incorrect if the image has been resized)</span></span></td></tr>
<tr class=b>
<td>IDCPreviewImage</td>
<td class=c>no</td>
<td class=n>IDCPreviewStart
<br>IDCPreviewLength</td>
<td>&nbsp;</td></tr>
<tr>
<td>ISO</td>
<td class=c>no</td>
<td class=n>Canon:CameraISO
<br>Canon:BaseISO
<br>Canon:AutoISO</td>
<td><span class=s><span class=n>(use CameraISO if numerical, otherwise calculate as BaseISO * AutoISO / 100)</span></span></td></tr>
<tr class=b>
<td>ImageHeight</td>
<td class=c>no</td>
<td class=n>IFD0:SensorTopBorder
<br>IFD0:SensorBottomBorder</td>
<td>&nbsp;</td></tr>
<tr>
<td>ImageHeight</td>
<td class=c>no</td>
<td class=n>Main:PostScript:ImageData
<br>PostScript:BoundingBox</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ImageSize</td>
<td class=c>no</td>
<td class=n>ImageWidth
<br>ImageHeight
<br>ExifImageWidth
<br>ExifImageHeight
<br>RawImageCroppedSize</td>
<td>&nbsp;</td></tr>
<tr>
<td>ImageWidth</td>
<td class=c>no</td>
<td class=n>IFD0:SensorLeftBorder
<br>IFD0:SensorRightBorder</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ImageWidth</td>
<td class=c>no</td>
<td class=n>Main:PostScript:ImageData
<br>PostScript:BoundingBox</td>
<td>&nbsp;</td></tr>
<tr>
<td>JpgFromRaw</td>
<td class=c>yes</td>
<td class=n>JpgFromRawStart
<br>JpgFromRawLength</td>
<td><span class=s><span class=n>(this tag is writable, and may be used to update existing embedded images,
but not create or delete them)</span></span></td></tr>
<tr class=b>
<td>Lens</td>
<td class=c>no</td>
<td class=n>Canon:MinFocalLength
<br>Canon:MaxFocalLength</td>
<td>&nbsp;</td></tr>
<tr>
<td>Lens35efl</td>
<td class=c>no</td>
<td class=n>Canon:MinFocalLength
<br>Canon:MaxFocalLength
<br>Lens
<br>ScaleFactor35efl</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>LensID</td>
<td class=c>no</td>
<td class=n>LensType
<br>FocalLength
<br>MaxAperture
<br>MaxApertureValue
<br>MinFocalLength
<br>MaxFocalLength
<br>LensModel
<br>LensFocalRange
<br>LensSpec
<br>LensType2
<br>LensType3
<br>LensFocalLength
<br>RFLensType</td>
<td><span class=s><span class=n>(attempt to identify the actual lens from all lenses with a given LensType.
Applies only to LensType values with a lookup table. May be configured
by adding user-defined lenses)</span></span></td></tr>
<tr>
<td>LensID</td>
<td class=c>no</td>
<td class=n>LensModel
<br>Lens
<br>XMP-aux:LensID
<br>Make</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>LensID</td>
<td class=c>no</td>
<td class=n>Nikon:LensIDNumber
<br>LensFStops
<br>MinFocalLength
<br>MaxFocalLength
<br>MaxApertureAtMinFocal
<br>MaxApertureAtMaxFocal
<br>MCUVersion
<br>Nikon:LensType</td>
<td>--&gt; <a href='Nikon.html#LensID'>Nikon LensID Values</a></td></tr>
<tr>
<td>LensID</td>
<td class=c>no</td>
<td class=n>Ricoh:LensFirmware</td>
<td>--&gt; <a href='Ricoh.html#LensID'>Ricoh LensID Values</a></td></tr>
<tr class=b>
<td>LensID</td>
<td class=c>no</td>
<td class=n>XMP-aux:LensID
<br>Make
<br>LensInfo
<br>FocalLength
<br>LensModel
<br>MaxApertureValue</td>
<td><span class=s><span class=n>(attempt to convert numerical XMP-aux:LensID stored by Adobe applications)</span></span></td></tr>
<tr>
<td>LensSpec</td>
<td class=c>no</td>
<td class=n>Nikon:Lens
<br>Nikon:LensType</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>LensType</td>
<td class=c>no</td>
<td class=n>LensTypeMake
<br>LensTypeModel</td>
<td>--&gt; <a href='Olympus.html#LensType'>Olympus LensType Values</a>
<br><span class='n s'>(based on tags found in some Panasonic RW2 images)</span></td></tr>
<tr>
<td>LightValue</td>
<td class=c>no</td>
<td class=n>Aperture
<br>ShutterSpeed
<br>ISO</td>
<td><span class=s><span class=n>(calculated LV = 2 * log2(Aperture) - log2(ShutterSpeed) - log2(ISO/100);
similar to exposure value but normalized to ISO 100)</span></span></td></tr>
<tr class=b>
<td>MPImage</td>
<td class=c>no</td>
<td class=n>MPImageStart
<br>MPImageLength
<br>MPImageType</td>
<td><span class=s><span class=n>(the first MPF &quot;Large Thumbnail&quot; is extracted as PreviewImage, and the rest
of the embedded MPF images are extracted as MPImage#. The <a href="../ExifTool.html#ExtractEmbedded">ExtractEmbedded</a>
option may be used to extract information from these embedded images.)</span></span></td></tr>
<tr>
<td>Megapixels</td>
<td class=c>no</td>
<td class=n>ImageSize</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>OriginalDecisionData</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=n>OriginalDecisionDataOffset</td>
<td>&nbsp;</td></tr>
<tr>
<td>OtherImage</td>
<td class=c>yes</td>
<td class=n>OtherImageStart
<br>OtherImageLength
<br>OtherImageStart (1)
<br>OtherImageLength (1)</td>
<td><span class=s><span class=n>(this tag is writable, and may be used to update existing embedded images,
but not create or delete them)</span></span></td></tr>
<tr class=b>
<td>PeakSpectralSensitivity</td>
<td class=c>no</td>
<td class=n>FLIR:PlanckB</td>
<td>&nbsp;</td></tr>
<tr>
<td>PhaseDetectAF</td>
<td class=c>no</td>
<td class=n>Nikon:FocusPointSchema
<br>Nikon:AFDetectionMethod</td>
<td><table class=cols><tr>
<td>0 = Off
<br>1 = On (51-point)
<br>2 = On (11-point)</td><td>&nbsp;&nbsp;</td>
<td>3 = On (39-point)
<br>7 = On (153-point)
<br>9 = On (105-point)</td></tr></table>
</td></tr>
<tr class=b>
<td>PreviewImage</td>
<td class=c>yes</td>
<td class=n>PreviewImageStart
<br>PreviewImageLength
<br>PreviewImageValid
<br>PreviewImageStart (1)
<br>PreviewImageLength (1)</td>
<td><span class=s><span class=n>(this tag is writable, and may be used to update existing embedded images,
but not create or delete them)</span></span></td></tr>
<tr>
<td>PreviewImage</td>
<td class=c>no</td>
<td class=n>ScreenNail</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>PreviewImageSize</td>
<td class=c>no</td>
<td class=n>PreviewImageWidth
<br>PreviewImageHeight</td>
<td>&nbsp;</td></tr>
<tr>
<td>PreviewJXL</td>
<td class=c>no</td>
<td class=n>PreviewJXLStart
<br>PreviewJXLLength
<br>PreviewJXLStart (1)
<br>PreviewJXLLength (1)</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>RedBalance</td>
<td class=c>no</td>
<td class=n>WB_RGGBLevels
<br>WB_RGBGLevels
<br>WB_RBGGLevels
<br>WB_GRBGLevels
<br>WB_GRGBLevels
<br>WB_GBRGLevels
<br>WB_RGBLevels
<br>WB_GRBLevels
<br>WB_RBLevels
<br>WBRedLevel
<br>WBGreenLevel</td>
<td>&nbsp;</td></tr>
<tr>
<td>RedEyeReduction</td>
<td class=c>no</td>
<td class=n>CanonFlashMode
<br>FlashBits</td>
<td><span class=s>0 = Off
<br>1 = On</span></td></tr>
<tr class=b>
<td>RicohPitch</td>
<td class=c>no</td>
<td class=n>Ricoh:Accelerometer</td>
<td>&nbsp;</td></tr>
<tr>
<td>RicohRoll</td>
<td class=c>no</td>
<td class=n>Ricoh:Accelerometer</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Rotation</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=n>QuickTime:MatrixStructure
<br>QuickTime:HandlerType</td>
<td><span class=s><span class=n>(degrees of clockwise camera rotation. Writing this tag updates QuickTime
MatrixStructure for all tracks with a non-zero image size)</span></span></td></tr>
<tr>
<td>RunTimeSincePowerUp</td>
<td class=c>no</td>
<td class=n>Apple:RunTimeValue
<br>Apple:RunTimeScale</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ScaleFactor35efl</td>
<td class=c>no</td>
<td class=n>FocalLength
<br>FocalLengthIn35mmFormat
<br>Composite:DigitalZoom
<br>FocalPlaneDiagonal
<br>SensorSize
<br>FocalPlaneXSize
<br>FocalPlaneYSize
<br>FocalPlaneResolutionUnit
<br>FocalPlaneXResolution
<br>FocalPlaneYResolution
<br>ExifImageWidth
<br>ExifImageHeight
<br>CanonImageWidth
<br>CanonImageHeight
<br>ImageWidth
<br>ImageHeight</td>
<td><span class=s><span class=n>(this value and any derived values may be incorrect if the image has been
resized)</span></span></td></tr>
<tr>
<td>ShootingMode</td>
<td class=c>no</td>
<td class=n>CanonExposureMode
<br>EasyMode
<br>BulbDuration</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ShutterCurtainHack</td>
<td class=c>no</td>
<td class=n>FlashBits
<br>ShutterCurtainSync</td>
<td><span class=s>0 = 1st-curtain sync
<br>1 = 2nd-curtain sync</span></td></tr>
<tr>
<td>ShutterSpeed</td>
<td class=c>no</td>
<td class=n>ExposureTime
<br>ShutterSpeedValue
<br>BulbDuration</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>SingleShotDepthMapTiff</td>
<td class=c>no</td>
<td class=n>SingleShotDepthMap
<br>SegWidth
<br>SegHeight</td>
<td>&nbsp;</td></tr>
<tr>
<td>SubSecCreateDate</td>
<td class=c>yes</td>
<td class=n>EXIF:CreateDate
<br>EXIF:SubSecTimeDigitized
<br>EXIF:OffsetTimeDigitized</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>SubSecDateTimeOriginal</td>
<td class=c>yes</td>
<td class=n>EXIF:DateTimeOriginal
<br>EXIF:SubSecTimeOriginal
<br>EXIF:OffsetTimeOriginal</td>
<td>&nbsp;</td></tr>
<tr>
<td>SubSecModifyDate</td>
<td class=c>yes</td>
<td class=n>EXIF:ModifyDate
<br>EXIF:SubSecTime
<br>EXIF:OffsetTime</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ThumbnailImage</td>
<td class=c>yes</td>
<td class=n>ThumbnailOffset
<br>ThumbnailLength</td>
<td><span class=s><span class=n>(this tag is writable, and may be used to update existing thumbnails, but may
only create a thumbnail in IFD1 of certain types of files. Note that for
this and other Composite embedded-image tags the family 0 and 1 groups match
those of the originating tags)</span></span></td></tr>
<tr>
<td>ThumbnailTIFF</td>
<td class=c>no</td>
<td class=n>SubfileType
<br>Compression
<br>ImageWidth
<br>ImageHeight
<br>BitsPerSample
<br>PhotometricInterpretation
<br>StripOffsets
<br>SamplesPerPixel
<br>RowsPerStrip
<br>StripByteCounts
<br>PlanarConfiguration
<br>Orientation</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>VolumeSize</td>
<td class=c>no</td>
<td class=n>ISO:VolumeBlockCount
<br>ISO:VolumeBlockSize</td>
<td>&nbsp;</td></tr>
<tr>
<td>WB_RGBLevels</td>
<td class=c>no</td>
<td class=n>KDC_IFD:WhiteBalance
<br>WB_RGBLevelsAuto
<br>WB_RGBLevelsFluorescent
<br>WB_RGBLevelsTungsten
<br>WB_RGBLevelsDaylight
<br>WB_RGBLevels4
<br>WB_RGBLevels5
<br>WB_RGBLevelsShade</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>WB_RGBLevels</td>
<td class=c>no</td>
<td class=n>KodakIFD:WhiteBalance
<br>WB_RGBMul0
<br>WB_RGBMul1
<br>WB_RGBMul2
<br>WB_RGBMul3
<br>WB_RGBCoeffs0
<br>WB_RGBCoeffs1
<br>WB_RGBCoeffs2
<br>WB_RGBCoeffs3
<br>KodakIFD:ColorTemperature
<br>Kodak:WB_RGBLevels</td>
<td>&nbsp;</td></tr>
<tr>
<td>WB_RGGBLevels</td>
<td class=c>no</td>
<td class=n>Canon:WhiteBalance
<br>WB_RGGBLevelsAsShot
<br>WB_RGGBLevelsAuto
<br>WB_RGGBLevelsDaylight
<br>WB_RGGBLevelsCloudy
<br>WB_RGGBLevelsTungsten
<br>WB_RGGBLevelsFluorescent
<br>WB_RGGBLevelsFlash
<br>WB_RGGBLevelsCustom
<br>WB_RGGBLevelsShade
<br>WB_RGGBLevelsKelvin</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>WB_RGGBLevels</td>
<td class=c>no</td>
<td class=n>WB_RGGBLevelsUncorrected
<br>WB_RGGBLevelsBlack</td>
<td>&nbsp;</td></tr>
<tr>
<td>ZoomedPreviewImage</td>
<td class=c>no</td>
<td class=n>ZoomedPreviewStart
<br>ZoomedPreviewLength</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised May 21, 2026</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+382
View File
@@ -0,0 +1,382 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>DNG Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>DNG Tags</h2>
<p>
The main DNG tags are found in the EXIF table. The tables below define only
information found within structures of these main DNG tag values. See
<a href="https://helpx.adobe.com/camera-raw/digital-negative.html">https://helpx.adobe.com/camera-raw/digital-negative.html</a> for the official
DNG specification.
</p>
<h2><a name='AdobeData'>DNG AdobeData Tags</a></h2>
<p>This information is found in the &quot;Adobe&quot; DNGPrivateData.</p>
<p>The maker notes (&#39;MakN&#39;) are processed by ExifTool, but some information may
have been lost by the Adobe DNG Converter. This is because the Adobe DNG
Converter (as of version 6.3) doesn&#39;t properly handle information referenced
from inside the maker notes that lies outside the original maker notes
block. This information is lost when only the maker note block is copied to
the DNG image. While this doesn&#39;t effect all makes of cameras, it is a
problem for some major brands such as Olympus and Sony.</p>
<p>Other entries in this table represent proprietary information that is
extracted from the original RAW image and restructured to a different (but
still proprietary) Adobe format.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'CRW '</td>
<td>AdobeCRW</td>
<td class=c>-</td>
<td>--&gt; <a href='CanonRaw.html'>CanonRaw Tags</a></td></tr>
<tr class=b>
<td>'Koda'</td>
<td>AdobeKoda</td>
<td class=c>-</td>
<td>--&gt; <a href='Kodak.html#IFD'>Kodak IFD Tags</a></td></tr>
<tr>
<td>'Leaf'</td>
<td>AdobeLeaf</td>
<td class=c>-</td>
<td>--&gt; <a href='Leaf.html#SubIFD'>Leaf SubIFD Tags</a></td></tr>
<tr class=b>
<td>'MRW '</td>
<td>AdobeMRW</td>
<td class=c>-</td>
<td>--&gt; <a href='MinoltaRaw.html'>MinoltaRaw Tags</a></td></tr>
<tr>
<td>'MakN'</td>
<td>MakerNoteApple
<br>MakerNoteNikon
<br>MakerNoteCanon
<br>MakerNoteCasio
<br>MakerNoteCasio2
<br>MakerNoteDJIInfo
<br>MakerNoteDJI
<br>MakerNoteFLIR
<br>MakerNoteFujiFilm
<br>MakerNoteGE
<br>MakerNoteGE2
<br>MakerNoteGoogle
<br>MakerNoteHasselblad
<br>MakerNoteHP
<br>MakerNoteHP2
<br>MakerNoteHP4
<br>MakerNoteHP6
<br>MakerNoteISL
<br>MakerNoteJVC
<br>MakerNoteJVCText
<br>MakerNoteKodak1a
<br>MakerNoteKodak1b
<br>MakerNoteKodak2
<br>MakerNoteKodak3
<br>MakerNoteKodak4
<br>MakerNoteKodak5
<br>MakerNoteKodak6a
<br>MakerNoteKodak6b
<br>MakerNoteKodak7
<br>MakerNoteKodak8a
<br>MakerNoteKodak8b
<br>MakerNoteKodak8c
<br>MakerNoteKodak9
<br>MakerNoteKodak10
<br>MakerNoteKodak11
<br>MakerNoteKodak12
<br>MakerNoteKodakUnknown
<br>MakerNoteKyocera
<br>MakerNoteMinolta
<br>MakerNoteMinolta2
<br>MakerNoteMinolta3
<br>MakerNoteMotorola
<br>MakerNoteNikon2
<br>MakerNoteNikon3
<br>MakerNoteNintendo
<br>MakerNoteOlympus
<br>MakerNoteOlympus2
<br>MakerNoteOlympus3
<br>MakerNoteLeica
<br>MakerNoteLeica2
<br>MakerNoteLeica3
<br>MakerNoteLeica4
<br>MakerNoteLeica5
<br>MakerNoteLeica6
<br>MakerNoteLeica7
<br>MakerNoteLeica8
<br>MakerNoteLeica9
<br>MakerNoteLeica10
<br>MakerNotePanasonic
<br>MakerNotePanasonic2
<br>MakerNotePanasonic3
<br>MakerNotePentax
<br>MakerNotePentax2
<br>MakerNotePentax3
<br>MakerNotePentax4
<br>MakerNotePentax5
<br>MakerNotePentax6
<br>MakerNotePhaseOne
<br>MakerNoteReconyxHyperFire
<br>MakerNoteReconyxUltraFire
<br>MakerNoteReconyxHyperFire2
<br>MakerNoteReconyxMicroFire
<br>MakerNoteReconyxHyperFire4K
<br>MakerNoteRicohPentax
<br>MakerNoteRicoh
<br>MakerNoteRicoh2
<br>MakerNoteRicohText
<br>MakerNoteSamsung1a
<br>MakerNoteSamsung1b
<br>MakerNoteSamsung2
<br>MakerNoteSanyo
<br>MakerNoteSanyoC4
<br>MakerNoteSanyoPatch
<br>MakerNoteSigma
<br>MakerNoteSony
<br>MakerNoteSony2
<br>MakerNoteSony3
<br>MakerNoteSony4
<br>MakerNoteSony5
<br>MakerNoteSonyEricsson
<br>MakerNoteSonySRF
<br>MakerNoteUnknownText
<br>MakerNoteUnknownBinary
<br>MakerNoteUnknown</td>
<td class=c>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef<br>undef</td>
<td>--&gt; <a href='Apple.html'>Apple Tags</a>
<br>--&gt; <a href='Nikon.html'>Nikon Tags</a>
<br>--&gt; <a href='Canon.html'>Canon Tags</a>
<br>--&gt; <a href='Casio.html'>Casio Tags</a>
<br>--&gt; <a href='Casio.html#Type2'>Casio Type2 Tags</a>
<br>--&gt; <a href='DJI.html#Info'>DJI Info Tags</a>
<br>--&gt; <a href='DJI.html'>DJI Tags</a>
<br>--&gt; <a href='FLIR.html'>FLIR Tags</a>
<br>--&gt; <a href='FujiFilm.html'>FujiFilm Tags</a>
<br>--&gt; <a href='GE.html'>GE Tags</a>
<br>--&gt; <a href='FujiFilm.html'>FujiFilm Tags</a>
<br>--&gt; <a href='Google.html#HDRPlusMakerNote'>Google HDRPlusMakerNote Tags</a>
<br>--&gt; <a href='Unknown.html'>Unknown Tags</a>
<br>--&gt; <a href='HP.html'>HP Tags</a>
<br>--&gt; <a href='HP.html#Type2'>HP Type2 Tags</a>
<br>--&gt; <a href='HP.html#Type4'>HP Type4 Tags</a>
<br>--&gt; <a href='HP.html#Type6'>HP Type6 Tags</a>
<br>--&gt; <a href='Unknown.html'>Unknown Tags</a>
<br>--&gt; <a href='JVC.html'>JVC Tags</a>
<br>--&gt; <a href='JVC.html#Text'>JVC Text Tags</a>
<br>--&gt; <a href='Kodak.html'>Kodak Tags</a>
<br>--&gt; <a href='Kodak.html'>Kodak Tags</a>
<br>--&gt; <a href='Kodak.html#Type2'>Kodak Type2 Tags</a>
<br>--&gt; <a href='Kodak.html#Type3'>Kodak Type3 Tags</a>
<br>--&gt; <a href='Kodak.html#Type4'>Kodak Type4 Tags</a>
<br>--&gt; <a href='Kodak.html#Type5'>Kodak Type5 Tags</a>
<br>--&gt; <a href='Kodak.html#Type6'>Kodak Type6 Tags</a>
<br>--&gt; <a href='Kodak.html#Type6'>Kodak Type6 Tags</a>
<br>--&gt; <a href='Kodak.html#Type7'>Kodak Type7 Tags</a>
<br>--&gt; <a href='Kodak.html#Type8'>Kodak Type8 Tags</a>
<br>--&gt; <a href='Kodak.html#Type8'>Kodak Type8 Tags</a>
<br>--&gt; <a href='Kodak.html#Type8'>Kodak Type8 Tags</a>
<br>--&gt; <a href='Kodak.html#Type9'>Kodak Type9 Tags</a>
<br>--&gt; <a href='Kodak.html#Type10'>Kodak Type10 Tags</a>
<br>--&gt; <a href='Kodak.html#Type11'>Kodak Type11 Tags</a>
<br>--&gt; <a href='Kodak.html#Type11'>Kodak Type11 Tags</a>
<br>--&gt; <a href='Kodak.html#Unknown'>Kodak Unknown Tags</a>
<br>--&gt; <a href='Unknown.html'>Unknown Tags</a>
<br>--&gt; <a href='Minolta.html'>Minolta Tags</a>
<br>--&gt; <a href='Olympus.html'>Olympus Tags</a>
<br><span class=n>(not EXIF-based)</span>
<br>--&gt; <a href='Motorola.html'>Motorola Tags</a>
<br>--&gt; <a href='Nikon.html#Type2'>Nikon Type2 Tags</a>
<br>--&gt; <a href='Nikon.html'>Nikon Tags</a>
<br>--&gt; <a href='Nintendo.html'>Nintendo Tags</a>
<br>--&gt; <a href='Olympus.html'>Olympus Tags</a>
<br>--&gt; <a href='Olympus.html'>Olympus Tags</a>
<br>--&gt; <a href='Olympus.html'>Olympus Tags</a>
<br>--&gt; <a href='Panasonic.html'>Panasonic Tags</a>
<br>--&gt; <a href='Panasonic.html#Leica2'>Panasonic Leica2 Tags</a>
<br>--&gt; <a href='Panasonic.html#Leica3'>Panasonic Leica3 Tags</a>
<br>--&gt; <a href='Panasonic.html#Leica4'>Panasonic Leica4 Tags</a>
<br>--&gt; <a href='Panasonic.html#Leica5'>Panasonic Leica5 Tags</a>
<br>--&gt; <a href='Panasonic.html#Leica6'>Panasonic Leica6 Tags</a>
<br>--&gt; <a href='Panasonic.html#Leica6'>Panasonic Leica6 Tags</a>
<br>--&gt; <a href='Panasonic.html#Leica5'>Panasonic Leica5 Tags</a>
<br>--&gt; <a href='Panasonic.html#Leica9'>Panasonic Leica9 Tags</a>
<br>--&gt; <a href='Panasonic.html'>Panasonic Tags</a>
<br>--&gt; <a href='Panasonic.html'>Panasonic Tags</a>
<br>--&gt; <a href='Panasonic.html#Type2'>Panasonic Type2 Tags</a>
<br>--&gt; <a href='Panasonic.html'>Panasonic Tags</a>
<br>--&gt; <a href='Pentax.html'>Pentax Tags</a>
<br>--&gt; <a href='Pentax.html#Type2'>Pentax Type2 Tags</a>
<br>--&gt; <a href='Casio.html#Type2'>Casio Type2 Tags</a>
<br>--&gt; <a href='Pentax.html#Type4'>Pentax Type4 Tags</a>
<br>--&gt; <a href='Pentax.html'>Pentax Tags</a>
<br>--&gt; <a href='Pentax.html#S1'>Pentax S1 Tags</a>
<br>--&gt; <a href='PhaseOne.html'>PhaseOne Tags</a>
<br>--&gt; <a href='Reconyx.html#HyperFire'>Reconyx HyperFire Tags</a>
<br>--&gt; <a href='Reconyx.html#UltraFire'>Reconyx UltraFire Tags</a>
<br>--&gt; <a href='Reconyx.html#HyperFire2'>Reconyx HyperFire2 Tags</a>
<br>--&gt; <a href='Reconyx.html#MicroFire'>Reconyx MicroFire Tags</a>
<br>--&gt; <a href='Reconyx.html#HyperFire4K'>Reconyx HyperFire4K Tags</a>
<br>--&gt; <a href='Pentax.html'>Pentax Tags</a>
<br>--&gt; <a href='Ricoh.html'>Ricoh Tags</a>
<br>--&gt; <a href='Ricoh.html#Type2'>Ricoh Type2 Tags</a>
<br>--&gt; <a href='Ricoh.html#Text'>Ricoh Text Tags</a>
<br><span class=n>(Samsung &quot;STMN&quot; maker notes without PreviewImage)</span>
<br>--&gt; <a href='Samsung.html'>Samsung Tags</a>
<br>--&gt; <a href='Samsung.html#Type2'>Samsung Type2 Tags</a>
<br>--&gt; <a href='Sanyo.html'>Sanyo Tags</a>
<br>--&gt; <a href='Sanyo.html'>Sanyo Tags</a>
<br>--&gt; <a href='Sanyo.html'>Sanyo Tags</a>
<br>--&gt; <a href='Sigma.html'>Sigma Tags</a>
<br>--&gt; <a href='Sony.html'>Sony Tags</a>
<br>--&gt; <a href='Olympus.html'>Olympus Tags</a>
<br>--&gt; <a href='Olympus.html'>Olympus Tags</a>
<br>--&gt; <a href='Sony.html#PIC'>Sony PIC Tags</a>
<br>--&gt; <a href='Sony.html'>Sony Tags</a>
<br>--&gt; <a href='Sony.html#Ericsson'>Sony Ericsson Tags</a>
<br>--&gt; <a href='Sony.html#SRF'>Sony SRF Tags</a>
<br><span class=n>(unknown text-based maker notes)</span>
<br><span class=n>(unknown binary maker notes)</span>
<br>--&gt; <a href='Unknown.html'>Unknown Tags</a></td></tr>
<tr class=b>
<td>'Pano'</td>
<td>AdobePano</td>
<td class=c>-</td>
<td>--&gt; <a href='PanasonicRaw.html'>PanasonicRaw Tags</a></td></tr>
<tr>
<td>'RAF '</td>
<td>AdobeRAF</td>
<td class=c>-</td>
<td>--&gt; <a href='FujiFilm.html#RAF'>FujiFilm RAF Tags</a></td></tr>
<tr class=b>
<td>'SR2 '</td>
<td>AdobeSR2</td>
<td class=c>-</td>
<td>--&gt; <a href='Sony.html#SR2Private'>Sony SR2Private Tags</a></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='OriginalRaw'>DNG OriginalRaw Tags</a></h2>
<p>This table defines tags extracted from the DNG OriginalRawFileData
information.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0000 = 0'>0x0000</td>
<td>OriginalRawImage</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0001 = 1'>0x0001</td>
<td>OriginalRawResource</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0002 = 2'>0x0002</td>
<td>OriginalRawFileType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0003 = 3'>0x0003</td>
<td>OriginalRawCreator</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0004 = 4'>0x0004</td>
<td>OriginalTHMImage</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0005 = 5'>0x0005</td>
<td>OriginalTHMResource</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0006 = 6'>0x0006</td>
<td>OriginalTHMFileType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0007 = 7'>0x0007</td>
<td>OriginalTHMCreator</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='ImageSeq'>DNG ImageSeq Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>SeqID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>SeqType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>SeqFrameInfo</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>SeqIndex</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='7 = 0x7'>7</td>
<td>SeqCount</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='11 = 0xb'>11</td>
<td>SeqFinal</td>
<td class=c>no</td>
<td><span class=s>0 = No
<br>1 = Yes</span></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='ProfileDynamicRange'>DNG ProfileDynamicRange Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>PDRVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='2 = 0x2'>2</td>
<td>DynamicRange</td>
<td class=c>no</td>
<td><span class=s>0 = Standard
<br>1 = High</span></td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>HintMaxOutputValue</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Sep 21, 2025</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+300
View File
@@ -0,0 +1,300 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>DPX Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>DPX Tags</h2>
<p>Tags extracted from DPX (Digital Picture Exchange) images.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>ByteOrder</td>
<td class=c>no</td>
<td><span class=s>&#39;SDPX&#39; = Big-endian
<br>&#39;XPDS&#39; = Little-endian</span></td></tr>
<tr class=b>
<td class=r title='8 = 0x8'>8</td>
<td>HeaderVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='16 = 0x10'>16</td>
<td>DPXFileSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='20 = 0x14'>20</td>
<td>DittoKey</td>
<td class=c>no</td>
<td><span class=s>0 = Same
<br>1 = New</span></td></tr>
<tr>
<td class=r title='36 = 0x24'>36</td>
<td>ImageFileName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='136 = 0x88'>136</td>
<td>CreateDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='160 = 0xa0'>160</td>
<td>Creator</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='260 = 0x104'>260</td>
<td>Project</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='460 = 0x1cc'>460</td>
<td>Copyright</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='660 = 0x294'>660</td>
<td>EncryptionKey</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='768 = 0x300'>768</td>
<td>Orientation</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = Horizontal (normal)
<br>1 = Mirror vertical
<br>2 = Mirror horizontal
<br>3 = Rotate 180
<br>4 = Mirror horizontal and rotate 270 CW
<br>5 = Rotate 90 CW
<br>6 = Rotate 270 CW
<br>7 = Mirror horizontal and rotate 90 CW</td></tr></table>
</td></tr>
<tr class=b>
<td class=r title='770 = 0x302'>770</td>
<td>ImageElements</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='772 = 0x304'>772</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='776 = 0x308'>776</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='780 = 0x30c'>780</td>
<td>DataSign</td>
<td class=c>no</td>
<td><span class=s>0 = Unsigned
<br>1 = Signed</span></td></tr>
<tr class=b>
<td class=r title='800 = 0x320'>800</td>
<td>ComponentsConfiguration</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = User-defined single component
<br>1 = Red (R)
<br>2 = Green (G)
<br>3 = Blue (B)
<br>4 = Alpha (matte)
<br>6 = Luminance (Y)
<br>7 = Chrominance (Cb, Cr, subsampled by two)
<br>8 = Depth (Z)
<br>9 = Composite video
<br>50 = R, G, B
<br>51 = R, G, B, Alpha
<br>52 = Alpha, B, G, R
<br>100 = Cb, Y, Cr, Y (4:2:2)
<br>101 = Cb, Y, A, Cr, Y, A (4:2:2:4)
<br>102 = Cb, Y, Cr (4:4:4)
<br>103 = Cb, Y, Cr, A (4:4:4:4)
<br>150 = User-defined 2 component element
<br>151 = User-defined 3 component element
<br>152 = User-defined 4 component element
<br>153 = User-defined 5 component element
<br>154 = User-defined 6 component element
<br>155 = User-defined 7 component element
<br>156 = User-defined 8 component element</td></tr></table>
</td></tr>
<tr>
<td class=r title='801 = 0x321'>801</td>
<td>TransferCharacteristic</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = User-defined
<br>1 = Printing density
<br>2 = Linear
<br>3 = Logarithmic
<br>4 = Unspecified video
<br>5 = SMPTE 274M
<br>6 = ITU-R 709-4
<br>7 = ITU-R 601-5 system B or G (625)
<br>8 = ITU-R 601-5 system M (525)
<br>9 = Composite video (NTSC)
<br>10 = Composite video (PAL)
<br>11 = Z (depth) - linear
<br>12 = Z (depth) - homogeneous
<br>13 = SMPTE ADX
<br>14 = ITU-R 2020 NCL
<br>15 = ITU-R 2020 CL
<br>16 = IEC 61966-2-4 xvYCC
<br>17 = ITU-R 2100 NCL/PQ
<br>18 = ITU-R 2100 ICtCp/PQ
<br>19 = ITU-R 2100 NCL/HLG
<br>20 = ITU-R 2100 ICtCp/HLG
<br>21 = RP 431-2:2011 Gama 2.6
<br>22 = IEC 61966-2-1 sRGB</td></tr></table>
</td></tr>
<tr class=b>
<td class=r title='802 = 0x322'>802</td>
<td>ColorimetricSpecification</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = User-defined
<br>1 = Printing density
<br>4 = Unspecified video
<br>5 = SMPTE 274M
<br>6 = ITU-R 709-4
<br>7 = ITU-R 601-5 system B or G (625)
<br>8 = ITU-R 601-5 system M (525)
<br>9 = Composite video (NTSC)
<br>10 = Composite video (PAL)
<br>13 = SMPTE ADX
<br>14 = ITU-R 2020
<br>15 = P3D65
<br>16 = P3DCI
<br>17 = P3D60
<br>18 = ACES</td></tr></table>
</td></tr>
<tr>
<td class=r title='803 = 0x323'>803</td>
<td>BitDepth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='820 = 0x334'>820</td>
<td>ImageDescription</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='892 = 0x37c'>892</td>
<td>Image2Description</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='964 = 0x3c4'>964</td>
<td>Image3Description</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='1036 = 0x40c'>1036</td>
<td>Image4Description</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1108 = 0x454'>1108</td>
<td>Image5Description</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='1180 = 0x49c'>1180</td>
<td>Image6Description</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1252 = 0x4e4'>1252</td>
<td>Image7Description</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='1324 = 0x52c'>1324</td>
<td>Image8Description</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1432 = 0x598'>1432</td>
<td>SourceFileName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='1532 = 0x5fc'>1532</td>
<td>SourceCreateDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1556 = 0x614'>1556</td>
<td>InputDeviceName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='1588 = 0x634'>1588</td>
<td>InputDeviceSerialNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1628 = 0x65c'>1628</td>
<td>AspectRatio</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='1724 = 0x6bc'>1724</td>
<td>OriginalFrameRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1728 = 0x6c0'>1728</td>
<td>ShutterAngle</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='1732 = 0x6c4'>1732</td>
<td>FrameID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1764 = 0x6e4'>1764</td>
<td>SlateInformation</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='1920 = 0x780'>1920</td>
<td>TimeCode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1940 = 0x794'>1940</td>
<td>FrameRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='1972 = 0x7b4'>1972</td>
<td>Reserved5?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='2048 = 0x800'>2048</td>
<td>UserID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised May 21, 2024</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+73
View File
@@ -0,0 +1,73 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>DSF Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>DSF Tags</h2>
<p>Tags read from the &#39;fmt &#39; header of a DSF (DSD Stream File) audio files. As
well, ID3 metadata may also exist in these files. See
<a href="https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf">https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf</a>
for the specification.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='3 = 0x3'>3</td>
<td>FormatVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4</td>
<td>FormatID</td>
<td class=c>no</td>
<td><span class=s>0 = DSD Raw</span></td></tr>
<tr>
<td class=r title='5 = 0x5'>5</td>
<td>ChannelType</td>
<td class=c>no</td>
<td><span class=s>1 = Mono
<br>2 = Stereo (Left, Right)
<br>3 = 3 Channels (Left, Right, Center)
<br>4 = Quad (Left, Right, Back L, Back R)
<br>5 = 4 Channels (Left, Right, Center, Bass)
<br>6 = 5 Channels (Left, Right, Center, Back L, Back R)
<br>7 = 5.1 Channels (Left, Right, Center, Bass, Back L, Back R)</span></td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>ChannelCount</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='7 = 0x7'>7</td>
<td>SampleRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='8 = 0x8'>8</td>
<td>BitsPerSample</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='9 = 0x9'>9</td>
<td>SampleCount</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='11 = 0xb'>11</td>
<td>BlockSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Sep 25, 2025</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+76
View File
@@ -0,0 +1,76 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>DV Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>DV Tags</h2>
<p>The following tags are extracted from DV videos.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>AspectRatio</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>AudioBitsPerSample</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>AudioChannels</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>AudioSampleRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>Colorimetry</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>DateTimeOriginal</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>Duration</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>FrameRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>TotalBitrate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>VideoFormat</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>VideoScanType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Jan 3, 2011</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff
+314
View File
@@ -0,0 +1,314 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>DjVu Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>DjVu Tags</h2>
<p>Information is extracted from the following chunks in DjVu images. See
<a href="http://www.djvu.org/">http://www.djvu.org/</a> for the DjVu specification.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'ANTa'</td>
<td>ANTa</td>
<td class=c>-</td>
<td>--&gt; <a href='DjVu.html#Ant'>DjVu Ant Tags</a></td></tr>
<tr class=b>
<td>'ANTz'</td>
<td>CompressedAnnotation</td>
<td class=c>-</td>
<td>--&gt; <a href='DjVu.html#Ant'>DjVu Ant Tags</a></td></tr>
<tr>
<td>'FORM'</td>
<td>FORM</td>
<td class=c>-</td>
<td>--&gt; <a href='DjVu.html#Form'>DjVu Form Tags</a></td></tr>
<tr class=b>
<td>'INCL'</td>
<td>IncludedFileID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'INFO'</td>
<td>INFO</td>
<td class=c>-</td>
<td>--&gt; <a href='DjVu.html#Info'>DjVu Info Tags</a></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Ant'>DjVu Ant Tags</a></h2>
<p>Information extracted from annotation chunks.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'metadata'</td>
<td>Metadata</td>
<td class=c>-</td>
<td>--&gt; <a href='DjVu.html#Meta'>DjVu Meta Tags</a></td></tr>
<tr class=b>
<td>'xmp'</td>
<td>XMP</td>
<td class=c>-</td>
<td>--&gt; <a href='XMP.html'>XMP Tags</a></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Meta'>DjVu Meta Tags</a></h2>
<p>This table lists the standard DjVu metadata tags, but ExifTool will extract
any tags that exist even if they don&#39;t appear here. The DjVu v3
documentation endorses tags borrowed from two standards: 1) BibTeX
bibliography system tags (all lowercase Tag ID&#39;s in the table below), and 2)
PDF DocInfo tags (capitalized Tag ID&#39;s).</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'Author'</td>
<td>Author</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'CreationDate'</td>
<td>CreateDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Creator'</td>
<td>Creator</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Keywords'</td>
<td>Keywords</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ModDate'</td>
<td>ModifyDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Producer'</td>
<td>Producer</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Subject'</td>
<td>Subject</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Title'</td>
<td>Title</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Trapped'</td>
<td>Trapped</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'address'</td>
<td>Address</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'annote'</td>
<td>Annotation</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'author'</td>
<td>Author</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'booktitle'</td>
<td>BookTitle</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'chapter'</td>
<td>Chapter</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'crossref'</td>
<td>CrossRef</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'edition'</td>
<td>Edition</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'eprint'</td>
<td>EPrint</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'howpublished'</td>
<td>HowPublished</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'institution'</td>
<td>Institution</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'journal'</td>
<td>Journal</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'key'</td>
<td>Key</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'month'</td>
<td>Month</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'note'</td>
<td>Note</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'number'</td>
<td>Number</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'organization'</td>
<td>Organization</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'pages'</td>
<td>Pages</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'publisher'</td>
<td>Publisher</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'school'</td>
<td>School</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'series'</td>
<td>Series</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'title'</td>
<td>Title</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'type'</td>
<td>Type</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'url'</td>
<td>URL</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'volume'</td>
<td>Volume</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'year'</td>
<td>Year</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Form'>DjVu Form Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>SubfileType</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>&#39;BM44&#39; = Grayscale IW44
<br>&#39;DJVI&#39; = Shared component
<br>&#39;DJVM&#39; = Multi-page document
<br>&#39;DJVU&#39; = Single-page image
<br>&#39;PM44&#39; = Color IW44
<br>&#39;THUM&#39; = Thumbnail image</td></tr></table>
</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Info'>DjVu Info Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='2 = 0x2'>2</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>DjVuVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>SpatialResolution</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='8 = 0x8'>8</td>
<td>Gamma</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='9 = 0x9'>9</td>
<td>Orientation</td>
<td class=c>no</td>
<td><span class=s>[val &amp; 0x7]
<br>1 = Horizontal (normal)
<br>2 = Rotate 180
<br>5 = Rotate 90 CW
<br>6 = Rotate 270 CW</span></td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Oct 24, 2018</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+894
View File
@@ -0,0 +1,894 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>EXE Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>EXE Tags</h2>
<p>This module extracts information from various types of Windows, MacOS and
Unix executable and library files. The first table below lists information
extracted from the header of Windows PE (Portable Executable) EXE files and
DLL libraries.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index2</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>MachineType</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0x0 = Unknown
<br>0x1 = Target host
<br>0x14c = Intel 386 or later, and compatibles
<br>0x14d = Intel i860
<br>0x162 = MIPS R3000
<br>0x166 = MIPS little endian (R4000)
<br>0x168 = MIPS R10000
<br>0x169 = MIPS little endian WCI v2
<br>0x183 = Alpha AXP (old)
<br>0x184 = Alpha AXP
<br>0x1a2 = Hitachi SH3
<br>0x1a3 = Hitachi SH3 DSP
<br>0x1a4 = Hitachi SH3E
<br>0x1a6 = Hitachi SH4
<br>0x1a8 = Hitachi SH5
<br>0x1c0 = ARM little endian
<br>0x1c2 = Thumb
<br>0x1c4 = Thumb 2 little endian
<br>0x1d3 = Matsushita AM33
<br>0x1f0 = PowerPC little endian
<br>0x1f1 = PowerPC with floating point support
<br>0x200 = Intel IA64
<br>0x266 = MIPS16
<br>0x268 = Motorola 68000 series
<br>0x284 = Alpha AXP 64-bit
<br>0x366 = MIPS with FPU
<br>0x466 = MIPS16 with FPU
<br>0x520 = Infineon Tricore
<br>0xcef = CEF
<br>0xebc = EFI Byte Code
<br>0x3a64 = Compiled Hybrid PE
<br>0x5032 = RISC-V 32-bit
<br>0x5064 = RISC-V 64-bit
<br>0x5128 = RISC-V 128-bit
<br>0x6232 = LoongArch 32-bit
<br>0x6264 = LoongArch 64-bit
<br>0x8664 = AMD AMD64
<br>0x9041 = Mitsubishi M32R little endian
<br>0xaa64 = ARM64 little endian
<br>0xc0ee = clr pure MSIL
<br>0xec20 = Dotnet 0xEC20</td></tr></table>
</td></tr>
<tr class=b>
<td class=r title='2 = 0x2'>2</td>
<td>TimeStamp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='9 = 0x9'>9</td>
<td>ImageFileCharacteristics</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>Bit 0 = No relocs
<br>Bit 1 = Executable
<br>Bit 2 = No line numbers
<br>Bit 3 = No symbols
<br>Bit 4 = Aggressive working-set trim
<br>Bit 5 = Large address aware
<br>Bit 7 = Bytes reversed lo
<br>Bit 8 = 32-bit
<br>Bit 9 = No debug
<br>Bit 10 = Removable run from swap
<br>Bit 11 = Net run from swap
<br>Bit 12 = System file
<br>Bit 13 = DLL
<br>Bit 14 = Uniprocessor only
<br>Bit 15 = Bytes reversed hi</td></tr></table>
</td></tr>
<tr class=b>
<td class=r title='10 = 0xa'>10</td>
<td>PEType</td>
<td class=c>no</td>
<td><span class=s>0x107 = ROM Image
<br>0x10b = PE32
<br>0x20b = PE32+</span></td></tr>
<tr>
<td class=r title='11 = 0xb'>11</td>
<td>LinkerVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='12 = 0xc'>12</td>
<td>CodeSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='14 = 0xe'>14</td>
<td>InitializedDataSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='16 = 0x10'>16</td>
<td>UninitializedDataSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='18 = 0x12'>18</td>
<td>EntryPoint</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='30 = 0x1e'>30</td>
<td>OSVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='32 = 0x20'>32</td>
<td>ImageVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='34 = 0x22'>34</td>
<td>SubsystemVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='44 = 0x2c'>44</td>
<td>Subsystem</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = Unknown
<br>1 = Native
<br>2 = Windows GUI
<br>3 = Windows command line
<br>5 = OS/2 command line
<br>7 = POSIX command line
<br>9 = Windows CE GUI
<br>10 = EFI application
<br>11 = EFI boot service
<br>12 = EFI runtime driver
<br>13 = EFI ROM
<br>14 = XBOX</td></tr></table>
</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='PEVersion'>EXE PEVersion Tags</a></h2>
<p>Information extracted from the VS_VERSION_INFO structure of Windows PE
files.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>FileVersionNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4</td>
<td>ProductVersionNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='6 = 0x6'>6</td>
<td>FileFlagsMask</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='7 = 0x7'>7</td>
<td>FileFlags</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>Bit 0 = Debug
<br>Bit 1 = Pre-release
<br>Bit 2 = Patched</td><td>&nbsp;&nbsp;</td>
<td>Bit 3 = Private build
<br>Bit 4 = Info inferred
<br>Bit 5 = Special build</td></tr></table>
</td></tr>
<tr>
<td class=r title='8 = 0x8'>8</td>
<td>FileOS</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0x1 = Win16
<br>0x2 = PM-16
<br>0x3 = PM-32
<br>0x4 = Win32
<br>0x10000 = DOS
<br>0x10001 = Windows 16-bit
<br>0x10004 = Windows 32-bit
<br>0x20000 = OS/2 16-bit
<br>0x20002 = OS/2 16-bit PM-16
<br>0x30000 = OS/2 32-bit
<br>0x30003 = OS/2 32-bit PM-32
<br>0x40000 = Windows NT
<br>0x40004 = Windows NT 32-bit</td></tr></table>
</td></tr>
<tr class=b>
<td class=r title='9 = 0x9'>9</td>
<td>ObjectFileType</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = Unknown
<br>1 = Executable application
<br>2 = Dynamic link library
<br>3 = Driver
<br>4 = Font
<br>5 = VxD
<br>7 = Static library</td></tr></table>
</td></tr>
<tr>
<td class=r title='10 = 0xa'>10</td>
<td>FileSubtype</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='PEString'>EXE PEString Tags</a></h2>
<p>Resource strings found in Windows PE files. The <b>TagID</b>&#39;s are not shown
because they are the same as the <b>Tag Name</b>. ExifTool will extract any
existing StringFileInfo tags even if not listed in this table.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>BuildDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>BuildVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>CharacterSet</td>
<td class=c>no</td>
<td><span class=s><span class=n>(extracted from the StringFileInfo value)</span></span><table class=cols><tr>
<td>&#39;0000&#39; = ASCII
<br>&#39;03A4&#39; = Windows, Japan (Shift - JIS X-0208)
<br>&#39;03A8&#39; = Windows, Chinese (Simplified)
<br>&#39;03B5&#39; = Windows, Korea (Shift - KSC 5601)
<br>&#39;03B6&#39; = Windows, Taiwan (Big5)
<br>&#39;04B0&#39; = Unicode
<br>&#39;04E2&#39; = Windows, Latin2 (Eastern European)
<br>&#39;04E3&#39; = Windows, Cyrillic
<br>&#39;04E4&#39; = Windows, Latin1
<br>&#39;04E5&#39; = Windows, Greek
<br>&#39;04E6&#39; = Windows, Turkish
<br>&#39;04E7&#39; = Windows, Hebrew
<br>&#39;04E8&#39; = Windows, Arabic</td></tr></table>
</td></tr>
<tr class=b>
<td>Comments</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>CompanyName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Copyright</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>FileDescription</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>FileVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>InternalName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>LanguageCode</td>
<td class=c>no</td>
<td>--&gt; <a href='EXE.html#LanguageCode'>EXE LanguageCode Values</a>
<br><span class='n s'>(Windows code page; extracted from the StringFileInfo value)</span></td></tr>
<tr>
<td>LegalCopyright</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>LegalTrademarks</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>OriginalFileName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>PrivateBuild</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>ProductName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ProductVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>SpecialBuild</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='LanguageCode'>EXE LanguageCode Values</a></h2>
<p>See <a href="https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid">https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid</a>
for the full list of Microsoft language codes.</p>
<blockquote>
<table class=frame><tr><td>
<table class='inner sep' cellspacing=1>
<tr class=h><th>Value</th><th>LanguageCode</th><th>Value</th><th>LanguageCode</th><th>Value</th><th>LanguageCode</th></tr>
<tr><td>'0000'</td><td>= Neutral</td>
<td class=b>'0437'</td><td class=b>= Georgian</td>
<td>'040E'</td><td>= Hungarian</td>
</tr><tr><td>'0400'</td><td>= Process default</td>
<td class=b>'0438'</td><td class=b>= Faeroese</td>
<td>'040F'</td><td>= Icelandic</td>
</tr><tr><td>'0401'</td><td>= Arabic</td>
<td class=b>'0439'</td><td class=b>= Hindi</td>
<td>'041A'</td><td>= Croato-Serbian (Latin)</td>
</tr><tr><td>'0402'</td><td>= Bulgarian</td>
<td class=b>'0440'</td><td class=b>= Kyrgyz</td>
<td>'041B'</td><td>= Slovak</td>
</tr><tr><td>'0403'</td><td>= Catalan</td>
<td class=b>'0441'</td><td class=b>= Swahili</td>
<td>'041C'</td><td>= Albanian</td>
</tr><tr><td>'0404'</td><td>= Chinese (Traditional)</td>
<td class=b>'0443'</td><td class=b>= Uzbek</td>
<td>'041D'</td><td>= Swedish</td>
</tr><tr><td>'0405'</td><td>= Czech</td>
<td class=b>'0444'</td><td class=b>= Tatar</td>
<td>'041E'</td><td>= Thai</td>
</tr><tr><td>'0406'</td><td>= Danish</td>
<td class=b>'0445'</td><td class=b>= Bengali</td>
<td>'041F'</td><td>= Turkish</td>
</tr><tr><td>'0407'</td><td>= German</td>
<td class=b>'0446'</td><td class=b>= Punjabi</td>
<td>'042a'</td><td>= Vietnamese</td>
</tr><tr><td>'0408'</td><td>= Greek</td>
<td class=b>'0447'</td><td class=b>= Gujarati</td>
<td>'042b'</td><td>= Armenian</td>
</tr><tr><td>'0409'</td><td>= English (U.S.)</td>
<td class=b>'0448'</td><td class=b>= Oriya</td>
<td>'042c'</td><td>= Azeri</td>
</tr><tr><td>'0410'</td><td>= Italian</td>
<td class=b>'0449'</td><td class=b>= Tamil</td>
<td>'042d'</td><td>= Basque</td>
</tr><tr><td>'0411'</td><td>= Japanese</td>
<td class=b>'0450'</td><td class=b>= Mongolian</td>
<td>'042e'</td><td>= Sorbian</td>
</tr><tr><td>'0412'</td><td>= Korean</td>
<td class=b>'0456'</td><td class=b>= Galician</td>
<td>'042f'</td><td>= Macedonian</td>
</tr><tr><td>'0413'</td><td>= Dutch</td>
<td class=b>'0457'</td><td class=b>= Konkani</td>
<td>'043a'</td><td>= Maltese</td>
</tr><tr><td>'0414'</td><td>= Norwegian (Bokml)</td>
<td class=b>'0458'</td><td class=b>= Manipuri</td>
<td>'043b'</td><td>= Saami</td>
</tr><tr><td>'0415'</td><td>= Polish</td>
<td class=b>'0459'</td><td class=b>= Sindhi</td>
<td>'043c'</td><td>= Gaelic</td>
</tr><tr><td>'0416'</td><td>= Portuguese (Brazilian)</td>
<td class=b>'0460'</td><td class=b>= Kashmiri</td>
<td>'043e'</td><td>= Malay</td>
</tr><tr><td>'0417'</td><td>= Rhaeto-Romanic</td>
<td class=b>'0461'</td><td class=b>= Nepali</td>
<td>'043f'</td><td>= Kazak</td>
</tr><tr><td>'0418'</td><td>= Romanian</td>
<td class=b>'0465'</td><td class=b>= Divehi</td>
<td>'044a'</td><td>= Telugu</td>
</tr><tr><td>'0419'</td><td>= Russian</td>
<td class=b>'0490'</td><td class=b>= Walon</td>
<td>'044b'</td><td>= Kannada</td>
</tr><tr><td>'0420'</td><td>= Urdu</td>
<td class=b>'0491'</td><td class=b>= Cornish</td>
<td>'044c'</td><td>= Malayalam</td>
</tr><tr><td>'0421'</td><td>= Indonesian</td>
<td class=b>'0492'</td><td class=b>= Welsh</td>
<td>'044d'</td><td>= Assamese</td>
</tr><tr><td>'0422'</td><td>= Ukrainian</td>
<td class=b>'0493'</td><td class=b>= Breton</td>
<td>'044e'</td><td>= Marathi</td>
</tr><tr><td>'0423'</td><td>= Belarusian</td>
<td class=b>'0800'</td><td class=b>= Neutral 2</td>
<td>'044f'</td><td>= Sanskrit</td>
</tr><tr><td>'0424'</td><td>= Slovenian</td>
<td class=b>'0804'</td><td class=b>= Chinese (Simplified)</td>
<td>'045a'</td><td>= Syriac</td>
</tr><tr><td>'0425'</td><td>= Estonian</td>
<td class=b>'0807'</td><td class=b>= German (Swiss)</td>
<td>'047f'</td><td>= Invariant</td>
</tr><tr><td>'0426'</td><td>= Latvian</td>
<td class=b>'0809'</td><td class=b>= English (British)</td>
<td>'048f'</td><td>= Esperanto</td>
</tr><tr><td>'0427'</td><td>= Lithuanian</td>
<td class=b>'0810'</td><td class=b>= Italian (Swiss)</td>
<td>'080A'</td><td>= Spanish (Mexican)</td>
</tr><tr><td>'0428'</td><td>= Maori</td>
<td class=b>'0813'</td><td class=b>= Dutch (Belgian)</td>
<td>'080C'</td><td>= French (Belgian)</td>
</tr><tr><td>'0429'</td><td>= Farsi</td>
<td class=b>'0814'</td><td class=b>= Norwegian (Nynorsk)</td>
<td>'081A'</td><td>= Serbo-Croatian (Cyrillic)</td>
</tr><tr><td>'0430'</td><td>= Sutu</td>
<td class=b>'0816'</td><td class=b>= Portuguese</td>
<td>'0C07'</td><td>= German (Austrian)</td>
</tr><tr><td>'0431'</td><td>= Tsonga</td>
<td class=b>'1009'</td><td class=b>= English (Canadian)</td>
<td>'0C09'</td><td>= English (Australian)</td>
</tr><tr><td>'0432'</td><td>= Tswana</td>
<td class=b>'007F'</td><td class=b>= Invariant</td>
<td>'0C0A'</td><td>= Spanish (Modern)</td>
</tr><tr><td>'0433'</td><td>= Venda</td>
<td class=b>'040A'</td><td class=b>= Spanish (Castilian)</td>
<td>'0C0C'</td><td>= French (Canadian)</td>
</tr><tr><td>'0434'</td><td>= Xhosa</td>
<td class=b>'040B'</td><td class=b>= Finnish</td>
<td>'100C'</td><td>= French (Swiss)</td>
</tr><tr><td>'0435'</td><td>= Zulu</td>
<td class=b>'040C'</td><td class=b>= French</td>
<td>&nbsp;</td><td>&nbsp;</td>
</tr><tr><td>'0436'</td><td>= Afrikaans</td>
<td class=b>'040D'</td><td class=b>= Hebrew</td>
<td>&nbsp;</td><td>&nbsp;</td>
</tr></table></td></tr></table></blockquote>
<h2><a name='DebugRSDS'>EXE DebugRSDS Tags</a></h2>
<p>CodeView RSDS debug information found in some Windows EXE files.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>PDBModifyDate</td>
<td class=c>no</td>
<td><span class=s><span class=n>(Taken from debug directory entry pointing to RSDS record.)</span></span></td></tr>
<tr class=b>
<td class=r title='20 = 0x14'>20</td>
<td>PDBAge</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='24 = 0x18'>24</td>
<td>PDBFileName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='DebugNB10'>EXE DebugNB10 Tags</a></h2>
<p>CodeView NB10 debug information found in some Windows EXE files.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>PDBModifyDate</td>
<td class=c>no</td>
<td><span class=s><span class=n>(Taken from debug directory entry pointing to NB10 record.)</span></span></td></tr>
<tr class=b>
<td class=r title='8 = 0x8'>8</td>
<td>PDBCreateDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='12 = 0xc'>12</td>
<td>PDBAge</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='16 = 0x10'>16</td>
<td>PDBFileName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Misc'>EXE Misc Tags</a></h2>
<p>Miscellaneous CodeView debug information in Windows EXE files.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='12 = 0xc'>12</td>
<td>EXEFileName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='MachO'>EXE MachO Tags</a></h2>
<p>Information extracted from Mach-O (Mac OS X) executable files and DYLIB
libraries.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>CPUArchitecture</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>CPUByteOrder</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>CPUCount</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>CPUType</td>
<td class=c title=' + = List'>no+</td>
<td><table class=cols><tr>
<td>-1 = Any
<br>1 = VAX
<br>2 = ROMP
<br>4 = NS32032
<br>5 = NS32332
<br>6 = MC680x0
<br>7 = x86
<br>8 = MIPS
<br>9 = NS32532
<br>10 = MC98000</td><td>&nbsp;&nbsp;</td>
<td>11 = HPPA
<br>12 = ARM
<br>13 = MC88000
<br>14 = SPARC
<br>15 = i860 big endian
<br>16 = i860 little endian
<br>17 = RS6000
<br>18 = PowerPC
<br>255 = VEO</td></tr></table>
</td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>CPUSubtype</td>
<td class=c title=' + = List'>no+</td>
<td><table class=cols><tr>
<td>&#39;1 0&#39; = VAX (all)
<br>&#39;1 1&#39; = VAX780
<br>&#39;1 2&#39; = VAX785
<br>&#39;1 3&#39; = VAX750
<br>&#39;1 4&#39; = VAX730
<br>&#39;1 5&#39; = UVAXI
<br>&#39;1 6&#39; = UVAXII
<br>&#39;1 7&#39; = VAX8200
<br>&#39;1 8&#39; = VAX8500
<br>&#39;1 9&#39; = VAX8600
<br>&#39;1 10&#39; = VAX8650
<br>&#39;1 11&#39; = VAX8800
<br>&#39;1 12&#39; = UVAXIII
<br>&#39;2 0&#39; = RT (all)
<br>&#39;2 1&#39; = RT PC
<br>&#39;2 2&#39; = RT APC
<br>&#39;2 3&#39; = RT 135
<br>&#39;4 0&#39; = NS32032 (all)
<br>&#39;4 1&#39; = NS32032 DPC (032 CPU)
<br>&#39;4 2&#39; = NS32032 SQT
<br>&#39;4 3&#39; = NS32032 APC FPU (32081)
<br>&#39;4 4&#39; = NS32032 APC FPA (Weitek)
<br>&#39;4 5&#39; = NS32032 XPC (532)
<br>&#39;5 0&#39; = NS32332 (all)
<br>&#39;5 1&#39; = NS32332 DPC (032 CPU)
<br>&#39;5 2&#39; = NS32332 SQT
<br>&#39;5 3&#39; = NS32332 APC FPU (32081)
<br>&#39;5 4&#39; = NS32332 APC FPA (Weitek)
<br>&#39;5 5&#39; = NS32332 XPC (532)
<br>&#39;6 1&#39; = MC680x0 (all)
<br>&#39;6 2&#39; = MC68040
<br>&#39;6 3&#39; = MC68030
<br>&#39;7 3&#39; = i386 (all)
<br>&#39;7 4&#39; = i486
<br>&#39;7 5&#39; = i586
<br>&#39;7 8&#39; = Pentium III
<br>&#39;7 9&#39; = Pentium M
<br>&#39;7 10&#39; = Pentium 4
<br>&#39;7 11&#39; = Itanium
<br>&#39;7 12&#39; = Xeon
<br>&#39;7 22&#39; = Pentium Pro
<br>&#39;7 24&#39; = Pentium III M
<br>&#39;7 26&#39; = Pentium 4 M
<br>&#39;7 27&#39; = Itanium 2
<br>&#39;7 28&#39; = Xeon MP
<br>&#39;7 40&#39; = Pentium III Xeon
<br>&#39;7 54&#39; = Pentium II M3
<br>&#39;7 86&#39; = Pentium II M5
<br>&#39;7 103&#39; = Celeron
<br>&#39;7 119&#39; = Celeron Mobile
<br>&#39;7 132&#39; = i486SX
<br>&#39;8 0&#39; = MIPS (all)
<br>&#39;8 1&#39; = MIPS R2300
<br>&#39;8 2&#39; = MIPS R2600
<br>&#39;8 3&#39; = MIPS R2800
<br>&#39;8 4&#39; = MIPS R2000a
<br>&#39;8 5&#39; = MIPS R2000
<br>&#39;8 6&#39; = MIPS R3000a
<br>&#39;8 7&#39; = MIPS R3000
<br>&#39;10 0&#39; = MC98000 (all)
<br>&#39;10 1&#39; = MC98601
<br>&#39;11 0&#39; = HPPA (all)
<br>&#39;11 1&#39; = HPPA 7100LC
<br>&#39;12 0&#39; = ARM (all)
<br>&#39;12 1&#39; = ARM A500 ARCH
<br>&#39;12 2&#39; = ARM A500
<br>&#39;12 3&#39; = ARM A440
<br>&#39;12 4&#39; = ARM M4
<br>&#39;12 5&#39; = ARM A680/V4T
<br>&#39;12 6&#39; = ARM V6
<br>&#39;12 7&#39; = ARM V5TEJ
<br>&#39;12 8&#39; = ARM XSCALE
<br>&#39;12 9&#39; = ARM V7
<br>&#39;13 0&#39; = MC88000 (all)
<br>&#39;13 1&#39; = MC88100
<br>&#39;13 2&#39; = MC88110
<br>&#39;14 0&#39; = SPARC (all)
<br>&#39;14 1&#39; = SUN 4/260
<br>&#39;14 2&#39; = SUN 4/110
<br>&#39;15 0&#39; = i860 (all)
<br>&#39;15 1&#39; = i860 860
<br>&#39;16 0&#39; = i860 little (all)
<br>&#39;16 1&#39; = i860 little
<br>&#39;17 0&#39; = RS6000 (all)
<br>&#39;17 1&#39; = RS6000
<br>&#39;18 0&#39; = PowerPC (all)
<br>&#39;18 1&#39; = PowerPC 601
<br>&#39;18 2&#39; = PowerPC 602
<br>&#39;18 3&#39; = PowerPC 603
<br>&#39;18 4&#39; = PowerPC 603e
<br>&#39;18 5&#39; = PowerPC 603ev
<br>&#39;18 6&#39; = PowerPC 604
<br>&#39;18 7&#39; = PowerPC 604e
<br>&#39;18 8&#39; = PowerPC 620
<br>&#39;18 9&#39; = PowerPC 750
<br>&#39;18 10&#39; = PowerPC 7400
<br>&#39;18 11&#39; = PowerPC 7450
<br>&#39;18 100&#39; = PowerPC 970
<br>&#39;255 1&#39; = VEO 1
<br>&#39;255 2&#39; = VEO 2</td></tr></table>
</td></tr>
<tr class=b>
<td class=r title='5 = 0x5'>5</td>
<td>ObjectFileType</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>-1 = Static library
<br>0x1 = Relocatable object
<br>0x2 = Demand paged executable
<br>0x3 = Fixed VM shared library
<br>0x4 = Core
<br>0x5 = Preloaded executable
<br>0x6 = Dynamically bound shared library
<br>0x7 = Dynamic link editor
<br>0x8 = Dynamically bound bundle
<br>0x9 = Shared library stub for static linking
<br>0xa = Debug information
<br>0xb = x86_64 kexts</td></tr></table>
</td></tr>
<tr>
<td class=r title='6 = 0x6'>6</td>
<td>ObjectFlags</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>Bit 0 = No undefs
<br>Bit 1 = Incrementa link
<br>Bit 2 = Dyld link
<br>Bit 3 = Bind at load
<br>Bit 4 = Prebound
<br>Bit 5 = Split segs
<br>Bit 6 = Lazy init
<br>Bit 7 = Two level
<br>Bit 8 = Force flat
<br>Bit 9 = No multi defs
<br>Bit 10 = No fix prebinding
<br>Bit 11 = Prebindable
<br>Bit 12 = All mods bound
<br>Bit 13 = Subsections via symbols
<br>Bit 14 = Canonical
<br>Bit 15 = Weak defines
<br>Bit 16 = Binds to weak
<br>Bit 17 = Allow stack execution
<br>Bit 18 = Dead strippable dylib
<br>Bit 19 = Root safe
<br>Bit 20 = No reexported dylibs
<br>Bit 21 = Random address</td></tr></table>
</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='PEF'>EXE PEF Tags</a></h2>
<p>Information extracted from PEF (Classic MacOS) executable files and
libraries.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>CPUArchitecture</td>
<td class=c>no</td>
<td><span class=s>&#39;m68k&#39; = 68000
<br>&#39;pwpc&#39; = PowerPC</span></td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>PEFVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>TimeStamp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='ELF'>EXE ELF Tags</a></h2>
<p>Information extracted from ELF (Unix) executable files and SO libraries.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>CPUArchitecture</td>
<td class=c>no</td>
<td><span class=s>1 = 32 bit
<br>2 = 64 bit</span></td></tr>
<tr class=b>
<td class=r title='5 = 0x5'>5</td>
<td>CPUByteOrder</td>
<td class=c>no</td>
<td><span class=s>1 = Little endian
<br>2 = Big endian</span></td></tr>
<tr>
<td class=r title='16 = 0x10'>16</td>
<td>ObjectFileType</td>
<td class=c>no</td>
<td><span class=s>0 = None
<br>1 = Relocatable file
<br>2 = Executable file
<br>3 = Shared object file
<br>4 = Core file</span></td></tr>
<tr class=b>
<td class=r title='18 = 0x12'>18</td>
<td>CPUType</td>
<td class=c>no</td>
<td><span class=s>0 = None
<br>1 = AT&amp;T WE 32100
<br>2 = SPARC
<br>3 = i386
<br>4 = Motorola 68000
<br>5 = Motorola 88000
<br>6 = i486
<br>7 = i860
<br>8 = MIPS R3000
<br>9 = IBM System/370
<br>10 = MIPS R4000
<br>15 = HP PA-RISC
<br>18 = Sun v8plus
<br>19 = Intel 80960
<br>20 = PowerPC
<br>21 = PowerPC 64-bit
<br>22 = IBM S/390
<br>23 = Cell BE SPU
<br>36 = NEC V800
<br>37 = Fujitsu FR20
<br>38 = TRW RH-32
<br>39 = Motorola RCE
<br>40 = Arm (up to Armv7/AArch32)
<br>41 = Digital Alpha
<br>42 = SuperH
<br>43 = SPARC v9 64-bit
<br>44 = Siemens TriCore
<br>45 = Argonaut RISC Core
<br>46 = Renesas H8/300,300H,H8S
<br>47 = Hitachi H8/300H
<br>48 = Hitachi H8S
<br>49 = Hitachi H8/500
<br>50 = HP/Intel IA-64
<br>51 = Stanford MIPS-X
<br>52 = Motorola ColdFire
<br>53 = Motorola M68HC12
<br>54 = Fujitsu MMA Multimedia Accelerator
<br>55 = Siemens PCP
<br>56 = Sony nCPU embedded RISC processor
<br>57 = Denso NDR1 microprocessor
<br>58 = Motorola Star*Core processor
<br>59 = Toyota ME16 processor
<br>60 = STMicroelectronics ST100 processor
<br>61 = Advanced Logic Corp. TinyJ embedded processor family
<br>62 = AMD x86-64
<br>63 = Sony DSP Processor
<br>64 = Digital Equipment Corp. PDP-10
<br>65 = Digital Equipment Corp. PDP-11
<br>66 = Siemens FX66 microcontroller
<br>67 = STMicroelectronics ST9+ 8/16 bit microcontroller
<br>68 = STMicroelectronics ST7 8-bit microcontroller
<br>69 = Motorola MC68HC16 Microcontroller
<br>70 = Motorola MC68HC11 Microcontroller
<br>71 = Motorola MC68HC08 Microcontroller
<br>72 = Motorola MC68HC05 Microcontroller
<br>73 = Silicon Graphics SVx
<br>74 = STMicroelectronics ST19 8-bit microcontroller
<br>75 = Digital VAX
<br>76 = Axis Communications 32-bit embedded processor
<br>77 = Infineon Technologies 32-bit embedded processor
<br>78 = Element 14 64-bit DSP Processor
<br>79 = LSI Logic 16-bit DSP Processor
<br>87 = NEC v850
<br>88 = Renesas M32R
<br>140 = TMS320C6000 Family
<br>175 = MCST Elbrus e2k
<br>183 = Arm 64-bits (Armv8/AArch64)
<br>220 = Zilog Z80
<br>243 = RISC-V
<br>247 = Berkeley Packet Filter
<br>257 = WDC 65C816
<br>21569 = Fujitsu FR-V
<br>36902 = Alpha
<br>36929 = m32r (old)
<br>36992 = v850 (old)
<br>41872 = S/390 (old)</span></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='AR'>EXE AR Tags</a></h2>
<p>Information extracted from static libraries.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='16 = 0x10'>16</td>
<td>CreateDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='CHM'>EXE CHM Tags</a></h2>
<p>Tags extracted from Microsoft Compiled HTML files.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='1 = 0x1'>1</td>
<td>CHMVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='5 = 0x5'>5</td>
<td>LanguageCode</td>
<td class=c>no</td>
<td>--&gt; <a href='EXE.html#LanguageCode'>EXE LanguageCode Values</a></td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Jan 25, 2025</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff
+687
View File
@@ -0,0 +1,687 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>Extra Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>Extra Tags</h2>
<p>
The extra tags provide extra features or extra information extracted or
generated by ExifTool that is not directly associated with another tag
group. The <b>Group</b> column lists the family 1 group name when reading.
Tags with a &quot;-&quot; in this column are write-only.</p>
<p>Tags in the family 1 &quot;System&quot; group are referred to as &quot;pseudo&quot; tags because
they don&#39;t represent real metadata in the file. Instead, this information
is stored in the directory structure of the filesystem. The <b>Writable</b>
System &quot;pseudo&quot; tags in this table may be written without modifying the file
itself. The TestName tag is used for dry-run testing before writing
FileName.
</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag Name</th>
<th>Writable</th><th>Group</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>Adobe</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>Adobe</td>
<td><span class=s><span class=n>(the JPEG APP14 Adobe segment. Extracted only if specified. See the
<a href="JPEG.html#Adobe">JPEG Adobe Tags</a> for more information)</span></span></td></tr>
<tr class=b>
<td>BaseName</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(file name without extension. Not generated unless specifically requested or
the API <a href="../ExifTool.html#RequestAll">RequestAll</a> option is set)</span></span></td></tr>
<tr>
<td>CanonDR4</td>
<td class=c title=' ! = Unsafe
^ = Deletable'>yes!^</td>
<td class=c>CanonVRD</td>
<td><span class=s><span class=n>(the full Canon DPP version 4 DR4 block. This tag is generated only if
specifically requested)</span></span></td></tr>
<tr class=b>
<td>CanonVRD</td>
<td class=c title=' ! = Unsafe
^ = Deletable'>yes!^</td>
<td class=c>CanonVRD</td>
<td><span class=s><span class=n>(the full Canon DPP VRD trailer block. This tag is generated only if
specifically requested)</span></span></td></tr>
<tr>
<td>Comment</td>
<td class=c>yes</td>
<td class=c>File</td>
<td><span class=s><span class=n>(comment embedded in JPEG, GIF89a or PPM/PGM/PBM image)</span></span></td></tr>
<tr class=b>
<td>CurrentIPTCDigest</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(MD5 digest of existing IPTC data. All zeros if IPTC exists but Digest::MD5
is not installed. Only calculated for IPTC in the standard location as
specified by the <a href="http://www.metadataworkinggroup.org/">MWG</a>. ExifTool
automates the handling of this tag in the MWG module -- see the
<a href="MWG.html">MWG Composite Tags</a> for details)</span></span></td></tr>
<tr>
<td>Directory</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>System</td>
<td><span class=s><span class=n>(the directory of the file as specified in the call to ExifTool, or &quot;.&quot; if no
directory was specified. May be written to move the file to another
directory that will be created if doesn&#39;t already exist)</span></span></td></tr>
<tr class=b>
<td>EXIF</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>EXIF</td>
<td><span class=s><span class=n>(the full EXIF data block from JPEG, PNG, JP2, MIE and MIFF images. This tag
is generated only if specifically requested)</span></span></td></tr>
<tr>
<td>EmbeddedVideo</td>
<td class=c>no</td>
<td class=c>File</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Error</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(returns errors that may have occurred while reading or writing a file. Any
Error will prevent the file from being processed. Minor errors may be
downgraded to warnings with the -m or <a href="../ExifTool.html#IgnoreMinorErrors">IgnoreMinorErrors</a> option)</span></span></td></tr>
<tr>
<td>ExifByteOrder</td>
<td class=c>yes</td>
<td class=c>File</td>
<td><span class=s><span class=n>(represents the byte order of EXIF information. May be written to set the
byte order only for newly created EXIF segments)</span>
<br>&#39;II&#39; = Little-endian (Intel, II)
<br>&#39;MM&#39; = Big-endian (Motorola, MM)</span></td></tr>
<tr class=b>
<td>ExifToolVersion</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(the version of ExifTool currently running)</span></span></td></tr>
<tr>
<td>ExifUnicodeByteOrder</td>
<td class=c>yes</td>
<td class=c>-</td>
<td><span class=s><span class=n>(specifies the byte order to use when writing EXIF Unicode text. The EXIF
specification is particularly vague about this byte ordering, and different
applications use different conventions. By default ExifTool writes Unicode
text in EXIF byte order, but this write-only tag may be used to force a
specific order. Applies to the EXIF UserComment tag when writing special
characters)</span>
<br>&#39;II&#39; = Little-endian (Intel, II)
<br>&#39;MM&#39; = Big-endian (Motorola, MM)</span></td></tr>
<tr class=b>
<td>FileAccessDate</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(the date/time of last access of the file. Note that this access time is
updated whenever any software, including ExifTool, reads the file)</span></span></td></tr>
<tr>
<td>FileAttributes</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(extracted only if specifically requested or the API <a href="../ExifTool.html#SystemTags">SystemTags</a> or <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set. 2 or 3 values: 0. File type, 1. Attribute bits, 2. Windows
attribute bits if Win32API::File is available)</span>
<br>[Value 0]</span><table class=cols><tr>
<td>0x0 = Unknown
<br>0x1000 = FIFO
<br>0x2000 = Character
<br>0x3000 = Mux Character
<br>0x4000 = Directory
<br>0x5000 = XENIX Named
<br>0x6000 = Block
<br>0x7000 = Mux Block</td><td>&nbsp;&nbsp;</td>
<td>0x8000 = Regular
<br>0x9000 = VxFS Compressed
<br>0xa000 = Symbolic Link
<br>0xb000 = Solaris Shadow Inode
<br>0xc000 = Socket
<br>0xd000 = Solaris Door
<br>0xe000 = BSD Whiteout</td></tr></table>
<span class=s>[Value 1]</span><table class=cols><tr>
<td>Bit 9 = Sticky
<br>Bit 10 = Set Group ID</td><td>&nbsp;&nbsp;</td>
<td>Bit 11 = Set User ID</td></tr></table>
<span class=s>[Value 2]</span><table class=cols><tr>
<td>Bit 0 = Read Only
<br>Bit 1 = Hidden
<br>Bit 2 = System
<br>Bit 3 = Volume Label
<br>Bit 4 = Directory
<br>Bit 5 = Archive
<br>Bit 6 = Device
<br>Bit 7 = Normal</td><td>&nbsp;&nbsp;</td>
<td>Bit 8 = Temporary
<br>Bit 9 = Sparse File
<br>Bit 10 = Reparse Point
<br>Bit 11 = Compressed
<br>Bit 12 = Offline
<br>Bit 13 = Not Content Indexed
<br>Bit 14 = Encrypted</td></tr></table>
</td></tr>
<tr class=b>
<td>FileBlockCount</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(extracted only if specifically requested or the API <a href="../ExifTool.html#SystemTags">SystemTags</a> or <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set)</span></span></td></tr>
<tr>
<td>FileBlockSize</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(extracted only if specifically requested or the API <a href="../ExifTool.html#SystemTags">SystemTags</a> or <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set)</span></span></td></tr>
<tr class=b>
<td>FileCreateDate</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>System</td>
<td><span class=s><span class=n>(the filesystem creation date/time. Windows/Mac/Linux only. In Windows, the
file creation date/time is preserved by default when writing if
Win32API::File and Win32::API are available. On Mac, this tag is extracted
only if it or the MacOS group is specifically requested or the API
<a href="../ExifTool.html#RequestAll">RequestAll</a> option is set to 2 or higher. On
Linux, this tag is read-only and extracted only if the filesystem supports
btime and &quot;File::StatX&quot; is available. Requires &quot;setfile&quot; for writing on
Mac, which may be installed by typing <code>xcode-select --install</code> in the
Terminal)</span></span></td></tr>
<tr>
<td>FileDeviceID</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(extracted only if specifically requested or the API <a href="../ExifTool.html#SystemTags">SystemTags</a> or <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set)</span></span></td></tr>
<tr class=b>
<td>FileDeviceNumber</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(extracted only if specifically requested or the API <a href="../ExifTool.html#SystemTags">SystemTags</a> or <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set)</span></span></td></tr>
<tr>
<td>FileGroupID</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>System</td>
<td><span class=s><span class=n>(extracted only if specifically requested or the API <a href="../ExifTool.html#SystemTags">SystemTags</a> or <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set. Returns group ID number with the -n option, or name
otherwise. May be written with either group name or number)</span></span></td></tr>
<tr class=b>
<td>FileHardLinks</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(extracted only if specifically requested or the API <a href="../ExifTool.html#SystemTags">SystemTags</a> or <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set)</span></span></td></tr>
<tr>
<td>FileInodeChangeDate</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(the date/time when the file&#39;s directory information was last changed.
Non-Windows systems only)</span></span></td></tr>
<tr class=b>
<td>FileInodeNumber</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(extracted only if specifically requested or the API <a href="../ExifTool.html#SystemTags">SystemTags</a> or <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set)</span></span></td></tr>
<tr>
<td>FileModifyDate</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>System</td>
<td><span class=s><span class=n>(the filesystem modification date/time. Note that ExifTool may not be able
to handle filesystem dates before 1970 depending on the limitations of the
system&#39;s standard libraries)</span></span></td></tr>
<tr class=b>
<td>FileName</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>System</td>
<td><span class=s><span class=n>(may be written with a full path name to set FileName and Directory in one
operation. This is such a powerful feature that a TestName tag is provided
to allow dry-run tests before actually writing the file name. See
<a href="../filename.html">filename.html</a> for more information on writing the
FileName, Directory and TestName tags)</span></span></td></tr>
<tr>
<td>FilePath</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(absolute path of source file. Not generated unless specifically requested or
the API <a href="../ExifTool.html#RequestAll">RequestAll</a> option is set. Does not support Windows Unicode file
names)</span></span></td></tr>
<tr class=b>
<td>FilePermissions</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>System</td>
<td><span class=s><span class=n>(r=read, w=write and x=execute permissions for the file owner, group and
others. The ValueConv value is an octal number so bit test operations on
this value should be done in octal, eg. &#39;oct($filePermissions#) &amp; 0200&#39;)</span></span></td></tr>
<tr>
<td>FileSequence</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(sequence number for each source file when extracting or copying information,
including files that fail the -if condition of the command-line application,
beginning at 0 for the first file. Not generated unless specifically
requested or the API <a href="../ExifTool.html#RequestAll">RequestAll</a> option is set)</span></span></td></tr>
<tr class=b>
<td>FileSize</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(note that the print conversion for this tag uses SI prefixes by default: 1
kB = 1000 bytes, etc. Set the API ByteUnit option to &quot;Binary&quot; to use binary
prefixes instead: 1 KiB = 1024 bytes, etc.)</span></span></td></tr>
<tr>
<td>FileType</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(a short description of the file type. For many file types this is the just
the uppercase file extension)</span></span></td></tr>
<tr class=b>
<td>FileTypeExtension</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(a common lowercase extension for this file type, or uppercase with the -n
option)</span></span></td></tr>
<tr>
<td>FileUserID</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>System</td>
<td><span class=s><span class=n>(extracted only if specifically requested or the API <a href="../ExifTool.html#SystemTags">SystemTags</a> or <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set. Returns user ID number with the -n option, or name
otherwise. May be written with either user name or number)</span></span></td></tr>
<tr class=b>
<td>ForceWrite</td>
<td class=c>yes</td>
<td class=c>-</td>
<td><span class=s><span class=n>(write-only tag used to force metadata in a file to be rewritten even if no
tag values are changed. May be set to &quot;EXIF&quot;, &quot;IPTC&quot;, &quot;XMP&quot; or &quot;PNG&quot; to
force the corresponding metadata type to be rewritten, &quot;FixBase&quot; to cause
EXIF to be rewritten only if the MakerNotes offset base was fixed, or &quot;All&quot;
to rewrite all of these metadata types. Values are case insensitive, and
multiple values may be separated with commas, eg. <code>-ForceWrite=exif,xmp</code>)</span></span></td></tr>
<tr>
<td>Geolocate</td>
<td class=c>yes</td>
<td class=c>-</td>
<td><span class=s><span class=n>(this write-only tag may be used to write geolocation city, region, country
code and country based in input GPS coordinates, or to write GPS
coordinates based on geolocation name. See the
<a href="../geolocation.html#Write">Writing section of the Geolocation page</a> for
details. This tag is writable regardless of the API <a href="../ExifTool.html#Geolocation">Geolocation</a>
option setting)</span></span></td></tr>
<tr class=b>
<td>GeolocationBearing</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(compass bearing to GeolocationCity center. Geolocation tags are
generated only if API <a href="../ExifTool.html#Geolocation">Geolocation</a> option is set)</span></span></td></tr>
<tr>
<td>GeolocationCity</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(name of city nearest to the current GPS coordinates)</span></span></td></tr>
<tr class=b>
<td>GeolocationCountry</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(geolocation country name)</span></span></td></tr>
<tr>
<td>GeolocationCountryCode</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(geolocation country code)</span></span></td></tr>
<tr class=b>
<td>GeolocationDistance</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(distance in km from current GPS to city)</span></span></td></tr>
<tr>
<td>GeolocationFeatureCode</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(geolocation feature code, see <a href="http://www.geonames.org/export/codes.html#P">http://www.geonames.org/export/codes.html#P</a>)</span></span></td></tr>
<tr class=b>
<td>GeolocationFeatureType</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(geolocation feature type)</span></span></td></tr>
<tr>
<td>GeolocationPopulation</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(city population rounded to 2 significant digits)</span></span></td></tr>
<tr class=b>
<td>GeolocationPosition</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(approximate GPS coordinates of city)</span></span></td></tr>
<tr>
<td>GeolocationRegion</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(geolocation state, province or region)</span></span></td></tr>
<tr class=b>
<td>GeolocationSubregion</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(geolocation county or subregion)</span></span></td></tr>
<tr>
<td>GeolocationTimeZone</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(geolocation time zone ID)</span></span></td></tr>
<tr class=b>
<td>GeolocationWarning</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td>&nbsp;</td></tr>
<tr>
<td>Geosync</td>
<td class=c>yes</td>
<td class=c>-</td>
<td><span class=s><span class=n>(this write-only tag specifies a time difference to add to Geotime for
synchronization with the GPS clock. For example, set this to &quot;-12&quot; if the
camera clock is 12 seconds faster than GPS time. Input format is
&quot;[+-][[[DD ]HH:]MM:]SS[.ss]&quot;. Additional features allow calculation of time
differences and time drifts, and extraction of synchronization times from
image files. See the <a href="../geotag.html">geotagging documentation</a> for details)</span></span></td></tr>
<tr class=b>
<td>Geotag</td>
<td class=c>yes</td>
<td class=c>-</td>
<td><span class=s><span class=n>(this write-only tag is used to define the GPS track log data or track log
file name. Currently supported track log formats are GPX, NMEA RMC/GGA/GLL,
KML, IGC, Garmin XML and TCX, Magellan PMGNTRK, Honeywell PTNTHPR, Winplus
Beacon text, Bramor gEO, Google Takeout JSON, and CSV log files. May be set
to the special value of &quot;DATETIMEONLY&quot; (all caps) to set GPS date/time tags
if no input track points are available. See <a href="../geotag.html">geotag.html</a>
for details)</span></span></td></tr>
<tr>
<td>Geotime</td>
<td class=c>yes</td>
<td class=c>-</td>
<td><span class=s><span class=n>(this write-only tag is used to define a date/time for interpolating a
position in the GPS track specified by the Geotag tag. Writing this tag
causes GPS information to be written into the EXIF or XMP of the target
files. The local system timezone is assumed if the date/time value does not
contain a timezone. May be deleted to delete associated GPS tags. A group
name of &quot;EXIF&quot; or &quot;XMP&quot; may be specified to write or delete only EXIF or XMP
GPS tags)</span></span></td></tr>
<tr class=b>
<td>HardLink</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>-</td>
<td><span class=s><span class=n>(this write-only tag is used to create a hard link with the specified name to
the source file. If the source file is edited, copied, renamed or moved in
the same operation as writing HardLink, then the link is made to the updated
file. Note that subsequent editing of either hard-linked file by exiftool
will break the link unless the -overwrite_original_in_place option is used)</span></span></td></tr>
<tr>
<td>ICC_Profile</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>ICC_Profile</td>
<td><span class=s><span class=n>(the full ICC_Profile data block. This tag is generated only if specifically
requested)</span></span></td></tr>
<tr class=b>
<td>ID3Size</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(size of the ID3 data block)</span></span></td></tr>
<tr>
<td>IPTC</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>IPTC</td>
<td><span class=s><span class=n>(the full IPTC data block. This tag is generated only if specifically
requested)</span></span></td></tr>
<tr class=b>
<td>ImageDataHash</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(Hash of image data. Generated only if specifically requested for JPEG, TIFF,
PNG, CRW, CR3, MRW, RAF, X3F, IIQ, JP2, JXL, HEIC and AVIF images, MOV/MP4
videos, and some RIFF-based files such as AVI, WAV and WEBP. The hash
algorithm is set by the API <a href="../ExifTool.html#ImageHashType">ImageHashType</a> option, and is &#39;MD5&#39; by default.
The hash includes the main image data, plus JpgFromRaw/OtherImage for some
formats, but does not include ThumbnailImage or PreviewImage. Includes
video and audio data for MOV/MP4. The <a href="XMP.html#ExifTool">XMP-et:OriginalImageHash and
XMP-et:OriginalImageHashType tags</a> provide a way to store
the this hash value and the hash type in the file.)</span></span></td></tr>
<tr>
<td>ImageHeight</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(the height of the image in number of pixels)</span></span></td></tr>
<tr class=b>
<td>ImageWidth</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(the width of the image in number of pixels)</span></span></td></tr>
<tr>
<td>JPEGDigest</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(an MD5 digest of the JPEG quantization tables is combined with the component
sub-sampling values to generate the value of this tag. The result is
compared to known values in an attempt to deduce the originating software
based only on the JPEG image data. For performance reasons, this tag is
generated only if specifically requested or the API <a href="../ExifTool.html#RequestAll">RequestAll</a> option is set
to 3 or higher)</span></span></td></tr>
<tr class=b>
<td>JPEGImageLength</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(byte length of JPEG image without metadata. For performance reasons, this
tag is generated only if specifically requested or the API <a href="../ExifTool.html#RequestAll">RequestAll</a> option
is set to 3 or higher)</span></span></td></tr>
<tr>
<td>JPEGQualityEstimate</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(an estimate of the IJG JPEG quality setting for the image, calculated from
the quantization tables. For performance reasons, this tag is generated
only if specifically requested or the API <a href="../ExifTool.html#RequestAll">RequestAll</a> option is set to 3 or
higher)</span></span></td></tr>
<tr class=b>
<td>JUMBF</td>
<td class=c>no</td>
<td class=c>JUMBF</td>
<td><span class=s><span class=n>(the C2PA JUMBF data block, extracted only if specifically requested)</span></span></td></tr>
<tr>
<td>MIMEType</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(the MIME type of the source file)</span></span></td></tr>
<tr class=b>
<td>MakerNoteByteOrder</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(byte order of maker notes. Generated only if different from ExifByteOrder)</span>
<br>&#39;II&#39; = Little-endian (Intel, II)
<br>&#39;MM&#39; = Big-endian (Motorola, MM)</span></td></tr>
<tr>
<td>MaxVal</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(maximum pixel value in PPM or PGM image)</span></span></td></tr>
<tr class=b>
<td>NewGUID</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(generates a new, random GUID with format
YYYYmmdd-HHMM-SSNN-PPPP-RRRRRRRRRRRR, where Y=year, m=month, d=day, H=hour,
M=minute, S=second, N=file sequence number in hex, P=process ID in hex, and
R=random hex number; without dashes with the -n option. Not generated
unless specifically requested or the API <a href="../ExifTool.html#RequestAll">RequestAll</a> option is set)</span></span></td></tr>
<tr>
<td>NewUUID</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(generates a version 4 (&quot;random&quot;), variant 1 UUID as per RFC 9562, Section
5.4. Not generated unless specifically requested or the API <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set)</span></span></td></tr>
<tr class=b>
<td>Now</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(the current date/time. Useful when setting the tag values, eg.
<code>&quot;-modifydate&lt;now&quot;</code>. Not generated unless specifically requested or the
API <a href="../ExifTool.html#RequestAll">RequestAll</a> option is set)</span></span></td></tr>
<tr>
<td>NumPlanes</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(number of color planes)</span></span></td></tr>
<tr class=b>
<td>OtherImage</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(other JPEG-format embedded image)</span></span></td></tr>
<tr>
<td>PageCount</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(the number of pages in a multi-page TIFF document)</span></span></td></tr>
<tr class=b>
<td>PreviewImage</td>
<td class=c>yes</td>
<td class=c>File</td>
<td><span class=s><span class=n>(JPEG-format embedded preview image)</span></span></td></tr>
<tr>
<td>PreviewJXL</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(JXL-format embedded preview image)</span></span></td></tr>
<tr class=b>
<td>PreviewPDF</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(PDF-format embedded preview image)</span></span></td></tr>
<tr>
<td>PreviewPNG</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(PNG-format embedded preview image)</span></span></td></tr>
<tr class=b>
<td>PreviewTIFF</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(TIFF-format embedded preview image)</span></span></td></tr>
<tr>
<td>PreviewWMF</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(WMF-format embedded preview image)</span></span></td></tr>
<tr class=b>
<td>ProcessingTime</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(the clock time in seconds taken by ExifTool to extract information from this
file. Not generated unless specifically requested or the API <a href="../ExifTool.html#RequestAll">RequestAll</a>
option is set. Requires Time::HiRes)</span></span></td></tr>
<tr>
<td>ResourceForkSize</td>
<td class=c>no</td>
<td class=c>System</td>
<td><span class=s><span class=n>(size of the file&#39;s resource fork if it contains data. Mac OS only. If this
tag is generated the <a href="../ExifTool.html#ExtractEmbedded">ExtractEmbedded</a> option may be used to extract
resource-fork information as a sub-document. When writing, the resource
fork is preserved by default, but it may be deleted with <code>-rsrc:all=</code> on
the command line)</span></span></td></tr>
<tr class=b>
<td>SphericalVideoXML</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>GSpherical</td>
<td><span class=s><span class=n>(the SphericalVideoXML block from MP4/MOV videos. This tag is generated only
if specifically requested)</span></span></td></tr>
<tr>
<td>SymLink</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>-</td>
<td><span class=s><span class=n>(this write-only tag is used to create a symbolic link with the specified
name to the source file. If the source file is edited, copied, renamed or
moved in the same operation as writing SymLink, then the link is made to the
updated file. The link uses an absolute path unless it is created in the
current working directory. Valid only for file systems that support
symbolic links. Note that subsequent editing of the file via the symbolic
link by exiftool will cause the link to be replaced by the edited file
without changing the original unless the -overwrite_original_in_place option
is used)</span></span></td></tr>
<tr class=b>
<td>TestName</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>-</td>
<td><span class=s><span class=n>(this write-only tag may be used instead of FileName for dry-run tests of the
file renaming feature. Writing this tag prints the old and new file names
to the console, but does not affect the file itself)</span></span></td></tr>
<tr>
<td>ThumbnailImage</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(JPEG-format embedded thumbnail image)</span></span></td></tr>
<tr class=b>
<td>Trailer</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>File</td>
<td><span class=s><span class=n>(the full JPEG trailer data block. Extracted only if specifically requested
or the API <a href="../ExifTool.html#RequestAll">RequestAll</a> option is set to 3 or higher)</span></span></td></tr>
<tr>
<td>Validate</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(generated only if specifically requested. Requesting this tag automatically
enables the API <a href="../ExifTool.html#Validate">Validate</a> option, imposing
additional validation checks when extracting metadata. Returns the number
of errors, warnings and minor warnings encountered. Note that the Validate
feature focuses mainly on validation of EXIF/TIFF metadata)</span>
<br>&#39;0 0 0&#39; = OK</span></td></tr>
<tr class=b>
<td>Warning</td>
<td class=c>no</td>
<td class=c>ExifTool</td>
<td><span class=s><span class=n>(returns warnings that may have occurred while reading or writing a file.
Use the -a or <a href="../ExifTool.html#Duplicates">Duplicates</a> option to see all warnings if more than one
occurred. Minor warnings may be ignored with the -m or <a href="../ExifTool.html#IgnoreMinorErrors">IgnoreMinorErrors</a>
option. Minor warnings with a capital &quot;M&quot; in the &quot;[Minor]&quot; designation
indicate that the processing is affected by ignoring the warning. Multiple
identical warnings are indicated by a count after the warning message, eg.
&quot;[x2]&quot; if the same warning occurred twice)</span></span></td></tr>
<tr>
<td>XML</td>
<td class=c>no</td>
<td class=c>XML</td>
<td><span class=s><span class=n>(the XML data block, extracted for some file types)</span></span></td></tr>
<tr class=b>
<td>XMP</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>XMP</td>
<td><span class=s><span class=n>(the XMP data block, but note that extended XMP in JPEG images may be split
into multiple blocks. This tag is generated only if specifically requested)</span></span></td></tr>
<tr>
<td>XResolution</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(the horizontal pixel resolution)</span></span></td></tr>
<tr class=b>
<td>YResolution</td>
<td class=c>no</td>
<td class=c>File</td>
<td><span class=s><span class=n>(the vertical pixel resolution)</span></span></td></tr>
<tr>
<td>ZoneIdentifier</td>
<td class=c title=' ! = Unsafe'>yes!</td>
<td class=c>System</td>
<td><span class=s><span class=n>(Windows only. Existence indicates that the file has a Zone.Identifier
alternate data stream, which is used by some Windows browsers to mark
downloaded files as possibly unsafe to run. May be deleted to remove this
stream. Requires Win32API::File)</span></span></td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised May 27, 2026</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+96
View File
@@ -0,0 +1,96 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>FITS Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>FITS Tags</h2>
<p>This table lists some standard Flexible Image Transport System (FITS) tags,
but ExifTool will extract any other tags found. See
<a href="https://fits.gsfc.nasa.gov/fits_standard.html">https://fits.gsfc.nasa.gov/fits_standard.html</a> for the specification.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'AUTHOR'</td>
<td>Author</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'BACKGRND'</td>
<td>Background</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'COMMENT'</td>
<td>Comment</td>
<td class=c>no</td>
<td><span class=s><span class=n>(leading spaces are removed if <a href="../ExifTool.html#PrintConv">PrintConv</a> is enabled)</span></span></td></tr>
<tr class=b>
<td>'DATE'</td>
<td>CreateDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'DATE-END'</td>
<td>ObservationDateEnd</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'DATE-OBS'</td>
<td>ObservationDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'HISTORY'</td>
<td>History</td>
<td class=c>no</td>
<td><span class=s><span class=n>(leading spaces are removed if <a href="../ExifTool.html#PrintConv">PrintConv</a> is enabled)</span></span></td></tr>
<tr class=b>
<td>'INSTRUME'</td>
<td>Instrument</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'OBJECT'</td>
<td>Object</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'OBSERVER'</td>
<td>Observer</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'REFERENC'</td>
<td>Reference</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'TELESCOP'</td>
<td>Telescope</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'TIME-END'</td>
<td>ObservationTimeEnd</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'TIME-OBS'</td>
<td>ObservationTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Feb 23, 2021</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+190
View File
@@ -0,0 +1,190 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>FLAC Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>FLAC Tags</h2>
<p>Free Lossless Audio Codec (FLAC) meta information. ExifTool also extracts
ID3 information from these files.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0000 = 0'>0x0000</td>
<td>StreamInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='FLAC.html#StreamInfo'>FLAC StreamInfo Tags</a></td></tr>
<tr class=b>
<td title='0x0001 = 1'>0x0001</td>
<td>Padding?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0002 = 2'>0x0002</td>
<td>Application_riff
<br>ApplicationUnknown?</td>
<td class=c>-<br>no</td>
<td>--&gt; <a href='RIFF.html'>RIFF Tags</a></td></tr>
<tr class=b>
<td title='0x0003 = 3'>0x0003</td>
<td>SeekTable?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0004 = 4'>0x0004</td>
<td>VorbisComment</td>
<td class=c>-</td>
<td>--&gt; <a href='Vorbis.html#Comments'>Vorbis Comments Tags</a></td></tr>
<tr class=b>
<td title='0x0005 = 5'>0x0005</td>
<td>CueSheet?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0006 = 6'>0x0006</td>
<td>Picture</td>
<td class=c>-</td>
<td>--&gt; <a href='FLAC.html#Picture'>FLAC Picture Tags</a></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='StreamInfo'>FLAC StreamInfo Tags</a></h2>
<p>FLAC is big-endian, so bit 0 is the high-order bit in this table.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'Bit000-015'</td>
<td>BlockSizeMin</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Bit016-031'</td>
<td>BlockSizeMax</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Bit032-055'</td>
<td>FrameSizeMin</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Bit056-079'</td>
<td>FrameSizeMax</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Bit080-099'</td>
<td>SampleRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Bit100-102'</td>
<td>Channels</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Bit103-107'</td>
<td>BitsPerSample</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Bit108-143'</td>
<td>TotalSamples</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Bit144-271'</td>
<td>MD5Signature</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Picture'>FLAC Picture Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>PictureType</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = Other
<br>1 = 32x32 PNG Icon
<br>2 = Other Icon
<br>3 = Front Cover
<br>4 = Back Cover
<br>5 = Leaflet
<br>6 = Media
<br>7 = Lead Artist
<br>8 = Artist
<br>9 = Conductor
<br>10 = Band
<br>11 = Composer
<br>12 = Lyricist
<br>13 = Recording Studio or Location
<br>14 = Recording Session
<br>15 = Performance
<br>16 = Capture from Movie or Video
<br>17 = Bright(ly) Colored Fish
<br>18 = Illustration
<br>19 = Band Logo
<br>20 = Publisher Logo</td></tr></table>
</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>PictureMIMEType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>PictureDescription</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>PictureWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>PictureHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='5 = 0x5'>5</td>
<td>PictureBitsPerPixel</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='6 = 0x6'>6</td>
<td>PictureIndexedColors</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='7 = 0x7'>7</td>
<td>PictureLength</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='8 = 0x8'>8</td>
<td>Picture</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Oct 19, 2022</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+85
View File
@@ -0,0 +1,85 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>FLIF Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>FLIF Tags</h2>
<p>Information extracted from Free Lossless Image Format files. See
<a href="http://flif.info/">http://flif.info/</a> for more information.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>ImageType</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>1 = Grayscale (non-interlaced)
<br>3 = RGB (non-interlaced)
<br>4 = RGBA (non-interlaced)
<br>&#39;A&#39; = Grayscale (interlaced)
<br>&#39;C&#39; = RGB (interlaced)
<br>&#39;D&#39; = RGBA (interlaced)
<br>&#39;Q&#39; = Grayscale Animation (non-interlaced)
<br>&#39;S&#39; = RGB Animation (non-interlaced)
<br>&#39;T&#39; = RGBA Animation (non-interlaced)
<br>&#39;a&#39; = Grayscale Animation (interlaced)
<br>&#39;c&#39; = RGB Animation (interlaced)
<br>&#39;d&#39; = RGBA Animation (interlaced)</td></tr></table>
</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>BitDepth</td>
<td class=c>no</td>
<td><span class=s>0 = Custom
<br>1 = 8
<br>2 = 16</span></td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>AnimationFrames</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='5 = 0x5'>5</td>
<td>Encoding</td>
<td class=c>no</td>
<td><span class=s>0 = FLIF16</span></td></tr>
<tr>
<td>'eXif'</td>
<td>EXIF</td>
<td class=c>-</td>
<td>--&gt; <a href='EXIF.html'>EXIF Tags</a></td></tr>
<tr class=b>
<td>'eXmp'</td>
<td>XMP</td>
<td class=c>-</td>
<td>--&gt; <a href='XMP.html'>XMP Tags</a></td></tr>
<tr>
<td>'iCCP'</td>
<td>ICC_Profile</td>
<td class=c>-</td>
<td>--&gt; <a href='ICC_Profile.html'>ICC_Profile Tags</a></td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Nov 2, 2016</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff
+420
View File
@@ -0,0 +1,420 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>Flash Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>Flash Tags</h2>
<p>The information below is extracted from SWF (Shockwave Flash) files. Tags
with string ID&#39;s represent information extracted from the file header.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'Compressed'</td>
<td>Compressed</td>
<td class=c>no</td>
<td><span class=s>0 = False
<br>1 = True</span></td></tr>
<tr class=b>
<td>'Duration'</td>
<td>Duration</td>
<td class=c>no</td>
<td><span class=s><span class=n>(calculated from FrameRate and FrameCount)</span></span></td></tr>
<tr>
<td>'FlashVersion'</td>
<td>FlashVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'FrameCount'</td>
<td>FrameCount</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'FrameRate'</td>
<td>FrameRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ImageHeight'</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ImageWidth'</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0045 = 69'>0x0045</td>
<td>FlashAttributes</td>
<td class=c>no</td>
<td><span class=s>Bit 0 = UseNetwork
<br>Bit 3 = ActionScript3
<br>Bit 4 = HasMetadata</span></td></tr>
<tr>
<td title='0x004d = 77'>0x004d</td>
<td>XMP</td>
<td class=c>-</td>
<td>--&gt; <a href='XMP.html'>XMP Tags</a></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='FLV'>Flash FLV Tags</a></h2>
<p>Information is extracted from the following packets in FLV (Flash Video)
files.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0008 = 8'>0x0008</td>
<td>Audio</td>
<td class=c>-</td>
<td>--&gt; <a href='Flash.html#Audio'>Flash Audio Tags</a></td></tr>
<tr class=b>
<td title='0x0009 = 9'>0x0009</td>
<td>Video</td>
<td class=c>-</td>
<td>--&gt; <a href='Flash.html#Video'>Flash Video Tags</a></td></tr>
<tr>
<td title='0x0012 = 18'>0x0012</td>
<td>Meta</td>
<td class=c>-</td>
<td>--&gt; <a href='Flash.html#Meta'>Flash Meta Tags</a></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Audio'>Flash Audio Tags</a></h2>
<p>Information extracted from the Flash Audio header.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'Bit0-3'</td>
<td>AudioEncoding</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>0 = PCM-BE (uncompressed)
<br>1 = ADPCM
<br>2 = MP3
<br>3 = PCM-LE (uncompressed)
<br>4 = Nellymoser 16kHz Mono
<br>5 = Nellymoser 8kHz Mono
<br>6 = Nellymoser
<br>7 = G.711 A-law logarithmic PCM
<br>8 = G.711 mu-law logarithmic PCM
<br>10 = AAC
<br>11 = Speex
<br>13 = MP3 8-Khz
<br>15 = Device-specific sound</td></tr></table>
</td></tr>
<tr class=b>
<td>'Bit4-5'</td>
<td>AudioSampleRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Bit6'</td>
<td>AudioBitsPerSample</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Bit7'</td>
<td>AudioChannels</td>
<td class=c>no</td>
<td><span class=s>1 = 1 (mono)
<br>2 = 2 (stereo)</span></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Video'>Flash Video Tags</a></h2>
<p>Information extracted from the Flash Video header.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'Bit4-7'</td>
<td>VideoEncoding</td>
<td class=c>no</td>
<td><table class=cols><tr>
<td>1 = JPEG
<br>2 = Sorensen H.263
<br>3 = Screen Video
<br>4 = On2 VP6</td><td>&nbsp;&nbsp;</td>
<td>5 = On2 VP6 Alpha
<br>6 = Screen Video 2
<br>7 = H.264</td></tr></table>
</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Meta'>Flash Meta Tags</a></h2>
<p>Below are a few observed FLV Meta tags, but ExifTool will attempt to extract
information from any tag found.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'audiocodecid'</td>
<td>AudioCodecID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'audiodatarate'</td>
<td>AudioBitrate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'audiodelay'</td>
<td>AudioDelay</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'audiosamplerate'</td>
<td>AudioSampleRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'audiosamplesize'</td>
<td>AudioSampleSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'audiosize'</td>
<td>AudioSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'bytelength'</td>
<td>ByteLength</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'canSeekToEnd'</td>
<td>CanSeekToEnd</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'canseekontime'</td>
<td>CanSeekOnTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'createdby'</td>
<td>CreatedBy</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'creationdate'</td>
<td>CreateDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'cuePoints'</td>
<td>CuePoint</td>
<td class=c>-</td>
<td>--&gt; <a href='Flash.html#CuePoint'>Flash CuePoint Tags</a></td></tr>
<tr>
<td>'datasize'</td>
<td>DataSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'duration'</td>
<td>Duration</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'filesize'</td>
<td>FileSizeBytes</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'framerate'</td>
<td>FrameRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'hasAudio'</td>
<td>HasAudio</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'hasCuePoints'</td>
<td>HasCuePoints</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'hasKeyframes'</td>
<td>HasKeyFrames</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'hasMetadata'</td>
<td>HasMetadata</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'hasVideo'</td>
<td>HasVideo</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'height'</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'httphostheader'</td>
<td>HTTPHostHeader</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'keyframesFilepositions'</td>
<td>KeyFramePositions</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'keyframesTimes'</td>
<td>KeyFramesTimes</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'lastkeyframetimestamp'</td>
<td>LastKeyFrameTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'lasttimestamp'</td>
<td>LastTimeStamp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'liveXML'</td>
<td>XMP</td>
<td class=c>-</td>
<td>--&gt; <a href='XMP.html'>XMP Tags</a></td></tr>
<tr>
<td>'metadatacreator'</td>
<td>MetadataCreator</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'metadatadate'</td>
<td>MetadataDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'pmsg'</td>
<td>Message</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'purl'</td>
<td>URL</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'sourcedata'</td>
<td>SourceData</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'starttime'</td>
<td>StartTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'stereo'</td>
<td>Stereo</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'totaldatarate'</td>
<td>TotalDataRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'totalduration'</td>
<td>TotalDuration</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'videocodecid'</td>
<td>VideoCodecID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'videodatarate'</td>
<td>VideoBitrate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'videosize'</td>
<td>VideoSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'width'</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='CuePoint'>Flash CuePoint Tags</a></h2>
<p>These tag names are added to the CuePoint name to generate complete tag
names like &quot;CuePoint0Name&quot;.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'name'</td>
<td>Name</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'parameters'</td>
<td>Parameter</td>
<td class=c>-</td>
<td>--&gt; <a href='Flash.html#Parameter'>Flash Parameter Tags</a></td></tr>
<tr>
<td>'time'</td>
<td>Time</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'type'</td>
<td>Type</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Parameter'>Flash Parameter Tags</a></h2>
<p>There are no pre-defined parameter tags, but ExifTool will extract any
existing parameters, with tag names like &quot;CuePoint0ParameterXxx&quot;.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr><td colspan=4 class=c><i>[no tags known]</i></td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Jul 9, 2015</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff
+640
View File
@@ -0,0 +1,640 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>Font Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>Font Tags</h2>
<p>This table contains a collection of tags found in font files of various
formats. ExifTool current recognizes OTF, TTF, TTC, DFONT, PFA, PFB, PFM,
AFM, ACFM, AMFM, WOFF and WOFF2 font files.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'AFM'</td>
<td>AFM</td>
<td class=c>-</td>
<td>--&gt; <a href='Font.html#AFM'>Font AFM Tags</a></td></tr>
<tr class=b>
<td>'C2PA'</td>
<td>C2PA</td>
<td class=c>-</td>
<td>--&gt; <a href='Jpeg2000.html'>Jpeg2000 Tags</a></td></tr>
<tr>
<td>'PFM'</td>
<td>PFMHeader</td>
<td class=c>-</td>
<td>--&gt; <a href='Font.html#PFM'>Font PFM Tags</a></td></tr>
<tr class=b>
<td>'PSInfo'</td>
<td>PSFontInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='Font.html#PSInfo'>Font PSInfo Tags</a></td></tr>
<tr>
<td>'WOFFVersion'</td>
<td>WOFFVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'XML'</td>
<td>XML</td>
<td class=c>-</td>
<td>--&gt; <a href='Font.html#XML'>Font XML Tags</a></td></tr>
<tr>
<td>'fontname'</td>
<td>FontName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'name'</td>
<td>Name</td>
<td class=c>-</td>
<td>--&gt; <a href='Font.html#Name'>Font Name Tags</a></td></tr>
<tr>
<td>'numfonts'</td>
<td>NumFonts</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'postfont'</td>
<td>PostScriptFontName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='AFM'>Font AFM Tags</a></h2>
<p>Tags extracted from Adobe Font Metrics files (AFM, ACFM and AMFM).</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'Ascender'</td>
<td>Ascender</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'CapHeight'</td>
<td>CapHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'CharacterSet'</td>
<td>CharacterSet</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Characters'</td>
<td>Characters</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Creation Date'</td>
<td>CreateDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Descender'</td>
<td>Descender</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'EncodingScheme'</td>
<td>EncodingScheme</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'EscChar'</td>
<td>EscChar</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'FamilyName'</td>
<td>FontFamily</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'FontName'</td>
<td>FontName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'FullName'</td>
<td>FullName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'IsBaseFont'</td>
<td>IsBaseFont</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'IsFixedV'</td>
<td>IsFixedV</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'MappingScheme'</td>
<td>MappingScheme</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Notice'</td>
<td>Notice</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Version'</td>
<td>Version</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Weight'</td>
<td>Weight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'XHeight'</td>
<td>XHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='PFM'>Font PFM Tags</a></h2>
<p>Tags extracted from the PFM file header.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>PFMVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>Copyright</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='66 = 0x42'>66</td>
<td>FontType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='68 = 0x44'>68</td>
<td>PointSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='70 = 0x46'>70</td>
<td>YResolution</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='72 = 0x48'>72</td>
<td>XResolution</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='74 = 0x4a'>74</td>
<td>Ascent</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='76 = 0x4c'>76</td>
<td>InternalLeading</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='78 = 0x4e'>78</td>
<td>ExternalLeading</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='80 = 0x50'>80</td>
<td>Italic</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='81 = 0x51'>81</td>
<td>Underline</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='82 = 0x52'>82</td>
<td>Strikeout</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='83 = 0x53'>83</td>
<td>Weight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='85 = 0x55'>85</td>
<td>CharacterSet</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='86 = 0x56'>86</td>
<td>PixWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='88 = 0x58'>88</td>
<td>PixHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='90 = 0x5a'>90</td>
<td>PitchAndFamily</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='91 = 0x5b'>91</td>
<td>AvgWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='93 = 0x5d'>93</td>
<td>MaxWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='95 = 0x5f'>95</td>
<td>FirstChar</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='96 = 0x60'>96</td>
<td>LastChar</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='97 = 0x61'>97</td>
<td>DefaultChar</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='98 = 0x62'>98</td>
<td>BreakChar</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='99 = 0x63'>99</td>
<td>WidthBytes</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='PSInfo'>Font PSInfo Tags</a></h2>
<p>Tags extracted from PostScript font files (PFA and PFB).</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'Copyright'</td>
<td>Copyright</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'FSType'</td>
<td>FSType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'FamilyName'</td>
<td>FontFamily</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'FontName'</td>
<td>FontName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'FontType'</td>
<td>FontType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'FullName'</td>
<td>FullName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ItalicAngle'</td>
<td>ItalicAngle</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'Notice'</td>
<td>Notice</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'UnderlinePosition'</td>
<td>UnderlinePosition</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'UnderlineThickness'</td>
<td>UnderlineThickness</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'Weight'</td>
<td>Weight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'isFixedPitch'</td>
<td>IsFixedPitch</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'version'</td>
<td>Version</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='XML'>Font XML Tags</a></h2>
<p>Tags found in WOFF and WOFF2 XML metadata.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'copyrightText'</td>
<td>Copyright</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'creditsCreditClass'</td>
<td>CreditClass</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'creditsCreditDir'</td>
<td>CreditDir</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'creditsCreditName'</td>
<td>CreditName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'creditsCreditRole'</td>
<td>CreditRole</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'creditsCreditUrl'</td>
<td>CreditURL</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'descriptionText'</td>
<td>Description</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'descriptionUrl'</td>
<td>DescriptionUrl</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'extensionId'</td>
<td>ExtensionID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'extensionItemId'</td>
<td>ExtensionItemID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'extensionItemName'</td>
<td>ExtensionItemName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'extensionItemValue'</td>
<td>ExtensionItemValue</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'extensionName'</td>
<td>ExtensionName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'licenseId'</td>
<td>LicenseID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'licenseText'</td>
<td>License</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'licenseUrl'</td>
<td>LicenseURL</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'licenseeClass'</td>
<td>LicenseeClass</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'licenseeDir'</td>
<td>LicenseeDir</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'licenseeName'</td>
<td>LicenseeName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'trademarkText'</td>
<td>Trademark</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'uniqueidId'</td>
<td>UniqueID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'vendorClass'</td>
<td>VendorClass</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'vendorDir'</td>
<td>VendorDir</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'vendorName'</td>
<td>VendorName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'vendorUrl'</td>
<td>VendorURL</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'version'</td>
<td>Version</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Name'>Font Name Tags</a></h2>
<p>The following tags are extracted from the TrueType font &quot;name&quot; table found
in OTF, TTF, TTC, DFONT, WOFF and WOFF2 files. These tags support localized
languages by adding a hyphen followed by a language code to the end of the
tag name (eg. &quot;Copyright-fr&quot; or &quot;License-en-US&quot;). Tags with no language
code use the default language of &quot;en&quot;.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0000 = 0'>0x0000</td>
<td>Copyright</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0001 = 1'>0x0001</td>
<td>FontFamily</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0002 = 2'>0x0002</td>
<td>FontSubfamily</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0003 = 3'>0x0003</td>
<td>FontSubfamilyID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0004 = 4'>0x0004</td>
<td>FontName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0005 = 5'>0x0005</td>
<td>NameTableVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0006 = 6'>0x0006</td>
<td>PostScriptFontName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0007 = 7'>0x0007</td>
<td>Trademark</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0008 = 8'>0x0008</td>
<td>Manufacturer</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0009 = 9'>0x0009</td>
<td>Designer</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x000a = 10'>0x000a</td>
<td>Description</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x000b = 11'>0x000b</td>
<td>VendorURL</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x000c = 12'>0x000c</td>
<td>DesignerURL</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x000d = 13'>0x000d</td>
<td>License</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x000e = 14'>0x000e</td>
<td>LicenseInfoURL</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0010 = 16'>0x0010</td>
<td>PreferredFamily</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0011 = 17'>0x0011</td>
<td>PreferredSubfamily</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0012 = 18'>0x0012</td>
<td>CompatibleFontName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0013 = 19'>0x0013</td>
<td>SampleText</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0014 = 20'>0x0014</td>
<td>PostScriptFontName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0015 = 21'>0x0015</td>
<td>WWSFamilyName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0016 = 22'>0x0016</td>
<td>WWSSubfamilyName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Oct 24, 2025</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+104
View File
@@ -0,0 +1,104 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>FotoStation Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>FotoStation Tags</h2>
<p>The following tables define information found in the FotoWare FotoStation
trailer.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0001 = 1'>0x0001</td>
<td>IPTC</td>
<td class=c>-</td>
<td>--&gt; <a href='IPTC.html'>IPTC Tags</a></td></tr>
<tr class=b>
<td title='0x0002 = 2'>0x0002</td>
<td>SoftEdit</td>
<td class=c>-</td>
<td>--&gt; <a href='FotoStation.html#SoftEdit'>FotoStation SoftEdit Tags</a></td></tr>
<tr>
<td title='0x0003 = 3'>0x0003</td>
<td>ThumbnailImage</td>
<td class=c>yes</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0004 = 4'>0x0004</td>
<td>PreviewImage</td>
<td class=c>yes</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='SoftEdit'>FotoStation SoftEdit Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>OriginalImageWidth</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>OriginalImageHeight</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>ColorPlanes</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>XYResolution</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>Rotation</td>
<td class=c>int32s</td>
<td><span class=s><span class=n>(rotations are stored as degrees CCW * 100, but converted to degrees CW by
ExifTool)</span></span></td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>CropLeft</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='7 = 0x7'>7</td>
<td>CropTop</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='8 = 0x8'>8</td>
<td>CropRight</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='9 = 0x9'>9</td>
<td>CropBottom</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='11 = 0xb'>11</td>
<td>CropRotation</td>
<td class=c>int32s</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Oct 20, 2006</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff
+41
View File
@@ -0,0 +1,41 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>GE Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>GE Tags</h2>
<p>This table lists tags found in the maker notes of some General Imaging
camera models.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0202 = 514'>0x0202</td>
<td>Macro</td>
<td class=c>int16u</td>
<td><span class=s>0 = Off
<br>1 = On</span></td></tr>
<tr class=b>
<td title='0x0207 = 519'>0x0207</td>
<td>GEModel</td>
<td class=c>string</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0300 = 768'>0x0300</td>
<td>GEMake</td>
<td class=c>string</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Dec 15, 2010</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+196
View File
@@ -0,0 +1,196 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>GIF Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>GIF Tags</h2>
<p>This table lists information extracted from GIF images. See
<a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt">http://www.w3.org/Graphics/GIF/spec-gif89a.txt</a> for the official GIF89a
specification.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>Comment</td>
<td class=c>yes</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Duration</td>
<td class=c>no</td>
<td><span class=s><span class=n>(duration of a single animation iteration)</span></span></td></tr>
<tr>
<td>Extensions</td>
<td class=c>-</td>
<td>--&gt; <a href='GIF.html#Extensions'>GIF Extensions Tags</a></td></tr>
<tr class=b>
<td>FrameCount</td>
<td class=c>no</td>
<td><span class=s><span class=n>(number of animated images)</span></span></td></tr>
<tr>
<td>GIFVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ScreenDescriptor</td>
<td class=c>-</td>
<td>--&gt; <a href='GIF.html#Screen'>GIF Screen Tags</a></td></tr>
<tr>
<td>Text</td>
<td class=c>no</td>
<td><span class=s><span class=n>(text displayed in image)</span></span></td></tr>
<tr class=b>
<td>TransparentColor</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Extensions'>GIF Extensions Tags</a></h2>
<p>Tags extracted from GIF89a application extensions.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'C2PA_GIF/'</td>
<td>JUMBF</td>
<td class=c>-</td>
<td>--&gt; <a href='Jpeg2000.html'>Jpeg2000 Tags</a></td></tr>
<tr class=b>
<td>'ICCRGBG1/012'</td>
<td>ICC_Profile</td>
<td class=c>yes</td>
<td>--&gt; <a href='ICC_Profile.html'>ICC_Profile Tags</a></td></tr>
<tr>
<td>'MIDICTRL/Jon'</td>
<td>MIDIControl</td>
<td class=c>-</td>
<td>--&gt; <a href='GIF.html#MIDIControl'>GIF MIDIControl Tags</a></td></tr>
<tr class=b>
<td>'MIDISONG/Dm7'</td>
<td>MIDISong</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'NETSCAPE/2.0'</td>
<td>Animation</td>
<td class=c>-</td>
<td>--&gt; <a href='GIF.html#Animation'>GIF Animation Tags</a></td></tr>
<tr class=b>
<td>'XMP Data/XMP'</td>
<td>XMP</td>
<td class=c>yes</td>
<td>--&gt; <a href='XMP.html'>XMP Tags</a></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='MIDIControl'>GIF MIDIControl Tags</a></h2>
<p>Information extracted from the MIDI control block extension.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>MIDIControlVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>SequenceNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>MelodicPolyphony</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>PercussivePolyphony</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>ChannelUsage</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>DelayTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Animation'>GIF Animation Tags</a></h2>
<p>Information extracted from the &quot;NETSCAPE2.0&quot; animation extension.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='1 = 0x1'>1</td>
<td>AnimationIterations</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Screen'>GIF Screen Tags</a></h2>
<p>Information extracted from the GIF logical screen descriptor.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='2 = 0x2'>2</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='4 = 0x4'>4.1</td>
<td>HasColorMap</td>
<td class=c>no</td>
<td><span class=s>[val &gt;&gt; 7 &amp; 0x1]
<br>0 = No
<br>1 = Yes</span></td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4.2</td>
<td>ColorResolutionDepth</td>
<td class=c>no</td>
<td><span class=s>[val &gt;&gt; 4 &amp; 0x7]</span></td></tr>
<tr>
<td class=r title='4 = 0x4'>4.3</td>
<td>BitsPerPixel</td>
<td class=c>no</td>
<td><span class=s>[val &amp; 0x7]</span></td></tr>
<tr class=b>
<td class=r title='5 = 0x5'>5</td>
<td>BackgroundColor</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='6 = 0x6'>6</td>
<td>PixelAspectRatio</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Nov 8, 2024</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+159
View File
@@ -0,0 +1,159 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>GIMP Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>GIMP Tags</h2>
<p>The GNU Image Manipulation Program (GIMP) writes these tags in its native
XCF (eXperimental Computing Facilty) images.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'header'</td>
<td>Header</td>
<td class=c>-</td>
<td>--&gt; <a href='GIMP.html#Header'>GIMP Header Tags</a></td></tr>
<tr class=b>
<td title='0x0011 = 17'>0x0011</td>
<td>Compression</td>
<td class=c>no</td>
<td><span class=s>0 = None
<br>1 = RLE Encoding
<br>2 = Zlib
<br>3 = Fractal</span></td></tr>
<tr>
<td title='0x0013 = 19'>0x0013</td>
<td>Resolution</td>
<td class=c>-</td>
<td>--&gt; <a href='GIMP.html#Resolution'>GIMP Resolution Tags</a></td></tr>
<tr class=b>
<td title='0x0014 = 20'>0x0014</td>
<td>Tattoo</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0015 = 21'>0x0015</td>
<td>Parasites</td>
<td class=c>-</td>
<td>--&gt; <a href='GIMP.html#Parasite'>GIMP Parasite Tags</a></td></tr>
<tr class=b>
<td title='0x0016 = 22'>0x0016</td>
<td>Units</td>
<td class=c>no</td>
<td><span class=s>1 = Inches
<br>2 = mm
<br>3 = Points
<br>4 = Picas</span></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Header'>GIMP Header Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='9 = 0x9'>9</td>
<td>XCFVersion</td>
<td class=c>no</td>
<td><span class=s>&#39;file&#39; = 0
<br>&#39;v001&#39; = 1
<br>&#39;v002&#39; = 2</span></td></tr>
<tr class=b>
<td class=r title='14 = 0xe'>14</td>
<td>ImageWidth</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='18 = 0x12'>18</td>
<td>ImageHeight</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='22 = 0x16'>22</td>
<td>ColorMode</td>
<td class=c>no</td>
<td><span class=s>0 = RGB Color
<br>1 = Grayscale
<br>2 = Indexed Color</span></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Resolution'>GIMP Resolution Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index4</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>XResolution</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>YResolution</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Parasite'>GIMP Parasite Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'exif-data'</td>
<td>ExifData</td>
<td class=c>-</td>
<td>--&gt; <a href='EXIF.html'>EXIF Tags</a></td></tr>
<tr class=b>
<td>'gimp-comment'</td>
<td>Comment</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'gimp-image-metadata'</td>
<td>XML</td>
<td class=c>-</td>
<td>--&gt; <a href='XMP.html#XML'>XMP XML Tags</a></td></tr>
<tr class=b>
<td>'gimp-metadata'</td>
<td>XMP</td>
<td class=c>-</td>
<td>--&gt; <a href='XMP.html'>XMP Tags</a></td></tr>
<tr>
<td>'icc-profile'</td>
<td>ICC_Profile</td>
<td class=c>-</td>
<td>--&gt; <a href='ICC_Profile.html'>ICC_Profile Tags</a></td></tr>
<tr class=b>
<td>'icc-profile-name'</td>
<td>ICCProfileName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'iptc-data'</td>
<td>IPTCData</td>
<td class=c>-</td>
<td>--&gt; <a href='IPTC.html'>IPTC Tags</a></td></tr>
<tr class=b>
<td>'jpeg-exif-data'</td>
<td>JPEGExifData</td>
<td class=c>-</td>
<td>--&gt; <a href='EXIF.html'>EXIF Tags</a></td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Aug 21, 2018</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+559
View File
@@ -0,0 +1,559 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>GM Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>GM Tags</h2>
<p>
These tags are extracted from GM/Cosworth PDR (Performance Data Recorder)
information found in videos from General Motors cars such as Corvette and
Camero.</p>
<p>Use the API <a href="../ExifTool.html#PrintCSV">PrintCSV</a> option to output all timed
PDR data in CSV format at greatly increased speed and with much lower memory
usage. This option prints the numerical values for each channel in CSV
format, suitable for import into RaceRender. In this output, the gear
numbers for Neutral and Reverse are changed to -1 and -100 respectively for
compatibility with RaceRender.
</p>
<h2><a name='marl'>GM marl Tags</a></h2>
<p>Tags extracted from the &#39;ctbx&#39; &#39;marl&#39; (Marlin) box of timed PDR metadata
from GM cars. Use the -ee (<a href="../ExifTool.html#ExtractEmbedded">API ExtractEmbedded</a>) option to extract this
information, or the <a href="../ExifTool.html#PrintCSV">API PrintCSV</a> option to output in CSV format.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>ABSActive</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>AccelPos</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>BatteryVoltage</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Beacon</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>BoostPressureInd</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>BrakePos</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>CPUFree</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>CPUIO</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>CPUIRQ</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>CPUSystem</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>CPUUser</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>ClutchPos</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>CoolantTemp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>CornerExitSetting</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>DiskReadOperations</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>DiskReadRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>DiskReadTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>DiskWriteOperations</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>DiskWriteRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>DiskWriteTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>Distance</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>DriverPerformanceMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>EngineSpeedRequest</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>EngineTorqureReq</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>FuelCapacity</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>FuelLevel</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>GPSAltitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSDateTime</td>
<td class=c>no</td>
<td><span class=s><span class=n>(generated from the TimeStamp only if specifically requested)</span></span></td></tr>
<tr>
<td>GPSFix</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSLatitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>GPSLongitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>GPSTrack</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>Gear</td>
<td class=c>no</td>
<td><span class=s><span class=n>(in the PrintCSV output, the value for Neutral is set to -1, and Reverse to
-100 for compatibility with RaceRender)</span></span><table class=cols><tr>
<td>1 = 1
<br>2 = 2
<br>3 = 3
<br>4 = 4</td><td>&nbsp;&nbsp;</td>
<td>5 = 5
<br>6 = 6
<br>13 = N
<br>14 = R</td></tr></table>
</td></tr>
<tr class=b>
<td>InfotainOpMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>IntakeAirTemperature</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>IntakeBoostPressure</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>LFTyrePressure</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>LFTyreTemp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>LRTyrePressure</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>LRTyreTemp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>LateralAcceleration</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>LongitudinalAcceleration</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>OilPressure</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>OilTemp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>OutsideAirTemperature</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>RFTyrePressure</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>RFTyreTemp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>RPM</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>RRTyrePressure</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>RRTyreTemp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>RecordingEventOdometer</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Speed</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>SpeedControlResponse</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>SpeedRequestIntervention</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>Steering1Switch</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>Steering2Switch</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>SteeringAngle</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>SuspensionDisplacementLeftFront</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>SuspensionDisplacementLeftRear</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>SuspensionDisplacementRightFront</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>SuspensionDisplacementRightRear</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>SystemBackupPowerEnabled</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>SystemBackupPowerMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>SystemPowerMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>TimeStamp</td>
<td class=c>no</td>
<td><span class=s><span class=n>(the numerical value is seconds since start of video, but the print
conversion adds StartTime to provide a date/time value. Extracted as
GPSDateTime if requested)</span></span></td></tr>
<tr class=b>
<td>TractionControlActive</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>TransOilTemp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>TransportStorageMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>ValetMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>VehicleStabilityActive</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>VerticalAcceleration</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>WheelspeedLeftDriven</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>WheelspeedLeftNon-Driven</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>WheelspeedRightDriven</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>WheelspeedRightNon-Driven</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>YawRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='mrld'>GM mrld Tags</a></h2>
<p>The Marlin dictionary. Only one channel is listed but all available
channels are extracted. Use the -struct (<a href="../ExifTool.html#Struct">API Struct</a>) option to extract the
channel information as structures.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>Channel01</td>
<td class=c>struct</td>
<td>--&gt; <a href='GM.html#Channel'>GM Channel Struct</a></td></tr>
<tr class=b>
<td>Channel01Description</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(channel description)</span></span></td></tr>
<tr>
<td>Channel01DispMax</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(displayed value maximum)</span></span></td></tr>
<tr class=b>
<td>Channel01DispMin</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(displayed value minimum)</span></span></td></tr>
<tr>
<td>Channel01Flags</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(channel flags)</span></span></td></tr>
<tr class=b>
<td>Channel01ID</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(channel ID number)</span></span></td></tr>
<tr>
<td>Channel01Interval</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(measurement interval)</span></span></td></tr>
<tr class=b>
<td>Channel01Max</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(raw value maximum)</span></span></td></tr>
<tr>
<td>Channel01Min</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(raw value minimum)</span></span></td></tr>
<tr class=b>
<td>Channel01Multiplier</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(multiplier for raw value)</span></span></td></tr>
<tr>
<td>Channel01Name</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(channel name)</span></span></td></tr>
<tr class=b>
<td>Channel01Num</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(units ID number)</span></span></td></tr>
<tr>
<td>Channel01Offset</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(offset for scaled value)</span></span></td></tr>
<tr class=b>
<td>Channel01Type</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(measurement type)</span></span></td></tr>
<tr>
<td>Channel01Units</td>
<td class=c title=' _ = Flattened'>no_</td>
<td><span class=s><span class=n>(units string)</span></span></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='Channel'>GM Channel Struct</a></h2>
<p>Information stored for each channel in the Marlin dictionary.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Field Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>ID</td>
<td class=c>no</td>
<td><span class=s><span class=n>(channel ID number)</span></span></td></tr>
<tr class=b>
<td>Type</td>
<td class=c>no</td>
<td><span class=s><span class=n>(measurement type)</span></span></td></tr>
<tr>
<td>Num</td>
<td class=c>no</td>
<td><span class=s><span class=n>(units ID number)</span></span></td></tr>
<tr class=b>
<td>Units</td>
<td class=c>no</td>
<td><span class=s><span class=n>(units string)</span></span></td></tr>
<tr>
<td>Flags</td>
<td class=c>no</td>
<td><span class=s><span class=n>(channel flags)</span></span></td></tr>
<tr class=b>
<td>Interval</td>
<td class=c>no</td>
<td><span class=s><span class=n>(measurement interval)</span></span></td></tr>
<tr>
<td>Min</td>
<td class=c>no</td>
<td><span class=s><span class=n>(raw value minimum)</span></span></td></tr>
<tr class=b>
<td>Max</td>
<td class=c>no</td>
<td><span class=s><span class=n>(raw value maximum)</span></span></td></tr>
<tr>
<td>DispMin</td>
<td class=c>no</td>
<td><span class=s><span class=n>(displayed value minimum)</span></span></td></tr>
<tr class=b>
<td>DispMax</td>
<td class=c>no</td>
<td><span class=s><span class=n>(displayed value maximum)</span></span></td></tr>
<tr>
<td>Multiplier</td>
<td class=c>no</td>
<td><span class=s><span class=n>(multiplier for raw value)</span></span></td></tr>
<tr class=b>
<td>Offset</td>
<td class=c>no</td>
<td><span class=s><span class=n>(offset for scaled value)</span></span></td></tr>
<tr>
<td>Name</td>
<td class=c>no</td>
<td><span class=s><span class=n>(channel name)</span></span></td></tr>
<tr class=b>
<td>Description</td>
<td class=c>no</td>
<td><span class=s><span class=n>(channel description)</span></span></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='mrlh'>GM mrlh Tags</a></h2>
<p>The Marlin PDR header.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>MarlinDataVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='mrlv'>GM mrlv Tags</a></h2>
<p>Tags found in the &#39;mrlv&#39; (Marlin values) box.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'date'</td>
<td>Date1</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'lang'</td>
<td>Language</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ldat'</td>
<td>Date2</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ltim'</td>
<td>Time2</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'swvs'</td>
<td>SoftwareVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'time'</td>
<td>Time1</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'tstm'</td>
<td>StartTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'unit'</td>
<td>Units</td>
<td class=c>no</td>
<td><span class=s>&#39;usim&#39; = U.S. Imperial</span></td></tr>
<tr>
<td>'zone'</td>
<td>TimeZone</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Apr 18, 2024</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
+233
View File
@@ -0,0 +1,233 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>GPS Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top>GPS Tags</h2>
<p>
These GPS tags are part of the EXIF standard, and are stored in a separate
IFD within the EXIF information.</p>
<p>ExifTool is very flexible about the input format when writing lat/long
coordinates, and will accept from 1 to 3 floating point numbers (for decimal
degrees, degrees and minutes, or degrees, minutes and seconds) separated by
just about anything, and will format them properly according to the EXIF
specification.</p>
<p>Some GPS tags have values which are fixed-length strings. For these, the
indicated string lengths include a null terminator which is added
automatically by ExifTool. Remember that the descriptive values are used
when writing (eg. &#39;Above Sea Level&#39;, not &#39;0&#39;) unless the print conversion is
disabled (with &#39;-n&#39; on the command line or the <a href="../ExifTool.html#PrintConv">PrintConv</a> option in the API,
or by suffixing the tag name with a <code>#</code> character).</p>
<p>When adding GPS information to an image, it is important to set all of the
following tags: GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef,
and GPSAltitude and GPSAltitudeRef if the altitude is known. ExifTool will
write the required GPSVersionID tag automatically if new a GPS IFD is added
to an image.
</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td title='0x0000 = 0'>0x0000</td>
<td>GPSVersionID</td>
<td class=c title=' : = Mandatory'>int8u[4]:</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0001 = 1'>0x0001</td>
<td>GPSLatitudeRef</td>
<td class=c>string[2]</td>
<td><span class=s><span class=n>(tags 0x0001-0x0006 used for camera location according to MWG 2.0. ExifTool
will also accept a number when writing GPSLatitudeRef, positive for north
latitudes or negative for south, or a string containing N, North, S or South)</span>
<br>&#39;N&#39; = North
<br>&#39;S&#39; = South</span></td></tr>
<tr>
<td title='0x0002 = 2'>0x0002</td>
<td>GPSLatitude</td>
<td class=c>rational64u[3]</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0003 = 3'>0x0003</td>
<td>GPSLongitudeRef</td>
<td class=c>string[2]</td>
<td><span class=s><span class=n>(ExifTool will also accept a number when writing this tag, positive for east
longitudes or negative for west, or a string containing E, East, W or West)</span>
<br>&#39;E&#39; = East
<br>&#39;W&#39; = West</span></td></tr>
<tr>
<td title='0x0004 = 4'>0x0004</td>
<td>GPSLongitude</td>
<td class=c>rational64u[3]</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0005 = 5'>0x0005</td>
<td>GPSAltitudeRef</td>
<td class=c>int8u</td>
<td><span class=s><span class=n>(ExifTool will also accept number when writing this tag, with negative
numbers indicating below sea level)</span>
<br>0 = Above Sea Level
<br>1 = Below Sea Level
<br>2 = Positive Sea Level (sea-level ref)
<br>3 = Negative Sea Level (sea-level ref)</span></td></tr>
<tr>
<td title='0x0006 = 6'>0x0006</td>
<td>GPSAltitude</td>
<td class=c>rational64u</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0007 = 7'>0x0007</td>
<td>GPSTimeStamp</td>
<td class=c>rational64u[3]</td>
<td><span class=s><span class=n>(UTC time of GPS fix. When writing, date is stripped off if present, and
time is adjusted to UTC if it includes a timezone)</span></span></td></tr>
<tr>
<td title='0x0008 = 8'>0x0008</td>
<td>GPSSatellites</td>
<td class=c>string</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0009 = 9'>0x0009</td>
<td>GPSStatus</td>
<td class=c>string[2]</td>
<td><span class=s>&#39;A&#39; = Measurement Active
<br>&#39;V&#39; = Measurement Void</span></td></tr>
<tr>
<td title='0x000a = 10'>0x000a</td>
<td>GPSMeasureMode</td>
<td class=c>string[2]</td>
<td><span class=s>2 = 2-Dimensional Measurement
<br>3 = 3-Dimensional Measurement</span></td></tr>
<tr class=b>
<td title='0x000b = 11'>0x000b</td>
<td>GPSDOP</td>
<td class=c>rational64u</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x000c = 12'>0x000c</td>
<td>GPSSpeedRef</td>
<td class=c>string[2]</td>
<td><span class=s>&#39;K&#39; = km/h
<br>&#39;M&#39; = mph
<br>&#39;N&#39; = knots</span></td></tr>
<tr class=b>
<td title='0x000d = 13'>0x000d</td>
<td>GPSSpeed</td>
<td class=c>rational64u</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x000e = 14'>0x000e</td>
<td>GPSTrackRef</td>
<td class=c>string[2]</td>
<td><span class=s>&#39;M&#39; = Magnetic North
<br>&#39;T&#39; = True North</span></td></tr>
<tr class=b>
<td title='0x000f = 15'>0x000f</td>
<td>GPSTrack</td>
<td class=c>rational64u</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0010 = 16'>0x0010</td>
<td>GPSImgDirectionRef</td>
<td class=c>string[2]</td>
<td><span class=s>&#39;M&#39; = Magnetic North
<br>&#39;T&#39; = True North</span></td></tr>
<tr class=b>
<td title='0x0011 = 17'>0x0011</td>
<td>GPSImgDirection</td>
<td class=c>rational64u</td>
<td>&nbsp;</td></tr>
<tr>
<td title='0x0012 = 18'>0x0012</td>
<td>GPSMapDatum</td>
<td class=c>string</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0013 = 19'>0x0013</td>
<td>GPSDestLatitudeRef</td>
<td class=c>string[2]</td>
<td><span class=s><span class=n>(tags 0x0013-0x001a used for subject location according to MWG 2.0)</span>
<br>&#39;N&#39; = North
<br>&#39;S&#39; = South</span></td></tr>
<tr>
<td title='0x0014 = 20'>0x0014</td>
<td>GPSDestLatitude</td>
<td class=c>rational64u[3]</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0015 = 21'>0x0015</td>
<td>GPSDestLongitudeRef</td>
<td class=c>string[2]</td>
<td><span class=s>&#39;E&#39; = East
<br>&#39;W&#39; = West</span></td></tr>
<tr>
<td title='0x0016 = 22'>0x0016</td>
<td>GPSDestLongitude</td>
<td class=c>rational64u[3]</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0017 = 23'>0x0017</td>
<td>GPSDestBearingRef</td>
<td class=c>string[2]</td>
<td><span class=s>&#39;M&#39; = Magnetic North
<br>&#39;T&#39; = True North</span></td></tr>
<tr>
<td title='0x0018 = 24'>0x0018</td>
<td>GPSDestBearing</td>
<td class=c>rational64u</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x0019 = 25'>0x0019</td>
<td>GPSDestDistanceRef</td>
<td class=c>string[2]</td>
<td><span class=s>&#39;K&#39; = Kilometers
<br>&#39;M&#39; = Miles
<br>&#39;N&#39; = Nautical Miles</span></td></tr>
<tr>
<td title='0x001a = 26'>0x001a</td>
<td>GPSDestDistance</td>
<td class=c>rational64u</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x001b = 27'>0x001b</td>
<td>GPSProcessingMethod</td>
<td class=c>undef</td>
<td><span class=s><span class=n>(values of &quot;GPS&quot;, &quot;CELLID&quot;, &quot;WLAN&quot; or &quot;MANUAL&quot; by the EXIF spec.)</span></span></td></tr>
<tr>
<td title='0x001c = 28'>0x001c</td>
<td>GPSAreaInformation</td>
<td class=c>undef</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td title='0x001d = 29'>0x001d</td>
<td>GPSDateStamp</td>
<td class=c>string[11]</td>
<td><span class=s><span class=n>(when writing, time is stripped off if present, after adjusting date/time to
UTC if time includes a timezone. Format is YYYY:mm:dd)</span></span></td></tr>
<tr>
<td title='0x001e = 30'>0x001e</td>
<td>GPSDifferential</td>
<td class=c>int16u</td>
<td><span class=s>0 = No Correction
<br>1 = Differential Corrected</span></td></tr>
<tr class=b>
<td title='0x001f = 31'>0x001f</td>
<td>GPSHPositioningError</td>
<td class=c>rational64u</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Mar 3, 2025</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+906
View File
@@ -0,0 +1,906 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->
<head>
<title>GoPro Tags</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
</head>
<body>
<h2 class=top><a name='GPMF'>GoPro GPMF Tags</a></h2>
<p>Tags extracted from the GPMF box of GoPro MP4 videos, the APP6 &quot;GoPro&quot;
segment of JPEG files, and from the &quot;gpmd&quot; timed metadata if the
<a href="../ExifTool.html#ExtractEmbedded">ExtractEmbedded</a> (-ee) option is enabled. Many more tags exist, but are
currently unknown and extracted only with the <a href="../ExifTool.html#Unknown">Unknown</a> (-u) option. Please
let me know if you discover the meaning of any of these unknown tags. See
<a href="https://github.com/gopro/gpmf-parser">https://github.com/gopro/gpmf-parser</a> for details about this format.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Tag&nbsp;ID</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td>'AALP'</td>
<td>AudioLevel</td>
<td class=c>no</td>
<td><span class=s><span class=n>(dBFS)</span></span></td></tr>
<tr class=b>
<td>'ABSC'</td>
<td>AutoBoostScore</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ACCL'</td>
<td>Accelerometer</td>
<td class=c>no</td>
<td><span class=s><span class=n>(accelerator readings in m/s2)</span></span></td></tr>
<tr class=b>
<td>'ALLD'</td>
<td>AutoLowLightDuration</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'APTO'</td>
<td>AudioProtuneOption</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ARUW'</td>
<td>AspectRatioUnwarped</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ARWA'</td>
<td>AspectRatioWarped</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ATTD'</td>
<td>Attitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ATTR'</td>
<td>AttitudeTarget</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'AUBT'</td>
<td>AudioBlueTooth</td>
<td class=c>no</td>
<td><span class=s>&#39;N&#39; = No
<br>&#39;Y&#39; = Yes</span></td></tr>
<tr>
<td>'AUDO'</td>
<td>AudioSetting</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'AUPT'</td>
<td>AutoProtune</td>
<td class=c>no</td>
<td><span class=s>&#39;N&#39; = No
<br>&#39;Y&#39; = Yes</span></td></tr>
<tr>
<td>'BITR'</td>
<td>BitrateSetting</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'BPOS'</td>
<td>Controller?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'CASN'</td>
<td>CameraSerialNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'CDAT'</td>
<td>CreationDate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'CDTM'</td>
<td>CaptureDelayTimer</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'CLDP'</td>
<td>ClassificationDataPresent</td>
<td class=c>no</td>
<td><span class=s>&#39;N&#39; = No
<br>&#39;Y&#39; = Yes</span></td></tr>
<tr>
<td>'CORI'</td>
<td>CameraOrientation</td>
<td class=c>no</td>
<td><span class=s><span class=n>(quaternions 0-1)</span></span></td></tr>
<tr class=b>
<td>'CPIN'</td>
<td>ChapterNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'CSEN'</td>
<td>CoyoteSense</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'CTRL'</td>
<td>ControlLevel</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'CYTS'</td>
<td>CoyoteStatus</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'DEVC'</td>
<td>DeviceContainer</td>
<td class=c>-</td>
<td>--&gt; <a href='GoPro.html#GPMF'>GoPro GPMF Tags</a></td></tr>
<tr>
<td>'DUST'</td>
<td>DurationSetting</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'DVID'</td>
<td>DeviceID?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'DVNM'</td>
<td>DeviceName</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'DZMX'</td>
<td>DigitalZoomAmount</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'DZOM'</td>
<td>DigitalZoomOn</td>
<td class=c>no</td>
<td><span class=s>&#39;N&#39; = No
<br>&#39;Y&#39; = Yes</span></td></tr>
<tr class=b>
<td>'DZST'</td>
<td>DigitalZoom</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'EISA'</td>
<td>ElectronicImageStabilization</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'EISE'</td>
<td>ElectronicStabilizationOn</td>
<td class=c>no</td>
<td><span class=s>&#39;N&#39; = No
<br>&#39;Y&#39; = Yes</span></td></tr>
<tr>
<td>'EMPT'</td>
<td>Empty?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ESCS'</td>
<td>EscapeStatus?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'EXPT'</td>
<td>ExposureType</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'FACE'</td>
<td>FaceDetected</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'FCNM'</td>
<td>FaceNumbers</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'FMWR'</td>
<td>FirmwareVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'FWVS'</td>
<td>OtherFirmware</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'GLPI'</td>
<td>GPSPos</td>
<td class=c>-</td>
<td>--&gt; <a href='GoPro.html#GLPI'>GoPro GLPI Tags</a></td></tr>
<tr>
<td>'GPRI'</td>
<td>GPSRaw?</td>
<td class=c>-</td>
<td>--&gt; <a href='GoPro.html#GPRI'>GoPro GPRI Tags</a></td></tr>
<tr class=b>
<td>'GPS5'</td>
<td>GPSInfo</td>
<td class=c>-</td>
<td>--&gt; <a href='GoPro.html#GPS5'>GoPro GPS5 Tags</a></td></tr>
<tr>
<td>'GPS9'</td>
<td>GPSInfo9</td>
<td class=c>-</td>
<td>--&gt; <a href='GoPro.html#GPS9'>GoPro GPS9 Tags</a></td></tr>
<tr class=b>
<td>'GPSA'</td>
<td>GPSAltitudeSystem</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'GPSF'</td>
<td>GPSMeasureMode</td>
<td class=c>no</td>
<td><span class=s>2 = 2-Dimensional Measurement
<br>3 = 3-Dimensional Measurement</span></td></tr>
<tr class=b>
<td>'GPSP'</td>
<td>GPSHPositioningError</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'GPSU'</td>
<td>GPSDateTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'GRAV'</td>
<td>GravityVector</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'GYRO'</td>
<td>Gyroscope</td>
<td class=c>no</td>
<td><span class=s><span class=n>(gyroscope readings in rad/s)</span></span></td></tr>
<tr class=b>
<td>'HCTL'</td>
<td>HorizonControl</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'HDRV'</td>
<td>HDRVideo</td>
<td class=c>no</td>
<td><span class=s>&#39;N&#39; = No
<br>&#39;Y&#39; = Yes</span></td></tr>
<tr class=b>
<td>'HSGT'</td>
<td>HindsightSettings</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'HUES'</td>
<td>PredominantHue</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'IORI'</td>
<td>ImageOrientation</td>
<td class=c>no</td>
<td><span class=s><span class=n>(quaternions 0-1)</span></span></td></tr>
<tr>
<td>'ISOE'</td>
<td>ISOSpeeds</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ISOG'</td>
<td>ImageSensorGain</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'KBAT'</td>
<td>BatteryStatus</td>
<td class=c>-</td>
<td>--&gt; <a href='GoPro.html#KBAT'>GoPro KBAT Tags</a></td></tr>
<tr class=b>
<td>'LNED'</td>
<td>LocalPositionNED</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'LOGS'</td>
<td>HealthLogs</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'MAGN'</td>
<td>Magnetometer</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'MAPX'</td>
<td>MappingXCoefficients</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'MAPY'</td>
<td>MappingYCoefficients</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'MINF'</td>
<td>Model</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'MMOD'</td>
<td>MediaMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'MTRX'</td>
<td>AccelerometerMatrix</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'MUID'</td>
<td>MediaUniqueID</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'MWET'</td>
<td>MicrophoneWet</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'MXCF'</td>
<td>MappingXMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'MYCF'</td>
<td>MappingYMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ORDP'</td>
<td>OrientationDataPresent</td>
<td class=c>no</td>
<td><span class=s>&#39;N&#39; = No
<br>&#39;Y&#39; = Yes</span></td></tr>
<tr>
<td>'OREN'</td>
<td>AutoRotation</td>
<td class=c>no</td>
<td><span class=s>&#39;A&#39; = Auto
<br>&#39;D&#39; = Down
<br>&#39;U&#39; = Up</span></td></tr>
<tr class=b>
<td>'ORIN'</td>
<td>InputOrientation</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ORIO'</td>
<td>OutputOrientation</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'PHDR'</td>
<td>HDRSetting</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'PIMD'</td>
<td>ProtuneISOMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'PIMN'</td>
<td>AutoISOMin</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'PIMX'</td>
<td>AutoISOMax</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'POLY'</td>
<td>PolynomialCoefficients</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'PRES'</td>
<td>PhotoResolution</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'PRJT'</td>
<td>LensProjection</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'PRTN'</td>
<td>Protune</td>
<td class=c>no</td>
<td><span class=s>&#39;N&#39; = Off
<br>&#39;Y&#39; = On</span></td></tr>
<tr class=b>
<td>'PTCL'</td>
<td>ColorMode</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'PTEV'</td>
<td>ExposureCompensation</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'PTSH'</td>
<td>Sharpness</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'PTWB'</td>
<td>WhiteBalance</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'PWPR'</td>
<td>PowerProfile</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'PYCF'</td>
<td>PolynomialPower</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'RAMP'</td>
<td>SpeedRampSetting</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'RATE'</td>
<td>Rate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'RMRK'</td>
<td>Comments</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'SCAL'</td>
<td>ScaleFactor?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'SCAP'</td>
<td>ScheduleCapture</td>
<td class=c>no</td>
<td><span class=s>&#39;N&#39; = No
<br>&#39;Y&#39; = Yes</span></td></tr>
<tr>
<td>'SCEN'</td>
<td>SceneClassification</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'SCPR'</td>
<td>ScaledPressure</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'SCTM'</td>
<td>ScheduleCaptureTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'SHUT'</td>
<td>ExposureTimes</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'SIMU'</td>
<td>ScaledIMU</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'SIUN'</td>
<td>SIUnits?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'SMTR'</td>
<td>SpotMeter</td>
<td class=c>no</td>
<td><span class=s>&#39;N&#39; = No
<br>&#39;Y&#39; = Yes</span></td></tr>
<tr class=b>
<td>'SROT'</td>
<td>SensorReadoutTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'STMP'</td>
<td>TimeStamp</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'STNM'</td>
<td>StreamName?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'STRM'</td>
<td>NestedSignalStream</td>
<td class=c>-</td>
<td>--&gt; <a href='GoPro.html#GPMF'>GoPro GPMF Tags</a></td></tr>
<tr class=b>
<td>'SYST'</td>
<td>SystemTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'TIMO'</td>
<td>TimeOffset</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'TMPC'</td>
<td>CameraTemperature</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'TSMP'</td>
<td>TotalSamples?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'TYPE'</td>
<td>StructureType?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'TZON'</td>
<td>TimeZone</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'UNIF'</td>
<td>InputUniformity</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'UNIT'</td>
<td>Units?</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'VERS'</td>
<td>MetadataVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'VFOV'</td>
<td>FieldOfView</td>
<td class=c>no</td>
<td><span class=s>&#39;L&#39; = Linear
<br>&#39;S&#39; = Super View
<br>&#39;W&#39; = Wide</span></td></tr>
<tr class=b>
<td>'VFPS'</td>
<td>VideoFrameRate</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'VFRH'</td>
<td>VisualFlightRulesHUD</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'VRES'</td>
<td>VideoFrameSize</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'WBAL'</td>
<td>ColorTemperatures</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'WNDM'</td>
<td>WindProcessing</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'WRGB'</td>
<td>WhiteBalanceRGB</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'YAVG'</td>
<td>LumaAverage</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td>'ZFOV'</td>
<td>DiagonalFieldOfView</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td>'ZMPL'</td>
<td>ZoomScaleNormalization</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='GLPI'>GoPro GLPI Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>GPSDateTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>GPSLatitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>GPSLongitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>GPSAltitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='5 = 0x5'>5</td>
<td>GPSSpeedX</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>GPSSpeedY</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='7 = 0x7'>7</td>
<td>GPSSpeedZ</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='8 = 0x8'>8</td>
<td>GPSTrack</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='GPRI'>GoPro GPRI Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>GPSDateTimeRaw</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>GPSLatitudeRaw</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>GPSLongitudeRaw</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>GPSAltitudeRaw</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='6 = 0x6'>6</td>
<td>GPSSpeedRaw</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='7 = 0x7'>7</td>
<td>GPSTrackRaw</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='GPS5'>GoPro GPS5 Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>GPSLatitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>GPSLongitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>GPSAltitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>GPSSpeed</td>
<td class=c>no</td>
<td><span class=s><span class=n>(stored as m/s but converted to km/h when extracted)</span></span></td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>GPSSpeed3D</td>
<td class=c>no</td>
<td><span class=s><span class=n>(stored as m/s but converted to km/h when extracted)</span></span></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='GPS9'>GoPro GPS9 Tags</a></h2>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>GPSLatitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>GPSLongitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='2 = 0x2'>2</td>
<td>GPSAltitude</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='3 = 0x3'>3</td>
<td>GPSSpeed</td>
<td class=c>no</td>
<td><span class=s><span class=n>(stored as m/s but converted to km/h when extracted)</span></span></td></tr>
<tr>
<td class=r title='4 = 0x4'>4</td>
<td>GPSSpeed3D</td>
<td class=c>no</td>
<td><span class=s><span class=n>(stored as m/s but converted to km/h when extracted)</span></span></td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>GPSDateTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='7 = 0x7'>7</td>
<td>GPSDOP</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='8 = 0x8'>8</td>
<td>GPSMeasureMode</td>
<td class=c>no</td>
<td><span class=s>2 = 2-Dimensional Measurement
<br>3 = 3-Dimensional Measurement</span></td></tr>
</table></td></tr></table></blockquote>
<h2><a name='KBAT'>GoPro KBAT Tags</a></h2>
<p>Battery status information found in GoPro Karma videos.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='0 = 0x0'>0</td>
<td>BatteryCurrent</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='1 = 0x1'>1</td>
<td>BatteryCapacity</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='3 = 0x3'>3</td>
<td>BatteryTemperature</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='4 = 0x4'>4</td>
<td>BatteryVoltage1</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='5 = 0x5'>5</td>
<td>BatteryVoltage2</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='6 = 0x6'>6</td>
<td>BatteryVoltage3</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='7 = 0x7'>7</td>
<td>BatteryVoltage4</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='8 = 0x8'>8</td>
<td>BatteryTime</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='14 = 0xe'>14</td>
<td>BatteryLevel</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<h2><a name='fdsc'>GoPro fdsc Tags</a></h2>
<p>Tags extracted from the MP4 &quot;fdsc&quot; timed metadata when the <a href="../ExifTool.html#ExtractEmbedded">ExtractEmbedded</a>
(-ee) option is used.</p>
<blockquote>
<table class=frame><tr><td>
<table class=inner cellspacing=1>
<tr class=h><th>Index1</th><th>Tag Name</th>
<th>Writable</th><th>Values / <span class=n>Notes</span></th></tr>
<tr>
<td class=r title='8 = 0x8'>8</td>
<td>FirmwareVersion</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='23 = 0x17'>23</td>
<td>SerialNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr>
<td class=r title='87 = 0x57'>87</td>
<td>OtherSerialNumber</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
<tr class=b>
<td class=r title='102 = 0x66'>102</td>
<td>Model</td>
<td class=c>no</td>
<td>&nbsp;</td></tr>
</table></td></tr></table></blockquote>
<hr>
(This document generated automatically by Image::ExifTool::BuildTagLookup)
<br><i>Last revised Sep 26, 2025</i>
<p class=lf><a href='index.html'>&lt;-- ExifTool Tag Names</a></p>
</body>
</html>
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More