1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Multidimensional Array Error

Discussion in 'C++' started by louiskepler, Nov 22, 2010.

  1. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    I have the following base code for a program I am writing that simply loads a bitmap from one location and transmits it to another (with limited compatibility). The problem is that when run it appears to go into an infinite loop. Any ideas why? (hoping its a stupid error and not something major)
    here is the code:
    Code:
    #include <fstream>
    using namespace std;
    class Bitmap
    {
        private:
        unsigned char ***ERROR3;//the error value
        //Some raw variables in the file data:
        unsigned char *HEADERS;
        unsigned char FTYPE[2];//should be MP
        int size;
        int start;
        int DIBsize;
        int width;
        int height;
        short BPP;
        int COMPMETHOD;//should be zero or we could likely have a major problem!
        //HERES THE IMAGE!!!!!!
        unsigned char ***IMAGE;
        //AND ONE WITH LESS MASSIVE RANGE, UPDATED BY A CALL TO UPDATE()
        int ***PICTURE;
        public:
        void UPDATE();
        unsigned char ***OPEN(char *fname);//BETTER NAME WOULD BE READ... OH WELL!
        void CLOSE(char *fname);//BETTER NAME WOULD BE SAVE... OH WELL!
    };
    void Bitmap::CLOSE(char *fname)
    {
        fstream FILE;
        FILE.open(fname, ios_base::in|ios_base::out|ios_base::binary);
        FILE<<HEADERS<<IMAGE;
        FILE.close();
    }
    unsigned char ***Bitmap::OPEN(char *fname)//returns a 3Dimensional array for the image in the form of [h][w][rgb(a)]
    {
        unsigned char ***ERROR3=new unsigned char**[3];
        for (int i=0; i<3; i++)
        {
            ERROR3[i]=new unsigned char*[3];
            for (int ii=0; ii<3; ii++)
            {
                ERROR3[ii][i]=new unsigned char[3];
            }
        }
        for (int i=0; i<3; i++)
        {
            for (int ii=0; ii<3; ii++)
            {
                for (int iii=0; iii<3; iii++)
                {
                    ERROR3[i][ii][iii]=40;
                }
            }
        }
        fstream FILE;
        char Byte;
        int asize = 1;
        unsigned char *ARRAY = new unsigned char[asize];
        FILE.open(fname, ios_base::in|ios_base::out|ios_base::binary);
        while (!(FILE.eof()))
        {
            FILE.read(&Byte, 1);
            unsigned char *TEMP = new unsigned char[asize];
            TEMP = ARRAY;
            asize++;
            ARRAY = new unsigned char[asize];
            for (int i = 0; i<asize-1; i++)
            {
                ARRAY[i] = TEMP[i];
            }
            ARRAY[asize-1] = Byte;
        }//NOW ARRAY IS FULL OF THE CONTENTS OF FILE IN BINARY (IN ORDER)
        int loc = 0;
        unsigned char RFTYPE[2] = {ARRAY[loc], ARRAY[loc+1]};//Get the Magic Number (Should likely be MB[it is reversed])
        FTYPE[0]=RFTYPE[0];
        FTYPE[1]=RFTYPE[1];
        loc += 2;
        unsigned char FSIZE[4] = {ARRAY[loc], ARRAY[loc+1], ARRAY[loc+2], ARRAY[loc+3]};//Get the Size in bytes, in bytes
        size = 0;
        size |= (FSIZE[3]<<24);
        size |= (FSIZE[2]<<16);
        size |= (FSIZE[1]<<8);
        size |= (FSIZE[0]);//size is now size of file in bytes!
        loc += 8;//includes the 4 reserved bytes of data
        if (loc > size)
        {
            FILE.close(); return ERROR3;
        }//now loc can be checked
        unsigned char FSTART[4] = {ARRAY[loc], ARRAY[loc+1], ARRAY[loc+2], ARRAY[loc+3]};//Get the start of image data, in bytes
        start = 0;
        start |= (FSIZE[3]<<24);
        start |= (FSIZE[2]<<16);
        start |= (FSIZE[1]<<8);
        start |= (FSIZE[0]);//start is now the beginning of image data
        loc += 4;//go to DIB header
        unsigned char FDIBSIZE[4] = {ARRAY[loc], ARRAY[loc+1], ARRAY[loc+2], ARRAY[loc+3]};//Get the length of the DIB header
        DIBsize = 0;
        DIBsize |= (FDIBSIZE[3]<<24);
        DIBsize |= (FDIBSIZE[2]<<16);
        DIBsize |= (FDIBSIZE[1]<<8);
        DIBsize |= (FDIBSIZE[0]);
        loc += 4;
        unsigned char IWIDTH[4];
        unsigned char IHEIGHT[4];
        unsigned char BitsPerPixel[2];
        unsigned char CMETHOD[4];
        short val;
        switch (DIBsize)
        {
            case 40://it is BITMAP INFO HEADER we can use it
            IWIDTH[0] = ARRAY[loc];
            IWIDTH[1] = ARRAY[loc+1];
            IWIDTH[2] = ARRAY[loc+2];
            IWIDTH[3] = ARRAY[loc+3];//Get the width of the image
            width = 0;
            width |= (IWIDTH[3]<<24);
            width |= (IWIDTH[2]<<16);
            width |= (IWIDTH[1]<<8);
            width |= (IWIDTH[0]);
            loc += 4;
            IHEIGHT[0] = ARRAY[loc];
            IHEIGHT[1] = ARRAY[loc+1];
            IHEIGHT[2] = ARRAY[loc+2];
            IHEIGHT[3] = ARRAY[loc+3];//Get the height of the image
            height = 0;
            height |= (IHEIGHT[3]<<24);
            height |= (IHEIGHT[2]<<16);
            height |= (IHEIGHT[1]<<8);
            height |= (IHEIGHT[0]);
            loc += 6;//to account for plane numbers which, if not one, will cause an error so we don't need to check it
            BitsPerPixel[0] = ARRAY[loc];
            BitsPerPixel[1] = ARRAY[loc+1];
            BPP = 0;
            BPP |= (BitsPerPixel[1]<<8);
            BPP |= (BitsPerPixel[0]);//sets the BPP of the image
            loc += 2;
            CMETHOD[0] = ARRAY[loc];
            CMETHOD[1] = ARRAY[loc+1];
            CMETHOD[2] = ARRAY[loc+2];
            CMETHOD[3] = ARRAY[loc+3];
            COMPMETHOD = 0;
            COMPMETHOD |= (CMETHOD[3]<<24);
            COMPMETHOD |= (CMETHOD[2]<<16);
            COMPMETHOD |= (CMETHOD[1]<<8);
            COMPMETHOD |= (CMETHOD[0]);//set the method of compression
            loc += 20;//we are done with the important stuff, since Pixels per meter and palettes are not going to change our program
            break;
            case 12://it is BITMAP CORE HEADER we can use it
            IWIDTH[0] = ARRAY[loc];
            IWIDTH[1] = ARRAY[loc+1];
            IWIDTH[2] = 0;
            IWIDTH[3] = 0;
            val = 0;
            val |= (IWIDTH[1]<<8);
            val |= (IWIDTH[0]);
            width = (int)val;
            loc += 2;
            IHEIGHT[0] = ARRAY[loc];
            IHEIGHT[1] = ARRAY[loc+1];
            IHEIGHT[2] = ARRAY[loc+2];
            IHEIGHT[3] = ARRAY[loc+3];
            val = 0;
            val |= (IHEIGHT[1]<<8);
            val |= (IHEIGHT[0]);
            height = (int)val;
            loc += 4;//Also includes plane numbers which, if not one, will cause an error so we don't need to check it
            BitsPerPixel[0] = ARRAY[loc];
            BitsPerPixel[1] = ARRAY[loc+1];
            BPP = 0;
            BPP |= (BitsPerPixel[1]<<8);
            BPP |= (BitsPerPixel[0]);//sets the BPP of the image
            loc += 2;
            break;
            default:
            FILE.close(); return ERROR3;
        }
        HEADERS=new unsigned char[DIBsize+14];
        for (int i=0; i<DIBsize+14; i++)
        {
            HEADERS[i]=ARRAY[i];
        }
        loc = start;
        unsigned char ***ret=new unsigned char**[BPP/8];
        for (int i=0; i<3; i++)
        {
            ret[i]=new unsigned char*[3];
            for (int ii=0; ii<3; ii++)
            {
                ret[ii][i]=new unsigned char[3];
            }
        }
        switch (BPP)
        {
            case 24://RGB
            for (int y=0; y<height; y++)
            {
                for (int x=0; x<width; x++)
                {
                    for (int i=0; i<3; i++)
                    {
                        ret[y][x][i]=ARRAY[loc];
                        loc++;
                    }
                }
                loc += 2;
            }
            FILE.close(); return ret;
            break;
            case 32://RGBA
            for (int y=0; y<height; y++)
            {
                for (int x=0; x<width; x++)
                {
                    for (int i=0; i<4; i++)
                    {
                        ret[y][x][i]=ARRAY[loc];
                        loc++;
                    }
                }
            }
            FILE.close(); return ret;
            break;
            default://32 is generally highest and anything lower than 24 divides by less than a byte, and I cannot access data that precisely without structs and tons of data
            FILE.close(); return ERROR3;
        }
    }
    void Bitmap::UPDATE()
    {
        unsigned char ***ret=new unsigned char**[BPP/8];
        for (int i=0; i<3; i++)
        {
            ret[i]=new unsigned char*[3];
            for (int ii=0; ii<3; ii++)
            {
                ret[ii][i]=new unsigned char[3];
            }
        }
        for (int y=0; y<height; y++)
        {
            for (int x=0; x<width; x++)
            {
                for (int i=0; i<(BPP/8); i++)
                {
                    ret[y][x][i]=IMAGE[y][x][i];
                }
            }
        }
        PICTURE=(int***)ret;
    }
    int main()
    {
        Bitmap PIC;
        PIC.OPEN(".\\TESTPIC.bmp");
        PIC.CLOSE(".\\TESTPIC2.bmp");
        return 0;
    }
    
     
  2. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    I was thinking of maybe converting the 3-dim arrays to one dimensional and creating an access function, but I can't figure out what that access function could be.
     
  3. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    Sorry, I can't edit my posts. I got the single dimensional array, three dimensional access function working, but the program itself still doesn't work. My hypothesis is that fstream cannot open .bmp files. So I was thinking maybe some kind of conversion might work. Any ideas how I could do this?!?!
     
  4. go4expert

    go4expert Moderator

    Joined:
    Aug 3, 2004
    Messages:
    306
    Likes Received:
    7
    Trophy Points:
    0
    Can you share where the infinite loop is because you have too many loops posted in the code and without running the program it is tedious to understand.
     
  5. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    That is the problem, I have no idea where the infinite loop may be happening, I could try adding more comments to the code and reposting, to see if that clears things up a bit.
     
  6. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    Here is some updated code, which has fewer loops:
    Code:
    #include <fstream>
    using namespace std;
    template <typename T>
    T &AT(int x, int y, int z, T *in, int ty, int tz)
    {
        return in[(x*(tz*ty))+z+tz*y];
    }
    class Bitmap
    {
        private:
        unsigned char *ERROR3;//the error value
        //Some raw variables in the file data:
        unsigned char *HEADERS;
        unsigned char FTYPE[2];//should be MP
        int size;
        int start;
        int DIBsize;
        int width;
        int height;
        short BPP;
        int COMPMETHOD;//should be zero or we could likely have a major problem!
        //HERES THE IMAGE!!!!!!
        unsigned char *IMAGE;
        //AND ONE WITH LESS MASSIVE RANGE, UPDATED BY A CALL TO UPDATE()
        int *PICTURE;
        public:
        void UPDATE();
        unsigned char *OPEN(char *fname);//BETTER NAME WOULD BE READ... OH WELL!
        void CLOSE(char *fname);//BETTER NAME WOULD BE SAVE... OH WELL!
    };
    void Bitmap::CLOSE(char *fname)
    {
        fstream FILE;
        FILE.open(fname, ios_base::in|ios_base::out|ios_base::binary);
        FILE<<HEADERS<<IMAGE;
        FILE.close();
    }
    unsigned char *Bitmap::OPEN(char *fname)//returns a 3Dimensional array for the image in the form of "H""W""RGB(A)"
    {
        unsigned char *ERROR3={0};
        fstream FILE;
        char Byte;
        int asize = 1;
        unsigned char *ARRAY = new unsigned char[asize];
        FILE.open(fname, ios_base::in|ios_base::out|ios_base::binary);
        while (!(FILE.eof()))
        {
            FILE.read(&Byte, 1);
            unsigned char *TEMP = new unsigned char[asize];
            TEMP = ARRAY;
            asize++;
            ARRAY = new unsigned char[asize];
            for (int i = 0; i<asize-1; i++)
            {
                ARRAY[i] = TEMP[i];
            }
            ARRAY[asize-1] = Byte;
        }//NOW ARRAY IS FULL OF THE CONTENTS OF FILE IN BINARY (IN ORDER)
        int loc = 0;
        unsigned char RFTYPE[2] = {ARRAY[loc], ARRAY[loc+1]};//Get the Magic Number (Should likely be MB[it is reversed])
        FTYPE[0]=RFTYPE[0];
        FTYPE[1]=RFTYPE[1];
        loc += 2;
        unsigned char FSIZE[4] = {ARRAY[loc], ARRAY[loc+1], ARRAY[loc+2], ARRAY[loc+3]};//Get the Size in bytes, in bytes
        size = 0;
        size |= (FSIZE[3]<<24);
        size |= (FSIZE[2]<<16);
        size |= (FSIZE[1]<<8);
        size |= (FSIZE[0]);//size is now size of file in bytes!
        loc += 8;//includes the 4 reserved bytes of data
        if (loc > size)
        {
            FILE.close(); return ERROR3;
        }//now loc can be checked
        unsigned char FSTART[4] = {ARRAY[loc], ARRAY[loc+1], ARRAY[loc+2], ARRAY[loc+3]};//Get the start of image data, in bytes
        start = 0;
        start |= (FSIZE[3]<<24);
        start |= (FSIZE[2]<<16);
        start |= (FSIZE[1]<<8);
        start |= (FSIZE[0]);//start is now the beginning of image data
        loc += 4;//go to DIB header
        unsigned char FDIBSIZE[4] = {ARRAY[loc], ARRAY[loc+1], ARRAY[loc+2], ARRAY[loc+3]};//Get the length of the DIB header
        DIBsize = 0;
        DIBsize |= (FDIBSIZE[3]<<24);
        DIBsize |= (FDIBSIZE[2]<<16);
        DIBsize |= (FDIBSIZE[1]<<8);
        DIBsize |= (FDIBSIZE[0]);
        loc += 4;
        unsigned char IWIDTH[4];
        unsigned char IHEIGHT[4];
        unsigned char BitsPerPixel[2];
        unsigned char CMETHOD[4];
        short val;
        switch (DIBsize)
        {
            case 40://it is BITMAP INFO HEADER we can use it
            IWIDTH[0] = ARRAY[loc];
            IWIDTH[1] = ARRAY[loc+1];
            IWIDTH[2] = ARRAY[loc+2];
            IWIDTH[3] = ARRAY[loc+3];//Get the width of the image
            width = 0;
            width |= (IWIDTH[3]<<24);
            width |= (IWIDTH[2]<<16);
            width |= (IWIDTH[1]<<8);
            width |= (IWIDTH[0]);
            loc += 4;
            IHEIGHT[0] = ARRAY[loc];
            IHEIGHT[1] = ARRAY[loc+1];
            IHEIGHT[2] = ARRAY[loc+2];
            IHEIGHT[3] = ARRAY[loc+3];//Get the height of the image
            height = 0;
            height |= (IHEIGHT[3]<<24);
            height |= (IHEIGHT[2]<<16);
            height |= (IHEIGHT[1]<<8);
            height |= (IHEIGHT[0]);
            loc += 6;//to account for plane numbers which, if not one, will cause an error so we don't need to check it
            BitsPerPixel[0] = ARRAY[loc];
            BitsPerPixel[1] = ARRAY[loc+1];
            BPP = 0;
            BPP |= (BitsPerPixel[1]<<8);
            BPP |= (BitsPerPixel[0]);//sets the BPP of the image
            loc += 2;
            CMETHOD[0] = ARRAY[loc];
            CMETHOD[1] = ARRAY[loc+1];
            CMETHOD[2] = ARRAY[loc+2];
            CMETHOD[3] = ARRAY[loc+3];
            COMPMETHOD = 0;
            COMPMETHOD |= (CMETHOD[3]<<24);
            COMPMETHOD |= (CMETHOD[2]<<16);
            COMPMETHOD |= (CMETHOD[1]<<8);
            COMPMETHOD |= (CMETHOD[0]);//set the method of compression
            loc += 20;//we are done with the important stuff, since Pixels per meter and palettes are not going to change our program
            break;
            case 12://it is BITMAP CORE HEADER we can use it
            IWIDTH[0] = ARRAY[loc];
            IWIDTH[1] = ARRAY[loc+1];
            IWIDTH[2] = 0;
            IWIDTH[3] = 0;
            val = 0;
            val |= (IWIDTH[1]<<8);
            val |= (IWIDTH[0]);
            width = (int)val;
            loc += 2;
            IHEIGHT[0] = ARRAY[loc];
            IHEIGHT[1] = ARRAY[loc+1];
            IHEIGHT[2] = ARRAY[loc+2];
            IHEIGHT[3] = ARRAY[loc+3];
            val = 0;
            val |= (IHEIGHT[1]<<8);
            val |= (IHEIGHT[0]);
            height = (int)val;
            loc += 4;//Also includes plane numbers which, if not one, will cause an error so we don't need to check it
            BitsPerPixel[0] = ARRAY[loc];
            BitsPerPixel[1] = ARRAY[loc+1];
            BPP = 0;
            BPP |= (BitsPerPixel[1]<<8);
            BPP |= (BitsPerPixel[0]);//sets the BPP of the image
            loc += 2;
            break;
            default:
            FILE.close(); return ERROR3;
        }
        HEADERS=new unsigned char[DIBsize+14];
        for (int i=0; i<DIBsize+14; i++)
        {
            HEADERS[i]=ARRAY[i];
        }
        loc = start;
        unsigned char *ret=new unsigned char[width*height*(BPP/8)];
        switch (BPP)
        {
            case 24://RGB
            for (int y=0; y<height; y++)
            {
                for (int x=0; x<width; x++)
                {
                    for (int i=0; i<3; i++)
                    {
                        AT<unsigned char>(x, y, i, ret, width, BPP/2)=ARRAY[loc];
                        loc++;
                    }
                }
                loc += 2;
            }
            FILE.close(); return ret;
            break;
            case 32://RGBA
            for (int y=0; y<height; y++)
            {
                for (int x=0; x<width; x++)
                {
                    for (int i=0; i<4; i++)
                    {
                        AT<unsigned char>(x, y, i, ret, width, BPP/2)=ARRAY[loc];
                        loc++;
                    }
                }
            }
            FILE.close(); return ret;
            break;
            default://32 is generally highest and anything lower than 24 divides by less than a byte, and I cannot access data that precisely without structs and tons of data
            FILE.close(); return ERROR3;
        }
    }
    void Bitmap::UPDATE()
    {
        unsigned char *ret=new unsigned char[width*height*(BPP/8)];
        for (int y=0; y<height; y++)
        {
            for (int x=0; x<width; x++)
            {
                for (int i=0; i<(BPP/8); i++)
                {
                    AT<unsigned char>(x, y, i, ret, width, (BPP/8))=AT<unsigned char>(x, y, i, IMAGE, width, (BPP/8));
                }
            }
        }
        PICTURE=(int*)ret;
    }
    int main()
    {
        Bitmap PIC;
        PIC.OPEN(".\\TESTPIC.bmp");
        PIC.CLOSE(".\\TESTPIC2.bmp");
        return 0;
    }
    
     
  7. NewsBot

    NewsBot New Member

    Joined:
    Dec 2, 2008
    Messages:
    1,267
    Likes Received:
    1
    Trophy Points:
    0
    How do you know then there is an infinite loop?
     
  8. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    I don't, but when it runs I get a blank STD console that waits for a few minutes, then causes windows to throw an exception (error report).
     
  9. NewsBot

    NewsBot New Member

    Joined:
    Dec 2, 2008
    Messages:
    1,267
    Likes Received:
    1
    Trophy Points:
    0
    It means there is some other issue then just an infinite loop. Debug and see where that exception happens
     
  10. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    That is one of the biggest problem's, I am using Code::Blocks and this is not a project, just an individual cpp file. How do I debug this?
     
  11. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    Alright I put the file into a blank project and debugged it. It all seemed fine except next to FILE it said incomplete type. What does this mean?
     
  12. NewsBot

    NewsBot New Member

    Joined:
    Dec 2, 2008
    Messages:
    1,267
    Likes Received:
    1
    Trophy Points:
    0
    Can you share the complete error it throws
     
  13. go4expert

    go4expert Moderator

    Joined:
    Aug 3, 2004
    Messages:
    306
    Likes Received:
    7
    Trophy Points:
    0
    Single CPP file does not mean it cannot be debugged. What compiler are you using?
     
  14. techgeek.in

    techgeek.in New Member

    Joined:
    Dec 20, 2009
    Messages:
    572
    Likes Received:
    17
    Trophy Points:
    0
    Occupation:
    EOC (exploitation of computers)..i m a Terminator.
    Location:
    Not an alien!! for sure
    Home Page:
    please share the error…then it would be easy for us to help you out..
     
  15. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    The error is in the debugging, I watch the variable called 'FILE' and it shows:
    FILE = <incomplete type>
    whereas next to Byte it shows
    Byte = 124 '|'
    I am also in the process of rewriting the program using fopen and such c-style file systems, hoping to avoid this error.
     
  16. techgeek.in

    techgeek.in New Member

    Joined:
    Dec 20, 2009
    Messages:
    572
    Likes Received:
    17
    Trophy Points:
    0
    Occupation:
    EOC (exploitation of computers)..i m a Terminator.
    Location:
    Not an alien!! for sure
    Home Page:
    is the debugger giving <incompatible type> after this line of your code...

    fstream FILE;

    or this line:-

    FILE.open(fname, ios_base::in|ios_base::eek:ut|ios_base::binary);
     
  17. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    it is the line after file.open, the while loop.
     
  18. NewsBot

    NewsBot New Member

    Joined:
    Dec 2, 2008
    Messages:
    1,267
    Likes Received:
    1
    Trophy Points:
    0
    What is the fname and does that file exists.
     
  19. louiskepler

    louiskepler New Member

    Joined:
    Nov 22, 2010
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    It does exist,, I was able to open it using fopen. I was thinking of trying to rewrite the code using fopen and fget, but I don't know how these work, i.e. fget returns an int (4 bytes) to show the contents of a char (1 byte), how does that work!
     

Share This Page