Skip to content

Commit bdb6551

Browse files
committed
Make copyRect function safer and add DX8Wrapper::Bytes_Per_Pixel function
1 parent eca8668 commit bdb6551

File tree

2 files changed

+125
-18
lines changed

2 files changed

+125
-18
lines changed

Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -134,62 +134,88 @@ void W3DSmudgeManager::ReAcquireResources(void)
134134
}
135135

136136
/*Copies a portion of the current render target into a specified buffer*/
137-
Int copyRect(unsigned char *buf, Int bufSize, int oX, int oY, int width, int height)
137+
Int copyRect(unsigned char *buf, Int bufSize, Int oX, Int oY, Int width, Int height)
138138
{
139-
IDirect3DSurface8 *surface=NULL; ///<previous render target
140-
IDirect3DSurface8 *tempSurface=NULL;
139+
IDirect3DSurface8 *surface=NULL; ///<previous render target
140+
IDirect3DSurface8 *tempSurface=NULL;
141141
Int result = 0;
142-
HRESULT hr = S_OK;
143142

144-
LPDIRECT3DDEVICE8 m_pDev=DX8Wrapper::_Get_D3D_Device8();
143+
LPDIRECT3DDEVICE8 m_pDev=DX8Wrapper::_Get_D3D_Device8();
145144

146145
if (!m_pDev)
147146
goto error;
148147

149-
m_pDev->GetRenderTarget(&surface);
148+
m_pDev->GetRenderTarget(&surface);
150149

151150
if (!surface)
152151
goto error;
153152

154-
D3DSURFACE_DESC desc;
155-
156-
surface->GetDesc(&desc);
153+
D3DSURFACE_DESC desc;
154+
surface->GetDesc(&desc);
157155

158156
RECT srcRect;
159157
srcRect.left=oX;
160158
srcRect.top=oY;
161159
srcRect.right=oX+width;
162160
srcRect.bottom=oY+height;
161+
DEBUG_ASSERTCRASH(srcRect.left >= 0, ("copyRect - Invalid size"));
162+
DEBUG_ASSERTCRASH(srcRect.top >= 0, ("copyRect - Invalid size"));
163+
DEBUG_ASSERTCRASH(srcRect.right < (LONG)desc.Width, ("copyRect - Invalid size"));
164+
DEBUG_ASSERTCRASH(srcRect.bottom < (LONG)desc.Height, ("copyRect - Invalid size"));
163165

164166
POINT dstPoint;
165167
dstPoint.x=0;
166168
dstPoint.y=0;
167169

168-
hr=m_pDev->CreateImageSurface( width, height, desc.Format, &tempSurface);
170+
HRESULT hr;
171+
hr=m_pDev->CreateImageSurface(width, height, desc.Format, &tempSurface);
169172

170173
if (hr != S_OK)
171174
goto error;
172175

173-
hr=m_pDev->CopyRects(surface,&srcRect,1,tempSurface,&dstPoint);
176+
hr=m_pDev->CopyRects(surface,&srcRect,1,tempSurface,&dstPoint);
174177

175178
if (hr != S_OK)
176179
goto error;
177180

178-
D3DLOCKED_RECT lrect;
181+
D3DLOCKED_RECT lrect;
179182

180-
hr=tempSurface->LockRect(&lrect,NULL,D3DLOCK_READONLY);
183+
hr=tempSurface->LockRect(&lrect,NULL,D3DLOCK_READONLY);
181184

182185
if (hr != S_OK)
183186
goto error;
184187

185-
tempSurface->GetDesc(&desc);
188+
tempSurface->GetDesc(&desc);
189+
UnsignedInt bytesPerPixel;
190+
bytesPerPixel = DX8Wrapper::Bytes_Per_Pixel(desc.Format);
191+
192+
if (bytesPerPixel == 0)
193+
goto error;
194+
195+
Int rowSize;
196+
Int totalSize;
197+
rowSize = width * bytesPerPixel;
198+
totalSize = height * rowSize;
186199

187-
if (desc.Size < bufSize)
188-
bufSize = desc.Size;
200+
if (totalSize > bufSize)
201+
totalSize = bufSize;
189202

190-
memcpy(buf,lrect.pBits,bufSize);
191-
result = bufSize;
203+
UnsignedByte* dst;
204+
UnsignedByte* src;
205+
Int rowCount;
206+
Int row;
207+
dst = buf;
208+
src = (UnsignedByte*)lrect.pBits;
209+
rowCount = totalSize / rowSize;
210+
211+
for (row = 0; row < rowCount; ++row)
212+
{
213+
memcpy(dst, src, rowSize);
214+
dst += rowSize;
215+
src += lrect.Pitch;
216+
}
192217

218+
result = totalSize;
193219
tempSurface->UnlockRect();
194220

195221
error:

GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,8 @@ class DX8Wrapper
455455
static void _Enable_Triangle_Draw(bool enable) { _EnableTriangleDraw=enable; }
456456
static bool _Is_Triangle_Draw_Enabled() { return _EnableTriangleDraw; }
457457

458+
static unsigned int Bytes_Per_Pixel(D3DFORMAT format);
459+
458460
/*
459461
** Additional swap chain interface
460462
**
@@ -1161,6 +1163,85 @@ WWINLINE void DX8Wrapper::Set_Alpha (const float alpha, unsigned int &color)
11611163
component [3] = 255.0f * alpha;
11621164
}
11631165

1166+
WWINLINE unsigned int DX8Wrapper::Bytes_Per_Pixel(D3DFORMAT format)
1167+
{
1168+
switch (format)
1169+
{
1170+
// 8-bit formats
1171+
case D3DFMT_A8:
1172+
case D3DFMT_P8:
1173+
case D3DFMT_L8:
1174+
return 1;
1175+
1176+
// 16-bit formats
1177+
case D3DFMT_R5G6B5:
1178+
case D3DFMT_X1R5G5B5:
1179+
case D3DFMT_A1R5G5B5:
1180+
case D3DFMT_A4R4G4B4:
1181+
case D3DFMT_X4R4G4B4:
1182+
case D3DFMT_A8L8:
1183+
case D3DFMT_A4L4:
1184+
case D3DFMT_V8U8:
1185+
case D3DFMT_L6V5U5:
1186+
return 2;
1187+
1188+
// 24-bit formats
1189+
case D3DFMT_R8G8B8:
1190+
return 3;
1191+
1192+
// 32-bit formats
1193+
case D3DFMT_A8R8G8B8:
1194+
case D3DFMT_X8R8G8B8:
1195+
case D3DFMT_A8R3G3B2:
1196+
case D3DFMT_A2B10G10R10:
1197+
case D3DFMT_G16R16:
1198+
case D3DFMT_X8L8V8U8:
1199+
case D3DFMT_Q8W8V8U8:
1200+
case D3DFMT_W11V11U10:
1201+
case D3DFMT_A2W10V10U10:
1202+
case D3DFMT_V16U16:
1203+
return 4;
1204+
1205+
// Palette-based alpha
1206+
case D3DFMT_A8P8:
1207+
return 0;
1208+
1209+
// Packed YUV
1210+
case D3DFMT_UYVY:
1211+
case D3DFMT_YUY2:
1212+
return 0;
1213+
1214+
// Block-compressed
1215+
case D3DFMT_DXT1:
1216+
case D3DFMT_DXT2:
1217+
case D3DFMT_DXT3:
1218+
case D3DFMT_DXT4:
1219+
case D3DFMT_DXT5:
1220+
return 0;
1221+
1222+
// Depth / stencil
1223+
case D3DFMT_D16_LOCKABLE:
1224+
case D3DFMT_D16:
1225+
case D3DFMT_D15S1:
1226+
case D3DFMT_D24S8:
1227+
case D3DFMT_D24X8:
1228+
case D3DFMT_D24X4S4:
1229+
case D3DFMT_D32:
1230+
return 0;
1231+
1232+
// Non-image data
1233+
case D3DFMT_VERTEXDATA:
1234+
case D3DFMT_INDEX16:
1235+
case D3DFMT_INDEX32:
1236+
return 0;
1237+
1238+
// Unknown / invalid
1239+
case D3DFMT_UNKNOWN:
1240+
default:
1241+
return 0;
1242+
}
1243+
}
1244+
11641245
WWINLINE void DX8Wrapper::Get_Render_State(RenderStateStruct& state)
11651246
{
11661247
state=render_state;

0 commit comments

Comments
 (0)