#include #include #include /* #define DEBUG 1 */ /* * RROW16 * subroutine reads a row of either bit, byte, short, long, * float, or double pixels into an unsigned short 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 rrow16.c * Written by Robert L. Kirby, U. of Md. CVL, August 4, 1983 * with modifications by Diane Donaldson and Chris Welsh. * * Modified 05/20/87 for switching on cv_bp rather than cv_bb, better error * handling/messages and diagnostics, Joe Sanjour */ int rrow16 (fd, buf, area) int fd; /* Input file descriptor */ unsigned short *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 unsigned short *obp = buf; /* Output buffer pointer */ icnt = area->cv_cols; /* use thead() to check header for inconsistencies */ switch(thead(area,1)) { case 1: { fprintf(stderr,"rrow16: inconsistencies found in header, fixed\n"); break; } case -1: { fprintf(stderr,"rrow16: inconsistencies found in header, unfixable\n"); return(-1); } #ifdef DEBUG case 0: { fprintf(stderr,"rrow16: header okay\n"); break; } default: { fprintf(stderr,"rrow16: thead is being wierd\n"); break; } #endif DEBUG } /* end switch */ if (area->cv_bb <= SHORTBITS) { if((nbytes = (area->cv_cols * area->cv_bp + BYTEBITS - 1) / BYTEBITS) == 0) /* Bytes per row */ { fprintf(stderr,"rrow16: error, bits per pixel = 0 ???\n"); return(-1); } #ifdef DEBUG fprintf(stderr,"rrow16: %d bytes per row\n",nbytes); #endif DEBUG if((bcnt = readp(fd, (char *) buf, nbytes)) == nbytes) { /* start after last pixel then go backward */ obp += icnt; switch(area->cv_bp) { case 1: { /* Character buffer of packed pixels */ register char *bp = ((char *) buf) + icnt / BYTEBITS; /* bit mask for packed binary values */ register mask = 1 << (icnt % BYTEBITS); do { if ((mask >>= 1) == 0) { mask = 1 << (BYTEBITS -1); bp--; } *--obp = ( *bp & mask) != 0; } while (--icnt); return(1); } #if BYTEBITS != SHORTBITS case BYTEBITS: { /* Character buffer */ register char *bp = ((char *) buf) + icnt; if(!area->cv_sbp || area->cv_sbp == area->cv_bp) do { /* Unsigned pixel values */ *--obp = *--bp & ((1 << BYTEBITS) -1); } while (--icnt > 0); else do { /* Signed pixel values */ *--obp = *--bp; } while (--icnt > 0); return(1); } #endif #if SHORTBITS == FLOATBITS case FLOATBITS: if (area->cv_ebp != 0 || area->cv_ebb != 0) { /* After last value and boing backward */ register float *bp = ((float *) buf) + icnt; do { *--obp = *--bp; } while (--icnt > 0); return(1); } /* Otherwise take shorts as is */ return(1); #endif case SHORTBITS: if(!area->cv_sbp || area->cv_sbp == area->cv_bp) return(1); else { /* After last value and going backward */ register short *bp = ((short *) buf) + icnt; do { /* Signed pixel values */ *--obp = *--bp; } while (--icnt > 0); return(1); } default: { fprintf(stderr,"rrow16: error, bits per pixel = %d\n",area->cv_bp); return(-1); } } } } else switch(area->cv_bp) { #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; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) 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; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) 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; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) 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; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) 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; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) return(1); } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #if FLOATBITS > SHORTBITS case FLOATBITS: { /* Buffer for values bigger than requested */ float ibuf[IBUFSIZE / sizeof (float)]; /* Fetch pixel values cycling forward thru buffer */ register float *bp = ibuf; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) return(1); } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #endif #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; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) return(1); } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #if FLOATBITS > SHORTBITS case FLOATBITS: { /* Buffer for values bigger than requested */ float ibuf[IBUFSIZE / sizeof (float)]; /* Fetch pixel values cycling forward thru buffer */ register float *bp = ibuf; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) 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; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) return(1); } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #endif #endif #endif #endif #else #if FLOATBITS > SHORTBITS case FLOATBITS: { /* Buffer for values bigger than requested */ float ibuf[IBUFSIZE / sizeof (float)]; /* Fetch pixel values cycling forward thru buffer */ register float *bp = ibuf; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) 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; 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,"rrow16: partial read\n"); return(-1); } break; } bp = ibuf; do { *obp++ = *bp++; if(--icnt == 0) return(1); } while (bp < ibuf + IBUFSIZE / sizeof *ibuf); } } #endif #endif #endif } if (bcnt == 0) return(0); /* end of input file */ else { fprintf(stderr,"rrow16: read errors\n"); return(-1); /* read errors */ } }