📄 pbm.c
字号:
/* * -*- Mode: ANSI C -*- * $Id: pbm.c,v 1.4 1996/09/17 16:10:28 fernande Exp $ * $Source: /sgi.acct/sweldens/cvs/liftpack/Files/pbm.c,v $ * Author: Gabriel Fernandez * * Routines to manipulate 'p?m' format pictures. * LoadPBM ( filename, image ) - loads a PBM, PGM, or PPM file. * WritePBM ( fp, pic, w, h, style, raw, cmt, comment ); *//* do not edit anything above this line *//* System header files */#include <string.h>/* FLWT header files */#include <flwterr.h>#include <file.h>#include <imgmem.h>#include <memchk.h>#include <pbm.h>#include <util.h>/* * Comments on error handling: * A truncated file is not considered a Major Error. The file is * loaded, the rest of the pic is filled with 0's. * * A file with garbage characters in it is an unloadable file. All * allocated stuff is tossed, and LoadPBM returns non-zero. * * Not being able to malloc is a Fatal Error. The program is aborted. */#define TRUNCSTR "File appears to be truncated.\n"/* Static variables */static int garbage;static long numgot, filesize;/* Static functions declarations */static int loadpbm (FILE *, Image *, int);static int loadpgm (FILE *, Image *, int, int);static int loadppm (FILE *, Image *, int, int);static int getint (FILE *, Image *);static int getbit (FILE *, Image *);static int getshort (FILE *);/* code *//* * LoadPBM function: loads a PNM file. Returns '1' on success. */intLoadPBM ( const char *filename, Image *image ){ FILE *fp; int c, c1; int maxv, rv; garbage = maxv = rv = 0; image->band[RED] = (Matrix)NULL; image->band[GREEN] = (Matrix)NULL; image->band[BLUE] = (Matrix)NULL; image->comment = (char *)NULL; image->levels = (int *)NULL; /* Open the file */ fp = OpenFile (filename, "r"); /* Compute file length */ fseek (fp, 0L, 2); filesize = ftell(fp); fseek (fp, 0L, 0); /* Read the first two bytes of the file to determine which format this file is. "P1" = ascii bitmap, "P2" = ascii greymap, "P3" = ascii pixmap, "P4" = raw bitmap, "P5" = raw greymap, "P6" = raw pixmap */ c = getc(fp); c1 = getc(fp); if (c!='P' || c1<'1' || c1>'6') { Error ("LoadPBM", CUSTOM, RETURN, "Invalid magic number.\n"); return 0; } /* Read in header information */ image->width = getint(fp, image); image->height = getint(fp, image); /* if we're not reading a bitmap, read the 'max value' */ if ( !(c1=='1' || c1=='4') ) { maxv = getint(fp, image); if ( maxv<1 ) garbage = 1; /* to avoid 'div by zero' probs */ } if (garbage) { fclose(fp); if (image->comment) free(image->comment); image->comment = (char *)NULL; Error ("LoadPBM", CUSTOM, RETURN, "Garbage characters in header.\n"); return 0; } if ( c1=='1' || c1=='2' || c1=='3' ) image->frmType = F_PBMASCII; else image->frmType = F_PBMRAW; /* Note: pic, band, bpp and colorPlanes fields of Image struct are filled in in the format-specific loaders */ /* Call the appropriate subroutine to handle format-specific stuff */ if ( c1=='1' || c1=='4' ) rv = loadpbm(fp, image, c1=='4' ? 1 : 0); else if ( c1=='2' || c1=='5' ) rv = loadpgm(fp, image, c1=='5' ? 1 : 0, maxv); else if ( c1=='3' || c1=='6' ) rv = loadppm(fp, image, c1=='6' ? 1 : 0, maxv); fclose(fp); if (!rv) { if (image->band[RED]) MEM_Free2D(image->band[RED]); if (image->band[GREEN]) MEM_Free2D(image->band[GREEN]); if (image->band[BLUE]) MEM_Free2D(image->band[BLUE]); if (image->comment) free(image->comment); image->band[RED] = (Matrix)NULL; image->band[GREEN] = (Matrix)NULL; image->band[BLUE] = (Matrix)NULL; image->comment = (char *)NULL; } return rv;} /* * loadpbm function: reads the PBM file pointed by fp. */static int loadpbm ( FILE *fp, Image *image, int raw ){ Vector pix; int i, j, bit, w, h, rv; /******************************/ /* Initialize image structure */ /******************************/ rv = (int)IMG_InitMem (image, (long)image->width, (long)image->height, 1, 1); if ( !rv ) { Error ("loadpbm", MEMORY_IMAGE, ABORT); /* NOTREACHED */ } image->colType = 2; /* B/W stipple */ w = image->width; h = image->height; sprintf(image->fullInfo, "PBM, %s format. (%ld bytes)", (raw) ? "raw" : "ascii", filesize); sprintf(image->shrtInfo, "%dx%d PBM.", w, h); if ( !raw ) { numgot = 0; for ( i=0, pix=image->band[GREY][0] ; i<h ; i++ ) { for ( j=0 ; j<w ; j++, pix++ ) *pix = (Flt)getbit(fp, image); } if ( numgot != (long)(w*h) ) Error ("loadpbm", CUSTOM, RETURN, TRUNCSTR); if (garbage) { Error ("loadpbm", CUSTOM, RETURN, "Garbage characters in image data."); return 0; } } else { /* read raw bits */ int trunc = 0, k = 0; for ( i=0, pix=image->band[GREY][0] ; i<h ; i++ ) { for ( j=0, bit=0 ; j<w ; j++, pix++, bit++ ) { bit &= 7; if ( !bit ) { k = getc(fp); if ( k==EOF ) { trunc = 1; k = 0; } } *pix = (k&0x80) ? (Flt)1 : (Flt)0; k = k << 1; } } if (trunc) Error ("loadpbm", CUSTOM, RETURN, TRUNCSTR); } return 1;}/* * loadpgm function: reads the PGM file pointed by fp. */static int loadpgm ( FILE *fp, Image *image, int raw, int maxv ){ Vector pixFlt; byte *pic8; int i, j, bitshift, w, h, holdmaxv, rv; /******************************/ /* Initialize image structure */ /******************************/ rv = (int)IMG_InitMem (image, (long)image->width, (long)image->height, 1, 8); if ( !rv ) { Error ("loadpgm", MEMORY_IMAGE, ABORT); /* NOTREACHED */ } image->colType = 1; /* Greyscale */ w = image->width; h = image->height; sprintf(image->fullInfo, "PGM, %s format. (%ld bytes)", (raw) ? "raw" : "ascii", filesize); sprintf(image->shrtInfo, "%dx%d PGM.", image->width, image->height); /* if maxv>255, keep dropping bits until it's reasonable */ holdmaxv = maxv; bitshift = 0; while ( maxv>255 ) { maxv = maxv>>1; bitshift++; } numgot = 0; if (!raw) { for ( i=0, pixFlt=image->band[GREY][0] ; i<h ; i++ ) { for ( j=0; j<w ; j++, pixFlt++ ) *pixFlt = (Flt) (getint(fp, image) >> bitshift); } } else { /* raw */ if ( holdmaxv>255 ) { for ( i=0, pixFlt=image->band[GREY][0] ; i<h ; i++ ) { for ( j=0 ; j<w ; j++, pixFlt++ ) *pixFlt = (Flt) (getshort(fp) >> bitshift); } } else { /* read raw data */ pic8 = (byte *) calloc((size_t)(w*h), (size_t)1); if ( !pic8 ) Error ("loadpgm", CALLOC_FAIL, ABORT); /* NOTREACHED */ numgot = (long)fread(pic8, (size_t)1, (size_t)(w*h), fp); for ( i=0, pixFlt=image->band[GREY][0] ; i<w*h ; i++, pixFlt++ ) *pixFlt = (Flt)pic8[i]; free (pic8); } } if ( numgot != (long)(w*h) ) { Error ("loadpgm", CUSTOM, RETURN, TRUNCSTR); /* warning only */ } if (garbage) { Error ("loadpgm", CUSTOM, RETURN, "Garbage characters in image data."); return 0; } return 1;}/* * loadppm function: reads the PPM file pointed by fp. */static int loadppm ( FILE *fp, Image *image, int raw, int maxv ){ byte *pix, *pic24; byte scale[256]; int i, j, bitshift, w, h, holdmaxv, rv; w = image->width; h = image->height; /* allocate 24-bit image */ pic24 = (byte *) calloc((size_t)(w*h*3), (size_t) 1); if ( !pic24 ) Error ("loadppm", CALLOC_FAIL, ABORT); /* NOTREACHED */ /******************************/ /* Initialize image structure */ /******************************/ rv = (int)IMG_InitMem (image, (long)image->width, (long)image->height, 3, 24); if ( !rv ) { Error ("loadppm", MEMORY_IMAGE, ABORT); /* NOTREACHED */ } image->colType = 0; /* Full Color */ sprintf(image->fullInfo, "PPM, %s format. (%ld bytes)", (raw) ? "raw" : "ascii", filesize); sprintf(image->shrtInfo, "%dx%d PPM.", w, h); /* If maxv>255, keep dropping bits until it's reasonable */ holdmaxv = maxv; bitshift = 0; while ( maxv>255 ) { maxv = maxv>>1; bitshift++; } numgot = 0; if (!raw) { for ( i=0, pix=pic24; i<h ; i++ ) { for ( j=0; j<w*3; j++, pix++ ) *pix = (byte) (getint(fp, image) >> bitshift); } } else { /* raw */ if ( holdmaxv>255 ) { for ( i=0, pix=pic24 ; i<h ; i++ ) { for ( j=0; j<w*3; j++, pix++ ) *pix = (byte) (getshort(fp) >> bitshift); } } else { /* read data */ numgot = (long)fread(pic24, (size_t)1, (size_t)(w*h*3), fp); } } if ( numgot != (long)(w*h*3) ) { Error ("loadppm", CUSTOM, RETURN, TRUNCSTR); } if (garbage) { Error ("loadppm", CUSTOM, RETURN, "Garbage characters in image data.");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -