0

I have some issues with this code it just prints the very first part of the image right and the rest of it just a gray screen can anyone help please.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

typedef uint8_t BYTE;


int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./recover image\n");
        return 1;
    }
    else
    {
        // This line is to open the card.
        FILE *memory = fopen(argv[1], "r");
        if (memory == NULL)
        {
            printf("Error reading this file\n");
            return 1;
        }

        // This file is to store whatever is before jpeg files.
        FILE *nothing_file = fopen("nothing_file", "w");

        int num_of_files = 0;
        // To use files that Im going to make I will say.
        FILE *new_file = NULL;
        // Im going to use (do while) loop because i want the compiler to proceed then check so if it got to the last part it will proceed then it will know that it reached the end of the file.
        unsigned char Buffer[512];
        int x;
        // This codition if the compiler found the begginning of the jpeg files.
        int condition = 0;
        do
        {
            // To hold a name of 7 digits I will do.
            char name[7];

            // To check if its the beginning of jpeg file.
            if ((unsigned char)Buffer[0] == 0xff && (unsigned char)Buffer[1] == 0xd8 && (unsigned char)Buffer[2] == 0xff && (((unsigned char)Buffer[3] & 0xf0) == 0xe0))
            {
                condition = 1;
                // To check if this is the first file.
                if (num_of_files == 0)
                {
                    if (new_file != NULL)
                    {
                        fclose(new_file);
                    }
                    sprintf(name, "%03i.jpg", num_of_files);
                    new_file = fopen(name, "a");
                    /*memcpy( new_file, memory, *Buffer);*/
                    fwrite(&Buffer, 512, 1, new_file);
                    num_of_files++;

                }
                else
                {
                    // If it wasn`t the first file.
                    fclose(new_file);
                    sprintf(name, "%03i.jpg", num_of_files);
                    num_of_files++;
                    new_file = fopen(name, "a");
                    /*memcpy( new_file, memory, *Buffer);*/
                    fwrite(&Buffer, 512, 1, new_file);
                }
            }
            else
            {
                if (condition == 0)
                {
                    
                    /*memcpy( nothing_file, memory, *Buffer);*/
                    fwrite(&Buffer, 512, 1, nothing_file);
                    
                }
                else
                {
                    // If it wasn`t the name of the file.
                    /*memcpy( new_file, memory, *Buffer);*/
                    fwrite(&Buffer, 512, 1, new_file);
                }
            }
        }while(fread(&Buffer, 512, 1, memory));
        

        // To close after finishing reading.
        fclose(new_file);
        fclose(memory);
    }
}
1

There are several issues with the code.

First, there's this: char name[7]; It's too short by 1. There needs to be room for the 7 char file name plus the end of string marker '\0'! Without that 8th byte, the code is going to step on whatever is next in physical memory. C won't register an error if the write goes past the end of the memory allocated to an array. In this program, it usually happens to be the buffer, so the first byte of the file gets stepped on.

Second problem: The output files are opened for append. They should be opened for write. In append mode, if the file already exists (say, after you've started testing), then the program will just add to the existing file. When a file is opened in write mode, if the file already exists, it will be erased or deleted. It's not necessary to open a file in append mode to keep writing to it. Once opened, a file will keep accepting more data.

Third, the code should use a while loop, not a do/while loop, especially when the fread is part of the while statement. In this case, on the first pass, the code is processing the contents of the buffer before anything is ever written to it. (Fortunately, since it's all zeros, it does no harm.)

Programming notes:

Look carefully at the two blocks of code in the if code block that checks for the signature.

Both blocks will check to see if there's already an open file, and will close it if there is. Both will then create a file name and open a new output file. That's a big red flag that the code can be consolidated and duplicated code can be removed. It can easily be done. I'll leave it to you to figure out how.

It isn't necessary to write the garbage data at the front of the input file out to a nothing_file. The data can simply not be processed, and overwritten by the next read. No need to waste disk space or processing time and resources to do these writes.

It's also not necessary to cast Buffer[0] or any other elements of the Buffer array as unsigned int. They are already declared as unsigned ints at creation.

You would do well to always go back and look at your code periodically to see if it can be streamlined. This can be useful once its working as well as when it has bugs. You'll benefit from doing that too, especially while you're learning to code!

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

You must log in to answer this question.

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