| 243 | // --------------------------------------------------------------------------- |
| 244 | |
| 245 | GTXVerticalShiftGrid *GTXVerticalShiftGrid::open(PJ_CONTEXT *ctx, |
| 246 | std::unique_ptr<File> fp, |
| 247 | const std::string &name) { |
| 248 | unsigned char header[40]; |
| 249 | |
| 250 | /* -------------------------------------------------------------------- */ |
| 251 | /* Read the header. */ |
| 252 | /* -------------------------------------------------------------------- */ |
| 253 | if (fp->read(header, sizeof(header)) != sizeof(header)) { |
| 254 | pj_log(ctx, PJ_LOG_ERROR, _("Cannot read grid header")); |
| 255 | proj_context_errno_set(ctx, |
| 256 | PROJ_ERR_INVALID_OP_FILE_NOT_FOUND_OR_INVALID); |
| 257 | return nullptr; |
| 258 | } |
| 259 | |
| 260 | /* -------------------------------------------------------------------- */ |
| 261 | /* Regularize fields of interest and extract. */ |
| 262 | /* -------------------------------------------------------------------- */ |
| 263 | if (IS_LSB) { |
| 264 | swap_words(header + 0, 8, 4); |
| 265 | swap_words(header + 32, 4, 2); |
| 266 | } |
| 267 | |
| 268 | double xorigin, yorigin, xstep, ystep; |
| 269 | int rows, columns; |
| 270 | |
| 271 | memcpy(&yorigin, header + 0, 8); |
| 272 | memcpy(&xorigin, header + 8, 8); |
| 273 | memcpy(&ystep, header + 16, 8); |
| 274 | memcpy(&xstep, header + 24, 8); |
| 275 | |
| 276 | memcpy(&rows, header + 32, 4); |
| 277 | memcpy(&columns, header + 36, 4); |
| 278 | |
| 279 | if (columns <= 0 || rows <= 0 || xorigin < -360 || xorigin > 360 || |
| 280 | yorigin < -90 || yorigin > 90) { |
| 281 | pj_log(ctx, PJ_LOG_ERROR, |
| 282 | _("gtx file header has invalid extents, corrupt?")); |
| 283 | proj_context_errno_set(ctx, |
| 284 | PROJ_ERR_INVALID_OP_FILE_NOT_FOUND_OR_INVALID); |
| 285 | return nullptr; |
| 286 | } |
| 287 | |
| 288 | /* some GTX files come in 0-360 and we shift them back into the |
| 289 | expected -180 to 180 range if possible. This does not solve |
| 290 | problems with grids spanning the dateline. */ |
| 291 | if (xorigin >= 180.0) |
| 292 | xorigin -= 360.0; |
| 293 | |
| 294 | if (xorigin >= 0.0 && xorigin + xstep * columns > 180.0) { |
| 295 | pj_log(ctx, PJ_LOG_DEBUG, |
| 296 | "This GTX spans the dateline! This will cause problems."); |
| 297 | } |
| 298 | |
| 299 | ExtentAndRes extent; |
| 300 | extent.isGeographic = true; |
| 301 | extent.west = xorigin * DEG_TO_RAD; |
| 302 | extent.south = yorigin * DEG_TO_RAD; |
nothing calls this directly
no test coverage detected