[BACK]Return to binary.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/binary.c, Revision 1.1

1.1     ! maekawa     1: #ifndef lint
        !             2: static char *RCSid = "$Id: binary.c,v 1.10 1998/04/14 00:14:49 drd Exp $";
        !             3: #endif
        !             4:
        !             5: /*
        !             6:  * The addition of gnubin and binary, along with a small patch
        !             7:  * to command.c, will permit gnuplot to plot binary files.
        !             8:  * gnubin  - contains the code that relies on gnuplot include files
        !             9:  *                     and other definitions
        !            10:  * binary      - contains those things that are independent of those
        !            11:  *                     definitions and files
        !            12:  *
        !            13:  * With these routines, hidden line removal of your binary data is possible!
        !            14:  *
        !            15:  * Last update:  3/29/92 memory allocation bugs fixed. jvdwoude@hut.nl
        !            16:  *               3/09/92 spelling errors, general cleanup, use alloc with no
        !            17:  *                       nasty fatal errors
        !            18:  *               3/03/92 for Gnuplot 3.24.
        !            19:  * Created from code for written by RKC for gnuplot 2.0b.
        !            20:  *
        !            21:  * Copyright (c) 1991,1992 Robert K. Cunningham, MIT Lincoln Laboratory
        !            22:  *
        !            23:  */
        !            24:
        !            25: #include "plot.h"              /* We have to get TRUE and FALSE */
        !            26: #include "stdfn.h"
        !            27: #include "binary.h"
        !            28:
        !            29: /*
        !            30:  * This routine scans the first block of the file to see if the file is a
        !            31:  * binary file.  A file is considered binary if 10% of the characters in it
        !            32:  * are not in the ascii character set. (values < 128), or if a NUL is found.
        !            33:  * I hope this doesn't break when used on the bizzare PC's.
        !            34:  */
        !            35: int is_binary_file(fp)
        !            36: register FILE *fp;
        !            37: {
        !            38:     register int i, len;
        !            39:     register int odd;          /* Contains a count of the odd characters */
        !            40:     long where;
        !            41:     register unsigned char *c;
        !            42:     unsigned char buffer[512];
        !            43:
        !            44:     if ((where = ftell(fp)) == -1) {   /* Find out where we start */
        !            45:        fprintf(stderr, "Notice: Assuming unseekable data is not binary\n");
        !            46:        return (FALSE);
        !            47:     } else {
        !            48:        rewind(fp);
        !            49:
        !            50:        len = fread(buffer, sizeof(char), 512, fp);
        !            51:        if (len <= 0)           /* Empty file is declared ascii */
        !            52:            return (FALSE);
        !            53:
        !            54:        c = buffer;
        !            55:
        !            56:        /* now scan buffer to look for odd characters */
        !            57:        odd = 0;
        !            58:        for (i = 0; i < len; i++, c++) {
        !            59:            if (!*c) {          /* NUL _never_ allowed in text */
        !            60:                odd += len;
        !            61:                break;
        !            62:            } else if ((*c & 128) ||    /* Meta-characters--we hope it's not formatting */
        !            63:                       (*c == 127) ||   /* DEL */
        !            64:                       (*c < 32 &&
        !            65:                        *c != '\n' && *c != '\r' && *c != '\b' &&
        !            66:                        *c != '\t' && *c != '\f' && *c != 27 /*ESC */ ))
        !            67:                odd++;
        !            68:        }
        !            69:
        !            70:        fseek(fp, where, 0);    /* Go back to where we started */
        !            71:
        !            72:        if (odd * 10 > len)     /* allow 10% of the characters to be odd */
        !            73:            return (TRUE);
        !            74:        else
        !            75:            return (FALSE);
        !            76:     }
        !            77: }
        !            78:
        !            79:
        !            80: /*========================= I/O Routines ================================
        !            81:   These may be useful for situations other than just gnuplot.  Note that I
        !            82:   have included the reading _and_ the writing routines, so others can create
        !            83:   the file as well as read the file.
        !            84: */
        !            85:
        !            86: /*
        !            87:    This function reads a matrix from a stream
        !            88:
        !            89:    This routine never returns anything other than vectors and arrays
        !            90:    that range from 0 to some number.
        !            91:
        !            92:  */
        !            93: #define START_ROWS 100         /* Each of these must be at least 1 */
        !            94: #define ADD_ROWS 50
        !            95: int fread_matrix(fin, ret_matrix, nr, nc, row_title, column_title)
        !            96: FILE *fin;
        !            97: float GPFAR *GPFAR * GPFAR * ret_matrix, GPFAR * GPFAR * row_title,
        !            98:  GPFAR * GPFAR * column_title;
        !            99: int *nr, *nc;
        !           100: {
        !           101:     float GPFAR *GPFAR * m, GPFAR * rt, GPFAR * ct;
        !           102:     register int num_rows = START_ROWS;
        !           103:     register int num_cols;
        !           104:     register int current_row = 0;
        !           105:     register float GPFAR *GPFAR * temp_array;
        !           106:     float fdummy;
        !           107:
        !           108:     if (fread(&fdummy, sizeof(fdummy), 1, fin) != 1)
        !           109:        return FALSE;
        !           110:
        !           111:     num_cols = (int) fdummy;
        !           112:
        !           113:     /*
        !           114:        Choose a reasonable number of rows,
        !           115:        allocate space for it and continue until this space
        !           116:        runs out, then extend the matrix as necessary.
        !           117:      */
        !           118:     ct = vector(0, num_cols - 1);
        !           119:     fread(ct, sizeof(*ct), num_cols, fin);
        !           120:
        !           121:     rt = vector(0, num_rows - 1);
        !           122:     m = matrix(0, num_rows - 1, 0, num_cols - 1);
        !           123:
        !           124:     while (fread(&rt[current_row], sizeof(rt[current_row]), 1, fin) == 1) {
        !           125:        /* We've got another row */
        !           126:        if (fread(m[current_row], sizeof(*(m[current_row])), num_cols, fin) != num_cols)
        !           127:            return (FALSE);     /* Not a True matrix */
        !           128:
        !           129:        current_row++;
        !           130:        if (current_row >= num_rows) {  /* We've got to make a bigger rowsize */
        !           131:            temp_array = extend_matrix(m, 0, num_rows - 1, 0, num_cols - 1,
        !           132:                                  num_rows + ADD_ROWS - 1, num_cols - 1);
        !           133:            rt = extend_vector(rt, 0, num_rows - 1, num_rows + ADD_ROWS - 1);
        !           134:
        !           135:            num_rows += ADD_ROWS;
        !           136:            m = temp_array;
        !           137:        }
        !           138:     }
        !           139:     /*  finally we force the matrix to be the correct row size */
        !           140:     /*  bug fixed. procedure called with incorrect 6th argument.
        !           141:      *   jvdwoude@hut.nl */
        !           142:     temp_array = retract_matrix(m, 0, num_rows - 1, 0, num_cols - 1, current_row - 1, num_cols - 1);
        !           143:     /* Now save the things that change */
        !           144:     *ret_matrix = temp_array;
        !           145:     *row_title = retract_vector(rt, 0, num_rows - 1, current_row - 1);
        !           146:     *column_title = ct;
        !           147:     *nr = current_row;         /* Really the total number of rows */
        !           148:     *nc = num_cols;
        !           149:     return (TRUE);
        !           150: }
        !           151:
        !           152: /* This writes a matrix to a stream
        !           153:    Note that our ranges are inclusive ranges--and we can specify subsets.
        !           154:    This behaves similarly to the xrange and yrange operators in gnuplot
        !           155:    that we all are familiar with.
        !           156:  */
        !           157: int fwrite_matrix(fout, m, nrl, nrh, ncl, nch, row_title, column_title)
        !           158: register FILE *fout;
        !           159: register float GPFAR *GPFAR * m, GPFAR * row_title, GPFAR * column_title;
        !           160: register int nrl, nrh, ncl, nch;
        !           161: {
        !           162:     register int j;
        !           163:     float length;
        !           164:     register int col_length;
        !           165:     register int status;
        !           166:     float GPFAR *title = NULL;
        !           167:
        !           168:     length = (float) (col_length = nch - ncl + 1);
        !           169:
        !           170:     if ((status = fwrite((char *) &length, sizeof(float), 1, fout)) != 1) {
        !           171:        fprintf(stderr, "fwrite 1 returned %d\n", status);
        !           172:        return (FALSE);
        !           173:     }
        !           174:     if (!column_title) {
        !           175:        column_title = title = vector(ncl, nch);
        !           176:        for (j = ncl; j <= nch; j++)
        !           177:            title[j] = (float) j;
        !           178:     }
        !           179:     fwrite((char *) column_title, sizeof(float), col_length, fout);
        !           180:     if (title) {
        !           181:        free_vector(title, ncl, nch);
        !           182:        title = NULL;
        !           183:     }
        !           184:     if (!row_title) {
        !           185:        row_title = title = vector(nrl, nrh);
        !           186:        for (j = nrl; j <= nrh; j++)
        !           187:            title[j] = (float) j;
        !           188:     }
        !           189:     for (j = nrl; j <= nrh; j++) {
        !           190:        fwrite((char *) &row_title[j], sizeof(float), 1, fout);
        !           191:        fwrite((char *) (m[j] + ncl), sizeof(float), col_length, fout);
        !           192:     }
        !           193:     if (title)
        !           194:        free_vector(title, nrl, nrh);
        !           195:
        !           196:     return (TRUE);
        !           197: }
        !           198:
        !           199: /*===================== Support routines ==============================*/
        !           200:
        !           201: /******************************** VECTOR *******************************
        !           202:  *       The following routines interact with vectors.
        !           203:  *
        !           204:  *   If there is an error we don't really return - int_error breaks us out.
        !           205:  *
        !           206:  *   This subroutine based on a subroutine listed in "Numerical Recipies in C",
        !           207:  *   by Press, Flannery, Teukoilsky and Vetterling (1988).
        !           208:  *
        !           209:  */
        !           210: float GPFAR *vector(nl, nh)
        !           211: register int nl, nh;
        !           212: {
        !           213:     register float GPFAR *vec;
        !           214:
        !           215:     if (!(vec = (float GPFAR *) gp_alloc((unsigned long) (nh - nl + 1) * sizeof(float), NULL))) {
        !           216:        int_error("not enough memory to create vector", NO_CARET);
        !           217:        return NULL;            /* Not reached */
        !           218:     }
        !           219:     return (vec - nl);
        !           220: }
        !           221:
        !           222:
        !           223: /*
        !           224:  *  Free a vector allocated above
        !           225:  *
        !           226:  *   This subroutine based on a subroutine listed in "Numerical Recipies in C",
        !           227:  *   by Press, Flannery, Teukoilsky and Vetterling (1988).
        !           228:  *
        !           229:  */
        !           230: void free_vector(vec, nl, nh)
        !           231: float GPFAR *vec;
        !           232: int nl, nh;
        !           233: {
        !           234:     free(vec + nl);
        !           235: }
        !           236:
        !           237: /************ Routines to modify the length of a vector ****************/
        !           238: float GPFAR *
        !           239:  extend_vector(vec, old_nl, old_nh, new_nh)
        !           240: float GPFAR *vec;
        !           241: register int old_nl, old_nh, new_nh;
        !           242: {
        !           243:     register float GPFAR *new_v;
        !           244:     new_v = (float GPFAR *) gp_realloc((void *) (vec + old_nl),
        !           245:                   (unsigned long) (new_nh - old_nl + 1) * sizeof(float),
        !           246:                                       "extend vector");
        !           247:     return new_v - old_nl;
        !           248: }
        !           249:
        !           250: float GPFAR *
        !           251:  retract_vector(v, old_nl, old_nh, new_nh)
        !           252: float GPFAR *v;
        !           253: register int old_nl, old_nh, new_nh;
        !           254: {
        !           255:     register float GPFAR *new_v;
        !           256:     new_v = (float GPFAR *) gp_realloc((void *) (v + old_nl),
        !           257:                                       (unsigned long) (new_nh - old_nl + 1) * sizeof(float), "retract vector");
        !           258:     return new_v - old_nl;
        !           259: }
        !           260:
        !           261:
        !           262: /***************************** MATRIX ************************
        !           263:  *
        !           264:  *       The following routines work with matricies
        !           265:  *
        !           266:  *      I always get confused with this, so here I write it down:
        !           267:  *                       for nrl<= nri <=nrh and
        !           268:  *                       for ncl<= ncj <=nch
        !           269:  *
        !           270:  *   This matrix is accessed as:
        !           271:  *
        !           272:  *     matrix[nri][ncj];
        !           273:  *     where nri is the offset to the pointer to a vector where the
        !           274:  *     ncjth element lies.
        !           275:  *
        !           276:  *   If there is an error we don't really return - int_error breaks us out.
        !           277:  *
        !           278:  *   This subroutine based on a subroutine listed in "Numerical Recipies in C",
        !           279:  *   by Press, Flannery, Teukoilsky and Vetterling (1988).
        !           280:  *
        !           281:  */
        !           282: float
        !           283: GPFAR *GPFAR * matrix(nrl, nrh, ncl, nch)
        !           284: register int nrl, nrh, ncl, nch;
        !           285: {
        !           286:     register int i;
        !           287:     register float GPFAR *GPFAR * m;
        !           288:
        !           289:     m = (float GPFAR * GPFAR *) gp_alloc((unsigned long) (nrh - nrl + 1) * sizeof(float GPFAR *), "matrix");
        !           290:     m -= nrl;
        !           291:
        !           292:     for (i = nrl; i <= nrh; i++) {
        !           293:        if (!(m[i] = (float GPFAR *) gp_alloc((unsigned long) (nch - ncl + 1) * sizeof(float), NULL))) {
        !           294:            free_matrix(m, nrl, i - 1, ncl, nch);
        !           295:            int_error("not enough memory to create matrix", NO_CARET);
        !           296:            return NULL;
        !           297:        }
        !           298:        m[i] -= ncl;
        !           299:     }
        !           300:     return m;
        !           301: }
        !           302: /*
        !           303:  * Free a matrix allocated above
        !           304:  *
        !           305:  *
        !           306:  *   This subroutine based on a subroutine listed in "Numerical Recipies in C",
        !           307:  *   by Press, Flannery, Teukoilsky and Vetterling (1988).
        !           308:  *
        !           309:  */
        !           310: void free_matrix(m, nrl, nrh, ncl, nch)
        !           311: float GPFAR *GPFAR * m;
        !           312: unsigned nrl, nrh, ncl, nch;
        !           313: {
        !           314:     register unsigned int i;
        !           315:
        !           316:     for (i = nrl; i <= nrh; i++)
        !           317:        free((char GPFAR *) (m[i] + ncl));
        !           318:     free((char GPFAR *) (m + nrl));
        !           319: }
        !           320:
        !           321: /*
        !           322:    This routine takes a sub matrix and extends the number of rows and
        !           323:    columns for a new matrix
        !           324:  */
        !           325: float GPFAR *GPFAR * extend_matrix(a, nrl, nrh, ncl, nch, srh, sch)
        !           326: register float GPFAR *GPFAR * a;
        !           327: register int nrl, nrh, ncl, nch;
        !           328: register int srh, sch;
        !           329: {
        !           330:     register int i;
        !           331:     register float GPFAR *GPFAR * m;
        !           332:
        !           333:     m = (float GPFAR * GPFAR *) gp_realloc((void *) (a + nrl), (unsigned long) (srh - nrl + 1) * sizeof(float GPFAR *), "extend matrix");
        !           334:
        !           335:     m -= nrl;
        !           336:
        !           337:     if (sch != nch) {
        !           338:        for (i = nrl; i <= nrh; i++) {  /* Copy and extend rows */
        !           339:            if (!(m[i] = extend_vector(m[i], ncl, nch, sch))) {
        !           340:                free_matrix(m, nrl, nrh, ncl, sch);
        !           341:                int_error("not enough memory to extend matrix", NO_CARET);
        !           342:                return NULL;
        !           343:            }
        !           344:        }
        !           345:     }
        !           346:     for (i = nrh + 1; i <= srh; i++) {
        !           347:        if (!(m[i] = (float GPFAR *) gp_alloc((unsigned long) (nch - ncl + 1) * sizeof(float), NULL))) {
        !           348:            free_matrix(m, nrl, i - 1, nrl, sch);
        !           349:            int_error("not enough memory to extend matrix", NO_CARET);
        !           350:            return NULL;
        !           351:        }
        !           352:        m[i] -= ncl;
        !           353:     }
        !           354:     return m;
        !           355: }
        !           356: /*
        !           357:    this routine carves a large matrix down to size
        !           358:  */
        !           359: float GPFAR *GPFAR * retract_matrix(a, nrl, nrh, ncl, nch, srh, sch)
        !           360: register float GPFAR *GPFAR * a;
        !           361: register int nrl, nrh, ncl, nch;
        !           362: register int srh, sch;
        !           363: {
        !           364:     register int i;
        !           365:     register float GPFAR *GPFAR * m;
        !           366:
        !           367:     for (i = srh + 1; i <= nrh; i++) {
        !           368:        free_vector(a[i], ncl, nch);
        !           369:     }
        !           370:
        !           371:     m = (float GPFAR * GPFAR *) gp_realloc((void *) (a + nrl), (unsigned long) (srh - nrl + 1) * sizeof(float GPFAR *), "retract matrix");
        !           372:
        !           373:     m -= nrl;
        !           374:
        !           375:     if (sch != nch) {
        !           376:        for (i = nrl; i <= srh; i++)
        !           377:            if (!(m[i] = retract_vector(m[i], ncl, nch, sch))) { {      /* Shrink rows */
        !           378:                    free_matrix(m, nrl, srh, ncl, sch);
        !           379:                    int_error("not enough memory to retract matrix", NO_CARET);
        !           380:                    return NULL;
        !           381:            }
        !           382:            }
        !           383:     }
        !           384:     return m;
        !           385: }
        !           386:
        !           387: float
        !           388: GPFAR *GPFAR * convert_matrix(a, nrl, nrh, ncl, nch)
        !           389: float GPFAR *a;
        !           390: register int nrl, nrh, ncl, nch;
        !           391:
        !           392: /* allocate a float matrix m[nrl...nrh][ncl...nch] that points to the
        !           393:    matrix declared in the standard C manner as a[nrow][ncol], where
        !           394:    nrow=nrh-nrl+1, ncol=nch-ncl+1.  The routine should be called with
        !           395:    the address &a[0][0] as the first argument.  This routine does
        !           396:    not free the memory used by the original array a but merely assigns
        !           397:    pointers to the rows. */
        !           398:
        !           399: {
        !           400:     register int i, j, ncol, nrow;
        !           401:     register float GPFAR *GPFAR * m;
        !           402:
        !           403:     nrow = nrh - nrl + 1;
        !           404:     ncol = nch - ncl + 1;
        !           405:     m = (float GPFAR * GPFAR *) gp_alloc((unsigned long) (nrh - nrl + 1) * sizeof(float GPFAR *), "convert_matrix");
        !           406:     m -= nrl;
        !           407:
        !           408:     m[nrl] = a - ncl;
        !           409:     for (i = 1, j = nrl + 1; i <= nrow - 1; i++, j++)
        !           410:        m[j] = m[j - 1] + ncol;
        !           411:     return m;
        !           412: }
        !           413:
        !           414:
        !           415: void free_convert_matrix(b, nrl, nrh, ncl, nch)
        !           416: float GPFAR *GPFAR * b;
        !           417: register int nrl, nrh, ncl, nch;
        !           418: {
        !           419:     free((char *) (b + nrl));
        !           420: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>