#ifndef PBM_H_INCLUDED #define PBM_H_INCLUDED #include #ifdef __cplusplus extern "C" { #endif #if 0 } /* to fake out automatic code indenters */ #endif typedef unsigned char bit; #define PBM_WHITE 0 #define PBM_BLACK 1 /* Magic constants. */ #define PBM_MAGIC1 'P' #define PBM_MAGIC2 '1' #define RPBM_MAGIC2 '4' #define PBM_FORMAT (PBM_MAGIC1 * 256 + PBM_MAGIC2) #define RPBM_FORMAT (PBM_MAGIC1 * 256 + RPBM_MAGIC2) #define PBM_TYPE PBM_FORMAT /* Macro for turning a format number into a type number. */ #define PBM_FORMAT_TYPE(f) \ ((f) == PBM_FORMAT || (f) == RPBM_FORMAT ? PBM_TYPE : -1) /* Declarations of routines. */ void pbm_init(int * const argcP, char ** const argv); void pbm_nextimage(FILE *file, int * const eofP); bit * pbm_allocrow(unsigned int const cols); #define pbm_allocarray(cols, rows) \ ((bit**) pm_allocarray(cols, rows, sizeof(bit))) #define pbm_freearray(bits, rows) pm_freearray((char**) bits, rows) #define pbm_freerow(bitrow) pm_freerow((char*) bitrow) /* Beware of arithmetic overflows when using pbm_packed_bytes(), pbm_allocrow_packed() and pbm_allocarray_packed(). When cols is signed int, pbm_packed_bytes(cols + 8) overflows with large values. Same with pamP->width which is always signed int. Function validateComputableSize() called by pbm_readpbminit() provides a margin of 10, but the "+7" uses much of it. To prevent overflows, cast cols or pamP->width to unsigned int like this: pbm_packed_bytes((unsigned int) cols +8)) */ #define pbm_packed_bytes(cols) (((cols)+7)/8) #define pbm_allocrow_packed(cols) \ ((unsigned char *) pm_allocrow(pbm_packed_bytes(cols), \ sizeof(unsigned char))) #define pbm_freerow_packed(packed_bits) \ pm_freerow((char *) packed_bits) #define pbm_allocarray_packed(cols, rows) ((unsigned char **) \ pm_allocarray(pbm_packed_bytes(cols), rows, sizeof(unsigned char))) #define pbm_freearray_packed(packed_bits, rows) \ pm_freearray((char **) packed_bits, rows) bit** pbm_readpbm(FILE * const file, int * const colsP, int * const rowsP); void pbm_readpbminit(FILE * const file, int * const colsP, int * const rowsP, int * const formatP); void pbm_readpbmrow(FILE * const file, bit * const bitrow, int const cols, int const format); void pbm_readpbmrow_packed(FILE * const file, unsigned char * const packedBits, int const cols, int const format); void pbm_readpbmrow_bitoffset(FILE * const fileP, unsigned char * const packedBits, int const cols, int const format, unsigned int const offset); void pbm_cleanrowend_packed(unsigned char * const packedBits, unsigned int const cols); void pbm_writepbminit(FILE * const fileP, int const cols, int const rows, int const forceplain); void pbm_writepbm(FILE * const fileP, bit ** const bits, int const cols, int const rows, int const forceplain); void pbm_writepbmrow(FILE * const fileP, const bit * const bitrow, int const cols, int const forceplain); void pbm_writepbmrow_packed(FILE * const fileP, const unsigned char * const packed_bits, int const cols, int const forceplain); void pbm_writepbmrow_bitoffset(FILE * const ifP, unsigned char * const packedBits, unsigned int const cols, int const format, unsigned int const offset); void pbm_check(FILE * file, const enum pm_check_type check_type, const int format, const int cols, const int rows, enum pm_check_code * const retval_p); bit pbm_backgroundbitrow(const unsigned char * const packedBits, unsigned int const cols, unsigned int const offset); #ifdef __cplusplus } #endif #endif