static int raiseNDFException( int *status ) { char param[ERR__SZPAR+1]; char opstr[ERR__SZMSG+1]; int parlen = 0; int oplen = 0; size_t stringlen = 1; PyObject * thisexc = NULL; char * errstring = NULL; if (*status == SAI__OK) { errEnd(status); return 0; } // We can translate some internal errors into standard python exceptions switch (*status) { case DAT__FILNF: thisexc = PyExc_IOError; break; default: thisexc = StarlinkNDFError; } // Start with a nul terminated buffer errstring = malloc( stringlen ); if (!errstring) PyErr_NoMemory(); errstring[0] = '\0'; // Build up a string with the full error message while (*status != SAI__OK && errstring) { errLoad( param, sizeof(param), &parlen, opstr, sizeof(opstr), &oplen, status ); if (*status != SAI__OK) { char *newstring; stringlen += oplen + 1; newstring = realloc( errstring, stringlen ); if (newstring) { errstring = newstring; strcat( errstring, opstr ); strcat( errstring, "\n" ); } else { if (errstring) free(errstring); PyErr_NoMemory(); } } } if (errstring) { PyErr_SetString( thisexc, errstring ); free(errstring); } errEnd(status); return 1; }
int write_ndf( int argc, void *argv[]) { /* ** Declare variables */ void *arr; /* Pointer to the data array */ int n_dims; /* The number of dimensions */ int *arr_bnds; /* The dimensions */ IDL_STRING *ndf_name; /* The name of the NDF to be created */ IDL_STRING *comp; /* The component name */ IDL_STRING *type; /* The HDS type of the NDF to be created */ int badset; /* Whether bad value is set */ void *bad_value; /* Pointer to the bad value */ int status; /* Starlink status */ int lbnd[5]={1L,1L,1L,1L,1L}; /* Lower bounds array */ int ndf; /* NDF identifier */ int place; /* NDF placeholder */ int npix; /* Number of pixels */ void *ptr[3]; /* Pointer to mapped NDF data Fortran style */ size_t nbytes; /* Number of bytes in NDF */ int bpix=1; /* Number of bits/pixel */ int idltype=1; /* Pixel type code */ int fstat; /* Final status (before errLoad) */ int errn=0; /* Error sequence number */ char param[ERR__SZPAR]; /* Error message parameter name */ int parlen; /* Length of error message parameter name */ char opstr[ERR__SZMSG]; /* Error message */ int oplen; /* Length of error message */ /* ** Start Error context */ status = SAI__OK; errMark(); /* ** Check that the correct number of arguments were passed in */ if(argc != 8) { /* ** Print an error message and return */ status = SAI__ERROR; errRep( " ", "write_ndf: Incorrect number of arguments", &status ); } else { /* ** Extract the arguments to comprehensible names */ arr = argv[0]; n_dims = *(int *)argv[1]; arr_bnds = (int *)argv[2]; ndf_name = (IDL_STRING *)argv[3]; comp = (IDL_STRING *)argv[4]; type = (IDL_STRING *)argv[5]; badset = *(int *)argv[6]; bad_value = (void *)argv[7]; /* ** Enable NDF calls */ ndfBegin(); if ( !strcmp( comp->s, "DATA" ) ) { /* ** Create the NDF */ ndfOpen( NULL, ndf_name->s, "WRITE", "NEW", &ndf, &place, &status ); ndfNew( type->s, n_dims, lbnd, arr_bnds, &place, &ndf, &status ); } else { if ( !strcmp( comp->s, "QUALITY") && strcmp(type->s, "_UBYTE")) { status = SAI__ERROR; errRep( " ", "write_ndf: Incorrect type for QUALITY", &status ); } /* ** Open existing NDF */ ndfOpen( NULL, ndf_name->s, "UPDATE", "OLD", &ndf, &place, &status ); } /* ** Check the number of pixels is same in given array and NDF for QUALITY ** and VARIANCE. */ if ( strcmp( comp->s, "DATA" ) ) { ndfSize( ndf, &npix, &status ); if ( ( status == SAI__OK ) && ( npix != arr_bnds[n_dims+1] ) ) { /* ** Array size and NDF size do not agree */ status = SAI__ERROR; errRep( " ", "write_ndf: Incorrect number elements supplied", &status ); } } /* ** Obtain mapped access to the array component of the NDF */ ndfMap( ndf, comp->s, type->s, "WRITE", ptr, &npix, &status ); /* ** Now copy the values from ARR into the mapped NDF */ if ( status == SAI__OK ) { /* ** First check the returned pointer is good */ if ( ptr[0] == NULL ) { /* ** Fortran to C pointer conversion failed */ status = SAI__ERROR; errRep( " ", "write_ndf: Fortran to C pointer conversion failed", &status ); } else { /* ** then get the IDL type code and number of bytes per pixel */ if (!strcmp(type->s, "_REAL")) { idltype = 4; bpix = 4; } else if (!strcmp(type->s, "_INTEGER")) { idltype = 3; bpix = 4; } else if (!strcmp(type->s, "_WORD")) { idltype = 2; bpix = 2; } else if (!strcmp(type->s, "_DOUBLE")) { idltype = 5; bpix = 8; } else if (!strcmp(type->s, "_UBYTE")) { idltype = 1; bpix = 1; } else { status = SAI__ERROR; msgSetc( "TYPE", type->s ); errRep( " ", "Illegal type ^TYPE", &status ); } /* ** Now copy the data from the array to the NDF. ** If we need to check for bad values in the array, use copybadout. ** If any bad values are found copybadout will replace them with the ** appropriate PRIMDAT bad value. The NDF bad pixel flag is then set ** depending on whether copybadout detected any bad values. ** If we need not check for bad pixels just copy the whole lot; */ if ( status == SAI__OK ) { if ( badset ) { if ( !copybadout( ptr[0], arr, npix, idltype, bad_value ) ) ndfSbad( 0, ndf, comp->s, &status); } else { nbytes = bpix * npix; memcpy( ptr[0], arr, nbytes ); } } } } /* ** Close NDF */ ndfEnd( &status ); } /* ** Report any error messages ** Adding Starlink-style !! and ! prefix */ fstat = status; while ( status != SAI__OK ) { errLoad( param, ERR__SZPAR, &parlen, opstr, ERR__SZMSG, &oplen, &status ); if ( status != SAI__OK ) printf( "%s %s\r\n", errn++?"! ":"!!", opstr ); } errRlse(); /* ** That's it, return to the calling routine */ return( fstat == SAI__OK ); }
int read_ndf( int argc, void *argv[] ) { /* ** Declare variables */ IDL_STRING *ndf_name; /* The name of the NDF to be read */ IDL_STRING *comp; /* The component name */ IDL_STRING *type; /* The HDS type of the component to be read */ void *arr; /* Pointer to the data array */ int badset; /* Whether bad value is set */ void *bad_value; /* Pointer to the bad value */ int status; /* Starlink status */ int ndf; /* NDF identifier */ int place; /* NDF placeholder */ int npix; /* Number of pixels */ void *ptr[3]; /* Pointer to mapped NDF data Fortran style */ size_t nbytes; /* Number of bytes in NDF */ int bpix=1; /* Number of bits/pixel */ int idltype=1; /* Pixel type code */ int bad; /* If bad pixels need handling */ int fstat; /* Final status (before errLoad) */ int errn=0; /* Error sequence number */ char param[ERR__SZPAR]; /* Error message parameter name */ int parlen; /* Length of error message parameter name */ char opstr[ERR__SZMSG]; /* Error message */ int oplen; /* Length of error message */ /* ** Start Error context */ status = SAI__OK; errMark(); /* ** Check that the correct number of arguments were passed in */ if(argc != 6) { /* ** Print an error message and return */ status = SAI__ERROR; errRep( " ", "read_ndf: Incorrect number of arguments", &status ); } else { /* ** Extract the arguments to comprehensible names */ ndf_name = (IDL_STRING *)argv[0]; comp = (IDL_STRING *)argv[1]; type = (IDL_STRING *)argv[2]; arr = argv[3]; badset = *(int *)argv[4]; bad_value = (void *)argv[5]; /* ** Enable NDF calls */ ndfBegin(); /* ptr[2]=malloc(256);*/ /* ** Open the NDF */ ndfOpen( NULL, ndf_name->s, "READ", "OLD", &ndf, &place, &status ); /* ** Obtain mapped access to the array component of the first NDF */ ndfMap( ndf, comp->s, type->s, "READ", ptr, &npix, &status ); /* ** Now copy the values from the mapped NDF into ARR */ if ( status == SAI__OK ) { /* ** First check the returned pointer is good */ if ( ptr[0] == NULL ) { /* ** Fortran to C pointer conversion failed */ status = SAI__ERROR; errRep( " ", "read_ndf: Fortran to C pointer conversion failed", &status ); } else { /* ** then get the IDL type and number of bytes per pixel */ if (!strcmp(type->s, "_REAL")) { idltype = 4; bpix = 4; } else if (!strcmp(type->s, "_INTEGER")) { idltype = 3; bpix = 4; } else if (!strcmp(type->s, "_WORD")) { idltype = 2; bpix = 2; } else if (!strcmp(type->s, "_DOUBLE")) { idltype = 5; bpix = 8; } else if (!strcmp(type->s, "_UBYTE")) { idltype = 1; bpix = 1; } else { status = SAI__ERROR; msgSetc( "TYPE", type->s ); errRep( " ", "Illegal type ^TYPE", &status ); } /* ** If badset is false, we can just copy everything; otherwise see if ** bad pixels may be set and act accordingly. Set bad if we need to check ** for bad pixels. */ bad = 0; if ( badset ) ndfBad( ndf, "DATA", 0, &bad, &status ); /* ** Now copy the data from the NDF to the array. ** If we need not check for bad pixels just copy the whole lot */ if ( status == SAI__OK ) { if ( bad ) { copybadin( arr, ptr[0], npix, idltype, bad_value ); } else { nbytes = bpix * npix; memcpy( arr, ptr[0], nbytes ); } } } } /* ** Close NDF */ ndfEnd( &status ); } /* ** Report any error messages ** Adding Starlink-style !! and ! prefix */ fstat = status; while ( status != SAI__OK ) { errLoad( param, ERR__SZPAR, &parlen, opstr, ERR__SZMSG, &oplen, &status ); if ( status != SAI__OK ) printf( "%s %s\r\n", errn++?"! ":"!!", opstr ); } errRlse(); /* ** That's it, return to the calling routine */ return( fstat == SAI__OK ); }