or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

encoding.mdfile-operations.mdimage-classes.mdindex.mdmetadata-utilities.mdpillow-integration.md

metadata-utilities.mddocs/

0

# Metadata and Utilities

1

2

Helper functions for MIME type detection, orientation handling, library information, and plugin loading. These utilities provide essential support functionality for HEIF/AVIF processing and integration with the broader image processing ecosystem.

3

4

## Capabilities

5

6

### MIME Type Detection

7

8

Determines the MIME type of HEIF/AVIF files for proper content type handling and format identification.

9

10

```python { .api }

11

def get_file_mimetype(fp) -> str:

12

"""

13

Determine MIME type of HEIF/AVIF file.

14

15

Parameters:

16

- fp: file path (str) or file-like object

17

18

Returns:

19

str: MIME type string ('image/heif', 'image/avif', or empty string if not supported)

20

21

Notes:

22

- Fast detection based on file signature

23

- Returns empty string for unsupported formats

24

- Useful for web applications and content type headers

25

"""

26

```

27

28

Usage example:

29

```python

30

import pillow_heif

31

32

# Check MIME type of various files

33

files = ["image.heic", "photo.avif", "unknown.jpg"]

34

35

for filepath in files:

36

mimetype = pillow_heif.get_file_mimetype(filepath)

37

if mimetype:

38

print(f"{filepath}: {mimetype}")

39

else:

40

print(f"{filepath}: Not a HEIF/AVIF file")

41

42

# Web application usage

43

def get_content_type(filepath):

44

"""Get appropriate content type for web responses."""

45

mimetype = pillow_heif.get_file_mimetype(filepath)

46

return mimetype if mimetype else "application/octet-stream"

47

```

48

49

### EXIF Orientation Handling

50

51

Resets EXIF orientation metadata to default value, useful for correcting orientation-related display issues.

52

53

```python { .api }

54

def set_orientation(info: dict) -> int | None:

55

"""

56

Reset EXIF orientation metadata to default (1).

57

58

Parameters:

59

- info: dict, image metadata dictionary containing EXIF data

60

61

Returns:

62

int | None: Previous orientation value, or None if no EXIF data present

63

64

Notes:

65

- Modifies the info dictionary in-place

66

- Sets orientation to 1 (normal, no rotation)

67

- Useful after applying rotation corrections

68

"""

69

```

70

71

Usage example:

72

```python

73

import pillow_heif

74

75

# Open image and check orientation

76

heif_file = pillow_heif.open_heif("rotated_photo.heic")

77

print(f"Metadata keys: {list(heif_file.info.keys())}")

78

79

# Reset orientation if present

80

if 'exif' in heif_file.info:

81

old_orientation = pillow_heif.set_orientation(heif_file.info)

82

if old_orientation:

83

print(f"Reset orientation from {old_orientation} to 1")

84

85

# Save with corrected orientation

86

heif_file.save("corrected_photo.heic")

87

88

# Function to auto-correct orientation

89

def correct_orientation(heif_file):

90

"""Auto-correct image orientation using EXIF data."""

91

if 'exif' in heif_file.info:

92

# Apply rotation based on EXIF before resetting

93

pil_image = heif_file.to_pillow()

94

95

# PIL automatically handles EXIF orientation

96

# Reset EXIF to prevent double-correction

97

pillow_heif.set_orientation(heif_file.info)

98

99

return pillow_heif.from_pillow(pil_image)

100

return heif_file

101

```

102

103

### Library Information

104

105

Functions to retrieve version and capability information about the underlying libheif library.

106

107

```python { .api }

108

def libheif_version() -> str:

109

"""

110

Get version string of underlying libheif library.

111

112

Returns:

113

str: Version string (e.g., "1.17.6")

114

115

Notes:

116

- Returns the version of the C library, not the Python bindings

117

- Useful for compatibility checking and debugging

118

"""

119

120

def libheif_info() -> dict:

121

"""

122

Get comprehensive information about libheif capabilities.

123

124

Returns:

125

dict: Information dictionary with keys:

126

- 'version': str, libheif version

127

- 'encoders': list, available encoder names

128

- 'decoders': list, available decoder names

129

- 'builtin_encoders': list, built-in encoder names

130

- 'builtin_decoders': list, built-in decoder names

131

132

Notes:

133

- Encoder/decoder availability depends on compile-time options

134

- Plugin encoders/decoders loaded at runtime are included

135

"""

136

```

137

138

Usage example:

139

