#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 resize an image


    Hi Everyone,

    I am currently working on problem set 4 for Harvard’s online CS50 course. I am working on a program that resizes a bmp image by a factor of N. N in entered along with an in-file and out-file in a command line argument. The program needs to calculate the header file for the out-file and write it to the out-file. It then needs to actually resize the image and, again, write to the out-file.

    The first question I have relates to the header file, here is my code for calculating the header file:


    bi2.biHeight = bi.biHeight *n;
    bi2.biWidth = bi.biWidth *n;
    int padding = (4 -(bi.biWidth * sizeof(RGBTRIPLE))%4)%4;
    bi2.biSizeImage = (bi2.biWidth * sizeof(RGBTRIPLE) + padding) * abs(bi2.biHeight);
    bf2.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi2.biSizeImage;


    And here is my code for writing the new header file (bi2 and bf2) to the out-file:

    fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);
    fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);

    Does my code look “OK” or do you see any issues???

    At this point I need to actually resize the image. As far as I can tell there are 2 ways to go about this you either have to use an array to store each line you want to print repeatedly (and then you can just write it repeatedly) OR you have to move the pointer back in the input stream and repeat the read/resize/write process each time you need to print the row.

    It is this that I am stuck on, first of all, I am not sure what system would be better for resizing the image, although I am leaning towards using an array, and regardless, I don’t even know where to begin when in implementing either.

    So what I am asking for is, first of all, just a “double check” to make sure my header code makes sense. And second of all, a push in the right direction for actually resizing the image. Please keep in mind that this is for a course so I don’t simply want you to “fix” my code, I want to learn, and discover.

    Thanks,
    Joshua McDonald

    Here is my complete code, if that helps:

    Code:
    /****************************************************************************
     * resize.c
     *
     * Computer Science 50
     * Problem Set 4
     *
     * Resizes a BMP piece by piece, just because.
     ***************************************************************************/
           
    #include <stdio.h>
    #include <stdlib.h>
    #include "bmp.h"
    
    int main(int argc, char* argv[])
    {
        // ensure proper usage
        if (argc != 4)
        {
            printf("Usage: copy N infile outfile\n");
            return 1;
        }
    
        // remember filenames
        char* nchar = argv[1];
        char* infile = argv[2];
        char* outfile = argv[3];
        
        int timeswriten = 0;
        
        //convert nchar to an int
        int n = atoi (nchar);
    
        if (n < 1 || n > 100)
        {
        printf("Please try again with a positive number less then 100\n");
        return 1;
        }
    
        // open input file 
        FILE* inptr = fopen(infile, "r");
        if (inptr == NULL)
        {
            printf("Could not open %s.\n", infile);
            return 2;
        }
    
        // open output file
        FILE* outptr = fopen(outfile, "w");
        if (outptr == NULL)
        {
            fclose(inptr);
            fprintf(stderr, "Could not create %s.\n", outfile);
            return 3;
        }
    
        // read infile's BITMAPFILEHEADER
        BITMAPFILEHEADER bf, bf2;
        fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
    
        // read infile's BITMAPINFOHEADER
        BITMAPINFOHEADER bi, bi2;
        fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
    
        // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
        if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
            bi.biBitCount != 24 || bi.biCompression != 0)
        {
            fclose(outptr);
            fclose(inptr);
            fprintf(stderr, "Unsupported file format.\n");
            return 4;
        }
        
        
        bi2.biHeight = bi.biHeight *n;
        bi2.biWidth = bi.biWidth *n;
        int padding = (4 -(bi.biWidth * sizeof(RGBTRIPLE))%4)%4;
        bi2.biSizeImage = (bi2.biWidth * sizeof(RGBTRIPLE) + padding) *        abs(bi2.biHeight);
        bf2.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi2.biSizeImage;
    
        // write outfile's BITMAPFILEHEADER and BITMAPINFOHEADER
        fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);
        fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);
    
        // iterate over infile's scanlines
        for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
        {
            // iterate over pixels in scanline
            for (int j = 0; j < bi.biWidth; j++)
            {
                // temporary storage
                RGBTRIPLE triple;
    
                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
                
                
                // Here is where I need to actually resise the image!!!!
    
    
                // write RGB triple to outfile
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
    
            }
    
            // skip over padding, if any
            fseek(inptr, padding, SEEK_CUR);
    
            // then add it back (to demonstrate how)
            for (int k = 0; k < padding; k++)
                fputc(0x00, outptr);
        }
    
        // close infile
        fclose(inptr);
    
        // close outfile
        fclose(outptr);
    
        // that's all folks
        return 0;
    }
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,384
    Rep Power
    1871
    Some recent attempt at the same thing

    It's a shame you didn't use the [code][/code] tags instead of the colour tags.
    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
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0

    I looked at the other thred


    Hi,

    I just read through the other thread, and although I will keep it for future reference, It doesn't really help my current problems.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    You are incorrectly calculating your padding for your new file in the following code:
    Code:
    int padding = (4 -(bi.biWidth * sizeof(RGBTRIPLE))%4)%4;
    bi2.biSizeImage = (bi2.biWidth * sizeof(RGBTRIPLE) + padding) * abs(bi2.biHeight);
    You should be using your new file width bi2.Width not bi.Width to calculate padding for your new file. Also, I'll assume that you byte aligned the BITMAPFILEHEADER structure. If not, your new file structure alignment will be off by two bytes.

    At this point I need to actually resize the image. As far as I can tell there are 2 ways to go about this you either have to use an array to store each line you want to print repeatedly (and then you can just write it repeatedly) OR you have to move the pointer back in the input stream and repeat the read/resize/write process each time you need to print the row.

    It is this that I am stuck on, first of all, I am not sure what system would be better for resizing the image, although I am leaning towards using an array, and regardless, I don’t even know where to begin when in implementing either.
    IMHO, using an array would be more elegant than than the latter method of moving the pointer etc.

    I've written a complete solution for the thread referenced by Salem. But I didn't post the solution in that thread because it was a homework thread. In my solution, I used a RGBTRIPLE buffer with a for loop to iterate over the scan lines with an inner loop to iterate over the pixels in the scan lines. I would then read a RGB triple from the input file and go over each pixel by your factor and then write it out to the RGBTRIPLE buffer. Next, skip over padding if any and write out each row a factor at a time.

    Comments on this post

    • salem agrees : Yeah - I did that too :)
    • Dude22 agrees : all his comments are relevant and helpful
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    Originally Posted by BobS0327
    You are incorrectly calculating your padding for your new file in the following code:
    Code:
    int padding = (4 -(bi.biWidth * sizeof(RGBTRIPLE))%4)%4;
    bi2.biSizeImage = (bi2.biWidth * sizeof(RGBTRIPLE) + padding) * abs(bi2.biHeight);
    You should be using your new file width bi2.Width not bi.Width to calculate padding for your new file.
    Ok fixed it! Here is the new code:

    Code:
    bi2.biHeight = bi.biHeight *n; bi2.biWidth = bi.biWidth *n; int padding = (4 -(bi2.biWidth * sizeof(RGBTRIPLE))%4)%4; bi2.biSizeImage = (bi2.biWidth * sizeof(RGBTRIPLE) + padding) * abs(bi2.biHeight); bf2.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi2.biSizeImage;

    Also, I'll assume that you byte aligned the BITMAPFILEHEADER structure. If not, your new file structure alignment will be off by two bytes.
    I am not sure what you mean by that.... I have my full code in the first post, If you could take a look at it to make sure the structure is aligned properly, that would be great!

    IMHO, using an array would be more elegant than than the latter method of moving the pointer etc.
    Yes, That is what I thought to, but I wasn't sure.

    I've written a complete solution for the thread referenced by Salem. But I didn't post the solution in that thread because it was a homework thread. In my solution, I used a RGBTRIPLE buffer
    I am not quite sure how to code a buffer, I assume it is like an array... But some help here would be great!

    with a for loop to iterate over the scan lines with an inner loop to iterate over the pixels in the scan lines. I would then read a RGB triple from the input file and go over each pixel by your factor and then write it out to the RGBTRIPLE buffer. Next, skip over padding if any and write out each row a factor at a time.
    I think I understand the last bit, once I have the rgb tripple in a buffer, I will revisit this section of the post and see if I do, in fact fully understand it.


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

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    I am not sure what you mean by that.... I have my full code in the first post, If you could take a look at it to make sure the structure is aligned properly, that would be great!
    Here is a link to a BMP file format link. Please note the 14 byte size of the Bitmap File Header struct.
    In a Windows environment, you would use Pragma Pack directives to byte align your BitmapFileHeader struct. If you do not byte align the structure, sizeof BitmapFileHeader will return 16 bytes but the BMP format requires a struct with a size of 14 bytes. Post your BMP.h file so we can see how you addressed this potential issue.

    I am not quite sure how to code a buffer, I assume it is like an array... But some help here would be great!
    I believe we have a semantics issue here. My buffer is really an array. Sorry, I'll try to be more specific in the future.

    As a starting point, I would suggest creating the array (buffer) as follows:

    Code:
    RGBTRIPLE *buffer = (RGBTRIPLE *)malloc(sizeof(RGBTRIPLE) * bi2.biWidth);

    Comments on this post

    • Dude22 agrees : Another helpful post!!!
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    Here is a link to a BMP file format link. Please note the 14 byte size of the Bitmap File Header struct.
    In a Windows environment, you would use Pragma Pack directives to byte align your BitmapFileHeader struct. If you do not byte align the structure, sizeof BitmapFileHeader will return 16 bytes but the BMP format requires a struct with a size of 14 bytes. Post your BMP.h file so we can see how you addressed this potential issue.
    I don't think the file will pose any issues as it was provided by the course, I will post it just in case though:

    Code:
    /****************************************************************************
     * bmp.h
     *
     * Computer Science 50
     * Problem Set 4
     *
     * BMP-related data types based on Microsoft's own.
     ***************************************************************************/
    
    #include <stdint.h>
    
    /**
     * Common Data Types 
     *
     * The data types in this section are essentially aliases for C/C++ 
     * primitive data types.
     *
     * Adapted from http://msdn.microsoft.com/en-us/library/cc230309(PROT.10).aspx.
     * See http://en.wikipedia.org/wiki/Stdint.h for more on stdint.h.
     */
    typedef uint8_t  BYTE;
    typedef uint32_t DWORD;
    typedef int32_t  LONG;
    typedef uint16_t WORD;
    
    /**
     * BITMAPFILEHEADER
     *
     * The BITMAPFILEHEADER structure contains information about the type, size,
     * and layout of a file that contains a DIB [device-independent bitmap].
     *
     * Adapted from http://msdn.microsoft.com/en-us/library/dd183374(VS.85).aspx.
     */
    typedef struct 
    { 
        WORD   bfType; 
        DWORD  bfSize; 
        WORD   bfReserved1; 
        WORD   bfReserved2; 
        DWORD  bfOffBits; 
    } __attribute__((__packed__)) 
    BITMAPFILEHEADER; 
    
    /**
     * BITMAPINFOHEADER
     *
     * The BITMAPINFOHEADER structure contains information about the 
     * dimensions and color format of a DIB [device-independent bitmap].
     *
     * Adapted from http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx.
     */
    typedef struct
    {
        DWORD  biSize; 
        LONG   biWidth; 
        LONG   biHeight; 
        WORD   biPlanes; 
        WORD   biBitCount; 
        DWORD  biCompression; 
        DWORD  biSizeImage; 
        LONG   biXPelsPerMeter; 
        LONG   biYPelsPerMeter; 
        DWORD  biClrUsed; 
        DWORD  biClrImportant; 
    } __attribute__((__packed__))
    BITMAPINFOHEADER; 
    
    /**
     * RGBTRIPLE
     *
     * This structure describes a color consisting of relative intensities of
     * red, green, and blue.
     *
     * Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx.
     */
    typedef struct
    {
        BYTE  rgbtBlue;
        BYTE  rgbtGreen;
        BYTE  rgbtRed;
    } __attribute__((__packed__))
    RGBTRIPLE;
    I believe we have a semantics issue here. My buffer is really an array. Sorry, I'll try to be more specific in the future.

    As a starting point, I would suggest creating the array (buffer) as follows:

    Code:
    RGBTRIPLE *buffer = (RGBTRIPLE *)malloc(sizeof(RGBTRIPLE) * bi2.biWidth);
    Ok, Here is my first go at writing the program with the help you have given me so far:


    Code:
    /****************************************************************************
     * resize.c
     *
     * Computer Science 50
     * Problem Set 4
     *
     * Resizes a BMP piece by piece, just because.
     ***************************************************************************/
           
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "bmp.h"
    
    int main(int argc, char* argv[])
    {
        // ensure proper usage
        if (argc != 4)
        {
            printf("Usage: copy N infile outfile\n");
            return 1;
        }
    
        // remember filenames
        char* nchar = argv[1];
        char* infile = argv[2];
        char* outfile = argv[3];
        
        int timeswriten = 0;
        
        //convert nchar to an int
        int n = atoi (nchar);
    
    
        
        if (n < 1 || n > 100)
        {
        printf("Please try again with a positive number less then 100\n");
        return 1;
        }
    
        // open input file 
        FILE* inptr = fopen(infile, "r");
        if (inptr == NULL)
        {
            printf("Could not open %s.\n", infile);
            return 2;
        }
    
        // open output file
        FILE* outptr = fopen(outfile, "w");
        if (outptr == NULL)
        {
            fclose(inptr);
            fprintf(stderr, "Could not create %s.\n", outfile);
            return 3;
        }
    
        // read infile's BITMAPFILEHEADER
        BITMAPFILEHEADER bf, bf2;
        fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
    
        // read infile's BITMAPINFOHEADER
        BITMAPINFOHEADER bi, bi2;
        fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
    
        // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
        if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
            bi.biBitCount != 24 || bi.biCompression != 0)
        {
            fclose(outptr);
            fclose(inptr);
            fprintf(stderr, "Unsupported file format.\n");
            return 4;
        }
        
        
        bi2.biHeight = bi.biHeight *n;
        bi2.biWidth = bi.biWidth *n;
        int padding = (4 -(bi2.biWidth * sizeof(RGBTRIPLE))%4)%4;
        bi2.biSizeImage = (bi2.biWidth * sizeof(RGBTRIPLE) + padding) * abs(bi2.biHeight);
        bf2.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi2.biSizeImage;
    
        // write outfile's BITMAPFILEHEADER and BITMAPINFOHEADER
        fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);
        fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);
    
        RGBTRIPLE *buffer = (RGBTRIPLE *)malloc(sizeof(RGBTRIPLE) * bi2.biWidth);
    
        // iterate over infile's scanlines
        for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
        {
            // iterate over pixels in scanline
            for (int j = 0; j < bi.biWidth; j++)
            {
                // temporary storage
                RGBTRIPLE triple;
    
                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
    
                // write RGB tripple to array n times    
                for (int z = 0; z < n; z++) 
                {
                // QUESTION 1
                }
    
              
            }
            
            // write RGB triple to outfile    QUESTION 2
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
    
            // skip over padding, if any
            fseek(inptr, padding, SEEK_CUR);
    
            // then add it back (to demonstrate how)
            for (int k = 0; k < padding; k++)
                fputc(0x00, outptr);
        }
    
        // close infile
        fclose(inptr);
    
        // close outfile
        fclose(outptr);
    
        // that's all folks
        return 0;
    }

    QUESTION 1: As this point in the program I think I need to write the RGB tripple to the array n times.... I am not sure how to do this, so any help would be GREAT!

    QUESTION 2: This is another problem, related to the first one, At this point in the program I think I should write the array to the outfile n times.... Again, any help would be GREAT!


    Thanks so much for you help so far and I hope you can continue to give it! :)

    Joshua
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    I don't think the file will pose any issues as it was provided by the course, I will post it just in case though:
    Your BMP.h file doesn't pose any issues. You're essentially using the Linux equivalent of Windows (Win32) pragma pack to align your structure on byte boundaries

    QUESTION 1: As this point in the program I think I need to write the RGB tripple to the array n times.... I am not sure how to do this, so any help would be GREAT!
    You should set up a temporary index to move thru the RGBTriple buffer. For example, factor n = 2, buffer[tempindex++] =triple, buffer[tempindex++] = triple etc. Keep in mind the the temp index is used to iterate thru each scan line. Thus, it has to be reset to zero for the next scan line, To reiterate, your for loop would iterate n times which is your "factor". Within the loop, you will assign triple to the RGBTRIPLE buffer and increment the buffer using the temp index to assign triple to the next position in the buffer until you've done it a "factor" of times.


    QUESTION 2: This is another problem, related to the first one, At this point in the program I think I should write the array to the outfile n times.... Again, any help would be GREAT!
    The first thing you want to do is skip over the padding in the input file. Thus, you have to create another int variable, let's call it iOldfFilePadding and calcuate the input file padding. Then use fseek to skip over this input file padding. Now, you will write out that RGBTRIPLE buffer that you previously built using fwrite. You would write out the buffer using a for loop a "factor" of times. After each fwrite of the buffer, you should use fputc to append the padding for the new output file. That is, you have to append padding (if required) after every fwrite of the buffer.

    Comments on this post

    • Dude22 agrees : And, again, another very helpful and informative post!!! Without you I would be completely stumped!
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    Your BMP.h file doesn't pose any issues. You're essentially using the Linux equivalent of Windows (Win32) pragma pack to align your structure on byte boundaries
    OK, great!


    You should set up a temporary index to move thru the RGBTriple buffer. For example, factor n = 2, buffer[tempindex++] =triple, buffer[tempindex++] = triple etc. Keep in mind the the temp index is used to iterate thru each scan line. Thus, it has to be reset to zero for the next scan line, To reiterate, your for loop would iterate n times which is your "factor". Within the loop, you will assign triple to the RGBTRIPLE buffer and increment the buffer using the temp index to assign triple to the next position in the buffer until you've done it a "factor" of times.
    I think I get that.... I just have 1 question: how to you write to the array (or buffer) from the RGBTRIPLE. Is it something like this: buffer[j]=triple[j];

    (the "j" is just an int that increases by 1 each time it loops!)

    It cant be completely correct, because that line is giving me an error, so what do you think I am doing wrong???

    I am not completely sure I am using the correct names to access the buffer or the triple, which may be causing the isue.



    The first thing you want to do is skip over the padding in the input file. Thus, you have to create another int variable, let's call it iOldfFilePadding and calcuate the input file padding. Then use fseek to skip over this input file padding. Now, you will write out that RGBTRIPLE buffer that you previously built using fwrite. You would write out the buffer using a for loop a "factor" of times. After each fwrite of the buffer, you should use fputc to append the padding for the new output file. That is, you have to append padding (if required) after every fwrite of the buffer.
    I think that all makes sense, I will come back to this once I have question 1 resolved and working.

    Thanks,
    Josh

    NOTE: I have started another thread for another program I am working on, if you could look at is as-well, that would be GREAT:

    http://forums.devshed.com/c-programming-42/help-with-a-program-to-recover-an-image-940454.html
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    I think I get that.... I just have 1 question: how to you write to the array (or buffer) from the RGBTRIPLE. Is it something like this: buffer[j]=triple[j];

    (the "j" is just an int that increases by 1 each time it loops!)

    It cant be completely correct, because that line is giving me an error, so what do you think I am doing wrong???

    I am not completely sure I am using the correct names to access the buffer or the triple, which may be causing the isue.
    In your for loop, you should be reading ONLY one RGBTRIPLE at a time:

    Code:
    fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
    It is this ONE RGBTRIPLE that you will add to your RGBTRIPLE buffer (array) a "factor" number of times.

    Keep in mind that your RGBTRIPLE array size is based on the new file's width size and the new file's width size is based on the old files width size times the "factor". Thus, you must only increment the RGBTRIPLE buffer and assign the ONE RGBTRIPLE to each index increment in the buffer. For example, let's assume factor is 3. You would read in ONE RGBTRIPLE and assign it to three incremental positions in the RGBTRIPBLE buffer.
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    Originally Posted by BobS0327
    In your for loop, you should be reading ONLY one RGBTRIPLE at a time:

    Code:
    fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
    It is this ONE RGBTRIPLE that you will add to your RGBTRIPLE buffer (array) a "factor" number of times.

    Keep in mind that your RGBTRIPLE array size is based on the new file's width size and the new file's width size is based on the old files width size times the "factor". Thus, you must only increment the RGBTRIPLE buffer and assign the ONE RGBTRIPLE to each index increment in the buffer. For example, let's assume factor is 3. You would read in ONE RGBTRIPLE and assign it to three incremental positions in the RGBTRIPBLE buffer.
    I think I understand how to read the file, but I am lost on how to WRITE it to the array...

    Thanks
    Josh

IMN logo majestic logo threadwatch logo seochat tools logo