| 42 | Internally GDALIdentifyDriver() will do the following |
| 43 | |
| 44 | 1. A GDALOpenInfo structure will be initialized based on pszDatasource and papszDirFiles. |
| 45 | 2. It will iterate over all drivers similarly to GDALOpen(). For each driver it will use the pfnIdentify function if available, otherwise it will use the pfnOpen() method to establish if the driver supports the file. |
| 46 | 3. It will return the driver handle for the first driver to respond positively or NULL if none accept it. |
| 47 | |
| 48 | == Driver Changes == |
| 49 | |
| 50 | In theory it is not necessary for any drivers to be modified, since GDALIdentifyDriver() will fallback to using the pfnOpen function to test. But in practice, no optimization is achieved unless at least some drivers (hopefully those for which Open can be very expensive) are updated. Part of the ongoing effort then is to implement identify functions for GDAL drivers. |
| 51 | |
| 52 | Generally speaking it should be easy to craft an identify function from the initial test logic in the open function. For instance, the GeoTIFF driver might be changed like this: |
| 53 | |
| 54 | {{{ |
| 55 | int GTiffDataset::Identify( GDALOpenInfo * poOpenInfo ) |
| 56 | |
| 57 | { |
| 58 | /* -------------------------------------------------------------------- */ |
| 59 | /* We have a special hook for handling opening a specific */ |
| 60 | /* directory of a TIFF file. */ |
| 61 | /* -------------------------------------------------------------------- */ |
| 62 | if( EQUALN(poOpenInfo->pszFilename,"GTIFF_DIR:",10) ) |
| 63 | return TRUE; |
| 64 | |
| 65 | /* -------------------------------------------------------------------- */ |
| 66 | /* First we check to see if the file has the expected header */ |
| 67 | /* bytes. */ |
| 68 | /* -------------------------------------------------------------------- */ |
| 69 | if( poOpenInfo->nHeaderBytes < 2 ) |
| 70 | return FALSE; |
| 71 | |
| 72 | if( (poOpenInfo->pabyHeader[0] != 'I' || poOpenInfo->pabyHeader[1] != 'I') |
| 73 | && (poOpenInfo->pabyHeader[0] != 'M' || poOpenInfo->pabyHeader[1] != 'M')) |
| 74 | return FALSE; |
| 75 | |
| 76 | // We can't support BigTIFF files for now. |
| 77 | if( poOpenInfo->pabyHeader[2] == 43 && poOpenInfo->pabyHeader[3] == 0 ) |
| 78 | return FALSE; |
| 79 | |
| 80 | |
| 81 | if( (poOpenInfo->pabyHeader[2] != 0x2A || poOpenInfo->pabyHeader[3] != 0) |
| 82 | && (poOpenInfo->pabyHeader[3] != 0x2A || poOpenInfo->pabyHeader[2] != 0) ) |
| 83 | return FALSE; |
| 84 | |
| 85 | return TRUE; |
| 86 | } |
| 87 | }}} |
| 88 | |
| 89 | The open might then be modified to use the identify function to avoid duplicating the test logic. |
| 90 | |
| 91 | {{{ |
| 92 | GDALDataset *GTiffDataset::Open( GDALOpenInfo * poOpenInfo ) |
| 93 | |
| 94 | { |
| 95 | TIFF *hTIFF; |
| 96 | |
| 97 | if( !Identify( poOpenInfo ) ) |
| 98 | return NULL; |
| 99 | |
| 100 | /* -------------------------------------------------------------------- */ |
| 101 | /* We have a special hook for handling opening a specific */ |
| 102 | /* directory of a TIFF file. */ |
| 103 | /* -------------------------------------------------------------------- */ |
| 104 | if( EQUALN(poOpenInfo->pszFilename,"GTIFF_DIR:",10) ) |
| 105 | return OpenDir( poOpenInfo->pszFilename ); |
| 106 | |
| 107 | GTiffOneTimeInit(); |
| 108 | ... |
| 109 | }}} |
| 110 | |
| 111 | Drivers which require header files such as the EHdr driver might implement Identify() like this: |
| 112 | |
| 113 | {{{ |
| 114 | int EHdrDataset::Identify( GDALOpenInfo * poOpenInfo ) |
| 115 | |
| 116 | { |
| 117 | int i, bSelectedHDR; |
| 118 | const char *pszHDRFilename; |
| 119 | |
| 120 | /* -------------------------------------------------------------------- */ |
| 121 | /* We assume the user is pointing to the binary (ie. .bil) file. */ |
| 122 | /* -------------------------------------------------------------------- */ |
| 123 | if( poOpenInfo->nHeaderBytes < 2 ) |
| 124 | return FALSE; |
| 125 | |
| 126 | /* -------------------------------------------------------------------- */ |
| 127 | /* Now we need to tear apart the filename to form a .HDR */ |
| 128 | /* filename. */ |
| 129 | /* -------------------------------------------------------------------- */ |
| 130 | CPLString osBasename = CPLGetBasename( poOpenInfo->pszFilename ); |
| 131 | pszHDRFilename = CPLFormCIFilename( "", osBasename, "hdr" ); |
| 132 | |
| 133 | if( CSLFindString( poOpenInfo->papszSiblingFiles, pszHDRFilename) ) |
| 134 | return TRUE; |
| 135 | else |
| 136 | return FALSE; |
| 137 | } |
| 138 | }}} |
| 139 | |
| 140 | During the initial implementation a variety of drivers will be updated, including the following. As well some performance and file system activity logging will be done to identify drivers that are currently expensive. |
| 141 | |
| 142 | * HFA |
| 143 | * GTiff |
| 144 | * JPEG |
| 145 | * PNG |
| 146 | * GIF |
| 147 | * HDF4 |
| 148 | * DTED |
| 149 | * USGS DEM |
| 150 | * MrSID |
| 151 | * JP2KAK |
| 152 | * ECW |
| 153 | * EHdr |
| 154 | |