```python

140

import pillow_heif

141

import json

142

143

# Check library version

144

version = pillow_heif.libheif_version()

145

print(f"libheif version: {version}")

146

147

# Get detailed capability information

148

info = pillow_heif.libheif_info()

149

print("Library capabilities:")

150

print(json.dumps(info, indent=2))

151

152

# Check for specific encoder support

153

if 'x265' in info.get('encoders', []):

154

print("x265 HEIF encoder available")

155

if 'aom' in info.get('encoders', []):

156

print("AOM AV1 encoder available for AVIF")

157

158

# Conditional functionality based on capabilities

159

def get_available_formats():

160

"""Get list of supported output formats."""

161

info = pillow_heif.libheif_info()

162

formats = []

163

164

if any('heif' in enc.lower() for enc in info.get('encoders', [])):

165

formats.append('HEIF')

166

if any('av1' in enc.lower() or 'aom' in enc.lower()

167

for enc in info.get('encoders', [])):

168

formats.append('AVIF')

169

170

return formats

171

172

print(f"Available output formats: {get_available_formats()}")

173

```

174

175

### Plugin Loading

176

177

Loads additional libheif plugins for extended format support and codec capabilities.

178

179

```python { .api }

180

def load_libheif_plugin(plugin_path: str) -> None:

181

"""

182

Load specified LibHeif plugin for extended format support.

183

184

Parameters:

185

- plugin_path: str, path to plugin library file

186

187

Notes:

188

- Extends encoder/decoder capabilities at runtime

189

- Plugin path must point to valid libheif plugin library

190

- Changes are reflected in libheif_info() output after loading

191

192

Raises:

193

OSError: If plugin cannot be loaded or is invalid

194

"""

195

```

196

197

Usage example:

198

```python

199

import pillow_heif

200

import os

201

202

# Check capabilities before loading plugins

203

info_before = pillow_heif.libheif_info()

204

print(f"Encoders before: {info_before.get('encoders', [])}")

205

206

# Load additional plugin (example path)

207

plugin_path = "/usr/local/lib/libheif/plugins/libheif-x265.so"

208

if os.path.exists(plugin_path):

209

try:

210

pillow_heif.load_libheif_plugin(plugin_path)

211

print(f"Successfully loaded plugin: {plugin_path}")

212

213

# Check updated capabilities

214

info_after = pillow_heif.libheif_info()

215

new_encoders = set(info_after.get('encoders', [])) - set(info_before.get('encoders', []))

216

if new_encoders:

217

print(f"New encoders available: {list(new_encoders)}")

218

219

except OSError as e:

220

print(f"Failed to load plugin: {e}")

221

222

# Batch plugin loading

223

def load_available_plugins(plugin_dir="/usr/local/lib/libheif/plugins"):

224

"""Load all available plugins from directory."""

225

if not os.path.exists(plugin_dir):

226

return

227

228

for filename in os.listdir(plugin_dir):

229

if filename.endswith(('.so', '.dll', '.dylib')):

230

plugin_path = os.path.join(plugin_dir, filename)

231

try:

232

pillow_heif.load_libheif_plugin(plugin_path)

233

print(f"Loaded: {filename}")

234

except OSError:

235

print(f"Failed to load: {filename}")

236

```

237

238

## Configuration Options Module

239

240

Runtime configuration variables that control library behavior, available in the `pillow_heif.options` module.

241

242

```python { .api }

243

# Threading configuration

244

DECODE_THREADS = 4 # Maximum threads for image decoding

245

246

# Feature toggles

247

THUMBNAILS = True # Enable/disable thumbnail support

248

DEPTH_IMAGES = True # Enable/disable depth image support

249

AUX_IMAGES = True # Enable/disable auxiliary image support

250

251

# Encoding defaults

252

QUALITY = None # Default encoding quality (None, -1, or 0-100)

253

SAVE_HDR_TO_12_BIT = False # Save 16-bit images as 12-bit vs 10-bit

254

SAVE_NCLX_PROFILE = True # Save NCLX color profiles

255

256

# Codec preferences

257

PREFERRED_ENCODER = {"AVIF": "", "HEIF": ""} # Preferred encoder IDs

258

PREFERRED_DECODER = {"AVIF": "", "HEIF": ""} # Preferred decoder IDs

259

260

# Security and compatibility

261

ALLOW_INCORRECT_HEADERS = False # Allow size mismatch in headers

262

DISABLE_SECURITY_LIMITS = False # Disable libheif security limits

263

```

264

265

Usage example:

266

```python

267

import pillow_heif

268

269

# Configure threading

270

pillow_heif.options.DECODE_THREADS = 8 # Use more threads for faster decoding

271

272

# Disable features for memory savings

273

pillow_heif.options.THUMBNAILS = False

274

pillow_heif.options.DEPTH_IMAGES = False

275

276

# Set default quality

277

pillow_heif.options.QUALITY = 85

278

279

# Configure HDR handling

280

pillow_heif.options.SAVE_HDR_TO_12_BIT = True

281

282

# Set encoder preferences

283

pillow_heif.options.PREFERRED_ENCODER["HEIF"] = "x265"

284

pillow_heif.options.PREFERRED_ENCODER["AVIF"] = "aom"

285

286

# Now all operations use these settings

287

heif_file = pillow_heif.open_heif("image.heic") # Uses 8 decode threads

288

heif_file.save("output.heic") # Uses quality=85, x265 encoder

289

```

290

291

## Color Space Enumerations

292

293

Enumeration types for color space and metadata handling, extending Python's IntEnum.

294

295

```python { .api }

296

class HeifColorPrimaries(IntEnum):

297

"""NCLX color primaries definitions for proper color reproduction."""

298

ITU_R_BT_709_5 = 1

299

UNSPECIFIED = 2

300

ITU_R_BT_470_6_SYSTEM_M = 4

301

ITU_R_BT_470_6_SYSTEM_B_G = 5

302

ITU_R_BT_601_6 = 6

303

SMPTE_240M = 7

304

GENERIC_FILM = 8

305

ITU_R_BT_2020_2_AND_2100_0 = 9

306

SMPTE_ST_428_1 = 10

307

SMPTE_RP_431_2 = 11

308

SMPTE_EG_432_1 = 12

309

EBU_TECH_3213_E = 22

310

311

class HeifTransferCharacteristics(IntEnum):

312

"""NCLX transfer characteristics for gamma/transfer functions."""

313

ITU_R_BT_709_5 = 1

314

UNSPECIFIED = 2

315

ITU_R_BT_470_6_SYSTEM_M = 4

316

ITU_R_BT_470_6_SYSTEM_B_G = 5

317

ITU_R_BT_601_6 = 6

318

SMPTE_240M = 7

319

LINEAR = 8

320

LOGARITHMIC_100 = 9

321

LOGARITHMIC_100_SQRT10 = 10

322

IEC_61966_2_4 = 11

323

ITU_R_BT_1361 = 12

324

IEC_61966_2_1 = 13

325

ITU_R_BT_2020_2_10BIT = 14

326

ITU_R_BT_2020_2_12BIT = 15

327

ITU_R_BT_2100_0_PQ = 16

328

SMPTE_ST_428_1 = 17

329

ITU_R_BT_2100_0_HLG = 18

330

331

class HeifMatrixCoefficients(IntEnum):

332

"""NCLX matrix coefficients for color space conversion."""

333

RGB_GBR = 0

334

ITU_R_BT_709_5 = 1

335

UNSPECIFIED = 2

336

US_FCC_T47 = 4

337

ITU_R_BT_470_6_SYSTEM_B_G = 5

338

ITU_R_BT_601_6 = 6

339

SMPTE_240M = 7

340

YCGCO = 8

341

ITU_R_BT_2020_2_NON_CONSTANT_LUMINANCE = 9

342

ITU_R_BT_2020_2_CONSTANT_LUMINANCE = 10

343

SMPTE_ST_2085 = 11

344

CHROMATICITY_DERIVED_NON_CONSTANT_LUMINANCE = 12

345

CHROMATICITY_DERIVED_CONSTANT_LUMINANCE = 13

346

ICTCP = 14

347

348

class HeifDepthRepresentationType(IntEnum):

349

"""Depth image representation types."""

350

UNIFORM_INVERSE_Z = 0

351

UNIFORM_DISPARITY = 1

352

UNIFORM_Z = 2

353

NON_UNIFORM_DISPARITY = 3

354

```

355

356

Usage example:

357

```python

358

import pillow_heif

359

from pillow_heif import HeifColorPrimaries, HeifTransferCharacteristics

360

361

# Working with color space metadata

362

heif_file = pillow_heif.open_heif("hdr_image.heic")

363

364

# Check color space information in metadata

365

if 'nclx_profile' in heif_file.info:

366

nclx = heif_file.info['nclx_profile']

367

368

# Use enums for color space interpretation

369

if nclx.get('color_primaries') == HeifColorPrimaries.ITU_R_BT_2020_2_AND_2100_0:

370

print("Image uses BT.2020 color primaries (wide color gamut)")

371

372

if nclx.get('transfer_characteristics') == HeifTransferCharacteristics.ITU_R_BT_2100_0_PQ:

373

print("Image uses PQ transfer characteristics (HDR)")

374

375

# Setting color space for encoding

376

encoding_options = {

377

'nclx_profile': {

378

'color_primaries': HeifColorPrimaries.ITU_R_BT_709_5,

379

'transfer_characteristics': HeifTransferCharacteristics.ITU_R_BT_709_5,

380

'matrix_coefficients': pillow_heif.HeifMatrixCoefficients.ITU_R_BT_709_5,

381

'full_range': True

382

}

383

}

384

385

heif_file.save("srgb_image.heic", **encoding_options)

386

```