Explore Our libfotodb
Fast. Lightweight. Production-Proven.
Effortlessly read, modify, and write EXIF metadata in JPEG images without re-encoding image binary data or pulling in heavy dependencies.
Featured inWhy libfotodb?
Most EXIF solutions are either heavy, read-only, or require bulky external dependencies that inflate your app binary. libfotodb was engineered in low-level C to deliver maximum performance and a minimal memory footprint across desktop, mobile, and embedded platforms.
-
Write and update tags (GPS, Camera settings, Timestamps, Custom Metadata) safely without corrupting image payloads.
-
Native C build with no bloated third-party requirements. Easy to compile statically or dynamically.
-
Adds negligible size to your final release binary—ideal for mobile (Android/iOS) and resource-constrained environments.
-
Clean C interface designed for seamless interoperability with Dart/Flutter, Python, Rust, and C++.
-
libfotodb isn't theoretical code—it powers fotodb: EXIF Photo Organizer on Android. It handles real-world photo files, varying device formats, and strict OS constraints every day.
Target Platforms: Android (NDK arm64-v8a, armeabi-v7a, x86_64), Linux, iOS, macOS.
C API Reference (fotodb.h)
Full EXIF Write & Delete Support (fdbSetX / fdbDeleteX)
//
// Copyright (c) 2023 Oguz Kupusoglu. All rights reserved.
//
// IN NO EVENT SHALL OGUZ KUPUSOGLU BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
// LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
// EVEN IF OGUZ KUPUSOGLU HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
#ifndef FOTODB_H
#define FOTODB_H
#include <stdbool.h>
#include <stdint.h>
#define EXPORTED __attribute__((__visibility__("default")))
///////////////////////////////////////////////////////////////////////////////////////////////////
typedef enum : int32_t {
UNKNOWN_ALTITUDE_REF = 0, // default
ABOVE_SEA_LEVEL = 1,
BELOW_SEA_LEVEL = 2
} FdbAltitudeRef;
typedef enum : int32_t {
UNKNOWN_IMAGE_DIRECTION_REF = 0, // default
TRUE_DIRECTION = 1,
MAGNETIC_DIRECTION = 2
} FdbImageDirectionRef;
typedef enum : int32_t {
BIG_ENDIAN = 0, // default
LITTLE_ENDIAN = 1
} FdbByteOrder;
//
// see:
// Exif Orientation Tag (Feb 17 2002)
// http://sylvana.net/jpegcrop/exif_orientation.html
//
// see:
// EXIF Orientation Handling Is a Ghetto
// http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/
//
// see:
// UIImageOrientation / EXIF orientation sample images
// http://www.galloway.me.uk/2012/01/uiimageorientation-exif-orientation-sample-images/
//
// note that the symbols are named in the WhatIsInRow0_WhatIsInColumn0 pattern
//
typedef enum : int32_t {
UNKNOWN_ORIENTATION = 0, // default: Orientation is not specified
TOP_LEFT = 1, // row0: visual top of the image
// column0: visual left-hand side of the image
// rotation necessary: none
TOP_RIGHT = 2, // row0: visual top of the image
// column0: visual right-hand side of the image
// rotation necessary: reverse horizontally
BOTTOM_RIGHT = 3, // row0: visual bottom of the image
// column0: visual right-hand side of the image
// rotation necessary: clockwise 180 degrees
BOTTOM_LEFT = 4, // row0: visual bottom of the image
// column0: visual left-hand side of the image
// rotation necessary: reverse vertically
LEFT_TOP = 5, // row0: visual left-hand side of the image
// column0: visual top of the image
// rotation necessary: clockwise 90 degrees and
// reverse horizontally
RIGHT_TOP = 6, // row0: visual right-hand side of the image
// column0: visual top of the image
// rotation necessary: clockwise 90 degrees
RIGHT_BOTTOM = 7, // row0: visual right-hand side of the image
// column0: visual bottom of the image
// rotation necessary: counter clockwise 90 degrees and
// reverse horizontally
LEFT_BOTTOM = 8, // row0: visual left-hand side of the image
// column0: visual bottom of the image
// rotation necessary: counter clockwise 90 degrees
} FdbOrientation;
typedef struct {
int length;
char* bytes;
} FdbData;
typedef struct {
int numerator;
int denominator;
} FdbRational;
typedef struct {
double latitude;
double longitude;
FdbAltitudeRef altitude_ref; // default UNKNOWN_ALTITUDE_REF
double altitude; // default 0.0
FdbImageDirectionRef img_direction_ref; // default UNKNOWN_IMAGE_DIRECTION_REF
double img_direction; // default 0.0
} FdbGps;
///////////////////////////////////////////////////////////////////////////////////////////////////
EXPORTED bool fdbInit(const char* const key);
EXPORTED bool fdbOpenPhoto(const char* filename);
EXPORTED bool fdbLoadPhoto(const FdbData* dataptr);
EXPORTED bool fdbHasExif();
EXPORTED void fdbClosePhoto();
EXPORTED void fdbClearData(FdbData* dataptr);
EXPORTED int fdbGetPhotoSize();
EXPORTED FdbByteOrder fdbGetExifByteOrder();
EXPORTED bool fdbGetPhotoWithoutExif(FdbData* dataptr);
EXPORTED bool fdbGetMake(FdbData* dataptr);
EXPORTED bool fdbGetModel(FdbData* dataptr);
EXPORTED bool fdbGetDateTime(FdbData* dataptr);
EXPORTED bool fdbGetTimeZone(FdbData* dataptr);
EXPORTED bool fdbGetFlashFired(bool* flashptr);
EXPORTED bool fdbGetPhotoDimensions(int* widthptr, int* heightptr);
EXPORTED bool fdbGetPhotoOrientation(FdbOrientation* orientationptr);
EXPORTED bool fdbGetShutterSpeedValue(FdbRational* rationalptr);
EXPORTED bool fdbGetPhoto(FdbData* dataptr);
EXPORTED bool fdbGetThumbnail(FdbData* dataptr);
EXPORTED bool fdbGetGps(FdbGps* gpsptr);
EXPORTED bool fdbDeleteGps();
EXPORTED bool fdbGetUserComment(FdbData* dataptr);
// always terminates the user comment with a null char
EXPORTED bool fdbSetUserComment(const char* byteptr);
EXPORTED bool fdbDeleteUserComment();
EXPORTED bool fdbGetCopyright(FdbData* dataptr);
EXPORTED bool fdbSetCopyright(const char* byteptr);
EXPORTED bool fdbDeleteCopyright();
EXPORTED bool fdbGetImageDescription(FdbData* dataptr);
EXPORTED bool fdbSetImageDescription(const char* byteptr);
EXPORTED bool fdbDeleteImageDescription();
EXPORTED bool fdbGetArtist(FdbData* dataptr);
EXPORTED bool fdbSetArtist(const char* byteptr);
EXPORTED bool fdbDeleteArtist();
EXPORTED bool fdbGetFNumber(FdbRational* rationalptr);
EXPORTED bool fdbGetFocalLengthIn35mmFormat(int* flin35mmptr);
#endif // FOTODB_H
Let’s Work TogetherIf you're interested in using our C library, complete the form with a few details about you. We'll review your message and get back to you as soon as possible.