Refactor reading the strip data fields into a function

This commit is contained in:
Abdelrahman Said 2024-05-04 23:31:20 +01:00
parent b546ce9fa7
commit de0235c0af

View File

@ -44,6 +44,15 @@ struct tiff_reader {
Pixel *pixels; 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); TiffHdr read_tiff_header(const TiffReader *reader);
TiffIFD read_ifd(const TiffReader *reader, Arena *arena); TiffIFD read_ifd(const TiffReader *reader, Arena *arena);
TiffImage read_fields(const TiffReader *reader); 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); void read_strips(const TiffReader *reader, Pixel *buf);
bool read_field(const TiffField *field, TiffImage *img); bool read_field(const TiffField *field, TiffImage *img);
bool validate_image_type(const 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); void read_from_file_with_offset(FILE *fp, void *dst, u64 count, u64 offset);
Image *read_baseline_tiff(const char *file, Arena *arena) { Image *read_baseline_tiff(const char *file, Arena *arena) {
@ -282,32 +292,6 @@ LOAD_IMAGE_PIXELS_RETURN:
return buf; 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) { bool read_strip_data(TiffReader *reader, Arena *arena) {
reader->img.strips = reader->img.strips =
wapp_mem_arena_alloc(arena, sizeof(TiffStrip) * reader->img.strip_count); 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) { for (u32 i = 0; i < reader->img.strip_count; ++i) {
TiffStrip *strip = &(reader->img.strips[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), read_strip_data_field(reader, &offsets);
// i, offsets_total_bytes, offset_size); read_strip_data_field(reader, &counts);
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);
}
} }
return true; return true;
@ -582,6 +530,42 @@ bool validate_image_type(const TiffImage *img) {
return true; 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) { void read_from_file_with_offset(FILE *fp, void *dst, u64 count, u64 offset) {
if (!fp || !dst) { if (!fp || !dst) {
return; return;