#define IMAGEIO_SOURCE_C_C #include "imageio.h" #if !defined(DELTA) # define DELTA 1e-9 #endif MAT_I ReadP5(char *fName, int *row, int *col) { FILE *IN; MAT_I dArray; char string[256]; int ftype; int i,j; if ( (IN= fopen(fName,"rb"))==NULL) { fprintf(stderr,"Cannot open file '%s'\n", fName); *row = *col = 0; return NULL; } fscanf(IN,"%s",string); if ( strcmp(string,"P5") && strcmp(string,"P2") ) { fprintf(stderr,"The system only works for P5 and P2 type PGM file.\n"); fclose(IN); *row = *col = 0; return NULL; } ftype = 0; if (strcmp(string,"P2") == 0) { ftype = 1; } while (1) { fscanf(IN,"%s",string); if (string[0] == '#') { while ( getc(IN) != '\n'); } else { sscanf(string,"%d",col); break; } } fscanf(IN, "%d%d",row,&i); getc(IN); dArray = Create_Int_Matrix(*row, *col); if (ftype == 0) { for (i=0; i< (*row); i++) { for (j=0; j <(*col); j++) { dArray[i][j] = getc(IN); } } } else { for (i=0; i< (*row); i++) { for (j=0; j <(*col); j++) { fscanf(IN,"%d", &(dArray[i][j])); } } } fclose(IN); return dArray; } void WriteP5Char(char *fName, int scale, int row, int col, MAT_I dArray) { FILE *OUT; int i,j; int c; if ( (OUT = fopen(fName, "wb")) == NULL) { fprintf(stderr,"Failed when writing file '%s'.\n", fName); return; } printf("Writing '%s' ..... ", fName); fflush(stdout); fprintf(OUT,"P5\n"); fprintf(OUT,"%d %d\n%d\n",col,row,255); for (i=0; i 255) c = 255; if (c < 0) c = 0; putc(c, OUT); } } fclose(OUT); printf(" DONE.\n"); return; } void ReadP6(char *fName, IMAGEINT_MBAND *image) { FILE *IN; char string[256], fileTypeName[256]; int ftype; int i,j,k; int row, col; int maxval; unsigned short int aword; unsigned char ch, *cp; if ( (IN= fopen(fName,"rb"))==NULL) { fprintf(stderr,"Cannot open file '%s'\n", fName); return; } fscanf(IN,"%s",fileTypeName); if ( strcmp(fileTypeName,"P5") && strcmp(fileTypeName,"P2") && strcmp(fileTypeName,"P6") && strcmp(fileTypeName,"P3") ) { fprintf(stderr,"The system only works for P2, P3, P5, and P6 "); fprintf(stderr,"type PGM file.\n"); fclose(IN); return; } while (1) { fscanf(IN,"%s",string); if (string[0] == '#') { while ( getc(IN) != '\n'); } else { sscanf(string,"%d",&col); break; } } /* Note here there should be one maximum regardless of how many color component. However, some softwares assume there is one maximum per color component */ fscanf(IN, "%d%d",&row,&i); maxval = i; /*if (maxval < j) maxval = j; if (maxval < k) maxval = k; */ /* printf("row = %d col = %d and max=%d\n", row, col, maxval); */ getc(IN); /* Read the extra white space following maximum number */ if (strcmp(fileTypeName,"P2")==0||strcmp(fileTypeName,"P5")==0) { Create_Image_MBAND(image, row, col, (int)1); } else { Create_Image_MBAND(image, row, col, (int)3); } for (i=0; i< image->nrow; i++) { for (j=0; j < image->ncol; j++) { for (k=0; k < image->nband; k++) { if (strcmp(fileTypeName,"P2")==0||strcmp(fileTypeName,"P3")==0) { fscanf(IN,"%d", &(image->bands[k].data[i][j])); } else { if (maxval < 256) { image->bands[k].data[i][j] = getc(IN); } else { cp = (char *)&aword; cp[1] = getc(IN); cp[0] = getc(IN); image->bands[k].data[i][j] = (int)((aword*255+128)/maxval); /* if (i==0 && j==0) { printf("%o %x %o %o\n", aword, aword, cp[0], cp[1]); } */ } } } } } /* printf("Check pixels in file %s\n", fName); do { printf("Pixel (col, row): "); scanf("%d%d",&j, &i); if (i<0 || i>= image->nrow) break; if (j<0 || j>= image->ncol) break; printf("R = %d G=%d B=%d\n",image->bands[0].data[i][j], image->bands[1].data[i][j], image->bands[2].data[i][j]); } while(1); */ fclose(IN); return; } void ReadP6COIL(char *fName, IMAGEINT_MBAND *image) { FILE *IN; char string[32]; int ftype; int i,j,k; int row, col; int maxval; unsigned short int aword; unsigned char ch, *cp; if ( (IN= fopen(fName,"rb"))==NULL) { fprintf(stderr,"Cannot open file '%s'\n", fName); return; } fscanf(IN,"%s",string); if ( strcmp(string,"P5") && strcmp(string,"P2") && strcmp(string,"P6") ) { fprintf(stderr,"The system only works for P2, P5, and P6 "); fprintf(stderr,"type PGM file.\n"); fclose(IN); return; } if (strcmp(string,"P2")==0||strcmp(string,"P5")==0) { fprintf(stderr,"Please use ReadP5 to read P2 and P5 images.\n"); fclose(IN); return; } while (1) { fscanf(IN,"%s",string); if (string[0] == '#') { while ( getc(IN) != '\n'); } else { sscanf(string,"%d",&col); break; } } /* Note here there is a maximum each color component and so there are three maximum numbers instead of one */ fscanf(IN, "%d%d%d%d",&row,&i,&j,&k); maxval = i; if (maxval < j) maxval = j; if (maxval < k) maxval = k; printf(" row = %d col = %d and max=%d ", row, col, maxval); getc(IN); Create_Image_MBAND(image, row, col, (int)3); for (i=0; i< image->nrow; i++) { for (j=0; j < image->ncol; j++) { for (k=0; k < image->nband; k++) { if (maxval < 256) { image->bands[k].data[i][j] = getc(IN); } else { cp = (char *)&aword; cp[1] = getc(IN); cp[0] = getc(IN); image->bands[k].data[i][j] = (int)((aword*255+128)/maxval); /*if (i==0 && j==0) { printf("%o %x %o %o\n", aword, aword, cp[0], cp[1]); } */ } } } } /* printf("Check pixels in file %s\n", fName); do { printf("Pixel (col, row): "); scanf("%d%d",&j, &i); if (i<0 || i>= image->nrow) break; if (j<0 || j>= image->ncol) break; printf("R = %d G=%d B=%d\n",image->bands[0].data[i][j], image->bands[1].data[i][j], image->bands[2].data[i][j]); } while(1); */ fclose(IN); return; } void WriteP6Char(char *fName, IMAGEINT_MBAND *image, int scale) { FILE *OUT; int i,j,k; int c; if ( (OUT = fopen(fName, "wb")) == NULL) { fprintf(stderr,"Failed when writing file '%s'.\n", fName); return; } printf("Writing '%s' ..... ", fName); fflush(stdout); if (image->nband == 1) { fprintf(OUT,"P5\n"); } else { fprintf(OUT,"P6\n"); } fprintf(OUT,"%d %d\n%d\n",image->ncol,image->nrow,255); for (i=0; inrow; i++) { for (j=0; j< image->ncol; j++) { for (k=0; k < image->nband; k++) { c = image->bands[k].data[i][j] * scale; if (c > 255) c = 255; if (c < 0) c = 0; putc(c, OUT); } } } fclose(OUT); printf(" DONE.\n"); return; } void Free_Image_MBAND(IMAGEINT_MBAND *image) { int k; if (image->nband > 0) { for (k=0; k < image->nband; k++) { Free_Image_Int(&(image->bands[k])); } free(image->bands); } image->nband = 0; return; } int Create_Image_MBAND(IMAGEINT_MBAND *image, int row, int col, int nband) { int k; if (image->nband>0) { Free_Image_MBAND(image); } image->nband = nband; image->nrow = row; image->ncol = col; image->bands = (IMAGEINT *)malloc(sizeof(IMAGEINT) * image->nband); for (k=0; k < nband; k++) { image->bands[k].nrow = 0; Create_An_Image_Int(image->nrow, image->ncol, &(image->bands[k])); } return 0; } int Read_An_Image_Int(char *name, IMAGEINT *animage) { if (animage->nrow >0 ) { Free_Image_Int(animage); } animage->data = ReadP5(name, &(animage->nrow), &(animage->ncol)); if (animage->data == NULL) return -1; return 0; } int Write_An_Image_Int(IMAGEINT *animage, int scale, char *name) { WriteP5Char(name, scale, animage->nrow, animage->ncol, animage->data); return; } int Create_An_Image_Int(int nrow, int ncol, IMAGEINT *animage) { if (animage->nrow == nrow && animage->ncol == ncol) return 0; if (animage->nrow >0 ) { Free_Image_Int(animage); } animage->data = Create_Int_Matrix(nrow, ncol); animage->nrow = nrow; animage->ncol = ncol; return 0; } void Free_Image_Int(IMAGEINT *animage) { if (animage->nrow >0 ) { Free_Int_Matrix(animage->data, animage->nrow); animage->nrow = 0; } return; } int Write_An_Image_Float(IMAGEFLOAT *animage, char *name) { int i, j; float scale, min, max; IMAGEINT tmpImg; tmpImg.nrow = 0; min = max = animage->data[0][0]; Create_An_Image_Int(animage->nrow, animage->ncol, &tmpImg); for (i=0; i < animage->nrow; i++) { for (j=0; jncol; j++) { if ( min > animage->data[i][j]) min = animage->data[i][j]; if (max < animage->data[i][j]) max = animage->data[i][j]; } } if (max < (min+DELTA)) max = min+DELTA; scale = 255./(max-min); for (i=0; i < animage->nrow; i++) { for (j=0; j < animage->ncol; j++) { tmpImg.data[i][j] = (int)((animage->data[i][j]-min)*scale); } } WriteP5Char(name, (int)1, tmpImg.nrow, tmpImg.ncol, tmpImg.data); Free_Image_Int(&tmpImg); return; } int Create_An_Image_Float(int nrow, int ncol, IMAGEFLOAT *animage) { if (animage->nrow == nrow && animage->ncol == ncol) return 0; if (animage->nrow >0 ) { Free_Image_Float(animage); } animage->data = Create_Matrix(nrow, ncol); animage->nrow = nrow; animage->ncol = ncol; return 0; } int Init_An_Image_Float(IMAGEFLOAT *animage, float cVal) { int i,j; for (i=0; i < animage->nrow; i++) { for (j=0; j < animage->ncol; j++) { animage->data[i][j] = cVal; } } return 0; } void Free_Image_Float(IMAGEFLOAT *animage) { if (animage->nrow >0 ) { Free_Matrix(animage->data, animage->nrow); animage->nrow = 0; } return; }