/* common.c: */ #include #include "pnm_private.h" #include "common.h" #include "pools.h" /* reads one symbol from fp. If this symbol is a space, the function * returns 0, if it is not, it returns non-zero: used to skip one space * before reading raw ppm, pgm, pbm data */ int skip_one_space(FILE *fp) { #ifdef DDEBUG fprintf(stderr, "\nskip_one_space:\n"); #endif /*DDEBUG*/ if (isspace(myfgetc(fp))) return 0; PnmError( #ifdef DEBUG "skip_one_space", #else NULL, #endif "Input is not valid"); return 1; } /* skips characters up to and including the first newline */ void skip_until_eol(FILE *fp) { int c; #ifdef DDEBUG fprintf(stderr, "\nskip_until_eol:\n"); #endif /*DDEBUG*/ while ((c = myfgetc(fp)) != '\n') {} } /* skips spaces and comments - does nothing if the first read character is * not a space or a '#'. */ void skipspace(FILE *fp) { int c; #ifdef DDEBUG fprintf(stderr, "\nskipspace:\n"); #endif /*DDEBUG*/ while (isspace(c = myfgetc(fp))) {} if (c == '#') { /* skip comment */ skip_until_eol(fp); skipspace(fp); } else myungetc(c, fp); } /* skips comments: if the first symbol read is a '#' all following symbols * up to and including the next newline character are skipped. If not, * nothing happens. */ void skip_comment(FILE *fp) { int c; #ifdef DDEBUG fprintf(stderr, "\nskip_comment:\n"); #endif /*DDEBUG*/ if ((c = myfgetc(fp)) == '#') skip_until_eol(fp); else myungetc(c,fp); } /* reads a series of successive digits until a non-digit is encountered, * converts the digits to number, returns that (non negative) number. * returns negative if the first read symbol is not a digit. */ unsigned int getnatural(FILE *fp) { int c; unsigned int num = 0; #ifdef DDEBUG fprintf(stderr, "\ngetnatural:\n"); #endif /*DDEBUG*/ if (!isdigit(c = myfgetc(fp))) { PnmError( #ifdef DEBUG "getnatural", #else NULL, #endif "Input is not valid"); return -1; } while (isdigit(c)) { num *= 10; num += (c - '0'); c = myfgetc(fp); } myungetc(c, fp); return num; } /* * returns 1 if reading a '0' (white) * 0 '1' (black) * negative something else */ CVAL getbit(FILE *fp) { #ifdef DDEBUG fprintf(stderr, "\ngetbit:\n"); #endif /*DDEBUG*/ switch (myfgetc(fp)) { case '0': return 1; case '1': return 0; default: PnmError( #ifdef DEBUG "getbit", #else NULL, #endif "Input is not valid"); } return -1; } /* round a up to an integer multiple of b */ #define up_mult(a, b) (b*((a+b-1)/b)) /* allocates space to hold the graphics data: nr. of channels, height and * width as specified in the IMAGE struct - returns zero if succesful, * nonzero otherwise. */ int AllocPixmap(IMAGE *pnm) { int chan, row, col, pad_height, pad_width; #ifdef DEBUG fprintf(stderr, "AllocPixmap: pnm->nrchannels = %ld, pnm->height = %ld, pnm->width = %ld\n", pnm->nrchannels, pnm->height, pnm->width); #endif /*DEBUG*/ pad_height = up_mult(pnm->height, PAD_SIZE); pad_width = up_mult(pnm->width, PAD_SIZE); pnm->pix = (CVAL ***)Alloc(pnm->nrchannels * sizeof(CVAL **)); for (chan=0; chan < pnm->nrchannels; chan++) { pnm->pix[chan] = (CVAL **)Alloc(pad_height * sizeof(CVAL *)); for (row=0; row < pad_height; row++) { pnm->pix[chan][row] = (CVAL *)Alloc(pad_width * sizeof(CVAL)); /* clear to zeroes */ for (col = 0; col < pad_width; col++) pnm->pix[chan][row][col] = 0; } } return 0; } /* deallocates the storage allocated for the image */ void PnmFree(IMAGE *pnm) { int chan, row, col, pad_height, pad_width; pad_height = up_mult(pnm->height, PAD_SIZE); pad_width = up_mult(pnm->width, PAD_SIZE); for (chan=0; chan < pnm->nrchannels; chan++) { for (row=0; row < pad_height; row++) { Free((char *)(pnm->pix[chan][row]), pad_width * sizeof(CVAL)); } Free((char *)(pnm->pix[chan]), pad_height * sizeof(CVAL *)); } Free((char *)(pnm->pix), pnm->nrchannels * sizeof(CVAL **)); Free((char *)pnm, sizeof(IMAGE)); }