| 189 | // --------------------------------------------------------------------------- |
| 190 | |
| 191 | GTXVerticalShiftGrid *GTXVerticalShiftGrid::open(PJ_CONTEXT *ctx, |
| 192 | std::unique_ptr<File> fp, |
| 193 | const std::string &name) { |
| 194 | unsigned char header[40]; |
| 195 | |
| 196 | /* -------------------------------------------------------------------- */ |
| 197 | /* Read the header. */ |
| 198 | /* -------------------------------------------------------------------- */ |
| 199 | if (fp->read(header, sizeof(header)) != sizeof(header)) { |
| 200 | pj_log(ctx, PJ_LOG_ERROR, _("Cannot read grid header")); |
| 201 | proj_context_errno_set(ctx, |
| 202 | PROJ_ERR_INVALID_OP_FILE_NOT_FOUND_OR_INVALID); |
| 203 | return nullptr; |
| 204 | } |
| 205 | |
| 206 | /* -------------------------------------------------------------------- */ |
| 207 | /* Regularize fields of interest and extract. */ |
| 208 | /* -------------------------------------------------------------------- */ |
| 209 | if (IS_LSB) { |
| 210 | swap_words(header + 0, 8, 4); |
| 211 | swap_words(header + 32, 4, 2); |
| 212 | } |
| 213 | |
| 214 | double xorigin, yorigin, xstep, ystep; |
| 215 | int rows, columns; |
| 216 | |
| 217 | memcpy(&yorigin, header + 0, 8); |
| 218 | memcpy(&xorigin, header + 8, 8); |
| 219 | memcpy(&ystep, header + 16, 8); |
| 220 | memcpy(&xstep, header + 24, 8); |
| 221 | |
| 222 | memcpy(&rows, header + 32, 4); |
| 223 | memcpy(&columns, header + 36, 4); |
| 224 | |
| 225 | if (xorigin < -360 || xorigin > 360 || yorigin < -90 || yorigin > 90) { |
| 226 | pj_log(ctx, PJ_LOG_ERROR, |
| 227 | _("gtx file header has invalid extents, corrupt?")); |
| 228 | proj_context_errno_set(ctx, |
| 229 | PROJ_ERR_INVALID_OP_FILE_NOT_FOUND_OR_INVALID); |
| 230 | return nullptr; |
| 231 | } |
| 232 | |
| 233 | /* some GTX files come in 0-360 and we shift them back into the |
| 234 | expected -180 to 180 range if possible. This does not solve |
| 235 | problems with grids spanning the dateline. */ |
| 236 | if (xorigin >= 180.0) |
| 237 | xorigin -= 360.0; |
| 238 | |
| 239 | if (xorigin >= 0.0 && xorigin + xstep * columns > 180.0) { |
| 240 | pj_log(ctx, PJ_LOG_DEBUG, |
| 241 | "This GTX spans the dateline! This will cause problems."); |
| 242 | } |
| 243 | |
| 244 | ExtentAndRes extent; |
| 245 | extent.isGeographic = true; |
| 246 | extent.west = xorigin * DEG_TO_RAD; |
| 247 | extent.south = yorigin * DEG_TO_RAD; |
| 248 | extent.resX = xstep * DEG_TO_RAD; |
no test coverage detected