/Users/craigcornelius/Projects/SPRING Mac Release 0.2/cyberware.cpp

Go to the documentation of this file.
00001 /* This module is used to hide the format of the Cyberware type image file
00002 * for historical reasons this file is in a compressed binary format and
00003 * may have a header which is inaccessable (easily) by some architectures,
00004 * especially iAPX xxx86 processors.  Also, the files from the digitizers
00005 * come in the old non-portable binary header style and in a newer portable
00006 * ASCII header style.  Use of this module will isolate you from all this
00007 * ugliness.
00008 *
00009 * Use these functions as follows:
00010 *
00011 *       #include "cyberware.h"
00012 *       GSPEC *cyread(int fd);
00013 *       int cywrite(GSPEC *gs, int fd);
00014 *       int cyfree(GSPEC *gs);
00015 *       long getr(GSPEC *gs, int latitude, int longitude);
00016 *       void putr(GSPEC *gs, int latitude, int longitude, long radius);
00017 *       int cyfree(GSPEC *gs);
00018 *       
00019 *       Cyread() allocates a new set of buffers each time it is called. If
00020 *       this is not what you intend, be sure to call cyfree(gs) first.
00021 *       Opening and closing the file descriptors is up to the caller.
00022 *       GETR() and PUTR() are inline macros for getr() and putr(), they
00023 *       usually execute about twice as fast as the function versions.
00024 *
00025 * Use the header variables as follows:
00026 *
00027 *       char gs->name           Image name string (40 characters max).
00028 *       long gs->ltincr         Increment between latitudes, y, microns.
00029 *       long gs->lgincr         Increment between longitudes, ur or um.
00030 *       short gs->ltmin         Data window, min latitude, inclusive.
00031 *       short gs->ltmax         Data window, max latitude, inclusive.
00032 *       short gs->lgmin         Data window, min longitude, inclusive.
00033 *       short gs->lgmax         Data window, max longitude, inclusive.
00034 *       short gs->nlt           Total number of latitudes.
00035 *       short gs->nlg           Total number of longitudes.
00036 *       long gs->flags          Bit flags, as below.
00037 *
00038 *       FLAG_OLDHEADER          Force writing of old style header.
00039 *       FLAG_CARTESIAN          Indicates cartesian data, lgincr is
00040 *                               in microns (x), radius becomes z. Think
00041 *                               of getr() as  z = getr(gs, yi, xi).
00042 *       FLAG_BILATERAL          Cartesian and bilateral, ie: nus hands.
00043 *
00044 *       Use other header variable at own risk.
00045 */
00046 
00047 #include <stdio.h>
00048 #include <math.h>
00049 #include <string.h>
00050 #include <stdlib.h>
00051 #include <time.h>
00052 
00053 #ifdef _WIN32
00054 #       include <fcntl.h>
00055 #       include <io.h>
00056 #else 
00057 #       include <unistd.h>
00058 #endif
00059 
00060 // Handle non-POSIX behavior
00061 #ifndef _WIN32
00062 #define _fdopen fdopen
00063 #define _dup dup
00064 #define _lseek lseek
00065 #define _read read
00066 #define _write write
00067 
00068 #endif // non-POSIX (at least Windows)
00069 
00070 
00071 //#include "strings.h"
00072 
00073 #ifndef __APPLE__
00074 #include "malloc.h"
00075 #endif // __APPLE__
00076 
00077 #include "cyberware.h"
00078 
00079 /* header globals */
00080 #define MAXHEADER 4096          /* ??? might hang on very short files */
00081 #define HEADEREND "DATA=\n"
00082 static char *header = 0;
00083 
00084 /* external declarations */
00085 extern int errno;
00086 extern char *ctime();
00087 extern long _lseek();
00088 extern void perror();
00089 
00090 /* error strings */
00091 char *STRXXX="Undefined Error String #@&*!";
00092 char *STR001="Problem accessing digitizer";
00093 char *STR002="Digitizer not at home position";
00094 char *STR003="Digitizer data input error";
00095 char *STR004="Problem controlling digitizer";
00096 char *STR005="Problem accessing DNC link";
00097 char *STR006="DNC link error";
00098 char *STR007="Mill does not support QUILLUP command";
00099 char *STR008="Memory problem, try switching off power and restarting";
00100 char *STR009="Parameter data problem, cannot continue";
00101 char *STR010="Command failed";
00102 char *STR011="Unrecognized command";
00103 char *STR012="Unimplemented command";
00104 char *STR013="No current image";
00105 char *STR014="Image must be filled first";
00106 char *STR015="Warning: VOID longitude";
00107 char *STR016="Number out of range";
00108 char *STR017="Latitude range is too small";
00109 char *STR018="Longitude range is too small";
00110 char *STR019="Invalid latitude period";
00111 char *STR020="Invalid longitude period";
00112 char *STR021="Current image must be saved or cleared";
00113 char *STR022="Cannot open file";
00114 char *STR023="Digitizer sync error (missing)";
00115 char *STR024="Digitizer sync error (misplaced)";
00116 char *STR025="Image has VOID zone, check settings, retry";
00117 char *STR026="Image file error on seek";
00118 char *STR027="Image file error on read";
00119 char *STR028="Image file error on write";
00120 char *STR029="Tabulation of radii (mm/10) in longitude";
00121 char *STR030="Raster refresh error PEBLKWR";
00122 char *STR031="Window manager error";
00123 char *STR032="Error accessing printer";
00124 char *STR033="Warning: voids in image, command gives unexpected results";
00125 char *STR034="Latitude or longitude range of one makes a null surface";
00126 char *STR035="Image data exceeds tool Z range";
00127 char *STR036="Tool diameter out of range";
00128 char *STR037="Already clear";
00129 char *STR038="UNNAMED";
00130 char *STR039="Is Echo Startup Disc inserted?";
00131 char *STR040="Cannot find or create file";
00132 char *STR041="Is Echo Startup Disc inserted and writeable?";
00133 char *STR042="Undefined option";
00134 char *STR043="\nR Lookup Table:";
00135 char *STR044="\nZ Lookup Table:";
00136 char *STR045="Serial           ";
00137 char *STR046="Data Format Type ";
00138 char *STR047="Vertical Range   ";
00139 char *STR048="Horizontal Range ";
00140 char *STR049="Horizontal Offset";
00141 char *STR050="Horizontal Center";
00142 char *STR051="Gauge Height     ";
00143 char *STR052="Gauge Width      ";
00144 char *STR053="Basic Angle      ";
00145 char *STR054="Samples per Frame";
00146 char *STR055="Frames per Image ";
00147 char *STR056="Radius Steps     ";
00148 char *STR057="\nCorrection Lookup Table, samples across, frames down:\n";
00149 char *STR058="You may want to make a new Correction Table";
00150 char *STR059="Standby...Computing new geometry lookup tables";
00151 char *STR060="Error occured while reading file";
00152 char *STR061="Error occured while writing file";
00153 char *STR062="Error in format or length of file";
00154 char *STR063="Enter image name: ";
00155 char *STR064="Ready ? (y/n): ";
00156 char *STR065="Warning HALFSPEED MODE selected";
00157 char *STR066="Geometry initialization error, cannot image";
00158 char *STR067="Digitizing failed, no image made";
00159 char *STR068="Use fscale command for this scale factor";
00160 char *STR069="Warning: negative scale, effect is untested";
00161 char *STR070="Warning: Scaling in sub-range, results may be unexpected";
00162 char *STR071="Warning: Rshift has been altered";
00163 char *STR072="Option specification required";
00164 char *STR073="Warning: Entirely VOID longitude cannot be filled";
00165 char *STR074="Warning: Entirely VOID latitude cannot be filled";
00166 char *STR075="Error during open";
00167 char *STR076="File protection error";
00168 char *STR077="File not found";
00169 char *STR078="Disc is Write-Protected";
00170 char *STR079="Device is not accessible";
00171 char *STR080="Error during file close";
00172 char *STR081="Error with device or window";
00173 char *STR082="Cannot allocate enough memory";
00174 char *STR083="Type CONTROL_C key to stop";
00175 char *STR084="'PASS COMPLETED'\r";              /* for the bridgeport */
00176 char *STR085="Echo> ";                                  /* command line prompt */
00177 char *STR086="Longitude increment";
00178 char *STR087="Latitude increment";
00179 char *STR088="Repeat terminated by error condition";
00180 char *STR089="Horizontal Horizon Plot";
00181 char *STR090="Horizontal Hemi-Cyl Plot";
00182 char *STR091="Axial View of a Slice";
00183 char *STR092="Cartesian Latitudes";
00184 char *STR093="Cartesian Longitudes";
00185 char *STR094="No options allowed, use 'display -s' command";
00186 char *STR095="Move Mouse, left button to stop";
00187 char *STR096="For menu press and hold right button";
00188 char *STR097="Hold button, select item, release button";
00189 char *STR098="Type a command, 'help' or 'exit'";
00190 char *STR099="Move mouse, middle picks, left stops";
00191 char *STR100="Use fscale command to scale cartesian data sets";
00192 char *STR101="Error reading text string";
00193 char *STR102="Cartesian/Cylindrical and data/command states do not match";
00194 char *STR103="Machining parameters:";
00195 char *STR104="Demo version, command not implemented";
00196 char *STR105="Usage: echodemo image-pathname";
00197 char *STR106="Undefined file header type";
00198 char *STR107="Problem with file header";
00199 char *STR108="Header seek error";
00200 char *STR109="Header read error";
00201 char *STR110="Header value not terminated properly";
00202 char *STR111="Required value not in header";
00203 char *STR112="Header value undefined";
00204 char *STR113="Unexpected VOID";
00205 char *STR114="Improper combination of options";
00206 char *STR115="Step Offset      ";
00207 char *STR116="Resolution Bits  ";
00208 char *STR117="Sample Low Margin";
00209 char *STR118="Sample Hi Margin ";
00210 char *STR119="Server Name      ";
00211 char *STR120="Set-up Date      ";
00212 char *STR121="Unable to read optical configuration file";
00213 char *STR122="Unable to read optical table file";
00214 char *STR123="Optical parameter file seek error";
00215 char *STR124="Optical parameter file read error";
00216 char *STR125="Missing required optical parameter:";
00217 char *STR126="Missing optical data table";
00218 char *STR127="Please Standby - %d%% Complete\r";
00219 char *STR128="                                \r";
00220 char *STR129="Missing required mill parameter: %s\n";
00221 char *STR130="Mill parameter file error";
00222 char *STR131="Environment variable %s not defined\n";
00223 char *STR132="Configuration file not found";
00224 char *STR133="Cannot execute mill interface filter";
00225 char *STR134="Cannot fork mill interface filter";
00226 char *STR135="ECHO_MILL_TYPE incompatible with this command";
00227 char *STR136="Unknown user";
00228 char *STR137="File name must be given";
00229 char *STR138="Environment variable has bad value: %s\n";
00230 char *STR139="Command usage error, see manual";
00231 char *STR140="Sorry, cannot find any information on \"%s\"\n";
00232 char *STR141="References to \"%s\" found, try the manual page for:\n";
00233 char *STR142="Server problem, frame receive";
00234 char *STR143="Optical table format error";
00235 char *STR144="Problem with SunView window system (Not a Sun terminal?)";
00236 char *STR145="Image processing failed, no image made";
00237 char *STR146="Longitude outside of current range window";
00238 char *STR147="Latitude outside of current range window";
00239 char *STR148="Tabulation of radii (mm/10) in latitude";
00240 char *STR149="You must meter a point before clipping";
00241 char *STR150="User Configuration file not found";
00242 
00243 
00244 /*************************** Private Functions *******************************/
00245 
00246 
00247 
00248 int gdallo(GSPEC* gs)                           /* allocate a data buffer */
00249 {
00250     unsigned long size;
00251     
00252     size = (unsigned long)gs->nlt *
00253         (unsigned long)gs->nlg * (unsigned long)sizeof(short);
00254     gs->base = (short *)malloc(size);
00255     
00256     if (gs->base == NULL) {
00257         puts(STR082);
00258         return(-1);
00259     } else {
00260         return(0);
00261     }
00262 }
00263 
00264 
00265 
00266 GSPEC *gsallo()                         /* allocate a GSPEC structure */
00267 {
00268     GSPEC *gs;
00269     
00270     gs = (GSPEC *)malloc((unsigned)sizeof(GSPEC));
00271     if (gs == NULL) {
00272         puts(STR082);
00273         return(NULL);
00274     }
00275     gs->base = NULL;
00276     return(gs);
00277 }
00278 
00279 
00280 /* copy value of name to dest or return -1 */
00281 int getvalue(char* name, char* dest, int length)  
00282 {
00283     char *h = header;
00284     int n;
00285     char *p;
00286     
00287     if (header == 0) {                                                          /* no header, oops! */
00288         puts("getvalue: no header");
00289         exit(-1);               /* fatal coding error */
00290     }
00291     n = strlen(name);
00292     while ((h = strchr(h, '\n')) != 0) {        /* move to next newline */
00293         h += 1;                                                                         /* skip over newline */
00294         if (strncmp(h, name, n) == 0) { /* compare names */
00295             h += strlen(name);  /* skip over matched name */
00296             if (*h == '=') {    /* verify assignment char */
00297                 h += 1;
00298                 /* no value terminator ? */
00299                 if ((p = strchr(h, '\n')) == 0) {
00300                     puts(STR110);
00301                     return(-1);
00302                 }
00303                 *p = 0;         /* temporary termination */
00304                 strncpy(dest, h, length);
00305                 *p = '\n';      /* restore terminator */
00306                 return(0);
00307             }
00308         }
00309     }
00310     return(-1);                         /* no match */
00311 }
00312 
00313 
00314 long getheader(int fd)  /* get header and seek to data */
00315 {
00316     int count;
00317     char *end;
00318     char *h;
00319     char *endstr = HEADEREND;
00320     char *temp_header;
00321     char *addr;
00322     int n;
00323     
00324     temp_header = (char*)malloc(MAXHEADER);
00325     
00326     if (_lseek(fd, (long)0, 0) == -1) {
00327         perror(STR108);
00328         return(-1);
00329     }
00330     addr = temp_header;
00331     for (count = 0; count < MAXHEADER; count += n) {
00332         if ((n = _read(fd, addr, (unsigned)MAXHEADER)) == -1) {
00333             perror(STR109);
00334             return(-1);
00335         }
00336         addr += n;
00337     }
00338     
00339     /* end of header is eof or endstr string */
00340     end = temp_header + count;
00341     for (h = temp_header; h < end; ++h) {
00342         if (*h == endstr[0]) {
00343             if (strncmp(endstr, h, strlen(endstr)) == 0) {
00344                 end = h + strlen(endstr);
00345                 break;
00346             }
00347         }
00348     }
00349     count = end - temp_header;
00350     if (header != 0) {
00351         free(header);
00352     }
00353     header = (char*)malloc((unsigned)(count+1));
00354     strncpy(header, temp_header, count);
00355     header[count] = 0;                  /* null terminate */
00356     free(temp_header);
00357     return(count);
00358 }
00359 
00360 
00361 
00362 #define STRINGLEN       24
00363 
00364 int makegsheader(GSPEC* gs)     /* fill GSPEC structure from portable header */
00365 {
00366     char string[STRINGLEN+1];
00367     long i;
00368     
00369     string[STRINGLEN] = 0;
00370     
00371     /* defaults */
00372     gs->flags = 0;
00373     
00374     /* mandatory items */
00375     if (getvalue("NLT", string, STRINGLEN) == -1) {
00376         printf("%s: %s\n", STR111, "NLT");
00377         return(-1);
00378     }
00379     gs->nlt = atoi(string);
00380     if (getvalue("NLG", string, STRINGLEN) == -1) {
00381         printf("%s: %s\n", STR111, "NLG");
00382         return(-1);
00383     }
00384     gs->nlg = atoi(string);
00385     if (getvalue("LGSHIFT", string, STRINGLEN) == -1) {
00386         printf("%s: %s\n", STR111, "LGSHIFT");
00387         return(-1);
00388     }
00389     gs->lgshift = atoi(string);
00390     if (getvalue("LTINCR", string, STRINGLEN) == -1) {
00391         printf("%s: %s\n", STR111, "LTINCR");
00392         return(-1);
00393     }
00394     gs->ltincr = atol(string);
00395     if (getvalue("LGINCR", string, STRINGLEN) == -1) {
00396         printf("%s: %s\n", STR111, "LGINCR");
00397         return(-1);
00398     }
00399     gs->lgincr = atol(string);
00400     if (getvalue("RSHIFT", string, STRINGLEN) == -1) {
00401         printf("%s: %s\n", STR111, "RSHIFT");
00402         return(-1);
00403     }
00404     gs->rshift = atoi(string);
00405     
00406     /* optional items */
00407     if (getvalue("NAME", gs->name, NAMELEN) == -1) {
00408         for (i = NAMELEN-1; i >= 0; --i) gs->name[i] = 0;
00409     }
00410     if (getvalue("LTMIN", string, STRINGLEN) == -1) {
00411         gs->ltmin = 0;
00412     } else {
00413         gs->ltmin = atoi(string);
00414     }
00415     if (getvalue("LTMAX", string, STRINGLEN) == -1) {
00416         gs->ltmax = gs->nlt - 1;
00417     } else {
00418         gs->ltmax = atoi(string);
00419     }
00420     if (getvalue("LGMIN", string, STRINGLEN) == -1) {
00421         gs->lgmin = 0;
00422     } else {
00423         gs->lgmin = atoi(string);
00424     }
00425     if (getvalue("LGMAX", string, STRINGLEN) == -1) {
00426         gs->lgmin = gs->nlg - 1;
00427     } else {
00428         gs->lgmax = atoi(string);
00429     }
00430     if (getvalue("RMIN", string, STRINGLEN) == -1) {
00431         gs->rmin = 0;
00432     } else {
00433         gs->rmin = atol(string);
00434     }
00435     if (getvalue("RMAX", string, STRINGLEN) == -1) {
00436         gs->rmax = 0;
00437     } else {
00438         gs->rmax = atol(string);
00439     }
00440     if (getvalue("SCALE", string, STRINGLEN) == -1) {
00441         gs->scale = 100.0;
00442     } else {
00443         gs->scale = atof(string);
00444     }
00445     if (getvalue("RPROP", string, STRINGLEN) == -1) {
00446         gs->rprop = 100.0;
00447     } else {
00448         gs->rprop = atof(string);
00449     }
00450     if (getvalue("FILLED", string, STRINGLEN) == -1) {
00451         gs->filled = 0;
00452     } else {
00453         gs->filled = 1;
00454     }
00455     if (getvalue("SMOOTHED", string, STRINGLEN) == -1) {
00456         gs->smoothed = 0;
00457     } else {
00458         gs->smoothed = 1;
00459     }
00460     if (getvalue("SPACE", string, STRINGLEN) == -1) {
00461         gs->flags = 0;
00462     } else {
00463         if (strcmp(string, "CARTESIAN") == 0) {
00464             gs->flags |= FLAG_CARTESIAN;
00465         } else if (strcmp(string, "CYLINDRICAL") == 0) {
00466             gs->flags &= ~FLAG_CARTESIAN;
00467         } else if (strcmp(string, "BILATERAL") == 0) {
00468             gs->flags |= FLAG_CARTESIAN;
00469             gs->flags |= FLAG_BILATERAL;
00470         } else {
00471             printf("%s: SPACE\n", STR112);
00472             return(-1);
00473         }
00474     }
00475     if (getvalue("INSIDE_OUT", string, STRINGLEN) != -1) {
00476         gs->flags |= FLAG_INSIDE_OUT;
00477     }
00478     if (getvalue("COLOR", string, STRINGLEN) != -1) {
00479         gs->flags |= FLAG_COLOR;
00480     }
00481     if (getvalue("THETA_RIGHTHAND", string, STRINGLEN) != -1) {
00482         gs->flags |= FLAG_THETARIGHT;
00483     }
00484     
00485     /* forced value items */
00486     gs->time = 0;
00487     gs->camera = 0;
00488     gs->setup = 0;
00489     gs->saved = 0;
00490     gs->valid = 0;
00491     gs->ltsize = gs->nlt * gs->ltincr;
00492     gs->lgsize = gs->nlg * gs->lgincr;
00493     return(0);
00494 }
00495 
00496 
00497 
00498 /* write a portable header from GSPEC struct */
00499 int writegsheader(GSPEC* gs, int fd)
00500 {
00501 /* Uses \012 instead of \n for the sake of DOS which outputs a
00502     * CR-LF sequence with \n !!! */
00503     
00504     /* Open a stream on a duplicate file descriptor.  The duplicate is
00505     * necessary to allow the stream to be closed with out closing the
00506     * callers file descriptor */
00507     
00508     FILE *fp = _fdopen(_dup(fd), "w");
00509     
00510     /* error status only checked on first line and last line */
00511     if (fprintf(fp, "Cyberware Digitizer Data\012") < 0) {
00512         perror(STR028);
00513         fclose(fp);
00514         return(-1);
00515     }
00516     fprintf(fp, "NAME=%.40s\012", gs->name);
00517 #ifdef _WIN32
00518     fprintf(fp, "DATE=%s", "01/01/01");
00519 #else
00520     fprintf(fp, "DATE=%s", ctime(&gs->time));
00521 #endif
00522     if (gs->flags & FLAG_CARTESIAN) {
00523         if (gs->flags & FLAG_BILATERAL) {
00524             fprintf(fp, "SPACE=BILATERAL\012");
00525         } else {
00526             fprintf(fp, "SPACE=CARTESIAN\012");
00527         }
00528     } else {
00529         fprintf(fp, "SPACE=CYLINDRICAL\012");
00530     }
00531     if (gs->flags & FLAG_COLOR) {
00532         fprintf(fp, "COLOR=SGI\012");
00533     }
00534     if (gs->flags & FLAG_INSIDE_OUT) {
00535         fprintf(fp, "INSIDE_OUT=TRUE\012");
00536     }
00537     if (gs->flags & FLAG_THETARIGHT) {
00538         fprintf(fp, "THETA_RIGHTHAND=TRUE\012");
00539     }
00540     fprintf(fp, "NLG=%-.1d\012", gs->nlg);
00541     fprintf(fp, "LGINCR=%-.1ld\012", gs->lgincr);
00542     fprintf(fp, "LGMIN=%-.1d\012", gs->lgmin);
00543     fprintf(fp, "LGMAX=%-.1d\012", gs->lgmax);
00544     fprintf(fp, "NLT=%-.1d\012", gs->nlt);
00545     fprintf(fp, "LTINCR=%-.1ld\012", gs->ltincr);
00546     fprintf(fp, "LTMIN=%-.1d\012", gs->ltmin);
00547     fprintf(fp, "LTMAX=%-.1d\012", gs->ltmax);
00548     fprintf(fp, "RMIN=%-.1ld\012", gs->rmin);
00549     fprintf(fp, "RMAX=%-.1ld\012", gs->rmax);
00550     fprintf(fp, "RSHIFT=%-.1d\012", gs->rshift);
00551     fprintf(fp, "LGSHIFT=%-.1d\012", gs->lgshift);
00552     fprintf(fp, "SCALE=%-.2f\012", (float)gs->scale);
00553     fprintf(fp, "RPROP=%-.2f\012", (float)gs->rprop);
00554     if (gs->filled) {
00555         fprintf(fp, "FILLED=1\012");
00556     }
00557     if (gs->smoothed) {
00558         fprintf(fp, "SMOOTHED=1\012");
00559     }
00560     fprintf(fp, "DATA=\012");
00561     if (fflush(fp) == EOF) {
00562         perror(STR028);
00563         fclose(fp);
00564         return(-1);
00565     }
00566     fclose(fp);
00567     return(0);
00568 }
00569 
00570 
00571 
00572 /* The loops around read()s facilitate the use of pipes, which may not always
00573 * read an entire header or data array at one time.  HP Integral i/o is
00574 * a little slow, so a line of dots is written across stderr to keep the user
00575 * awake.
00576 */
00577 
00578 
00579 int gsget(GSPEC* gs, int fd)            /* read GSPEC structure from file fd */
00580 {
00581     unsigned count = sizeof(GSPEC);             /* number of bytes in header */
00582     char *addr = (char *)gs;                    /* start of header */
00583     int n;
00584     short *base_save = gs->base;                /* save address of start of data */
00585     
00586     if (_lseek(fd, (long)0, 0) == -1L) { /* seek to beginning of file */
00587         perror(STR026);
00588         return(-1);
00589     }
00590     
00591     /* assume the header is of the older binary type */
00592     while (count > 0) {
00593         if ((n = _read(fd, addr, count)) == -1) { /* n has number bytes read */
00594             perror(STR027);
00595             gs->base = base_save;
00596             return(-1);
00597         }
00598         count -= n; /* decrement count by number bytes read */
00599         addr += n;  /* update ptr to header structure */
00600     }
00601     
00602     /* determine header type */
00603     if (gs->offset != 122 && gs->offset != 114 && gs->offset != 128) {
00604         gs->flags |= FLAG_OLDHEADER;
00605         if (*((char *)gs + 4) == 'r') {
00606             /* reread header as portable type */
00607             if ((gs->offset = getheader(fd)) == -1) {
00608                 puts(STR107);   /* some format problem */
00609                 gs->base = base_save;
00610                 return(-1);
00611             }
00612             if (makegsheader(gs) == -1) {
00613                 puts(STR107);   /* some format problem */
00614                 gs->base = base_save;
00615                 return(-1);
00616             }
00617         } else {
00618             puts(STR106);               /* undefined header type */
00619             gs->base = base_save;
00620             return(-1);
00621         }
00622     }
00623     gs->base = base_save;
00624     gs->saved = 0;
00625     gs->valid = 0;
00626     return(0);
00627 }
00628 
00629 
00630 
00631 int gsput(GSPEC* gs, int fd)            /* write GSPEC structure to file fd */
00632 {
00633     int count = sizeof(GSPEC);
00634     
00635 #ifdef _WIN32
00636     if (_lseek(fd, (long)0, 0) == -1) {
00637         perror(STR026);
00638         return(-1);
00639     }
00640 #else
00641     if (ftruncate(fd, (long)0) == -1 || _lseek(fd, (long)0, 0) == -1) {
00642         perror(STR026);
00643         return(-1);
00644     }
00645 #endif
00646     
00647     if (gs->flags & FLAG_OLDHEADER) {
00648         gs->offset = count;
00649         if (_write(fd, (char *)gs, count) != count) {
00650             perror(STR028);
00651             return(-1);
00652         }
00653     } else {
00654         if (writegsheader(gs, fd) == -1) {
00655             return(-1);
00656         }
00657     }
00658     return(0);
00659 }
00660 
00661 
00662 
00663 int gdget(GSPEC* gs, int fd)            /* read data from grid file fd */
00664 {
00665     unsigned long count = (long)sizeof(short) * (long)gs->nlt * (long)gs->nlg;
00666     int n;
00667     unsigned int readsize;
00668     char *addr;
00669     unsigned size = count;
00670     
00671     /* if unallocated, allocate image memory */
00672     if (gs->base == NULL) {
00673         if (gdallo(gs) == -1) {
00674             return(-1);
00675         }
00676     }
00677     
00678     if (_lseek(fd, gs->offset, 0) == -1L) {
00679         perror(STR026);
00680         return(-1);
00681     }
00682     addr = (char *)gs->base;
00683     while (count > 0) {
00684         readsize = (unsigned int) MIN(size, count);
00685         if ((n = _read(fd, addr, readsize)) == -1L) {
00686             perror(STR027);
00687             return(-1);
00688         }
00689         count -= (unsigned long)n;
00690         addr += n;
00691     }
00692     return(0);
00693 }
00694 
00695 
00696 
00697 int gdput(GSPEC* gs, int fd)            /* write data to grid file */
00698 {
00699     unsigned long count;
00700     int n;
00701     unsigned int writesize;
00702     char *addr = (char *)gs->base;
00703     unsigned size = 64*1024;            /* a large block size */
00704     
00705     count = (long)sizeof(short) * (long)gs->nlt * (long)gs->nlg;
00706     
00707     if (gs->flags & FLAG_OLDHEADER) {
00708         if (_lseek(fd, (long)gs->offset, 0) == (long)-1) {
00709             perror(STR026);
00710             return(-1);
00711         }
00712     }
00713     while (count > 0) {
00714         writesize = (unsigned int) MIN(size, count);
00715 #ifdef _WIN32
00716         if ((n = _write(fd, addr, writesize)) == -1L) {  /* ??? really?? */
00717 #else
00718             if ((n = write(fd, addr, writesize)) == -1L) {
00719 #endif
00720                 perror(STR028);
00721                 return(-1);
00722             }
00723             count -= (unsigned long)n;
00724             addr += n;
00725         }
00726         return(0);
00727     }
00728     
00729     
00730     
00731     /*************************** Public Functions ********************************/
00732     
00733     
00734     
00735     /* Cyread optionally allocates buffer space for an image and its header; and
00736     * optionally reads an image file into these buffers.  If buffers are not
00737     * yet allocated then call with gs set to NULL.  The return value will be
00738     * a pointer to the header structure, gs.  If a file is to be read then
00739     * open a file and pass the descriptor in fd.  If fd is -1 then no files are
00740     * read and the buffers, if any, have undefined contents.
00741     */
00742     
00743     GSPEC *cyread(GSPEC* gs, int fd)    /* read data file from fd */
00744     {
00745         /* if gs is NULL allocate gs structure, if fd is not -1 read file */
00746         
00747         if (gs == NULL) {
00748             if ((gs = gsallo()) == NULL) {      /* allocate header memory */
00749                 return(NULL);
00750             }
00751         } else {
00752             if (gs->base != NULL) {
00753                 free((char *)gs->base);
00754                 gs->base = NULL;
00755             }
00756         }
00757         if (fd != -1) {
00758             if (gsget(gs, fd) == -1) {  /* read header */
00759                 return(NULL);
00760             }
00761             if (gs->base == NULL) {             /* not yet allocated ? */
00762                 if (gdallo(gs) == -1) { /* allocate data memory */
00763                     return(NULL);
00764                 }
00765             }
00766             if (gdget(gs, fd) == -1) {  /* read data */
00767                 return(NULL);
00768             }
00769         }
00770         return(gs);
00771     }
00772     
00773     
00774     
00775     /* Cywrite writes the header and image data defined by the header to the
00776     * file with open descriptor fd.  The header and buffer contents are
00777     * not altered in any way.  Use cyfree to release the buffers if necessary.
00778     */
00779     
00780     int cywrite(GSPEC* gs, int fd)      /* write data file to fd */
00781     {
00782         if (gsput(gs, fd) == -1) {      /* write header */
00783             return(-1);
00784         }
00785         if (gdput(gs, fd) == -1) {
00786             return(-1);
00787         }
00788         return(0);
00789     }
00790     
00791     
00792     
00793     /* Cyfree will release any memory resources associated with the header gs
00794     * and its image buffer.
00795     */
00796     
00797     void cyfree(GSPEC* gs)              /* free private resources */
00798     {
00799         if (gs != NULL) {
00800             if (gs->base != NULL) {
00801                 free((char *)gs->base);
00802             }
00803             free((char *)gs);
00804         }
00805     }
00806     
00807     
00808     
00809     /* Getr and putr are to be used to access the image data.  Please note
00810     * the histroically backwards order of the arguments lt and lg.
00811     * Getr may return the value VOID, which is a very large negative number.
00812     * The return value should always be tested for VOID unless you can be
00813     * sure that all have been filled.  Putr will accept VOID as the radius
00814     * argument to store a void value.
00815     */
00816     
00817     /* a function version of GETR() used globally */
00818     long getr(GSPEC* gs, int lt, int lg)
00819     {
00820 #ifdef _WIN32
00821         long offset;
00822         unsigned short range_packed;
00823         long range_um;
00824         
00825         offset = lg * gs->nlt + lt;
00826         range_packed = *(unsigned short *)(gs->base + offset);
00827         range_packed = range_packed << 8 | range_packed >> 8;
00828         range_um = (long)(short)range_packed << gs->rshift;
00829         return range_um;
00830 #else
00831         return(GETR(gs, lt, lg));
00832 #endif
00833     }
00834     
00835     
00836     
00837     /* a function version of PUTR() used globally */
00838     void putr(GSPEC* gs, int lt, int lg, int r)
00839     {
00840 #ifdef _WIN32
00841         long offset;
00842         unsigned short range_packed;
00843         offset = lg * gs->nlt + lt;
00844         
00845         range_packed = (unsigned short)(r >> gs->rshift);
00846         range_packed = range_packed << 8 | range_packed >> 8;
00847         *(gs->base + offset) = (short)range_packed;
00848 #else
00849         PUTR(gs, lt, lg, r);
00850 #endif
00851     }
00852     

Generated on Thu Aug 30 11:03:13 2007 for SPRING Mac by  doxygen 1.5.3