#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0

    Smile Help with a program to recover an image


    Hi again,

    I am working on a program to recover 51 images from a .raw file.

    Any slack space is filled with 0's so what I need to do, is look for the start of an image by its signature then, copy all I see to an out-file until a start signature is seen again, then the process is repeated.

    Here is the code I have so far:


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <cs50.h>
    
    int main(void)
    {
    // open input file 
    FILE* inptr = fopen("card.raw", "r");
    if (inptr == NULL)
    {
        printf("Sorry, me noes able to open the file!!!\n");
        return 2;
    }
    
    int timeslooped = 0;
    
    bool jpegfoundbefore = false;
    
    int number = 0;
    
    int block_size = 512;
    
    BYTE buffer [512];
    
    char image_name[8];
    
    // untill eof is reached
    while (feof(inptr) == false)
    {
         //copy 512 bytes into buffer
         fread(buffer, block_size, 1, inptr);
         
         if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] == 0xe0 || buffer[3] == 0xe1)
         {
            // if a previous jpeg was found close file 
                if (jpegfoundbefore == true)
                {
                    fclose(outptr);
                }
    
                jpegfoundbefore = true;
     
                // name the image
                sprintf(image_name, "%.3d.jpg", number);
                number++; 
                
                // create the new jpg image file
                outptr = fopen (image_name, "w");
                if (outptr == NULL)
                {
                    printf("could not create jpeg file\n");
                    return 2;
                }     
                
                // write 512 byte block to current jpeg file 
                fwrite(buffer, block_size, 1, outptr);        
          }
    
          // continue writing parts of a jpg to file on disk 
          else if (jpegfoundbefore == true)
          {
              fwrite(buffer, block_size, 1, outptr);        
          } 
     
     
    }
    
    // close card.raw 
    fclose(inptr);
    
    // close last jpg
    fclose(outptr);
    
    }
    The problem is I am getting 13 errors all related to undeclared identifiers... Here is what the compiler is spitting out:

    jharvard@appliance (~/Dropbox/pset4/jpg): make recover
    clang -ggdb3 -O0 -std=c99 -Wall -Werror recover.c -lcs50 -lm -o recover
    recover.c:76:1: error: use of undeclared identifier 'BYTE'
    BYTE buffer [512];
    ^
    recover.c:84:12: error: use of undeclared identifier 'buffer'
    fread(buffer, block_size, 1, inptr);
    ^
    recover.c:86:10: error: use of undeclared identifier 'buffer'
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] == 0xe0 || buffer[3] == 0xe1)
    ^
    recover.c:86:31: error: use of undeclared identifier 'buffer'
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] == 0xe0 || buffer[3] == 0xe1)
    ^
    recover.c:86:52: error: use of undeclared identifier 'buffer'
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] == 0xe0 || buffer[3] == 0xe1)
    ^
    recover.c:86:73: error: use of undeclared identifier 'buffer'
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] == 0xe0 || buffer[3] == 0xe1)
    ^
    recover.c:86:94: error: use of undeclared identifier 'buffer'
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] == 0xe0 || buffer[3] == 0xe1)
    ^
    recover.c:91:24: error: use of undeclared identifier 'outptr'
    fclose(outptr);
    ^
    recover.c:101:13: error: use of undeclared identifier 'outptr'
    outptr = fopen (image_name, "w");
    ^
    recover.c:102:17: error: use of undeclared identifier 'outptr'
    if (outptr == NULL)
    ^
    recover.c:109:20: error: use of undeclared identifier 'buffer'
    fwrite(buffer, block_size, 1, outptr);
    ^
    recover.c:115:18: error: use of undeclared identifier 'buffer'
    fwrite(buffer, block_size, 1, outptr);
    ^
    recover.c:125:8: error: use of undeclared identifier 'outptr'
    fclose(outptr);
    ^
    13 errors generated.
    make: *** [recover] Error 1


    Any help to remove the errors and point out any other problems with my code would be GREAT!!!

    NOTE: I also have a thread going on another program that I am writing to resize an image, if you would like to take a look at that, and give me some feedback, that would be great:

    http://forums.devshed.com/c-programming-42/help-with-a-program-to-resize-an-image-940226.html
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,696
    Rep Power
    480
    main should return a value. You've only returned an error code in one case.

    Let's discard cs50.h, discard your unused variables, and insert these definitions and declaration.
    Code:
    #define false 0
    #define true 1
    typedef int bool;
    typedef unsigned char BYTE;
    
    int main(void) {
      FILE*outptr;			/* declare outptr */
    That reduces the compiler messages to (my line numbers vary)
    c.c:26:5: warning: suggest parentheses around && within || [-Wparentheses]

    Otherwise, you have assumed that you know the value of false, defeating the purpose of the name.

    while (feof(file_pointer) == 0)

    instead of using false for 0 .

    I write (! feof) , read as "not eof of file".

    Beyond that, I don't know if your program works.


    I see that you also link with cs50 . Unlikely, but possible that cs50 supplies its own main function and has redefined main to mean something else. Thereby your professor could cleverly collect some sort of information before calling your "main". So maybe you need cs50.
    Last edited by b49P23TIvg; February 22nd, 2013 at 03:57 PM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    main should return a value. You've only returned an error code in one case.

    Let's discard cs50.h, discard your unused variables, and insert these definitions and declaration.
    Code:
    #define false 0
    #define true 1
    typedef int bool;
    typedef unsigned char BYTE;
    Code:
    Ok that all makes sense to me and is done.
    
    
    int main(void) { FILE*outptr; /* declare outptr */
    I added in the FILE*outptr; and that removed an error, but do I still need to declare outptr... If so how do I do that???
    That reduces the compiler messages to (my line numbers vary)
    c.c:26:5: warning: suggest parentheses around && within || [-Wparentheses]

    Otherwise, you have assumed that you know the value of false, defeating the purpose of the name.
    I think I know what you mean, I have implemented the changes as best as I can.

    while (feof(file_pointer) == 0)

    instead of using false for 0 .

    I write (! feof) , read as "not eof of file".

    Beyond that, I don't know if your program works.
    That also makes sense, and I have changed it

    I see that you also link with cs50 . Unlikely, but possible that cs50 supplies its own main function and has redefined main to mean something else. Thereby your professor could cleverly collect some sort of information before calling your "main". So maybe you need cs50.
    As far as I know all cs50.h is not needed, the original reason for having it was that it simplifies a few functions, but I didn't end up using them any ways so I removed it.


    Here is my code now:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define false 0
    #define true 1
    
    typedef int bool;
    typedef unsigned char BYTE;
    
    int main(void)  {
    
    FILE*outptr;
    
    // open input file 
    FILE* inptr = fopen("card.raw", "r");
    if (inptr == NULL)
    {
        printf("Sorry, me noes able to open the file!!!\n");
        return 2;
    }
    
    int timeslooped = 0;
    
    bool jpegfoundbefore = false;
    
    int number = 0;
    
    int block_size = 512;
    
    BYTE buffer [512];
    
    char image_name[8];
    
    // untill eof is reached
    while (! feof(inptr) == 0)
    {
         //copy 512 bytes into buffer
         fread(buffer, block_size, 1, inptr);
         
         if (buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) && (buffer[3] == 0xe0) || (buffer[3] == 0xe1)
         {
            // if a previous jpeg was found close file 
                if (jpegfoundbefore == true)
                {
                    fclose(outptr);
                }
    
                jpegfoundbefore = true;
     
                // name the image
                sprintf(image_name, "%.3d.jpg", number);
                number++; 
                
                // create the new jpg image file
                outptr = fopen (image_name, "w");
                if (outptr == NULL)
                {
                    printf("could not create jpeg file\n");
                    return 2;
                }     
                
                // write 512 byte block to current jpeg file 
                fwrite(buffer, block_size, 1, outptr);        
          }
    
          // continue writing parts of a jpg to file on disk 
          else if (jpegfoundbefore == true)
          {
              fwrite(buffer, block_size, 1, outptr);        
          } 
     
     
    }
    
    // close card.raw 
    fclose(inptr);
    
    // close last jpg
    fclose(outptr);
    
    }
    It is WAY better but I am still getting 1 error:

    jharvard@appliance (~/Dropbox/pset4/jpg): make recover
    clang -ggdb3 -O0 -std=c99 -Wall -Werror recover.c -lcs50 -lm -o recover
    recover.c:93:32: error: expected identifier
    if (buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) && (buffer[3] == 0xe0) || ...
    ^
    1 error generated.
    make: *** [recover] Error 1


    Any ideas what might be causing it???
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,696
    Rep Power
    480
    if ((((((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) && (buffer[3] == 0xe0) || (buffer[3] == 0xe1))))))

    get it?

    I'm sure the syntax for an "if" statement contains

    if ( expression )

    Parenthesizing the equality tests is good, but the issue was about clear grouping the terms of && and || .
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    SO CLOSE!!!

    What you said makes sense, and I made the change you recommended... BUT I now have a new error:

    jharvard@appliance (~/Dropbox/pset4/jpg): make recover
    clang -ggdb3 -O0 -std=c99 -Wall -Werror recover.c -lcs50 -lm -o recover
    recover.c:93:80: error: '&&' within '||' [-Werror,-Wlogical-op-parentheses]
    if ((((((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) && (buffer[3] == 0xe0) || ...
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~ ~~
    recover.c:93:80: note: place parentheses around the '&&' expression to silence this warning
    if ((((((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) && (buffer[3] == 0xe0) || ...
    ^
    ( )
    1 error generated.


    Any ideas???

    Thanks,
    Josh
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    185
    Rep Power
    82
    The correct way to get the jpg magic number:

    Code:
     if (buffer[0] == 0xFF &&
                buffer[1] == 0xD8 &&
                buffer[2] == 0xFF &&
                (buffer[3] == 0xE0 || buffer[3] == 0xE1))
  12. #7
  13. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,363
    Rep Power
    1870
    Seems like a hacked mashup of this to me (not that I have any illusion that the cprogramming.com version is original anyway). google finds about 20 sites for people messing about with "card.raw" files.

    Apart from a few variable renames, the structure is remarkably similar. The naming of output files is very specific, and identical in both files.

    You see, in reality, nobody would write that much code and then come over all dumb and stupid not knowing what BYTE was, if they had actually written BYTE themselves when coding it in the first place.

    You're just another wannabe copy/paster.

    Comments on this post

    • Dude22 disagrees : I disagree entirely, the program I wrote was not copied from the forum you refrensed, I, using information, psudocode, and some code from Harvards OWN forms came to the program I first posted!
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0

    Unhappy I will be back in a few days.


    Hi everyone, thanks for your responses, unfortunately my home experienced a power surge last night and it killed my computer's hard drive. Lucky I am a meticulous backuper so I should be back up and running in a few days.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    Originally Posted by BobS0327
    The correct way to get the jpg magic number:

    Code:
     if (buffer[0] == 0xFF &&
                buffer[1] == 0xD8 &&
                buffer[2] == 0xFF &&
                (buffer[3] == 0xE0 || buffer[3] == 0xE1))
    OK, I made that change and now NO ERRORS but... when I run the program I get a segmentation fault and the core is dumped..... I have looked over the program and it all "looks" aright, that is, nothing jumps out at me as being wrong.

    Below is my program, if you could look over it and let me know what might be wrong that would be GREAT!!!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define false 0
    #define true 1
    
    typedef int bool;
    typedef unsigned char BYTE;
    
    int main(void)  {
    
    FILE*outptr;
    
    // open input file 
    FILE* inptr = fopen("card.raw", "r");
    if (inptr == NULL)
    {
        printf("Sorry, me noes able to open the file!!!\n");
        return 2;
    }
    
    bool jpegfoundbefore = false;
    
    int number = 0;
    
    int block_size = 512;
    
    BYTE buffer [512];
    
    char image_name[8];
    
    // untill eof is reached
    while (! feof(inptr) == 0)
    {
         //copy 512 bytes into buffer
         fread(buffer, block_size, 1, inptr);
         
    
         {
            // if a previous jpeg was found close file 
                if (jpegfoundbefore == true)
                {
                    fclose(outptr);
                }
    
                jpegfoundbefore = true;
     
                // name the image
                sprintf(image_name, "%.3d.jpg", number);
                number++; 
                
                // create the new jpg image file
                outptr = fopen (image_name, "w");
                if (outptr == NULL)
                {
                    printf("could not create jpeg file\n");
                    return 2;
                }     
                
                // write 512 byte block to current jpeg file 
                fwrite(buffer, block_size, 1, outptr);        
          }
    
          // continue writing parts of a jpg to file on disk 
          if (jpegfoundbefore == true)
          {
              fwrite(buffer, block_size, 1, outptr);        
          } 
     
     
    }
    
    // close card.raw 
    fclose(inptr);
    
    // close last jpg
    fclose(outptr);
    
    }
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    185
    Rep Power
    82
    OK, I made that change and now NO ERRORS but... when I run the program I get a segmentation fault and the core is dumped..... I have looked over the program and it all "looks" aright, that is, nothing jumps out at me as being wrong.
    There is a reason why you're reading the raw file in chunks of 512 bytes. This will always put the JPEG magic number in the first five bytes of every chunk read. I would suggest that you put your magic number test in a separate function with a boolean return. When you first open your raw file for reading you will check each chunk read for the magic number. Once the magic number is found, you will open an output file and continue to read additional chunks and check EACH chunk for the magic number. If you do not find the magic number, write the chunk out to the output file. If you do find the magic number, close the current output file and start writing a new output file.

IMN logo majestic logo threadwatch logo seochat tools logo