Start implementing tiffread
This commit is contained in:
parent
b0d7098add
commit
e7a3fddb30
97
src/main.c
Normal file
97
src/main.c
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define TAG_MAX_COUNT (UINT16_MAX * sizeof(const char *))
|
||||||
|
// Technically, the type parameter is 2-bytes long, but there aren't so many
|
||||||
|
// types specified in the spec, so UINT8_MAX should be sufficient
|
||||||
|
#define TYPE_MAX_COUNT (UINT8_MAX * sizeof(const char *))
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
enum {
|
||||||
|
TIFF_ORDER_LITTLE_ENDIAN = 0x4949,
|
||||||
|
TIFF_ORDER_BIG_ENDIAN = 0x4d4d,
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
typedef struct hdr TiffHdr;
|
||||||
|
struct hdr {
|
||||||
|
uint16_t order;
|
||||||
|
uint16_t magic;
|
||||||
|
uint32_t first_ifd_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum tiff_public_tags {
|
||||||
|
#include "tiff_public_tags.inc"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *tag_names[TAG_MAX_COUNT] = {
|
||||||
|
#define TIFF_TAG_LOOKUP
|
||||||
|
#include "tiff_public_tags.inc"
|
||||||
|
#undef TIFF_TAG_LOOKUP
|
||||||
|
};
|
||||||
|
|
||||||
|
enum tiff_field_types {
|
||||||
|
#include "tiff_field_types.inc"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *filed_type_names[TYPE_MAX_COUNT] = {
|
||||||
|
#define TIFF_TYPE_LOOKUP
|
||||||
|
#include "tiff_field_types.inc"
|
||||||
|
#undef TIFF_TYPE_LOOKUP
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct field TiffField;
|
||||||
|
struct field {
|
||||||
|
uint16_t tag;
|
||||||
|
uint16_t type;
|
||||||
|
uint32_t count;
|
||||||
|
uint32_t value_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct IFD TiffIFD;
|
||||||
|
struct IFD {
|
||||||
|
uint16_t count;
|
||||||
|
TiffField *fields;
|
||||||
|
uint32_t next_ifd;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
const char *file_to_open = argc > 1 ? argv[1] : "./resources/test.tif";
|
||||||
|
|
||||||
|
FILE *fp = fopen(file_to_open, "r");
|
||||||
|
|
||||||
|
TiffHdr header;
|
||||||
|
TiffIFD ifd = {0};
|
||||||
|
|
||||||
|
fread(&header, sizeof(TiffHdr), 1, fp);
|
||||||
|
|
||||||
|
printf("ORDER: %04x\n", header.order);
|
||||||
|
printf("MAGIC: %04x\n", header.magic);
|
||||||
|
|
||||||
|
fseek(fp, header.first_ifd_offset, SEEK_SET);
|
||||||
|
|
||||||
|
fread(&(ifd.count), sizeof(ifd.count), 1, fp);
|
||||||
|
|
||||||
|
printf("COUNT: %u\n", ifd.count);
|
||||||
|
|
||||||
|
TiffField fields[ifd.count];
|
||||||
|
memset(fields, 0, sizeof(TiffField) * ifd.count);
|
||||||
|
|
||||||
|
for (uint32_t 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_type_names[fields[i].type] ? filed_type_names[fields[i].type]
|
||||||
|
: "UNKNOWN");
|
||||||
|
printf("\t COUNT: %04u\n", fields[i].count);
|
||||||
|
printf("\tVAL/OFF: %04u\n", fields[i].value_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
20
src/tiff_field_types.inc
Normal file
20
src/tiff_field_types.inc
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifdef TIFF_TYPE_LOOKUP
|
||||||
|
#undef TIFF_TYPE
|
||||||
|
#define TIFF_TYPE(NAME, ID, VALUE) [VALUE] = NAME,
|
||||||
|
#else
|
||||||
|
#undef TIFF_TYPE
|
||||||
|
#define TIFF_TYPE(NAME, ID, VALUE) ID = VALUE,
|
||||||
|
#endif /* ifdef TIFF_TYPE_LOOKUP */
|
||||||
|
|
||||||
|
TIFF_TYPE("UNSIGNED BYTE" , TIFF_ENTRY_BYTE , 0x0001) // 8-bit unsigned integer
|
||||||
|
TIFF_TYPE("ASCII" , TIFF_ENTRY_ASCII , 0x0002) // 8-bit byte that contains a 7-bit ASCII code; the last byte must be NUL (binary zero)
|
||||||
|
TIFF_TYPE("UNSIGNED SHORT" , TIFF_ENTRY_SHORT , 0x0003) // 16-bit (2-byte) unsigned integer
|
||||||
|
TIFF_TYPE("UNSIGNED LONG" , TIFF_ENTRY_LONG , 0x0004) // 32-bit (4-byte) unsigned integer
|
||||||
|
TIFF_TYPE("UNSIGNED RATIONAL", TIFF_ENTRY_RATIONAL , 0x0005) // Two LONGs: the first represents the numerator of a fraction; the second, the denominator
|
||||||
|
TIFF_TYPE("SIGNED BYTE" , TIFF_ENTRY_SBYTE , 0x0006) // An 8-bit signed (twos-complement) integer
|
||||||
|
TIFF_TYPE("UNDEFINED" , TIFF_ENTRY_UNDEFINED , 0x0007) // An 8-bit byte that may contain anything, depending on the definition of the field
|
||||||
|
TIFF_TYPE("SIGNED SHORT" , TIFF_ENTRY_SSHORT , 0x0008) // A 16-bit (2-byte) signed (twos-complement) integer
|
||||||
|
TIFF_TYPE("SIGNED LONG" , TIFF_ENTRY_SLONG , 0x0009) // A 32-bit (4-byte) signed (twos-complement) integer
|
||||||
|
TIFF_TYPE("SIGNED RATIONAL" , TIFF_ENTRY_SRATIONAL , 0x000a) // Two SLONG’s: the first represents the numerator of a fraction, the second the denominator
|
||||||
|
TIFF_TYPE("FLOAT" , TIFF_ENTRY_FLOAT , 0x000b) // Single precision (4-byte) IEEE format
|
||||||
|
TIFF_TYPE("DOUBLE" , TIFF_ENTRY_DOUBLE , 0x000c) // Double precision (8-byte) IEEE format
|
82
src/tiff_public_tags.inc
Normal file
82
src/tiff_public_tags.inc
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#ifdef TIFF_TAG_LOOKUP
|
||||||
|
#undef TIFF_TAG
|
||||||
|
#define TIFF_TAG(NAME, ID, VALUE) [VALUE] = NAME,
|
||||||
|
#else
|
||||||
|
#undef TIFF_TAG
|
||||||
|
#define TIFF_TAG(NAME, ID, VALUE) ID = VALUE,
|
||||||
|
#endif /* ifdef TIFF_TAG_LOOKUP */
|
||||||
|
|
||||||
|
TIFF_TAG("NEW_SUBFILE_TYPE" , TIFF_PUBLIC_TAG_NEW_SUBFILE_TYPE , 0x00fe)
|
||||||
|
TIFF_TAG("SUBFILE_TYPE" , TIFF_PUBLIC_TAG_SUBFILE_TYPE , 0x00ff)
|
||||||
|
TIFF_TAG("IMAGE_WIDTH" , TIFF_PUBLIC_TAG_IMAGE_WIDTH , 0x0100)
|
||||||
|
TIFF_TAG("IMAGE_LENGTH" , TIFF_PUBLIC_TAG_IMAGE_LENGTH , 0x0101)
|
||||||
|
TIFF_TAG("BITS_PER_SAMPLE" , TIFF_PUBLIC_TAG_BITS_PER_SAMPLE , 0x0102)
|
||||||
|
TIFF_TAG("COMPRESSION" , TIFF_PUBLIC_TAG_COMPRESSION , 0x0103)
|
||||||
|
TIFF_TAG("PHOTOMETRIC_INTERPRETATION" , TIFF_PUBLIC_TAG_PHOTOMETRIC_INTERPRETATION , 0x0106)
|
||||||
|
TIFF_TAG("THRESHHOLDING" , TIFF_PUBLIC_TAG_THRESHHOLDING , 0x0107)
|
||||||
|
TIFF_TAG("CELL_WIDTH" , TIFF_PUBLIC_TAG_CELL_WIDTH , 0x0108)
|
||||||
|
TIFF_TAG("CELL_LENGTH" , TIFF_PUBLIC_TAG_CELL_LENGTH , 0x0109)
|
||||||
|
TIFF_TAG("FILL_ORDER" , TIFF_PUBLIC_TAG_FILL_ORDER , 0x010a)
|
||||||
|
TIFF_TAG("DOCUMENT_NAME" , TIFF_PUBLIC_TAG_DOCUMENT_NAME , 0x010d)
|
||||||
|
TIFF_TAG("IMAGE_DESCRIPTION" , TIFF_PUBLIC_TAG_IMAGE_DESCRIPTION , 0x010e)
|
||||||
|
TIFF_TAG("MAKE" , TIFF_PUBLIC_TAG_MAKE , 0x010f)
|
||||||
|
TIFF_TAG("MODEL" , TIFF_PUBLIC_TAG_MODEL , 0x0110)
|
||||||
|
TIFF_TAG("STRIP_OFFSETS" , TIFF_PUBLIC_TAG_STRIP_OFFSETS , 0x0111)
|
||||||
|
TIFF_TAG("ORIENTATION" , TIFF_PUBLIC_TAG_ORIENTATION , 0x0112)
|
||||||
|
TIFF_TAG("SAMPLES_PER_PIXEL" , TIFF_PUBLIC_TAG_SAMPLES_PER_PIXEL , 0x0115)
|
||||||
|
TIFF_TAG("ROWS_PER_STRIP" , TIFF_PUBLIC_TAG_ROWS_PER_STRIP , 0x0116)
|
||||||
|
TIFF_TAG("STRIP_BYTE_COUNTS" , TIFF_PUBLIC_TAG_STRIP_BYTE_COUNTS , 0x0117)
|
||||||
|
TIFF_TAG("MIN_SAMPLE_VALUE" , TIFF_PUBLIC_TAG_MIN_SAMPLE_VALUE , 0x0118)
|
||||||
|
TIFF_TAG("MAX_SAMPLE_VALUE" , TIFF_PUBLIC_TAG_MAX_SAMPLE_VALUE , 0x0119)
|
||||||
|
TIFF_TAG("X_RESOLUTION" , TIFF_PUBLIC_TAG_X_RESOLUTION , 0x011a)
|
||||||
|
TIFF_TAG("Y_RESOLUTION" , TIFF_PUBLIC_TAG_Y_RESOLUTION , 0x011b)
|
||||||
|
TIFF_TAG("PLANAR_CONFIGURATION" , TIFF_PUBLIC_TAG_PLANAR_CONFIGURATION , 0x011c)
|
||||||
|
TIFF_TAG("PAGE_NAME" , TIFF_PUBLIC_TAG_PAGE_NAME , 0x011d)
|
||||||
|
TIFF_TAG("X_POSITION" , TIFF_PUBLIC_TAG_X_POSITION , 0x011e)
|
||||||
|
TIFF_TAG("Y_POSITION" , TIFF_PUBLIC_TAG_Y_POSITION , 0x011f)
|
||||||
|
TIFF_TAG("FREE_OFFSETS" , TIFF_PUBLIC_TAG_FREE_OFFSETS , 0x0120)
|
||||||
|
TIFF_TAG("FREE_BYTE_COUNTS" , TIFF_PUBLIC_TAG_FREE_BYTE_COUNTS , 0x0121)
|
||||||
|
TIFF_TAG("GRAY_RESPONSE_UNIT" , TIFF_PUBLIC_TAG_GRAY_RESPONSE_UNIT , 0x0122)
|
||||||
|
TIFF_TAG("GRAY_RESPONSE_CURVE" , TIFF_PUBLIC_TAG_GRAY_RESPONSE_CURVE , 0x0123)
|
||||||
|
TIFF_TAG("T4_OPTIONS" , TIFF_PUBLIC_TAG_T4_OPTIONS , 0x0124)
|
||||||
|
TIFF_TAG("T6_OPTIONS" , TIFF_PUBLIC_TAG_T6_OPTIONS , 0x0125)
|
||||||
|
TIFF_TAG("RESOLUTION_UNIT" , TIFF_PUBLIC_TAG_RESOLUTION_UNIT , 0x0128)
|
||||||
|
TIFF_TAG("PAGE_NUMBER" , TIFF_PUBLIC_TAG_PAGE_NUMBER , 0x0129)
|
||||||
|
TIFF_TAG("TRANSFER_FUNCTION" , TIFF_PUBLIC_TAG_TRANSFER_FUNCTION , 0x012d)
|
||||||
|
TIFF_TAG("SOFTWARE" , TIFF_PUBLIC_TAG_SOFTWARE , 0x0131)
|
||||||
|
TIFF_TAG("DATE_TIME" , TIFF_PUBLIC_TAG_DATE_TIME , 0x0132)
|
||||||
|
TIFF_TAG("ARTIST" , TIFF_PUBLIC_TAG_ARTIST , 0x013b)
|
||||||
|
TIFF_TAG("HOST_COMPUTER" , TIFF_PUBLIC_TAG_HOST_COMPUTER , 0x013c)
|
||||||
|
TIFF_TAG("PREDICTOR" , TIFF_PUBLIC_TAG_PREDICTOR , 0x013d)
|
||||||
|
TIFF_TAG("WHITE_POINT" , TIFF_PUBLIC_TAG_WHITE_POINT , 0x013e)
|
||||||
|
TIFF_TAG("PRIMARY_CHROMATICITIES" , TIFF_PUBLIC_TAG_PRIMARY_CHROMATICITIES , 0x013f)
|
||||||
|
TIFF_TAG("COLOR_MAP" , TIFF_PUBLIC_TAG_COLOR_MAP , 0x0140)
|
||||||
|
TIFF_TAG("HALFTONE_HINTS" , TIFF_PUBLIC_TAG_HALFTONE_HINTS , 0x0141)
|
||||||
|
TIFF_TAG("TILE_WIDTH" , TIFF_PUBLIC_TAG_TILE_WIDTH , 0x0142)
|
||||||
|
TIFF_TAG("TILE_LENGTH" , TIFF_PUBLIC_TAG_TILE_LENGTH , 0x0143)
|
||||||
|
TIFF_TAG("TILE_OFFSETS" , TIFF_PUBLIC_TAG_TILE_OFFSETS , 0x0144)
|
||||||
|
TIFF_TAG("TILE_BYTE_COUNTS" , TIFF_PUBLIC_TAG_TILE_BYTE_COUNTS , 0x0145)
|
||||||
|
TIFF_TAG("INK_SET" , TIFF_PUBLIC_TAG_INK_SET , 0x014c)
|
||||||
|
TIFF_TAG("INK_NAMES" , TIFF_PUBLIC_TAG_INK_NAMES , 0x014d)
|
||||||
|
TIFF_TAG("NUMBER_OF_INKS" , TIFF_PUBLIC_TAG_NUMBER_OF_INKS , 0x014e)
|
||||||
|
TIFF_TAG("DOT_RANGE" , TIFF_PUBLIC_TAG_DOT_RANGE , 0x0150)
|
||||||
|
TIFF_TAG("TARGET_PRINTER" , TIFF_PUBLIC_TAG_TARGET_PRINTER , 0x0151)
|
||||||
|
TIFF_TAG("EXTRA_SAMPLES" , TIFF_PUBLIC_TAG_EXTRA_SAMPLES , 0x0152)
|
||||||
|
TIFF_TAG("SAMPLE_FORMAT" , TIFF_PUBLIC_TAG_SAMPLE_FORMAT , 0x0153)
|
||||||
|
TIFF_TAG("S_MIN_SAMPLE_VALUE" , TIFF_PUBLIC_TAG_S_MIN_SAMPLE_VALUE , 0x0154)
|
||||||
|
TIFF_TAG("S_MAX_SAMPLE_VALUE" , TIFF_PUBLIC_TAG_S_MAX_SAMPLE_VALUE , 0x0155)
|
||||||
|
TIFF_TAG("TRANSFER_RANGE" , TIFF_PUBLIC_TAG_TRANSFER_RANGE , 0x0156)
|
||||||
|
TIFF_TAG("JPEG_PROC" , TIFF_PUBLIC_TAG_JPEG_PROC , 0x0200)
|
||||||
|
TIFF_TAG("JPEG_INTERCHANGE_FORMAT" , TIFF_PUBLIC_TAG_JPEG_INTERCHANGE_FORMAT , 0x0201)
|
||||||
|
TIFF_TAG("JPEG_INTERCHANGE_FORMAT_LENGTH", TIFF_PUBLIC_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH , 0x0202)
|
||||||
|
TIFF_TAG("JPEG_RESTART_INTERVAL" , TIFF_PUBLIC_TAG_JPEG_RESTART_INTERVAL , 0x0203)
|
||||||
|
TIFF_TAG("JPEG_LOSSLESS_PREDICTORS" , TIFF_PUBLIC_TAG_JPEG_LOSSLESS_PREDICTORS , 0x0205)
|
||||||
|
TIFF_TAG("JPEG_POINT_TRANSFORMS" , TIFF_PUBLIC_TAG_JPEG_POINT_TRANSFORMS , 0x0206)
|
||||||
|
TIFF_TAG("JPEG_QTABLES" , TIFF_PUBLIC_TAG_JPEG_QTABLES , 0x0207)
|
||||||
|
TIFF_TAG("JPEG_DCTABLES" , TIFF_PUBLIC_TAG_JPEG_DCTABLES , 0x0208)
|
||||||
|
TIFF_TAG("JPEG_ACTABLES" , TIFF_PUBLIC_TAG_JPEG_ACTABLES , 0x0209)
|
||||||
|
TIFF_TAG("YCBCR_COEFFICIENTS" , TIFF_PUBLIC_TAG_YCBCR_COEFFICIENTS , 0x0211)
|
||||||
|
TIFF_TAG("YCBCR_SUB_SAMPLING" , TIFF_PUBLIC_TAG_YCBCR_SUB_SAMPLING , 0x0212)
|
||||||
|
TIFF_TAG("YCBCR_POSITIONING" , TIFF_PUBLIC_TAG_YCBCR_POSITIONING , 0x0213)
|
||||||
|
TIFF_TAG("REFERENCE_BLACK_WHITE" , TIFF_PUBLIC_TAG_REFERENCE_BLACK_WHITE , 0x0214)
|
||||||
|
TIFF_TAG("COPYRIGHT" , TIFF_PUBLIC_TAG_COPYRIGHT , 0x8298)
|
Loading…
Reference in New Issue
Block a user