From: ShadowFlare Date: Sat, 9 Sep 2006 08:40:54 +0000 (+0000) Subject: Encoding is now error-free and more extensive on usage of space-saving strategies. X-Git-Url: https://sfsrealm.hopto.org/projects/gitweb.cgi?p=grpapi.git;a=commitdiff_plain;h=0df810495ce1e922f22278469a15014e9b5de5aa Encoding is now error-free and more extensive on usage of space-saving strategies. --- diff --git a/drawgrp/drawgrp.cpp b/drawgrp/drawgrp.cpp index 9b5e286..f446793 100644 --- a/drawgrp/drawgrp.cpp +++ b/drawgrp/drawgrp.cpp @@ -3,6 +3,7 @@ #define _CRT_RAND_S #include +#include #include "stdafx.h" @@ -99,28 +100,35 @@ int main(int argc, char* argv[]) } hGrp2 = hGrp; hGrp = CreateGrp(BI.pBuffer, GrpInfo.nFrames, GrpInfo.wMaxWidth, GrpInfo.wMaxHeight, &nGrpSize); + /*HANDLE hFile; + hFile = CreateFile("generated ultralisk.grp", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); + if (hFile != INVALID_HANDLE_VALUE) { + WriteFile(hFile, hGrp, nGrpSize, &j, 0); + CloseHandle(hFile); + }*/ BI.nFrame = 0xFFFF; - for (i=13;i<14;i+=17) { - rect.left = rect.top = i; + j=0; + for (i=0;i 0) { - y--; - lpFrameHeaders[i].Offset = lpFrameHeaders[i-1].Offset + lpFrameData[i-1].lpRowOffsets[y] + lpFrameData[i-1].lpRowSizes[y]; - } - else { - lpFrameHeaders[i].Offset = lpFrameHeaders[i-1].Offset; - } + lpFrameHeaders[i].Offset = nLastOffset; } - if (i == nFrames) continue; // Scan frame to find dimensions of used part x1 = y1 = 0x10000; @@ -489,37 +496,53 @@ HANDLE GRPAPI WINAPI CreateGrp(signed short *lpImageData, WORD nFrames, WORD wMa lpFrameHeaders[i].Height = y2 - y1 + 1; 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]; + } + else { + nLastOffset = lpFrameHeaders[i].Offset; + } } - lpGrpData = (LPBYTE)malloc(lpFrameHeaders[nFrames].Offset); + lpGrpData = (LPBYTE)malloc(nLastOffset); // Write completed GRP to buffer memcpy(lpGrpData, &GrpHeader, sizeof(GRPHEADER)); memcpy(lpGrpData + sizeof(GRPHEADER), lpFrameHeaders, nFrames * sizeof(FRAMEHEADER)); for (i = 0; i < nFrames; i++) { - memcpy(lpGrpData + lpFrameHeaders[i].Offset, lpFrameData[i].lpRowOffsets, lpFrameHeaders[i].Height * sizeof(WORD)); + if (lpFrameHeaders[i].Offset) { + memcpy(lpGrpData + lpFrameHeaders[i].Offset, lpFrameData[i].lpRowOffsets, lpFrameHeaders[i].Height * sizeof(WORD)); - 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]); - } + 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; + } + } } - *nGrpSize = lpFrameHeaders[nFrames].Offset; free(lpFrameHeaders); free(lpFrameData); + *nGrpSize = nLastOffset; return (HANDLE)lpGrpData; } void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHeader, FRAMEHEADER *lpFrameHeader, FRAMEDATA *lpFrameData) { - int x, y, i, nBufPos; + int x, y, i, nBufPos, nRepeat; LPBYTE lpRowBuf; lpFrameData->lpRowOffsets = (WORD *)malloc(lpFrameHeader->Height * sizeof(WORD)); @@ -530,48 +553,65 @@ void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHea for (y = 0; y < lpFrameHeader->Height; y++) { i = nFrame * lpGrpHeader->wMaxWidth * lpGrpHeader->wMaxHeight + (lpFrameHeader->Top + y) * lpGrpHeader->wMaxWidth; nBufPos = 0; - if (lpFrameHeader->Width > 1) { - for (x = lpFrameHeader->Left; x < lpFrameHeader->Left + lpFrameHeader->Width - 1; x++) { - if (lpImageData[i+x] < 0) { - lpRowBuf[nBufPos] = 0x80; - for (; lpImageData[i+x] < 0 && x < lpFrameHeader->Left + lpFrameHeader->Width; x++) { - lpRowBuf[nBufPos]++; + if (lpFrameHeader->Width > 0) { + for (x = lpFrameHeader->Left; x < lpFrameHeader->Left + lpFrameHeader->Width; x++) { + if (x < lpFrameHeader->Left + lpFrameHeader->Width - 1) { + if (lpImageData[i+x] < 0) { + lpRowBuf[nBufPos] = 0x80; + for (; lpImageData[i+x] < 0 && x < lpFrameHeader->Left + lpFrameHeader->Width && lpRowBuf[nBufPos] < 0xFF; x++) { + lpRowBuf[nBufPos]++; + } + x--; + nBufPos++; + continue; } - x--; - nBufPos++; - } - else if (lpImageData[i+x] == lpImageData[i+x+1]) { - lpRowBuf[nBufPos] = 0x41; - lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+x]; - for (; lpImageData[i+x] == lpImageData[i+x+1] && x < lpFrameHeader->Left + lpFrameHeader->Width - 1; x++) { - lpRowBuf[nBufPos]++; + + // Count repeating pixels, nRepeat = number of pixels - 1, ignore if there are less than 4 duplicates + for (nRepeat = 0; lpImageData[i+x+nRepeat] == lpImageData[i+x+nRepeat+1] && x+nRepeat < lpFrameHeader->Left + lpFrameHeader->Width - 1 && nRepeat < 0x3F; nRepeat++) {} + + if (nRepeat > 2) { + lpRowBuf[nBufPos] = 0x41 + nRepeat; + lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+x]; + x += nRepeat; + nBufPos += 2; + } + else { + lpRowBuf[nBufPos] = 0; + for (; lpImageData[i+x] >= 0 && x < lpFrameHeader->Left + lpFrameHeader->Width && lpRowBuf[nBufPos] < 0x3F; x++) { + // Count repeating pixels, ignore if there are less than 4 duplicates + for (nRepeat = 0; lpImageData[i+x+nRepeat] == lpImageData[i+x+nRepeat+1] && x+nRepeat < lpFrameHeader->Left + lpFrameHeader->Width - 1 && nRepeat < 3; nRepeat++) {} + if (nRepeat > 2) break; + + lpRowBuf[nBufPos]++; + lpRowBuf[nBufPos+lpRowBuf[nBufPos]] = (BYTE)lpImageData[i+x]; + } + if (lpImageData[i+x] >= 0 && x == lpFrameHeader->Left + lpFrameHeader->Width - 1 && lpRowBuf[nBufPos] < 0x3F) { + lpRowBuf[nBufPos]++; + lpRowBuf[nBufPos+lpRowBuf[nBufPos]] = (BYTE)lpImageData[i+x]; + } + x--; + nBufPos += 1 + lpRowBuf[nBufPos]; } - nBufPos += 2; } else { - lpRowBuf[nBufPos] = 1; - lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+x]; - x++; - for (; lpImageData[i+x] != lpImageData[i+x+1] && x < lpFrameHeader->Left + lpFrameHeader->Width - 1; x++) { - lpRowBuf[nBufPos]++; - lpRowBuf[nBufPos+lpRowBuf[nBufPos]] = (BYTE)lpImageData[i+x]; + if (lpImageData[i+x] < 0) { + lpRowBuf[nBufPos] = 0x81; + nBufPos++; + } + else { + lpRowBuf[nBufPos] = 1; + lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+x]; + nBufPos += 2; } - x--; - nBufPos += 1 + lpRowBuf[nBufPos]; } } } - else if (lpFrameHeader->Width == 1){ - if (lpImageData[i] < 0) { - lpRowBuf[nBufPos] = 0x81; - nBufPos++; - } - else { - lpRowBuf[nBufPos] = 1; - lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+1]; - nBufPos += 2; - } + +#ifdef _DEBUG + if (!VerifyRow(&lpImageData[i+lpFrameHeader->Left], lpFrameHeader->Width, lpRowBuf, nBufPos)) { + nBufPos = nBufPos; } +#endif if (y == 0) { lpFrameData->lpRowOffsets[y] = lpFrameHeader->Height * sizeof(WORD); @@ -587,3 +627,39 @@ void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHea free(lpRowBuf); } + +#ifdef _DEBUG +BOOL VerifyRow(signed short *lpRawRow, int nWidth, LPBYTE lpEncRow, int nSize) +{ + int i,x=0,ofs=0; + while (x < nWidth && ofs < nSize) { + if (!(lpEncRow[ofs] & 0x80)) { + if (!(lpEncRow[ofs] & 0x40)) { + for (i=1;i<=lpEncRow[ofs] && x= 0) return FALSE; + } + x+=lpEncRow[ofs]-128; + ofs++; + } + } + + if (x != nWidth || ofs != nSize) return FALSE; + + return TRUE; +} +#endif