You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-10-06 05:47:18 +02:00
This makes the functions extensible, as future behavior change flags can be introduced. This is strictly speaking not an API break. Only if a user was setting recursive to anything other than 1 it would now behave differently, but given these functions have been in the tree for only a few days, the chances for that are practically zero. Signed-off-by: James Almer <jamrial@gmail.com>
230 lines
7.4 KiB
C
230 lines
7.4 KiB
C
/*
|
|
* EXIF metadata parser
|
|
* Copyright (c) 2013 Thilo Borgmann <thilo.borgmann _at_ mail.de>
|
|
* Copyright (c) 2024-2025 Leo Izen <leo.izen@gmail.com>
|
|
*
|
|
* This file is part of FFmpeg.
|
|
*
|
|
* FFmpeg is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* FFmpeg is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with FFmpeg; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* EXIF metadata parser
|
|
* @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
|
|
* @author Leo Izen <leo.izen@gmail.com>
|
|
*/
|
|
|
|
#ifndef AVCODEC_EXIF_H
|
|
#define AVCODEC_EXIF_H
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include "libavutil/buffer.h"
|
|
#include "libavutil/dict.h"
|
|
#include "libavutil/rational.h"
|
|
#include "version_major.h"
|
|
|
|
/** Data type identifiers for TIFF tags */
|
|
enum AVTiffDataType {
|
|
AV_TIFF_BYTE = 1,
|
|
AV_TIFF_STRING,
|
|
AV_TIFF_SHORT,
|
|
AV_TIFF_LONG,
|
|
AV_TIFF_RATIONAL,
|
|
AV_TIFF_SBYTE,
|
|
AV_TIFF_UNDEFINED,
|
|
AV_TIFF_SSHORT,
|
|
AV_TIFF_SLONG,
|
|
AV_TIFF_SRATIONAL,
|
|
AV_TIFF_FLOAT,
|
|
AV_TIFF_DOUBLE,
|
|
AV_TIFF_IFD,
|
|
};
|
|
|
|
enum AVExifHeaderMode {
|
|
/**
|
|
* The TIFF header starts with 0x49492a00, or 0x4d4d002a.
|
|
* This one is used internally by FFmpeg.
|
|
*/
|
|
AV_EXIF_TIFF_HEADER,
|
|
/** skip the TIFF header, assume little endian */
|
|
AV_EXIF_ASSUME_LE,
|
|
/** skip the TIFF header, assume big endian */
|
|
AV_EXIF_ASSUME_BE,
|
|
/** The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER */
|
|
AV_EXIF_T_OFF,
|
|
/** The first six bytes contain "Exif\0\0", then it's AV_EXIF_TIFF_HEADER */
|
|
AV_EXIF_EXIF00,
|
|
};
|
|
|
|
typedef struct AVExifEntry AVExifEntry;
|
|
|
|
typedef struct AVExifMetadata {
|
|
/* array of EXIF metadata entries */
|
|
AVExifEntry *entries;
|
|
/* number of entries in this array */
|
|
unsigned int count;
|
|
/* size of the buffer, used for av_fast_realloc */
|
|
unsigned int size;
|
|
} AVExifMetadata;
|
|
|
|
struct AVExifEntry {
|
|
uint16_t id;
|
|
enum AVTiffDataType type;
|
|
uint32_t count;
|
|
|
|
/*
|
|
* These are for IFD-style MakerNote
|
|
* entries which occur after a fixed
|
|
* offset rather than at the start of
|
|
* the entry. The ifd_lead field contains
|
|
* the leading bytes which typically
|
|
* identify the type of MakerNote.
|
|
*/
|
|
uint32_t ifd_offset;
|
|
uint8_t *ifd_lead;
|
|
|
|
/*
|
|
* An array of entries of size count
|
|
* Unless it's an IFD, in which case
|
|
* it's not an array and count = 1
|
|
*/
|
|
union {
|
|
void *ptr;
|
|
int64_t *sint;
|
|
uint64_t *uint;
|
|
double *dbl;
|
|
char *str;
|
|
uint8_t *ubytes;
|
|
int8_t *sbytes;
|
|
AVRational *rat;
|
|
AVExifMetadata ifd;
|
|
} value;
|
|
};
|
|
|
|
/**
|
|
* Retrieves the tag name associated with the provided tag ID.
|
|
* If the tag ID is unknown, NULL is returned.
|
|
*
|
|
* For example, av_exif_get_tag_name(0x112) returns "Orientation".
|
|
*/
|
|
const char *av_exif_get_tag_name(uint16_t id);
|
|
|
|
/**
|
|
* Retrieves the tag ID associated with the provided tag string name.
|
|
* If the tag name is unknown, a negative number is returned. Otherwise
|
|
* it always fits inside a uint16_t integer.
|
|
*
|
|
* For example, av_exif_get_tag_id("Orientation") returns 274 (0x0112).
|
|
*/
|
|
int32_t av_exif_get_tag_id(const char *name);
|
|
|
|
/**
|
|
* Add an entry to the provided EXIF metadata struct. If one already exists with the provided
|
|
* ID, it will set the existing one to have the other information provided. Otherwise, it
|
|
* will allocate a new entry.
|
|
*
|
|
* This function reallocates ifd->entries using av_realloc and allocates (using av_malloc)
|
|
* a new value member of the entry, then copies the contents of value into that buffer.
|
|
*/
|
|
int av_exif_set_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, enum AVTiffDataType type,
|
|
uint32_t count, const uint8_t *ifd_lead, uint32_t ifd_offset, const void *value);
|
|
|
|
/**
|
|
* Also check subdirectories.
|
|
*/
|
|
#define AV_EXIF_FLAG_RECURSIVE (1 << 0)
|
|
|
|
/**
|
|
* Get an entry with the tagged ID from the EXIF metadata struct. A pointer to the entry
|
|
* will be written into *value.
|
|
*
|
|
* If the entry was present and returned successfully, a positive number is returned.
|
|
* If the entry was not found, *value is left untouched and zero is returned.
|
|
* If an error occurred, a negative number is returned.
|
|
*/
|
|
int av_exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags, AVExifEntry **value);
|
|
|
|
/**
|
|
* Remove an entry from the provided EXIF metadata struct.
|
|
*
|
|
* If the entry was present and removed successfully, a positive number is returned.
|
|
* If the entry was not found, zero is returned.
|
|
* If an error occurred, a negative number is returned.
|
|
*/
|
|
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags);
|
|
|
|
/**
|
|
* Decodes the EXIF data provided in the buffer and writes it into the
|
|
* struct *ifd. If this function succeeds, the IFD is owned by the caller
|
|
* and must be cleared after use by calling av_exif_free(); If this function
|
|
* fails and returns a negative value, it will call av_exif_free(ifd) before
|
|
* returning.
|
|
*/
|
|
int av_exif_parse_buffer(void *logctx, const uint8_t *data, size_t size,
|
|
AVExifMetadata *ifd, enum AVExifHeaderMode header_mode);
|
|
|
|
/**
|
|
* Allocates a buffer using av_malloc of an appropriate size and writes the
|
|
* EXIF data represented by ifd into that buffer.
|
|
*
|
|
* Upon error, *buffer will be NULL. The buffer becomes owned by the caller upon
|
|
* success. The *buffer argument must be NULL before calling.
|
|
*/
|
|
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode);
|
|
|
|
/**
|
|
* Frees all resources associated with the given EXIF metadata struct.
|
|
* Does not free the pointer passed itself, in case it is stack-allocated.
|
|
* The pointer passed to this function must be freed by the caller,
|
|
* if it is heap-allocated. Passing NULL is permitted.
|
|
*/
|
|
void av_exif_free(AVExifMetadata *ifd);
|
|
|
|
/**
|
|
* Recursively reads all tags from the IFD and stores them in the
|
|
* provided metadata dictionary.
|
|
*/
|
|
int av_exif_ifd_to_dict(void *logctx, const AVExifMetadata *ifd, AVDictionary **metadata);
|
|
|
|
/**
|
|
* Allocates a duplicate of the provided EXIF metadata struct. The caller owns
|
|
* the duplicate and must free it with av_exif_free. Returns NULL if the duplication
|
|
* process failed.
|
|
*/
|
|
AVExifMetadata *av_exif_clone_ifd(const AVExifMetadata *ifd);
|
|
|
|
/**
|
|
* Convert a display matrix used by AV_FRAME_DATA_DISPLAYMATRIX
|
|
* into an orientation constant used by EXIF's orientation tag.
|
|
*
|
|
* Returns an EXIF orientation between 1 and 8 (inclusive) depending
|
|
* on the rotation and flip factors. Returns 0 if the matrix is singular.
|
|
*/
|
|
int av_exif_matrix_to_orientation(const int32_t *matrix);
|
|
|
|
/**
|
|
* Convert an orientation constant used by EXIF's orientation tag
|
|
* into a display matrix used by AV_FRAME_DATA_DISPLAYMATRIX.
|
|
*
|
|
* Returns 0 on success and negative if the orientation is invalid,
|
|
* i.e. not between 1 and 8 (inclusive).
|
|
*/
|
|
int av_exif_orientation_to_matrix(int32_t *matrix, int orientation);
|
|
|
|
#endif /* AVCODEC_EXIF_H */
|