?? image_file.c
字號:
/*..........................................................................*//* *//* L a s t W a v e P a c k a g e 'image' 2.1 *//* *//* Copyright (C) 1998-2002 Emmanuel Bacry, Jerome Fraleu. *//* emails : fraleu@cmap.polytechnique.fr *//* lastwave@cmap.polytechnique.fr *//* *//*..........................................................................*//* *//* This program is a free software, you can redistribute it and/or *//* modify it under the terms of the GNU General Public License as *//* published by the Free Software Foundation; either version 2 of the *//* License, or (at your option) any later version *//* *//* This program is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *//* GNU General Public License for more details. *//* *//* You should have received a copy of the GNU General Public License *//* along with this program (in a file named COPYRIGHT); *//* if not, write to the Free Software Foundation, Inc., *//* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* *//*..........................................................................*/#include "lastwave.h"#include "images.h"/* * Read an image from a stream * * nrow,ncol : The size of the image to read if cannot be guessed * flagChar : YES if each pixel value is coded on a single char (otherwise it is coded on a LWFLOAT) * flagBinary : YES if each pixel value is coded using binary coding of a real number * using endian mode specified by binaryCoding and size of float nsize. */void ReadImageStream(IMAGE image ,STREAM s, int nrow, int ncol,char flagChar,char flagBinary, char binaryCoding, int nsize){ FILE *stream; char flagHeader; fpos_t beginning; char name[255],str[1000],*str1,c; int n; char *h; int countRC; int comment=0; char header[200],car[200]; LWFLOAT *values; int i; LWFLOAT *array; if (s->mode != StreamRead) Errorf("ReadImageStream() : The stream should be an input stream and not an output stream"); if (s->stream == NULL) Errorf("ReadImageStream() : You cannot read an image to standard input"); stream = s->stream; /* * Try to read LastWave header */ flagHeader = NO; fgetpos(stream,&beginning); str1 = "LastWave Header"; while (*str1 != '\0') { c = fgetc(stream); if (c != *str1) break; str1++; } /* There is a LastWave header */ if (*str1 == '\0') { c = fgetc(stream); c = fgetc(stream); if (c != '\n') ungetc(c,stream); flagHeader = YES; n = 0; n += fscanf(stream,"nrow %d ",&nrow); n += fscanf(stream,"ncol %d ",&ncol); n += fscanf(stream,"name %[^\n\r] ",name); n += fscanf(stream,"binary %[^\n\r] ",str); if (n != 4) Errorf("ReadImageStream() : Error in the LastWave header of the file"); if (strcmp(name,"none")) SetNameImage(image,name); else SetNameImage(image,NULL); flagBinary = NO; if (!strcmp(str, "no")) flagBinary = NO; else { flagBinary = YES; if (!strncmp(str, "little",6)) { binaryCoding= BinaryLittleEndian; str1 = str+6; } else if (!strncmp(str, "big",3)) { binaryCoding= BinaryBigEndian; str1 = str+3; } else Errorf("ReadImageStream() : Bad field value '%s' of field 'binary'",str); nsize = sizeof(float); if (*str1 == ' ') { str1++; sscanf(str1,"%d",&nsize); } if (nsize != sizeof(float) && nsize != sizeof(double)) Errorf("ReadImageStream() : Can't read binary files using %d bytes to store numbers (that size is neither float or double)",nsize); } fscanf(stream,"%[^\n\r] ",str); } /* * If no LastWave header, try to read a pgm header * (otherwise nrow and ncol have been given) */ if (!flagHeader) { fsetpos(stream,&beginning); str1 = "P5"; while (*str1 != '\0') { c = fgetc(stream); if (c != *str1) break; str1++; } /* There is a PGM header */ if (*str1 == '\0') { fsetpos(stream,&beginning); countRC =0; while (countRC!=3){ h = header; while(1) { *h = fgetc(stream); if (*h == '\n' || *h == '\r') break; h++; if (h-header == 190) break; } *(h+1) = '\0'; countRC += (*h=='\n' || *h == '\r'); if (strchr(header,'#')) countRC--; else { if (countRC==2) { nrow=atoi(header); sprintf(car,"%d",nrow); for (i=0;i<(strlen(car)+1);i++) header[i]=' '; ncol=atoi(header); } } } flagChar = YES; flagHeader = YES; } } /* If no header, the number of rows/cols must have been given */ if (!flagHeader) { fsetpos(stream,&beginning); if (nrow < 0 || ncol < 0) Errorf("ReadImageStream() : number of rows/columns must be specified"); } /* Resize the image */ SizeImage(image,ncol,nrow); values = image->pixels; /* Char read */ if (flagChar) { for(i = 0; i < ncol*nrow; i++) { fscanf(stream,"%c",&c); values[i] = (LWFLOAT) ((((int) c)+256)%256); } return; } /* ascii read */ if (!flagBinary) { for(i = 0; i < ncol*nrow; i++) {#ifdef NUMDOUBLE fscanf(stream,"%lf ",values+i);#elif fscanf(stream,"%f ",values+i);#endif } return; } /* Binary LWFLOAT read */ if (sizeof(LWFLOAT) == nsize) array = values; else array = Malloc(nsize*nrow*ncol); /* Read the data */ if (fread(array,nsize,nrow*ncol,stream) != nrow*ncol) Errorf("ReadImageStream() : nrow*ncol seems to be too large for this file"); /* Big/Little conversions */ if ((binaryCoding == BinaryLittleEndian && IsCPUBigEndian) || (binaryCoding != BinaryLittleEndian && IsCPULittleEndian)) BigLittleValues(array,nrow*ncol,nsize); /* Conversion of the array if necessary */ if (sizeof(LWFLOAT) != nsize) { for (i=0;i<nrow*ncol;i++) { if (sizeof(float) == nsize) values[i] = ((float *) array)[i]; else values[i] = ((double *) array)[i]; } Free(array); } }/* The corresponding command */void C_ReadImage(char ** argv){ char *fname; IMAGE image; STREAM s; char flagChar; char car; int nrow,ncol,nsize; char binaryCoding,flagBinary; char *mode; argv = ParseArgv(argv,tIMAGE,&image,tSTREAM_,NULL,&s,-1); fname = NULL; if (s == NULL) { argv = ParseArgv(argv,tSTR,&fname,-1); s = OpenFileStream(fname,"r"); if (s == NULL) Errorf("Cannot open the file '%s'",fname); } ClearImage(image); if (s->mode != StreamRead) Errorf("The stream should be an input stream and not an output stream"); if (s->stream == NULL) Errorf("You cannot read an image to standard input"); flagChar = NO; nrow = ncol = -1; flagBinary = NO; while (car=ParseOption(&argv)) { switch (car) { case 'r': flagBinary = YES; flagChar = NO; argv = ParseArgv(argv,tINT,&nrow,tINT,&ncol,-1); if (*argv != NULL && '0'<=**argv && **argv<='9') { argv = ParseArgv(argv,tINT_,0,&nsize,-1); mode = ""; } else argv = ParseArgv(argv,tSTR_,"",&mode,tINT_,0,&nsize,-1); if (!strcmp(mode,"little")) binaryCoding = BinaryLittleEndian; else if (!strcmp(mode,"big")) binaryCoding = BinaryBigEndian; else if (!strcmp(mode,"")) binaryCoding = 0; else Errorf("Bad binary mode '%s'",mode); if (nsize != 0 && nsize != sizeof(float) && nsize != sizeof(double)) Errorf("Bad number of bytes (%d) for float (must be either %d or %d)",nsize,sizeof(float),sizeof(double)); break; case 'a': flagChar = NO; flagBinary = NO; argv = ParseArgv(argv,tINT,&nrow,tINT,&ncol,-1); break; case 'c': flagChar = YES; flagBinary = NO; argv = ParseArgv(argv,tINT,&nrow,tINT,&ncol,-1); break; default: ErrorOption(car); } } NoMoreArgs(argv); ReadImageStream(image,s,nrow,ncol,flagChar,flagBinary,binaryCoding,nsize); if (fname) CloseStream(s); }/* * Write an image to a stream * * flagPGM : if set write using PGM format * flagLW : if set write using Lastwave format * flagBinary : if set write using binary coding * format : if flagBinary is not set then format to use for ascii printing * sep : if flagBinary is not set then string separator to use for ascii printing * flagChar : set if each pixel value is coded on a single char (otherwise it is coded on a LWFLOAT) * In case it is set and if min<max then rescaling will be performed between min and max in * order to match 0 and 255. */void WriteImageStream(IMAGE image,STREAM s, char flagPGM, char flagLW, char flagBinary, char *format, char *sep, char flagChar,LWFLOAT min, LWFLOAT max){ FILE * stream; char *type,*format1; LWFLOAT *values,val; int i,j; if (s->mode != StreamWrite) Errorf("WriteImageStream() : The stream should be an output stream and not an input stream"); if (s->stream == NULL) Errorf("WriteImageStream() : You cannot write a signal to standard output"); stream = s->stream; /* Test the format */ if (format != NULL) { if (*format == '\0') type = NULL; else { format1 = format; if (strlen(format1)<2 && format1[0] != '%') Errorf("WriteImageStream() : Bad format '%s'",format); format1++; while(*format1 != '\0' && *format1 != '%' && !isalpha(*format1)) format1++; if (*format1 == '\0' || *format1 == '%') Errorf("WriteImageStream() : Bad format '%s'",format); /* Case of an int */ if (*format1 == 'd' || *format1 == 'i' || *format1 == 'o' || *format1 == 'x' || *format1 == 'X' || *format1 == 'u') type = intType; /* Case of an double */ else if (*format1 == 'f' || *format1 == 'e' || *format1 == 'E' || *format1 == 'g' || *format1 == 'G') type = floatType; else Errorf("WriteImageStream() : Bad format '%s", format); } } /* PGM header */ if (flagPGM) { fprintf(stream,"P5\n%d %d\n",image->nrow,image->ncol); if (flagChar) fprintf(stream,"255\n"); else fprintf(stream,"255.0\n"); } /* LW header */ else if (flagLW) { if (flagChar) Errorf("WriteImageStream() : Cannot using char in LastWave format"); fprintf(stream,"LastWave Header\n"); fprintf(stream,"nrow %d\n",image->nrow); fprintf(stream,"ncol %d\n",image->ncol); if (image->name == NULL || image->name[0] == '\0') fprintf(stream,"name none\n"); else fprintf(stream,"name %s\n",image->name); if (flagBinary == NO) fprintf(stream,"binary no\n"); else { if (IsCPULittleEndian) fprintf(stream,"binary little %ld\n",sizeof(LWFLOAT)); else fprintf(stream,"binary big %ld\n",sizeof(LWFLOAT)); } fprintf(stream,"End of Header\n"); } /* Case we must store a char image */ if (flagChar) { values = image->pixels; for (i = 0; i < image->nrow*image->ncol ; i++) { if (min < max) val = (values[i]-min)*255./(max-min); else val = values[i]; val = MAX(0,val); val = MIN(255,val); fprintf(stream,"%c",(unsigned char)((int)(values[i]))); } return; } /* Case we must store a binary (float) image */ if (flagBinary) { values = image->pixels; fwrite(values,sizeof(LWFLOAT),image->nrow*image->ncol,stream); return; } /* Case we must store an ascii image (with tabs) */ if (type == NULL) {#ifdef NUMDOUBLE format = "%.16g";#else format = "%.8g";#endif } if (!strcmp(sep,"")) sep = "\t"; for (i = 0; i < image->nrow ; i++) { for (j = 0; j < image->ncol ; j++) { if (type == NULL || type == floatType) fprintf(stream,format,image->pixels[i*image->ncol+j]); else fprintf(stream,format,(int) image->pixels[i*image->ncol+j]); if (j != image->ncol-1) fprintf(stream,"%s",sep); } fprintf(stream,"\n"); } }/* The corresponding command */void C_WriteImage(char**argv){ char *fname; STREAM s; IMAGE input; char flagLW,flagChar,flagPGM,flagBinary; LWFLOAT min,max,f; char opt,*sep,*format; argv= ParseArgv(argv,tIMAGEI,&input,tSTREAM_,NULL,&s,-1); fname = NULL; if (s == NULL) { argv = ParseArgv(argv,tSTR,&fname,-1); s = OpenFileStream(fname,"w"); if (s == NULL) Errorf("Cannot open the file '%s'",fname); } if (s->mode != StreamWrite) Errorf("The stream should be an output stream and not an input stream"); if (s->stream == NULL) Errorf(" You cannot write a signal to standard output"); flagLW = YES; flagBinary = YES; flagPGM = NO; flagChar = NO; min = max = 0; format = ""; sep = "\t"; while (opt=ParseOption(&argv)) { switch (opt) { case 'a': flagBinary = NO; break; case 'c': flagChar = YES; argv = ParseArgv(argv,tFLOAT_,min,&min,tFLOAT_,max,&max,-1); break; case 'h': flagLW = NO; flagPGM = NO; break; case 'f': if (flagBinary) Errorf("Cannot use -b flag along with -f flag"); if (*argv != NULL && **argv != '-') argv = ParseArgv(argv,tSTR,&format,-1); else format = ""; if (*argv != NULL && **argv != '-') argv = ParseArgv(argv,tSTR,&sep,-1); else sep = "\t"; break; case 'p': flagPGM = YES; flagLW = NO; flagChar = YES; MinMaxImage(input,NULL,NULL,&min,NULL,NULL,&max); break; default: ErrorOption(opt); } } NoMoreArgs(argv); if (min > max) { f = min; min = max; max = f; } WriteImageStream(input,s,flagPGM,flagLW,flagBinary,format,sep,flagChar,min,max); if (fname) CloseStream(s);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -