6 * Original version 2005 Lars Ellenberg, base on dcraw by David coffin.
8 * This software is released under the GNU General Public License (GNU GPL).
9 * Please read the included file COPYING for more information.
10 * This software comes with no warranty of any kind, use at your own risk!
21 #include <sys/types.h>
29 #include "format_raw.h"
31 #include "format_canon.h"
32 #include "format_fuji.h"
33 #include "format_nikon.h"
36 typedef struct _FormatRawEntry FormatRawEntry;
37 struct _FormatRawEntry {
38 const void *header_pattern;
39 const guint header_length;
40 const gchar *description;
41 FormatRawParseFunc func_parse;
44 static FormatRawEntry format_raw_list[] = {
47 { NULL, 0, NULL, NULL }
51 typedef struct _FormatExifEntry FormatExifEntry;
52 struct _FormatExifEntry {
53 FormatExifMatchType header_type;
54 const void *header_pattern;
55 const guint header_length;
56 FormatExifParseFunc func_parse;
59 static FormatExifEntry format_exif_list[] = {
67 static FormatRawEntry *format_raw_find(const void *data, const guint len)
72 while (format_raw_list[n].header_pattern)
74 if (format_raw_list[n].header_length <= len &&
75 memcmp(data, format_raw_list[n].header_pattern, format_raw_list[n].header_length) == 0)
77 return &format_raw_list[n];
85 static gint format_raw_parse(FormatRawEntry *entry,
86 const void *data, const guint len,
87 guint *image_offset, guint *exif_offset)
93 if (!entry || !entry->func_parse) return FALSE;
95 found = entry->func_parse(data, len, &io, &eo);
104 if (image_offset) *image_offset = io;
105 if (exif_offset) *exif_offset = eo;
110 gint format_raw_img_exif_offsets(const void *data, const guint len,
111 guint *image_offset, guint *exif_offset)
113 FormatRawEntry *entry;
115 if (!data || len < 1) return FALSE;
117 entry = format_raw_find(data, len);
119 if (!entry || !entry->func_parse) return FALSE;
121 return format_raw_parse(entry, data, len, image_offset, exif_offset);
125 gint format_raw_img_exif_offsets_fd(int fd, const void *header_data, const guint header_len,
126 guint *image_offset, guint *exif_offset)
128 FormatRawEntry *entry;
129 void *map_data = NULL;
134 if (!header_data || fd < 0) return FALSE;
136 entry = format_raw_find(header_data, header_len);
138 if (!entry || !entry->func_parse) return FALSE;
140 if (fstat(fd, &st) == -1)
142 printf("Failed to stat file %d\n", fd);
145 map_len = st.st_size;
146 map_data = mmap(0, map_len, PROT_READ, MAP_PRIVATE, fd, 0);
147 if (map_data == MAP_FAILED)
149 printf("Failed to mmap file %d\n", fd);
153 success = format_raw_parse(entry, map_data, map_len, image_offset, exif_offset);
155 if (munmap(map_data, map_len) == -1)
157 printf("Failed to unmap file %d\n", fd);
160 if (success && image_offset)
162 if (lseek(fd, *image_offset, SEEK_SET) != *image_offset)
164 printf("Failed to seek to embedded image\n");
167 if (*exif_offset) *exif_offset = 0;
176 static FormatExifEntry *format_exif_makernote_find(ExifData *exif, unsigned char *tiff,
177 guint offset, guint size)
182 make = exif_get_item(exif, "Make");
185 while (format_exif_list[n].header_pattern)
187 switch (format_exif_list[n].header_type)
189 case FORMAT_EXIF_MATCH_MAKERNOTE:
190 if (format_exif_list[n].header_length + offset < size &&
191 memcmp(tiff + offset, format_exif_list[n].header_pattern,
192 format_exif_list[n].header_length) == 0)
194 return &format_exif_list[n];
197 case FORMAT_EXIF_MATCH_MAKE:
199 make->data_len >= format_exif_list[n].header_length &&
200 memcmp(make->data, format_exif_list[n].header_pattern,
201 format_exif_list[n].header_length) == 0)
203 return &format_exif_list[n];
213 gint format_exif_makernote_parse(ExifData *exif, unsigned char *tiff, guint offset,
214 guint size, ExifByteOrder byte_order)
216 FormatExifEntry *entry;
218 entry = format_exif_makernote_find(exif, tiff, offset, size);
220 if (!entry || !entry->func_parse) return FALSE;
222 return entry->func_parse(exif, tiff, offset, size, byte_order);