Mercurial > geeqie.yaz
comparison src/format_raw.c @ 101:847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
* exif.c: Use new format_raw_exif_offset() function to find Exif in
raw files.
* filelist.c: Add orf and pef to displayed file types.
* format_canon.h, format_fuji.h: Update to new #define format.
* format_fuji.c: Use same offset for Exif as the jpeg image as the
Exif is always embedded in the jpeg and assuming offset of 12 is
just broken.
* format_nikon.h: Update to new #define format, and add pentax here
as finding the jpeg will be same code.
* format_olympus.[ch]: Support Olympus raw files with embedded jpegs,
not all raw files will have a jpeg, but all appear to have Exif tags.
* format_raw.[ch]: Add new camera types, and add a debugging facility
to easily list all tags within tiff files (see format_raw.h to enable).
author | gqview |
---|---|
date | Tue, 07 Nov 2006 21:00:50 +0000 |
parents | 57f6da2510d9 |
children | 50fc73e08550 |
comparison
equal
deleted
inserted
replaced
100:deafec7cd99f | 101:847e4bc6b54c |
---|---|
1 /* | 1 /* |
2 * GQView | 2 * GQView |
3 * (C) 2005 John Ellis | 3 * (C) 2006 John Ellis |
4 * | 4 * |
5 * Authors: | 5 * Authors: |
6 * Original version 2005 Lars Ellenberg, base on dcraw by David coffin. | 6 * Original version 2005 Lars Ellenberg, base on dcraw by David coffin. |
7 * | 7 * |
8 * This software is released under the GNU General Public License (GNU GPL). | 8 * This software is released under the GNU General Public License (GNU GPL). |
43 const gchar *extension; | 43 const gchar *extension; |
44 FormatRawMatchType magic_type; | 44 FormatRawMatchType magic_type; |
45 const guint magic_offset; | 45 const guint magic_offset; |
46 const void *magic_pattern; | 46 const void *magic_pattern; |
47 const guint magic_length; | 47 const guint magic_length; |
48 const FormatRawExifType exif_type; | |
49 FormatRawExifParseFunc exif_func; | |
48 const gchar *description; | 50 const gchar *description; |
49 FormatRawParseFunc func_parse; | 51 FormatRawParseFunc func_parse; |
50 }; | 52 }; |
51 | 53 |
52 static FormatRawEntry format_raw_list[] = { | 54 static FormatRawEntry format_raw_list[] = { |
55 #if DEBUG_RAW_TIFF | |
56 FORMAT_RAW_DEBUG_TIFF, | |
57 #endif | |
53 FORMAT_RAW_CANON, | 58 FORMAT_RAW_CANON, |
54 FORMAT_RAW_FUJI, | 59 FORMAT_RAW_FUJI, |
55 FORMAT_RAW_NIKON, | 60 FORMAT_RAW_NIKON, |
56 { NULL, 0, 0, NULL, 0, NULL, NULL } | 61 FORMAT_RAW_OLYMPUS, |
62 FORMAT_RAW_PENTAX, | |
63 { NULL, 0, 0, NULL, 0, 0, NULL, NULL, NULL } | |
57 }; | 64 }; |
58 | 65 |
59 | 66 |
60 typedef struct _FormatExifEntry FormatExifEntry; | 67 typedef struct _FormatExifEntry FormatExifEntry; |
61 struct _FormatExifEntry { | 68 struct _FormatExifEntry { |
263 | 270 |
264 return format_raw_parse(entry, data, len, image_offset, exif_offset); | 271 return format_raw_parse(entry, data, len, image_offset, exif_offset); |
265 } | 272 } |
266 | 273 |
267 | 274 |
275 FormatRawExifType format_raw_exif_offset(unsigned char *data, const guint len, guint *exif_offset, | |
276 FormatRawExifParseFunc *exif_parse_func) | |
277 { | |
278 FormatRawEntry *entry; | |
279 | |
280 if (!data || len < 1) return FALSE; | |
281 | |
282 entry = format_raw_find(data, len); | |
283 | |
284 if (!entry || !entry->func_parse) return FALSE; | |
285 | |
286 if (!format_raw_parse(entry, data, len, NULL, exif_offset)) return FORMAT_RAW_EXIF_NONE; | |
287 | |
288 if (entry->exif_type == FORMAT_RAW_EXIF_PROPRIETARY && exif_parse_func) | |
289 { | |
290 *exif_parse_func = entry->exif_func; | |
291 } | |
292 | |
293 return entry->exif_type; | |
294 } | |
295 | |
296 | |
268 gint format_raw_img_exif_offsets_fd(int fd, const gchar *path, | 297 gint format_raw_img_exif_offsets_fd(int fd, const gchar *path, |
269 unsigned char *header_data, const guint header_len, | 298 unsigned char *header_data, const guint header_len, |
270 guint *image_offset, guint *exif_offset) | 299 guint *image_offset, guint *exif_offset) |
271 { | 300 { |
272 FormatRawEntry *entry; | 301 FormatRawEntry *entry; |
397 if (debug) printf("EXIF using makernote parser for %s\n", entry->description); | 426 if (debug) printf("EXIF using makernote parser for %s\n", entry->description); |
398 | 427 |
399 return entry->func_parse(exif, tiff, offset, size, bo); | 428 return entry->func_parse(exif, tiff, offset, size, bo); |
400 } | 429 } |
401 | 430 |
402 | 431 /* |
432 *----------------------------------------------------------------------------- | |
433 * Basic TIFF debugger, prints all IFD entries within tiff file | |
434 *----------------------------------------------------------------------------- | |
435 */ | |
436 #if DEBUG_RAW_TIFF | |
437 | |
438 static guint format_debug_tiff_table(unsigned char *data, const guint len, guint offset, | |
439 ExifByteOrder bo, gint level); | |
440 | |
441 static void format_debug_tiff_entry(unsigned char *data, const guint len, guint offset, | |
442 ExifByteOrder bo, gint level) | |
443 { | |
444 guint tag; | |
445 guint type; | |
446 guint count; | |
447 guint segment; | |
448 guint seg_len; | |
449 | |
450 tag = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_TAG, bo); | |
451 type = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_FORMAT, bo); | |
452 count = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_COUNT, bo); | |
453 | |
454 seg_len = ExifFormatList[type].size * count; | |
455 if (seg_len > 4) | |
456 { | |
457 segment = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_DATA, bo); | |
458 if (segment + seg_len > len) return; | |
459 } | |
460 else | |
461 { | |
462 segment = offset + EXIF_TIFD_OFFSET_DATA; | |
463 } | |
464 | |
465 printf("%*stag:0x%04X (%05d), type:%2d %9s, len:%6d [%02X %02X %02X %02X] @ offset:%d\n", | |
466 level, "", tag, tag, type, | |
467 (type < EXIF_FORMAT_COUNT) ? ExifFormatList[type].short_name : "???", count, | |
468 data[segment], data[segment + 1], data[segment + 2], data[segment + 3], segment); | |
469 | |
470 if (tag == 0x8769 || tag == 0x14a) | |
471 { | |
472 gint i; | |
473 | |
474 printf("%*s~~~ found %s table\n", level, "", (tag == 0x14a) ? "subIFD" : "EXIF" ); | |
475 | |
476 for (i = 0; i < count; i++) | |
477 { | |
478 guint subset; | |
479 | |
480 subset = exif_byte_get_int32(data + segment + i * 4, bo); | |
481 format_debug_tiff_table(data, len, subset, bo, level + 1); | |
482 } | |
483 } | |
484 else if (tag == 0x201 && (type == EXIF_FORMAT_LONG_UNSIGNED || type == EXIF_FORMAT_LONG)) | |
485 { | |
486 guint subset = exif_byte_get_int32(data + segment, bo); | |
487 printf("%*s~~~ found jpeg data at offset %d\n", level, "", subset); | |
488 } | |
489 else if (tag == 0x202 && (type == EXIF_FORMAT_LONG_UNSIGNED || type == EXIF_FORMAT_LONG)) | |
490 { | |
491 guint subset = exif_byte_get_int32(data + segment, bo); | |
492 printf("%*s~~~ found jpeg data length of %d\n", level, "", subset); | |
493 } | |
494 } | |
495 | |
496 static guint format_debug_tiff_table(unsigned char *data, const guint len, guint offset, | |
497 ExifByteOrder bo, gint level) | |
498 { | |
499 guint count; | |
500 guint i; | |
501 | |
502 if (level > EXIF_TIFF_MAX_LEVELS) return 0; | |
503 | |
504 if (len < offset + 2) return FALSE; | |
505 | |
506 count = exif_byte_get_int16(data + offset, bo); | |
507 offset += 2; | |
508 if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0; | |
509 | |
510 printf("%*s== tiff table #%d has %d entries ==\n", level, "", level, count); | |
511 | |
512 for (i = 0; i < count; i++) | |
513 { | |
514 format_debug_tiff_entry(data, len, offset + i * EXIF_TIFD_SIZE, bo, level); | |
515 } | |
516 | |
517 printf("%*s----------- end of #%d ------------\n", level, "", level); | |
518 | |
519 return exif_byte_get_int32(data + offset + count * EXIF_TIFD_SIZE, bo); | |
520 } | |
521 | |
522 gint format_debug_tiff_raw(unsigned char *data, const guint len, | |
523 guint *image_offset, guint *exif_offset) | |
524 { | |
525 ExifByteOrder bo; | |
526 gint level; | |
527 guint offset; | |
528 | |
529 if (len < 8) return FALSE; | |
530 | |
531 /* for debugging, we are more relaxed as to magic header */ | |
532 if (memcmp(data, "II", 2) == 0) | |
533 { | |
534 bo = EXIF_BYTE_ORDER_INTEL; | |
535 } | |
536 else if (memcmp(data, "MM", 2) == 0) | |
537 { | |
538 bo = EXIF_BYTE_ORDER_MOTOROLA; | |
539 } | |
540 else | |
541 { | |
542 return FALSE; | |
543 } | |
544 | |
545 printf("*** debug parsing tiff\n"); | |
546 | |
547 offset = exif_byte_get_int32(data + 4, bo); | |
548 level = 0; | |
549 while (offset && level < EXIF_TIFF_MAX_LEVELS) | |
550 { | |
551 offset = format_debug_tiff_table(data, len, offset, bo, 0); | |
552 level++; | |
553 } | |
554 | |
555 printf("*** end\n"); | |
556 | |
557 /* we are debugging, not trying to return any data */ | |
558 return FALSE; | |
559 } | |
560 #endif | |
561 | |
562 |