0

The images are created but come back as blurry messes. I can't see my bug so I'm hoping to get a hint.

int main(int argc, char *argv[]){
  // take in single card name
  if(argc > 2){
    fprintf(stderr, "Too many args. Should be two.\n");
    return 1;
  } else if (argc < 2){
    fprintf(stderr, "Too few args. Should be two.\n");
    return 1;
  }

  //card.raw
  char *infile = argv[1];

  //fopen card.raw
  FILE *inptr = fopen(infile, "r");
    if(inptr == NULL)
    {
      fprintf(stderr, "Could not open %s.\n", infile);
      return 1;

    }
  // make BYTE a data type from bmp spec
  typedef uint8_t  BYTE;
  // // assign buffer 512 bytes
  BYTE buffer[512];
  // count files
  int fileCount = 0;
  // filename arr
  char filename[8];
  // assign file pointer
  FILE *img = NULL;

  // fread returns 1 after every 512 chunk
  while(fread(buffer, 512,1,inptr) == 1){

    // new jpeg
   if(buffer[0] == 0xff &&
      buffer[1] == 0xd8 &&
      buffer[2] == 0xff &&
      (buffer[3] & 0xf0) == 0xe0){

      // already exists, so close
        if(img != NULL){
          fclose(img);
          //reset img to NULL
          img = NULL;
          printf("%i closed:\n", fileCount);

          // increment file count before making new one
          fileCount++;
          printf("%i\n", fileCount);
        }

        printf("%i create new:\n", fileCount);
        sprintf(filename,"%03i.jpg",fileCount);
        img = fopen(filename, "w");
        fwrite(buffer, 512,1,img);

      }

      if(img != NULL){
    printf("%i writing to\n", fileCount);
        fwrite(buffer, 512,1,img);
      } else {
        puts("do nothing");
      }

  }

  fclose(img);
  fclose(inptr);

  return 0;
}

PS- I know fileCount++ is in a weird spot potentially, but moving it doesn't make a difference. Problem here seems to be with each file not getting enough bytes.

I used ls -al *.jpg and files are not all 512 so something is happening, but not sure what since the data flow seems to be correct-ish

1 Answer 1

2

Let's look at the following and see what it does:

 while(fread(buffer, 512,1,inptr) == 1){

    // new jpeg
   if(buffer[0] == 0xff &&
      buffer[1] == 0xd8 &&
      buffer[2] == 0xff &&
      (buffer[3] & 0xf0) == 0xe0){

      ...

        img = fopen(filename, "w");
        fwrite(buffer, 512,1,img);

      }

      if(img != NULL){
    printf("%i writing to\n", fileCount);
        fwrite(buffer, 512,1,img);

      ...
    }

When a signature is found, it opens a new file and calls fwrite() to write the current 512 bytes in buffer to the file. Then, if an output file is open, it writes the same 512 bytes out to the file before looping around and reading the next block.

Do you think there might be an issue with writing the first 512 bytes of the header twice?

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

2
  • I added an else in front if the if(img != NULL) and now the images are clear and all the tests pass. That was such a simple fix.
    – Mote Zart
    Commented Apr 1, 2018 at 4:39
  • That's one fix. Another would have been to delete the first fwrite. Which is right? It depends. Do you want the code to execute faster or to be written with less lines? Think about which is which, or is it more efficent both as code and execution speed to eliminate the first read and the else, leaving just the if? Think about it. ;-)
    – Cliff B
    Commented Apr 1, 2018 at 4:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .