summaryrefslogtreecommitdiffstats
path: root/src/file_tiff.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/file_tiff.c')
-rw-r--r--src/file_tiff.c97
1 files changed, 44 insertions, 53 deletions
diff --git a/src/file_tiff.c b/src/file_tiff.c
index 02d0bf7..96626ce 100644
--- a/src/file_tiff.c
+++ b/src/file_tiff.c
@@ -38,6 +38,9 @@
#include "common.h"
#include "file_tiff.h"
#include "log.h"
+#if defined(__FRAMAC__)
+#include "__fc_builtin.h"
+#endif
static void register_header_check_tiff(file_stat_t *file_stat);
@@ -50,6 +53,8 @@ const file_hint_t file_hint_tiff= {
.register_header_check=&register_header_check_tiff
};
+/* @ ensures \result == 1 || \result == 2 || \result == 4 || \result == 8;
+ */
unsigned int tiff_type2size(const unsigned int type)
{
switch(type)
@@ -132,72 +137,58 @@ const char *tag_name(unsigned int tag)
}
#endif
-const char *find_tag_from_tiff_header(const TIFFHeader *tiff, const unsigned int tiff_size, const unsigned int tag, const char **potential_error)
+unsigned int find_tag_from_tiff_header(const unsigned char*buffer, const unsigned int buffer_size, const unsigned int tag, const unsigned char **potential_error)
{
+ const TIFFHeader *tiff=(const TIFFHeader *)buffer;
+ /*@ assert sizeof(TIFFHeader) <= sizeof(struct ifd_header); */
+ if(buffer_size < sizeof(struct ifd_header))
+ return 0;
+ /*@ assert buffer_size >= sizeof(TIFFHeader); */
+ /*@ assert buffer_size >= sizeof(struct ifd_header); */
+#ifndef MAIN_tiff_le
if(tiff->tiff_magic==TIFF_BIGENDIAN)
- return find_tag_from_tiff_header_be(tiff, tiff_size, tag, potential_error);
- else if(tiff->tiff_magic==TIFF_LITTLEENDIAN)
- return find_tag_from_tiff_header_le(tiff, tiff_size, tag, potential_error);
- return NULL;
+ return find_tag_from_tiff_header_be(buffer, buffer_size, tag, potential_error);
+#endif
+#ifndef MAIN_tiff_be
+ if(tiff->tiff_magic==TIFF_LITTLEENDIAN)
+ return find_tag_from_tiff_header_le(buffer, buffer_size, tag, potential_error);
+#endif
+ return 0;
}
-time_t get_date_from_tiff_header(const TIFFHeader *tiff, const unsigned int tiff_size)
+time_t get_date_from_tiff_header(const unsigned char *buffer, const unsigned int buffer_size)
{
- const char *potential_error=NULL;
- const char *date_asc;
+ const unsigned char *potential_error=NULL;
+ unsigned int date_asc=0;
+ time_t tmp;
+ /*@ assert \valid_read(buffer+(0..buffer_size-1)); */
+ /*@ assert sizeof(TIFFHeader) <= sizeof(struct ifd_header); */
+ if(buffer_size < sizeof(struct ifd_header) || buffer_size < 19)
+ return (time_t)0;
+ /*@ assert buffer_size >= sizeof(TIFFHeader); */
+ /*@ assert buffer_size >= sizeof(struct ifd_header); */
/* DateTimeOriginal */
- date_asc=find_tag_from_tiff_header(tiff, tiff_size, 0x9003, &potential_error);
+ date_asc=find_tag_from_tiff_header(buffer, buffer_size, 0x9003, &potential_error);
/* DateTimeDigitalized*/
- if(date_asc==NULL || date_asc < (const char *)tiff || &date_asc[18] >= (const char *)tiff + tiff_size)
- date_asc=find_tag_from_tiff_header(tiff, tiff_size, 0x9004, &potential_error);
- if(date_asc==NULL || date_asc < (const char *)tiff || &date_asc[18] >= (const char *)tiff + tiff_size)
- date_asc=find_tag_from_tiff_header(tiff, tiff_size, 0x132, &potential_error);
- if(date_asc==NULL || date_asc < (const char *)tiff || &date_asc[18] >= (const char *)tiff + tiff_size)
+ if(date_asc==0 || date_asc > buffer_size - 19)
+ date_asc=find_tag_from_tiff_header(buffer, buffer_size, 0x9004, &potential_error);
+ if(date_asc==0 || date_asc > buffer_size - 19)
+ date_asc=find_tag_from_tiff_header(buffer, buffer_size, 0x132, &potential_error);
+ if(date_asc==0 || date_asc > buffer_size - 19)
return (time_t)0;
- return get_time_from_YYYY_MM_DD_HH_MM_SS(date_asc);
+ tmp=get_time_from_YYYY_MM_DD_HH_MM_SS(&buffer[date_asc]);
+ /*@ assert \valid_read(buffer+(0..buffer_size-1)); */
+ return tmp;
}
static void register_header_check_tiff(file_stat_t *file_stat)
{
static const unsigned char tiff_header_be[4]= { 'M','M',0x00, 0x2a};
static const unsigned char tiff_header_le[4]= { 'I','I',0x2a, 0x00};
- register_header_check(0, tiff_header_be, sizeof(tiff_header_be), &header_check_tiff_be_new, file_stat);
- register_header_check(0, tiff_header_le, sizeof(tiff_header_le), &header_check_tiff_le_new, file_stat);
-}
-
-void file_check_tiff(file_recovery_t *fr)
-{
- static uint64_t calculated_file_size=0;
- TIFFHeader header;
- calculated_file_size = 0;
- if(fseek(fr->handle, 0, SEEK_SET) < 0 ||
- fread(&header, sizeof(TIFFHeader), 1, fr->handle) != 1)
- {
- fr->file_size=0;
- return;
- }
- if(header.tiff_magic==TIFF_LITTLEENDIAN)
- calculated_file_size=header_check_tiff_le(fr, le32(header.tiff_diroff), 0, 0);
- else if(header.tiff_magic==TIFF_BIGENDIAN)
- calculated_file_size=header_check_tiff_be(fr, be32(header.tiff_diroff), 0, 0);
-#ifdef DEBUG_TIFF
- log_info("TIFF Current %llu\n", (unsigned long long)fr->file_size);
- log_info("TIFF Estimated %llu %llx\n", (unsigned long long)calculated_file_size, (unsigned long long)calculated_file_size);
+#if !defined(MAIN_tiff_le) && !defined(MAIN_jpg)
+ register_header_check(0, tiff_header_be, sizeof(tiff_header_be), &header_check_tiff_be, file_stat);
+#endif
+#if !defined(MAIN_tiff_be) && !defined(MAIN_jpg)
+ register_header_check(0, tiff_header_le, sizeof(tiff_header_le), &header_check_tiff_le, file_stat);
#endif
- if(fr->file_size < calculated_file_size || calculated_file_size==0)
- fr->file_size=0;
- /* PhotoRec isn't yet capable to find the correct filesize for
- * Sony arw and dng,
- * Panasonic raw/rw2,
- * Minolta tif
- * Sony sr2
- * so don't truncate them */
- else if(strcmp(fr->extension,"cr2")==0 ||
- strcmp(fr->extension,"dcr")==0 ||
- strcmp(fr->extension,"nef")==0 ||
- strcmp(fr->extension,"orf")==0 ||
- strcmp(fr->extension,"pef")==0 ||
- (strcmp(fr->extension,"tif")==0 && calculated_file_size>1024*1024*1024) ||
- strcmp(fr->extension,"wdp")==0)
- fr->file_size=calculated_file_size;
}