00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "xtiffiop.h"
00018 #include <stdio.h>
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 static const TIFFFieldInfo xtiffFieldInfo[] = {
00030
00031
00032 { TIFFTAG_GEOPIXELSCALE, -1,-1, TIFF_DOUBLE, FIELD_GEOPIXELSCALE,
00033 TRUE, TRUE, "GeoPixelScale" },
00034 { TIFFTAG_INTERGRAPH_MATRIX,-1,-1, TIFF_DOUBLE, FIELD_INTERGRAPH_MATRIX,
00035 TRUE, TRUE, "Intergraph TransformationMatrix" },
00036 { TIFFTAG_GEOTRANSMATRIX, -1,-1, TIFF_DOUBLE, FIELD_GEOTRANSMATRIX,
00037 TRUE, TRUE, "GeoTransformationMatrix" },
00038 { TIFFTAG_GEOTIEPOINTS, -1,-1, TIFF_DOUBLE, FIELD_GEOTIEPOINTS,
00039 TRUE, TRUE, "GeoTiePoints" },
00040 { TIFFTAG_GEOKEYDIRECTORY,-1,-1, TIFF_SHORT, FIELD_GEOKEYDIRECTORY,
00041 TRUE, TRUE, "GeoKeyDirectory" },
00042 { TIFFTAG_GEODOUBLEPARAMS, -1,-1, TIFF_DOUBLE, FIELD_GEODOUBLEPARAMS,
00043 TRUE, TRUE, "GeoDoubleParams" },
00044 { TIFFTAG_GEOASCIIPARAMS, -1,-1, TIFF_ASCII, FIELD_GEOASCIIPARAMS,
00045 TRUE, FALSE, "GeoASCIIParams" },
00046 #ifdef JPL_TAG_SUPPORT
00047 { TIFFTAG_JPL_CARTO_IFD, 1, 1, TIFF_LONG, FIELD_JPL_CARTO_IFD,
00048 TRUE, TRUE, "JPL Carto IFD offset" },
00049 #endif
00050 };
00051 #define N(a) (sizeof (a) / sizeof (a[0]))
00052
00053
00054 static void
00055 _XTIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
00056 {
00057 xtiff *xt = XTIFFDIR(tif);
00058 XTIFFDirectory *xd = &xt->xtif_dir;
00059 int i,j,num;
00060
00061
00062 if (PARENT(xt,printdir))
00063 (PARENT(xt,printdir))(tif,fd,flags);
00064
00065
00066
00067 fprintf(fd,"--GeoTIFF Tags--\n");
00068
00069 if (TIFFFieldSet(tif,FIELD_GEOTIEPOINTS))
00070 {
00071 num = xd->xd_geodimensions[GEO_NUM_TIEPOINT];
00072 fprintf(fd, " Geo Tiepoints:");
00073 if (num>6) fprintf(fd,"\n ");
00074 for (i=0;i<num;i+=6)
00075 {
00076 fprintf(fd," (");
00077 for (j=0;j<3;j++)
00078 fprintf(fd, " %f", xd->xd_geotiepoints[i+j]);
00079 fprintf(fd,")->(");
00080 for (j=3;j<6;j++)
00081 fprintf(fd, " %f", xd->xd_geotiepoints[i+j]);
00082 fprintf(fd,")\n");
00083 }
00084 }
00085
00086 if (TIFFFieldSet(tif,FIELD_GEOPIXELSCALE))
00087 {
00088 num = xd->xd_geodimensions[GEO_NUM_PIXELSCALE];
00089 fprintf(fd, " Geo Pixel Scale: (");
00090 for (j=0;j<num;j++)
00091 fprintf(fd, " %f", xd->xd_geopixelscale[j]);
00092 fprintf(fd, " )\n");
00093 }
00094
00095 if (TIFFFieldSet(tif,FIELD_INTERGRAPH_MATRIX))
00096 {
00097 num = xd->xd_geodimensions[GEO_NUM_IG_MATRIX];
00098 fprintf(fd, " Intergraph Transformation Matrix:\n");
00099 for (i=0;num>3;num-=4)
00100 {
00101 for (j=0;j<4;j++)
00102 fprintf(fd, " %8.2f", xd->xd_geomatrix[i++]);
00103 fprintf(fd, "\n");
00104 }
00105 if (num)
00106 {
00107 for (j=0;j<num;j++)
00108 fprintf(fd, " %8.2f", xd->xd_geomatrix[i++]);
00109 fprintf(fd, "\n");
00110 }
00111 }
00112
00113 if (TIFFFieldSet(tif,FIELD_GEOTRANSMATRIX))
00114 {
00115 num = xd->xd_geodimensions[GEO_NUM_MATRIX];
00116 fprintf(fd, " Geo Transformation Matrix:\n");
00117 for (i=0;i<num;i+=4)
00118 {
00119 for (j=0;j<4;j++)
00120 fprintf(fd, " %8.2f", xd->xd_geomatrix[i+j]);
00121 fprintf(fd, "\n");
00122 }
00123 }
00124
00125 if (TIFFFieldSet(tif,FIELD_GEOKEYDIRECTORY))
00126 {
00127 num = xd->xd_geodimensions[GEO_NUM_DIR];
00128 fprintf(fd, " GeoKey Directory:");
00129 if (flags & TIFFPRINT_GEOKEYDIRECTORY)
00130 {
00131 fprintf(fd, "\n");
00132 for (i=0;i<num;i+=4)
00133 {
00134 for (j=0;j<4;j++)
00135 fprintf(fd, " %8hu", xd->xd_geokeydirectory[i+j]);
00136 fprintf(fd, "\n");
00137 }
00138 } else
00139 fprintf(fd, "(present)\n");
00140
00141 }
00142
00143 if (TIFFFieldSet(tif,FIELD_GEODOUBLEPARAMS))
00144 {
00145 num = xd->xd_geodimensions[GEO_NUM_DOUBLE];
00146 fprintf(fd, " GeoKey Double Params:");
00147 if (flags & TIFFPRINT_GEOKEYPARAMS)
00148 {
00149 fprintf(fd, "\n");
00150 for (i=0;i<num;i++)
00151 fprintf(fd, " %8.2f", xd->xd_geodoubleparams[i]);
00152 fprintf(fd, "\n");
00153 } else
00154 fprintf(fd, "(present)\n");
00155
00156 }
00157
00158 if (TIFFFieldSet(tif,FIELD_GEOASCIIPARAMS))
00159 {
00160 if (flags & TIFFPRINT_GEOKEYPARAMS)
00161 {
00162 _TIFFprintAsciiTag(fd,"GeoKey ASCII Parameters",
00163 xd->xd_geoasciiparams);
00164 } else
00165 fprintf(fd, " GeoKey ASCII Parameters:(present)\n");
00166 }
00167 }
00168
00169 static int
00170 _XTIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
00171 {
00172 xtiff *xt = XTIFFDIR(tif);
00173 XTIFFDirectory* xd = &xt->xtif_dir;
00174 int status = 1;
00175 uint16 num;
00176
00177
00178
00179 switch (tag) {
00180
00181 case TIFFTAG_GEOKEYDIRECTORY:
00182 xd->xd_geodimensions[GEO_NUM_DIR] = (uint16) va_arg(ap, int);
00183 _TIFFsetShortArray(&xd->xd_geokeydirectory, va_arg(ap, uint16*),
00184 (long) xd->xd_geodimensions[GEO_NUM_DIR]);
00185 break;
00186 case TIFFTAG_GEODOUBLEPARAMS:
00187 xd->xd_geodimensions[GEO_NUM_DOUBLE] = (uint16) va_arg(ap, int);
00188 _TIFFsetDoubleArray(&xd->xd_geodoubleparams, va_arg(ap, double*),
00189 (long) xd->xd_geodimensions[GEO_NUM_DOUBLE]);
00190 break;
00191 case TIFFTAG_GEOTIEPOINTS:
00192 xd->xd_geodimensions[GEO_NUM_TIEPOINT] = (uint16) va_arg(ap, int);
00193 _TIFFsetDoubleArray(&xd->xd_geotiepoints, va_arg(ap, double*),
00194 (long) xd->xd_geodimensions[GEO_NUM_TIEPOINT]);
00195 break;
00196 case TIFFTAG_GEOTRANSMATRIX:
00197 xd->xd_geodimensions[GEO_NUM_MATRIX] = (uint16) va_arg(ap, int);
00198 _TIFFsetDoubleArray(&xd->xd_geomatrix, va_arg(ap, double*),
00199 (long) xd->xd_geodimensions[GEO_NUM_MATRIX]);
00200 break;
00201 case TIFFTAG_INTERGRAPH_MATRIX:
00202 num = (uint16) va_arg(ap, int);
00203 xd->xd_geodimensions[GEO_NUM_IG_MATRIX] = num;
00204 _TIFFsetDoubleArray(&xd->xd_intergraph_matrix, va_arg(ap, double*),
00205 (long) num);
00206
00207
00208
00209
00210 if (!TIFFFieldSet(tif,FIELD_GEOTRANSMATRIX) && num==16)
00211 TIFFSetField(tif,TIFFTAG_GEOTRANSMATRIX,
00212 num, xd->xd_intergraph_matrix);
00213 break;
00214 case TIFFTAG_GEOPIXELSCALE:
00215 xd->xd_geodimensions[GEO_NUM_PIXELSCALE] = (uint16) va_arg(ap, int);
00216 _TIFFsetDoubleArray(&xd->xd_geopixelscale, va_arg(ap, double*),
00217 (long) xd->xd_geodimensions[GEO_NUM_PIXELSCALE]);
00218 break;
00219 case TIFFTAG_GEOASCIIPARAMS:
00220 _TIFFsetString(&xd->xd_geoasciiparams, va_arg(ap, char*));
00221 break;
00222 #ifdef JPL_TAG_SUPPORT
00223 case TIFFTAG_JPL_CARTO_IFD:
00224 xd->xd_jpl_ifd_offset = va_arg(ap, uint32);
00225 break;
00226 #endif
00227 default:
00228
00229 return (PARENT(xt,vsetfield))(tif,tag,ap);
00230 }
00231 if (status) {
00232
00233
00234
00235
00236
00237
00238 if (!(xt->xtif_flags & XTIFFP_PRINT))
00239 {
00240 PARENT(xt,printdir) = TIFFMEMBER(tif,printdir);
00241 TIFFMEMBER(tif,printdir) = _XTIFFPrintDirectory;
00242 xt->xtif_flags |= XTIFFP_PRINT;
00243 }
00244 TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
00245 tif->tif_flags |= TIFF_DIRTYDIRECT;
00246 }
00247 va_end(ap);
00248 return (status);
00249 }
00250
00251
00252 static int
00253 _XTIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
00254 {
00255 xtiff *xt = XTIFFDIR(tif);
00256 XTIFFDirectory* xd = &xt->xtif_dir;
00257
00258 switch (tag) {
00259
00260 case TIFFTAG_GEOKEYDIRECTORY:
00261 *va_arg(ap, uint16*) = xd->xd_geodimensions[GEO_NUM_DIR];
00262 *va_arg(ap, uint16**) = xd->xd_geokeydirectory;
00263 break;
00264 case TIFFTAG_GEODOUBLEPARAMS:
00265 *va_arg(ap, uint16*) = xd->xd_geodimensions[GEO_NUM_DOUBLE];
00266 *va_arg(ap, double**) = xd->xd_geodoubleparams;
00267 break;
00268 case TIFFTAG_GEOTIEPOINTS:
00269 *va_arg(ap, uint16*) = xd->xd_geodimensions[GEO_NUM_TIEPOINT];
00270 *va_arg(ap, double**) = xd->xd_geotiepoints;
00271 break;
00272 case TIFFTAG_GEOTRANSMATRIX:
00273 *va_arg(ap, uint16*) = xd->xd_geodimensions[GEO_NUM_MATRIX];
00274 *va_arg(ap, double**) = xd->xd_geomatrix;
00275 break;
00276 case TIFFTAG_INTERGRAPH_MATRIX:
00277 *va_arg(ap, uint16*) = xd->xd_geodimensions[GEO_NUM_IG_MATRIX];
00278 *va_arg(ap, double**) = xd->xd_intergraph_matrix;
00279 break;
00280 case TIFFTAG_GEOPIXELSCALE:
00281 *va_arg(ap, uint16*) = xd->xd_geodimensions[GEO_NUM_PIXELSCALE];
00282 *va_arg(ap, double**) = xd->xd_geopixelscale;
00283 break;
00284 case TIFFTAG_GEOASCIIPARAMS:
00285 *va_arg(ap, char**) = xd->xd_geoasciiparams;
00286 break;
00287 #ifdef JPL_TAG_SUPPORT
00288 case TIFFTAG_JPL_CARTO_IFD:
00289 *va_arg(ap, uint32*) = xd->xd_jpl_ifd_offset;
00290 break;
00291 #endif
00292 default:
00293
00294 return (PARENT(xt,vgetfield))(tif,tag,ap);
00295 }
00296 return (1);
00297 }
00298
00299 #define CleanupField(member) { \
00300 if (xd->member) { \
00301 _TIFFfree(xd->member); \
00302 xd->member = 0; \
00303 } \
00304 }
00305
00306
00307
00308 static void
00309 _XTIFFFreeDirectory(xtiff* xt)
00310 {
00311 XTIFFDirectory* xd = &xt->xtif_dir;
00312
00313
00314
00315
00316
00317
00318
00319
00320 CleanupField(xd_geokeydirectory);
00321 CleanupField(xd_geodoubleparams);
00322 CleanupField(xd_geoasciiparams);
00323 CleanupField(xd_geomatrix);
00324 CleanupField(xd_geopixelscale);
00325 CleanupField(xd_geotiepoints);
00326 CleanupField(xd_intergraph_matrix);
00327
00328 }
00329 #undef CleanupField
00330
00331 static void _XTIFFLocalDefaultDirectory(TIFF *tif)
00332 {
00333 xtiff *xt = XTIFFDIR(tif);
00334
00335
00336 _TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
00337
00338
00339
00340
00341
00342
00343 _XTIFFFreeDirectory(xt);
00344 _TIFFmemset(xt,0,sizeof(xtiff));
00345
00346
00347
00348 PARENT(xt,vsetfield) = TIFFMEMBER(tif,vsetfield);
00349 TIFFMEMBER(tif,vsetfield) = _XTIFFVSetField;
00350 PARENT(xt,vgetfield) = TIFFMEMBER(tif,vgetfield);
00351 TIFFMEMBER(tif,vgetfield) = _XTIFFVGetField;
00352
00353
00354
00355
00356
00357
00358
00359 }
00360
00361
00362
00363
00364
00365
00366
00367 static TIFFExtendProc _ParentExtender;
00368
00369
00370
00371
00372
00373
00374
00375 static void
00376 _XTIFFDefaultDirectory(TIFF *tif)
00377 {
00378 xtiff *xt;
00379
00380
00381 if (!(tif->tif_flags & XTIFF_INITIALIZED))
00382 {
00383 xt = _TIFFmalloc(sizeof(xtiff));
00384 if (!xt)
00385 {
00386
00387 return;
00388 }
00389 _TIFFmemset(xt,0,sizeof(xtiff));
00390
00391
00392
00393 TIFFMEMBER(tif,clientdir) = (tidata_t)xt;
00394 tif->tif_flags |= XTIFF_INITIALIZED;
00395 }
00396
00397
00398 _XTIFFLocalDefaultDirectory(tif);
00399
00400
00401
00402
00403
00404
00405 if (_ParentExtender)
00406 (*_ParentExtender)(tif);
00407
00408 }
00409
00410
00411
00412
00413
00414
00415 static
00416 void _XTIFFInitialize(void)
00417 {
00418 static int first_time=1;
00419
00420 if (! first_time) return;
00421 first_time = 0;
00422
00423
00424 _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
00425 }
00426
00427
00450 TIFF*
00451 XTIFFOpen(const char* name, const char* mode)
00452 {
00453 TIFF *tif;
00454
00455
00456 _XTIFFInitialize();
00457
00458
00459
00460 tif = TIFFOpen(name, mode);
00461 if (!tif) return tif;
00462
00463 return tif;
00464 }
00465
00466 TIFF*
00467 XTIFFFdOpen(int fd, const char* name, const char* mode)
00468 {
00469 TIFF *tif;
00470
00471
00472 _XTIFFInitialize();
00473
00474
00475
00476 tif = TIFFFdOpen(fd, name, mode);
00477 if (!tif) return tif;
00478
00479 return tif;
00480 }
00481
00492 void
00493 XTIFFClose(TIFF *tif)
00494 {
00495 xtiff *xt = XTIFFDIR(tif);
00496
00497
00498 TIFFClose(tif);
00499
00500
00501 _XTIFFFreeDirectory(xt);
00502 _TIFFfree(xt);
00503 }