0

I am aware that the same question has been asked before: PSET4 Recover only finds 13/16 images

However, as far as I could try given this answer, I could not fix my function so it would successfully find all the JPGs(without just outright copying their code in its entirety).

int findAllJpg(FILE *ptr,unsigned char buffer[512], int blocks)
{
    int counter = 0
    int offset = 0;
    
    for(int i = 0; i<2048;i++)
    {   
        offset = 512 * i;
        fseek(ptr, offset, SEEK_SET);
        fread(buffer, 512, 1, ptr);
        for(int j = 0; j < 512; j++)
        {
            
            if(buffer[j] == 0xff)
            {
                //printf("Test 1 Passed\n");
                //printf("%u is next\n", buffer[i+1]);
                if(buffer[j+1] == 0xd8)
                {
                   // printf("Test 2 Passed\n");
                    if(buffer[j+2] == 0xff)
                    {
                        //printf("Test 3 Passed\n");
                        if((buffer[j+3] & 0xF0) == 0xe0 || buffer[j+3] == 0xe1)
                        {
                            printf("Test 4 Passed at %i block\n", i);
                            counter++;
                            
                        }
                    }
                }
            }
        }
    }
    printf("Counter: %i", counter);
    //Since there will be no JPG header in this block, the program returns -1, a value which can't exist in an array.
    return -1;
}

Any idea as to why only 13 of the images are being found?

Here is the rest of my code, as per Cliff's request. Don't cheat off of this anyone :)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int counter = 0;
int findJpg(unsigned char buffer[512], int blocks);
int recover(FILE *ptr, unsigned char buffer[512],int blocks, int fileNumber);
int findAllJpg(FILE *ptr,unsigned char buffer[512], int blocks);

int main(int argc, char *argv[])
{
    //DONE: Open a memory card file
    if((argc-1)< 1)
    {
        return 1;
    }
    FILE *ptr = fopen(argv[1], "r");
    //Store a 512 bit block in an array
    unsigned char buffer[512];
    bool writing = false;
    int blocks = 0;
    //DONE: Look for the beginning of a JPEG
    
    //TODO: Open a new JPG File To begin writing to
    int fileNumber = 0;
    int offset = 512 * blocks;
    
    
    while(blocks <= 2048)
    {
    offset = 512 * blocks;
    fseek(ptr, offset, SEEK_SET);
    fread(buffer, 512, 1, ptr);
    blocks = recover(ptr, buffer, blocks, fileNumber);
    fileNumber++;
    }
    
    
    
    
    //DONE: Write 512 Bytes till a new JPEG is found
    //DONE: Close old JPEG
    //DONE: Open New one
    //DONE: Repeat
    //DONE: Close "ptr"
    fclose(ptr);
    
    return 0;
}

int findJpg(unsigned char buffer[512], int blocks)
{
    
    int i = 0;
    if(buffer[i] == 0xff)
    {
        //printf("Test 1 Passed\n");
        if(buffer[i+1] == 0xd8)
        {
            //printf("Test 2 Passed\n");
            if(buffer[i+2] == 0xff)
            {
                //printf("Test 3 Passed\n");
                if((buffer[i+3] & 0xF0) == 0xe0)
                {
                    printf("Test 4 Passed at %i block\n", blocks);
                    
                    return i;
                    
                }
            }
        }
    }
    
    //Since there will be no JPG header in this block, the program returns -1, a value which can't exist in an array.
    return -1;
}

int recover(FILE *ptr, unsigned char buffer[512],int blocks, int fileNumber)
{
    char *filename = malloc(3);
    sprintf(filename, "%03i.jpg", fileNumber);
    
    FILE *img = fopen(filename, "w");
    
    bool found = false;
    while(found == false)
    {
        if(findJpg(buffer, blocks) > -1)
        {
            while(counter < 50)
            {
            
                fwrite(buffer, 512, 1, img);
                fread(buffer, 512, 1, ptr);
                blocks++;
                
                if(findJpg(buffer, blocks) > -1)
                {
                    found = true;
                    fclose(img);
                    counter++;
                    printf("Blocks: %i\n", blocks);
                    printf("Counter: %i\n", counter);
                    return blocks;
                }
            }
        }
        fread(buffer, 512, 1, ptr);
    }

    return -1;
}



//For debugging purposes
//Not for actual running of the program
//If you would like to see the actual function for finding the JPGs
//Please refer to "findJpg()"
int findAllJpg(FILE *ptr,unsigned char buffer[512], int blocks)
{
    int offset = 0;
    
    for(int i = 0; i<2048;i++)
    {   
        offset = 512 * i;
        fseek(ptr, offset, SEEK_SET);
        fread(buffer, 512, 1, ptr);
        for(int j = 0; j < 512; j++)
        {
            
            if(buffer[j] == 0xff)
            {
                //printf("Test 1 Passed\n");
                //printf("%u is next\n", buffer[i+1]);
                if(buffer[j+1] == 0xd8)
                {
                   // printf("Test 2 Passed\n");
                    if(buffer[j+2] == 0xff)
                    {
                        //printf("Test 3 Passed\n");
                        if((buffer[j+3] & 0xF0) == 0xe0 || buffer[j+3] == 0xe1)
                        {
                            printf("Test 4 Passed at %i block\n", i);
                            counter++;
                            
                        }
                    }
                }
            }
        }
    }
    printf("Counter: %i", counter);
    //Since there will be no JPG header in this block, the program returns -1, a value which can't exist in an array.
    return -1;
}
0

I think I know what the problem is just by reading the title. But, the code I'd need to see isn't in the post.

Or, the problem is this: Are you using the 2020 pset and distro? Or are you using one from 2015? (There are 50 files this year, are you using this year's distro?)

Almost always, when the problem is only half of the files being recovered , the problem is due to two consecutive freads that throw away half the data. It usually looks like this:

while(fread(buffer,512,1,cardfile) )
{
    fread(buffer,512,1,cardfile);

It's due to an errroneous belief that the while statement only tests for EOF (tests the return value) but doesn't actually execute the fread. IT DOES EXECUTE THE READ!!! Then the second fread executes and replaces the data just read by the first call to fread.

However, if you're doing the 2015 version of the file, the code isn't making the correct checks. You would need to update the code to the current year's code and requirememts!

If this isn't the problem, please post the entire code for testing.

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

| improve this answer | |
  • I will update the code in the post with the rest of my code right now – Ruben Alias Aug 4 at 19:51
  • Also I executed the command wget https://cdn.cs50.net/2019/fall/psets/4/recover/recover.zip that they put on the pset 4 recover page, unless they changed it within the last few days. – Ruben Alias Aug 4 at 19:54
  • Hey Cliff I posted all the code – Ruben Alias Aug 5 at 17:52

You must log in to answer this question.

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