diff options
author | Christophe Grenier <[email protected]> | 2009-05-24 17:14:12 +0200 |
---|---|---|
committer | Christophe Grenier <[email protected]> | 2009-05-24 17:14:12 +0200 |
commit | 124ea44ab7679bb370cf040573faddc74abd93c3 (patch) | |
tree | e2c90a2c254e5c410dbce6456e0ef8e8005d2a3f | |
parent | 06e4c760a4bb6fc62355d62603f48ebd5dd8961f (diff) |
PhotoRec: Fix Panasonic rw2 recovery
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/file_list.c | 4 | ||||
-rw-r--r-- | src/file_raw.c | 11 | ||||
-rw-r--r-- | src/file_rw2.c | 68 | ||||
-rw-r--r-- | src/file_tiff.c | 25 | ||||
-rw-r--r-- | src/file_tiff.h | 1 |
6 files changed, 88 insertions, 22 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 228fd853..1a58cb9a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -166,6 +166,7 @@ file_C = filegen.c \ file_rm.c \ file_rns.c \ file_rpm.c \ + file_rw2.c \ file_ses.c \ file_sib.c \ file_sit.c \ diff --git a/src/file_list.c b/src/file_list.c index 8406610a..41c53593 100644 --- a/src/file_list.c +++ b/src/file_list.c @@ -169,6 +169,7 @@ extern const file_hint_t file_hint_riff; extern const file_hint_t file_hint_rm; extern const file_hint_t file_hint_rns; extern const file_hint_t file_hint_rpm; +extern const file_hint_t file_hint_rw2; extern const file_hint_t file_hint_ses; extern const file_hint_t file_hint_sib; extern const file_hint_t file_hint_sit; @@ -338,7 +339,7 @@ file_enable_t list_file_enable[]= { .enable=0, .file_hint=&file_hint_qbb }, { .enable=0, .file_hint=&file_hint_qdf }, { .enable=0, .file_hint=&file_hint_qxd }, - { .enable=0, .file_hint=&file_hint_ra }, + { .enable=0, .file_hint=&file_hint_ra }, { .enable=0, .file_hint=&file_hint_raf }, { .enable=0, .file_hint=&file_hint_rar }, { .enable=0, .file_hint=&file_hint_raw }, @@ -349,6 +350,7 @@ file_enable_t list_file_enable[]= { .enable=0, .file_hint=&file_hint_rm }, { .enable=0, .file_hint=&file_hint_rns }, { .enable=0, .file_hint=&file_hint_rpm }, + { .enable=0, .file_hint=&file_hint_rw2 }, { .enable=0, .file_hint=&file_hint_ses }, { .enable=0, .file_hint=&file_hint_sib }, { .enable=0, .file_hint=&file_hint_sit }, diff --git a/src/file_raw.c b/src/file_raw.c index 5919c6bd..6dfeac52 100644 --- a/src/file_raw.c +++ b/src/file_raw.c @@ -36,7 +36,7 @@ static int header_check_raw(const unsigned char *buffer, const unsigned int buff const file_hint_t file_hint_raw= { .extension="raw", /* What is the correct extension ? */ - .description="Contax picture, Panasonic/Leica RAW", + .description="Contax picture RAW", .min_header_distance=0, .max_filesize=PHOTOREC_MAX_FILE_SIZE, .recover=1, @@ -45,12 +45,10 @@ const file_hint_t file_hint_raw= { }; static const unsigned char raw_header_contax[7]= {'A','R','E','C','O','Y','K'}; -static const unsigned char raw_header_panasonic[4]= {'I','I','U','\0'}; static void register_header_check_raw(file_stat_t *file_stat) { register_header_check(25, raw_header_contax,sizeof(raw_header_contax), &header_check_raw, file_stat); - register_header_check(0, raw_header_panasonic,sizeof(raw_header_panasonic), &header_check_raw, file_stat); } static int header_check_raw(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new) @@ -62,13 +60,6 @@ static int header_check_raw(const unsigned char *buffer, const unsigned int buff file_recovery_new->extension=file_hint_raw.extension; return 1; } - /* Panasonic/Leica */ - if(memcmp(buffer, raw_header_panasonic, sizeof(raw_header_panasonic))==0) - { - reset_file_recovery(file_recovery_new); - file_recovery_new->extension="raw"; - return 1; - } return 0; } diff --git a/src/file_rw2.c b/src/file_rw2.c new file mode 100644 index 00000000..157a9aca --- /dev/null +++ b/src/file_rw2.c @@ -0,0 +1,68 @@ +/* + + File: file_rw2.c + + Copyright (C) 1998-2009 Christophe GRENIER <[email protected]> + + This software is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#include <stdio.h> +#include "types.h" +#include "filegen.h" +#include "file_tiff.h" + +static void register_header_check_rw2(file_stat_t *file_stat); +static int header_check_rw2(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new); + +const file_hint_t file_hint_rw2= { + .extension="rw2", + .description="Panasonic/Leica RAW", + .min_header_distance=0x800, /* Avoid jpg fragment */ + .max_filesize=PHOTOREC_MAX_FILE_SIZE, + .recover=1, + .enable_by_default=1, + .register_header_check=®ister_header_check_rw2 +}; + +static const unsigned char rw2_header_panasonic[4]= {'I','I','U','\0'}; + +static void register_header_check_rw2(file_stat_t *file_stat) +{ + register_header_check(0, rw2_header_panasonic, sizeof(rw2_header_panasonic), &header_check_rw2, file_stat); +} + +static int header_check_rw2(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new) +{ + /* Panasonic/Leica */ + if(memcmp(buffer, rw2_header_panasonic, sizeof(rw2_header_panasonic))==0) + { + reset_file_recovery(file_recovery_new); + file_recovery_new->extension="rw2"; + file_recovery_new->time=get_date_from_tiff_header((const TIFFHeader *)buffer, buffer_size); + file_recovery_new->file_check=&file_check_tiff; + return 1; + } + return 0; +} + + diff --git a/src/file_tiff.c b/src/file_tiff.c index a6343e61..9fc62d47 100644 --- a/src/file_tiff.c +++ b/src/file_tiff.c @@ -41,7 +41,6 @@ static void register_header_check_tiff(file_stat_t *file_stat); static int header_check_tiff(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new); -static void file_check_tiff(file_recovery_t *file_recovery); static uint64_t header_check_tiff_be(FILE *in, const uint32_t tiff_diroff, const unsigned int depth, const unsigned int count); static uint64_t header_check_tiff_le(FILE *in, const uint32_t tiff_diroff, const unsigned int depth, const unsigned int count); @@ -165,13 +164,13 @@ const char *find_tag_from_tiff_header(const TIFFHeader *tiff, const unsigned int { if(tiff_size < sizeof(TIFFHeader)) return NULL; - if(memcmp(&tiff->tiff_magic, tiff_header_be, sizeof(tiff_header_be))==0) + if(tiff->tiff_magic==TIFF_BIGENDIAN) { if(tiff_size < be32(tiff->tiff_diroff)+sizeof(TIFFDirEntry)) return NULL; return find_tag_from_tiff_header_be(tiff, tiff_size, tag); } - else if(memcmp(&tiff->tiff_magic, tiff_header_le, sizeof(tiff_header_le))==0) + else if(tiff->tiff_magic==TIFF_LITTLEENDIAN) { if(tiff_size < le32(tiff->tiff_diroff)+sizeof(TIFFDirEntry)) return NULL; @@ -207,8 +206,8 @@ time_t get_date_from_tiff_header(const TIFFHeader *tiff, const unsigned int tiff static void register_header_check_tiff(file_stat_t *file_stat) { - register_header_check(0, tiff_header_be,sizeof(tiff_header_be), &header_check_tiff, file_stat); - register_header_check(0, tiff_header_le,sizeof(tiff_header_le), &header_check_tiff, file_stat); + register_header_check(0, tiff_header_be, sizeof(tiff_header_be), &header_check_tiff, file_stat); + register_header_check(0, tiff_header_le, sizeof(tiff_header_le), &header_check_tiff, file_stat); } static int header_check_tiff(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new) @@ -428,7 +427,8 @@ static uint64_t header_check_tiff_le(FILE *in, const uint32_t tiff_diroff, const } entry++; } - if(strip_bytecounts > 0 && max_offset < strip_offsets + strip_bytecounts) + if(strip_bytecounts > 0 && strip_offsets!=0xffffffff && + max_offset < strip_offsets + strip_bytecounts) max_offset = strip_offsets + strip_bytecounts; if(jpegifbytecount > 0 && max_offset < jpegifoffset + jpegifbytecount) max_offset = jpegifoffset + jpegifbytecount; @@ -558,7 +558,8 @@ static uint64_t header_check_tiff_be(FILE *in, const uint32_t tiff_diroff, const } entry++; } - if(strip_bytecounts > 0 && max_offset < strip_offsets + strip_bytecounts) + if(strip_bytecounts > 0 && strip_offsets!=0xffffffff && + max_offset < strip_offsets + strip_bytecounts) max_offset = strip_offsets + strip_bytecounts; if(jpegifbytecount > 0 && max_offset < jpegifoffset + jpegifbytecount) max_offset = jpegifoffset + jpegifbytecount; @@ -571,7 +572,7 @@ static uint64_t header_check_tiff_be(FILE *in, const uint32_t tiff_diroff, const return max_offset; } -static void file_check_tiff(file_recovery_t *fr) +void file_check_tiff(file_recovery_t *fr) { static uint64_t calculated_file_size=0; TIFFHeader header; @@ -584,14 +585,16 @@ static void file_check_tiff(file_recovery_t *fr) else if(header.tiff_magic==TIFF_BIGENDIAN) calculated_file_size=header_check_tiff_be(fr->handle, be32(header.tiff_diroff), 0, 0); #ifdef DEBUG_TIFF - log_info("TIFF Current %llu\n", fr->file_size); - log_info("TIFF Estimated %llu\n", calculated_file_size); + log_info("TIFF Current %llu\n", (unsigned long long)fr->file_size); + log_info("TIFF Estimated %llu\n", (unsigned long long)calculated_file_size); #endif if(fr->file_size < calculated_file_size) fr->file_size=0; /* PhotoRec isn't yet capable to find the correct Sony arw and dng filesize, + * same problem for panasonic raw/rw2, * so don't truncate them */ else if(strcmp(fr->extension,"arw")!=0 && - strcmp(fr->extension,"dng")!=0) + strcmp(fr->extension,"dng")!=0 && + strcmp(fr->extension,"rw2")!=0) fr->file_size=calculated_file_size; } diff --git a/src/file_tiff.h b/src/file_tiff.h index 644916b3..79f513b6 100644 --- a/src/file_tiff.h +++ b/src/file_tiff.h @@ -59,6 +59,7 @@ struct ifd_header { time_t get_date_from_tiff_header(const TIFFHeader *tiff, const unsigned int tiff_size); const char *find_tag_from_tiff_header(const TIFFHeader *tiff, const unsigned int tiff_size, const unsigned int tag); +void file_check_tiff(file_recovery_t *file_recovery); #ifdef __cplusplus } /* closing brace for extern "C" */ |