#include #include #include /* #define DEBUG 1 */ /* * RROWB * subroutine reads a row of either bit, byte, short, long, * float, or double pixels, packing 8 pixels into * each member of the character array BUF * from the file descriptor FD using the parameters * found in the CVL header AREA. * Returns 1 on success, 0 on end-of-file, -1 on error. * Partial reads after retries are treated as errors. * Alters a zero value in the optional bits/band field of AREA. * Calls READP to avoid pipe shortchanging on reads. * 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 rrowb.c * Written by Diane Donaldson, U. of Md. CVL, December 12, 1983. * * Modified 05/15/87 for switching on cv_bp rather than cv_bb, better error * handling/messages and diagnostics, Joe Sanjour */ int rrowb (fd, buf, area) int fd; /* Input file descriptor */ char *buf; /* Buffer to receive converted values */ struct cvl_p *area; { int bcnt; /* Bytes read */ int nbytes; /* Bytes per input row */ register int icnt; /* Data items in row */ register char *obp = buf; /* Output buffer pointer */ icnt = area->cv_cols; /* use thead() to check header for inconsistencies */ switch(thead(area,1)) { case 1: { fprintf(stderr,"rrowb: inconsistencies found in header, fixed\n"); break; } case -1: { fprintf(stderr,"rrowb: inconsistencies found in header, unfixable\n"); return(-1); } #ifdef DEBUG case 0: { fprintf(stderr,"rrowb: header okay\n"); break; } default: { fprintf(stderr,"rrowb: 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,"rrowb: error, bits per pixel = 0 ???\n"); return(-1); } #ifdef DEBUG fprintf(stderr,"rrowb: %d bytes per row\n",nbytes); #endif DEBUG switch(area->cv_bp) { case 1: if ((bcnt = readp(fd,buf,nbytes)) == nbytes) return(1); break; case BYTEBITS: { /* Buffer for values bigger than requested */ char ibuf[IBUFSIZE/sizeof(char)]; /* Fetch pixel values cycling forward thru buffer */ register char *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #if SHORTBITS > BYTEBITS case SHORTBITS: { /* Buffer for values bigger than requested */ short ibuf[IBUFSIZE/sizeof(short)]; /* Fetch pixel values cycling forward thru buffer */ register short *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #endif #if LONGBITS > BYTEBITS #if LONGBITS != SHORTBITS #if LONGBITS == FLOATBITS case LONGBITS: if (area->cv_ebp == 0 && area->cv_ebb == 0) { /* Buffer for values bigger than requested */ long ibuf[IBUFSIZE/sizeof(long)]; /* Fetch pixel values cycling forward thru buffer */ register long *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } else { /* Buffer for values bigger than requested */ float ibuf[IBUFSIZE/sizeof(float)]; /* Fetch pixel values cycling forward thru buffer */ register float *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #if FLOATBITS != DOUBLEBITS case DOUBLEBITS: { /* Buffer for values bigger than requested */ double ibuf[IBUFSIZE/sizeof(double)]; /* Fetch pixel values cycling forward thru buffer */ register double *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #endif #else #if LONGBITS == DOUBLEBITS case LONGBITS: if (area->cv_ebp == 0 && area->cv_ebb == 0) { /* Buffer for values bigger than requested */ long ibuf[IBUFSIZE/sizeof(long)]; /* Fetch pixel values cycling forward thru buffer */ register long *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } else { /* Buffer for values bigger than requested */ double ibuf[IBUFSIZE/sizeof(double)]; /* Fetch pixel values cycling forward thru buffer */ register double *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } case FLOATBITS: { /* Buffer for values bigger than requested */ float ibuf[IBUFSIZE/sizeof(float)]; /* Fetch pixel values cycling forward thru buffer */ register float *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #else case LONGBITS: { /* Buffer for values bigger than requested */ long ibuf[IBUFSIZE/sizeof(long)]; /* Fetch pixel values cycling forward thru buffer */ register long *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } case FLOATBITS: { /* Buffer for values bigger than requested */ float ibuf[IBUFSIZE/sizeof(float)]; /* Fetch pixel values cycling forward thru buffer */ register float *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #if DOUBLEBITS != FLOATBITS case DOUBLEBITS: { /* Buffer for values bigger than requested */ double ibuf[IBUFSIZE/sizeof(double)]; /* Fetch pixel values cycling forward thru buffer */ register double *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #endif #endif #endif #endif #else case FLOATBITS: { /* Buffer for values bigger than requested */ float ibuf[IBUFSIZE/sizeof(float)]; /* Fetch pixel values cycling forward thru buffer */ register float *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #if FLOATBITS != DOUBLEBITS case DOUBLEBITS: { /* Buffer for values bigger than requested */ double ibuf[IBUFSIZE/sizeof(double)]; /* Fetch pixel values cycling forward thru buffer */ register double *bp = ibuf; int mask; int i = BYTEBITS; for (;;) { nbytes = icnt >= IBUFSIZE / sizeof *ibuf? sizeof ibuf : icnt * sizeof *ibuf; if ((bcnt = readp(fd, (char *) ibuf, nbytes)) != nbytes) { if (bp != ibuf) { /* Only a partial read */ fprintf(stderr,"rrowb: partial read\n"); return(-1); } break; } mask = 0; bp = ibuf; do { if (--i < 0) { i = BYTEBITS - 1; mask >>= 1; *obp++ = mask; mask = 0; } else mask >>= 1; if (*bp++) mask |= (1 << BYTEBITS); if (--icnt == 0) { mask >>= (i + 1); *obp++ = mask; return(1); } } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #endif #endif } if (bcnt == 0) return(0); /* end of input file */ else { fprintf(stderr,"rrowb: read errors\n"); return(-1); /* read errors */ } }