Mercurial > geeqie.yaz
view src/format_raw.c @ 45:7cfa60beda76
Thu May 26 13:57:19 2005 John Ellis <johne@verizon.net>
* format_raw.[ch]: Move camera specific code to manufacturer specific
format_*.c files. Change code so that file descripter version is now a
separate functions that wraps the standard parser by using mmap.
* format_canon.[ch]: Moved Canon specific raw support here, removed
file descriptor versions of parser. This Canon raw file parser written
by Daniel M. German.
* format_fuji.[ch]: Move Fuji specific raw support here, parser written
by Lars Ellenberg.
* exif.c: Update for change to format_raw_img_exif_offsets.
* filelist.c: Add cr2 extension to Canon raw format list.
* image-load.c: Fixes for changes to format_raw_img_exif_offset_fd so
that buffer is refilled using new offset of file descriptor.
* src/Makefile.am: Add format_canon.[ch], format_fuji.[ch] to build.
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
##### an offical release when making enhancements and translation updates. #####
author | gqview |
---|---|
date | Thu, 26 May 2005 18:10:52 +0000 |
parents | ee03f36e9e4b |
children | 905f8fa583a3 |
line wrap: on
line source
/* * GQView * (C) 2005 John Ellis * * Authors: * Original version 2005 Lars Ellenberg, base on dcraw by David coffin. * * This software is released under the GNU General Public License (GNU GPL). * Please read the included file COPYING for more information. * This software comes with no warranty of any kind, use at your own risk! */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <glib.h> #include "intl.h" #include "format_raw.h" #include "format_canon.h" #include "format_fuji.h" typedef struct _FormatEntry FormatEntry; struct _FormatEntry { const void *header_pattern; const guint header_length; const gchar *description; FormatRawParseFunc func_parse; }; static FormatEntry format_list[] = { FORMAT_RAW_CANON, FORMAT_RAW_FUJI, { NULL, 0, NULL, NULL } }; static FormatEntry *format_raw_find(const void *data, const guint len) { gint n; n = 0; while (format_list[n].header_pattern) { if (format_list[n].header_length <= len && memcmp(data, format_list[n].header_pattern, format_list[n].header_length) == 0) { return &format_list[n]; } n++; } return NULL; } static gint format_raw_parse(FormatEntry *entry, const void *data, const guint len, guint *image_offset, guint *exif_offset) { gint io = 0; gint eo = 0; gint found; if (!entry || !entry->func_parse) return FALSE; found = entry->func_parse(data, len, &io, &eo); if (!found || io >= len - 4 || eo >= len) { return FALSE; } if (image_offset) *image_offset = io; if (exif_offset) *exif_offset = eo; return TRUE; } gint format_raw_img_exif_offsets(const void *data, const guint len, guint *image_offset, guint *exif_offset) { FormatEntry *entry; if (!data || len < 1) return FALSE; entry = format_raw_find(data, len); if (!entry || !entry->func_parse) return FALSE; return format_raw_parse(entry, data, len, image_offset, exif_offset); } gint format_raw_img_exif_offsets_fd(int fd, const void *header_data, const guint header_len, guint *image_offset, guint *exif_offset) { FormatEntry *entry; void *map_data = NULL; size_t map_len = 0; struct stat st; gint success; if (!header_data || fd < 0) return FALSE; entry = format_raw_find(header_data, header_len); if (!entry || !entry->func_parse) return FALSE; if (fstat(fd, &st) == -1) { printf("Failed to stat file %d\n", fd); return FALSE; } map_len = st.st_size; map_data = mmap(0, map_len, PROT_READ, MAP_PRIVATE, fd, 0); if (map_data == MAP_FAILED) { printf("Failed to mmap of file %d\n", fd); return FALSE; } success = format_raw_parse(entry, map_data, map_len, image_offset, exif_offset); if (munmap(map_data, map_len) == -1) { printf("Failed to unmap file %d\n", fd); } if (success && image_offset) { if (lseek(fd, *image_offset, SEEK_SET) != *image_offset) { printf("Failed to seek to embedded image\n"); *image_offset = 0; if (*exif_offset) *exif_offset = 0; success = FALSE; } } return success; }