CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 17

Threaded View

  1. #1
    Join Date
    Apr 2012
    Posts
    15

    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
  •  





Click Here to Expand Forum to Full Width

Featured