TIFFCUSTOMDIRECTORY(3tiff) LibTIFF TIFFCUSTOMDIRECTORY(3tiff) NNAAMMEE TIFFCustomDirectory - routines to create a custom directory SSYYNNOOPPSSIISS #include iinntt TTIIFFFFCCrreeaatteeCCuussttoommDDiirreeccttoorryy((TTIIFFFF **ttiiff,, ccoonnsstt TTIIFFFFFFiieellddAArrrraayy **iinnffooaarr-- rraayy)) iinntt TTIIFFFFCCrreeaatteeEEXXIIFFDDiirreeccttoorryy((TTIIFFFF **ttiiff)) iinntt TTIIFFFFCCrreeaatteeGGPPSSDDiirreeccttoorryy((TTIIFFFF **ttiiff)) iinntt TTIIFFFFWWrriitteeCCuussttoommDDiirreeccttoorryy((TTIIFFFF **ttiiff,, uuiinntt6644 **ppddiirrooffff)) iinntt TTIIFFFFRReeaaddCCuussttoommDDiirreeccttoorryy((TTIIFFFF **ttiiff,, ttooffff__tt ddiirrooffff,, ccoonnsstt TTIIFFFFFFiieelldd-- AArrrraayy **iinnffooaarrrraayy)) iinntt TTIIFFFFRReeaaddEEXXIIFFDDiirreeccttoorryy((TTIIFFFF **ttiiff,, ttooffff__tt ddiirrooffff)) iinntt TTIIFFFFRReeaaddGGPPSSDDiirreeccttoorryy((TTIIFFFF **ttiiff,, ttooffff__tt ddiirrooffff)) ccoonnsstt TTIIFFFFFFiieellddAArrrraayy **__TTIIFFFFGGeettEExxiiffFFiieellddss((vvooiidd)) ccoonnsstt TTIIFFFFFFiieellddAArrrraayy **__TTIIFFFFGGeettGGppssFFiieellddss((vvooiidd)) DDEESSCCRRIIPPTTIIOONN The following routines create a custom directory and retrieve informa- tion about directories in an open TIFF file. _T_I_F_F_C_r_e_a_t_e_C_u_s_t_o_m_D_i_r_e_c_t_o_r_y_(_), _T_I_F_F_C_r_e_a_t_e_E_X_I_F_D_i_r_e_c_t_o_r_y_(_), _T_I_F_F_C_r_e_a_t_e_G_P_S_D_i_r_e_c_t_o_r_y_(_) will setup a custom directory or one of the predefined EXIF or GPS directories and set the context of the TIFF-han- dle ttiiff to that custom directory for functions like _T_I_F_F_S_e_t_F_i_e_l_d_(_). _T_I_F_F_W_r_i_t_e_C_u_s_t_o_m_D_i_r_e_c_t_o_r_y_(_) will write the contents of the current cus- tom directory to the file and return the offset to that directory in ppddiirrooffff. That offset has to be written to the main-IFD: /* Go back to the first directory, and add the EXIFIFD pointer. */ TIFFSetDirectory(tif, 0); TIFFSetField(tif, TIFFTAG_EXIFIFD, pdiroff); _T_I_F_F_R_e_a_d_C_u_s_t_o_m_D_i_r_e_c_t_o_r_y_(_) will read the custom directory from the arbi- trary offset into the iinnffooaarrrraayy and sets the context of the TIFF-handle ttiiff to that custom directory for functions like TTIIFFFFRReeaaddFFiieelldd(()). The TTIIFFFFFFiieellddAArrrraayy iinnffooaarrrraayy has to be according the layout of the custom directory. For the predefined EXIF and GPS directories, the relevant TTIIFFFFFFiieellddAArrrraayy definitions are hidden within the functions _T_I_F_F_R_e_a_d_E_X_I_F_D_i_r_e_c_t_o_r_y_(_) and _T_I_F_F_R_e_a_d_G_P_S_D_i_r_e_c_t_o_r_y_(_) The code is very similar to _T_I_F_F_R_e_a_d_D_i_r_e_c_t_o_r_y_(_). The offset to the custom directory diroff has to be read from the relative TIFF tag first. ___T_I_F_F_G_e_t_E_x_i_f_F_i_e_l_d_s_(_) and ___T_I_F_F_G_e_t_G_p_s_F_i_e_l_d_s_(_) will return a pointer to the lliibbttiiffff internal definition list of the EXIF and GPS tags, respec- tively. NNOOTTEESS Be aware +o that until a directory is not written to file AND read back, the query functions wont retrieve the correct information! +o that the newly created directory will not exist on the file till _T_I_F_F_W_r_i_t_e_D_i_r_e_c_t_o_r_y_(_), _T_I_F_F_C_h_e_c_k_p_o_i_n_t_D_i_r_e_c_t_o_r_y_(_), _T_I_F_F_F_l_u_s_h_(_) or _T_I_F_F_C_l_o_s_e_(_) has been called. +o that _T_I_F_F_C_r_e_a_t_e_D_i_r_e_c_t_o_r_y_(_) and _T_I_F_F_W_r_i_t_e_D_i_r_e_c_t_o_r_y_(_) create a new directory, free the **ttiiff structure and set up a new one. +o that unlike _T_I_F_F_W_r_i_t_e_D_i_r_e_c_t_o_r_y_(_), _T_I_F_F_C_h_e_c_k_p_o_i_n_t_D_i_r_e_c_t_o_r_y_(_) does not free up the directory data structures in memory. +o that LibTiff does not support custom directory chains (NextIFD point- ing to another IFD). NextIFD of custom directories is always set to zero and should be zero when reading. Unfortunately to create or read custom directories with predefined fields it is necessary to include the private tif_dir.h. However, for EXIF and GPS directories, which have a predefined schema within lliibbttiiffff, this is not necessary. There are some test programmes that briefly demonstrate the creation and reading of EXIF, GPS and custom directories. See test/custom_dir.c and test/custom_dir_EXIF_231.c HHIINNTTSS AANNDD DDEETTAAIILLEEDD IINNSSTTRRUUCCTTIIOONNSS Writing TIFF files with more than one directory (IFD) is not easy because some side effects need to be known. The main point here is that there can only be one ttiiff structure in the main memory for a file, which can only hold the tags of one directory at a time. It is useless to work with two different tiffOut1, tiffOut2 pointers, because there is only ONE TIFF object (TIFF directory) within the lliibbttiiffff. If you want to address a second directory in the file, the tags of the current directory must first be saved in the file, other- wise they will be lost (overwritten or mixed). Then the ttiiff structure in the main memory must be tidied up, otherwise the old tags will bein- cluded in the new directory. This can be done either by creating a new, empty ttiiff structure or by reading in an directory previously saved in the file. A sequence to handle a second (or third) TIFF directory - in this case the GPS IFD - is as follows: 1. Create TIFF file 2. Complete the normal metadata 3. Set the tag for the custom directory with a dummy value in order to get the tag reserved. The final value will be inserted lateron. This prevents the main directory from being written to the file again at an additional area, leaving the first memory area unused: TIFFSetField(tiffOut, TIFFTAG_GPSIFD, dir_offset); 4. Save current TIFF-directory to file. Otherwise, it will be lost. Remember also the number of the current directory: TIFFWriteDirectory(tiffOut); dirNum = TIFFCurrentDirectory(tiffOut); 5. Create the second TIFF-directory (e.g. custom directory) and set its fields. The TIFFFieldArray infoarray has to be specified beforehand somewhere in your private include files. An example is given for the EXIF directory in tif_dirinfo.c TIFFCreateCustomDirectory(tiffOut, infoarray); /* for a real custom directory */ /* or alternatively, use GPS or EXIF with pre-defined TIFFFieldArray IFD field structure */ TIFFCreateGPSDirectory(tiffOut); TIFFSetField(tiffOut, GPSTAG_VERSIONID, gpsVersion); /* set fields of the custom directory */ Be aware that every _T_I_F_F_C_r_e_a_t_e_D_i_r_e_c_t_o_r_y_(_) or _T_I_F_F_W_r_i_t_e_D_i_r_e_c_t_o_r_y_(_) apparently frees the **ttiiff structure and sets up a new one! 6. Write custom directory to file. The offset to that directory in the file is returned in ddiirr__ooffffsseett. TIFFWriteCustomDirectory(tiffOut, &dir_offset); 7. Reload the first directory (i.e. the original TIFF directory). Apparently, this reads the data back from file. TIFFSetDirectory(tiffOut, dirNum); 8. Set the correct offset value of the custom directory IFD tag and save that changes to file. TIFFSetField(tiffOut, TIFFTAG_GPSIFD, dir_offset); TIFFWriteDirectory(tiffOut); RREETTUURRNN VVAALLUUEESS 1 is returned when the contents are successfully written to the file. Otherwise, 0 is returned if an error was encountered when writing the directory contents. DDIIAAGGNNOOSSTTIICCSS All error messages are directed to the _T_I_F_F_E_r_r_o_r_E_x_t_R_(_) routine. Like- wise, warning messages are directed to the _T_I_F_F_W_a_r_n_i_n_g_E_x_t_R_(_) routine. SSEEEE AALLSSOO _l_i_b_t_i_f_f (3tiff), _T_I_F_F_C_r_e_a_t_e_D_i_r_e_c_t_o_r_y (3tiff), _T_I_F_F_q_u_e_r_y (3tiff), _T_I_F_F_S_e_t_D_i_r_e_c_t_o_r_y (3tiff), _T_I_F_F_W_r_i_t_e_D_i_r_e_c_t_o_r_y (3tiff) AAUUTTHHOORR LibTIFF contributors CCOOPPYYRRIIGGHHTT 1988-2022, LibTIFF contributors 4.6 Sep 08, 2023 TIFFCUSTOMDIRECTORY(3tiff)