File indexing completed on 2025-01-05 04:11:58
0001 /* (C) 2002 C. Barth Netterfield */ 0002 /*************************************************************************** 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU General Public License as published by * 0006 * the Free Software Foundation; either version 2 of the License, or * 0007 * (at your option) any later version. * 0008 * * 0009 ***************************************************************************/ 0010 #include <assert.h> 0011 #include <stdio.h> 0012 #include <stdlib.h> 0013 #include <fcntl.h> 0014 #include <libgen.h> 0015 #include <sys/stat.h> 0016 #include <sys/types.h> 0017 #include <unistd.h> 0018 #include <string.h> 0019 #include <math.h> 0020 0021 #include "getdata.h" 0022 #include "getdata_struct.h" 0023 0024 const char *GD_ERROR_CODES[15] = {"OK", 0025 "Could not open Format file", 0026 "Error in Format file", 0027 "Could not open Data file", 0028 "Field name too long", 0029 "Field code not found in File Format", 0030 "Unrecognized return type", 0031 "Could not open field file", 0032 "Could not open included Format file", 0033 "Internal error", 0034 " ", 0035 " ", 0036 "Size mismatch in linear combination", 0037 "Could not open interpolation file", 0038 "Too many levels of recursion" 0039 }; 0040 0041 /* Suberror codes -- these don't need to be public */ 0042 #define GD_E_FORMAT_SE_BAD_TYPE 0 0043 #define GD_E_FORMAT_SE_BAD_SPF 1 0044 #define GD_E_FORMAT_SE_N_FIELDS 2 0045 #define GD_E_FORMAT_SE_N_COLS 3 0046 #define GD_E_FORMAT_SE_MAX_I 4 0047 #define GD_E_FORMAT_SE_NUMBITS 5 0048 #define GD_E_FORMAT_SE_BITNUM 6 0049 #define GD_E_FORMAT_SE_BITSIZE 7 0050 #define GD_E_FORMAT_SE_FIELD_LEN 8 0051 #define GD_E_FORMAT_SE_BAD_LINE 9 0052 #define GD_E_FORMAT_SE_N_RAW 10 0053 0054 #define GD_E_LINFILE_SE_OPEN 0 0055 #define GD_E_LINFILE_SE_LENGTH 1 0056 0057 static struct { 0058 int n; 0059 struct FormatType *F; 0060 } Formats; 0061 0062 static int recurse_level = 0; 0063 static int first_time = 1; 0064 static int getdata_error = GD_E_OK; 0065 static int getdata_suberror = 0; 0066 static char getdata_error_string[MAX_FILENAME_LENGTH + 6]; 0067 static char getdata_error_file[MAX_FILENAME_LENGTH + 6]; 0068 static int getdata_error_line = 0; 0069 0070 static int DoField(struct FormatType *F, const char *field_code, 0071 int first_frame, int first_samp, 0072 int num_frames, int num_samp, 0073 char return_type, void *data_out, 0074 int *error_code); 0075 0076 /***************************************************************************/ 0077 /* */ 0078 /* GetLine: read non-comment line from format file */ 0079 /* The line is placed in *line. */ 0080 /* Returns 1 if successful, 0 if unsuccessful */ 0081 /* */ 0082 /***************************************************************************/ 0083 static int GetLine(FILE *fp, char *line, int* linenum) { 0084 char *ret_val; 0085 int first_char; 0086 int i, len; 0087 0088 do { 0089 ret_val = fgets(line, MAX_LINE_LENGTH, fp); 0090 (*linenum)++; 0091 first_char = 0; 0092 while (line[first_char] == ' ' || line[first_char] == '\t') ++first_char; 0093 line += first_char; 0094 } while (ret_val && (line[0] == '#' || line[0] == 0 || line[1] == 0)); 0095 0096 0097 if (ret_val) { 0098 /* truncate comments from end of lines */ 0099 len = strlen(line); 0100 for (i = 0; i < len; i++) { 0101 if (line[i]=='#') 0102 line[i] = '\0'; 0103 } 0104 0105 return(1); /* a line was read */ 0106 } 0107 return(0); /* there were no valid lines */ 0108 } 0109 0110 /* SetGetDataError: Sets the global error variables for a library error */ 0111 static int SetGetDataError(int error, int suberror, 0112 const char* format_file, int line, const char* token) 0113 { 0114 getdata_error = error; 0115 getdata_suberror = suberror; 0116 getdata_error_line = line; 0117 if (format_file != NULL) 0118 strncpy(getdata_error_file, format_file, MAX_FILENAME_LENGTH + 6); 0119 if (token != NULL) 0120 strncpy(getdata_error_string, token, MAX_FILENAME_LENGTH + 6); 0121 0122 return error; 0123 } 0124 0125 /***************************************************************************/ 0126 /* */ 0127 /* GetDataErrorString: Write a descriptive message in the supplied */ 0128 /* buffer describing the last library error. The message may be */ 0129 /* truncated but should be null terminated. */ 0130 /* */ 0131 /* buffer: memory into which to write the string */ 0132 /* buflen: length of the buffer. GetDataErrorString will not write */ 0133 /* more than buflen characters (including the trailing '\0') */ 0134 /* */ 0135 /* return value: buffer or NULL if buflen < 1 */ 0136 /* */ 0137 /***************************************************************************/ 0138 char* GetDataErrorString(char* buffer, size_t buflen) 0139 { 0140 char* ptr; 0141 0142 /* Sanity check */ 0143 if (buffer == NULL || buflen < 1) 0144 return NULL; 0145 0146 /* Copy the default error message into the buffer and make sure 0147 * the result is null terminated */ 0148 strncpy(buffer, GD_ERROR_CODES[getdata_error], buflen - 1); 0149 buffer[buflen - 1] = 0; 0150 0151 /* point to the end of the string and reduce buflen appropriately */ 0152 ptr = buffer + strlen(buffer); 0153 buflen -= strlen(buffer); 0154 0155 /* add the anciliary data - we use snprintfs here to ensure the resultant 0156 * string is properly null terminated (while not overflowing the buffer) */ 0157 switch (getdata_error) { 0158 case GD_E_INTERNAL_ERROR: /* internal error: report line and source file 0159 where it happened */ 0160 snprintf(ptr, buflen, " [%s,%i]", getdata_error_file, 0161 getdata_error_line); 0162 break; 0163 case GD_E_OPEN_FORMAT: /* main format file couldn't be opened -- report 0164 the filename we tried to open */ 0165 snprintf(ptr, buflen, " %s", getdata_error_file); 0166 break; 0167 case GD_E_FORMAT: /* syntax errors in the format file -- lots of 0168 suberror types here */ 0169 0170 /* No RAW fields specified -- this isn't tied to a particular line */ 0171 if (getdata_suberror == GD_E_FORMAT_SE_N_RAW) { 0172 snprintf(ptr, buflen, ": no raw fields defined"); 0173 break; 0174 } 0175 0176 /* otherwise, add the format filename and line number where the 0177 * syntax error was found */ 0178 snprintf(ptr, buflen, " on line %i of %s: ", getdata_error_line, 0179 getdata_error_file); 0180 buflen -= strlen(ptr); 0181 ptr += strlen(ptr); 0182 0183 switch (getdata_suberror) { 0184 case GD_E_FORMAT_SE_BAD_TYPE: /* bad field type; include the thing 0185 we thought was the type specifier */ 0186 snprintf(ptr, buflen, "bad raw field type: %c", 0187 getdata_error_string[0]); 0188 break; 0189 case GD_E_FORMAT_SE_BAD_SPF: /* SPF < 0 -- print the column we expected 0190 to hold the SPF */ 0191 snprintf(ptr, buflen, "samples per frame out of range: %s", 0192 getdata_error_string); 0193 break; 0194 case GD_E_FORMAT_SE_N_FIELDS: /* number of fields in the LINCOM and 0195 the number of columns in the format 0196 file don't match */ 0197 snprintf(ptr, buflen, "lincom field count out of range: %s", 0198 getdata_error_string); 0199 break; 0200 case GD_E_FORMAT_SE_N_COLS: /* missing data we expected to find on this 0201 line */ 0202 snprintf(ptr, buflen, "missing column"); 0203 break; 0204 case GD_E_FORMAT_SE_MAX_I: /* max_i out of range (what is an MPLEX?) */ 0205 snprintf(ptr, buflen, "max_i out of range: %s", getdata_error_string); 0206 break; 0207 case GD_E_FORMAT_SE_NUMBITS: /* bitfield numbits is less than 1 */ 0208 snprintf(ptr, buflen, "numbits out of range"); 0209 break; 0210 case GD_E_FORMAT_SE_BITNUM: /* bitnum is less than 0 */ 0211 snprintf(ptr, buflen, "starting bit out of range"); 0212 break; 0213 case GD_E_FORMAT_SE_BITSIZE: /* bitfield extends past 32 bits */ 0214 snprintf(ptr, buflen, "end of bitfield is out of bounds"); 0215 break; 0216 case GD_E_FORMAT_SE_FIELD_LEN: /* field name is too long */ 0217 snprintf(ptr, buflen, "field name too long: %s", 0218 getdata_error_string); 0219 break; 0220 case GD_E_FORMAT_SE_BAD_LINE: /* couldn't make heads nor tails of the 0221 line -- ie. a mistyped keyword &c. */ 0222 snprintf(ptr, buflen, "line indecypherable"); 0223 break; 0224 } 0225 break; 0226 case GD_E_OPEN_INCLUDE: /* Couldn't open an INCLUDEd file -- report the 0227 included filename as well as the line and name 0228 of the format file where it was encountered */ 0229 snprintf(ptr, buflen, "%s on line %i of %s", getdata_error_string, 0230 getdata_error_line, getdata_error_file); 0231 break; 0232 case GD_E_BAD_RETURN_TYPE: /* unsupported data return type passed to 0233 GetData */ 0234 snprintf(ptr, buflen, ": %c", (char)getdata_suberror); 0235 break; 0236 case GD_E_RECURSE_LEVEL: /* recursion too deep -- report field name for 0237 which this happened */ 0238 snprintf(ptr, buflen, " while resolving field %s", getdata_error_string); 0239 break; 0240 case GD_E_BAD_CODE: /* A required field name wasn't defined */ 0241 case GD_E_OPEN_RAWFIELD: /* A raw field file wasn't found on disk */ 0242 snprintf(ptr, buflen, ": %s", getdata_error_string); 0243 break; 0244 case GD_E_OPEN_LINFILE: /* problems with LINTERPs: report the linterp 0245 filename with the error message */ 0246 snprintf(ptr, buflen, " %s: %s", getdata_error_string, 0247 (getdata_suberror == GD_E_LINFILE_SE_OPEN) ? "open failed" 0248 : "file too short"); 0249 break; 0250 } 0251 0252 return buffer; 0253 } 0254 0255 /***************************************************************************/ 0256 /* */ 0257 /* FreeF: free any entries that have been allocated in F */ 0258 /* */ 0259 /***************************************************************************/ 0260 static void FreeF(struct FormatType *F) { 0261 if (F->n_raw > 0) free(F->rawEntries); 0262 if (F->n_lincom > 0) free(F->lincomEntries); 0263 if (F->n_multiply > 0) free(F->multiplyEntries); 0264 if (F->n_linterp >0) free(F->linterpEntries); 0265 if (F->n_mplex > 0) free(F->mplexEntries); 0266 if (F->n_bit > 0) free(F->bitEntries); 0267 } 0268 0269 /***************************************************************************/ 0270 /* */ 0271 /* ParseRaw: parse a RAW data type in the formats file */ 0272 /* */ 0273 /***************************************************************************/ 0274 static int ParseRaw(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], 0275 struct RawEntryType *R, const char* subdir, const char* format_file, 0276 int line) 0277 { 0278 strcpy(R->field, in_cols[0]); /* field */ 0279 snprintf(R->file, MAX_FILENAME_LENGTH + FIELD_LENGTH + 2, "%s/%s", subdir, 0280 in_cols[0]); /* path and filename */ 0281 R->fp = -1; /* file not opened yet */ 0282 switch (in_cols[2][0]) { 0283 case 'c': 0284 R->size = 1; 0285 break; 0286 case 's': case 'u': 0287 R->size = 2; 0288 break; 0289 case 'S': case 'U': case 'f': case 'i': 0290 R->size = 4; 0291 break; 0292 case 'd': 0293 R->size = 8; 0294 break; 0295 default: 0296 return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_BAD_TYPE, format_file, 0297 line, in_cols[2]); 0298 } 0299 R->type = in_cols[2][0]; 0300 R->samples_per_frame = atoi(in_cols[3]); 0301 if (R->samples_per_frame<=0) { 0302 return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_BAD_SPF, format_file, 0303 line, in_cols[3]); 0304 } 0305 0306 return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 0307 } 0308 0309 /***************************************************************************/ 0310 /* */ 0311 /* ParseLincom: parse a LINCOM data type in the formats file */ 0312 /* */ 0313 /***************************************************************************/ 0314 static int ParseLincom(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], int n_cols, 0315 struct LincomEntryType *L, const char* format_file, int line) 0316 { 0317 int i; 0318 strcpy(L->field, in_cols[0]); /* field */ 0319 L->n_infields = atoi(in_cols[2]); 0320 if ((L->n_infields<1) || (L->n_infields>MAX_LINCOM) || 0321 (n_cols < L->n_infields*3 + 3)) { 0322 return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_FIELDS, format_file, 0323 line, in_cols[2]); 0324 } 0325 0326 for (i=0; i<L->n_infields; i++) { 0327 strncpy(L->in_fields[i], in_cols[i*3+3], FIELD_LENGTH); 0328 L->m[i] = atof(in_cols[i*3+4]); 0329 L->b[i] = atof(in_cols[i*3+5]); 0330 } 0331 0332 return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 0333 } 0334 /***************************************************************************/ 0335 /* */ 0336 /* ParseLinterp: parse a LINTERP data type in the formats file */ 0337 /* */ 0338 /***************************************************************************/ 0339 static int ParseLinterp(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], 0340 struct LinterpEntryType *L) 0341 { 0342 strcpy(L->field, in_cols[0]); /* field */ 0343 strncpy(L->raw_field, in_cols[2], FIELD_LENGTH); 0344 strcpy(L->linterp_file, in_cols[3]); 0345 L->n_interp = -1; /* linterp file not read yet */ 0346 0347 return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 0348 } 0349 0350 /***************************************************************************/ 0351 /* */ 0352 /* ParseMultiply: parse MULTIPLY data type entry in formats file */ 0353 /* */ 0354 /***************************************************************************/ 0355 static int ParseMultiply(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], int n_cols, 0356 struct MultiplyEntryType *M, const char* format_file, int line) 0357 { 0358 if (n_cols < 4) 0359 return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_COLS, format_file, 0360 line, NULL); 0361 0362 strcpy(M->field, in_cols[0]); /* field */ 0363 0364 strncpy(M->in_fields[0], in_cols[2], FIELD_LENGTH); 0365 strncpy(M->in_fields[1], in_cols[3], FIELD_LENGTH); 0366 0367 return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 0368 } 0369 0370 /***************************************************************************/ 0371 /* */ 0372 /* ParseMplex: parse MPLEX data type entry in formats file */ 0373 /* */ 0374 /***************************************************************************/ 0375 static int ParseMplex(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], int n_cols, 0376 struct MplexEntryType *M, const char* format_file, int line) 0377 { 0378 if (n_cols < 6) 0379 return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_COLS, format_file, 0380 line, NULL); 0381 0382 strcpy(M->field, in_cols[0]); /* field */ 0383 strncpy(M->cnt_field, in_cols[2], FIELD_LENGTH); 0384 strncpy(M->data_field, in_cols[3], FIELD_LENGTH); 0385 M->i = atoi(in_cols[4]); 0386 M->max_i = atoi(in_cols[5]); 0387 if ((M->max_i < 1) || (M->max_i < M->i)) 0388 return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_MAX_I, format_file, 0389 line, NULL); 0390 0391 return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 0392 } 0393 0394 /***************************************************************************/ 0395 /* */ 0396 /* ParseBit: parse BIT data type entry in formats file */ 0397 /* */ 0398 /***************************************************************************/ 0399 static int ParseBit(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], int n_cols, 0400 struct BitEntryType *B, const char* format_file, int line) 0401 { 0402 0403 strcpy(B->field, in_cols[0]); /* field */ 0404 strncpy(B->raw_field, in_cols[2], FIELD_LENGTH); /* field */ 0405 0406 B->bitnum=atoi(in_cols[3]); 0407 if (n_cols>4) { 0408 B->numbits=atoi(in_cols[4]); 0409 } else { 0410 B->numbits=1; 0411 } 0412 0413 if (B->numbits < 1) 0414 return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_NUMBITS, format_file, 0415 line, NULL); 0416 if (B->bitnum < 0) 0417 return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_BITNUM, format_file, 0418 line, NULL); 0419 if (B->bitnum + B->numbits - 1 > 31) 0420 return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_BITSIZE, format_file, 0421 line, NULL); 0422 0423 return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 0424 } 0425 0426 /***************************************************************************/ 0427 /* */ 0428 /* Compare functions for sorting the lists (using stdlib qsort) */ 0429 /* */ 0430 /***************************************************************************/ 0431 static int RawCmp(const void *A, const void *B) { 0432 return (strcmp(((struct RawEntryType *)A)->field, 0433 ((struct RawEntryType *)B)->field)); 0434 } 0435 0436 static int LincomCmp(const void *A, const void *B) { 0437 return (strcmp(((struct LincomEntryType *)A)->field, 0438 ((struct LincomEntryType *)B)->field)); 0439 } 0440 0441 static int LinterpCmp(const void *A, const void *B) { 0442 return (strcmp(((struct LinterpEntryType *)A)->field, 0443 ((struct LinterpEntryType *)B)->field)); 0444 } 0445 0446 static int MultiplyCmp(const void *A, const void *B) { 0447 return (strcmp(((struct MultiplyEntryType *)A)->field, 0448 ((struct MultiplyEntryType *)B)->field)); 0449 } 0450 0451 static int MplexCmp(const void *A, const void *B) { 0452 return (strcmp(((struct MplexEntryType *)A)->field, 0453 ((struct MplexEntryType *)B)->field)); 0454 } 0455 0456 static int BitCmp(const void *A, const void *B) { 0457 return (strcmp(((struct BitEntryType *)A)->field, 0458 ((struct BitEntryType *)B)->field)); 0459 } 0460 0461 /***************************************************************************/ 0462 /* */ 0463 /* ParseFormatFile: Perform the actual parsing of the format file. This */ 0464 /* function is called from GetFormat once for the main format file and */ 0465 /* once for each included file. */ 0466 /* */ 0467 /***************************************************************************/ 0468 static int ParseFormatFile(FILE* fp, struct FormatType *F, const char* filedir, 0469 const char* subdir, const char* format_file, char*** IncludeList, 0470 int *i_include) 0471 { 0472 char instring[MAX_LINE_LENGTH]; 0473 char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH]; 0474 int n_cols, error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 0475 int linenum = 0; 0476 0477 /***** start parsing ****/ 0478 while (GetLine(fp, instring, &linenum)) { 0479 /* ok, brute force parse... slow and ugly but convenient... */ 0480 n_cols = sscanf(instring, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", 0481 in_cols[0], in_cols[1], in_cols[2], in_cols[3], 0482 in_cols[4], in_cols[5], in_cols[6], in_cols[7], 0483 in_cols[8], in_cols[9], in_cols[10], in_cols[11], 0484 in_cols[12], in_cols[13], in_cols[14]); 0485 0486 if (n_cols<2) { 0487 error_code = SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_COLS, 0488 format_file, linenum, NULL); 0489 } else if (strlen(in_cols[0])>FIELD_LENGTH) { 0490 error_code = SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_FIELD_LEN, 0491 format_file, linenum, in_cols[0]); 0492 } else if (strcmp(in_cols[1], "RAW")==0) { 0493 F->n_raw++; 0494 F->rawEntries = 0495 realloc(F->rawEntries, F->n_raw*sizeof(struct RawEntryType)); 0496 error_code = ParseRaw(in_cols, F->rawEntries+F->n_raw - 1, subdir, 0497 format_file, linenum); 0498 } else if (strcmp(in_cols[1], "LINCOM")==0) { 0499 F->n_lincom++; 0500 F->lincomEntries = 0501 realloc(F->lincomEntries, 0502 F->n_lincom*sizeof(struct LincomEntryType)); 0503 error_code = ParseLincom(in_cols, n_cols, F->lincomEntries+F->n_lincom 0504 - 1, format_file, linenum); 0505 } else if (strcmp(in_cols[1], "LINTERP")==0) { 0506 F->n_linterp++; 0507 F->linterpEntries = 0508 realloc(F->linterpEntries, 0509 F->n_linterp*sizeof(struct LinterpEntryType)); 0510 error_code = ParseLinterp(in_cols, F->linterpEntries+F->n_linterp - 1); 0511 } else if (strcmp(in_cols[1], "MULTIPLY")==0) { 0512 F->n_multiply++; 0513 F->multiplyEntries = 0514 realloc(F->multiplyEntries, 0515 F->n_multiply*sizeof(struct MultiplyEntryType)); 0516 error_code = ParseMultiply(in_cols, n_cols, F->multiplyEntries + 0517 F->n_multiply - 1, format_file, linenum); 0518 } else if (strcmp(in_cols[1], "MPLEX")==0) { 0519 F->n_mplex++; 0520 F->mplexEntries = 0521 realloc(F->mplexEntries, 0522 F->n_mplex*sizeof(struct MplexEntryType)); 0523 error_code = ParseMplex(in_cols, n_cols, F->mplexEntries+F->n_mplex - 1, 0524 format_file, linenum); 0525 } else if (strcmp(in_cols[1], "BIT")==0) { 0526 F->n_bit++; 0527 F->bitEntries = 0528 realloc(F->bitEntries, 0529 F->n_bit*sizeof(struct BitEntryType)); 0530 error_code = ParseBit(in_cols, n_cols, F->bitEntries+F->n_bit - 1, 0531 format_file, linenum); 0532 } else if (strcmp(in_cols[0], "FRAMEOFFSET")==0) { 0533 F->frame_offset = atoi(in_cols[1]); 0534 } else if (strcmp(in_cols[0], "INCLUDE")==0) { 0535 int i, found = 0; 0536 char new_format_file[MAX_FILENAME_LENGTH + 6]; 0537 char new_subdir[MAX_FILENAME_LENGTH + 1]; 0538 FILE* new_fp = NULL; 0539 0540 /* Run through the include list to see if we've already included this 0541 * file */ 0542 for (i = 0; i < *i_include; ++i) 0543 if (strcmp(in_cols[1], (*IncludeList)[i]) == 0) { 0544 found = 1; 0545 break; 0546 } 0547 0548 /* If we found the file, we won't reopen it. Continue parsing. */ 0549 if (found) 0550 continue; 0551 0552 /* Otherwise, try to open the file */ 0553 snprintf(new_format_file, MAX_FILENAME_LENGTH + 6, "%s/%s/%s", filedir, 0554 subdir, in_cols[1]); 0555 new_fp = fopen(new_format_file, "r"); 0556 0557 /* If opening the file failed, set the error code and abort parsing. */ 0558 if (new_fp == NULL) { 0559 error_code = SetGetDataError(GD_E_OPEN_INCLUDE, 0, format_file, linenum, 0560 new_format_file); 0561 break; 0562 } 0563 0564 /* If we got here, we managed to open the inlcuded file; parse it */ 0565 *IncludeList = realloc(*IncludeList, ++(*i_include) * sizeof(char*)); 0566 (*IncludeList)[*i_include - 1] = strdup(in_cols[1]); 0567 0568 /* extract the subdirectory name - dirname both returns a volatile string 0569 * and modifies its argument, ergo strcpy */ 0570 strcpy(new_format_file, in_cols[1]); 0571 if (strcmp(subdir, ".") == 0) 0572 strcpy(new_subdir, dirname(new_format_file)); 0573 else 0574 snprintf(new_subdir, MAX_FILENAME_LENGTH, "%s/%s", subdir, 0575 dirname(new_format_file)); 0576 0577 error_code = ParseFormatFile(new_fp, F, filedir, new_subdir, 0578 new_format_file, IncludeList, i_include); 0579 fclose(new_fp); 0580 } else 0581 error_code = SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_BAD_LINE, 0582 format_file, linenum, NULL); 0583 0584 /* break out of loop (so we can return) if we've encountered an error */ 0585 if (error_code != GD_E_OK) 0586 break; 0587 } 0588 0589 return error_code; 0590 } 0591 0592 /***************************************************************************/ 0593 /* */ 0594 /* GetFormat: Read format file and fill structure. The format */ 0595 /* is cached. */ 0596 /* */ 0597 /***************************************************************************/ 0598 struct FormatType *GetFormat(const char *filedir, int *error_code) { 0599 int i_format, i; 0600 struct stat statbuf; 0601 FILE *fp; 0602 char format_file[MAX_FILENAME_LENGTH+6]; 0603 struct FormatType *F; 0604 char raw_data_filename[MAX_FILENAME_LENGTH+FIELD_LENGTH+2]; 0605 char **IncludeList = NULL; 0606 int i_include; 0607 0608 /** first check to see if we have already read it **/ 0609 for (i_format=0; i_format<Formats.n; i_format++) { 0610 if (strncmp(filedir, 0611 Formats.F[i_format].FileDirName, MAX_FILENAME_LENGTH) == 0) { 0612 *error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 0613 return(Formats.F + i_format); 0614 } 0615 } 0616 0617 /** if we get here, the file has not yet been read */ 0618 /** Allocate the memory, then fill. If we have an error, */ 0619 /* we will have to free the memory... */ 0620 Formats.n++; 0621 Formats.F = realloc(Formats.F, Formats.n * sizeof(struct FormatType)); 0622 0623 F = Formats.F+Formats.n-1; 0624 0625 /***** open the format file (if there is one) ******/ 0626 snprintf(format_file, MAX_FILENAME_LENGTH+6, "%s/format", filedir); 0627 fp = fopen(format_file, "r"); 0628 if (fp == NULL) { 0629 *error_code = SetGetDataError(GD_E_OPEN_FORMAT, 0, format_file, 0, NULL); 0630 Formats.n--; /* no need to free. The next realloc will just do nothing */ 0631 return (NULL); 0632 } 0633 0634 strcpy(F->FileDirName, filedir); 0635 F->n_raw = F->n_lincom = F->n_multiply = F->n_linterp = F->n_mplex = F->n_bit 0636 = 0; 0637 F->frame_offset = 0; 0638 F->rawEntries = NULL; 0639 F->lincomEntries = NULL; 0640 F->multiplyEntries = NULL; 0641 F->linterpEntries = NULL; 0642 F->mplexEntries = NULL; 0643 F->bitEntries = NULL; 0644 0645 /* Parse the file. This will take care of any necessary inclusions */ 0646 i_include = 1; 0647 IncludeList = malloc(sizeof(char*)); 0648 IncludeList[0] = strdup("format"); 0649 *error_code = ParseFormatFile(fp, F, filedir, ".", format_file, &IncludeList, 0650 &i_include); 0651 fclose(fp); 0652 0653 /* Clean up IncludeList. We don't need it anymore */ 0654 for (i = 0; i < i_include; ++i) 0655 free(IncludeList[i]); 0656 free(IncludeList); 0657 0658 if (*error_code!=GD_E_OK) { 0659 FreeF(F); 0660 Formats.n--; 0661 return(NULL); 0662 } 0663 0664 /** Now sort the lists */ 0665 if (F->n_raw > 1) { 0666 for (i=0; i<F->n_raw; i++) { 0667 snprintf(raw_data_filename, MAX_FILENAME_LENGTH+FIELD_LENGTH+2, 0668 "%s/%s", filedir, F->rawEntries[i].file); 0669 if (stat(raw_data_filename, &statbuf) >=0) { 0670 F->first_field = F->rawEntries[i]; 0671 break; 0672 } 0673 } 0674 0675 qsort(F->rawEntries, F->n_raw, sizeof(struct RawEntryType), 0676 RawCmp); 0677 } 0678 0679 if (F->n_lincom > 1) { 0680 qsort(F->lincomEntries, F->n_lincom, sizeof(struct LincomEntryType), 0681 LincomCmp); 0682 } 0683 if (F->n_linterp > 1) { 0684 qsort(F->linterpEntries, F->n_linterp, sizeof(struct LinterpEntryType), 0685 LinterpCmp); 0686 } 0687 if (F->n_multiply > 1) { 0688 qsort(F->multiplyEntries, F->n_multiply, sizeof(struct MultiplyEntryType), 0689 MultiplyCmp); 0690 } 0691 if (F->n_mplex > 1) { 0692 qsort(F->mplexEntries, F->n_mplex, sizeof(struct MplexEntryType), 0693 MplexCmp); 0694 } 0695 if (F->n_bit > 1) { 0696 qsort(F->bitEntries, F->n_bit, sizeof(struct BitEntryType), 0697 BitCmp); 0698 } 0699 return(F); 0700 } 0701 0702 /***************************************************************************/ 0703 /* */ 0704 /* File File Frame numbers into dataout */ 0705 /* */ 0706 /***************************************************************************/ 0707 static void FillFileFrame(void *dataout, char rtype, int s0, int n) { 0708 int i; 0709 0710 switch(rtype) { 0711 case 'c': 0712 for (i=0; i<n; i++) { 0713 ((unsigned char*)dataout)[i] = (unsigned char)i+s0; 0714 } 0715 break; 0716 case 'i': /* for compatibility with creaddata. (deprecated) */ 0717 case 'S': 0718 for (i=0; i<n; i++) { 0719 ((int*)dataout)[i] = (int)i+s0; 0720 } 0721 break; 0722 case 's': 0723 for (i=0; i<n; i++) { 0724 ((short*)dataout)[i] = (short)i+s0; 0725 } 0726 break; 0727 case 'U': 0728 for (i=0; i<n; i++) { 0729 ((unsigned int *)dataout)[i] = (unsigned int)i+s0; 0730 } 0731 break; 0732 case 'u': 0733 for (i=0; i<n; i++) { 0734 ((unsigned short *)dataout)[i] = (unsigned short)i+s0; 0735 } 0736 break; 0737 case 'f': 0738 for (i=0; i<n; i++) { 0739 ((float*)dataout)[i] = (float)i+s0; 0740 } 0741 break; 0742 case 'd': 0743 for (i=0; i<n; i++) { 0744 ((double*)dataout)[i] = (double)i+s0; 0745 } 0746 break; 0747 } 0748 } 0749 /***************************************************************************/ 0750 /* */ 0751 /* ConvertType: copy data to output buffer while converting type */ 0752 /* Returns error code */ 0753 /* */ 0754 /***************************************************************************/ 0755 static int ConvertType(unsigned char *data_in, char in_type, 0756 void *data_out, char out_type, int n) { 0757 int i; 0758 0759 if (out_type=='n') { /* null return type: don't return data */ 0760 return(0); 0761 } 0762 0763 switch (in_type) { 0764 case 'c': 0765 switch (out_type) { 0766 case 'c': 0767 for (i=0;i<n;i++) ((unsigned char*) data_out)[i]=data_in[i]; 0768 break; 0769 case 's': 0770 for (i=0;i<n;i++) ((short*)data_out)[i]=data_in[i]; 0771 break; 0772 case 'u': 0773 for (i=0;i<n;i++) ((unsigned short*)data_out)[i]=data_in[i]; 0774 break; 0775 case 'i': case 'S': 0776 for (i=0;i<n;i++) ((int*)data_out)[i]=data_in[i]; 0777 break; 0778 case 'U': 0779 for (i=0;i<n;i++) ((unsigned int*)data_out)[i]=data_in[i]; 0780 break; 0781 case 'f': 0782 for (i=0;i<n;i++) ((float*)data_out)[i]=data_in[i]; 0783 break; 0784 case 'd': 0785 for (i=0;i<n;i++) ((double*)data_out)[i]=data_in[i]; 0786 break; 0787 default: 0788 return SetGetDataError(GD_E_BAD_RETURN_TYPE, out_type, NULL, 0, NULL); 0789 } 0790 break; 0791 case 's': 0792 switch (out_type) { 0793 case 'c': 0794 for (i=0;i<n;i++) ((unsigned char*) data_out)[i]=((short *)data_in)[i]; 0795 break; 0796 case 's': 0797 for (i=0;i<n;i++) ((short*)data_out)[i]=((short *)data_in)[i]; 0798 break; 0799 case 'u': 0800 for (i=0;i<n;i++) ((unsigned short*)data_out)[i]=((short *)data_in)[i]; 0801 break; 0802 case 'S': case 'i': 0803 for (i=0;i<n;i++) ((int*)data_out)[i]=((short *)data_in)[i]; 0804 break; 0805 case 'U': 0806 for (i=0;i<n;i++) ((unsigned int*)data_out)[i]=((short *)data_in)[i]; 0807 break; 0808 case 'f': 0809 for (i=0;i<n;i++) ((float*)data_out)[i]=((short *)data_in)[i]; 0810 break; 0811 case 'd': 0812 for (i=0;i<n;i++) ((double*)data_out)[i]=((short *)data_in)[i]; 0813 break; 0814 default: 0815 return SetGetDataError(GD_E_BAD_RETURN_TYPE, out_type, NULL, 0, NULL); 0816 } 0817 break; 0818 case 'u': 0819 switch (out_type) { 0820 case 'c': 0821 for (i=0;i<n;i++) ((unsigned char*) data_out)[i]= 0822 ((unsigned short *)data_in)[i]; 0823 break; 0824 case 's': 0825 for (i=0;i<n;i++) ((short*)data_out)[i]= 0826 ((unsigned short *)data_in)[i]; 0827 break; 0828 case 'u': 0829 for (i=0;i<n;i++) ((unsigned short*)data_out)[i]= 0830 ((unsigned short *)data_in)[i]; 0831 break; 0832 case 'i': case 'S': 0833 for (i=0;i<n;i++) ((int*)data_out)[i]= 0834 ((unsigned short *)data_in)[i]; 0835 break; 0836 case 'U': 0837 for (i=0;i<n;i++) ((unsigned int*)data_out)[i]= 0838 ((unsigned short *)data_in)[i]; 0839 break; 0840 case 'f': 0841 for (i=0;i<n;i++) ((float*)data_out)[i]= 0842 ((unsigned short *)data_in)[i]; 0843 break; 0844 case 'd': 0845 for (i=0;i<n;i++) ((double*)data_out)[i]= 0846 ((unsigned short *)data_in)[i]; 0847 break; 0848 default: 0849 return SetGetDataError(GD_E_BAD_RETURN_TYPE, out_type, NULL, 0, NULL); 0850 } 0851 break; 0852 case 'i': 0853 case 'S': 0854 switch (out_type) { 0855 case 'c': 0856 for (i=0;i<n;i++) ((unsigned char*) data_out)[i]=((int *)data_in)[i]; 0857 break; 0858 case 's': 0859 for (i=0;i<n;i++) ((short*)data_out)[i]=((int *)data_in)[i]; 0860 break; 0861 case 'u': 0862 for (i=0;i<n;i++) ((unsigned short*)data_out)[i]=((int *)data_in)[i]; 0863 break; 0864 case 'i': case 'S': 0865 for (i=0;i<n;i++) ((int*)data_out)[i]=((int *)data_in)[i]; 0866 break; 0867 case 'U': 0868 for (i=0;i<n;i++) ((unsigned int*)data_out)[i]=((int *)data_in)[i]; 0869 break; 0870 case 'f': 0871 for (i=0;i<n;i++) ((float*)data_out)[i]=((int *)data_in)[i]; 0872 break; 0873 case 'd': 0874 for (i=0;i<n;i++) ((double*)data_out)[i]=((int *)data_in)[i]; 0875 break; 0876 default: 0877 return SetGetDataError(GD_E_BAD_RETURN_TYPE, out_type, NULL, 0, NULL); 0878 } 0879 break; 0880 case 'U': 0881 switch (out_type) { 0882 case 'c': 0883 for (i=0;i<n;i++) ((unsigned char*) data_out)[i]= 0884 ((unsigned *)data_in)[i]; 0885 break; 0886 case 's': 0887 for (i=0;i<n;i++) ((short*)data_out)[i]= 0888 ((unsigned *)data_in)[i]; 0889 break; 0890 case 'u': 0891 for (i=0;i<n;i++) ((unsigned short*)data_out)[i]= 0892 ((unsigned *)data_in)[i]; 0893 break; 0894 case 'i': case 'S': 0895 for (i=0;i<n;i++) ((int*)data_out)[i]= 0896 ((unsigned *)data_in)[i]; 0897 break; 0898 case 'U': 0899 for (i=0;i<n;i++) ((unsigned int*)data_out)[i]= 0900 ((unsigned *)data_in)[i]; 0901 break; 0902 case 'f': 0903 for (i=0;i<n;i++) ((float*)data_out)[i]= 0904 ((unsigned *)data_in)[i]; 0905 break; 0906 case 'd': 0907 for (i=0;i<n;i++) ((double*)data_out)[i]= 0908 ((unsigned *)data_in)[i]; 0909 break; 0910 default: 0911 return SetGetDataError(GD_E_BAD_RETURN_TYPE, out_type, NULL, 0, NULL); 0912 } 0913 break; 0914 case 'f': 0915 switch (out_type) { 0916 case 'c': 0917 for (i=0;i<n;i++) ((unsigned char*) data_out)[i]=((float *)data_in)[i]; 0918 break; 0919 case 's': 0920 for (i=0;i<n;i++) ((short*)data_out)[i]=((float *)data_in)[i]; 0921 break; 0922 case 'u': 0923 for (i=0;i<n;i++) ((unsigned short*)data_out)[i]=((float *)data_in)[i]; 0924 break; 0925 case 'i': case 'S': 0926 for (i=0;i<n;i++) ((int*)data_out)[i]=((float *)data_in)[i]; 0927 break; 0928 case 'U': 0929 for (i=0;i<n;i++) ((unsigned int*)data_out)[i]=((float *)data_in)[i]; 0930 break; 0931 case 'f': 0932 for (i=0;i<n;i++) ((float*)data_out)[i]=((float *)data_in)[i]; 0933 break; 0934 case 'd': 0935 for (i=0;i<n;i++) ((double*)data_out)[i]=((float *)data_in)[i]; 0936 break; 0937 default: 0938 return SetGetDataError(GD_E_BAD_RETURN_TYPE, out_type, NULL, 0, NULL); 0939 } 0940 break; 0941 case 'd': 0942 switch (out_type) { 0943 case 'c': 0944 for (i=0;i<n;i++) ((unsigned char*) data_out)[i]=((double *)data_in)[i]; 0945 break; 0946 case 's': 0947 for (i=0;i<n;i++) ((short*)data_out)[i]=((double *)data_in)[i]; 0948 break; 0949 case 'u': 0950 for (i=0;i<n;i++) ((unsigned short*)data_out)[i]=((double *)data_in)[i]; 0951 break; 0952 case 'i': case 'S': 0953 for (i=0;i<n;i++) ((int*)data_out)[i]=((double *)data_in)[i]; 0954 break; 0955 case 'U': 0956 for (i=0;i<n;i++) ((unsigned int*)data_out)[i]=((double *)data_in)[i]; 0957 break; 0958 case 'f': 0959 for (i=0;i<n;i++) ((float*)data_out)[i]=((double *)data_in)[i]; 0960 break; 0961 case 'd': 0962 for (i=0;i<n;i++) ((double*)data_out)[i]=((double *)data_in)[i]; 0963 break; 0964 default: 0965 return SetGetDataError(GD_E_BAD_RETURN_TYPE, out_type, NULL, 0, NULL); 0966 } 0967 break; 0968 default: 0969 return SetGetDataError(GD_E_INTERNAL_ERROR, in_type, __FILE__, __LINE__, 0970 NULL); 0971 } 0972 0973 return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 0974 } 0975 0976 0977 /***************************************************************************/ 0978 /* */ 0979 /* FillZero: fill data buffer with zero/NaN of the appropriate type */ 0980 /* used if s0<0 - fill up to 0, or up to ns+s0, whichever is less */ 0981 /* */ 0982 /***************************************************************************/ 0983 static int FillZero(char *databuffer, char type, int s0, int ns) { 0984 int i, nz; 0985 const double NaN = NAN; 0986 0987 if (s0>=0) return 0; 0988 0989 if (s0+ns>0) nz = -s0; 0990 else nz = ns; 0991 0992 switch (type) { 0993 case 'c': 0994 memset(databuffer, 0, nz); 0995 break; 0996 case 's': 0997 case 'u': 0998 memset(databuffer, 0, nz*sizeof(short)); 0999 break; 1000 case 'i': 1001 case 'S': 1002 case 'U': 1003 memset(databuffer, 0, nz*sizeof(int)); 1004 break; 1005 case 'f': 1006 for (i = 0; i < nz; ++i) 1007 *((float*)databuffer + i) = (float)NaN; 1008 break; 1009 case 'd': 1010 for (i = 0; i < nz; ++i) 1011 *((double*)databuffer + i) = (double)NaN; 1012 break; 1013 } 1014 1015 return (nz); 1016 1017 } 1018 /***************************************************************************/ 1019 /* */ 1020 /* Get samples per frame for field, given FormatType *F */ 1021 /* */ 1022 /***************************************************************************/ 1023 static int GetSPF(const char *field_code, struct FormatType *F, int *error_code) { 1024 struct RawEntryType tR; 1025 struct RawEntryType *R; 1026 struct LincomEntryType tL; 1027 struct LincomEntryType *L; 1028 struct MultiplyEntryType tM; 1029 struct MultiplyEntryType *M; 1030 struct BitEntryType tB; 1031 struct BitEntryType *B; 1032 struct LinterpEntryType tI; 1033 struct LinterpEntryType *I; 1034 int spf; 1035 1036 if (!F) { /* don't crash */ 1037 return(0); 1038 } 1039 1040 if (recurse_level > 10) { 1041 *error_code = SetGetDataError(GD_E_RECURSE_LEVEL, 0, NULL, 0, field_code); 1042 return(0); 1043 } 1044 1045 if ((strcmp(field_code,"FILEFRAM")==0) || 1046 (strcmp(field_code,"INDEX")==0)) { 1047 return(1); 1048 } 1049 1050 /***************************************/ 1051 /** Check to see if it is a raw entry **/ 1052 /* binary search for the field */ 1053 /* make a RawEntry we can compare to */ 1054 strncpy(tR.field, field_code, FIELD_LENGTH); 1055 /** use the stdlib binary search */ 1056 R = bsearch(&tR, F->rawEntries, F->n_raw, 1057 sizeof(struct RawEntryType), RawCmp); 1058 if (R!=NULL) { 1059 spf = R->samples_per_frame; 1060 return(spf); 1061 } 1062 1063 /***************************************/ 1064 /** Check to see if it is a lincom entry **/ 1065 /* binary search for the field */ 1066 /* make a RawEntry we can compare to */ 1067 strncpy(tL.field, field_code, FIELD_LENGTH); 1068 /** use the stdlib binary search */ 1069 L = bsearch(&tL, F->lincomEntries, F->n_lincom, 1070 sizeof(struct LincomEntryType), LincomCmp); 1071 if (L!=NULL) { 1072 recurse_level++; 1073 spf = GetSPF(L->in_fields[0], F, error_code); 1074 recurse_level--; 1075 return(spf); 1076 } 1077 1078 /***************************************/ 1079 /** Check to see if it is a multiply entry **/ 1080 /* binary search for the field */ 1081 /* make a RawEntry we can compare to */ 1082 strncpy(tM.field, field_code, FIELD_LENGTH); 1083 /** use the stdlib binary search */ 1084 M = bsearch(&tM, F->multiplyEntries, F->n_multiply, 1085 sizeof(struct MultiplyEntryType), MultiplyCmp); 1086 if (M != NULL) { 1087 int spf2; 1088 recurse_level++; 1089 spf = GetSPF(M->in_fields[0], F, error_code); 1090 spf2 = GetSPF(M->in_fields[1], F, error_code); 1091 recurse_level--; 1092 if (spf2 > spf) 1093 spf = spf2; 1094 return(spf); 1095 } 1096 1097 /***************************************/ 1098 /** Check to see if it is a bit entry **/ 1099 /* binary search for the field */ 1100 /* make a BitEntry we can compare to */ 1101 strncpy(tB.field, field_code, FIELD_LENGTH); 1102 /** use the stdlib binary search */ 1103 B = bsearch(&tB, F->bitEntries, F->n_bit, 1104 sizeof(struct BitEntryType), BitCmp); 1105 if (B!=NULL) { 1106 recurse_level++; 1107 spf = GetSPF(B->raw_field, F, error_code); 1108 recurse_level--; 1109 return(spf); 1110 } 1111 1112 /***************************************/ 1113 /** Check to see if it is a linterp entry **/ 1114 /* binary search for the field */ 1115 /* make a LinterpEntry we can compare to */ 1116 strncpy(tI.field, field_code, FIELD_LENGTH); 1117 /** use the stdlib binary search */ 1118 I = bsearch(&tI, F->linterpEntries, F->n_linterp, 1119 sizeof(struct LinterpEntryType), LinterpCmp); 1120 if (I!=NULL) { 1121 recurse_level++; 1122 spf = GetSPF(I->raw_field, F, error_code); 1123 recurse_level--; 1124 return(spf); 1125 } 1126 1127 *error_code = SetGetDataError(GD_E_BAD_CODE, 0, NULL, 0, field_code); 1128 return(0); 1129 } 1130 1131 /***************************************************************************/ 1132 /* */ 1133 /* Look to see if the field code belongs to a raw. If so, parse it. */ 1134 /* */ 1135 /***************************************************************************/ 1136 static int DoIfRaw(struct FormatType *F, const char *field_code, 1137 int first_frame, int first_samp, 1138 int num_frames, int num_samp, 1139 char return_type, void *data_out, 1140 int *error_code, int *n_read) { 1141 1142 struct RawEntryType tR; 1143 struct RawEntryType *R; 1144 int s0, ns, bytes_read; 1145 char datafilename[2 * MAX_FILENAME_LENGTH + FIELD_LENGTH + 2]; 1146 unsigned char *databuffer; 1147 1148 /******* binary search for the field *******/ 1149 /* make a RawEntry we can compare to */ 1150 strncpy(tR.field, field_code, FIELD_LENGTH); 1151 /** use the stdlib binary search */ 1152 R = bsearch(&tR, F->rawEntries, F->n_raw, 1153 sizeof(struct RawEntryType), RawCmp); 1154 if (R==NULL) return(0); 1155 1156 /** if we got here, we found the field! **/ 1157 s0 = first_samp + first_frame*R->samples_per_frame; 1158 ns = num_samp + num_frames*R->samples_per_frame; 1159 1160 /** open the file (and cache the fp) if it hasn't been opened yet. */ 1161 if (R->fp <0) { 1162 snprintf(datafilename, 2 * MAX_FILENAME_LENGTH + FIELD_LENGTH + 2, 1163 "%s/%s", F->FileDirName, R->file); 1164 R->fp = open(datafilename, O_RDONLY); 1165 if (R->fp<0) { 1166 *n_read = 0; 1167 *error_code = SetGetDataError(GD_E_OPEN_RAWFIELD, 0, NULL, 0, 1168 datafilename); 1169 return(1); 1170 } 1171 } 1172 1173 databuffer = (unsigned char *)malloc(ns*R->size); 1174 1175 *n_read = 0; 1176 if (s0 < 0) { 1177 *n_read = FillZero(databuffer, R->type, s0, ns); 1178 ns -= *n_read; 1179 s0 = 0; 1180 } 1181 1182 if (ns>0) { 1183 lseek(R->fp, s0*R->size, SEEK_SET); 1184 bytes_read = read(R->fp, databuffer + *n_read*R->size, ns*R->size); 1185 *n_read += bytes_read/R->size; 1186 } 1187 1188 *error_code = 1189 ConvertType(databuffer, R->type, data_out, return_type, *n_read); 1190 1191 free(databuffer); 1192 1193 return(1); 1194 } 1195 1196 1197 /***************************************************************************/ 1198 /* */ 1199 /* AllocTmpbuff: allocate a buffer of the right type and size */ 1200 /* */ 1201 /***************************************************************************/ 1202 static void *AllocTmpbuff(char type, int n) { 1203 assert(n > 0); 1204 void *buff=NULL; 1205 switch(type) { 1206 case 'n': 1207 buff = NULL; 1208 break; 1209 case 'c': 1210 buff = malloc(n*sizeof(char)); 1211 break; 1212 case 'i': 1213 case 'S': 1214 case 'U': 1215 buff = malloc(n*sizeof(int)); 1216 break; 1217 case 's': 1218 case 'u': 1219 buff = malloc(n*sizeof(short)); 1220 break; 1221 case 'f': 1222 buff = malloc(n*sizeof(float)); 1223 break; 1224 case 'd': 1225 buff = malloc(n*sizeof(double)); 1226 break; 1227 default: 1228 printf("Unexpected bad type error in AllocTmpbuff (%c)\n",type); 1229 abort(); 1230 break; 1231 } 1232 if ((type != 'n') && (buff==NULL)) { 1233 printf("Memory Allocation error in AllocTmpbuff\n"); 1234 } 1235 return(buff); 1236 } 1237 1238 /***************************************************************************/ 1239 /* */ 1240 /* ScaleData: out = m*in+b */ 1241 /* */ 1242 /***************************************************************************/ 1243 static void ScaleData(void *data, char type, int npts, double m, double b) { 1244 unsigned char *data_c; 1245 short *data_s; 1246 unsigned short *data_u; 1247 unsigned *data_U; 1248 int *data_i; 1249 float *data_f; 1250 double *data_d; 1251 1252 int i; 1253 1254 switch(type) { 1255 case 'n': 1256 break; 1257 case 'c': 1258 data_c = (unsigned char *)data; 1259 for (i=0; i<npts; i++) { 1260 data_c[i] =(unsigned char)((double)data_c[i] * m + b); 1261 } 1262 break; 1263 case 's': 1264 data_s = (short *)data; 1265 for (i=0; i<npts; i++) { 1266 data_s[i] = (short)((double)data_s[i] * m + b); 1267 } 1268 break; 1269 case 'u': 1270 data_u = (unsigned short *)data; 1271 for (i=0; i<npts; i++) { 1272 data_u[i] = (unsigned short)((double)data_u[i] * m + b); 1273 } 1274 break; 1275 case 'S': case 'i': 1276 data_i = (int *)data; 1277 for (i=0; i<npts; i++) { 1278 data_i[i] = (int)((double)data_i[i] * m + b); 1279 } 1280 break; 1281 case 'U': 1282 data_U = (unsigned*)data; 1283 for (i=0; i<npts; i++) { 1284 data_U[i] = (unsigned)((double)data_U[i] * m + b); 1285 } 1286 break; 1287 case 'f': 1288 data_f = (float *)data; 1289 for (i=0; i<npts; i++) { 1290 data_f[i] = (float)((double)data_f[i] * m + b); 1291 } 1292 break; 1293 case 'd': 1294 data_d = (double *)data; 1295 for (i=0; i<npts; i++) { 1296 data_d[i] = data_d[i] * m + b; 1297 } 1298 break; 1299 default: 1300 printf("Another impossible error\n"); 1301 abort(); 1302 break; 1303 } 1304 } 1305 1306 /***************************************************************************/ 1307 /* */ 1308 /* AddData: add B to A. B is unchanged */ 1309 /* */ 1310 /***************************************************************************/ 1311 static void AddData(void *A, int spfA, void *B, int spfB, char type, int n) { 1312 int i; 1313 1314 switch(type) { 1315 case 'n': /* null read */ 1316 break; 1317 case 'c': 1318 for (i=0; i<n; i++) { 1319 ((unsigned char*)A)[i] += ((unsigned char*)B)[i * spfB / spfA]; 1320 } 1321 break; 1322 case 'S': case 'i': 1323 for (i=0; i<n; i++) { 1324 ((int*)A)[i] += ((int*)B)[i * spfB / spfA]; 1325 } 1326 break; 1327 case 's': 1328 for (i=0; i<n; i++) { 1329 ((short*)A)[i] += ((short*)B)[i * spfB / spfA]; 1330 } 1331 break; 1332 case 'u': 1333 for (i=0; i<n; i++) { 1334 ((unsigned short*)A)[i] += ((unsigned short*)B)[i * spfB / spfA]; 1335 } 1336 break; 1337 case 'U': 1338 for (i=0; i<n; i++) { 1339 ((unsigned*)A)[i] += ((unsigned*)B)[i * spfB / spfA]; 1340 } 1341 break; 1342 case 'f': 1343 for (i=0; i<n; i++) { 1344 ((float*)A)[i] += ((float*)B)[i * spfB / spfA]; 1345 } 1346 break; 1347 case 'd': 1348 for (i=0; i<n; i++) { 1349 ((double*)A)[i] += ((double*)B)[i * spfB / spfA]; 1350 } 1351 break; 1352 default: 1353 printf("Unexpected bad type error in AddData\n"); 1354 abort(); 1355 break; 1356 } 1357 } 1358 1359 /***************************************************************************/ 1360 /* */ 1361 /* MultiplyData: multiply B by A. B is unchanged */ 1362 /* */ 1363 /***************************************************************************/ 1364 static void MultiplyData(void *A, int spfA, void *B, int spfB, char type, int n) 1365 { 1366 int i; 1367 1368 switch(type) { 1369 case 'n': /* null read */ 1370 break; 1371 case 'c': 1372 for (i=0; i<n; i++) { 1373 ((unsigned char*)A)[i] *= ((unsigned char*)B)[i * spfB / spfA]; 1374 } 1375 break; 1376 case 'S': case 'i': 1377 for (i=0; i<n; i++) { 1378 ((int*)A)[i] *= ((int*)B)[i * spfB / spfA]; 1379 } 1380 break; 1381 case 's': 1382 for (i=0; i<n; i++) { 1383 ((short*)A)[i] *= ((short*)B)[i * spfB / spfA]; 1384 } 1385 break; 1386 case 'u': 1387 for (i=0; i<n; i++) { 1388 ((unsigned short*)A)[i] *= ((unsigned short*)B)[i * spfB / spfA]; 1389 } 1390 break; 1391 case 'U': 1392 for (i=0; i<n; i++) { 1393 ((unsigned*)A)[i] *= ((unsigned*)B)[i * spfB / spfA]; 1394 } 1395 break; 1396 case 'f': 1397 for (i=0; i<n; i++) { 1398 ((float*)A)[i] *= ((float*)B)[i * spfB / spfA]; 1399 } 1400 break; 1401 case 'd': 1402 for (i=0; i<n; i++) { 1403 ((double*)A)[i] *= ((double*)B)[i * spfB / spfA]; 1404 } 1405 break; 1406 default: 1407 printf("Unexpected bad type error in MultiplyData\n"); 1408 abort(); 1409 break; 1410 } 1411 } 1412 1413 1414 /***************************************************************************/ 1415 /* */ 1416 /* Look to see if the field code belongs to a lincom. If so, parse it. */ 1417 /* */ 1418 /***************************************************************************/ 1419 static int DoIfLincom(struct FormatType *F, const char *field_code, 1420 int first_frame, int first_samp, 1421 int num_frames, int num_samp, 1422 char return_type, void *data_out, 1423 int *error_code, int *n_read) { 1424 struct LincomEntryType tL; 1425 struct LincomEntryType *L; 1426 void *tmpbuf; 1427 int i; 1428 int spf1, spf2, num_samp2, first_samp2; 1429 int n_read2; 1430 1431 /******* binary search for the field *******/ 1432 /* make a LincomEntry we can compare to */ 1433 strncpy(tL.field, field_code, FIELD_LENGTH); 1434 /** use the stdlib binary search */ 1435 L = bsearch(&tL, F->lincomEntries, F->n_lincom, 1436 sizeof(struct LincomEntryType), LincomCmp); 1437 if (L==NULL) return(0); 1438 1439 /*****************************************/ 1440 /** if we got here, we found the field! **/ 1441 /** read into dataout and scale the first element **/ 1442 recurse_level++; 1443 spf1 = GetSPF(L->in_fields[0], F, error_code); 1444 if (*error_code != GD_E_OK) return(1); 1445 1446 /* read and scale the first field and record the number of samples 1447 * returned */ 1448 *n_read = DoField(F, L->in_fields[0], 1449 first_frame, first_samp, 1450 num_frames, num_samp, 1451 return_type, data_out, 1452 error_code); 1453 1454 recurse_level--; 1455 1456 if (*error_code != GD_E_OK) 1457 return(1); 1458 1459 /* Nothing to lincomise */ 1460 if (*n_read == 0) 1461 return 1; 1462 1463 ScaleData(data_out, return_type, *n_read, L->m[0], L->b[0]); 1464 1465 if (L->n_infields > 1) { 1466 for (i=1; i<L->n_infields; i++) { 1467 recurse_level++; 1468 1469 /* find the samples per frame of the next field */ 1470 spf2 = GetSPF(L->in_fields[i], F, error_code); 1471 if (*error_code != GD_E_OK) return(1); 1472 1473 /* calculate the first sample and number of samples to read of the 1474 * next field */ 1475 num_samp2 = (int)ceil((double)*n_read * spf2 / spf1); 1476 first_samp2 = (first_frame * spf2 + first_samp * spf2 / spf1); 1477 1478 /* Allocate a temporary buffer for the next field */ 1479 tmpbuf = AllocTmpbuff(return_type, num_samp2); 1480 if (!tmpbuf && return_type != 'n') { 1481 return(0); 1482 } 1483 1484 /* read the next field */ 1485 n_read2 = DoField(F, L->in_fields[i], 1486 0, first_samp2, 1487 0, num_samp2, 1488 return_type, tmpbuf, 1489 error_code); 1490 recurse_level--; 1491 if (*error_code != GD_E_OK) { 1492 free(tmpbuf); 1493 return(1); 1494 } 1495 1496 ScaleData(tmpbuf, return_type, n_read2, L->m[i], L->b[i]); 1497 1498 if (n_read2 > 0 && n_read2 * spf1 != *n_read * spf2) { 1499 *n_read = n_read2 * spf1 / spf2; 1500 } 1501 1502 AddData(data_out, spf1, tmpbuf, spf2, return_type, *n_read); 1503 1504 free(tmpbuf); 1505 } 1506 } 1507 1508 return(1); 1509 } 1510 1511 /***************************************************************************/ 1512 /* */ 1513 /* Look to see if the field code belongs to a multiply. If so, parse it. */ 1514 /* */ 1515 /***************************************************************************/ 1516 static int DoIfMultiply(struct FormatType *F, const char *field_code, 1517 int first_frame, int first_samp, 1518 int num_frames, int num_samp, 1519 char return_type, void *data_out, 1520 int *error_code, int *n_read) { 1521 struct MultiplyEntryType tM; 1522 struct MultiplyEntryType *M; 1523 void *tmpbuf; 1524 int spf1, spf2, num_samp2, first_samp2; 1525 int n_read2; 1526 1527 /******* binary search for the field *******/ 1528 /* make a LincomEntry we can compare to */ 1529 strncpy(tM.field, field_code, FIELD_LENGTH); 1530 /** use the stdlib binary search */ 1531 M = bsearch(&tM, F->multiplyEntries, F->n_multiply, 1532 sizeof(struct MultiplyEntryType), MultiplyCmp); 1533 if (M==NULL) return(0); 1534 1535 /*****************************************/ 1536 /** if we got here, we found the field! **/ 1537 /** read into dataout and scale the first element **/ 1538 recurse_level++; 1539 1540 /* find the samples per frame of the first field */ 1541 spf1 = GetSPF(M->in_fields[0], F, error_code); 1542 if (*error_code != GD_E_OK) return(1); 1543 1544 /* read the first field and record the number of samples 1545 * returned */ 1546 *n_read = DoField(F, M->in_fields[0], 1547 first_frame, first_samp, 1548 num_frames, num_samp, 1549 return_type, data_out, 1550 error_code); 1551 1552 recurse_level--; 1553 1554 if (*error_code != GD_E_OK) 1555 return 1; 1556 1557 /* Nothing to multiply */ 1558 if (*n_read == 0) 1559 return 1; 1560 1561 recurse_level++; 1562 1563 /* find the samples per frame of the second field */ 1564 spf2 = GetSPF(M->in_fields[1], F, error_code); 1565 if (*error_code != GD_E_OK) return(1); 1566 1567 /* calculate the first sample and number of samples to read of the 1568 * second field */ 1569 num_samp2 = (int)ceil((double)*n_read * spf2 / spf1); 1570 first_samp2 = (first_frame * spf2 + first_samp * spf2 / spf1); 1571 1572 /* Allocate a temporary buffer for the second field */ 1573 tmpbuf = AllocTmpbuff(return_type, num_samp2); 1574 if (!tmpbuf && return_type != 'n') { 1575 return(0); 1576 } 1577 1578 /* read the second field */ 1579 n_read2 = DoField(F, M->in_fields[1], 1580 0, first_samp2, 1581 0, num_samp2, 1582 return_type, tmpbuf, 1583 error_code); 1584 recurse_level--; 1585 if (*error_code != GD_E_OK) { 1586 free(tmpbuf); 1587 return(1); 1588 } 1589 1590 if (n_read2 > 0 && n_read2 * spf1 < *n_read * spf2) { 1591 *n_read = n_read2 * spf1 / spf2; 1592 } 1593 MultiplyData(data_out, spf1, tmpbuf, spf2, return_type, *n_read); 1594 free(tmpbuf); 1595 1596 return(1); 1597 } 1598 1599 /***************************************************************************/ 1600 /* */ 1601 /* Look to see if the field code belongs to a bitfield. If so, parse it.*/ 1602 /* */ 1603 /***************************************************************************/ 1604 static int DoIfBit(struct FormatType *F, const char *field_code, 1605 int first_frame, int first_samp, 1606 int num_frames, int num_samp, 1607 char return_type, void *data_out, 1608 int *error_code, int *n_read) { 1609 struct BitEntryType tB; 1610 struct BitEntryType *B; 1611 unsigned *tmpbuf; 1612 int i; 1613 int spf; 1614 int ns; 1615 unsigned mask; 1616 1617 /******* binary search for the field *******/ 1618 /* make a BitEntry we can compare to */ 1619 strncpy(tB.field, field_code, FIELD_LENGTH); 1620 /** use the stdlib binary search */ 1621 B = bsearch(&tB, F->bitEntries, F->n_bit, 1622 sizeof(struct BitEntryType), BitCmp); 1623 if (B==NULL) return(0); 1624 1625 /*****************************************/ 1626 /** if we got here, we found the field! **/ 1627 recurse_level++; 1628 spf = GetSPF(B->raw_field, F, error_code); 1629 recurse_level--; 1630 if (*error_code!=GD_E_OK) { 1631 *n_read = 0; 1632 return(1); 1633 } 1634 1635 ns = num_samp + num_frames*spf; 1636 tmpbuf = (unsigned *)malloc(ns*sizeof(unsigned)); 1637 1638 recurse_level++; 1639 *n_read = DoField(F, B->raw_field, 1640 first_frame, first_samp, 1641 num_frames, num_samp, 1642 'U', tmpbuf, 1643 error_code); 1644 recurse_level--; 1645 if (*error_code!=GD_E_OK) { 1646 free(tmpbuf); 1647 return(1); 1648 } 1649 1650 if (B->numbits==32) mask = 0xffffffff; 1651 else mask = (unsigned)(pow(2,B->numbits)-0.9999); 1652 1653 for (i=0; i<*n_read; i++) { 1654 tmpbuf[i] = (tmpbuf[i]>>B->bitnum) & mask; 1655 } 1656 1657 *error_code = ConvertType((unsigned char *)tmpbuf, 'U', 1658 data_out, return_type, *n_read); 1659 free(tmpbuf); 1660 1661 return(1); 1662 } 1663 1664 /***************************************************************************/ 1665 /* */ 1666 /* ReadLinterpFile: Read in the linterp data for this field */ 1667 /* */ 1668 /***************************************************************************/ 1669 void MakeDummyLinterp(struct LinterpEntryType *E); /* prototype => no warning... */ 1670 void MakeDummyLinterp(struct LinterpEntryType *E) { 1671 E->n_interp = 2; 1672 E->x = (double *)malloc(2*sizeof(double)); 1673 E->y = (double *)malloc(2*sizeof(double)); 1674 E->x[0] = 0; 1675 E->y[0] = 0; 1676 E->x[1] = 1; 1677 E->y[1] = 1; 1678 } 1679 1680 static int ReadLinterpFile(struct LinterpEntryType *E) { 1681 FILE *fp; 1682 int i; 1683 char line[255]; 1684 int linenum = 0; 1685 1686 fp = fopen(E->linterp_file, "r"); 1687 if (fp==NULL) { 1688 MakeDummyLinterp(E); 1689 return SetGetDataError(GD_E_OPEN_LINFILE, GD_E_LINFILE_SE_OPEN, NULL, 0, 1690 E->linterp_file); 1691 } 1692 1693 /* first read the file to see how big it is */ 1694 i=0; 1695 while (GetLine(fp, line, &linenum)) { 1696 i++; 1697 } 1698 if (i<2) { 1699 MakeDummyLinterp(E); 1700 return SetGetDataError(GD_E_OPEN_LINFILE, GD_E_LINFILE_SE_LENGTH, NULL, 0, 1701 E->linterp_file); 1702 } 1703 E->n_interp = i; 1704 E->x = (double *)malloc(i*sizeof(double)); 1705 E->y = (double *)malloc(i*sizeof(double)); 1706 /* now read in the data */ 1707 rewind(fp); 1708 linenum = 0; 1709 for (i=0; i<E->n_interp; i++) { 1710 GetLine(fp, line, &linenum); 1711 sscanf(line, "%lg %lg",&(E->x[i]), &(E->y[i])); 1712 } 1713 return (GD_E_OK); 1714 } 1715 1716 /***************************************************************************/ 1717 /* */ 1718 /* GetIndex: just linearly search - we are probably right to start with */ 1719 /* */ 1720 /***************************************************************************/ 1721 static int GetIndex(double x, double lx[], int idx, int n) { 1722 /* increment until we are bigger */ 1723 while ((idx < n-2) && (x > lx[idx])) { 1724 idx++; 1725 } 1726 /* decrement until we are smaller */ 1727 while ((idx > 0) && (x < lx[idx])) { 1728 idx--; 1729 } 1730 1731 return(idx); 1732 } 1733 1734 /***************************************************************************/ 1735 /* */ 1736 /* LinterpData: calibrate data using lookup table lx and ly */ 1737 /* */ 1738 /***************************************************************************/ 1739 static void LinterpData(void *data, char type, int npts, 1740 double *lx, double *ly, int n_ln) { 1741 int i, idx=0; 1742 double x; 1743 1744 for (i=0; i<npts; i++) { 1745 switch(type) { 1746 case 'n': 1747 return; 1748 break; 1749 case 'c': 1750 x = ((unsigned char *)data)[i]; 1751 idx = GetIndex(x, lx, idx, n_ln); 1752 ((unsigned char *)data)[i] = 1753 (unsigned char)(ly[idx] + (ly[idx+1]-ly[idx])/ 1754 (lx[idx+1]-lx[idx]) * (x-lx[idx])); 1755 break; 1756 case 's': 1757 x = ((short *)data)[i]; 1758 idx = GetIndex(x, lx, idx, n_ln); 1759 ((short *)data)[i] = (short)(ly[idx] + (ly[idx+1]-ly[idx])/ 1760 (lx[idx+1]-lx[idx]) * (x-lx[idx])); 1761 break; 1762 case 'u': 1763 x = ((unsigned short *)data)[i]; 1764 idx = GetIndex(x, lx, idx,n_ln); 1765 ((unsigned short *)data)[i] = 1766 (unsigned short)(ly[idx] + (ly[idx+1]-ly[idx])/ 1767 (lx[idx+1]-lx[idx]) * (x-lx[idx])); 1768 break; 1769 case 'S': case 'i': 1770 x = ((int *)data)[i]; 1771 idx = GetIndex(x, lx, idx, n_ln); 1772 ((int *)data)[i] = (int)(ly[idx] + (ly[idx+1]-ly[idx])/ 1773 (lx[idx+1]-lx[idx]) * (x-lx[idx])); 1774 break; 1775 case 'U': 1776 x = ((unsigned *)data)[i]; 1777 idx = GetIndex(x, lx, idx, n_ln); 1778 ((unsigned *)data)[i] = 1779 (unsigned)(ly[idx] + (ly[idx+1]-ly[idx])/ 1780 (lx[idx+1]-lx[idx]) * (x-lx[idx])); 1781 break; 1782 case 'f': 1783 x = ((float *)data)[i]; 1784 idx = GetIndex(x, lx, idx, n_ln); 1785 ((float *)data)[i] = (float)(ly[idx] + (ly[idx+1]-ly[idx])/ 1786 (lx[idx+1]-lx[idx]) * (x-lx[idx])); 1787 break; 1788 case 'd': 1789 x = ((double *)data)[i]; 1790 idx = GetIndex(x, lx, idx, n_ln); 1791 ((double *)data)[i] = (double)(ly[idx] + (ly[idx+1]-ly[idx])/ 1792 (lx[idx+1]-lx[idx]) * (x-lx[idx])); 1793 break; 1794 default: 1795 printf("Another impossible error\n"); 1796 abort(); 1797 break; 1798 } 1799 } 1800 } 1801 1802 /***************************************************************************/ 1803 /* */ 1804 /* Look to see if the field code belongs to a bitfield. If so, parse it.*/ 1805 /* */ 1806 /***************************************************************************/ 1807 static int DoIfLinterp(struct FormatType *F, const char *field_code, 1808 int first_frame, int first_samp, 1809 int num_frames, int num_samp, 1810 char return_type, void *data_out, 1811 int *error_code, int *n_read) { 1812 struct LinterpEntryType tI; 1813 struct LinterpEntryType *I; 1814 1815 /******* binary search for the field *******/ 1816 /* make a LinterpEntry we can compare to */ 1817 strncpy(tI.field, field_code, FIELD_LENGTH); 1818 /** use the stdlib binary search */ 1819 I = bsearch(&tI, F->linterpEntries, F->n_linterp, 1820 sizeof(struct LinterpEntryType), LinterpCmp); 1821 if (I==NULL) return(0); 1822 1823 /*****************************************/ 1824 /** if we got here, we found the field! **/ 1825 if (I->n_interp<0) { 1826 *error_code = ReadLinterpFile(I); 1827 if (*error_code != GD_E_OK) { 1828 *n_read = 0; 1829 return(1); 1830 } 1831 } 1832 recurse_level++; 1833 *n_read = DoField(F, I->raw_field, 1834 first_frame, first_samp, 1835 num_frames, num_samp, 1836 return_type, data_out, 1837 error_code); 1838 recurse_level--; 1839 if (*error_code!=GD_E_OK) return(1); 1840 LinterpData(data_out, return_type, *n_read, I->x, I->y, I->n_interp); 1841 return(1); 1842 1843 } 1844 1845 /***************************************************************************/ 1846 /* */ 1847 /* DoField: Doing one field once F has been identified */ 1848 /* */ 1849 /***************************************************************************/ 1850 static int DoField(struct FormatType *F, const char *field_code, 1851 int first_frame, int first_samp, 1852 int num_frames, int num_samp, 1853 char return_type, void *data_out, 1854 int *error_code) { 1855 int n_read; 1856 1857 if (recurse_level>10) { 1858 *error_code = SetGetDataError(GD_E_RECURSE_LEVEL, 0, NULL, 0, field_code); 1859 return(0); 1860 } 1861 1862 1863 /********************************************/ 1864 /* if Asking for "FILEFRAM" or "INDEX", just return it */ 1865 if ((strcmp(field_code,"FILEFRAM")==0) || 1866 (strcmp(field_code,"INDEX")==0)) { 1867 n_read = num_frames + num_samp; 1868 if (data_out!=NULL) { 1869 FillFileFrame(data_out, return_type, first_frame+first_samp+ 1870 F->frame_offset, n_read); 1871 } 1872 *error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 1873 return(n_read); 1874 } 1875 1876 if (DoIfRaw(F, field_code, 1877 first_frame, first_samp, 1878 num_frames, num_samp, 1879 return_type, data_out, 1880 error_code, &n_read)) { 1881 return(n_read); 1882 } else if (DoIfLincom(F, field_code, 1883 first_frame, first_samp, 1884 num_frames, num_samp, 1885 return_type, data_out, 1886 error_code, &n_read)) { 1887 return(n_read); 1888 } else if (DoIfBit(F, field_code, 1889 first_frame, first_samp, 1890 num_frames, num_samp, 1891 return_type, data_out, 1892 error_code, &n_read)) { 1893 return(n_read); 1894 } else if (DoIfLinterp(F, field_code, 1895 first_frame, first_samp, 1896 num_frames, num_samp, 1897 return_type, data_out, 1898 error_code, &n_read)) { 1899 return(n_read); 1900 } else if (DoIfMultiply(F, field_code, 1901 first_frame, first_samp, 1902 num_frames, num_samp, 1903 return_type, data_out, 1904 error_code, &n_read)) { 1905 return(n_read); 1906 } else { 1907 *error_code = SetGetDataError(GD_E_BAD_CODE, 0, NULL, 0, field_code); 1908 return(0); 1909 } 1910 } 1911 1912 /***************************************************************************/ 1913 /* */ 1914 /* GetData: read BLAST format files. */ 1915 /* filename_in: the name of the file directory (raw files are in here) */ 1916 /* field_code: the name of the field you want to read */ 1917 /* first_frame, first_samp: the first sample read is */ 1918 /* first_samp + samples_per_frame*first_frame */ 1919 /* num_frames, num_samps: the number of samples read is */ 1920 /* num_samps + samples_per_frame*num_frames */ 1921 /* return_type: data type of *data_out. 's': 16 bit signed */ 1922 /* 'u' 16bit unsigned 'S' 32bit signed 'U' 32bit unsigned */ 1923 /* 'c' 8 bit unsigned */ 1924 /* void *data_out: array to put the data */ 1925 /* *error_code: error code is returned here. */ 1926 /* */ 1927 /* return value: returns number of samples actually read into data_out */ 1928 /* */ 1929 /***************************************************************************/ 1930 int GetData(const char *filename_in, const char *field_code, 1931 int first_frame, int first_samp, 1932 int num_frames, int num_samp, 1933 char return_type, void *data_out, 1934 int *error_code) { 1935 1936 struct FormatType *F; 1937 int n_read=0; 1938 char filename[MAX_FILENAME_LENGTH+1]; 1939 1940 *error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 1941 1942 if (first_time) { 1943 Formats.n = 0; 1944 Formats.F = NULL; 1945 first_time = 0; 1946 } 1947 1948 strncpy(filename, filename_in, MAX_FILENAME_LENGTH); 1949 if (filename[strlen(filename)-1]=='/') filename[strlen(filename)-1]='\0'; 1950 F = GetFormat(filename, error_code); 1951 if (!F || *error_code != GD_E_OK) { 1952 return(0); 1953 } 1954 first_frame -= F->frame_offset; 1955 1956 n_read = DoField(F, field_code, 1957 first_frame, first_samp, 1958 num_frames, num_samp, 1959 return_type, data_out, 1960 error_code); 1961 1962 return(n_read); 1963 } 1964 1965 /***************************************************************************/ 1966 /* */ 1967 /* Get the number of frames available */ 1968 /* */ 1969 /***************************************************************************/ 1970 int GetNFrames(const char *filename_in, int *error_code, const char *in_field) { 1971 struct FormatType *F; 1972 char filename[MAX_FILENAME_LENGTH+1]; 1973 char raw_data_filename[2 * MAX_FILENAME_LENGTH + FIELD_LENGTH + 2]; 1974 struct stat statbuf; 1975 int nf; 1976 1977 *error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 1978 1979 if (first_time) { 1980 Formats.n = 0; 1981 Formats.F = NULL; 1982 first_time = 0; 1983 } 1984 1985 strncpy(filename, filename_in, MAX_FILENAME_LENGTH); 1986 if (filename[strlen(filename)-1]=='/') filename[strlen(filename)-1]='\0'; 1987 F = GetFormat(filename, error_code); 1988 if (*error_code != GD_E_OK) { 1989 return(0); 1990 } 1991 1992 if (!F || F->n_raw==0) { 1993 *error_code = SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_RAW, NULL, 0, 1994 NULL); 1995 return(0); 1996 } 1997 1998 /* load the first valid raw field */ 1999 snprintf(raw_data_filename, 2 * MAX_FILENAME_LENGTH + FIELD_LENGTH + 2, 2000 "%s/%s", filename, F->first_field.file); 2001 if (stat(raw_data_filename, &statbuf) < 0) { 2002 return(0); 2003 } 2004 2005 nf = statbuf.st_size/ 2006 (F->first_field.size*F->first_field.samples_per_frame); 2007 nf += F->frame_offset; 2008 2009 nf -= 2; 2010 if (nf < 0) 2011 nf = 0; 2012 return(nf); 2013 } 2014 2015 /***************************************************************************/ 2016 /* */ 2017 /* Get the number of samples for each frame for the given field */ 2018 /* */ 2019 /***************************************************************************/ 2020 int GetSamplesPerFrame(const char *filename_in, const char *field_name, int *error_code) { 2021 struct FormatType *F; 2022 char filename[MAX_FILENAME_LENGTH+1]; 2023 2024 *error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); 2025 2026 if (first_time) { 2027 Formats.n = 0; 2028 Formats.F = NULL; 2029 first_time = 0; 2030 } 2031 2032 strncpy(filename, filename_in, MAX_FILENAME_LENGTH); 2033 if (filename[strlen(filename)-1]=='/') filename[strlen(filename)-1]='\0'; 2034 F = GetFormat(filename, error_code); 2035 if (*error_code!=GD_E_OK) { 2036 return(0); 2037 } 2038 2039 if (!F || F->n_raw==0) { 2040 *error_code = SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_RAW, NULL, 0, 2041 NULL); 2042 return(0); 2043 } 2044 2045 return GetSPF(field_name, F, error_code); 2046 } 2047 /* vim: ts=2 sw=2 et 2048 */