# memcpy to dx7 surface

This topic is 2443 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have an issue loading a bitmap file and then copying it to a directx7 surface.
I have isolated the header files and checked all of the resulting values against the image that I am trying to load, they all seem ok.
However when I run it, the image does not display correctly.
I would very much appreciate somebody casting their eye over my code and perhaps giving me a few pointers

I have been chasing this round for a while now. Think I'm going a bit bonkers. - code follows Cheers.

 void Bitmap::LoadBMP(const char *filename, const char *mode, bool isRLE) { HBITMAP hbm; BITMAP bm; FILE *m_bitMapFile; PVOID* pixData; DDSURFACEDESC2 ddsd; BYTE* surfacePointer; //HDC hdcImage; m_bitMapFile = fopen(filename,mode);//open the file for binary reading //structures defined in winGDi.h //describing .bmp header information BITMAPFILEHEADER bmfh; BITMAPINFOHEADER bmih; BITMAPINFO bmi; BITMAPINFO bmi2; fread(&bmfh,sizeof(BITMAPFILEHEADER),1,m_bitMapFile);// Read the file header info into bmfh fread(&bmi,sizeof(BITMAPINFO),1,m_bitMapFile); //fread(&bmih,sizeof(BITMAPINFOHEADER),1,m_bitMapFile);// Read the info header info into bmih //GetObject(m_bitMapFile,sizeof(bmi),&bmi); //Now that we have isolated the header info //A check to ensure the file is a bitmap //a value of 19778 (0x4d42) should be in BITMAPFILEHEADER.bfType WORD isBitmap = bmfh.bfType; if (isBitmap != 19778) { /* include some error response here */ //return false; }//OK we have a bitmap //fclose(m_bitMapFile); //Create our internal DirectDraw surface using values taken from the loaded bmp //first thing to do is reserve some memory for ddsd. //This will be passed to the CopyToInternalSurface ZeroMemory(&ddsd,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = bmi.bmiHeader.biWidth; ddsd.dwHeight = bmi.bmiHeader.biHeight; ddsd.ddpfPixelFormat.dwFlags = DDPF_COMPRESSED; ddsd.ddpfPixelFormat.dwRGBBitCount = bmi.bmiHeader.biBitCount; DirectDraw::GetInstance()->GetDirectDrawObject()->CreateSurface(&ddsd, &m_bitmapSurface, NULL); //Check to see if any compression is in use // 0 = none, if this is true the wronf function has been called - return // 1 = RLE 8-bit/pixel,Decode before copying to Surface // 2 = RLE 4-bit/pixel, Decode before copying to surface //decisions can be made for decoding based on this value. unsigned int compressed = bmi.bmiHeader.biCompression; if (compressed == 0)//no compression { //find the size of the image data //subtracting to offBits from the size is the most accurate way of doing this. DWORD size; size = bmfh.bfSize - bmfh.bfOffBits; //DWORD size = bmi.bmiHeader.biSizeImage; temppixelData = new BYTE[size]; size_t result; //fseek(m_bitMapFile,bmfh.bfOffBits,SEEK_SET); result = fread(temppixelData,sizeof(BYTE),size,m_bitMapFile); int e = feof(m_bitMapFile); //temppixelData now holds the raw image data. if((m_bitmapSurface->Lock(NULL,&ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK | DDLOCK_WRITEONLY, NULL))==DD_OK); { surfacePointer = (BYTE*)ddsd.lpSurface; for(int y=0; y < bmi.bmiHeader.biHeight; y++) { memcpy(surfacePointer +y*ddsd.lPitch, temppixelData+y*ddsd.dwWidth, ddsd.dwWidth*ddsd.ddpfPixelFormat.dwRGBBitCount); } } m_bitmapSurface->Unlock(NULL); m_bitmapwidth = bmi.bmiHeader.biWidth; m_bitmapheight = bmi.bmiHeader.biHeight; fclose(m_bitMapFile); } else if (compressed ==1)//RLE 8 { } else if (compressed ==2)//RLE 4 { //check for pallete then decode } } 

##### Share on other sites
Break into the debugger or log the values before you do the copy, and make sure the values obtained for the locked surface are what you expect.
In particular, ddsd.ddpfPixelFormat.dwRGBBitCount is in bits, not bytes, so you need to divide it by 8.
Also, y*ddsd.dwWidth should probably be multiplied by the number of bytes per pixel.
Do you need to use the DDPF_COMPRESSED flag?
Not sure what exactly that will do..

##### Share on other sites
I'm confused. First of all you create the surface with compression, then you check if compression is used in the bitmap, you have a comment explicitly stating that if no compression is used we don't even attempt to load the bitmap, and finally you do the exact opposite - you load an uncompressed bitmap into a compressed surface and don't handle the compressed bitmap cases.

##### Share on other sites
Erik and mhagain, thanks for the reply. I will try these thing out. My reason for handling an uncompressed images was that I am new to this and I wanted to be sure that I was copying to the surface correctly before I move onto trying this with compressed data. I didnt want to come across issues later on that appeared to compression related that were infact relateing to the moving of the data. My BITMAP class already has a function to load an uncompressed image that works well, but I have a need to be able to handle RLE compression. Thanks again for your reply

##### Share on other sites
I think I am getting somewhere with this. it seems that the surface lock is changing the [color=#1C2837][color=#000000]ddsd[color=#666600].[color=#000000]ddpfPixelFormat[color=#666600].[color=#000000]dwRGBBitCount.
[color=#1C2837][color=#000000]

[color=#1C2837][color=#000000]I cant imagine why.
[color=#1C2837][color=#000000]Can any body?

##### Share on other sites
It's also an output parameter, and it is supposed to change and tell you information about the surface you lock. The surface is already created and has a specific format, and you can't change that by locking it. The structure will be changed to reflect the actual contents of the surface, as that is the only type of data you can write to it with any reliable result.

##### Share on other sites
Hi Erik

So my surface is unchanged. I have also made the changes that you suggested earlier. I now see my image. the height is good. However the image width is not correct, it is squashed and is grey scale and the image background appears to have stripes. All of the other values are correct. could this be a problem with the DWORD boundary of the bitmap?

##### Share on other sites
Yes it could. Always read the Pitch, sometimes called row-bytes or similar, and use that to get the source and destination data for copying rows, as there may be padding. Also, make sure the bit-depth is the same in both source and destination, so you're not trying to copy 32 bit data to a 24 bit surface, or the other way around.

• 10
• 9
• 48
• 12
• 10
• ### Forum Statistics

• Total Topics
631383
• Total Posts
2999694
×