Start implementing tiffread
This commit is contained in:
		
							
								
								
									
										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) | ||||
		Reference in New Issue
	
	Block a user