updated copyright in source files
[geeqie.git] / src / format_raw.c
1 /*
2  *  GQView
3  *  (C) 2006 John Ellis
4  * Copyright (C) 2008 The Geeqie Team
5  *
6  *  Authors:
7  *    Original version 2005 Lars Ellenberg, base on dcraw by David coffin.
8  *
9  * This software is released under the GNU General Public License (GNU GPL).
10  * Please read the included file COPYING for more information.
11  * This software comes with no warranty of any kind, use at your own risk!
12  */
13
14 #ifdef HAVE_CONFIG_H
15 #  include "config.h"
16 #endif
17
18 #ifndef HAVE_EXIV2
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <sys/mman.h>
26
27 #include <glib.h>
28
29 #include "intl.h"
30
31 #include "main.h"
32 #include "format_raw.h"
33
34 #include "format_canon.h"
35 #include "format_fuji.h"
36 #include "format_nikon.h"
37 #include "format_olympus.h"
38
39 #ifdef DEBUG
40 /* so that debugging is honored */
41 extern gint debug;
42 #endif
43
44 typedef struct _FormatRawEntry FormatRawEntry;
45 struct _FormatRawEntry {
46         const gchar *extension;
47         FormatRawMatchType magic_type;
48         const guint magic_offset;
49         const void *magic_pattern;
50         const guint magic_length;
51         const FormatRawExifType exif_type;
52         FormatRawExifParseFunc exif_func;
53         const gchar *description;
54         FormatRawParseFunc func_parse;
55 };
56
57 static FormatRawEntry format_raw_list[] = {
58 #if DEBUG_RAW_TIFF
59         FORMAT_RAW_DEBUG_TIFF,
60 #endif
61         FORMAT_RAW_CANON,
62         FORMAT_RAW_FUJI,
63         FORMAT_RAW_NIKON,
64         FORMAT_RAW_OLYMPUS,
65         FORMAT_RAW_PENTAX,
66         FORMAT_RAW_SAMSUNG,
67         { NULL, 0, 0, NULL, 0, 0, NULL, NULL, NULL }
68 };
69
70
71 typedef struct _FormatExifEntry FormatExifEntry;
72 struct _FormatExifEntry {
73         FormatExifMatchType header_type;
74         const void *header_pattern;
75         const guint header_length;
76         const gchar *description;
77         FormatExifParseFunc func_parse;
78 };
79
80 static FormatExifEntry format_exif_list[] = {
81         FORMAT_EXIF_CANON,
82         FORMAT_EXIF_FUJI,
83         FORMAT_EXIF_NIKON,
84         FORMAT_EXIF_OLYMPUS,
85         { 0, NULL, 0, NULL }
86 };
87
88
89 static guint tiff_table(unsigned char *data, const guint len, guint offset, ExifByteOrder bo,
90                         guint tag, ExifFormatType type,
91                         guint *result_offset, guint *result_count)
92 {
93         guint count;
94         guint i;
95
96         if (len < offset + 2) return 0;
97         if (type < 0 || type > EXIF_FORMAT_COUNT) return 0;
98
99         count = exif_byte_get_int16(data + offset, bo);
100         offset += 2;
101         if (len < offset + count * 12 + 4) return 0;
102
103         for (i = 0; i < count; i++)
104                 {
105                 guint segment;
106
107                 segment = offset + i * 12;
108                 if (exif_byte_get_int16(data + segment, bo) == tag &&
109                     exif_byte_get_int16(data + segment + 2, bo) == type)
110                         {
111                         guint chunk_count;
112                         guint chunk_offset;
113                         guint chunk_length;
114
115                         chunk_count = exif_byte_get_int32(data + segment + 4, bo);
116                         chunk_length = ExifFormatList[type].size * chunk_count;
117
118                         if (chunk_length > 4)
119                                 {
120                                 chunk_offset = exif_byte_get_int32(data + segment + 8, bo);
121                                 }
122                         else
123                                 {
124                                 chunk_offset = segment + 8;
125                                 }
126
127                         if (chunk_offset + chunk_length <= len)
128                                 {
129                                 *result_offset = chunk_offset;
130                                 *result_count = chunk_count;
131                                 }
132
133                         return 0;
134                         }
135                 }
136
137         return exif_byte_get_int32(data + offset + count * 12, bo);
138 }
139
140 static gint format_tiff_find_tag_data(unsigned char *data, const guint len,
141                                       guint tag, ExifFormatType type,
142                                       guint *result_offset, guint *result_count)
143 {
144         ExifByteOrder bo;
145         guint offset;
146
147         if (len < 8) return FALSE;
148
149         if (memcmp(data, "II", 2) == 0)
150                 {
151                 bo = EXIF_BYTE_ORDER_INTEL;
152                 }
153         else if (memcmp(data, "MM", 2) == 0)
154                 {
155                 bo = EXIF_BYTE_ORDER_MOTOROLA;
156                 }
157         else
158                 {
159                 return FALSE;
160                 }
161
162         if (exif_byte_get_int16(data + 2, bo) != 0x002A)
163                 {
164                 return FALSE;
165                 }
166
167         offset = exif_byte_get_int32(data + 4, bo);
168
169         while (offset != 0)
170                 {
171                 guint ro = 0;
172                 guint rc = 0;
173
174                 offset = tiff_table(data, len, offset, bo, tag, type, &ro, &rc);
175                 if (ro != 0)
176                         {
177                         *result_offset = ro;
178                         *result_count = rc;
179                         return TRUE;
180                         }
181                 }
182
183         return FALSE;
184 }
185
186 static FormatRawEntry *format_raw_find(unsigned char *data, const guint len)
187 {
188         gint n;
189         gint tiff;
190         guint make_count = 0;
191         guint make_offset = 0;
192
193         tiff = (len > 8 &&
194                 (memcmp(data, "II\x2a\x00", 4) == 0 ||
195                  memcmp(data, "MM\x00\x2a", 4) == 0));
196
197         n = 0;
198         while (format_raw_list[n].magic_pattern)
199                 {
200                 FormatRawEntry *entry = &format_raw_list[n];
201
202                 switch (entry->magic_type)
203                         {
204                         case FORMAT_RAW_MATCH_MAGIC:
205                                 if (entry->magic_length + entry->magic_offset <= len &&
206                                     memcmp(data + entry->magic_offset,
207                                            entry->magic_pattern, entry->magic_length) == 0)
208                                         {
209                                         return entry;
210                                         }
211                                 break;
212                         case FORMAT_RAW_MATCH_TIFF_MAKE:
213                                 if (tiff &&
214                                     make_offset == 0 &&
215                                     !format_tiff_find_tag_data(data, len, 0x10f, EXIF_FORMAT_STRING,
216                                                                &make_offset, &make_count))
217                                         {
218                                         tiff = FALSE;
219                                         }
220                                 if (make_offset != 0 &&
221                                     make_count >= entry->magic_offset + entry->magic_length &&
222                                     memcmp(entry->magic_pattern,
223                                            data + make_offset + entry->magic_offset, entry->magic_length) == 0)
224                                         {
225                                         return entry;
226                                         }
227                                 break;
228                         default:
229                                 break;
230                         }
231                 n++;
232                 }
233
234         return NULL;
235 }
236
237 static gint format_raw_parse(FormatRawEntry *entry,
238                              unsigned char *data, const guint len,
239                              guint *image_offset, guint *exif_offset)
240 {
241         guint io = 0;
242         guint eo = 0;
243         gint found;
244
245         if (!entry || !entry->func_parse) return FALSE;
246
247         if (debug) printf("RAW using file parser for %s\n", entry->description);
248
249         found = entry->func_parse(data, len, &io, &eo);
250
251         if (!found ||
252             io >= len - 4 ||
253             eo >= len)
254                 {
255                 return FALSE;
256                 }
257
258         if (image_offset) *image_offset = io;
259         if (exif_offset) *exif_offset = eo;
260
261         return TRUE;
262 }
263
264 gint format_raw_img_exif_offsets(unsigned char *data, const guint len,
265                                  guint *image_offset, guint *exif_offset)
266 {
267         FormatRawEntry *entry;
268
269         if (!data || len < 1) return FALSE;
270
271         entry = format_raw_find(data, len);
272
273         if (!entry || !entry->func_parse) return FALSE;
274
275         return format_raw_parse(entry, data, len, image_offset, exif_offset);
276 }
277
278
279 FormatRawExifType format_raw_exif_offset(unsigned char *data, const guint len, guint *exif_offset,
280                                          FormatRawExifParseFunc *exif_parse_func)
281 {
282         FormatRawEntry *entry;
283
284         if (!data || len < 1) return FALSE;
285
286         entry = format_raw_find(data, len);
287
288         if (!entry || !entry->func_parse) return FALSE;
289
290         if (!format_raw_parse(entry, data, len, NULL, exif_offset)) return FORMAT_RAW_EXIF_NONE;
291
292         if (entry->exif_type == FORMAT_RAW_EXIF_PROPRIETARY && exif_parse_func)
293                 {
294                 *exif_parse_func = entry->exif_func;
295                 }
296
297         return entry->exif_type;
298 }
299
300
301 gint format_raw_img_exif_offsets_fd(int fd, const gchar *path,
302                                     unsigned char *header_data, const guint header_len,
303                                     guint *image_offset, guint *exif_offset)
304 {
305         FormatRawEntry *entry;
306         void *map_data = NULL;
307         size_t map_len = 0;
308         struct stat st;
309         gint success;
310
311         if (!header_data || fd < 0) return FALSE;
312
313         /* given image pathname, first do simple (and fast) file extension test */
314         if (path)
315                 {
316                 const gchar *ext;
317                 gint match = FALSE;
318                 gint i;
319
320                 ext = strrchr(path, '.');
321                 if (!ext) return FALSE;
322                 ext++;
323
324                 i = 0;
325                 while (!match && format_raw_list[i].magic_pattern)
326                         {
327                         if (format_raw_list[i].extension &&
328                             strcasecmp(format_raw_list[i].extension, ext) == 0)
329                                 {
330                                 match = TRUE;
331                                 }
332                         i++;
333                         }
334
335                 if (!match) return FALSE;
336
337                 if (debug) printf("RAW file parser extension match\n");
338                 }
339
340         /* FIXME:
341          * when the target is a tiff file it should be mmaped prior to format_raw_find as
342          * the make field data may not always be within header_data + header_len
343          */
344         entry = format_raw_find(header_data, header_len);
345
346         if (!entry || !entry->func_parse) return FALSE;
347
348         if (fstat(fd, &st) == -1)
349                 {
350                 printf("Failed to stat file %d\n", fd);
351                 return FALSE;
352                 }
353         map_len = st.st_size;
354         map_data = mmap(0, map_len, PROT_READ, MAP_PRIVATE, fd, 0);
355         if (map_data == MAP_FAILED)
356                 {
357                 printf("Failed to mmap file %d\n", fd);
358                 return FALSE;
359                 }
360
361         success = format_raw_parse(entry, map_data, map_len, image_offset, exif_offset);
362
363         if (munmap(map_data, map_len) == -1)
364                 {
365                 printf("Failed to unmap file %d\n", fd);
366                 }
367
368         if (success && image_offset)
369                 {
370                 if (lseek(fd, *image_offset, SEEK_SET) != *image_offset)
371                         {
372                         printf("Failed to seek to embedded image\n");
373
374                         *image_offset = 0;
375                         if (*exif_offset) *exif_offset = 0;
376                         success = FALSE;
377                         }
378                 }
379
380         return success;
381 }
382
383
384 static FormatExifEntry *format_exif_makernote_find(ExifData *exif, unsigned char *tiff,
385                                                    guint offset, guint size)
386 {
387         ExifItem *make;
388         gint n;
389
390         make = exif_get_item(exif, "Exif.Image.Make");
391
392         n = 0;
393         while (format_exif_list[n].header_pattern)
394                 {
395                 switch (format_exif_list[n].header_type)
396                         {
397                         case FORMAT_EXIF_MATCH_MAKERNOTE:
398                                 if (format_exif_list[n].header_length + offset < size &&
399                                     memcmp(tiff + offset, format_exif_list[n].header_pattern,
400                                                           format_exif_list[n].header_length) == 0)
401                                         {
402                                         return &format_exif_list[n];
403                                         }
404                                 break;
405                         case FORMAT_EXIF_MATCH_MAKE:
406                                 if (make &&
407                                     make->data_len >= format_exif_list[n].header_length &&
408                                     memcmp(make->data, format_exif_list[n].header_pattern,
409                                                        format_exif_list[n].header_length) == 0)
410                                         {
411                                         return &format_exif_list[n];
412                                         }
413                                 break;
414                         }
415                 n++;
416                 }
417
418         return FALSE;
419 }
420
421 gint format_exif_makernote_parse(ExifData *exif, unsigned char *tiff, guint offset,
422                                  guint size, ExifByteOrder bo)
423 {
424         FormatExifEntry *entry;
425
426         entry = format_exif_makernote_find(exif, tiff, offset, size);
427
428         if (!entry || !entry->func_parse) return FALSE;
429
430         if (debug) printf("EXIF using makernote parser for %s\n", entry->description);
431
432         return entry->func_parse(exif, tiff, offset, size, bo);
433 }
434
435 /*
436  *-----------------------------------------------------------------------------
437  * Basic TIFF debugger, prints all IFD entries within tiff file
438  *-----------------------------------------------------------------------------
439  */
440 #if DEBUG_RAW_TIFF
441
442 static guint format_debug_tiff_table(unsigned char *data, const guint len, guint offset,
443                                      ExifByteOrder bo, gint level);
444
445 static void format_debug_tiff_entry(unsigned char *data, const guint len, guint offset,
446                                     ExifByteOrder bo, gint level)
447 {
448         guint tag;
449         guint type;
450         guint count;
451         guint segment;
452         guint seg_len;
453
454         tag = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_TAG, bo);
455         type = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_FORMAT, bo);
456         count = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_COUNT, bo);
457
458         seg_len = ExifFormatList[type].size * count;
459         if (seg_len > 4)
460                 {
461                 segment = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_DATA, bo);
462                 if (segment + seg_len > len) return;
463                 }
464         else
465                 {
466                 segment = offset + EXIF_TIFD_OFFSET_DATA;
467                 }
468
469         printf("%*stag:0x%04X (%05d), type:%2d %9s, len:%6d [%02X %02X %02X %02X] @ offset:%d\n",
470                 level, "", tag, tag, type,
471                 (type < EXIF_FORMAT_COUNT) ? ExifFormatList[type].short_name : "???", count,
472                 data[segment], data[segment + 1], data[segment + 2], data[segment + 3], segment);
473
474         if (tag == 0x8769 || tag == 0x14a)
475                 {
476                 gint i;
477
478                 printf("%*s~~~ found %s table\n", level, "", (tag == 0x14a) ? "subIFD" : "EXIF" );
479
480                 for (i = 0; i < count; i++)
481                         {
482                         guint subset;
483
484                         subset = exif_byte_get_int32(data + segment + i * 4, bo);
485                         format_debug_tiff_table(data, len, subset, bo, level + 1);
486                         }
487                 }
488         else if (tag == 0x8773 && type == EXIF_FORMAT_UNDEFINED)
489                 {
490                 printf("%*s~~~ found ICC color profile at offset %d, length %d\n", level, "", segment, seg_len);
491                 }
492         else if (tag == 0x201 && (type == EXIF_FORMAT_LONG_UNSIGNED || type == EXIF_FORMAT_LONG))
493                 {
494                 guint subset = exif_byte_get_int32(data + segment, bo);
495                 printf("%*s~~~ found jpeg data at offset %d\n", level, "", subset);
496                 }
497         else if (tag == 0x202 && (type == EXIF_FORMAT_LONG_UNSIGNED || type == EXIF_FORMAT_LONG))
498                 {
499                 guint subset = exif_byte_get_int32(data + segment, bo);
500                 printf("%*s~~~ found jpeg data length of %d\n", level, "", subset);
501                 }
502 }
503
504 static guint format_debug_tiff_table(unsigned char *data, const guint len, guint offset,
505                                      ExifByteOrder bo, gint level)
506 {
507         guint count;
508         guint i;
509
510         if (level > EXIF_TIFF_MAX_LEVELS) return 0;
511
512         if (len < offset + 2) return FALSE;
513
514         count = exif_byte_get_int16(data + offset, bo);
515         offset += 2;
516         if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0;
517
518         printf("%*s== tiff table #%d has %d entries ==\n", level, "", level, count);
519
520         for (i = 0; i < count; i++)
521                 {
522                 format_debug_tiff_entry(data, len, offset + i * EXIF_TIFD_SIZE, bo, level);
523                 }
524
525         printf("%*s----------- end of #%d ------------\n", level, "", level);
526
527         return exif_byte_get_int32(data + offset + count * EXIF_TIFD_SIZE, bo);
528 }
529
530 gint format_debug_tiff_raw(unsigned char *data, const guint len,
531                            guint *image_offset, guint *exif_offset)
532 {
533         ExifByteOrder bo;
534         gint level;
535         guint offset;
536
537         if (len < 8) return FALSE;
538
539         /* for debugging, we are more relaxed as to magic header */
540         if (memcmp(data, "II", 2) == 0)
541                 {
542                 bo = EXIF_BYTE_ORDER_INTEL;
543                 }
544         else if (memcmp(data, "MM", 2) == 0)
545                 {
546                 bo = EXIF_BYTE_ORDER_MOTOROLA;
547                 }
548         else
549                 {
550                 return FALSE;
551                 }
552
553         printf("*** debug parsing tiff\n");
554
555         offset = exif_byte_get_int32(data + 4, bo);
556         level = 0;
557         while (offset && level < EXIF_TIFF_MAX_LEVELS)
558                 {
559                 offset = format_debug_tiff_table(data, len, offset, bo, 0);
560                 level++;
561                 }
562
563         printf("*** end\n");
564
565         /* we are debugging, not trying to return any data */
566         return FALSE;
567 }
568 #endif
569
570 #endif
571 /* not HAVE_EXIV2 */