Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: Reading image from sd card

  1. #1
    Junior Member
    Join Date
    Aug 2023
    Posts
    12

    Reading image from sd card

    I have image.pgm on SD card. In this code, I can't print the size of the image after reading, the code inters in loop. The commented lines represent the code in c, and it was work (as a c code) without any problem. I convert some functions the deal with files to can work on Arduino but the problem I can't get the size of image. any help please? to read the image in correct way?

    Code:
    #include <SD.h>
    typedef struct _PGMData {
        int row;
        int col;
        int max_gray;
        int **matrix;
    } PGMData;
    
    #define HI(num) (((num) & 0x0000FF00) << 8)
    #define LO(num) ((num) & 0x000000FF)
    
    
    int **allocate_dynamic_matrix(int row, int col)
    {
        int **ret_val;
        int i;
     
        ret_val = (int **)malloc(sizeof(int *) * row);
        if (ret_val == NULL) {
            perror("memory allocation failure");
            exit(EXIT_FAILURE);
        }
     
        for (i = 0; i < row; ++i) {
            ret_val[i] = (int *)malloc(sizeof(int) * col);
            if (ret_val[i] == NULL) {
                perror("memory allocation failure");
                exit(EXIT_FAILURE);
            }
        }
     
        return ret_val;
    }
     
    void deallocate_dynamic_matrix(int **matrix, int row)
    {
        int i;
     
        for (i = 0; i < row; ++i) {
            free(matrix[i]);
        }
        free(matrix);
    }
    void SkipComments(File &fp)
    {
    
        int ch;
        char line[100];
      /*  
        while ((ch = fgetc(fp)) != EOF && isspace(ch)) {
            ;
        }
     
        if (ch == '#') {
            fgets(line, sizeof(line), fp);
            SkipComments(fp);
        } else {
            fseek(fp, -1, SEEK_CUR);
        }
     */
    
    while (fp.available() && isspace(ch) ){
     //  Serial.write(fin.read());
       ch = fp.read();
    }
         
    if (ch == '#') {
           // fgets(line, sizeof(line), fp);
          
    int bar=0;
    int in_char;
    while((in_char = fp.read()) >= 0){             
        line[bar++] = (char)in_char;
    }
            SkipComments(fp);
        } else {
           // fseek(fp, -1, SEEK_CUR);
             fp.seek(fp.position());   
        }
    
    
    }
    //for reading:*
    
    PGMData* readPGM( PGMData *data)
    {
        File pgmFile;
        char version[3];
        int i, j;
        int lo, hi;
        if (!SD.begin(BUILTIN_SDCARD)) {
        Serial.println("Failed to mount card read pgm");
      }
       pgmFile = SD.open("/image.pgm", FILE_READ);
      if (!pgmFile) {
        Serial.println("Opening file to read failed read pgm");
      }
       /* if (pgmFile == NULL) {
            perror("cannot open file to read");
            exit(EXIT_FAILURE);
        }*/
      /*  fgets(version, sizeof(version), pgmFile);
        if (strcmp(version, "P5")) {
            fprintf(stderr, "Wrong file type!\n");
            exit(EXIT_FAILURE);
        }
        */
    
        /*
        SkipComments(pgmFile);
       // fscanf(pgmFile, "%d", &data->col);
        SkipComments(pgmFile);
       // fscanf(pgmFile, "%d", &data->row);
        SkipComments(pgmFile);
       // fscanf(pgmFile, "%d", &data->max_gray);
       */
    
       while (pgmFile.available()){
     
        SkipComments(pgmFile);
       // fscanf(pgmFile, "%d", &data->col);
       data->col = pgmFile.read();
        SkipComments(pgmFile);
       // fscanf(pgmFile, "%d", &data->row);
       data->row = pgmFile.read();
        SkipComments(pgmFile);
       // fscanf(pgmFile, "%d", &data->max_gray);
       data->max_gray = pgmFile.read();
      
    }
       /// fgetc(pgmFile);
        data->matrix = allocate_dynamic_matrix(data->row, data->col);
        if (data->max_gray > 255) {
            for (i = 0; i < data->row; ++i) {
                for (j = 0; j < data->col; ++j) {
                    hi = pgmFile.read();    //fgetc(pgmFile);
                    lo = pgmFile.read();   //fgetc(pgmFile);
                    data->matrix[i][j] = (hi << 8) + lo;
                }
            }
        }
        else {
            for (i = 0; i < data->row; ++i) {
                for (j = 0; j < data->col; ++j) {
                    lo = pgmFile.read();   //fgetc(pgmFile);
                    data->matrix[i][j] = lo;
                }
            }
        }
     
        pgmFile.close();
        return data;
     
    }
    
    void setup() {
      // put your setup code here, to run once:
    Serial.begin(115200);
      while (!Serial){}; 
        PGMData im;
        readPGM( &im);
    
       Serial.print("The size of image = ");
       Serial.println(im.col);
       Serial.println(im.row);   
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,925
    I've massaged your code so that it can read a PGM header file. I could only test with an example PGM that was way too big to fit in a teensy, so I can't guarantee that it'll read the image itself correctly.

    Code:
    // Read a PBM image from Teensy 4.1 built-in SDcard
    
    #include <SD.h>
    typedef struct _PGMData {
      int row;
      int col;
      int max_gray;
      int **matrix;
    } PGMData;
    
    int **allocate_dynamic_matrix(int row, int col)
    {
      int **ret_val;
      int i;
      
      ret_val = (int **)malloc(sizeof(int *) * row);
      if (ret_val == NULL) {
        perror("memory allocation failure A");
        exit(EXIT_FAILURE);
      }
    
      for (i = 0; i < row; ++i) {
        ret_val[i] = (int *)malloc(sizeof(int) * col);
        if (ret_val[i] == NULL) {
          perror("memory allocation failure B");
          exit(EXIT_FAILURE);
        }
      }
    
      return ret_val;
    }
    
    void deallocate_dynamic_matrix(int **matrix, int row)
    {
      int i;
    
      for (i = 0; i < row; ++i) {
        free(matrix[i]);
      }
      free(matrix);
    }
    
    void SkipComments(File pgmFile/*File &fp*/)
    {
    
      int ch;
    
      while ((ch = pgmFile.read()) != EOF && isspace(ch)) {
        ;
      }
      // If this is a comment, read and ignore
      // all of it up to a newline
      if (ch == '#') {
        while((ch = pgmFile.read()) >= 0) {
          if(ch == '\n' || ch == '\r')break;
        }
        // end of file?
        if(ch < 0)return;
        SkipComments(pgmFile);
      } else {
        // back up one character if this isn't a comment
        // so that we re-read the previous character
        pgmFile.seek(pgmFile.position()-1);
      }
    }
    
    // Read one line from the file into istr
    char istr[100];
    void readln_istr(File pgmFile)
    {
      uint32_t i;
      char ch;
      
      for(i = 0; i < sizeof(istr); i++) {
        ch = pgmFile.read();
        istr[i] = ch;
        if(ch == '\r' || ch == '\n') return;
      }
      // The line is too long. Force termination with '\r'
      istr[i - 1] = '\r';
    }
    
    PGMData* readPGM( PGMData *data)
    {
      File pgmFile;
      char version[3];
      char *p;
      int i, j;
      int lo, hi;
    
      if (!SD.begin(BUILTIN_SDCARD)) {
        Serial.println("Failed to mount card read pgm");
      }
      pgmFile = SD.open("/image.pgm", FILE_READ);
      if (!pgmFile) {
        Serial.println("Opening file to read failed read pgm");
        // No point continuing
        while(1);
      }
    
      // Read the version string
      version[0] = pgmFile.read();
      version[1] = pgmFile.read();
      version[2] = 0;
      // Ignore the whites[ace that follows the P5 */
      SkipComments(pgmFile);
      if (strcmp(version, "P5")) {
        Serial.printf("Wrong file type!\n");
        while(1);
      }
      // read the line containing the dimensions
      // of the image
      readln_istr(pgmFile);
      // parse the line
      // get the number of columns
      data->col = atoi(istr);
      for(p = istr; *p != ' ' && *p; p++);
      p++;
      // and the number of rows
      data->row = atoi(p);
    
      // Read the line containing the max_gray value
      readln_istr(pgmFile);
      data->max_gray = atoi(istr);
    
    Serial.printf("file dimensions %d x %d : Max_gray = %d\n",data->col,data->row,data->max_gray);
    
      data->matrix = allocate_dynamic_matrix(data->row, data->col);
      if (data->max_gray > 255) {
        for (i = 0; i < data->row; ++i) {
          for (j = 0; j < data->col; ++j) {
            hi = pgmFile.read();    //fgetc(pgmFile);
            lo = pgmFile.read();   //fgetc(pgmFile);
            data->matrix[i][j] = (hi << 8) + lo;
          }
        }
      } else {
        for (i = 0; i < data->row; ++i) {
          for (j = 0; j < data->col; ++j) {
            lo = pgmFile.read();   //fgetc(pgmFile);
            data->matrix[i][j] = lo;
          }
        }
      }
    
      pgmFile.close();
      return data;
    
    }
    
    void setup()
    {
      // put your setup code here, to run once:
      Serial.begin(115200);
      while (!Serial) {};
      PGMData im;
      readPGM( &im);
    
      Serial.print("The size of image = ");
      Serial.println(im.col);
      Serial.println(im.row);
    }
    
    void loop()
    {
      // put your main code here, to run repeatedly:
    
    }
    Pete

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •