-
January 21st, 2013, 02:56 PM
#1
Optimizing jpeg recovery code
Hello guys,
I'm taking a CS course and we've been tasked with creating a program that recovers jpegs from a formatted CF card which uses the FAT file system with a block size of 512 bytes, the jpegs in the card are block aligned which means that the beginning of a jpeg marks the end of the former.
I've wrote the program and it works nicely and recovers the 51 jpegs in the CF card (actually just an image of some 4-5 megabytes of the actual card which can be downloaded here) but I'm looking for ways to optimize/improve my code so I need a second look from experienced programmers.
Here's my code:
Code:
/*
* filename : recover.c
* author : ####
* username : ####
* course : ####
* description : Recovers jpegs from a forensic image
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define BLOCK 512 // fat file system block size
int main(void)
{
// open CF card image
FILE* img = fopen("card.raw", "r");
if (img == NULL)
{
fprintf(stderr, "Could not open forensic image %s.\n", "card.raw");
return 1;
}
int num = 0; // keep track of retrieved files
FILE* jpeg = NULL; // output file
char fileName[8]; // file name
char sig1[4] = {0xff, 0xd8, 0xff, 0xe0}; // jpeg files #1 signature
char sig2[4] = {0xff, 0xd8, 0xff, 0xe1}; // jpeg files #2 signature
// make buffer to hold blocks of data, and read first block
char* buffer = malloc(BLOCK);
fread(buffer, BLOCK, 1, img);
// traverse img for jpegs and retrieve them
while (!feof(img))
{
// jpeg signatures not found yet
bool found = false;
if (num == 0) // find first jpeg
{
for (int i = 0; i < BLOCK; i += 4)
{
if (memcmp(sig1, &buffer[i], 4) == 0 ||
memcmp(sig2, &buffer[i], 4) == 0)
{
// set file name and open file
sprintf(fileName, "%.3d.jpg", num);
found = true;
num += 1;
}
}
}
else // check first four bytes only
{
if (memcmp(sig1, buffer, 4) == 0 ||
memcmp(sig2, buffer, 4) == 0)
{
// set file name and open file
sprintf(fileName, "%.3d.jpg", num);
found = true;
num += 1;
}
}
/* if already writing to a jpeg continue,
* else start writing to a new one
*/
if (found == false && num != 0)
{
fwrite(buffer, BLOCK, 1, jpeg);
}
else if (found == true)
{
if (num == 1)
{
jpeg = fopen(fileName, "w");
fwrite(buffer, BLOCK, 1, jpeg);
}
else
{
fclose(jpeg);
jpeg = fopen(fileName, "w");
fwrite(buffer, BLOCK, 1, jpeg);
}
}
// read next block from file
fread(buffer, BLOCK, 1, img);
}
fclose(jpeg);
fclose(img);
free(buffer);
return 0;
}
My questions are:
1) What are the possible optimizations that can make my code faster/better/more concise?
2) I'm not handling slack space, since trailing zeros at the end of a jpeg won't affect rendering it (we were told it won't contain any garbage values)... how may I approach the problem?
3) Can I enhance my if else constructs? or even replace them with something more elegant?
Much thanks in advance guys.
Last edited by VeNiX; January 21st, 2013 at 03:00 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|