📄 wtf.c
字号:
/* * -*- Mode: ANSI C -*- * $Id: wtf.c,v 1.5 1996/09/17 16:10:29 fernande Exp $ * $Source: /sgi.acct/sweldens/cvs/liftpack/Files/wtf.c,v $ * Author: Gabriel Fernandez * * Routines to manipulate 'wtf' format pictures. * LoadWTF ( filename, image ) - loads a WGM, or WPM file. * WriteWTF ( fp, pic, w, h, style, wlt, cmt, comment ); *//* do not edit anything above this line *//* System header files */#include <string.h>/* FLWT header files */#include <wtf.h>#include <flwterr.h>#include <file.h>#include <imgmem.h>#include <mem.h>#include <memchk.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 LoadWTF 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, blocks;static long numgot, filesize;/* Static functions declarations */static int loadwgm (FILE *, Image *, int);static int loadwpm (FILE *, Image *, int);static int getint (FILE *, Image *);/* code *//* * LoadWTF function: loads a WNM file. Returns '1' on success. */intLoadWTF ( const char *filename, Image *image ){ FILE *fp; int c, c1; int rv; /* Set initial values */ garbage = 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. "W1" = packets greymap, "W3" = wavelet greymap, "W2" = packets pixmap, "W4" = wavelet pixmap */ c = getc(fp); c1 = getc(fp); if (c!='W' || c1<'1' || c1>'4') { Error ("LoadWTF", CUSTOM, RETURN, "Invalid magic number.\n"); return 0; } /* Read in header information */ image->width = getint(fp, image); image->height = getint(fp, image); /* if the file is of packets, read the number of blocks */ if ( c1=='1' || c1=='2' ) { blocks = getint(fp, image); if ( blocks<1 ) garbage = 1; /* to avoid further probs */ } else blocks = 0; if (garbage) { fclose(fp); if (image->comment) free(image->comment); image->comment = (char *)NULL; Error ("LoadWTF", CUSTOM, RETURN, "Garbage characters in header.\n"); return 0; } if ( c1=='1' || c1=='2' ) image->frmType = F_WTFWLT; else image->frmType = F_WTFPCK; /* 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=='3' ) rv = loadwgm( fp, image, c1=='3' ? 1 : 0 ); else if ( c1=='2' || c1=='4' ) rv = loadwpm( fp, image, c1=='4' ? 1 : 0 ); 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;}/* * loadwgm function: reads the WGM file pointed by fp. */static int loadwgm ( FILE *fp, Image *image, int wlt ){ Vector pixFlt; int i, j, w, h, rv; /******************************/ /* Initialize image structure */ /******************************/ rv = (int)IMG_InitMem (image, (long)image->width, (long)image->height, 1, 8); if ( !rv ) { Error ("loadwgm", MEMORY_IMAGE, ABORT); /* NOTREACHED */ } image->colType = 1; /* Greyscale */ w = image->width; h = image->height; sprintf(image->fullInfo, "WGM, %s format. (%ld bytes)", (wlt) ? "wavelet" : "packets", filesize); sprintf(image->shrtInfo, "%dx%d WGM.", image->width, image->height); numgot = 0; if (!wlt) { /* packets */ int total = 0; int *levels = ivector( 0, (long)(2*blocks-1) ), *reallevels, *lvlPtr;/* fprintf (stdout, "\n"); */ for ( i=0 ; i<2*blocks ; i+=2 ) { levels[i] = (int)fgetc(fp); levels[i+1] = (int)fgetc(fp); total += levels[i];/* fprintf (stdout, "%d -> %d\n", levels[i], levels[i+1]);fflush(stdout); */ } reallevels = ivector( 0, (long)(total-1) ); lvlPtr = reallevels; for ( i=0 ; i<2*blocks ; i+=2 ) for ( j=0 ; j<levels[i] ; j++ ) *(lvlPtr++) = levels[i+1]; image->blocks = total; image->levels = reallevels; free_ivector( levels, 0, (long)(2*blocks-1) ); } else { /* wavelet */ image->levels = NULL; image->blocks = 0; } pixFlt = image->band[GREY][0]; numgot = (long)fread(pixFlt, (size_t)sizeof(pixFlt[0]), (size_t)(w*h), fp); if ( numgot != (long)(w*h) ) { Error ("loadwgm", CUSTOM, RETURN, TRUNCSTR); /* warning only */ } if (garbage) { Error ("loadwgm", CUSTOM, RETURN, "Garbage characters in image data."); return 0; } return 1;}/* * loadwpm function: reads the WPM file pointed by fp. */static int loadwpm ( FILE *fp, Image *image, int wlt ){ Vector pixR, pixG, pixB; int i, j, w, h, rv; w = image->width; h = image->height; /******************************/ /* Initialize image structure */ /******************************/ rv = (int)IMG_InitMem (image, (long)image->width, (long)image->height, 3, 24); if ( !rv ) { Error ("loadwpm", MEMORY_IMAGE, ABORT); /* NOTREACHED */ } image->colType = 0; /* Full Color */ sprintf(image->fullInfo, "WPM, %s format. (%ld bytes)", (wlt) ? "wavelet" : "packets", filesize); sprintf(image->shrtInfo, "%dx%d WPM.", w, h); numgot = 0; if (!wlt) { /* packets */ int total = 0; int *levels = ivector( 0, (long)(2*blocks-1) ), *reallevels, *lvlPtr;/* fprintf (stdout, "\n"); */ for ( i=0 ; i<2*blocks ; i+=2 ) { levels[i] = (int)fgetc(fp); levels[i+1] = (int)fgetc(fp); total += levels[i];/* fprintf (stdout, "%d -> %d\n", levels[i], levels[i+1]);fflush(stdout); */ } reallevels = ivector( 0, (long)(total-1) ); lvlPtr = reallevels; for ( i=0 ; i<2*blocks ; i+=2 ) for ( j=0 ; j<levels[i] ; j++ ) *(lvlPtr++) = levels[i+1]; image->blocks = total; image->levels = reallevels; free_ivector( levels, 0, (long)(2*blocks-1) ); } else { /* wavelet */ image->levels = NULL; image->blocks = 0; } pixR = image->band[RED][0]; pixG = image->band[GREEN][0]; pixB = image->band[BLUE][0]; for ( i=0 ; i<w*h*3 ; i+=3, pixR++, pixG++, pixB++ ) { numgot += (long)fread( pixR, (size_t)sizeof(pixR[0]), (size_t)1, fp ); numgot += (long)fread( pixG, (size_t)sizeof(pixG[0]), (size_t)1, fp ); numgot += (long)fread( pixB, (size_t)sizeof(pixB[0]), (size_t)1, fp ); } if ( numgot != (long)(w*h*3) ) { Error ("loadwpm", CUSTOM, RETURN, TRUNCSTR); } if (garbage) { Error ("loadwpm", CUSTOM, RETURN, "Garbage characters in image data."); return 0; } return 1;}/* * getint function: gets and integer value from the actual position * pointed by fp. */static int getint ( FILE *fp, Image *image ){ int c, i, firstchar; /* Note: if it sees a '#' character, all characters from there to end of line are appended to the comment string */ /* Skip forward to start of next number */ c = getc(fp); while (1) { /* Eat comments */ if ( c=='#' ) { /* if we're at a comment, read to end of line */ char cmt[256], *sp, *tmpptr; sp = cmt; firstchar = 1; while (1) { c = getc(fp); if ( firstchar && c == ' ' ) firstchar = 0; /* loop off 1 sp after # */ else { if ( c == '\n' || c == EOF ) break; if ( (sp-cmt)<250 ) *sp++ = (char)c; } } *sp++ = '\n'; *sp = '\0'; if ( strlen(cmt) > 0 ) { /* add to image->comment */ if ( !image->comment ) { image->comment = (char *) malloc(strlen(cmt) + 1); if ( !image->comment ) Error ("getint", MALLOC_FAIL, ABORT); /* NOTREACHED */ image->comment[0] = '\0'; } else { tmpptr = (char *) realloc(image->comment, strlen(image->comment) + strlen(cmt) + 1); if (!tmpptr) Error ("getint", REALLOC_FAIL, ABORT); /* NOTREACHED */ image->comment = tmpptr; } strcat(image->comment, cmt); } } if ( c==EOF ) return 0; if ( c>='0' && c<='9' ) break; /* we've found what we were looking for */ /* see if we are getting garbage (non-whitespace) */ if ( c!=' ' && c!='\t' && c!='\r' && c!='\n' && c!=',' ) garbage=1; c = getc(fp); } /* we're at the start of a number, continue until we hit a non-number */ i = 0; while (1) { i = (i*10) + (c - '0'); c = getc(fp); if ( c==EOF ) return i; if ( c<'0' || c>'9' ) break; } numgot++; return i;}/* * WriteWTF function: writes a WGM/WPM file to the already open stream. * If (wlt), writes wavelets, otherwise writes * packets. Everything is written in f.p. format. * 'colorstyle' single-handedly determines the * type of file written: * if colorstyle==0, (Full Color) a WPM file is written, * if colorstyle==1, (Greyscale) a WGM file is written, */intWriteWTF ( FILE *fp, Vector pic, const int w, const int h, const int colorstyle, const int bpp, int *levels, const int Blocks, const boolean wlt, char *comment ){ int magic; Vector pix; int i, j; char buf[BUFSIZ]; /* Print info to user */ sprintf (buf , "%4dx%-4d %s, %s format.", w, h, (colorstyle==0) ? "WPM" : "WGM", (wlt) ? "wavelet" : "packets"); fprintf (stdout, "\n[%s]", buf); /* Calc the appropriate magic number for this file type */ magic = 0; if (colorstyle==0) magic = 2; else if (colorstyle==1) magic = 1; if (wlt && magic) magic+=2; /* Write the header info */ fprintf (fp, "W%d\n",magic); fprintf (fp, "# Creator: flwt %s\n", REVDATE); if (comment) { /* write comment lines */ char *sp; sp = comment; while (*sp) { fprintf (fp, "# "); while (*sp && *sp != '\n') fputc((int)*sp++, fp); if (*sp == '\n') sp++; fputc('\n', fp); } } fprintf (fp, "%d %d\n", w, h); if ( ferror(fp) ) return 0; /* Write special header information */ if ( !wlt ) { /* write packets header info */ int sum, blocks; int buff[BUFSIZ]; if ( levels == NULL ) { Error( "WriteWTF", CUSTOM, ABORT, "levels vector is missing." " Aborting..."); } sum = 1; blocks = 1; for ( i=1, j=0 ; i<Blocks ; i++ ) { if ( levels[i] == levels[i-1] ) sum++; else { buff[j++] = sum; buff[j++] = levels[i-1]; sum = 1; blocks++; } } buff[j++] = sum; buff[j++] = levels[i-1]; fprintf (fp, "%d\n", blocks);/* fprintf (stdout, "\n"); */ for ( i=0 ; i<2*blocks ; i+=2 ) { fputc ((int)buff[i], fp); fputc ((int)buff[i+1], fp);/* fprintf (stdout, "%d -> %d\n", buff[i], buff[i+1]);fflush(stdout); */ } } else { /* for wavelets there is no further info */ } /* Write the image data */ if ( colorstyle==0 ) { /* 24bit RGB, 3 bytes per pixel */ for ( i=0, pix=pic ; i<h ; i++ ) { for ( j=0 ; j<w*3 ; j++ ) { if ( fwrite( pix, (size_t)sizeof(pix[0]), (size_t)3, fp ) == 0 ) { fclose( fp ); Error( "WriteWTF", WRITE_ERROR, RETURN ); return 0; } pix += 3; } } } else if (colorstyle==1) { /* 8-bit greyscale */ int height = h, width = w; pix = pic; while (height--) { if (fwrite( pix, (size_t)sizeof(pix[0]), (size_t)width, fp ) == 0) { fclose( fp ); Error( "WriteWTF", WRITE_ERROR, RETURN ); return 0; } pix += width; } } if ( ferror(fp) ) return 0; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -