From de0235c0afebd7de44e2d7e3b3b76cd5b846acd2 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sat, 4 May 2024 23:31:20 +0100 Subject: [PATCH] Refactor reading the strip data fields into a function --- src/tiff/tiffread.c | 140 ++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 78 deletions(-) diff --git a/src/tiff/tiffread.c b/src/tiff/tiffread.c index 3a14ce0..8fc7d21 100644 --- a/src/tiff/tiffread.c +++ b/src/tiff/tiffread.c @@ -44,6 +44,15 @@ struct tiff_reader { Pixel *pixels; }; +typedef struct strip_data_field StripDataField; +struct strip_data_field { + u32 *strip_value; + const ShortLongValue *value_from_file; + u32 strip_index; + u32 length_in_bytes; + u16 type_byte_count; +}; + TiffHdr read_tiff_header(const TiffReader *reader); TiffIFD read_ifd(const TiffReader *reader, Arena *arena); TiffImage read_fields(const TiffReader *reader); @@ -52,6 +61,7 @@ bool read_strip_data(TiffReader *reader, Arena *arena); void read_strips(const TiffReader *reader, Pixel *buf); bool read_field(const TiffField *field, TiffImage *img); bool validate_image_type(const TiffImage *img); +void read_strip_data_field(const TiffReader *reader, StripDataField *field); void read_from_file_with_offset(FILE *fp, void *dst, u64 count, u64 offset); Image *read_baseline_tiff(const char *file, Arena *arena) { @@ -282,32 +292,6 @@ LOAD_IMAGE_PIXELS_RETURN: return buf; } -#if 0 -void read_strip_field(FILE *fp, const TiffHdr *header, const TiffImage *img, TiffStrip *strip) { - if (offsets_total_bytes > sizeof(u32)) { - u32 offset = img->strip_offsets.long_val + offset_size * i; - read_from_file_with_offset(fp, &(strip->offset), offset_size, offset); - - switch (header->order) { - case TIFF_ORDER_BIG_ENDIAN: - if (IS_LITTLE_ENDIAN) { - strip->offset = offset_size > sizeof(u16) ? ntohl(strip->offset) - : ntohs(strip->offset); - } - break; - case TIFF_ORDER_LITTLE_ENDIAN: - if (IS_BIG_ENDIAN) { - strip->offset = offset_size > sizeof(u16) ? htonl(strip->offset) - : htons(strip->offset); - } - break; - } - } else { - memcpy(&(strip->offset), &(img->strip_offsets.long_val), offset_size); - } -} -#endif - bool read_strip_data(TiffReader *reader, Arena *arena) { reader->img.strips = wapp_mem_arena_alloc(arena, sizeof(TiffStrip) * reader->img.strip_count); @@ -332,59 +316,23 @@ bool read_strip_data(TiffReader *reader, Arena *arena) { for (u32 i = 0; i < reader->img.strip_count; ++i) { TiffStrip *strip = &(reader->img.strips[i]); + StripDataField offsets = { + .strip_value = &(strip->offset), + .value_from_file = &(reader->img.strip_offsets), + .strip_index = i, + .length_in_bytes = offsets_total_bytes, + .type_byte_count = offset_size, + }; + StripDataField counts = { + .strip_value = &(strip->byte_count), + .value_from_file = &(reader->img.strip_byte_counts), + .strip_index = i, + .length_in_bytes = byte_count_total_bytes, + .type_byte_count = counts_size, + }; - // read_strip_field(reader, &(strip->offset), &(reader->img.strip_offsets), - // i, offsets_total_bytes, offset_size); - - if (offsets_total_bytes > sizeof(u32)) { - u32 offset = reader->img.strip_offsets.long_val + offset_size * i; - read_from_file_with_offset(reader->fp, &(strip->offset), offset_size, - offset); - - switch (reader->header.order) { - case TIFF_ORDER_BIG_ENDIAN: - if (IS_LITTLE_ENDIAN) { - strip->offset = offset_size > sizeof(u16) ? ntohl(strip->offset) - : ntohs(strip->offset); - } - break; - case TIFF_ORDER_LITTLE_ENDIAN: - if (IS_BIG_ENDIAN) { - strip->offset = offset_size > sizeof(u16) ? htonl(strip->offset) - : htons(strip->offset); - } - break; - } - } else { - memcpy(&(strip->offset), &(reader->img.strip_offsets.long_val), - offset_size); - } - - if (byte_count_total_bytes > sizeof(u32)) { - u32 offset = reader->img.strip_byte_counts.long_val + counts_size * i; - read_from_file_with_offset(reader->fp, &(strip->byte_count), counts_size, - offset); - - switch (reader->header.order) { - case TIFF_ORDER_BIG_ENDIAN: - if (IS_LITTLE_ENDIAN) { - strip->byte_count = counts_size > sizeof(u16) - ? ntohl(strip->byte_count) - : ntohs(strip->byte_count); - } - break; - case TIFF_ORDER_LITTLE_ENDIAN: - if (IS_BIG_ENDIAN) { - strip->byte_count = counts_size > sizeof(u16) - ? htonl(strip->byte_count) - : htons(strip->byte_count); - } - break; - } - } else { - memcpy(&(strip->byte_count), &(reader->img.strip_byte_counts.long_val), - counts_size); - } + read_strip_data_field(reader, &offsets); + read_strip_data_field(reader, &counts); } return true; @@ -582,6 +530,42 @@ bool validate_image_type(const TiffImage *img) { return true; } +void read_strip_data_field(const TiffReader *reader, StripDataField *field) { + u16 tiff_long_byte_count = field_types[TIFF_FIELD_TYPE_LONG].byte_count; + + bool value_is_file_offset = field->length_in_bytes > tiff_long_byte_count; + u32 offset = field->type_byte_count * field->strip_index; + + if (!value_is_file_offset) { + u8 *value = (u8 *)&(field->value_from_file->long_val); + memcpy(field->strip_value, value + offset, field->type_byte_count); + + return; + } + + read_from_file_with_offset(reader->fp, field->strip_value, + field->type_byte_count, + field->value_from_file->long_val + offset); + + u16 tiff_short_byte_count = field_types[TIFF_FIELD_TYPE_SHORT].byte_count; + switch (reader->header.order) { + case TIFF_ORDER_BIG_ENDIAN: + if (IS_LITTLE_ENDIAN) { + *(field->strip_value) = field->type_byte_count > tiff_short_byte_count + ? ntohl(*(field->strip_value)) + : ntohs(*(field->strip_value)); + } + break; + case TIFF_ORDER_LITTLE_ENDIAN: + if (IS_BIG_ENDIAN) { + *(field->strip_value) = field->type_byte_count > tiff_short_byte_count + ? htonl(*(field->strip_value)) + : htons(*(field->strip_value)); + } + break; + } +} + void read_from_file_with_offset(FILE *fp, void *dst, u64 count, u64 offset) { if (!fp || !dst) { return;