#include #include #include /* #define DEBUG 1 */ /* * WROWD * subroutine takes double array BUF & writes a row of * either bit, byte, short, long, float, or double pixels * to the file descriptor FD using the parameters * found in the CVL header AREA. * Returns 1 on success, -1 on error. * Partial reads after retries are treated as errors. * Alters a zero value in the optional bits/band field of AREA. * The optional CVL header exponent bit fields are only used * to distinguish floating and integral values of the same size; * otherwise, if the bits per pixel fields match an allowable * input pixel type then that type is used with further checks. * cc -c -O wrowd.c * Written by Robert L. Kirby, U. of Md. CVL, August 4, 1983 * with modifications by Diane Donaldson and Chris Welsh. * * Modified 04/07/87 for switching on cv_bp rather than cv_bb, better error * handling/messages and diagnostics, Joe Sanjour */ char *malloc(); int wrowd (fd, buf, area) int fd; /* Input file descriptor */ double *buf; /* Buffer to receive converted values */ struct cvl_p *area; { int nbytes; /* Bytes per input row */ register int icnt; /* Data items in row */ register double *obp = buf; /* Output buffer pointer */ icnt = area->cv_cols; /* use thead() to check header for inconsistencies */ switch(thead(area,1)) { case 1: { fprintf(stderr,"wrowd: inconsistencies found in header, fixed\n"); break; } case -1: { fprintf(stderr,"wrowd: inconsistencies found in header, unfixable\n"); return(-1); } #ifdef DEBUG case 0: { fprintf(stderr,"wrowd: header okay\n"); break; } default: { fprintf(stderr,"wrowd: thead is being wierd\n"); break; } #endif DEBUG } /* end switch */ if((nbytes = (area->cv_cols * area->cv_bp + BYTEBITS - 1)/ BYTEBITS) == 0) /* Bytes per row */ { fprintf(stderr,"wrowd: error, bits per pixel = 0 ???\n"); return (-1); } #ifdef DEBUG fprintf(stderr,"wrowd: %d bytes per row\n",nbytes); #endif DEBUG switch(area->cv_bp) { case 1: { char *ibuf; /* Character buffer of packed pixels */ register char *bp; int mask = 0; /* bit mask for packed binary values */ int i = BYTEBITS; if ((ibuf = malloc((icnt+BYTEBITS-1)/sizeof(char)))==(char *)-1) { fprintf(stderr,"wrowd: core allocation error"); return(-1); } bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *bp++ = mask; mask = 0; } else mask >>= 1; if (*obp++) mask |= 1 << (BYTEBITS); } while (--icnt); mask >>= (i + 1); *bp++ = mask; if (write(fd,ibuf,nbytes) == nbytes) { free(ibuf); return(1); } else { free(ibuf); fprintf(stderr,"wrowd: write error"); return(-1); } } #if BYTEBITS != SHORTBITS case BYTEBITS: { /* Character buffer */ char *ibuf; register char *bp; if ((ibuf = malloc(icnt*sizeof(char)))== (char *)-1) { fprintf(stderr,"wrowd: core allocation error"); return(-1); } bp = ibuf; if(!area->cv_sbp || area->cv_sbp == area->cv_bp) do { /* Unsigned pixel values */ *bp = (char) *obp & ((1 << BYTEBITS) -1); *bp++; *obp++; } while (--icnt > 0); else do { *bp++ = *obp++; } while (--icnt > 0); if (write(fd,ibuf,nbytes) == nbytes) { free(ibuf); return(1); } else { free(ibuf); fprintf(stderr,"wrowd: write error"); return(-1); } } #endif #if SHORTBITS != LONGBITS case SHORTBITS: { short *ibuf; register short *bp; if ((ibuf = (short *)malloc(icnt*sizeof(short)))==(short *) -1) { fprintf(stderr,"wrowd: core allocation error"); return(-1); } bp = ibuf; if(!area->cv_sbp || area->cv_sbp == area->cv_bp) do { /* Unsigned pixel values */ *bp = (short) *obp & ((1L << SHORTBITS) -1); *bp++; *obp++; } while (--icnt > 0); else do { /* Signed pixel values */ *bp++ = *obp++; } while (--icnt > 0); if (write(fd,(char *)ibuf,nbytes) == nbytes) { free((char *)ibuf); return(1); } else { free((char *)ibuf); fprintf(stderr,"wrowd: write error"); return(-1); } } #endif #if LONGBITS == DOUBLEBITS case LONGBITS: if(area->cv_ebp == 0 && area->cv_ebb == 0) { long *ibuf; register long *bp; if((ibuf = (long *)malloc(icnt*sizeof(long)))==(long *) -1) { fprintf(stderr,"wrowd: core allocation error"); return(-1); } bp = ibuf; do { *bp++ = *obp++; } while (--icnt > 0); if (write(fd,(char *)ibuf,nbytes) == nbytes) { free((char *)ibuf); return(1); } else { free((char *)ibuf); fprintf(stderr,"wrowd: write error"); return(-1); } } else /* Use doubles as is */ break; #if FLOATBITS != DOUBLEBITS case FLOATBITS: { float *ibuf; register float *bp; if ((ibuf = (float *)malloc(icnt*sizeof(float)))==(float *) -1) { fprintf(stderr,"wrowd: core allocation error"); return(-1); } bp = ibuf; do { *bp++ = obp++; } while (--icnt > 0); if (write(fd,(char *)ibuf,nbytes) == nbytes) { free((char *)ibuf); return(1); } else { free((char *)ibuf); fprintf(stderr,"wrowd: write error"); return(-1); } } #endif #else #if LONGBITS == FLOATBITS case LONGBITS: if(area->cv_ebp == 0 && area->cv_ebb == 0) { long *ibuf; register long *bp; if ((ibuf = (long *)malloc(icnt*sizeof(long)))==(long *) -1) { fprintf(stderr,"wrowd: core allocation error"); return(-1); } bp = ibuf; do { *bp++ = *obp++; } while (--icnt > 0); if (write(fd,(char *)ibuf,nbytes) == nbytes) { free((char *)ibuf); return(1); } else { free((char *)ibuf); fprintf(stderr,"wrowd: write error"); return(-1); } } else { float *ibuf; register float *bp; if ((ibuf = (float *)malloc(icnt*sizeof(float)))==(float *) -1) { fprintf(stderr,"wrowd: core allocation error"); return(-1); } bp = ibuf; do { *bp++ = *obp++; } while (--icnt > 0); if (write(fd,(char *)ibuf,nbytes) == nbytes) { free((char *)ibuf); return(1); } else { free((char *)ibuf); fprintf(stderr,"wrowd: write error"); return(-1); } } #else case LONGBITS: { long *ibuf; register long *bp; if ((ibuf = (long *) malloc(icnt*sizeof(long)))==(long *) -1) { fprintf(stderr,"wrowd: core allocation error"); return(-1); } bp = ibuf; do { *bp++ = *obp++; } while (--icnt > 0); if (write(fd,(char *)ibuf,nbytes) == nbytes) { free((char *)ibuf); return(1); } else { free((char *)ibuf); fprintf(stderr,"wrowd: write error"); return(-1); } } #if FLOATBITS != DOUBLEBITS case FLOATBITS: { float *ibuf; register float *bp; if ((ibuf = (float *)malloc(icnt*sizeof(float)))==(float *) -1) { fprintf(stderr,"wrowd: core allocation error"); return(-1); } bp = ibuf; do { *bp++ = *obp++; } while (--icnt > 0); if (write(fd,(char *)ibuf,nbytes) == nbytes) { free((char *)ibuf); return(1); } else { free((char *)ibuf); fprintf(stderr,"wrowd: write error"); return(-1); } } #endif #endif #endif case DOUBLEBITS: /* Otherwise use doubles as is */ break; #include "newdefault" } if (write (fd, (char *) buf, nbytes) == nbytes) return(1); else { fprintf(stderr,"wrowd: write error"); return(-1); } }