Changeset 20936 for trunk/Ohana/src/opihi/dvo/imextract.c
- Timestamp:
- Dec 7, 2008, 3:31:01 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/Ohana/src/opihi/dvo/imextract.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/dvo/imextract.c
r17246 r20936 1 1 # include "dvoshell.h" 2 2 3 // need to upgrade this to support multiple fields and WHERE clauses4 5 enum {ZERO,6 RA,7 DEC,8 Xm,9 AIRMASS,10 MCAL,11 dMCAL,12 PHOTCODE,13 TIME,14 FWHM,15 EXPTIME,16 NSTAR,17 NCAL,18 SKY,19 FLAG,20 NX_PIX,21 NY_PIX,22 THETA,23 SKEW,24 SCALE,25 DSCALE,26 IMAGE_ID,27 X_LL_CHIP,28 X_LR_CHIP,29 X_UL_CHIP,30 X_UR_CHIP,31 Y_LL_CHIP,32 Y_LR_CHIP,33 Y_UL_CHIP,34 Y_UR_CHIP,35 X_LL_FP,36 X_LR_FP,37 X_UL_FP,38 X_UR_FP,39 Y_LL_FP,40 Y_LR_FP,41 Y_UL_FP,42 Y_UR_FP,43 };44 45 3 int imextract (int argc, char **argv) { 46 4 47 int i, j, Nimage, mode, N, PhotcodeSelect; 48 int TimeSelect, *subset, Nsubset, TimeFormat, FlagSelect, FlagValue; 49 double x, y, ra, dec, t, trange; 50 time_t tzero, TimeReference; 5 // int *subset, Nsubset; -- not sure if we need to use this or not... 6 7 int i, j, n, N, Npts, NPTS, last, next, state, Nfields, Nreturn, Ncstack, Nstack; 8 int Nimage, VERBOSE; 9 char **cstack, name[1024]; 10 void *Signal; 11 12 Vector **vec; 13 Image *image; 14 dbStack *stack; 15 dbField *fields; 16 dbValue *values; 51 17 SkyRegionSelection *selection; 52 18 53 PhotCode *code; 54 Image *image; 55 Vector *vec; 56 57 if (!InitPhotcodes ()) return (FALSE); 19 /* defaults */ 20 vec = NULL; 21 image = NULL; 22 stack = NULL; 23 fields = NULL; 24 values = NULL; 25 selection = NULL; 26 27 if ((N = get_argument (argc, argv, "-h"))) goto help; 28 if ((N = get_argument (argc, argv, "--help"))) goto help; 29 30 VERBOSE = FALSE; 31 if ((N = get_argument (argc, argv, "-v"))) { 32 remove_argument (N, &argc, argv); 33 VERBOSE = TRUE; 34 } 35 36 if (!InitPhotcodes ()) goto escape; 58 37 59 38 // parse skyregion options 60 39 if ((selection = SetRegionSelection (&argc, argv)) == NULL) { 61 40 gprint (GP_ERR, "invalid sky region selection\n"); 62 return FALSE; 63 } 64 65 /* check for time-based selection */ 66 TimeSelect = FALSE; 67 if ((N = get_argument (argc, argv, "-time"))) { 68 remove_argument (N, &argc, argv); 69 if (!ohana_str_to_time (argv[N], &tzero)) { 70 gprint (GP_ERR, "syntax error\n"); 71 return (FALSE); 72 } 73 remove_argument (N, &argc, argv); 74 if (!ohana_str_to_dtime (argv[N], &trange)) { 75 gprint (GP_ERR, "syntax error\n"); 76 return (FALSE); 77 } 78 remove_argument (N, &argc, argv); 79 TimeSelect = TRUE; 80 } 81 82 /* check for region-based selection */ 83 FlagValue = 0; 84 FlagSelect = FALSE; 85 if ((N = get_argument (argc, argv, "-flag"))) { 86 remove_argument (N, &argc, argv); 87 FlagValue = atoi (argv[N]); 88 remove_argument (N, &argc, argv); 89 FlagSelect = TRUE; 90 } 91 92 /* check for photcode-based selection */ 93 code = NULL; 94 PhotcodeSelect = FALSE; 95 if ((N = get_argument (argc, argv, "-photcode"))) { 96 PhotcodeSelect = TRUE; 97 remove_argument (N, &argc, argv); 98 if ((code = GetPhotcodebyName (argv[N])) == NULL) { 99 gprint (GP_ERR, "ERROR: photcode %s not found in photcode table\n", argv[N]); 100 return (FALSE); 101 } 102 if ((code[0].type != PHOT_SEC) && (code[0].type != PHOT_DEP)) { 103 gprint (GP_ERR, "photcode must be primary, secondary, or dependent code\n"); 104 return (FALSE); 105 } 106 remove_argument (N, &argc, argv); 107 } 108 109 if (argc != 2) { 110 gprint (GP_ERR, "USAGE: imextract (value) [-region] [-time start range] [-photcode photcode]\n"); 41 goto escape; 42 } 43 44 // command-line is of the form: imextract field,field, field [where (field op value)...] 45 46 // parse the fields to be extracted and returned 47 fields = dbCmdlineFields (argc, argv, DVO_TABLE_IMAGE, &last, &Nfields); 48 if (fields == NULL) goto escape; 49 if (Nfields == 0) { 50 FreeSkyRegionSelection (selection); 51 dbFreeFields (fields, Nfields); 52 goto help; 53 } 54 55 // examine line for 'where' or 'match to'. 'match to' is forbidden 56 state = dbCmdlineConditions (argc, argv, last, &next); 57 if (state == DVO_DB_CMDLINE_ERROR) goto escape; 58 if (state == DVO_DB_CMDLINE_IS_MATCH) goto escape; // not allowed for mextract 59 60 // parse the remainder of the line as a boolean math expression 61 cstack = isolate_elements (argc-next, &argv[next], &Ncstack); 62 63 // construct the db Boolean math stack (frees cstack) 64 stack = dbRPN (Ncstack, cstack, &Nstack); 65 66 // add the skyregion limits to the where statement (or create) 67 // XXX we may want to drop this and use just the image_subset function 68 dbAstroRegionLimits (&stack, &Nstack, selection, DVO_TABLE_IMAGE); 69 70 // parse stack elements into fields and scalars as needed 71 Nreturn = Nfields; 72 if (!dbCheckStack (stack, Nstack, DVO_TABLE_IMAGE, &fields, &Nfields)) goto escape; 73 74 /* create output storage vectors */ 75 ALLOCATE (values, dbValue, Nfields); 76 ALLOCATE (vec, Vector *, Nreturn); 77 for (i = 0; i < Nreturn; i++) { 78 if (ISNUM(fields[i].name[0])) { 79 sprintf (name, "v_%s", fields[i].name); 80 } else { 81 sprintf (name, "%s", fields[i].name); 82 } 83 if ((vec[i] = SelectVector (name, ANYVECTOR, TRUE)) == NULL) goto escape; 84 ResetVector (vec[i], fields[i].type, NPTS); 85 } 86 87 Npts = 0; 88 NPTS = 1; 89 90 if ((image = LoadImages (&Nimage)) == NULL) goto escape; 91 BuildChipMatch (image, Nimage); 92 dbExtractImagesInit (); 93 94 // XXX do I need to use this, or the region portion 95 // image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, trange, TimeSelect); 96 97 // grab data from all selected sky regions 98 Signal = signal (SIGINT, handle_interrupt); 99 interrupt = FALSE; 100 for (j = 0; (j < Nimage) && !interrupt; j++) { 101 102 // reset counters for saved fields, extract fields 103 dbExtractImagesReset (); 104 for (n = 0; n < Nfields; n++) { 105 values[n] = dbExtractImages (image, Nimage, j, &fields[n]); 106 } 107 108 // test the conditional statement 109 if (!dbBooleanCond (stack, Nstack, values)) continue; 110 for (n = 0; n < Nreturn; n++) { 111 if (vec[n][0].type == OPIHI_FLT) { 112 vec[n][0].elements.Flt[Npts] = values[n].Flt; 113 } else { 114 vec[n][0].elements.Int[Npts] = values[n].Int; 115 } 116 } 117 Npts++; 118 if (Npts >= NPTS) { 119 NPTS += 2000; 120 for (n = 0; n < Nreturn; n++) { 121 if (vec[n][0].type == OPIHI_FLT) { 122 REALLOCATE (vec[n][0].elements.Flt, opihi_flt, NPTS); 123 } else { 124 REALLOCATE (vec[n][0].elements.Int, opihi_int, NPTS); 125 } 126 } 127 } 128 } 129 signal (SIGINT, Signal); 130 interrupt = FALSE; 131 for (n = 0; n < Nreturn; n++) { 132 vec[n][0].Nelements = Npts; 133 if (vec[n][0].type == OPIHI_FLT) { 134 REALLOCATE (vec[n][0].elements.Flt, opihi_flt, MAX(1,Npts)); 135 } else { 136 REALLOCATE (vec[n][0].elements.Int, opihi_int, MAX(1,Npts)); 137 } 138 } 139 140 // free (subset); 141 free (image); 142 143 if (vec) free (vec); 144 if (values) free (values); 145 dbFreeFields (fields, Nfields); 146 dbFreeStack (stack, Nstack); 147 if (stack) free (stack); 148 return (TRUE); 149 150 escape: 151 if (vec) free (vec); 152 if (values) free (values); 153 dbFreeFields (fields, Nfields); 154 dbFreeStack (stack, Nstack); 155 if (stack) free (stack); 156 return (FALSE); 157 158 help: 159 gprint (GP_ERR, "USAGE: imextract field[,field,field...] where (expression)\n"); 160 161 if ((argc > N + 1) && !strcasecmp (argv[N+1], "fields")) { 162 gprint (GP_ERR, " USAGE: imextract field[,field,field...] where (expression)\n"); 163 gprint (GP_ERR, " RA : right ascension of field center (J2000)\n"); 164 gprint (GP_ERR, " DEC : declination of field center\n"); 165 gprint (GP_ERR, " GLON : galactic longitude of field center (J2000)\n"); 166 gprint (GP_ERR, " GLAT : galactic latitude of field center (J2000)\n"); 167 gprint (GP_ERR, " ELON : ecliptic longitude of field center (J2000)\n"); 168 gprint (GP_ERR, " ELAT : ecliptic latitude of field center (J2000)\n"); 169 170 gprint (GP_ERR, " theta : position angle of image\n"); 171 gprint (GP_ERR, " skew : distortion from rectangle\n"); 172 gprint (GP_ERR, " scale : pixel scale\n"); 173 gprint (GP_ERR, " dscale : pixel-scale error (or variation?)\n"); 174 175 gprint (GP_ERR, " time : time of exposure\n"); 176 gprint (GP_ERR, " nstar : number of stars detected in exposure\n"); 177 gprint (GP_ERR, " airmass : mean airmass of exposure\n"); 178 gprint (GP_ERR, " NX : image dimensions\n"); 179 gprint (GP_ERR, " NY : image dimensions\n"); 180 181 gprint (GP_ERR, " apresid : aperture - fit magnitude\n"); 182 gprint (GP_ERR, " dapresid : aperture - fit magnitude scatter\n"); 183 184 gprint (GP_ERR, " Mcal : photometry calibration (mags)\n"); 185 gprint (GP_ERR, " dMcal : photometry calibration error (mags)\n"); 186 gprint (GP_ERR, " Xm : chisq of photometry calibration\n"); 187 gprint (GP_ERR, " photcode : numeric photcode value for image\n"); 188 gprint (GP_ERR, " exptime : exposure duration (seconds)\n"); 189 gprint (GP_ERR, " sidtime : sidereal time of exposure\n"); 190 191 gprint (GP_ERR, " latitude : observatory latitude\n"); 192 193 gprint (GP_ERR, " detlimit : detection limit of exposure\n"); 194 gprint (GP_ERR, " satlimit : saturation limit of exposure\n"); 195 gprint (GP_ERR, " cerror : astrometric scatter\n"); 196 197 gprint (GP_ERR, " FWHM : mean fwhm of exposure\n"); 198 gprint (GP_ERR, " FWHM_MAJ : fwhm of major axis\n"); 199 gprint (GP_ERR, " FWHM_MIN : fwhm of minor axis\n"); 200 gprint (GP_ERR, " trate : tracking rate for TDI images\n"); 201 202 gprint (GP_ERR, " ncal : number of stars used for photometry calibration\n"); 203 gprint (GP_ERR, " sky : mean background flux\n"); 204 205 gprint (GP_ERR, " flag : processing bit flags\n"); 206 gprint (GP_ERR, " ccdnum : identifier for CCD\n"); 207 208 gprint (GP_ERR, " imageID : unique image identifier\n"); 209 gprint (GP_ERR, " externID : external image identifier\n"); 210 gprint (GP_ERR, " sourceID : external db reference\n"); 211 212 gprint (GP_ERR, " X_LL_CHIP : chip x-pixel coordinate of lower left corner\n"); 213 gprint (GP_ERR, " X_LR_CHIP : chip x-pixel coordinate of lower right corner\n"); 214 gprint (GP_ERR, " X_UL_CHIP : chip x-pixel coordinate of upper left corner\n"); 215 gprint (GP_ERR, " X_UR_CHIP : chip x-pixel coordinate of upper right corner\n"); 216 gprint (GP_ERR, " Y_LL_CHIP : chip y-pixel coordinate of lower left corner\n"); 217 gprint (GP_ERR, " Y_LR_CHIP : chip y-pixel coordinate of lower right corner\n"); 218 gprint (GP_ERR, " Y_UL_CHIP : chip y-pixel coordinate of upper left corner\n"); 219 gprint (GP_ERR, " Y_UR_CHIP : chip y-pixel coordinate of upper right corner\n"); 220 gprint (GP_ERR, " X_LL_FP : focal-plane x-pixel coordinate of lower left corner\n"); 221 gprint (GP_ERR, " X_LR_FP : focal-plane x-pixel coordinate of lower right corner\n"); 222 gprint (GP_ERR, " X_UL_FP : focal-plane x-pixel coordinate of upper left corner\n"); 223 gprint (GP_ERR, " X_UR_FP : focal-plane x-pixel coordinate of upper right corner\n"); 224 gprint (GP_ERR, " Y_LL_FP : focal-plane y-pixel coordinate of lower left corner\n"); 225 gprint (GP_ERR, " Y_LR_FP : focal-plane y-pixel coordinate of lower right corner\n"); 226 gprint (GP_ERR, " Y_UL_FP : focal-plane y-pixel coordinate of upper left corner\n"); 227 gprint (GP_ERR, " Y_UR_FP : focal-plane y-pixel coordinate of upper right corner\n"); 111 228 return (FALSE); 112 229 } 113 114 /* identify selection */ 115 mode = ZERO; 116 if (!strcasecmp (argv[1], "ra" )) mode = RA; 117 if (!strcasecmp (argv[1], "dec" )) mode = DEC; 118 if (!strcasecmp (argv[1], "Xm" )) mode = Xm; 119 if (!strcasecmp (argv[1], "airmass" )) mode = AIRMASS; 120 if (!strcasecmp (argv[1], "Mcal" )) mode = MCAL; 121 if (!strcasecmp (argv[1], "dMcal" )) mode = dMCAL; 122 if (!strcasecmp (argv[1], "photcode" )) mode = PHOTCODE; 123 if (!strcasecmp (argv[1], "time" )) mode = TIME; 124 if (!strcasecmp (argv[1], "FWHM" )) mode = FWHM; 125 if (!strcasecmp (argv[1], "exptime" )) mode = EXPTIME; 126 if (!strcasecmp (argv[1], "nstar" )) mode = NSTAR; 127 if (!strcasecmp (argv[1], "ncal" )) mode = NCAL; 128 if (!strcasecmp (argv[1], "sky" )) mode = SKY; 129 if (!strcasecmp (argv[1], "flag" )) mode = FLAG; 130 if (!strcasecmp (argv[1], "NX" )) mode = NX_PIX; 131 if (!strcasecmp (argv[1], "NY" )) mode = NY_PIX; 132 if (!strcasecmp (argv[1], "theta" )) mode = THETA; 133 if (!strcasecmp (argv[1], "skew" )) mode = SKEW; 134 if (!strcasecmp (argv[1], "scale" )) mode = SCALE; 135 if (!strcasecmp (argv[1], "dscale" )) mode = DSCALE; 136 if (!strcasecmp (argv[1], "imageID" )) mode = IMAGE_ID; 137 if (!strcasecmp (argv[1], "X_LL_CHIP")) mode = X_LL_CHIP; 138 if (!strcasecmp (argv[1], "X_LR_CHIP")) mode = X_LR_CHIP; 139 if (!strcasecmp (argv[1], "X_UL_CHIP")) mode = X_UL_CHIP; 140 if (!strcasecmp (argv[1], "X_UR_CHIP")) mode = X_UR_CHIP; 141 if (!strcasecmp (argv[1], "Y_LL_CHIP")) mode = Y_LL_CHIP; 142 if (!strcasecmp (argv[1], "Y_LR_CHIP")) mode = Y_LR_CHIP; 143 if (!strcasecmp (argv[1], "Y_UL_CHIP")) mode = Y_UL_CHIP; 144 if (!strcasecmp (argv[1], "Y_UR_CHIP")) mode = Y_UR_CHIP; 145 if (!strcasecmp (argv[1], "X_LL_FP" )) mode = X_LL_FP; 146 if (!strcasecmp (argv[1], "X_LR_FP" )) mode = X_LR_FP; 147 if (!strcasecmp (argv[1], "X_UL_FP" )) mode = X_UL_FP; 148 if (!strcasecmp (argv[1], "X_UR_FP" )) mode = X_UR_FP; 149 if (!strcasecmp (argv[1], "Y_LL_FP" )) mode = Y_LL_FP; 150 if (!strcasecmp (argv[1], "Y_LR_FP" )) mode = Y_LR_FP; 151 if (!strcasecmp (argv[1], "Y_UL_FP" )) mode = Y_UL_FP; 152 if (!strcasecmp (argv[1], "Y_UR_FP" )) mode = Y_UR_FP; 153 if (mode == ZERO) { 154 gprint (GP_ERR, "value may be one of the following:\n"); 155 gprint (GP_ERR, " ra dec airmass Mcal dMcal Xm photcode time fwhm exptime nstar ncal sky flag\n"); 156 return (FALSE); 157 } 158 if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) return (FALSE); 159 160 if ((image = LoadImages (&Nimage)) == NULL) return (FALSE); 161 image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, trange, TimeSelect); 162 if ((mode == RA) || (mode == DEC)) BuildChipMatch (image, Nimage); 163 164 GetTimeFormat (&TimeReference, &TimeFormat); 165 166 /* create storage vector */ 167 REALLOCATE (vec[0].elements, float, Nimage); 168 vec[0].Nelements = Nimage; 169 170 N = 0; 171 /* assign vector values */ 172 for (i = 0; i < Nsubset; i++) { 173 j = subset[i]; 174 if (PhotcodeSelect) { 175 if (code[0].type == PHOT_DEP) { 176 if (code[0].code != image[j].photcode) continue; 177 } else { 178 if (code[0].code != GetPhotcodeEquivCodebyCode (image[j].photcode)) continue; 179 } 180 } 181 if (FlagSelect && (FlagValue != image[j].code)) continue; 182 switch (mode) { 183 case RA: 184 if (!FindMosaicForImage (image, Nimage, j)) continue; 185 x = 0.5*image[j].NX; 186 y = 0.5*image[j].NY; 187 XY_to_RD (&ra, &dec, x, y, &image[j].coords); 188 vec[0].elements[N] = ra; 189 break; 190 case DEC: 191 if (!FindMosaicForImage (image, Nimage, j)) continue; 192 x = 0.5*image[j].NX; 193 y = 0.5*image[j].NY; 194 XY_to_RD (&ra, &dec, x, y, &image[j].coords); 195 vec[0].elements[N] = dec; 196 break; 197 case Xm: 198 vec[0].elements[N] = pow(10.0, 0.01*image[j].Xm); 199 break; 200 case AIRMASS: 201 vec[0].elements[N] = image[j].secz; 202 break; 203 case MCAL: 204 vec[0].elements[N] = image[j].Mcal; 205 break; 206 case dMCAL: 207 vec[0].elements[N] = image[j].dMcal; 208 break; 209 case PHOTCODE: 210 vec[0].elements[N] = image[j].photcode; 211 break; 212 case TIME: 213 t = image[j].tzero + 0.5*image[j].NY * image[j].trate / 10000; 214 vec[0].elements[N] = TimeValue (t, TimeReference, TimeFormat); 215 break; 216 case FWHM: 217 vec[0].elements[N] = image[j].fwhm_x / 25.0; 218 break; 219 case EXPTIME: 220 vec[0].elements[N] = image[j].exptime; 221 break; 222 case NSTAR: 223 vec[0].elements[N] = image[j].nstar; 224 break; 225 case NCAL: 226 vec[0].elements[N] = image[j].Mxxxx; 227 break; 228 case SKY: 229 vec[0].elements[N] = image[j].Myyyy + 0x8000; 230 break; 231 case FLAG: 232 vec[0].elements[N] = image[j].code; 233 break; 234 case NX_PIX: 235 vec[0].elements[N] = image[j].NX; 236 break; 237 case NY_PIX: 238 vec[0].elements[N] = image[j].NY; 239 break; 240 case IMAGE_ID: 241 vec[0].elements[N] = image[j].imageID; 242 break; 243 case THETA: { 244 double theta1, theta2, s1, s2; 245 s1 = SIGN(image[j].coords.pc1_1); 246 s2 = SIGN(image[j].coords.pc2_2); 247 theta1 = DEG_RAD*atan2 (+s1*image[j].coords.pc1_2, s1*image[j].coords.pc1_1); 248 theta2 = DEG_RAD*atan2 (-s2*image[j].coords.pc2_1, s2*image[j].coords.pc2_2); 249 vec[0].elements[N] = 0.5*(theta1+theta2); 250 break; } 251 case SKEW: { 252 double theta1, theta2, s1, s2; 253 s1 = SIGN(image[j].coords.pc1_1); 254 s2 = SIGN(image[j].coords.pc2_2); 255 theta1 = DEG_RAD*atan2 (+s1*image[j].coords.pc1_2, s1*image[j].coords.pc1_1); 256 theta2 = DEG_RAD*atan2 (-s2*image[j].coords.pc2_1, s2*image[j].coords.pc2_2); 257 vec[0].elements[N] = (theta1-theta2); 258 break; } 259 case SCALE: { 260 double scale1, scale2; 261 scale1 = fabs(image[j].coords.cdelt1); 262 scale2 = fabs(image[j].coords.cdelt2); 263 vec[0].elements[N] = 0.5*(scale1+scale2); 264 break; } 265 case DSCALE: { 266 double scale1, scale2; 267 scale1 = fabs(image[j].coords.cdelt1); 268 scale2 = fabs(image[j].coords.cdelt2); 269 vec[0].elements[N] = (scale1-scale2); 270 break; } 271 272 // reference pixel extractions 273 case X_LL_CHIP: 274 case Y_LL_CHIP: 275 case Y_LR_CHIP: 276 case X_UL_CHIP: 277 vec[0].elements[N] = 0.0; 278 break; 279 case X_LR_CHIP: 280 case X_UR_CHIP: 281 vec[0].elements[N] = image[j].NX; 282 break; 283 case Y_UL_CHIP: 284 case Y_UR_CHIP: 285 vec[0].elements[N] = image[j].NX; 286 break; 287 288 case X_LL_FP: 289 case Y_LL_FP: 290 XY_to_LM (&x, &y, 0.0, 0.0, &image[j].coords); 291 vec[0].elements[N] = (mode == X_LL_FP) ? x : y; 292 break; 293 case X_LR_FP: 294 case Y_LR_FP: 295 XY_to_LM (&x, &y, image[j].NX, 0.0, &image[j].coords); 296 vec[0].elements[N] = (mode == X_LR_FP) ? x : y; 297 break; 298 case X_UL_FP: 299 case Y_UL_FP: 300 XY_to_LM (&x, &y, 0.0, image[j].NY, &image[j].coords); 301 vec[0].elements[N] = (mode == X_UL_FP) ? x : y; 302 break; 303 case X_UR_FP: 304 case Y_UR_FP: 305 XY_to_LM (&x, &y, image[j].NX, image[j].NY, &image[j].coords); 306 vec[0].elements[N] = (mode == X_UR_FP) ? x : y; 307 break; 308 } 309 N++; 310 } 311 312 vec[0].Nelements = N; 313 REALLOCATE (vec[0].elements, float, N); 314 315 free (subset); 316 free (image); 317 return (TRUE); 318 230 gprint (GP_ERR, " imextract --help fields : for a complete listing of allowed fields\n"); 231 return (FALSE); 319 232 } 320 233
Note:
See TracChangeset
for help on using the changeset viewer.
