int TIFFFlush(TIFF* tif) { if( tif->tif_mode == O_RDONLY ) return 1; if (!TIFFFlushData(tif)) return (0); /* In update (r+) mode we try to detect the case where only the strip/tile map has been altered, and we try to rewrite only that portion of the directory without making any other changes */ if( (tif->tif_flags & TIFF_DIRTYSTRIP) && !(tif->tif_flags & TIFF_DIRTYDIRECT) && tif->tif_mode == O_RDWR ) { uint64 *offsets=NULL, *sizes=NULL; if( TIFFIsTiled(tif) ) { if( TIFFGetField( tif, TIFFTAG_TILEOFFSETS, &offsets ) && TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &sizes ) && _TIFFRewriteField( tif, TIFFTAG_TILEOFFSETS, TIFF_LONG8, tif->tif_dir.td_nstrips, offsets ) && _TIFFRewriteField( tif, TIFFTAG_TILEBYTECOUNTS, TIFF_LONG8, tif->tif_dir.td_nstrips, sizes ) ) { tif->tif_flags &= ~TIFF_DIRTYSTRIP; tif->tif_flags &= ~TIFF_BEENWRITING; return 1; } } else { if( TIFFGetField( tif, TIFFTAG_STRIPOFFSETS, &offsets ) && TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &sizes ) && _TIFFRewriteField( tif, TIFFTAG_STRIPOFFSETS, TIFF_LONG8, tif->tif_dir.td_nstrips, offsets ) && _TIFFRewriteField( tif, TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG8, tif->tif_dir.td_nstrips, sizes ) ) { tif->tif_flags &= ~TIFF_DIRTYSTRIP; tif->tif_flags &= ~TIFF_BEENWRITING; return 1; } } } if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP)) && !TIFFRewriteDirectory(tif)) return (0); return (1); }
int main(int argc, char* argv[]) { TIFF *tiff; double res = 17.74; int i; if (argc < 2) return 1; res = atof(argv[1]); res = 1.0 / (res * 1.0e-4); for (i=2;i<argc;i++) { tiff = TIFFOpen(argv[i], "r+"); if (tiff == NULL) { perror(argv[i]); return 2; } /* For list of available tags and tag values see tiff.h */ if (TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER) != 1) fprintf( stderr, "Failed to set ResolutionUnit.\n"); /* Don't forget to calculate and set new resolution values */ if (TIFFSetField(tiff, TIFFTAG_XRESOLUTION, res) != 1) fprintf( stderr, "Failed to set XResolution.\n"); if (TIFFSetField(tiff, TIFFTAG_YRESOLUTION, res) != 1) fprintf( stderr, "Failed to set YResolution.\n"); TIFFRewriteDirectory(tiff); TIFFClose(tiff); } return 0; }
__declspec(dllexport) int AppendPage(int*& FileRef, double* DataArray, uint32 ImageHeight, uint32 ImageWidth, char* ImageType) { uint16 SamplesPerPixel, BitsPerSample; uint8* DataArray_uint8 = (uint8*) DataArray; uint16* DataArray_uint16 = (uint16*)DataArray; int16* DataArray_int16 = (int16*)DataArray; uint32* DataArray_RGBA32 = (uint32*)DataArray; uint64* DataArray_RGBA64 = (uint64*)DataArray; float* DataArray_float32 = (float*)DataArray; tsize_t StripSize; uint32 rows; int nPixels = ImageWidth * ImageHeight; tstrip_t nStrips; if (!strcmp(ImageType, "uint8")) { BitsPerSample = 8; SamplesPerPixel = 1; DataArray_uint8 = new uint8[nPixels]; for (int i = 0; i < nPixels; i++) DataArray_uint8[i] = (uint8)DataArray[i]; } else if (!strcmp(ImageType, "uint16")) { BitsPerSample = 16; SamplesPerPixel = 1; DataArray_uint16 = new uint16[nPixels]; for (int i = 0; i < nPixels; i++) DataArray_uint16[i] = (uint16)DataArray[i]; } else if (!strcmp(ImageType, "int16")) { BitsPerSample = 16; SamplesPerPixel = 1; DataArray_int16 = new int16[nPixels]; for (int i = 0; i < nPixels; i++) DataArray_int16[i] = (int16)DataArray[i]; } else if (!strcmp(ImageType, "RGBA32")) { BitsPerSample = 8; SamplesPerPixel = 4; DataArray_RGBA32 = new uint32[nPixels]; for (int i = 0; i < nPixels; i++) DataArray_RGBA32[i] = (uint32)DataArray[i]; } else if (!strcmp(ImageType, "RGBA64")) { BitsPerSample = 16; SamplesPerPixel = 4; DataArray_RGBA64 = new uint64[nPixels]; for (int i = 0; i < nPixels; i++) DataArray_RGBA64[i] = (uint64)DataArray[i]; } else if (!strcmp(ImageType, "float32")) { BitsPerSample = 32; SamplesPerPixel = 1; DataArray_float32 = new float[nPixels]; for (int i = 0; i < nPixels; i++) DataArray_float32[i] = (float)DataArray[i]; } TIFF *tif = (TIFF*)FileRef; TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, ImageWidth); TIFFSetField(tif, TIFFTAG_IMAGELENGTH, ImageHeight); TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, SamplesPerPixel); TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, BitsPerSample); TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, 1); // black is zero TIFFSetField(tif, TIFFTAG_COMPRESSION, 5); // LZW compression rows = TIFFDefaultStripSize(tif, 0); TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rows); nStrips = TIFFNumberOfStrips(tif); StripSize = TIFFStripSize(tif); // the code works fine for even number of rows. A proper handling of remainders should be introduced. // currently, the remainders are just not used. int striprows = (int)rows * (int)nStrips; if (striprows > (int)ImageHeight) { nStrips = nStrips - 1; TIFFSetField(tif, TIFFTAG_IMAGELENGTH, ImageHeight-1); } for (tstrip_t StripCount = 0; StripCount < nStrips; StripCount++) { if (!strcmp(ImageType, "uint8")) TIFFWriteEncodedStrip(tif, StripCount, &DataArray_uint8[StripCount * StripSize], StripSize); else if (!strcmp(ImageType, "uint16")) TIFFWriteEncodedStrip(tif, StripCount, &DataArray_uint16[(StripCount * StripSize)/2], StripSize); else if (!strcmp(ImageType, "int16")) TIFFWriteEncodedStrip(tif, StripCount, &DataArray_int16[(StripCount * StripSize)/2], StripSize); else if (!strcmp(ImageType, "RGBA32")) TIFFWriteEncodedStrip(tif, StripCount, &DataArray_RGBA32[(StripCount * StripSize)/4], StripSize); else if (!strcmp(ImageType, "RGBA64")) TIFFWriteEncodedStrip(tif, StripCount, &DataArray_RGBA64[(StripCount * StripSize)/4], StripSize); else if (!strcmp(ImageType, "float32")) TIFFWriteEncodedStrip(tif, StripCount, &DataArray_float32[(StripCount * StripSize)/4], StripSize); } TIFFRewriteDirectory(tif); if (!strcmp(ImageType, "uint8")) { delete[] DataArray_uint8; } else if (!strcmp(ImageType, "uint16")) { delete[] DataArray_uint16; } else if (!strcmp(ImageType, "int16")) { delete[] DataArray_int16; } else if (!strcmp(ImageType, "RGBA32")) { delete[] DataArray_RGBA32; } else if (!strcmp(ImageType, "RGBA64")) { delete[] DataArray_RGBA64; } else if (!strcmp(ImageType, "float32")) { delete [] DataArray_float32; } return 0; }
int main(int argc, char* argv[]) { TIFF *tiff; int arg_index; if (argc < 2) usage(); tiff = TIFFOpen(argv[argc-1], "r+"); if (tiff == NULL) return (-2); for( arg_index = 1; arg_index < argc-1; arg_index++ ) { if( strcmp(argv[arg_index],"-s") == 0 && arg_index < argc-3 ) { ttag_t id; if( atoi(argv[arg_index+1]) > 0 ) id = atoi(argv[arg_index+1]); else id = field_name_to_id(argv[arg_index+1]); if( id < 1 ) { fprintf( stderr, "Field name %s not recognised.\n" ); exit( -3 ); } if( TIFFSetField( tiff, id, argv[arg_index+2] ) != 1 ) { fprintf( stderr, "Failed to set %s=%s\n", argv[arg_index+1], argv[arg_index+2] ); } arg_index += 2; } else if( strcmp(argv[arg_index],"-sf") == 0 && arg_index < argc-3 ) { ttag_t id; FILE *fp; char *text; int len; if( atoi(argv[arg_index+1]) > 0 ) id = atoi(argv[arg_index+1]); else id = field_name_to_id(argv[arg_index+1]); if( id < 1 ) { fprintf( stderr, "Field name %s not recognised.\n" ); exit( -3 ); } fp = fopen( argv[arg_index+2], "rt" ); if( fp == NULL ) { perror( argv[arg_index+2] ); continue; } text = (char *) malloc(66000); len = fread( text, 1, 65535, fp ); text[len] = '\0'; fclose( fp ); if( TIFFSetField( tiff, id, text ) != 1 ) { fprintf( stderr, "Failed to set %s=%s\n", argv[arg_index+1], argv[arg_index+2] ); } free( text ); arg_index += 2; } else { fprintf( stderr, "Unrecognised option: %s\n", argv[arg_index] ); usage(); } } #ifdef notdef tiff->tif_header.tiff_diroff = 0; tiff->tif_diroff = 0; #endif TIFFRewriteDirectory(tiff); TIFFClose(tiff); return (0); }
int main(int argc, char* argv[]) { TIFF *tiff; int arg_index; if (argc < 2) usage(); tiff = TIFFOpen(argv[argc-1], "r+"); if (tiff == NULL) return 2; for( arg_index = 1; arg_index < argc-1; arg_index++ ) { if (strcmp(argv[arg_index],"-s") == 0 && arg_index < argc-3) { const TIFFFieldInfo *fip; const char *tagname; arg_index++; tagname = argv[arg_index]; fip = GetField(tiff, tagname); if (!fip) return 3; arg_index++; if (fip->field_type == TIFF_ASCII) { if (TIFFSetField(tiff, fip->field_tag, argv[arg_index]) != 1) fprintf( stderr, "Failed to set %s=%s\n", fip->field_name, argv[arg_index] ); } else if (fip->field_writecount > 0) { int ret = 1; short wc; if (fip->field_writecount == TIFF_VARIABLE) wc = atoi(argv[arg_index++]); else wc = fip->field_writecount; if (argc - arg_index < wc) { fprintf( stderr, "Number of tag values is not enough. " "Expected %d values for %s tag, got %d\n", wc, fip->field_name, argc - arg_index); return 4; } if (wc > 1) { int i, size; void *array; switch (fip->field_type) { /* * XXX: We can't use TIFFDataWidth() * to determine the space needed to store * the value. For TIFF_RATIONAL values * TIFFDataWidth() returns 8, but we use 4-byte * float to represent rationals. */ case TIFF_BYTE: case TIFF_ASCII: case TIFF_SBYTE: case TIFF_UNDEFINED: default: size = 1; break; case TIFF_SHORT: case TIFF_SSHORT: size = 2; break; case TIFF_LONG: case TIFF_SLONG: case TIFF_FLOAT: case TIFF_IFD: case TIFF_RATIONAL: case TIFF_SRATIONAL: size = 4; break; case TIFF_DOUBLE: size = 8; break; } array = _TIFFmalloc(wc * size); if (!array) { fprintf(stderr, "No space for %s tag\n", tagname); return 4; } switch (fip->field_type) { case TIFF_BYTE: for (i = 0; i < wc; i++) ((uint8 *)array)[i] = atoi(argv[arg_index+i]); break; case TIFF_SHORT: for (i = 0; i < wc; i++) ((uint16 *)array)[i] = atoi(argv[arg_index+i]); break; case TIFF_SBYTE: for (i = 0; i < wc; i++) ((int8 *)array)[i] = atoi(argv[arg_index+i]); break; case TIFF_SSHORT: for (i = 0; i < wc; i++) ((int16 *)array)[i] = atoi(argv[arg_index+i]); break; case TIFF_LONG: for (i = 0; i < wc; i++) ((uint32 *)array)[i] = atol(argv[arg_index+i]); break; case TIFF_SLONG: case TIFF_IFD: for (i = 0; i < wc; i++) ((uint32 *)array)[i] = atol(argv[arg_index+i]); break; case TIFF_DOUBLE: for (i = 0; i < wc; i++) ((double *)array)[i] = atof(argv[arg_index+i]); break; case TIFF_RATIONAL: case TIFF_SRATIONAL: case TIFF_FLOAT: for (i = 0; i < wc; i++) ((float *)array)[i] = (float)atof(argv[arg_index+i]); break; default: break; } if (fip->field_passcount) { ret = TIFFSetField(tiff, fip->field_tag, wc, array); } else { ret = TIFFSetField(tiff, fip->field_tag, array); } _TIFFfree(array); } else { switch (fip->field_type) { case TIFF_BYTE: case TIFF_SHORT: case TIFF_SBYTE: case TIFF_SSHORT: ret = TIFFSetField(tiff, fip->field_tag, atoi(argv[arg_index++])); break; case TIFF_LONG: case TIFF_SLONG: case TIFF_IFD: ret = TIFFSetField(tiff, fip->field_tag, atol(argv[arg_index++])); break; case TIFF_DOUBLE: ret = TIFFSetField(tiff, fip->field_tag, atof(argv[arg_index++])); break; case TIFF_RATIONAL: case TIFF_SRATIONAL: case TIFF_FLOAT: ret = TIFFSetField(tiff, fip->field_tag, (float)atof(argv[arg_index++])); break; default: break; } } if (ret != 1) fprintf(stderr, "Failed to set %s\n", fip->field_name); arg_index += wc; } } else if (strcmp(argv[arg_index],"-sf") == 0 && arg_index < argc-3) { FILE *fp; const TIFFFieldInfo *fip; char *text; int len; arg_index++; fip = GetField(tiff, argv[arg_index]); if (!fip) return 3; if (fip->field_type != TIFF_ASCII) { fprintf( stderr, "Only ASCII tags can be set from file. " "%s is not ASCII tag.\n", fip->field_name ); return 5; } arg_index++; fp = fopen( argv[arg_index], "rt" ); if(fp == NULL) { perror( argv[arg_index] ); continue; } text = (char *) malloc(1000000); len = fread( text, 1, 999999, fp ); text[len] = '\0'; fclose( fp ); if(TIFFSetField( tiff, fip->field_tag, text ) != 1) { fprintf(stderr, "Failed to set %s from file %s\n", fip->field_name, argv[arg_index]); } _TIFFfree( text ); arg_index++; } else { fprintf(stderr, "Unrecognised option: %s\n", argv[arg_index]); usage(); } } TIFFRewriteDirectory(tiff); TIFFClose(tiff); return 0; }
int main(int argc, char* argv[]) { TIFF *tiff; int arg_index; if (argc < 2) usage(); tiff = TIFFOpen(argv[argc-1], "r+"); if (tiff == NULL) return 2; for( arg_index = 1; arg_index < argc-1; arg_index++ ) { if (strcmp(argv[arg_index],"-d") == 0 && arg_index < argc-2) { arg_index++; if( TIFFSetDirectory(tiff, atoi(argv[arg_index]) ) != 1 ) { fprintf( stderr, "Failed to set directory=%s\n", argv[arg_index] ); return 6; } arg_index++; } if (strcmp(argv[arg_index],"-sd") == 0 && arg_index < argc-2) { arg_index++; if( TIFFSetSubDirectory(tiff, atoi(argv[arg_index]) ) != 1 ) { fprintf( stderr, "Failed to set sub directory=%s\n", argv[arg_index] ); return 7; } arg_index++; } /* Add unset option to tiffset -- Zach Baker ([email protected]) 11/14/2012 */ if (strcmp(argv[arg_index],"-u") == 0 && arg_index < argc-2) { const TIFFField *fip; const char *tagname; arg_index++; tagname = argv[arg_index]; fip = GetField(tiff, tagname); if (!fip) return 3; if (TIFFUnsetField(tiff, TIFFFieldTag(fip)) != 1) { fprintf(stderr, "Failed to unset %s\n", TIFFFieldName(fip)); } arg_index++; } else if (strcmp(argv[arg_index],"-s") == 0 && arg_index < argc-3) { const TIFFField *fip; const char *tagname; arg_index++; tagname = argv[arg_index]; fip = GetField(tiff, tagname); if (!fip) return 3; arg_index++; if (TIFFFieldDataType(fip) == TIFF_ASCII) { if (TIFFSetField(tiff, TIFFFieldTag(fip), argv[arg_index]) != 1) fprintf( stderr, "Failed to set %s=%s\n", TIFFFieldName(fip), argv[arg_index] ); } else if (TIFFFieldWriteCount(fip) > 0 || TIFFFieldWriteCount(fip) == TIFF_VARIABLE) { int ret = 1; short wc; if (TIFFFieldWriteCount(fip) == TIFF_VARIABLE) wc = atoi(argv[arg_index++]); else wc = TIFFFieldWriteCount(fip); if (argc - arg_index < wc) { fprintf( stderr, "Number of tag values is not enough. " "Expected %d values for %s tag, got %d\n", wc, TIFFFieldName(fip), argc - arg_index); return 4; } if (wc > 1) { int i, size; void *array; switch (TIFFFieldDataType(fip)) { /* * XXX: We can't use TIFFDataWidth() * to determine the space needed to store * the value. For TIFF_RATIONAL values * TIFFDataWidth() returns 8, but we use 4-byte * float to represent rationals. */ case TIFF_BYTE: case TIFF_ASCII: case TIFF_SBYTE: case TIFF_UNDEFINED: default: size = 1; break; case TIFF_SHORT: case TIFF_SSHORT: size = 2; break; case TIFF_LONG: case TIFF_SLONG: case TIFF_FLOAT: case TIFF_IFD: case TIFF_RATIONAL: case TIFF_SRATIONAL: size = 4; break; case TIFF_DOUBLE: size = 8; break; } array = _TIFFmalloc(wc * size); if (!array) { fprintf(stderr, "No space for %s tag\n", tagname); return 4; } switch (TIFFFieldDataType(fip)) { case TIFF_BYTE: for (i = 0; i < wc; i++) ((uint8 *)array)[i] = atoi(argv[arg_index+i]); break; case TIFF_SHORT: for (i = 0; i < wc; i++) ((uint16 *)array)[i] = atoi(argv[arg_index+i]); break; case TIFF_SBYTE: for (i = 0; i < wc; i++) ((int8 *)array)[i] = atoi(argv[arg_index+i]); break; case TIFF_SSHORT: for (i = 0; i < wc; i++) ((int16 *)array)[i] = atoi(argv[arg_index+i]); break; case TIFF_LONG: for (i = 0; i < wc; i++) ((uint32 *)array)[i] = atol(argv[arg_index+i]); break; case TIFF_SLONG: case TIFF_IFD: for (i = 0; i < wc; i++) ((uint32 *)array)[i] = atol(argv[arg_index+i]); break; case TIFF_DOUBLE: for (i = 0; i < wc; i++) ((double *)array)[i] = atof(argv[arg_index+i]); break; case TIFF_RATIONAL: case TIFF_SRATIONAL: case TIFF_FLOAT: for (i = 0; i < wc; i++) ((float *)array)[i] = (float)atof(argv[arg_index+i]); break; default: break; } if (TIFFFieldPassCount(fip)) { ret = TIFFSetField(tiff, TIFFFieldTag(fip), wc, array); } else if (TIFFFieldTag(fip) == TIFFTAG_PAGENUMBER || TIFFFieldTag(fip) == TIFFTAG_HALFTONEHINTS || TIFFFieldTag(fip) == TIFFTAG_YCBCRSUBSAMPLING || TIFFFieldTag(fip) == TIFFTAG_DOTRANGE) { if (TIFFFieldDataType(fip) == TIFF_BYTE) { ret = TIFFSetField(tiff, TIFFFieldTag(fip), ((uint8 *)array)[0], ((uint8 *)array)[1]); } else if (TIFFFieldDataType(fip) == TIFF_SHORT) { ret = TIFFSetField(tiff, TIFFFieldTag(fip), ((uint16 *)array)[0], ((uint16 *)array)[1]); } } else { ret = TIFFSetField(tiff, TIFFFieldTag(fip), array); } _TIFFfree(array); } else { switch (TIFFFieldDataType(fip)) { case TIFF_BYTE: case TIFF_SHORT: case TIFF_SBYTE: case TIFF_SSHORT: ret = TIFFSetField(tiff, TIFFFieldTag(fip), atoi(argv[arg_index++])); break; case TIFF_LONG: case TIFF_SLONG: case TIFF_IFD: ret = TIFFSetField(tiff, TIFFFieldTag(fip), atol(argv[arg_index++])); break; case TIFF_DOUBLE: ret = TIFFSetField(tiff, TIFFFieldTag(fip), atof(argv[arg_index++])); break; case TIFF_RATIONAL: case TIFF_SRATIONAL: case TIFF_FLOAT: ret = TIFFSetField(tiff, TIFFFieldTag(fip), (float)atof(argv[arg_index++])); break; default: break; } } if (ret != 1) fprintf(stderr, "Failed to set %s\n", TIFFFieldName(fip)); arg_index += wc; } } else if (strcmp(argv[arg_index],"-sf") == 0 && arg_index < argc-3) { FILE *fp; const TIFFField *fip; char *text; size_t len; arg_index++; fip = GetField(tiff, argv[arg_index]); if (!fip) return 3; if (TIFFFieldDataType(fip) != TIFF_ASCII) { fprintf( stderr, "Only ASCII tags can be set from file. " "%s is not ASCII tag.\n", TIFFFieldName(fip) ); return 5; } arg_index++; fp = fopen( argv[arg_index], "rt" ); if(fp == NULL) { perror( argv[arg_index] ); continue; } text = (char *) malloc(1000000); len = fread( text, 1, 999999, fp ); text[len] = '\0'; fclose( fp ); if(TIFFSetField( tiff, TIFFFieldTag(fip), text ) != 1) { fprintf(stderr, "Failed to set %s from file %s\n", TIFFFieldName(fip), argv[arg_index]); } _TIFFfree( text ); arg_index++; } else { fprintf(stderr, "Unrecognised option: %s\n", argv[arg_index]); usage(); } } TIFFRewriteDirectory(tiff); TIFFClose(tiff); return 0; }
static int InstallGeoTIFF(const char *geofile, const char *tiffile) { TIFF *tif = (TIFF*)0; /* TIFF-level descriptor */ GTIF *gtif=(GTIF*)0; /* GeoKey-level descriptor */ FILE *fp; uint16 *panVI = NULL; uint16 nKeyCount; tif = XTIFFOpen(tiffile, "r+"); if (!tif) { perror(tiffile); fprintf(stderr, "Cannot open TIFF file %s (does not exist or not a valid TIFF file)\n", tiffile); return(-1); } /* If we have existing geokeys, try to wipe them by writing a dummy geokey directory. (#2546) */ if( TIFFGetField( tif, TIFFTAG_GEOKEYDIRECTORY, &nKeyCount, &panVI ) ) { uint16 anGKVersionInfo[4] = { 1, 1, 0, 0 }; double adfDummyDoubleParams[1] = { 0.0 }; TIFFSetField( tif, TIFFTAG_GEOKEYDIRECTORY, 4, anGKVersionInfo ); TIFFSetField( tif, TIFFTAG_GEODOUBLEPARAMS, 1, adfDummyDoubleParams ); TIFFSetField( tif, TIFFTAG_GEOASCIIPARAMS, "" ); } gtif = GTIFNew(tif); if (!gtif) { fprintf(stderr, "Internal error (GTIFNew)\n"); return(-2); } /* Read GeoTIFF projection information from geofile */ fp = fopen(geofile, "r"); if( fp == NULL ) { perror( geofile ); fprintf(stderr, "Cannot open projection definition file %s\n", geofile); return(-3); } if (!GTIFImport(gtif, 0, fp)) { fprintf(stderr,"Projection definition file is not valid (%s)\n", geofile); return(-4); } fclose(fp); /* Install GeoTIFF keys into the TIFF file */ GTIFWriteKeys(gtif); /* Clean up */ GTIFFree(gtif); TIFFRewriteDirectory(tif); XTIFFClose(tif); return(0); }