int wcsfixi(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[], struct wcserr info[]) { int ifix, status = 0; struct wcserr err; /* Handling the status values returned from the sub-fixers is trickier than it might seem, especially considering that wcs->err may contain an error status on input which should be preserved if no translation errors occur. The simplest way seems to be to save a copy of wcs->err and clear it before each sub-fixer. The last real error to occur, excluding informative messages, is the one returned. To get informative messages from spcfix() it must precede celfix() and cylfix(). The latter call wcsset() which also translates AIPS-convention spectral axes. */ wcserr_copy(wcs->err, &err); for (ifix = CDFIX; ifix < NWCSFIX; ifix++) { /* Clear (delete) wcs->err. */ wcserr_clear(&(wcs->err)); switch (ifix) { case CDFIX: stat[ifix] = cdfix(wcs); break; case DATFIX: stat[ifix] = datfix(wcs); break; case UNITFIX: stat[ifix] = unitfix(ctrl, wcs); break; case SPCFIX: stat[ifix] = spcfix(wcs); break; case CELFIX: stat[ifix] = celfix(wcs); break; case CYLFIX: stat[ifix] = cylfix(naxis, wcs); break; default: continue; } if (stat[ifix] == FIXERR_NO_CHANGE) { /* No change => no message. */ wcserr_copy(0x0, info+ifix); } else if (stat[ifix] == FIXERR_SUCCESS) { /* Successful translation, but there may be an informative message. */ if (wcs->err && wcs->err->status < 0) { wcserr_copy(wcs->err, info+ifix); } else { wcserr_copy(0x0, info+ifix); } } else { /* An informative message or error message. */ wcserr_copy(wcs->err, info+ifix); if ((status = (stat[ifix] > 0))) { /* It was an error, replace the previous one. */ wcserr_copy(wcs->err, &err); } } } /* Restore the last error to occur. */ if (err.status) { wcserr_copy(&err, wcs->err); } else { wcserr_clear(&(wcs->err)); } return status; }
int pipeline_all_pixel2world( pipeline_t* pipeline, const unsigned int ncoord, const unsigned int nelem, const double* const pixcrd /* [ncoord][nelem] */, double* world /* [ncoord][nelem] */) { static const char* function = "pipeline_all_pixel2world"; const double* wcs_input = NULL; double* wcs_output = NULL; int has_det2im; int has_sip; int has_p4; int has_wcs; int status = 1; struct wcserr **err; /* Temporary buffer for performing WCS calculations */ unsigned char* buffer = NULL; unsigned char* mem = NULL; /*@null@*/ double* tmp; /*@null@*/ double* imgcrd; /*@null@*/ double* phi; /*@null@*/ double* theta; /*@null@*/ int* stat; if (pipeline == NULL || pixcrd == NULL || world == NULL) { return WCSERR_NULL_POINTER; } err = &(pipeline->err); has_det2im = pipeline->det2im[0] != NULL || pipeline->det2im[1] != NULL; has_sip = pipeline->sip != NULL; has_p4 = pipeline->cpdis[0] != NULL || pipeline->cpdis[1] != NULL; has_wcs = pipeline->wcs != NULL; if (has_det2im || has_sip || has_p4) { if (nelem != 2) { status = wcserr_set( PIP_ERRMSG(WCSERR_BAD_COORD_TRANS), "Data must be 2-dimensional when Paper IV lookup table or SIP transform is present."); goto exit; } } if (has_wcs) { buffer = mem = malloc( ncoord * nelem * sizeof(double) + /* imgcrd */ ncoord * sizeof(double) + /* phi */ ncoord * sizeof(double) + /* theta */ ncoord * nelem * sizeof(double) + /* tmp */ ncoord * nelem * sizeof(int) /* stat */ ); if (buffer == NULL) { status = wcserr_set( PIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed"); goto exit; } imgcrd = (double *)mem; mem += ncoord * nelem * sizeof(double); phi = (double *)mem; mem += ncoord * sizeof(double); theta = (double *)mem; mem += ncoord * sizeof(double); tmp = (double *)mem; mem += ncoord * nelem * sizeof(double); stat = (int *)mem; /* mem += ncoord * nelem * sizeof(int); */ if (has_det2im || has_sip || has_p4) { status = pipeline_pix2foc(pipeline, ncoord, nelem, pixcrd, tmp); if (status != 0) { goto exit; } wcs_input = tmp; wcs_output = world; } else { wcs_input = pixcrd; wcs_output = world; } if ((status = wcsp2s(pipeline->wcs, (int)ncoord, (int)nelem, wcs_input, imgcrd, phi, theta, wcs_output, stat))) { wcserr_copy(pipeline->wcs->err, pipeline->err); } if (status == 8) { set_invalid_to_nan((int)ncoord, (int)nelem, wcs_output, stat); } } else { if (has_det2im || has_sip || has_p4) { status = pipeline_pix2foc(pipeline, ncoord, nelem, pixcrd, world); } } exit: free(buffer); return status; }
int wcsfixi(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[], struct wcserr info[]) { int status = 0; struct wcserr *err; err = info + CDFIX; if ((stat[CDFIX] = cdfix(wcs)) > 0) { wcserr_copy(wcs->err, err); status = 1; } else { wcserr_copy(0x0, err); } err = info + DATFIX; if ((stat[DATFIX] = datfix(wcs)) > 0) { wcserr_copy(wcs->err, err); status = 1; } else { wcserr_copy(0x0, err); } err = info + UNITFIX; if ((stat[UNITFIX] = unitfix(ctrl, wcs)) > 0) { wcserr_copy(wcs->err, err); status = 1; } else { wcserr_copy(0x0, err); } err = info + CELFIX; if ((stat[CELFIX] = celfix(wcs)) > 0) { wcserr_copy(wcs->err, err); status = 1; } else { wcserr_copy(0x0, err); } err = info + SPCFIX; if ((stat[SPCFIX] = spcfix(wcs)) > 0) { wcserr_copy(wcs->err, err); status = 1; } else { wcserr_copy(0x0, err); } err = info + CYLFIX; wcserr_copy(0x0, err); if (naxis) { if ((stat[CYLFIX] = cylfix(naxis, wcs)) > 0) { err = info + CYLFIX; wcserr_copy(wcs->err, err); status = 1; } } else { stat[CYLFIX] = -2; } if (wcs->err) free(wcs->err); wcs->err = 0x0; return status; }
int pipeline_pix2foc( pipeline_t* pipeline, const unsigned int ncoord, const unsigned int nelem, const double* const pixcrd /* [ncoord][nelem] */, double* foc /* [ncoord][nelem] */) { static const char* function = "pipeline_pix2foc"; int has_det2im; int has_sip; int has_p4; const double * input = NULL; double * tmp = NULL; int status = 1; struct wcserr **err; assert(nelem == 2); assert(pixcrd != foc); if (pipeline == NULL || pixcrd == NULL || foc == NULL) { return WCSERR_NULL_POINTER; } err = &(pipeline->err); has_det2im = pipeline->det2im[0] != NULL || pipeline->det2im[1] != NULL; has_sip = pipeline->sip != NULL; has_p4 = pipeline->cpdis[0] != NULL || pipeline->cpdis[1] != NULL; if (has_det2im) { if (has_sip || has_p4) { tmp = malloc(ncoord * nelem * sizeof(double)); if (tmp == NULL) { status = wcserr_set( PIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed"); goto exit; } memcpy(tmp, pixcrd, sizeof(double) * ncoord * nelem); status = p4_pix2deltas(2, (void*)pipeline->det2im, ncoord, pixcrd, tmp); if (status) { wcserr_set(PIP_ERRMSG(WCSERR_NULL_POINTER), "NULL pointer passed"); goto exit; } input = tmp; memcpy(foc, input, sizeof(double) * ncoord * nelem); } else { memcpy(foc, pixcrd, sizeof(double) * ncoord * nelem); status = p4_pix2deltas(2, (void*)pipeline->det2im, ncoord, pixcrd, foc); if (status) { wcserr_set(PIP_ERRMSG(WCSERR_NULL_POINTER), "NULL pointer passed"); goto exit; } } } else { /* Copy pixcrd to foc as a starting point. The "deltas" functions below will undistort from there */ memcpy(foc, pixcrd, sizeof(double) * ncoord * nelem); input = pixcrd; } if (has_sip) { status = sip_pix2deltas(pipeline->sip, 2, ncoord, input, foc); if (status) { wcserr_copy(pipeline->sip->err, pipeline->err); goto exit; } } if (has_p4) { status = p4_pix2deltas(2, (void*)pipeline->cpdis, ncoord, input, foc); if (status) { wcserr_set(PIP_ERRMSG(WCSERR_NULL_POINTER), "NULL pointer passed"); goto exit; } } status = 0; exit: free(tmp); return status; }