I'm seriously struggling with this assignment and I can't seem to find the problem in my code.
I'm supposed to create a program that reads a raw card one block at a time with each block containing 512 bytes and write the blocks that are of a JPEG but I think you probably know this.
Basically I run this program with card.raw (usage: ./recover card.raw) but keep getting a segmentation fault with around 5000+ JPEGs being created. I've checked my code over and over to make sure I've used memory correctly but am failing to see where the problem is. Without the read and write functionality, however, the code actually succeeds in identifying the 50 individual JPEGs, so I know that my approach is roughly correct.
Any help would be greatly appreciated!
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#define BLOCK_SIZE 512 // defining a block size of 512
typedef uint8_t BYTE;
int main(int argc, char* argv[])
{
bool found = false; // Boolean that switches to true once the first file has been found
char filename[8]; // Array to store my filename
int file_count = 1; // Counter to keep track of the file number
BYTE buffer[512] = {0}; // This is the buffer where I will place 1 block of 512 bytes at a time from the raw file and write onto the JPEG files
if (argc != 2)
{
printf("Usage: ./r filename\n");
return 1;
}
// Open raw file
FILE *rawPtr = fopen(argv[1], "r");
if (rawPtr == NULL)
{
fclose(rawPtr);
printf("ERROR: CANNOT OPEN FILE.\n");
return 2;
}
FILE *outptr = NULL; // Declaring output file pointer as NULL
size_t bytesRead = fread(buffer, sizeof(BYTE), BLOCK_SIZE, rawPtr); // reading first 512 bytes and storing in buffer array AND storing number of bytes
// read in bytesRead
while (bytesRead != 0) // While loop keeps looping until the last block (EOF) has been attempted to be read but bytesRead holds value of 0
{
// Is the block the start of a JPEG?
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
// Has a JPEG been found yet?
if (found == true) // If JPEG has been found, close previous JPEG file, open new JPEG file with new name (hence file_count++) and write buffer array
{ // into new file
fclose(outptr);
file_count++;
sprintf(filename, "%03i.jpg", file_count);
outptr = fopen(filename, "w");
fwrite(buffer, sizeof(BYTE), BLOCK_SIZE, outptr);
}
else // If JPEG not found, must be first JPEG so open file and write buffer array into file
{
sprintf(filename, "%03i.jpg", file_count);
outptr = fopen(filename, "w");
fwrite(buffer, sizeof(BYTE), BLOCK_SIZE, outptr);
found = true;
}
}
else // If not start of JPEG ...
{
if (found == true) // If start of new JPEG not detected BUT JPEG has been previously found, append buffer onto latest JPEG file
{
fwrite(buffer, sizeof(BYTE), BLOCK_SIZE, outptr);
}
else // If start of new JPEG not detected AND no file has yet been detected, do nothing as it must not be part of JPEG
{
printf("Searching...\n");
}
bytesRead = fread(buffer, sizeof(BYTE), BLOCK_SIZE, rawPtr); // Read next 512 bytes and store in buffer array. I am assuming the previous 512 bytes
// will be overwritten. If end of file is reached, bytesRead will be 0 and while loop will quit
}
}
printf("%i JPEGs recovered\n", file_count); // Used this line to test whether the JPEGs were being identified and they indeed were (50 in total were found)
// so the problem seems to have come after introducing the code to read from and write into the files
fclose(outptr); // close last output/JPEG file
fclose(rawPtr); // close raw input file
return 0;
}
EDIT: