I changed the code from the first time I asked this question, so I decided to make a new thread. Sorry if this is not a good idea.
Anyway, I'm still getting a Seg fault here.
And even if that weren't the case, I do have trouble figuring out how to check for when the current JPEG ends and the next one starts. I do know what bytes can potentially be used in the signature of a JPEG, and I also know that they're stored contiguously in a CF card. But I'm not really sure how to check for it. I was thinking of making an array to store the four bytes after each 512 minus 4 bytes and checking if the bytes in the array represent the signature of a JPEG. But I'll need to see how to write that in actual code as right now it's just in my head and I'm having trouble figuring out how to express it in code. Like, for instance, if the buffer of 512 bytes from the card.raw file that I'm reading into each time through the loop is an array of uint8_t called "buffer," do I add the first four bytes from that into an array and check if it's the right signature, and if it is, I look at the next 512th byte after that and the next three bytes after it? But will the cursor move if I do that, or will I not have to worry about that?
Here's the updated code:
/**
* recover.c
*
* Computer Science 50
* Problem Set 4
*
* Recovers JPEGs from a forensic image.
*/
/**
* psuedo code
* open card file
* repeat until end of file
* read 512 bytes into a buffer
* start of a new jpg?
* yes -->
* no -->
* already found a jpg?
* no -->
* yes -->
* close last jpg
* close card file
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main()
{
// open card file
FILE* infile = fopen("card.raw", "r");
// test if it was properly opened
if (infile == NULL)
{
printf("Could not open %s.\n", "card.raw");
return 1;
}
// create a string variable used
// when opening output file to write jpeg
char* title = malloc(8);
// create a boolean variable for checking
// if a new jpeg was found
int newimg = 1;
// buffer array to store being read or written
BYTE* buffer = malloc(512);
int img_number = 0;
// create file pointer to store
// to represent output file
FILE* img;
// repeat until end of file
while (!feof(infile) && fread(&buffer, 512, 1, infile) == 1)
{
// in this if and
// in the one nested in it
// check if a new jpeg is found
// and check if it's really
// a jpeg
if (newimg)
{
if (buffer[0] == 0xff && buffer[1] == 0xf8 && buffer[2] == 0xff && (buffer[3] >= 0xe0 || buffer[3] <= 0xef))
{
// yes
// found jpeg
// reset boolean
newimg = 0;
// write the name of the jpeg to output file
sprintf(title, "%3d.jpg", img_number);
// open file and write jpeg img data to it
img = fopen(title, "a");
fwrite(&buffer, 512, 1, img);
}
}
// checking if a jpeg was already found
else
{
// yes
if (buffer[0] == 0xff && buffer[1] == 0xf8 && buffer[2] == 0xff && (buffer[3] >= 0xe0 || buffer[3] <= 0xef))
{
// close the output file to stop reading into it
fclose(img);
// update img_number variable
// so that the next image's file name
// has one number greater in it as part of the
// file name
img_number++;
// write the name of the jpeg to the output file
// with the update number from img_number
sprintf(title, "%3d.jpg", img_number);
// open a new file to store the next jpeg
img = fopen(title, "a");
// write the data to the new file
fwrite(&buffer, 512, 1, img);
}
// no
else
{
// keep writing to current jpeg
// because we haven't found a new
// jpeg yet
fwrite(&buffer, 512, 1, img);
}
}
}
// no more sets of 512 bytes left to read
// close last jpg file
fclose(img);
// close card.raw
fclose(infile);
free(buffer);
free(title);
return 0;
}
Also, how do I fix the way I'm formatting the filename for the JPEGs, if it's currently incorrect?
Edit: I'm editing this to add the newly updated code.
/**
* recover.c
*
* Computer Science 50
* Problem Set 4
*
* Recovers JPEGs from a forensic image.
*/
/**
* psuedo code
* open card file
* repeat until end of file
* read 512 bytes into a buffer
* start of a new jpg?
* yes -->
* no -->
* already found a jpg?
* no -->
* yes -->
* close last jpg
* close card file
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main()
{
// open card file
FILE* infile = fopen("card.raw", "r");
// test if it was properly opened
if (infile == NULL)
{
printf("Could not open %s.\n", "card.raw");
return 1;
}
// create a string variable used
// when opening output file to write jpeg
char* title = malloc(8);
// create a boolean variable for checking
// if a new jpeg was found
int newimg = 1;
// buffer array to store being read or written
BYTE* buffer = malloc(512);
int img_number = 0;
// create file pointer to store
// to represent output file
FILE* img;
// repeat until end of file
while (!feof(infile) && fread(&buffer, 512, 1, infile) == 1)
{
// in this if and
// in the one nested in it
// check if a new jpeg is found
// and check if it's really
// a jpeg
if (newimg)
{
if (buffer[0] == 0xff && buffer[1] == 0xf8 && buffer[2] == 0xff && (buffer[3] >= 0xe0 && buffer[3] <= 0xef))
{
// yes
// found jpeg
// reset boolean
newimg = 0;
// write the name of the jpeg to output file
sprintf(title, "%03d.jpg", img_number);
// open file and write jpeg img data to it
if (fopen(title, "w") != NULL && img != NULL)
{
img = fopen(title, "w");
fwrite(buffer, 512, 1, img);
}
}
}
// checking if a jpeg was already found
else
{
// yes
if (buffer[0] == 0xff && buffer[1] == 0xf8 && buffer[2] == 0xff && (buffer[3] >= 0xe0 && buffer[3] <= 0xef))
{
// close the output file to stop reading into it
fclose(img);
// update img_number variable
// so that the next image's file name
// has one number greater in it as part of the
// file name
img_number++;
// write the name of the jpeg to the output file
// with the update number from img_number
sprintf(title, "%03d.jpg", img_number);
if (fopen(title, "w") != NULL && img != NULL)
{
// open a new file to store the next jpeg
img = fopen(title, "w");
// write the data to the new file
fwrite(buffer, 512, 1, img);
}
}
// no
else
{
if (img != NULL)
{
// keep writing to current jpeg
// because we haven't found a new
// jpeg yet
fwrite(buffer, 512, 1, img);
}
}
}
}
// no more sets of 512 bytes left to read
if (!fclose(img))
{
// close last jpg file
fclose(img);
}
// close card.raw
fclose(infile);
free(buffer);
free(title);
return 0;
}