X-Git-Url: https://sfsrealm.hopto.org/projects/?a=blobdiff_plain;f=grpapi%2Fgrpapi.cpp;h=6c96c561290fac94dfba899aa2deb14a2561daef;hb=b54e4e4936096a8e3b1b25b435ac9aaac7c3660d;hp=fcb1c27632d76a82e7fd40d760f2ae03574f21b0;hpb=58a8b78cdc107c2e6136f562e9453723c7322949;p=grpapi.git diff --git a/grpapi/grpapi.cpp b/grpapi/grpapi.cpp index fcb1c27..6c96c56 100644 --- a/grpapi/grpapi.cpp +++ b/grpapi/grpapi.cpp @@ -79,6 +79,23 @@ void GRPAPI WINAPI FreeGrpApi() { } +/* +HANDLE hProcessHeap = NULL; + +void * SFAlloc(size_t nSize) +{ + if (!hProcessHeap) hProcessHeap = GetProcessHeap(); + if (hProcessHeap) return HeapAlloc(hProcessHeap, 0, nSize); + else return NULL; +} + +void SFFree(void *lpMem) +{ + if (!hProcessHeap) hProcessHeap = GetProcessHeap(); + if (hProcessHeap) HeapFree(hProcessHeap, 0, lpMem); +} +*/ + BOOL GRPAPI WINAPI SetMpqDll(LPCSTR lpDllFileName) { if (LoadStorm((char *)lpDllFileName)) return TRUE; @@ -439,7 +456,7 @@ void __inline SetPix(HDC hDC, int X, int Y, COLORREF clrColor, DWORD *dwPalette, MySetPixel(hDC,X,Y,clrColor); } -HANDLE GRPAPI WINAPI CreateGrp(signed short *lpImageData, WORD nFrames, WORD wMaxWidth, WORD wMaxHeight, DWORD *nGrpSize) +HANDLE GRPAPI WINAPI CreateGrp(signed short *lpImageData, WORD nFrames, WORD wMaxWidth, WORD wMaxHeight, BOOL bNoCompress, DWORD *nGrpSize) { GRPHEADER GrpHeader; FRAMEHEADER *lpFrameHeaders; @@ -455,6 +472,7 @@ HANDLE GRPAPI WINAPI CreateGrp(signed short *lpImageData, WORD nFrames, WORD wMa GrpHeader.wMaxHeight = wMaxHeight; lpFrameHeaders = (FRAMEHEADER *)malloc(nFrames * sizeof(FRAMEHEADER)); lpFrameData = (FRAMEDATA *)malloc(nFrames * sizeof(FRAMEDATA)); + nLastOffset = sizeof(GRPHEADER) + nFrames * sizeof(FRAMEHEADER); for (i = 0; i < nFrames; i++) { // Search for duplicate frames @@ -467,6 +485,7 @@ HANDLE GRPAPI WINAPI CreateGrp(signed short *lpImageData, WORD nFrames, WORD wMa if (j < i) { memcpy(&lpFrameHeaders[i], &lpFrameHeaders[j], sizeof(FRAMEHEADER)); + lpFrameData[i].lpRowOffsets = 0; continue; } @@ -490,20 +509,31 @@ HANDLE GRPAPI WINAPI CreateGrp(signed short *lpImageData, WORD nFrames, WORD wMa } } } + x2 = x2 - x1 + 1; + y2 = y2 - y1 + 1; + if ((WORD)x1 > 255) x1 = 255; + if ((WORD)y1 > 255) y1 = 255; + if ((WORD)x2 > 255) x2 = 255; + if ((WORD)y2 > 255) y2 = 255; lpFrameHeaders[i].Left = x1; lpFrameHeaders[i].Top = y1; - lpFrameHeaders[i].Width = x2 - x1 + 1; - lpFrameHeaders[i].Height = y2 - y1 + 1; + lpFrameHeaders[i].Width = x2; + lpFrameHeaders[i].Height = y2; - EncodeFrameData(lpImageData, i, &GrpHeader, &lpFrameHeaders[i], &lpFrameData[i]); + if (!bNoCompress) { + EncodeFrameData(lpImageData, i, &GrpHeader, &lpFrameHeaders[i], &lpFrameData[i]); - y = lpFrameHeaders[i].Height; - if (y > 0) { - y--; - nLastOffset = lpFrameHeaders[i].Offset + lpFrameData[i].lpRowOffsets[y] + lpFrameData[i].lpRowSizes[y]; + y = lpFrameHeaders[i].Height; + if (y > 0) { + y--; + nLastOffset = lpFrameHeaders[i].Offset + lpFrameData[i].lpRowOffsets[y] + lpFrameData[i].lpRowSizes[y]; + } + else { + nLastOffset = lpFrameHeaders[i].Offset; + } } else { - nLastOffset = lpFrameHeaders[i].Offset; + nLastOffset = lpFrameHeaders[i].Offset + lpFrameHeaders[i].Width * lpFrameHeaders[i].Height; } } @@ -514,21 +544,28 @@ HANDLE GRPAPI WINAPI CreateGrp(signed short *lpImageData, WORD nFrames, WORD wMa memcpy(lpGrpData + sizeof(GRPHEADER), lpFrameHeaders, nFrames * sizeof(FRAMEHEADER)); for (i = 0; i < nFrames; i++) { - if (lpFrameHeaders[i].Offset) { - memcpy(lpGrpData + lpFrameHeaders[i].Offset, lpFrameData[i].lpRowOffsets, lpFrameHeaders[i].Height * sizeof(WORD)); + if (lpFrameData[i].lpRowOffsets) { + if (!bNoCompress) { + memcpy(lpGrpData + lpFrameHeaders[i].Offset, lpFrameData[i].lpRowOffsets, lpFrameHeaders[i].Height * sizeof(WORD)); + + for (y = 0; y < lpFrameHeaders[i].Height; y++) { + if (lpFrameData[i].lpRowData[y]) { + memcpy(lpGrpData + lpFrameHeaders[i].Offset + lpFrameData[i].lpRowOffsets[y], lpFrameData[i].lpRowData[y], lpFrameData[i].lpRowSizes[y]); + free(lpFrameData[i].lpRowData[y]); + } + } - for (y = 0; y < lpFrameHeaders[i].Height; y++) { - memcpy(lpGrpData + lpFrameHeaders[i].Offset + lpFrameData[i].lpRowOffsets[y], lpFrameData[i].lpRowData[y], lpFrameData[i].lpRowSizes[y]); - free(lpFrameData[i].lpRowData[y]); + free(lpFrameData[i].lpRowOffsets); + free(lpFrameData[i].lpRowSizes); + free(lpFrameData[i].lpRowData); } - - free(lpFrameData[i].lpRowOffsets); - free(lpFrameData[i].lpRowSizes); - free(lpFrameData[i].lpRowData); - - for (j = i + 1; j < nFrames; j++) { - if (lpFrameHeaders[i].Offset == lpFrameHeaders[j].Offset) - lpFrameHeaders[j].Offset = 0; + else { + for (y = 0; y < lpFrameHeaders[i].Height; y++) { + for (x = 0; x < lpFrameHeaders[i].Width; x++) { + lpGrpData[lpFrameHeaders[i].Offset + y * lpFrameHeaders[i].Width + x] = + (BYTE)lpImageData[i * wMaxWidth * wMaxHeight + (lpFrameHeaders[i].Top + y) * wMaxWidth + lpFrameHeaders[i].Left + x]; + } + } } } } @@ -544,14 +581,42 @@ void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHea { int x, y, i, nBufPos, nRepeat; LPBYTE lpRowBuf; + WORD nLastOffset; lpFrameData->lpRowOffsets = (WORD *)malloc(lpFrameHeader->Height * sizeof(WORD)); lpFrameData->lpRowSizes = (WORD *)malloc(lpFrameHeader->Height * sizeof(WORD)); lpFrameData->lpRowData = (LPBYTE *)malloc(lpFrameHeader->Height * sizeof(LPBYTE)); lpRowBuf = (LPBYTE)malloc(lpFrameHeader->Width * 2); + nLastOffset = lpFrameHeader->Height * sizeof(WORD); for (y = 0; y < lpFrameHeader->Height; y++) { i = nFrame * lpGrpHeader->wMaxWidth * lpGrpHeader->wMaxHeight + (lpFrameHeader->Top + y) * lpGrpHeader->wMaxWidth; + + /* Fails verification when using this. Bug in encoder or decoder? Doesn't provide much benefit. + // Search for duplicate rows (experimental) + for (x = 0; x < y; x++) { + j = nFrame * lpGrpHeader->wMaxWidth * lpGrpHeader->wMaxHeight + (lpFrameHeader->Top + x) * lpGrpHeader->wMaxWidth; + if (memcmp(&lpImageData[i+lpFrameHeader->Left], + &lpImageData[j+lpFrameHeader->Left], + lpGrpHeader->wMaxWidth * sizeof(short)) == 0) + break; + } + + if (x < y) { + lpFrameData->lpRowOffsets[y] = lpFrameData->lpRowOffsets[x]; + lpFrameData->lpRowSizes[y] = 0; + lpFrameData->lpRowData[y] = 0; + +#ifdef _DEBUG + if (!VerifyRow(&lpImageData[i+lpFrameHeader->Left], lpFrameHeader->Width, lpFrameData->lpRowData[x], lpFrameData->lpRowSizes[x])) { + nBufPos = nBufPos; + } +#endif + + continue; + } + */ + nBufPos = 0; if (lpFrameHeader->Width > 0) { for (x = lpFrameHeader->Left; x < lpFrameHeader->Left + lpFrameHeader->Width; x++) { @@ -562,7 +627,8 @@ void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHea lpRowBuf[nBufPos]++; } x--; - nBufPos++; + if (nLastOffset + nBufPos + 1 <= 0xFFFF) + nBufPos++; continue; } @@ -573,7 +639,8 @@ void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHea lpRowBuf[nBufPos] = 0x41 + nRepeat; lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+x]; x += nRepeat; - nBufPos += 2; + if (nLastOffset + nBufPos + 2 <= 0xFFFF) + nBufPos += 2; } else { lpRowBuf[nBufPos] = 0; @@ -590,18 +657,21 @@ void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHea lpRowBuf[nBufPos+lpRowBuf[nBufPos]] = (BYTE)lpImageData[i+x]; } x--; - nBufPos += 1 + lpRowBuf[nBufPos]; + if (nLastOffset + nBufPos + 1 + lpRowBuf[nBufPos] <= 0xFFFF) + nBufPos += 1 + lpRowBuf[nBufPos]; } } else { if (lpImageData[i+x] < 0) { lpRowBuf[nBufPos] = 0x81; - nBufPos++; + if (nLastOffset + nBufPos + 1 <= 0xFFFF) + nBufPos++; } else { lpRowBuf[nBufPos] = 1; lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+x]; - nBufPos += 2; + if (nLastOffset + nBufPos + 2 <= 0xFFFF) + nBufPos += 2; } } } @@ -617,9 +687,11 @@ void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHea lpFrameData->lpRowOffsets[y] = lpFrameHeader->Height * sizeof(WORD); } else { - lpFrameData->lpRowOffsets[y] = lpFrameData->lpRowOffsets[y-1] + lpFrameData->lpRowSizes[y-1]; + lpFrameData->lpRowOffsets[y] = nLastOffset; } + nLastOffset = lpFrameData->lpRowOffsets[y] + nBufPos; + lpFrameData->lpRowSizes[y] = nBufPos; lpFrameData->lpRowData[y] = (LPBYTE)malloc(nBufPos); memcpy(lpFrameData->lpRowData[y], lpRowBuf, nBufPos);