具有魔术代码P3的ppm格式

时间:2013-11-30 21:35:14

标签: c

我如何阅读具有魔法代码P3的ppm图像。用c语言? 这段代码读取的ppm图像有魔法代码P3,但加载方法有问题,这段代码在读取pixles的值时会进入无限循环?

    /* This is for reading and Writing images file in PPM
    Also example of making Negative images

    - Use this file as an example of reading (loading) and writing (storing) images files.

    - This program loads an PPM image and store a new image that is the negative of the      original image.


    */
    typedef struct pdata {
    int red;
    int green;
    int blue;

    } pdata;
    typedef struct ppm {
    int w;
    int h;
    int max;
    pdata *pData;
    } ppm;


#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//#define kernelW 3
//#define kernelH 3
//#define imageW 403
//#define imageH 332
char filename[256];

/*
   This LoadPGM function is an updated version that will deal with
   comments in file headers and do at least some basic checking if the
   file can be opened or is the correct format. It does assume the file
   is actually a valid length once the header has been read.

   You are of course free to use your own file reading functions.
*/

void LoadPGM( char* filename, ppm* pPgm ) {
  FILE* ifp;
  int word;
  int nRead = 0;
  char readChars[256];

  //open the file, check if successful
  ifp = fopen( filename, "r" );
  if (!ifp) {
    printf("Error: Unable to open file %s.\n\n", filename);
    exit(1);
  }

  //read headers from file
  printf ("Reading PPM file: %s...\n", filename);
  fscanf (ifp, "%s", readChars);

  if (strcmp(readChars, "P3") == 0) {
    //valid file type
    //get a word from the file
    fscanf (ifp, "%s", readChars);
    while (readChars[0] == '#') {
      //if a comment, get the rest of the line and a new word
      fgets (readChars, 255, ifp);
      fscanf (ifp, "%s", readChars);
    }

    //ok, comments are gone
    //get width, height, color depth
    sscanf (readChars, "%d", &pPgm->w);
    fscanf (ifp, "%d", &pPgm->h);
    fscanf (ifp, "%d", &pPgm->max);

    // allocate some memory, note that on the HandyBoard you want to
    // use constant memory and NOT use calloc/malloc
      pPgm = (ppm *)malloc(sizeof(ppm));
     pPgm->pData = (pdata*)malloc(pPgm->w *pPgm->h * sizeof(pPgm->pData));
 fscanf(ifp, "%d" ,&word);
      pPgm->pData[0].red = word;
      printf (" %d \n", word);
    for (nRead = 0; nRead < pPgm->w * pPgm->h; nRead++) {
      fscanf(ifp, "%d" ,&word);
      // printf (" %d \n",word);
      pPgm->pData[nRead].red = word;
      fscanf(ifp, "%d" ,&word);
      pPgm->pData[nRead].green = word;
      fscanf(ifp, "%d" ,&word);
      pPgm->pData[nRead].blue = word;

    }

    printf ("Loaded PPM. Size: %dx%d, Greyscale: %d \n",
        pPgm->w, pPgm->h, pPgm->max + 1);
  }
  else {
    printf ("Error: Read file type %s. Format unsupported.\n\n", readChars);
    exit(1);
  }
  fclose(ifp);
}

/* Simply saves the PGM file to a file whose name is in filename */

void WritePGM( char* filename, ppm* pPgm ) {
  FILE* ofp;
  int w, h, max;
  int nWrite = 0;
  int i,j;


  strcat(filename, ".out.ppm");
  ofp = fopen(filename, "w");
  if (!ofp) {
    printf("Error: Unable to open file %s.\n\n", filename);
    exit(1);
  }

  printf ("Writing ouput PPM: %s\n\n", filename);


  //write the header
  fprintf( ofp, "P3\n" );
  fprintf( ofp, "%d %d\n", pPgm->w, pPgm->h );
 //  printf("Done. Have a nice day...\n\n");
  fprintf( ofp, "%d\n", pPgm->max );


  //write the image data
  for (i = 0; i < pPgm->h;i++) {
    for (j = 0; j < pPgm->w; j++)
      fprintf(ofp,"%d ",*(pPgm->pData + i * pPgm->w + j));
    fprintf(ofp,"\n");
  }
  fclose(ofp);
}


int main(int argc, char * argv[]) {

  ppm* image, *r1,*r2;
 // char filename[256];
  int val;
  int errchk;
  char f1[256];

  //check if a filename was given, if not, ask for one
  if (argc > 1) {
    strcpy(filename, argv[1]);
  }
  else {
    printf ("Enter filename: ");
    scanf ("%s", filename);
  }

  //allocate memory for the pgm struct
  image = (ppm *) malloc (sizeof(ppm));




  //read the file
  LoadPGM(filename, image);
 int h,w;

w=image->w;
h=image->h;

int* pBuff1;
int* pBuff2;

   int size;
   int sum=0;




 WritePGM(filename, image);




//  end of the program
}

1 个答案:

答案 0 :(得分:1)

这一行

malloc(pPgm->w *pPgm->h * sizeof(pPgm->pData))

分配错误的大小。它在您需要时sizeof(pointer)分配sizeof(pdata),您自己的RGB结构。

通常,只需要RGB作为3个无符号字符,并且你曾经使用过该错误,因为指针通常是4个字节长(现在甚至可以更长)。 但是因为你的每个值都是int,所以结构总共使用了12个字节。在读完第一个三分之一(给予或接受)之后的某个地方,你的代码开始覆盖内存中的其他内容并且你会被烘烤。