Initial implementation of the reader
This commit is contained in:
parent
61f0182c3f
commit
0bd448a8a9
56
src/main.c
56
src/main.c
@ -1,44 +1,54 @@
|
||||
#include "aliases.h"
|
||||
#include "mem_allocator.h"
|
||||
#include "mem_ctx.h"
|
||||
#include "tiffread.h"
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
wapp_mem_ctx_init(10 * 1024 * 1024, 2 * 1024 * 1024);
|
||||
Allocator ctx_main_allocator = wapp_mem_ctx_allocator(CTX_DEST_BUFFER_MAIN);
|
||||
Allocator ctx_temp_allocator = wapp_mem_ctx_allocator(CTX_DEST_BUFFER_TEMP);
|
||||
(void)(ctx_temp_allocator);
|
||||
|
||||
const char *file_to_open = argc > 1 ? argv[1] : "./resources/test.tif";
|
||||
|
||||
FILE *fp = fopen(file_to_open, "r");
|
||||
read_baseline_tiff(file_to_open, &ctx_main_allocator);
|
||||
|
||||
TiffHdr header;
|
||||
TiffIFD ifd = {0};
|
||||
// FILE *fp = fopen(file_to_open, "rb");
|
||||
|
||||
fread(&header, sizeof(TiffHdr), 1, fp);
|
||||
// TiffHdr header;
|
||||
// fread(&header, sizeof(header), 1, fp);
|
||||
|
||||
printf("ORDER: %04x\n", header.order);
|
||||
printf("MAGIC: %04x\n", header.magic);
|
||||
// TiffIFD ifd = {0};
|
||||
|
||||
fseek(fp, header.first_ifd_offset, SEEK_SET);
|
||||
// printf("ORDER: %04x\n", header.order);
|
||||
// printf("MAGIC: %04x\n", header.magic);
|
||||
|
||||
fread(&(ifd.count), sizeof(ifd.count), 1, fp);
|
||||
// fseek(fp, header.first_ifd_offset, SEEK_SET);
|
||||
|
||||
printf("COUNT: %u\n", ifd.count);
|
||||
// fread(&(ifd.count), sizeof(ifd.count), 1, fp);
|
||||
|
||||
TiffField fields[ifd.count];
|
||||
memset(fields, 0, sizeof(TiffField) * ifd.count);
|
||||
// printf("COUNT: %u\n", ifd.count);
|
||||
|
||||
for (u32 i = 0; i < ifd.count; ++i) {
|
||||
fread(fields + i, sizeof(TiffField), 1, fp);
|
||||
printf("ENTRY %02u\n", i);
|
||||
printf("\t TAG: %04u (%s)\n", fields[i].tag,
|
||||
tag_names[fields[i].tag] ? tag_names[fields[i].tag] : "UNKNOWN");
|
||||
printf("\t TYPE: 0x%04x (%s)\n", fields[i].type,
|
||||
filed_types[fields[i].type].name ? filed_types[fields[i].type].name
|
||||
: "UNKNOWN");
|
||||
printf("\t COUNT: %04u\n", fields[i].count);
|
||||
printf("\tVAL/OFF: %04u\n", fields[i].value_offset);
|
||||
}
|
||||
// TiffField fields[ifd.count];
|
||||
// memset(fields, 0, sizeof(TiffField) * ifd.count);
|
||||
|
||||
fclose(fp);
|
||||
// for (u32 i = 0; i < ifd.count; ++i) {
|
||||
// fread(fields + i, sizeof(TiffField), 1, fp);
|
||||
// printf("ENTRY %02u (%lu)\n", i, ftell(fp));
|
||||
// printf("\t TAG: %04u (%s)\n", fields[i].tag,
|
||||
// tag_names[fields[i].tag] ? tag_names[fields[i].tag] : "UNKNOWN");
|
||||
// printf("\t TYPE: 0x%04x (%s)\n", fields[i].type,
|
||||
// field_types[fields[i].type].name ?
|
||||
// field_types[fields[i].type].name
|
||||
// : "UNKNOWN");
|
||||
// printf("\t COUNT: %04u\n", fields[i].count);
|
||||
// printf("\tVAL/OFF: %04u\n", fields[i].value_offset);
|
||||
// }
|
||||
|
||||
wapp_mem_ctx_free();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
455
src/tiffread.c
Normal file
455
src/tiffread.c
Normal file
@ -0,0 +1,455 @@
|
||||
#include "tiffread.h"
|
||||
#include "aliases.h"
|
||||
#include "endianness.h"
|
||||
#include "image.h"
|
||||
#include "mem_allocator.h"
|
||||
#include "mem_ctx.h"
|
||||
#include "mem_libc.h"
|
||||
#include <math.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TIFF_MAGIC 0x002a
|
||||
|
||||
#define TIFF_FILENAME_MIN_LENGTH 6
|
||||
#define TIFF_EXT_MAX_LENGTH 5
|
||||
#define IS_TIFF_EXTENSION(EXT) \
|
||||
(strncmp(EXT, ".tif", 4) == 0 || strncmp(EXT, ".tiff", 5) == 0)
|
||||
|
||||
#define NULL_TIFF_HEADER ((TiffHdr){0})
|
||||
#define IS_NULL_HEADER(HDR) (HDR.order == 0)
|
||||
|
||||
#define NULL_TIFF_IFD ((TiffIFD){0})
|
||||
#define IS_NULL_IFD(IFD) (IFD.count == 0)
|
||||
|
||||
enum tiff_image_types {
|
||||
TIFF_IMAGE_BILEVEL,
|
||||
TIFF_IMAGE_GRAYSCALE,
|
||||
TIFF_IMAGE_PALETTE,
|
||||
TIFF_IMAGE_RGB,
|
||||
|
||||
COUNT_TIFF_IMAGE,
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
internal u16 tiff_image_identifiers[COUNT_TIFF_IMAGE] = {
|
||||
[TIFF_IMAGE_BILEVEL] = 0,
|
||||
[TIFF_IMAGE_GRAYSCALE] = TIFF_PUBLIC_TAG_BITS_PER_SAMPLE,
|
||||
[TIFF_IMAGE_PALETTE] = TIFF_PUBLIC_TAG_BITS_PER_SAMPLE | TIFF_PUBLIC_TAG_COLOR_MAP,
|
||||
[TIFF_IMAGE_RGB] = TIFF_PUBLIC_TAG_BITS_PER_SAMPLE | TIFF_PUBLIC_TAG_SAMPLES_PER_PIXEL,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
TiffHdr read_tiff_header(FILE *fp);
|
||||
TiffIFD read_ifd(FILE *fp, const TiffHdr *header, u32 offset,
|
||||
const Allocator *allocator);
|
||||
Image *read_fields(FILE *fp, const TiffHdr *header, const TiffIFD *ifd,
|
||||
const Allocator *allocator);
|
||||
void read_from_file_with_offset(FILE *fp, void *dst, u64 count, u64 offset);
|
||||
|
||||
Image *read_baseline_tiff(const char *file, const Allocator *allocator) {
|
||||
Image *img_out = NULL;
|
||||
|
||||
if (!file) {
|
||||
goto RETURN_IMG;
|
||||
}
|
||||
|
||||
u64 name_length = strlen(file);
|
||||
if (name_length < TIFF_FILENAME_MIN_LENGTH) {
|
||||
goto RETURN_IMG;
|
||||
}
|
||||
|
||||
const char *ext = NULL;
|
||||
for (u32 i = name_length - 1; i >= name_length - TIFF_FILENAME_MIN_LENGTH;
|
||||
--i) {
|
||||
if (file[i] == '.') {
|
||||
ext = &(file[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ext || !IS_TIFF_EXTENSION(ext)) {
|
||||
goto RETURN_IMG;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(file, "rb");
|
||||
if (!fp) {
|
||||
goto RETURN_IMG;
|
||||
}
|
||||
|
||||
TiffHdr header = read_tiff_header(fp);
|
||||
if (IS_NULL_HEADER(header)) {
|
||||
goto FILE_CLEANUP;
|
||||
}
|
||||
|
||||
Allocator alloc;
|
||||
if (!allocator) {
|
||||
alloc = wapp_mem_libc_allocator();
|
||||
} else {
|
||||
alloc = *allocator;
|
||||
}
|
||||
|
||||
TiffIFD ifd = read_ifd(fp, &header, header.first_ifd_offset, &alloc);
|
||||
read_fields(fp, &header, &ifd, &alloc);
|
||||
|
||||
FILE_CLEANUP:
|
||||
fclose(fp);
|
||||
|
||||
RETURN_IMG:
|
||||
return img_out;
|
||||
}
|
||||
|
||||
TiffHdr read_tiff_header(FILE *fp) {
|
||||
if (!fp) {
|
||||
return NULL_TIFF_HEADER;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
TiffHdr header = NULL_TIFF_HEADER;
|
||||
fread((void *)&header, sizeof(TiffHdr), 1, fp);
|
||||
|
||||
switch (header.order) {
|
||||
case TIFF_ORDER_LITTLE_ENDIAN:
|
||||
if (IS_BIG_ENDIAN) {
|
||||
header.magic = htons(header.magic);
|
||||
header.first_ifd_offset = htonl(header.first_ifd_offset);
|
||||
}
|
||||
|
||||
break;
|
||||
case TIFF_ORDER_BIG_ENDIAN:
|
||||
if (IS_LITTLE_ENDIAN) {
|
||||
header.magic = ntohs(header.magic);
|
||||
header.first_ifd_offset = ntohl(header.first_ifd_offset);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return NULL_TIFF_HEADER;
|
||||
}
|
||||
|
||||
if (header.magic != TIFF_MAGIC) {
|
||||
return NULL_TIFF_HEADER;
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
TiffIFD read_ifd(FILE *fp, const TiffHdr *header, u32 offset,
|
||||
const Allocator *allocator) {
|
||||
if (!fp || !header) {
|
||||
return NULL_TIFF_IFD;
|
||||
}
|
||||
|
||||
fseek(fp, offset, SEEK_SET);
|
||||
|
||||
TiffIFD ifd = NULL_TIFF_IFD;
|
||||
|
||||
fread(&(ifd.count), sizeof(ifd.count), 1, fp);
|
||||
|
||||
switch (header->order) {
|
||||
case TIFF_ORDER_LITTLE_ENDIAN:
|
||||
if (IS_BIG_ENDIAN) {
|
||||
ifd.count = htons(ifd.count);
|
||||
}
|
||||
|
||||
break;
|
||||
case TIFF_ORDER_BIG_ENDIAN:
|
||||
if (IS_LITTLE_ENDIAN) {
|
||||
ifd.count = ntohs(ifd.count);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
u64 field_byte_count = sizeof(TiffField) * ifd.count;
|
||||
ifd.fields =
|
||||
(TiffField *)wapp_mem_allocator_alloc(allocator, field_byte_count);
|
||||
|
||||
fread(ifd.fields, field_byte_count, 1, fp);
|
||||
fread(&(ifd.next_ifd), sizeof(ifd.next_ifd), 1, fp);
|
||||
|
||||
return ifd;
|
||||
}
|
||||
|
||||
Image *read_fields(FILE *fp, const TiffHdr *header, const TiffIFD *ifd,
|
||||
const Allocator *allocator) {
|
||||
if (!fp || !header || !ifd) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u16 identifier = 0;
|
||||
|
||||
u16 photometric_interpretation = TIFF_PHOTOMETRIC_INTERPRETATION_INVALID;
|
||||
|
||||
u16 samples_per_pixel = 1;
|
||||
u16 *bits_per_sample = NULL;
|
||||
|
||||
u32 strip_count = 1;
|
||||
u8 *strip_offsets = NULL;
|
||||
u16 strip_offsets_type = TIFF_FIELD_TYPE_LONG;
|
||||
u8 *strip_byte_counts = NULL;
|
||||
u16 strip_byte_counts_type = TIFF_FIELD_TYPE_LONG;
|
||||
|
||||
u64 width = 0;
|
||||
u64 height = 0;
|
||||
|
||||
for (u64 i = 0; i < ifd->count; ++i) {
|
||||
TiffField *field = &(ifd->fields[i]);
|
||||
switch (header->order) {
|
||||
case TIFF_ORDER_LITTLE_ENDIAN:
|
||||
if (IS_BIG_ENDIAN) {
|
||||
field->tag = htons(field->tag);
|
||||
field->type = htons(field->type);
|
||||
field->count = htonl(field->count);
|
||||
field->value_offset = htonl(field->value_offset);
|
||||
}
|
||||
|
||||
break;
|
||||
case TIFF_ORDER_BIG_ENDIAN:
|
||||
if (IS_LITTLE_ENDIAN) {
|
||||
field->tag = ntohs(field->tag);
|
||||
field->type = ntohs(field->type);
|
||||
field->count = ntohl(field->count);
|
||||
field->value_offset = ntohl(field->value_offset);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch (field->tag) {
|
||||
case TIFF_PUBLIC_TAG_IMAGE_WIDTH:
|
||||
if (field->count != 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
width = field->value_offset;
|
||||
|
||||
break;
|
||||
case TIFF_PUBLIC_TAG_IMAGE_LENGTH:
|
||||
if (field->count != 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
height = field->value_offset;
|
||||
|
||||
break;
|
||||
case TIFF_PUBLIC_TAG_BITS_PER_SAMPLE:
|
||||
identifier |= field->tag;
|
||||
|
||||
u64 byte_count = field->count * sizeof(u16);
|
||||
bits_per_sample = wapp_mem_ctx_alloc(CTX_DEST_BUFFER_TEMP, byte_count);
|
||||
if (!bits_per_sample) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (byte_count <= 4) {
|
||||
bits_per_sample = (u16 *)&(field->value_offset);
|
||||
} else {
|
||||
read_from_file_with_offset(fp, bits_per_sample, byte_count,
|
||||
field->value_offset);
|
||||
|
||||
for (u64 i = 0; i < field->count; ++i) {
|
||||
switch (header->order) {
|
||||
case TIFF_ORDER_LITTLE_ENDIAN:
|
||||
if (IS_BIG_ENDIAN) {
|
||||
bits_per_sample[i] = htons(bits_per_sample[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
case TIFF_ORDER_BIG_ENDIAN:
|
||||
if (IS_LITTLE_ENDIAN) {
|
||||
bits_per_sample[i] = ntohs(bits_per_sample[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case TIFF_PUBLIC_TAG_COMPRESSION:
|
||||
if (field->count != 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (field->value_offset) {
|
||||
case TIFF_COMPRESSION_UNCOMPRESSED:
|
||||
break;
|
||||
case TIFF_COMPRESSION_CCITT_1D:
|
||||
case TIFF_COMPRESSION_GROUP_3_FAX:
|
||||
case TIFF_COMPRESSION_GROUP_4_FAX:
|
||||
case TIFF_COMPRESSION_LZW:
|
||||
case TIFF_COMPRESSION_JPEG:
|
||||
case TIFF_COMPRESSION_PACK_BITS:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
case TIFF_PUBLIC_TAG_PHOTOMETRIC_INTERPRETATION:
|
||||
photometric_interpretation = field->value_offset;
|
||||
break;
|
||||
case TIFF_PUBLIC_TAG_STRIP_OFFSETS: {
|
||||
strip_offsets_type = field->type;
|
||||
u16 field_type_byte_count = field_types[strip_offsets_type].byte_count;
|
||||
u32 total_byte_count = field->count * field_type_byte_count;
|
||||
strip_count = field->count;
|
||||
|
||||
strip_offsets =
|
||||
(u8 *)wapp_mem_ctx_alloc(CTX_DEST_BUFFER_TEMP, total_byte_count);
|
||||
if (!strip_offsets) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (total_byte_count <= 4) {
|
||||
memcpy(strip_offsets, &(field->value_offset), 4);
|
||||
|
||||
switch (header->order) {
|
||||
case TIFF_ORDER_LITTLE_ENDIAN:
|
||||
if (IS_BIG_ENDIAN) {
|
||||
u32 val = htonl(*(u32 *)strip_offsets);
|
||||
strip_offsets = (u8 *)&val;
|
||||
}
|
||||
|
||||
break;
|
||||
case TIFF_ORDER_BIG_ENDIAN:
|
||||
if (IS_LITTLE_ENDIAN) {
|
||||
u32 val = ntohl(*(u32 *)strip_offsets);
|
||||
strip_offsets = (u8 *)&val;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
read_from_file_with_offset(fp, strip_offsets, total_byte_count,
|
||||
field->value_offset);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TIFF_PUBLIC_TAG_SAMPLES_PER_PIXEL:
|
||||
if (field->count != 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
identifier |= field->tag;
|
||||
samples_per_pixel = field->value_offset;
|
||||
|
||||
break;
|
||||
case TIFF_PUBLIC_TAG_ROWS_PER_STRIP:
|
||||
if (field->count != 1 || height == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strip_count =
|
||||
floor((f64)(height + field->value_offset - 1) / field->value_offset);
|
||||
|
||||
break;
|
||||
case TIFF_PUBLIC_TAG_STRIP_BYTE_COUNTS: {
|
||||
strip_byte_counts_type = field->type;
|
||||
u16 field_type_byte_count = field_types[strip_offsets_type].byte_count;
|
||||
u32 total_byte_count = field->count * field_type_byte_count;
|
||||
strip_count = field->count;
|
||||
|
||||
strip_byte_counts =
|
||||
(u8 *)wapp_mem_ctx_alloc(CTX_DEST_BUFFER_TEMP, total_byte_count);
|
||||
if (!strip_byte_counts) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (total_byte_count <= 4) {
|
||||
memcpy(strip_byte_counts, &(field->value_offset), 4);
|
||||
|
||||
switch (header->order) {
|
||||
case TIFF_ORDER_LITTLE_ENDIAN:
|
||||
if (IS_BIG_ENDIAN) {
|
||||
u32 val = htonl(*(u32 *)strip_byte_counts);
|
||||
strip_byte_counts = (u8 *)&val;
|
||||
}
|
||||
|
||||
break;
|
||||
case TIFF_ORDER_BIG_ENDIAN:
|
||||
if (IS_LITTLE_ENDIAN) {
|
||||
u32 val = ntohl(*(u32 *)strip_byte_counts);
|
||||
strip_byte_counts = (u8 *)&val;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
read_from_file_with_offset(fp, strip_byte_counts, total_byte_count,
|
||||
field->value_offset);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TIFF_PUBLIC_TAG_PLANAR_CONFIGURATION:
|
||||
if (field->count != 1 ||
|
||||
field->value_offset != TIFF_PLANAR_CONFIG_CHUNKY) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
case TIFF_PUBLIC_TAG_COLOR_MAP:
|
||||
identifier |= field->tag;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (identifier == tiff_image_identifiers[TIFF_IMAGE_BILEVEL]) {
|
||||
printf("BILEVEL\n");
|
||||
} else if (identifier == tiff_image_identifiers[TIFF_IMAGE_GRAYSCALE]) {
|
||||
printf("GRAYSCALE\n");
|
||||
} else if (identifier == tiff_image_identifiers[TIFF_IMAGE_PALETTE]) {
|
||||
printf("PALETTE\n");
|
||||
} else if (identifier == tiff_image_identifiers[TIFF_IMAGE_RGB]) {
|
||||
printf("RGB\n");
|
||||
} else {
|
||||
printf("UNKNOWN\n");
|
||||
}
|
||||
|
||||
printf("WIDTH: %lu, HEIGHT: %lu\n", width, height);
|
||||
printf("SAMPLES: %u\n", samples_per_pixel);
|
||||
printf("STRIPS: %u\n", strip_count);
|
||||
printf("PHOTOMETRIC INTERPRETATION: %u\n", photometric_interpretation);
|
||||
for (u64 i = 0; i < samples_per_pixel; ++i) {
|
||||
printf("%u\n", bits_per_sample[i]);
|
||||
}
|
||||
|
||||
printf("OFFSETS: ");
|
||||
for (u64 i = 0; i < strip_count; ++i) {
|
||||
if (strip_offsets_type == TIFF_FIELD_TYPE_LONG) {
|
||||
printf("%u ", ((u32 *)strip_offsets)[i]);
|
||||
} else {
|
||||
printf("%u ", ((u16 *)strip_offsets)[i]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("COUNTS: ");
|
||||
for (u64 i = 0; i < strip_count; ++i) {
|
||||
if (strip_byte_counts_type == TIFF_FIELD_TYPE_LONG) {
|
||||
printf("%u ", ((u32 *)strip_byte_counts)[i]);
|
||||
} else {
|
||||
printf("%u ", ((u16 *)strip_byte_counts)[i]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void read_from_file_with_offset(FILE *fp, void *dst, u64 count, u64 offset) {
|
||||
if (!fp || !dst) {
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(fp, offset, SEEK_SET);
|
||||
|
||||
fread(dst, count, 1, fp);
|
||||
}
|
@ -6,6 +6,7 @@ extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#include "aliases.h"
|
||||
#include "image.h"
|
||||
|
||||
#define TAG_MAX_COUNT (UINT16_MAX * sizeof(const char *))
|
||||
// Technically, the type parameter is 2-bytes long, but there aren't so many
|
||||
@ -13,7 +14,7 @@ extern "C" {
|
||||
#define TYPE_MAX_COUNT (UINT8_MAX * sizeof(const char *))
|
||||
|
||||
// clang-format off
|
||||
enum {
|
||||
enum tiff_byte_order {
|
||||
TIFF_ORDER_LITTLE_ENDIAN = 0x4949,
|
||||
TIFF_ORDER_BIG_ENDIAN = 0x4d4d,
|
||||
};
|
||||
@ -31,7 +32,7 @@ enum tiff_public_tags {
|
||||
#include "tiff_public_tags.inc"
|
||||
};
|
||||
|
||||
const char *tag_names[TAG_MAX_COUNT] = {
|
||||
internal const char *tag_names[TAG_MAX_COUNT] = {
|
||||
#define TIFF_TAG_LOOKUP
|
||||
#include "tiff_public_tags.inc"
|
||||
#undef TIFF_TAG_LOOKUP
|
||||
@ -43,11 +44,11 @@ enum tiff_field_types {
|
||||
|
||||
typedef struct field_type TiffFieldType;
|
||||
struct field_type {
|
||||
const char *name;
|
||||
u16 byte_count;
|
||||
const char *name;
|
||||
u16 byte_count;
|
||||
};
|
||||
|
||||
TiffFieldType filed_types[TYPE_MAX_COUNT] = {
|
||||
internal TiffFieldType field_types[TYPE_MAX_COUNT] = {
|
||||
#define TIFF_TYPE_LOOKUP
|
||||
#include "tiff_field_types.inc"
|
||||
#undef TIFF_TYPE_LOOKUP
|
||||
@ -79,9 +80,7 @@ enum tiff_compression {
|
||||
TIFF_COMPRESSION_JPEG = 0x0006,
|
||||
TIFF_COMPRESSION_PACK_BITS = 0x8005,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
enum tiff_photometric_interpretation {
|
||||
TIFF_PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO = 0x0000,
|
||||
TIFF_PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO = 0x0001,
|
||||
@ -91,9 +90,18 @@ enum tiff_photometric_interpretation {
|
||||
TIFF_PHOTOMETRIC_INTERPRETATION_CMYK = 0x0005,
|
||||
TIFF_PHOTOMETRIC_INTERPRETATION_YCbCr = 0x0006,
|
||||
TIFF_PHOTOMETRIC_INTERPRETATION_CIELab = 0x0008,
|
||||
|
||||
TIFF_PHOTOMETRIC_INTERPRETATION_INVALID,
|
||||
};
|
||||
|
||||
enum tiff_planar_configuration {
|
||||
TIFF_PLANAR_CONFIG_CHUNKY = 0x0001,
|
||||
TIFF_PLANAR_CONFIG_PLANAR = 0x0002,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
Image *read_baseline_tiff(const char *file, const Allocator *allocator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
Loading…
x
Reference in New Issue
Block a user