#include #include #include /* #define DEBUG 1 */ /* * WROWL * subroutine takes long 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 wrowl.c * Written by Robert L. Kirby, U. of Md. CVL, August 4, 1983 * with modifications by Diane Donaldson and Chris Welsh. * * Modified 04/22/87 for switching on cv_bp rather than cv_bb, better error * handling/messages and diagnostics, Joe Sanjour */ char *malloc(); int wrowl (fd, buf, area) int fd; /* Input file descriptor */ long *buf; /* Buffer to receive converted values */ struct cvl_p *area; { int nbytes; /* Bytes per input row */ register int icnt; /* Data items in row */ register long *obp = buf; /* Output buffer pointer */ icnt = area->cv_cols; /* use thead() to check header for inconsistencies */ switch(thead(area,1)) { case 1: { fprintf(stderr,"wrowl: inconsistencies found in header, fixed\n"); break; } case -1: { fprintf(stderr,"wrowl: inconsistencies found in header, unfixable\n"); return(-1); } #ifdef DEBUG case 0: { fprintf(stderr,"wrowl: header okay\n"); break; } default: { fprintf(stderr,"wrowl: 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,"wrowl: error, bits per pixel = 0 ???\n"); return(-1); } #ifdef DEBUG fprintf(stderr,"wrowl: %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,"wrowl: 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,"wrowl: 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,"wrowl: 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,"wrowl: 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,"wrowl: 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,"wrowl: write error"); return(-1); } } #endif #if LONGBITS == DOUBLEBITS case DOUBLEBITS: if(area->cv_ebp != 0 || area->cv_ebb != 0) { double *ibuf; register double *bp; if ((ibuf=(double *)malloc(icnt*sizeof(double)))==(double *)-1) { fprintf(stderr,"wrowl: 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,"wrowl: write error"); return(-1); } } else /* Use longs as is */ break; #if FLOATBITS != DOUBLEBITS case FLOATBITS: { float *ibuf; register float *bp; if ((ibuf=(float *)malloc(icnt*sizeof(float)))==(float *)-1) { fprintf(stderr,"wrowl: 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,"wrowl: write error"); return(-1); } } #endif #else #if LONGBITS == FLOATBITS case FLOATBITS: if(area->cv_ebp != 0 || area->cv_ebb != 0) { float *ibuf; register float *bp; if ((ibuf=(float *)malloc(icnt*sizeof(float)))==(float *)-1) { fprintf(stderr,"wrowl: 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,"wrowl: write error"); return(-1); } } else /* Use floats as is */ break; case DOUBLEBITS: { double *ibuf; register double *bp; if ((ibuf=(double *)malloc(icnt*sizeof(double)))==(double *)-1) { fprintf(stderr,"wrowl: 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,"wrowl: write error"); return(-1); } } #else case LONGBITS: /* Otherwise use longs as is */ break; case FLOATBITS: { float *ibuf; register float *bp; if ((ibuf = (float *)malloc(icnt*sizeof(float)))==(float *) -1) { fprintf(stderr,"wrowl: 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,"wrowl: write error"); return(-1); } } #if FLOATBITS != DOUBLEBITS case DOUBLEBITS: { double *ibuf; register double *bp; if ((ibuf=(double *)malloc(icnt*sizeof(double)))==(double *)-1) { fprintf(stderr,"wrowl: 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,"wrowl: write error"); return(-1); } } #endif #endif #endif default: fprintf(stderr,"wrowl: error, bits per pixel = %d\n",area->cv_bp); return(-1); } if (write (fd, (char *) buf, nbytes) == nbytes) return(1); else { fprintf(stderr,"wrowl: write error"); return(-1); } }