0

I'm having some trouble trying to read and loop through the card.raw file. I'm not running into any errors though I can't figure out why when I call fread I continually get 0 as a return value. My code is below. Thanks in advance!!

    //Recover 50 jpeg's from the file called card.raw

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

    int main(int argc, char *argv[])
    {
    // ensure proper usage
    if (argc != 2)
    {
        fprintf(stderr, "You need to supply one argument only.  This argument must be a file name\n");
        return 1;
    }

    char *infile = argv[1];

    printf("This is the file: %s\n", argv[1]);

    FILE *inptr = fopen(infile, "r");

    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 2;
    }

    int count = 0;

    //This while loop counts each byte of the file so I know how many total bytes are in the file
    while(fgetc(inptr) != EOF)
    {
    count++;
    }

    //Buffer for fread to store each block I'm looking at reading
    int buf[128];

    //printf("%i", count);

    //This array will be used to store the jpg data once I find the blocks
    //char *outPut;

    //I want to see how many times the loop runs
    int loopCount = 0;
    size_t fr = 1;

    do{

            //fread(data, size, number, inptr)
            //128 integers equals 512 bytes as each integer is 4 bytes per int
            fr = fread(buf, 512, 1, inptr);

            printf("This is fr: %zu\n", fr);

            //printf("%lu\n\n", sizeof(buf));//Integers are four bytes and chars are one byte

            //See if we can find a match so it is a jpg
            if(buf[0] == 0xff &&
                buf[1] == 0xd8 &&
                buf[2] == 0xff &&
                //Check the last byte for 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5,
                //0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, of 0xef
                (buf[3] & 0xf0) == 0xe0)
                {

                    //DO SOMETHING HERE ONCE I FIND THE DATA I'M LOOKING FOR!!!!!!!!!!!!!!!!!!!!

                }//End if statement


                loopCount++;


        } while(fr >= 1);//End while loop if fread returns less than 1

        printf("This is the buffer sizeof size:  %lu\n", sizeof(buf));
        printf("This is how many times the loop iterated through 1 block of size 512:  %i\n", loopCount);

        //Tested to here without errors **************************************************************************************************************


    // close infile
    fclose(inptr);

    return 0;
    }
1

Don't use int buf[128]; but uint8_t buf[512];, or BYTE buf[512];, or unsigned char buf[512];. With int, the first four bytes would be stored together in buf[0], and your test would have to be different.

Oh, and remove the counting loop. You know you're at the end of the file if fread no longer returns 1.

The counting loop makes things worse: You consume the whole file (the read pointer is at its end), and your fread has nothing left, unless you fseek(inptr, 0, SEEK_SET);. But you don't need the total file size, and you could get it easier, for example: fseek(inptr, 0, SEEK_END); count = ftell(inptr); fseek(inptr, 0, SEEK_SET); (no read operation involved)

1
  • Thank you for your help!!! I have no idea why it never even dawned on me to comment out the fgetc call I made earlier. I completely ignored the fact I used it earlier and the FILE pointer would have been at the EOF. That and the fact I was using int buf[128] and not uint8_t made a ton of sense also. – ndjustin20 Feb 20 '18 at 17:27
2

Lets look at some info provided in the Problem Set:

  1. JPEG signature: 0xff 0xd8 0xff 0xe0-0xef

  2. Each photo is stored immediately after the previously taken photo

  3. The image will be formatted with the FAT filesystem, where the block size is 512 Bytes.
    Therefore the camera only writes to the image in units of 512 B.

B     8 Bits
KB    2^10 = 1024 Bytes
MB    2^20 = 1,048,576 Bytes
@see http://digital.ni.com/public.nsf/allkb/0F8C8B70234EBE308625708B00424DAD
  1. Thanks to FAT, you can trust that JPEGs' signatures will be "block-aligned."
    That is, you need only look for those signatures in a block’s first four bytes.

  2. The memory card was brand-new when used; therefore you can assume that the "slack space" is filled with 0s.

We need to define a FAT block (ha!)

Since we will be reading "block-aligned" (i.e., in order) datasets we can't use an array to store these data sets - arrays are affected by Endianess.

Recall from whodunit.c that you've been asked to investigate the stdint.h file which exposes the uint8_t data type that should be used in our situation:

#include <stdint.h>
#define FAT_BLOCK_SIZE 512

// get a FAT block of memory
uint8_t *fat_block_ptr = malloc(FAT_BLOCK_SIZE);
if (fat_block_ptr == NULL)
{
    fprintf(stderr, "not enough memory to perform this operation\n");
    return 3;
}

Reading FAT blocks

Now that you have a block that can hold your data in the same order the FAT filesystem does, you need to populate it with data sets, iterating over the image.raw file until the fread() function can no longer return a valid data set (i.e instead returning 1 it returns 0).

// while can read a FAT block from image
while (fread(fat_block_ptr, FAT_BLOCK_SIZE, 1, img_ptr) == 1)
{
    // your algorithm
} // while

Your Algorithm

Now all that's left to do is write your algorithm :)

1
  • Thank you for posting I appreciate it. Although I'm able to get it to work without using memory management now I'm going back through my code to ensure I'm managing memory based off your feedback. Thank you for helping me to better understand and resolve this problem. – ndjustin20 Feb 20 '18 at 17:41

You must log in to answer this question.

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