diff options
| -rw-r--r-- | fastiv-io.c | 46 | ||||
| -rw-r--r-- | fastiv-io.h | 17 | 
2 files changed, 63 insertions, 0 deletions
| diff --git a/fastiv-io.c b/fastiv-io.c index f76e817..c16c61d 100644 --- a/fastiv-io.c +++ b/fastiv-io.c @@ -1123,6 +1123,52 @@ fastiv_io_open_from_data(const char *data, size_t len, const gchar *path,  	return surface;  } +// --- Metadata ---------------------------------------------------------------- + +FastivIoOrientation +fastiv_io_exif_orientation(const guint8 *tiff, gsize len) +{ +	// libtiff also knows how to do this, but it's not a lot of code. +	// The "Orientation" tag/field is part of Baseline TIFF 6.0 (1992), +	// it just so happens that Exif is derived from this format. +	// There is no other meaningful placement for this than right in IFD0, +	// describing the main image. +	const uint8_t *end = tiff + len, +		le[4] = {'I', 'I', 42, 0}, +		be[4] = {'M', 'M', 0, 42}; + +	uint16_t (*u16)(const uint8_t *) = NULL; +	uint32_t (*u32)(const uint8_t *) = NULL; +	if (tiff + 8 > end) { +		return FastivIoOrientationUnknown; +	} else if (!memcmp(tiff, le, sizeof le)) { +		u16 = wuffs_base__peek_u16le__no_bounds_check; +		u32 = wuffs_base__peek_u32le__no_bounds_check; +	} else if (!memcmp(tiff, be, sizeof be)) { +		u16 = wuffs_base__peek_u16be__no_bounds_check; +		u32 = wuffs_base__peek_u32be__no_bounds_check; +	} else { +		return FastivIoOrientationUnknown; +	} + +	const uint8_t *ifd0 = tiff + u32(tiff + 4); +	if (ifd0 + 2 > end) +		return FastivIoOrientationUnknown; + +	uint16_t fields = u16(ifd0); +	enum { BYTE = 1, ASCII, SHORT, LONG, RATIONAL, +		SBYTE, UNDEFINED, SSHORT, SLONG, SRATIONAL, FLOAT, DOUBLE }; +	enum { Orientation = 274 }; +	for (const guint8 *p = ifd0 + 2; fields-- && p + 12 <= end; p += 12) { +		uint16_t tag = u16(p), type = u16(p + 2); +		uint32_t count = u32(p + 4), value = u32(p + 8); +		if (tag == Orientation && type == SHORT && count == 1 && +			value >= 1 && value <= 8) +			return value; +	} +	return FastivIoOrientationUnknown; +} +  // --- Thumbnails --------------------------------------------------------------  GType diff --git a/fastiv-io.h b/fastiv-io.h index 3aed342..a611078 100644 --- a/fastiv-io.h +++ b/fastiv-io.h @@ -46,6 +46,23 @@ cairo_surface_t *fastiv_io_open_from_data(  int fastiv_io_filecmp(GFile *f1, GFile *f2); +// --- Metadata ---------------------------------------------------------------- + +// https://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf Table 6 +typedef enum _FastivIoOrientation { +	FastivIoOrientationUnknown   = 0, +	FastivIoOrientation0         = 1, +	FastivIoOrientationMirror0   = 2, +	FastivIoOrientation180       = 3, +	FastivIoOrientationMirror180 = 4, +	FastivIoOrientationMirror90  = 5, +	FastivIoOrientation90        = 6, +	FastivIoOrientationMirror270 = 7, +	FastivIoOrientation270       = 8 +} FastivIoOrientation; + +FastivIoOrientation fastiv_io_exif_orientation(const guint8 *exif, gsize len); +  // --- Thumbnails --------------------------------------------------------------  // And this is how you avoid glib-mkenums. | 
