Thread: Read in binary file ( pointers )

  1. #31
    Yes, I play CounterStrike
    Join Date
    Jun 2005
    Location
    Edinburgh, Scotland
    Posts
    33
    I do not know how to thank you enough....i have been working on this problem for 3 straight days and now (thanks to your good self) it is working a treat thanks again

    Matt.

    p.s. its my birthday today as well, so cheers for the random present

  2. #32
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    Happy Birthday! Happy to help.

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

  3. #33
    Yes, I play CounterStrike
    Join Date
    Jun 2005
    Location
    Edinburgh, Scotland
    Posts
    33
    Right...here's an interesting question (i hope ).


    I believe what is happen in the program you made, is that you are making a pointer to an array then saving all the relevant pixel information to that array. If i was to pass that pointer back to the function that called it (which in turn stores each pointer into an array), would that work? because at present it does not seem too

    basically the function call is:
    Code:
    ptr_pixeldata[i] = *ReadImageData(ptr_file->nextFileName, ptr_header);
    with 'i' increasing as the filenumber increases (this is all done automatically and works fine),

    when i use your script as function ReadImageData and print information form within that function it is fine and as you would expect, but when i want to print information from within the function where the call line resides, it wont work.

    I am using:
    Code:
    for (k=0; k<10; k++){
    printf("%02X \n", ptr_pixeldata[i][j]);
    //this returns error C2109: subscript requires array or pointer type
    //so output is with ptr_pixeldata[i]
    }
    to try and print the first ten values of the specific photo that i represents....
    any reason why this shouldn't work ?

    output:

    Output From File Number 0061 is: 70
    70
    70
    70
    70
    70
    70
    70
    70
    70

    my return line is
    Code:
    return(ptr_data);
    Last edited by Giant; 06-22-2005 at 07:40 AM.

  4. #34
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    I may root around and try to put together a Windows program to actually display this, if so I will post back with the image. Does this help you?

    Code:
    #include <ctype.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    /* note that most compilers will pad this structure to 4 bytes! */
    struct PixelRGB{
        unsigned char Red, Green, Blue;
    };
    
    /*
        Expect a series of images of the form base0000.ppm, base0001.ppm, etc
        Supports forward or reverse image ordering
    */
    int main(int argc, char **argv) {
        int i, j, height, width, color;
        FILE *temp_fptr;
        size_t totBytes, bytesRead;
        const char *fileName = "img0061.ppm"; /* get from the command line */
        char buf[BUFSIZ];
        struct PixelRGB **image;
    
        temp_fptr = fopen(fileName,"rb");
        if (!temp_fptr){
            fprintf(stderr, "Can't open file!\n");
            exit(1);
        }
    
        /* get and check magic number */
        i=0;
        while (!isspace(buf[i] = fgetc(temp_fptr))){i++;}
        buf[i] = '\0';
        if (strncmp(buf, "P6", 2)){
            fprintf(stderr, "File's magic number is invalid! (only read P6 files)\n");
            exit(1);
        }
    
        /* get and check width */
        i=0;
        while (!isspace(buf[i] = fgetc(temp_fptr))){i++;}
        buf[i] = '\0';
        if (sscanf(buf, "%d", &width) != 1){
            fprintf(stderr, "Failed to read in width correctly!\n");
            exit(1);
        }
        if (width < 1 || width > 65536){ /* arbitrary upper limit, you can change this */
            fprintf(stderr, "Invalid or out-of-bounds value for width!\n");
            exit(1);
        }
    
        /* get and check height */
        i=0;
        while (!isspace(buf[i] = fgetc(temp_fptr))){i++;}
        buf[i] = '\0';
        if (sscanf(buf, "%d", &height) != 1){
            fprintf(stderr, "Failed to read in height correctly!\n");
            exit(1);
        }
        if (height < 1 || height > 65536){ /* arbitrary upper limit, you can change this */
            fprintf(stderr, "Invalid or out-of-bounds value for height!\n");
            exit(1);
        }
    
    
        /* get color (don't care about validity) */
        i=0;
        while (!isspace(buf[i] = fgetc(temp_fptr))){i++;}
        buf[i] = '\0';
        if (sscanf(buf, "%d", &color) != 1){
            fprintf(stderr, "Failed to read in color correctly!\n");
            exit(1);
        }
        totBytes = 3*width*height;
    
    
        image = (struct PixelRGB **) malloc(width * sizeof(struct PixelRGB *));
        if (!image){
            fprintf(stderr, "Failed to allocate %d bytes of memory for first dimension of image array!\n", width * sizeof(struct PixelRGB *));
            exit(1);
        }
        for (i=0; i<width; i++){
            image[i] = (struct PixelRGB *) malloc(height * sizeof(struct PixelRGB));
            if (!image[i]){
                fprintf(stderr, "Failed to allocate %d bytes of memory for second dimension of image array %d!\n", height * sizeof(struct PixelRGB), i+1);
                exit(1);
            }
        }
    
        /* I am only reading in the bytes one at a time for clarity, this could be buffered
           though the performance gain would be marginal */
        bytesRead = 0;
        for (i=0; i<width; i++){
            for (j=0; j<height; j++){
                image[i][j].Red   = (unsigned char) fgetc(temp_fptr);
                image[i][j].Green = (unsigned char) fgetc(temp_fptr);
                image[i][j].Blue  = (unsigned char) fgetc(temp_fptr);
                bytesRead += 3;
                if (feof(temp_fptr)) break;
            }
            if (feof(temp_fptr)) break;
        }
        fclose(temp_fptr);
    
        printf("\nbytesRead: %d\nFirst 9 bytes in hex:\n", bytesRead);
        for (i=0; i<3; i++){
            printf("%02X ", image[0][i].Red);
            printf("%02X ", image[0][i].Green);
            printf("%02X ", image[0][i].Blue);
        }
        printf("\n");
    
    
        /* deallocate memory */
        for (i=0; i<width; i++){
            free(image[i]);
        }
        free(image);
    
        return 0;
    }

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

  5. #35
    Yes, I play CounterStrike
    Join Date
    Jun 2005
    Location
    Edinburgh, Scotland
    Posts
    33
    erm sort of , you do give me a clearer indication of what I need to do, though i am still pretty lost , below is a simplified version of my code as it stands (most of the validation and header checking have been taking out)

    Code:
    #include <iostream>
    #include <ctype.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #include "practice.h"
    /*
    	Expect a series of images of the form base0000.ppm, base0001.ppm, etc
    	Supports forward or reverse image ordering
    */
    filenamestruct* GetImageBase(char *, filenamestruct*);
    headerstruct* GetHeader(char *, headerstruct*);
    unsigned char* ReadImageData(const char *, headerstruct*);
    int CheckHeader(char*, headerstruct*);
    
    int main(int argc, char **argv)
    { 
    	//intialisation code
    	size_t i=0,k=0, flag_done= 0, maximagenumber;
    	filenamestruct *ptr_file;
    	headerstruct *ptr_header;
    //	char *ptr_pixeldata;
        unsigned char *ptr_pixeldata;
    	int bn = 0;
    	char bn_ch[4];
    
    	ptr_file = new filenamestruct;
    	ptr_header = new headerstruct;
    
    	maximagenumber = 1;
    
    	ptr_pixeldata = (unsigned char *) malloc(maximagenumber);
    
    	while(i<(maximagenumber))
    	{
    		ptr_pixeldata[i] = (unsigned char) malloc((atoi(ptr_header->width))*(atoi(ptr_header->height)));
    		ptr_pixeldata[i] = *ReadImageData(argv[1], ptr_header);
    
    		printf("\nOutput From File is: ");
    		for (k=0; k<10; k++){
            printf("%02X \n", ptr_pixeldata[i][k]);
            }
      		i++;
    		//get next filename here at the moment just use one filename
    	}
    
    }
    
    unsigned char* ReadImageData(const char *fileName, headerstruct *temp_head){
    	
    	unsigned char *ptr_data;
        FILE *temp_fptr;
        size_t j=0,totBytes, bytesRead;
        
        temp_fptr = fopen(fileName,"rb");
        if (!temp_fptr){
            fprintf(stderr, "Can't open file!\n");
            exit(1);
        }
    
        while(j<(temp_head->headerend)){j++;getc(temp_fptr);}//jump header
    
    	totBytes = 3*(atoi(temp_head->height))*(atoi(temp_head->width));
    
        ptr_data = (unsigned char *) malloc(totBytes);
        if (!ptr_data){
            fprintf(stderr, "Failed to allocate %d bytes of memory!\n", totBytes);
            exit(1);
        }
        bytesRead = fread(ptr_data, 1, (totBytes), temp_fptr); //if does not equal count then errorz
    
        fclose(temp_fptr);
        return (ptr_data);
    }

  6. #36
    Yes, I play CounterStrike
    Join Date
    Jun 2005
    Location
    Edinburgh, Scotland
    Posts
    33
    ha, got it working, cheers for the help, definatly pointed me in the right direction

  7. #37
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    Correct me if my assumptions are incorrect, but don't you want to read the image data into a 2d array of RGB values for manipulation/display? That is exactly what my code is doing. Without spending a lot of time looking at your code, I am pretty sure you have massive memory leaks (allocating memory but never deallocating it). This is not fatal as once the program exits the OS cleans up after the app, but it is very poor programming practice.

    Perhaps if you explain what you are trying to do and give some very high-level pseudo code I can be of more help.

    BTW, you are using plenty of C++ constructs yet are posting on a C board. Are you doing that on purpose or do you not realize the differences? Encapsulating this in classes would be a much cleaner way of handling things.

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

  8. #38
    Yes, I play CounterStrike
    Join Date
    Jun 2005
    Location
    Edinburgh, Scotland
    Posts
    33
    this is where the fact that i dont know either C or C++ well (certainly C better than C++) at all comes out . And I thought I was using C enough to warrent posting on this board, though i could be wrong.

    What I am wanting to do is:

    Take in an[EDIT]series of .ppm images and store each image in an array of pixelvalues, then store this array in another array of all images. Obviously I don't want to be copying big files from one array to another, so I was hoping to take in an image to an array then pass the pointer to this array back to another array, where I could call it like: i.e.
    Code:
    pixelvalue[photonumber][pixellocation]
    pixel location is set in one field (and not [x][y], though i suppose it could be, as later I will be processing every pixel so it doesnt matter how they are stored as long as they are in order)
    Last edited by Giant; 06-22-2005 at 09:21 AM.

  9. #39
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    Each pixel is made up of 3 8 bit values (RGB, Red, Green and Blue) and each image is logically a 2d array of pixels, so the format I provided will make it easiest for any post-processing. This will give you an idea of where to go, but it needs some tweaking. Personally I would do all this in C++ classes so you don't have to remember to deallocate memory all the time.

    Code:
    #include <ctype.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    /* note that most compilers will pad this structure to 4 bytes! */
    struct PixelRGB{
        unsigned char Red, Green, Blue;
    };
    
    
    struct PixelRGB **getImageIntoArray(const char *fileName) {/* returns NULL if error */
        int i, j, height, width, color;
        FILE *temp_fptr;
        size_t bytesRead;
        char buf[BUFSIZ];
        struct PixelRGB **image;
    
        temp_fptr = fopen(fileName,"rb");
        if (!temp_fptr){
            fprintf(stderr, "Can't open file!\n");
            return NULL;
        }
    
        /* get and check magic number */
        i=0;
        while (!isspace(buf[i] = fgetc(temp_fptr))){i++;}
        buf[i] = '\0';
        if (strncmp(buf, "P6", 2)){
            fprintf(stderr, "File's magic number is invalid! (only read P6 files)\n");
            return NULL;
        }
    
        /* get and check width */
        i=0;
        while (!isspace(buf[i] = fgetc(temp_fptr))){i++;}
        buf[i] = '\0';
        if (sscanf(buf, "%d", &width) != 1){
            fprintf(stderr, "Failed to read in width correctly!\n");
            return NULL;
        }
        if (width < 1 || width > 65536){ /* arbitrary upper limit, you can change this */
            fprintf(stderr, "Invalid or out-of-bounds value for width!\n");
            return NULL;
        }
    
        /* get and check height */
        i=0;
        while (!isspace(buf[i] = fgetc(temp_fptr))){i++;}
        buf[i] = '\0';
        if (sscanf(buf, "%d", &height) != 1){
            fprintf(stderr, "Failed to read in height correctly!\n");
            return NULL;
        }
        if (height < 1 || height > 65536){ /* arbitrary upper limit, you can change this */
            fprintf(stderr, "Invalid or out-of-bounds value for height!\n");
            return NULL;
        }
    
    
        /* get color (don't care about validity) */
        i=0;
        while (!isspace(buf[i] = fgetc(temp_fptr))){i++;}
        buf[i] = '\0';
        if (sscanf(buf, "%d", &color) != 1){
            fprintf(stderr, "Failed to read in color correctly!\n");
            return NULL;
        }
    
    
        image = (struct PixelRGB **) malloc(width * sizeof(struct PixelRGB *));
        if (!image){
            fprintf(stderr, "Failed to allocate %d bytes of memory for first dimension of image array!\n", width * sizeof(struct PixelRGB *));
            return NULL;
        }
        for (i=0; i<width; i++){
            image[i] = (struct PixelRGB *) malloc(height * sizeof(struct PixelRGB));
            if (!image[i]){
                fprintf(stderr, "Failed to allocate %d bytes of memory for second dimension of image array %d!\n", height * sizeof(struct PixelRGB), i+1);
                return NULL;
            }
        }
    
        /* I am only reading in the bytes one at a time for clarity, this could be buffered
           though the performance gain would be marginal */
        bytesRead = 0;
        for (i=0; i<width; i++){
            for (j=0; j<height; j++){
                image[i][j].Red   = (unsigned char) fgetc(temp_fptr);
                image[i][j].Green = (unsigned char) fgetc(temp_fptr);
                image[i][j].Blue  = (unsigned char) fgetc(temp_fptr);
                bytesRead += 3;
                if (feof(temp_fptr)) break;
            }
            if (feof(temp_fptr)) break;
        }
        fclose(temp_fptr);
    
        printf("width: %d\n", width);
        printf("height: %d\n", height);
        printf("bytesRead: %d\n", bytesRead);
        printf("First 9 bytes in hex:\n");
        for (i=0; i<3; i++){
            printf("%02X ", image[0][i].Red);
            printf("%02X ", image[0][i].Green);
            printf("%02X ", image[0][i].Blue);
        }
        printf("\n");
    
    
        return image;
    }
    
    int main(int argc, char **argv) {
        int i, j, numImages = 3;/* hard-coded for convinence */
        const char *fileName = "img0061.ppm"; /* get from the command line */
        struct PixelRGB ***imageMatrix;/* a pointer to a series of 2d arrays */
    
    
    
    
        imageMatrix = (struct PixelRGB ***) malloc(numImages * sizeof(struct PixelRGB ***));
        if (!imageMatrix){
            fprintf(stderr, "Failed to allocate memory for imageMatrix array!\n");
            exit(1);
        }
        for (i=0; i<numImages; i++){
            imageMatrix[i] = getImageIntoArray(fileName);
        }
    
        printf("\n\nFrom main()\n\n");
    
        for (j=0; j<numImages; j++){
            printf("image number %d\n", j+1);
            printf("First 9 bytes in hex:\n");
            for (i=0; i<3; i++){
                printf("%02X ", imageMatrix[j][0][i].Red);
                printf("%02X ", imageMatrix[j][0][i].Green);
                printf("%02X ", imageMatrix[j][0][i].Blue);
            }
            printf("\n");
        }
    
    
        /* deallocate memory */
        for (j=0; j<numImages; j++){
            for (i=0; i<492; i++){ /* width hard-coded here, the best way to handle this is to use classes */
                free(imageMatrix[j][i]);
            }
            free(imageMatrix[j]);
        }
        free(imageMatrix);
    
        return 0;
    }

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

  10. #40
    Yes, I play CounterStrike
    Join Date
    Jun 2005
    Location
    Edinburgh, Scotland
    Posts
    33
    i have to go now meeting the parents for dinner , but i will work on this tomorrow, thanks for all your help (AGAIN!)

  11. #41
    Yes, I play CounterStrike
    Join Date
    Jun 2005
    Location
    Edinburgh, Scotland
    Posts
    33
    just a quick update, slotted your program into my existing code, and it showed me where I was going wrong (especially with allocating memory) and even showed me where I was getting memory leaks which was v. good. All I need to do now is some post processing (which wont be easy, but determined to do this on my own [its all maths rather than hard programming ]). So thanks alot for all your help, there is no way i would be at this stage with out it .

  12. #42
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    No problemo, happy to help. Good luck on the rest of your project and don't hessitate to ask if you have problems!

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Read a file (binary) into an array of structs
    By Separ in forum C Programming
    Replies: 3
    Last Post: 04-14-2009, 09:09 PM
  2. Binary file is read with bytes missing
    By thomas41546 in forum C# Programming
    Replies: 1
    Last Post: 09-03-2006, 04:15 AM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM