Current News
Archived News
Search News
Discussion Forum


Old Forum
Install Programs More Downloads...
Troubleshooting
Source Code
Format Specs.
Misc. Information
Non-SF Stuff
Links




CommitLineData
14362b19 1#include "grpapi.h"\r
ecca31ff 2#include "../LoadStorm/storm.h"\r
14362b19 3#include <malloc.h>\r
4\r
5#ifdef GRPAPI_STATIC\r
6#define DllMain GrpMain\r
7\r
8#include "grp_static.h"\r
9\r
10struct GRPLIBMODULE {\r
11 GRPLIBMODULE();\r
12 ~GRPLIBMODULE();\r
13} GrpLib;\r
14\r
15BOOL APIENTRY DllMain(HINSTANCE hInstDLL, DWORD ul_reason_for_call, LPVOID lpReserved);\r
16\r
17GRPLIBMODULE::GRPLIBMODULE()\r
18{\r
19 GrpMain(0,DLL_PROCESS_ATTACH,0);\r
20}\r
21\r
22GRPLIBMODULE::~GRPLIBMODULE()\r
23{\r
24 GrpMain(0,DLL_PROCESS_DETACH,0);\r
25}\r
26\r
27#endif\r
28\r
29typedef struct {\r
30 BYTE Left;\r
31 BYTE Top;\r
32 BYTE Width;\r
33 BYTE Height;\r
34 DWORD Offset;\r
35} FRAMEHEADER;\r
36\r
c483a082 37typedef struct {\r
38 WORD *lpRowOffsets;\r
39 WORD *lpRowSizes;\r
40 LPBYTE *lpRowData;\r
41} FRAMEDATA;\r
42\r
ecca31ff 43GETPIXELPROC MyGetPixel = GetPixel;\r
44SETPIXELPROC MySetPixel = (SETPIXELPROC)SetPixelV;\r
45\r
ff024783 46void __inline SetPix(HDC hDC, int X, int Y, COLORREF clrColor, DWORD *dwPalette, DWORD dwFlags, DWORD dwAlpha);\r
c483a082 47void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHeader, FRAMEHEADER *lpFrameHeader, FRAMEDATA *lpFrameData);\r
14362b19 48\r
49extern HINSTANCE hStorm;\r
50\r
51BOOL APIENTRY DllMain( HINSTANCE hInstDLL, \r
52 DWORD ul_reason_for_call, \r
53 LPVOID lpReserved\r
54 )\r
55{\r
56 switch (ul_reason_for_call)\r
57 {\r
58 case DLL_PROCESS_ATTACH:\r
59 break;\r
60 case DLL_THREAD_ATTACH:\r
61 break;\r
62 case DLL_THREAD_DETACH:\r
63 break;\r
64 case DLL_PROCESS_DETACH:\r
65 break;\r
66 }\r
67\r
68 return TRUE;\r
69}\r
70\r
71BOOL GRPAPI WINAPI LoadGrpApi()\r
72{\r
ecca31ff 73 if (!hStorm) return FALSE;\r
14362b19 74 else return TRUE;\r
75}\r
76\r
77void GRPAPI WINAPI FreeGrpApi()\r
78{\r
79}\r
80\r
ecca31ff 81BOOL GRPAPI WINAPI SetMpqDll(LPCSTR lpDllFileName)\r
82{\r
83 if (LoadStorm((char *)lpDllFileName)) return TRUE;\r
84 else return FALSE;\r
85}\r
86\r
14362b19 87BOOL GRPAPI WINAPI LoadPalette(LPCSTR lpFileName, DWORD *dwPaletteBuffer)\r
88{\r
ecca31ff 89 if (!lpFileName || !dwPaletteBuffer) return FALSE;\r
14362b19 90 HANDLE hFile;\r
ecca31ff 91 if (SFileOpenFileEx && SFileGetFileSize\r
92 && SFileSetFilePointer && SFileReadFile\r
93 && SFileCloseFile) {\r
94 if (!SFileOpenFileEx(0,lpFileName,1,&hFile)) return FALSE;\r
14362b19 95 DWORD fsz = SFileGetFileSize(hFile,0);\r
96 SFileSetFilePointer(hFile,0,0,FILE_BEGIN);\r
97 if (fsz>=1024) {\r
98 memset(dwPaletteBuffer,0,1024);\r
99 SFileReadFile(hFile,dwPaletteBuffer,1024,0,0);\r
100 }\r
101 else if (fsz==768) {\r
102 char *buffer = (char *)_alloca(768);\r
103 memset(buffer,0,768);\r
104 SFileReadFile(hFile,buffer,768,0,0);\r
105 for (DWORD i=0;i<256;i++) {\r
106 memcpy(&dwPaletteBuffer[i],buffer+i*3,3);\r
107 *(((char *)&dwPaletteBuffer[i])+3) = 0;\r
108 }\r
109 }\r
110 else {\r
111 memset(dwPaletteBuffer,0,1024);\r
112 SFileReadFile(hFile,dwPaletteBuffer,fsz,0,0);\r
113 }\r
114 SFileCloseFile(hFile);\r
115 }\r
116 else {\r
117 hFile = CreateFile(lpFileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);\r
118 if (hFile==INVALID_HANDLE_VALUE) return FALSE;\r
119 DWORD fsz = GetFileSize(hFile,0),tsz;\r
120 SetFilePointer(hFile,0,0,FILE_BEGIN);\r
121 if (fsz>=1024) {\r
122 memset(dwPaletteBuffer,0,1024);\r
123 ReadFile(hFile,dwPaletteBuffer,1024,&tsz,0);\r
124 }\r
125 else if (fsz==768) {\r
126 char *buffer = (char *)_alloca(768);\r
127 memset(buffer,0,768);\r
128 ReadFile(hFile,buffer,768,&tsz,0);\r
129 for (DWORD i=0;i<256;i++) {\r
130 memcpy(&dwPaletteBuffer[i],buffer+i*3,3);\r
131 *(((char *)&dwPaletteBuffer[i])+3) = 0;\r
132 }\r
133 }\r
134 else {\r
135 memset(dwPaletteBuffer,0,1024);\r
136 ReadFile(hFile,dwPaletteBuffer,fsz,&tsz,0);\r
137 }\r
138 CloseHandle(hFile);\r
139 }\r
140 return TRUE;\r
141}\r
142\r
143HANDLE GRPAPI WINAPI LoadGrp(LPCSTR lpFileName)\r
144{\r
ecca31ff 145 if (!lpFileName) return (HANDLE)-1;\r
14362b19 146 HANDLE hFile;\r
147 char *GrpFile;\r
ecca31ff 148 if (SFileOpenFileEx && SFileGetFileSize\r
149 && SFileSetFilePointer && SFileReadFile\r
150 && SFileCloseFile) {\r
151 if (!SFileOpenFileEx(0,lpFileName,1,&hFile)) return (HANDLE)-1;\r
14362b19 152 DWORD fsz = SFileGetFileSize(hFile,0);\r
153 if (fsz<6) {\r
154 SFileCloseFile(hFile);\r
155 return (HANDLE)-1;\r
156 }\r
afcd1861 157 GrpFile = (char *)malloc(fsz);\r
ecca31ff 158 if (GrpFile) {\r
14362b19 159 SFileSetFilePointer(hFile,0,0,FILE_BEGIN);\r
160 SFileReadFile(hFile,GrpFile,fsz,0,0);\r
161 }\r
162 else GrpFile=(char *)-1;\r
163 SFileCloseFile(hFile);\r
164 }\r
165 else {\r
166 hFile = CreateFile(lpFileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);\r
167 if (hFile==INVALID_HANDLE_VALUE) return (HANDLE)-1;\r
168 DWORD fsz = GetFileSize(hFile,0),tsz;\r
169 if (fsz<6) {\r
170 CloseHandle(hFile);\r
171 return (HANDLE)-1;\r
172 }\r
afcd1861 173 GrpFile = (char *)malloc(fsz);\r
ecca31ff 174 if (GrpFile) {\r
14362b19 175 SetFilePointer(hFile,0,0,FILE_BEGIN);\r
176 ReadFile(hFile,GrpFile,fsz,&tsz,0);\r
177 }\r
178 else GrpFile=(char *)-1;\r
179 CloseHandle(hFile);\r
180 }\r
181 return (HANDLE)GrpFile;\r
182}\r
183\r
184BOOL GRPAPI WINAPI DestroyGrp(HANDLE hGrp)\r
185{\r
ecca31ff 186 if (!hGrp || hGrp==INVALID_HANDLE_VALUE) return FALSE;\r
afcd1861 187 free(hGrp);\r
14362b19 188 return TRUE;\r
189}\r
190\r
191BOOL GRPAPI WINAPI DrawGrp(HANDLE hGrp, HDC hdcDest, int nXDest, int nYDest, WORD nFrame, DWORD *dwPalette, DWORD dwFlags, DWORD dwAlpha)\r
192{\r
c483a082 193 if (!hGrp || hGrp==INVALID_HANDLE_VALUE || hdcDest==0 || (!dwPalette && !(dwFlags&USE_INDEX))) return FALSE;\r
14362b19 194 GRPHEADER *GrpFile = (GRPHEADER *)hGrp;\r
195 nFrame %= GrpFile->nFrames;\r
196 FRAMEHEADER *GrpFrame = &((FRAMEHEADER *)(((char *)GrpFile)+6))[nFrame];\r
2975ca34 197 FRAMEHEADER *GrpFrames = &((FRAMEHEADER *)(((char *)GrpFile)+6))[0];\r
198 int FrameSize = 0xFFFFFF;\r
14362b19 199 DWORD Right,Bottom;\r
200 if (dwFlags&HORIZONTAL_FLIP) Right = nXDest+GrpFile->wMaxWidth-1-GrpFrame->Left;\r
201 if (dwFlags&VERTICAL_FLIP) Bottom = nYDest+GrpFile->wMaxHeight-1-GrpFrame->Top;\r
202 nXDest += GrpFrame->Left;\r
203 nYDest += GrpFrame->Top;\r
204 WORD *GrpOffsets = ((WORD *)(((char *)GrpFile)+GrpFrame->Offset));\r
2975ca34 205 BYTE *GrpRaw = (BYTE *)GrpOffsets;\r
ecca31ff 206 BYTE *RowData;\r
207 WORD x,ofs;\r
208 DWORD y;\r
209 WORD i;\r
2975ca34 210 int j;\r
211 if (nFrame + 1 < GrpFile->nFrames) {\r
212 for (i = 0; i + 1 < GrpFile->nFrames; i++) {\r
213 j = GrpFrames[i].Offset - GrpFrame->Offset;\r
214 if (j > 0 && j < FrameSize)\r
215 FrameSize = j;\r
216 }\r
217 }\r
218 if (FrameSize == 0xFFFFFF) {\r
219 for (i = 0; i + 1 < GrpFile->nFrames; i++) {\r
220 j = GrpFrames[i].Offset - GrpFrames[0].Offset;\r
221 if (j > 0 && j < FrameSize)\r
222 FrameSize = j;\r
223 }\r
224 if (FrameSize == GrpFrames[0].Width * GrpFrames[0].Height)\r
225 FrameSize = GrpFrame->Width * GrpFrame->Height;\r
226 }\r
ecca31ff 227 if (!(dwFlags&HORIZONTAL_FLIP) && !(dwFlags&VERTICAL_FLIP)) {\r
2975ca34 228 if (FrameSize != GrpFrame->Width * GrpFrame->Height) {\r
229 for (y=0;y<GrpFrame->Height;y++) {\r
230 RowData = ((BYTE *)(((char *)GrpOffsets)+GrpOffsets[y]));\r
231 x=0; ofs=0;\r
232 while (x<GrpFrame->Width) {\r
233 if (!(RowData[ofs] & 0x80)) {\r
234 if (!(RowData[ofs] & 0x40)) {\r
235 for (i=1;i<=RowData[ofs] && x<GrpFrame->Width;i++) {\r
ff024783 236 SetPix(hdcDest,nXDest+x,nYDest+y,RowData[ofs+i],dwPalette,dwFlags,dwAlpha);\r
2975ca34 237 x++;\r
238 }\r
239 ofs+=RowData[ofs]+1;\r
240 }\r
241 else {\r
242 for (i=0;i<RowData[ofs]-64 && x<GrpFrame->Width;i++) {\r
ff024783 243 SetPix(hdcDest,nXDest+x,nYDest+y,RowData[ofs+1],dwPalette,dwFlags,dwAlpha);\r
2975ca34 244 x++;\r
245 }\r
246 ofs+=2;\r
ecca31ff 247 }\r
14362b19 248 }\r
ecca31ff 249 else {\r
2975ca34 250 x+=RowData[ofs]-128;\r
251 ofs++;\r
14362b19 252 }\r
253 }\r
2975ca34 254 }\r
255 }\r
256 else {\r
257 for (y=0;y<GrpFrame->Height;y++) {\r
258 for (x=0;x<GrpFrame->Width;x++) {\r
ff024783 259 SetPix(hdcDest,nXDest+x,nYDest+y,GrpRaw[y * GrpFrame->Width + x],dwPalette,dwFlags,dwAlpha);\r
ecca31ff 260 }\r
261 }\r
262 }\r
263 }\r
264 else if (dwFlags&HORIZONTAL_FLIP && !(dwFlags&VERTICAL_FLIP)) {\r
2975ca34 265 if (FrameSize != GrpFrame->Width * GrpFrame->Height) {\r
266 for (y=0;y<GrpFrame->Height;y++) {\r
267 RowData = ((BYTE *)(((char *)GrpOffsets)+GrpOffsets[y]));\r
268 x=0; ofs=0;\r
269 while (x<GrpFrame->Width) {\r
270 if (!(RowData[ofs] & 0x80)) {\r
271 if (!(RowData[ofs] & 0x40)) {\r
272 for (i=1;i<=RowData[ofs] && x<GrpFrame->Width;i++) {\r
ff024783 273 SetPix(hdcDest,Right-x,nYDest+y,RowData[ofs+i],dwPalette,dwFlags,dwAlpha);\r
2975ca34 274 x++;\r
275 }\r
276 ofs+=RowData[ofs]+1;\r
277 }\r
278 else {\r
279 for (i=0;i<RowData[ofs]-64 && x<GrpFrame->Width;i++) {\r
ff024783 280 SetPix(hdcDest,Right-x,nYDest+y,RowData[ofs+1],dwPalette,dwFlags,dwAlpha);\r
2975ca34 281 x++;\r
282 }\r
283 ofs+=2;\r
ecca31ff 284 }\r
ecca31ff 285 }\r
286 else {\r
2975ca34 287 x+=RowData[ofs]-128;\r
288 ofs++;\r
14362b19 289 }\r
290 }\r
2975ca34 291 }\r
292 }\r
293 else {\r
294 for (y=0;y<GrpFrame->Height;y++) {\r
295 for (x=0;x<GrpFrame->Width;x++) {\r
ff024783 296 SetPix(hdcDest,Right-x,nYDest+y,GrpRaw[y * GrpFrame->Width + x],dwPalette,dwFlags,dwAlpha);\r
14362b19 297 }\r
14362b19 298 }\r
ecca31ff 299 }\r
300 }\r
301 else if (!(dwFlags&HORIZONTAL_FLIP) && dwFlags&VERTICAL_FLIP) {\r
2975ca34 302 if (FrameSize != GrpFrame->Width * GrpFrame->Height) {\r
303 for (y=0;y<GrpFrame->Height;y++) {\r
304 RowData = ((BYTE *)(((char *)GrpOffsets)+GrpOffsets[y]));\r
305 x=0; ofs=0;\r
306 while (x<GrpFrame->Width) {\r
307 if (!(RowData[ofs] & 0x80)) {\r
308 if (!(RowData[ofs] & 0x40)) {\r
309 for (i=1;i<=RowData[ofs] && x<GrpFrame->Width;i++) {\r
ff024783 310 SetPix(hdcDest,nXDest+x,Bottom-y,RowData[ofs+i],dwPalette,dwFlags,dwAlpha);\r
2975ca34 311 x++;\r
312 }\r
313 ofs+=RowData[ofs]+1;\r
314 }\r
315 else {\r
316 for (i=0;i<RowData[ofs]-64 && x<GrpFrame->Width;i++) {\r
ff024783 317 SetPix(hdcDest,nXDest+x,Bottom-y,RowData[ofs+1],dwPalette,dwFlags,dwAlpha);\r
2975ca34 318 x++;\r
319 }\r
320 ofs+=2;\r
ecca31ff 321 }\r
14362b19 322 }\r
ecca31ff 323 else {\r
2975ca34 324 x+=RowData[ofs]-128;\r
325 ofs++;\r
14362b19 326 }\r
327 }\r
2975ca34 328 }\r
329 }\r
330 else {\r
331 for (y=0;y<GrpFrame->Height;y++) {\r
332 for (x=0;x<GrpFrame->Width;x++) {\r
ff024783 333 SetPix(hdcDest,nXDest+x,Bottom-y,GrpRaw[y * GrpFrame->Width + x],dwPalette,dwFlags,dwAlpha);\r
ecca31ff 334 }\r
335 }\r
336 }\r
337 }\r
338 else {\r
2975ca34 339 if (FrameSize != GrpFrame->Width * GrpFrame->Height) {\r
340 for (y=0;y<GrpFrame->Height;y++) {\r
341 RowData = ((BYTE *)(((char *)GrpOffsets)+GrpOffsets[y]));\r
342 x=0; ofs=0;\r
343 while (x<GrpFrame->Width) {\r
344 if (!(RowData[ofs] & 0x80)) {\r
345 if (!(RowData[ofs] & 0x40)) {\r
346 for (i=1;i<=RowData[ofs] && x<GrpFrame->Width;i++) {\r
ff024783 347 SetPix(hdcDest,Right-x,Bottom-y,RowData[ofs+i],dwPalette,dwFlags,dwAlpha);\r
2975ca34 348 x++;\r
349 }\r
350 ofs+=RowData[ofs]+1;\r
351 }\r
352 else {\r
353 for (i=0;i<RowData[ofs]-64 && x<GrpFrame->Width;i++) {\r
ff024783 354 SetPix(hdcDest,Right-x,Bottom-y,RowData[ofs+1],dwPalette,dwFlags,dwAlpha);\r
2975ca34 355 x++;\r
356 }\r
357 ofs+=2;\r
ecca31ff 358 }\r
ecca31ff 359 }\r
360 else {\r
2975ca34 361 x+=RowData[ofs]-128;\r
362 ofs++;\r
14362b19 363 }\r
364 }\r
2975ca34 365 }\r
366 }\r
367 else {\r
368 for (y=0;y<GrpFrame->Height;y++) {\r
369 for (x=0;x<GrpFrame->Width;x++) {\r
ff024783 370 SetPix(hdcDest,Right-x,Bottom-y,GrpRaw[y * GrpFrame->Width + x],dwPalette,dwFlags,dwAlpha);\r
14362b19 371 }\r
14362b19 372 }\r
373 }\r
374 }\r
375 return TRUE;\r
376}\r
377\r
378BOOL GRPAPI WINAPI GetGrpInfo(HANDLE hGrp, GRPHEADER *GrpInfo)\r
379{\r
ecca31ff 380 if (!hGrp || hGrp==INVALID_HANDLE_VALUE || !GrpInfo) return FALSE;\r
14362b19 381 memcpy(GrpInfo,hGrp,6);\r
382 return TRUE;\r
383}\r
384\r
ecca31ff 385void GRPAPI WINAPI SetFunctionGetPixel(GETPIXELPROC lpGetPixelProc)\r
386{\r
afcd1861 387 if (!lpGetPixelProc)\r
388 MyGetPixel = GetPixel;\r
389 else\r
390 MyGetPixel = lpGetPixelProc;\r
ecca31ff 391}\r
392\r
393void GRPAPI WINAPI SetFunctionSetPixel(SETPIXELPROC lpSetPixelProc)\r
394{\r
afcd1861 395 if (!lpSetPixelProc)\r
396 MySetPixel = (SETPIXELPROC)SetPixelV;\r
397 else\r
398 MySetPixel = lpSetPixelProc;\r
ecca31ff 399}\r
400\r
ff024783 401void __inline SetPix(HDC hDC, int X, int Y, COLORREF clrColor, DWORD *dwPalette, DWORD dwFlags, DWORD dwAlpha)\r
14362b19 402{\r
ff024783 403 if (!(dwFlags&USE_INDEX)) {\r
404 if (dwFlags&SHADOW_COLOR) {\r
405 clrColor = (dwFlags >> 8) & 0x00FFFFFF;\r
406 }\r
407 else {\r
408 clrColor = dwPalette[clrColor];\r
409 }\r
410 if (dwFlags&ALPHA_BLEND) {\r
411 DWORD dwColor = MyGetPixel(hDC,X,Y);\r
14362b19 412\r
ff024783 413 // Old alpha\r
414 /*((BYTE *)&dwColor)[0]*=1-((float)((BYTE *)&dwAlpha)[0]/256);\r
415 ((BYTE *)&dwColor)[1]*=1-((float)((BYTE *)&dwAlpha)[1]/256);\r
416 ((BYTE *)&dwColor)[2]*=1-((float)((BYTE *)&dwAlpha)[2]/256);\r
417 ((BYTE *)&clrColor)[0]*=(float)((BYTE *)&dwAlpha)[0]/256;\r
418 ((BYTE *)&clrColor)[1]*=(float)((BYTE *)&dwAlpha)[1]/256;\r
419 ((BYTE *)&clrColor)[2]*=(float)((BYTE *)&dwAlpha)[2]/256;\r
420 ((BYTE *)&clrColor)[0]+=((BYTE *)&dwColor)[0];\r
421 ((BYTE *)&clrColor)[1]+=((BYTE *)&dwColor)[1];\r
422 ((BYTE *)&clrColor)[2]+=((BYTE *)&dwColor)[2];*/\r
14362b19 423\r
ff024783 424 /* blendedcolor =\r
425 ( ( forecolor * ( 1 - alpha ) ) >> 8 )\r
426 + ( ( backcolor * ( 256 - alpha ) ) >> 8 ) */\r
427 ((BYTE *)&clrColor)[0] =\r
428 ( ( ((BYTE *)&clrColor)[0] * ( ((BYTE *)&dwAlpha)[0] + 1 ) ) >> 8 )\r
429 + ( ( ((BYTE *)&dwColor)[0] * ( 256 - ((BYTE *)&dwAlpha)[0] ) ) >> 8 );\r
430 ((BYTE *)&clrColor)[1] =\r
431 ( ( ((BYTE *)&clrColor)[1] * ( ((BYTE *)&dwAlpha)[1] + 1 ) ) >> 8 )\r
432 + ( ( ((BYTE *)&dwColor)[1] * ( 256 - ((BYTE *)&dwAlpha)[1] ) ) >> 8 );\r
433 ((BYTE *)&clrColor)[2] =\r
434 ( ( ((BYTE *)&clrColor)[2] * ( ((BYTE *)&dwAlpha)[2] + 1 ) ) >> 8 )\r
435 + ( ( ((BYTE *)&dwColor)[2] * ( 256 - ((BYTE *)&dwAlpha)[2] ) ) >> 8 );\r
436 }\r
14362b19 437 }\r
ecca31ff 438 MySetPixel(hDC,X,Y,clrColor);\r
14362b19 439}\r
c483a082 440\r
441HANDLE GRPAPI WINAPI CreateGrp(signed short *lpImageData, WORD nFrames, WORD wMaxWidth, WORD wMaxHeight, DWORD *nGrpSize)\r
442{\r
443 GRPHEADER GrpHeader;\r
444 FRAMEHEADER *lpFrameHeaders;\r
445 FRAMEDATA *lpFrameData;\r
446 LPBYTE lpGrpData;\r
447 int i, x, y, x1, x2, y1, y2;\r
448\r
449 if (!lpImageData || !nGrpSize) return (HANDLE)-1;\r
450\r
451 GrpHeader.nFrames = nFrames;\r
452 GrpHeader.wMaxWidth = wMaxWidth;\r
453 GrpHeader.wMaxHeight = wMaxHeight;\r
454 lpFrameHeaders = (FRAMEHEADER *)malloc((nFrames + 1) * sizeof(FRAMEHEADER));\r
455 lpFrameData = (FRAMEDATA *)malloc(nFrames * sizeof(FRAMEDATA));\r
456\r
457 for (i = 0; i <= nFrames; i++) {\r
458 if (i == 0) {\r
459 lpFrameHeaders[i].Offset = sizeof(GRPHEADER) + nFrames * sizeof(FRAMEHEADER);\r
460 }\r
461 else {\r
462 y = lpFrameHeaders[i-1].Height;\r
463 if (y > 0) {\r
464 y--;\r
465 lpFrameHeaders[i].Offset = lpFrameHeaders[i-1].Offset + lpFrameData[i-1].lpRowOffsets[y] + lpFrameData[i-1].lpRowSizes[y];\r
466 }\r
467 else {\r
468 lpFrameHeaders[i].Offset = lpFrameHeaders[i-1].Offset;\r
469 }\r
470 }\r
471 if (i == nFrames) continue;\r
472\r
473 // Scan frame to find dimensions of used part\r
474 x1 = y1 = 0x10000;\r
475 x2 = y2 = -1;\r
476 for (y = 0; y < wMaxHeight; y++) {\r
477 for (x = 0; x < wMaxWidth; x++) {\r
478 if (lpImageData[i * wMaxWidth * wMaxHeight + y * wMaxWidth + x] >= 0) {\r
479 if (x < x1) x1 = x;\r
480 if (x > x2) x2 = x;\r
481 if (y < y1) y1 = y;\r
482 if (y > y2) y2 = y;\r
483 }\r
484 }\r
485 }\r
486 lpFrameHeaders[i].Left = x1;\r
487 lpFrameHeaders[i].Top = y1;\r
488 lpFrameHeaders[i].Width = x2 - x1 + 1;\r
489 lpFrameHeaders[i].Height = y2 - y1 + 1;\r
490\r
491 EncodeFrameData(lpImageData, i, &GrpHeader, &lpFrameHeaders[i], &lpFrameData[i]);\r
492 }\r
493\r
494 lpGrpData = (LPBYTE)malloc(lpFrameHeaders[nFrames].Offset);\r
495\r
496 // Write completed GRP to buffer\r
497 memcpy(lpGrpData, &GrpHeader, sizeof(GRPHEADER));\r
498 memcpy(lpGrpData + sizeof(GRPHEADER), lpFrameHeaders, nFrames * sizeof(FRAMEHEADER));\r
499\r
500 for (i = 0; i < nFrames; i++) {\r
501 memcpy(lpGrpData + lpFrameHeaders[i].Offset, lpFrameData[i].lpRowOffsets, lpFrameHeaders[i].Height * sizeof(WORD));\r
502\r
503 for (y = 0; y < lpFrameHeaders[i].Height; y++) {\r
504 memcpy(lpGrpData + lpFrameHeaders[i].Offset + lpFrameData[i].lpRowOffsets[y], lpFrameData[i].lpRowData[y], lpFrameData[i].lpRowSizes[y]);\r
505 free(lpFrameData[i].lpRowData[y]);\r
506 }\r
507\r
508 free(lpFrameData[i].lpRowOffsets);\r
509 free(lpFrameData[i].lpRowSizes);\r
510 free(lpFrameData[i].lpRowData);\r
511 }\r
512\r
513 *nGrpSize = lpFrameHeaders[nFrames].Offset;\r
514 free(lpFrameHeaders);\r
515 free(lpFrameData);\r
516\r
517 return (HANDLE)lpGrpData;\r
518}\r
519\r
520void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHeader, FRAMEHEADER *lpFrameHeader, FRAMEDATA *lpFrameData)\r
521{\r
522 int x, y, i, nBufPos;\r
523 LPBYTE lpRowBuf;\r
524\r
525 lpFrameData->lpRowOffsets = (WORD *)malloc(lpFrameHeader->Height * sizeof(WORD));\r
526 lpFrameData->lpRowSizes = (WORD *)malloc(lpFrameHeader->Height * sizeof(WORD));\r
527 lpFrameData->lpRowData = (LPBYTE *)malloc(lpFrameHeader->Height * sizeof(LPBYTE));\r
528 lpRowBuf = (LPBYTE)malloc(lpFrameHeader->Width * 2);\r
529\r
530 for (y = 0; y < lpFrameHeader->Height; y++) {\r
531 i = nFrame * lpGrpHeader->wMaxWidth * lpGrpHeader->wMaxHeight + (lpFrameHeader->Top + y) * lpGrpHeader->wMaxWidth;\r
532 nBufPos = 0;\r
533 if (lpFrameHeader->Width > 1) {\r
534 for (x = lpFrameHeader->Left; x < lpFrameHeader->Left + lpFrameHeader->Width - 1; x++) {\r
535 if (lpImageData[i+x] < 0) {\r
536 lpRowBuf[nBufPos] = 0x80;\r
537 for (; lpImageData[i+x] < 0 && x < lpFrameHeader->Left + lpFrameHeader->Width; x++) {\r
538 lpRowBuf[nBufPos]++;\r
539 }\r
540 x--;\r
541 nBufPos++;\r
542 }\r
543 else if (lpImageData[i+x] == lpImageData[i+x+1]) {\r
544 lpRowBuf[nBufPos] = 0x41;\r
545 lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+x];\r
546 for (; lpImageData[i+x] == lpImageData[i+x+1] && x < lpFrameHeader->Left + lpFrameHeader->Width - 1; x++) {\r
547 lpRowBuf[nBufPos]++;\r
548 }\r
549 nBufPos += 2;\r
550 }\r
551 else {\r
552 lpRowBuf[nBufPos] = 1;\r
553 lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+x];\r
554 x++;\r
555 for (; lpImageData[i+x] != lpImageData[i+x+1] && x < lpFrameHeader->Left + lpFrameHeader->Width - 1; x++) {\r
556 lpRowBuf[nBufPos]++;\r
557 lpRowBuf[nBufPos+lpRowBuf[nBufPos]] = (BYTE)lpImageData[i+x];\r
558 }\r
559 x--;\r
560 nBufPos += 1 + lpRowBuf[nBufPos];\r
561 }\r
562 }\r
563 }\r
564 else if (lpFrameHeader->Width == 1){\r
565 if (lpImageData[i] < 0) {\r
566 lpRowBuf[nBufPos] = 0x81;\r
567 nBufPos++;\r
568 }\r
569 else {\r
570 lpRowBuf[nBufPos] = 1;\r
571 lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+1];\r
572 nBufPos += 2;\r
573 }\r
574 }\r
575\r
576 if (y == 0) {\r
577 lpFrameData->lpRowOffsets[y] = lpFrameHeader->Height * sizeof(WORD);\r
578 }\r
579 else {\r
580 lpFrameData->lpRowOffsets[y] = lpFrameData->lpRowOffsets[y-1] + lpFrameData->lpRowSizes[y-1];\r
581 }\r
582\r
583 lpFrameData->lpRowSizes[y] = nBufPos;\r
584 lpFrameData->lpRowData[y] = (LPBYTE)malloc(nBufPos);\r
585 memcpy(lpFrameData->lpRowData[y], lpRowBuf, nBufPos);\r
586 }\r
587\r
588 free(lpRowBuf);\r
589}\r