The instructions for "recover.c" in pset4 seem to indicate that all the jpeg photos will be aligned with a block of 512... eg, I only need to check the first 4 bytes starting at 0, 512, etc to find matches.
I wrote a program initially that only checked every 512 bytes, and only found one match.
Curious, I changed it from 512 bytes to 1 byte, and voila! I got 50 matches. I also printed out the location of each match... and they don't seem to start at 512-byte intervals.
So either something is wrong with my program, or I am failing to understand what the assignment description means when it talks about jpgs being at the start of blocks.
(I will admit, the description already confuses me, as it says both that a new file will end immediately after an old one closes, but also that there can be trailing 0s after the end of a jpg to the beginning of the next block. To me, these seem like contradictory statements, but I suspect I am confused there as well.)
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// #define CARD_SIZE 17095168;
typedef uint8_t BYTE;
typedef struct
{
BYTE first;
BYTE second;
BYTE third;
BYTE fourth;
} __attribute__((__packed__))
STARTBYTES;
int main(int argc, char* argv[])
{
FILE* inptr = fopen("card.raw", "r");
//should check for error opening file
STARTBYTES sb;
int pic_count = 0;
for(int i =0; i < 17095168 /*CARD_SIZE*/; i += 1/*512*/){
fread(&sb, sizeof(STARTBYTES), 1, inptr);
if (sb.first == 0xff && sb.second == 0xd8 && sb.third == 0xff){
printf("Found an image at %i.\n", i);
pic_count++;
}
}
printf("Found a total of %i matches.\n", pic_count);
fclose(inptr);
}
The output:
Found an image at 256. Found an image at 188288. Found an image at 224768. Found an image at 258176. Found an image at 273664. Found an image at 1991936. Found an image at 2020736. Found an image at 2031488. Found an image at 2126720. Found an image at 2173952. Found an image at 2231808. Found an image at 2288256. Found an image at 2365824. Found an image at 2433408. Found an image at 2507264. Found an image at 2540288. Found an image at 2652928. Found an image at 2715648. Found an image at 2774272. Found an image at 2801792. Found an image at 2900096. Found an image at 2931968. Found an image at 2977792. Found an image at 3022336. Found an image at 3060608. Found an image at 3085440. Found an image at 3131648. Found an image at 3137664. Found an image at 3181568. Found an image at 3201408. Found an image at 3261440. Found an image at 3273856. Found an image at 3313792. Found an image at 3326464. Found an image at 3352192. Found an image at 3413760. Found an image at 3443072. Found an image at 3465600. Found an image at 3492352. Found an image at 3520896. Found an image at 3547648. Found an image at 3585024. Found an image at 3688832. Found an image at 3705216. Found an image at 3780864. Found an image at 3844352. Found an image at 3855488. Found an image at 3907840. Found an image at 3948160. Found an image at 4253952.
Found a total of 50 matches.
(note: my real code inserts new lines after each one, but I'm not going to put spaces after every entry here!)
What gives? Am I wrong that the jpegs were supposed to start at a block of 512? Or is my code creating the wrong output somehow?
As a bonus question: as you can see from what I commented out, I initially wanted to define CARD_SIZE as the size of the file (which I checked using ls -l on the jpg folder), but that failed; can you point me to what I'm doing wrong therE?
Update:
Here is the relevant correct code for what I am trying to do (the answer below by Cliff, which I marked as correct, asked me to use a different approach entirely, which is in line with what Zamyla suggests and certainly a good idea, but I'll never learn why my instinctive approach is wrong if I don't work on it until I find an insurmountable problem or an explanation of why it's inferior!)
for(int i =0; i < 17095168/512 /*CARD_SIZE*/; i++)
{
fseek(inptr, i*512, SEEK_SET);
fread(&sb, sizeof(STARTBYTES), 1, inptr);
fseek(inptr, - 4, SEEK_CUR);
if (sb.first == 0xff && sb.second == 0xd8 && sb.third == 0xff && sb.fourth >= 0xe0 && sb.fourth <= 0xef){)
{
printf("Found an image at %i.\n", i * 512);
pic_count++;
}
//...
There were a few problems. First, I wasn't setting the read head back 4 spaces after the fread. Second, my loop wasn't doing anything to specify where to read from; it was just iterating once for every byte of the file. I forgot to make the read head change relative to the current iteration.
So from this skeleton code, I don't see why I won't be able to store new jpgs. This also successfully checks only each 512th byte. I guess if I get it working, I'll post a followup question to the boards: if I can do it without creating a 512b temporary buffer, why not do it that way?
PS: 1) I assume there is a trivial command to check the size of a file, which I would use instead of manually entering the size of the file. 2) I'm also interested in why my #DEFINE CARD_SIZE didn't work, letting me plug "CARD_SIZE" into i < CARD_SIZE/512, but I can probably figure that out on my own once I fix the more pressing problems.