12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012 |
- #include <malloc.h>
- #include <memory.h>
- #include <SMRTHEAP.HPP>
- #include "common/system.H"
- #include "flx/FLX.H"
- void CFlx::Restart(void)
- {
-
- m_file.Seek(m_filehdr.lOffsetFrame1, SEEK_SET);
-
-
- m_sFrameNum = 0;
- }
-
-
- short CFlx::DoReadFrame(FLX_BUF* pbufRead)
- {
- short sError = 0;
-
-
- pbufRead->bPixelsModified = FALSE;
- pbufRead->bColorsModified = FALSE;
-
-
-
-
-
-
- long lFramePos = m_file.Tell();
-
-
- FLX_FRAME_HDR framehdr;
- m_file.Read(&framehdr.lChunkSize);
- m_file.Read(&framehdr.wType);
- m_file.Read(&framehdr.sNumSubChunks);
- m_file.Read(framehdr.bReserved, 8);
-
-
- if (m_file.Error() == FALSE && framehdr.wType == 0xF1FA)
- {
-
-
-
-
- FLX_DATA_HDR datahdr;
- for (short sSub = 0; sSub < framehdr.sNumSubChunks && sError == 0; sSub++)
- {
-
-
-
-
-
- long lDataPos = m_file.Tell();
-
-
- m_file.Read(&datahdr.lChunkSize);
- m_file.Read(&datahdr.wType);
- if (m_file.Error() == FALSE)
- {
-
- long lDataSize = datahdr.lChunkSize - 6;
-
-
- switch(datahdr.wType)
- {
- case FLX_DATA_COLOR256:
-
- if (pbufRead->prgbColors != NULL)
- sError = ReadDataColor(pbufRead, FLX_DATA_COLOR256);
- break;
-
- case FLX_DATA_SS2:
-
- if (pbufRead->pbPixels != NULL)
- sError = ReadDataSS2(pbufRead);
- break;
-
- case FLX_DATA_COLOR:
-
- if (pbufRead->prgbColors != NULL)
- sError = ReadDataColor(pbufRead, FLX_DATA_COLOR);
- break;
-
- case FLX_DATA_LC:
-
- if (pbufRead->pbPixels != NULL)
- sError = ReadDataLC(pbufRead);
- break;
-
- case FLX_DATA_BLACK:
-
- if (pbufRead->pbPixels != NULL)
- sError = ReadDataBlack(pbufRead);
- break;
-
- case FLX_DATA_BRUN:
-
- if (pbufRead->pbPixels != NULL)
- sError = ReadDataBRun(pbufRead);
- break;
-
- case FLX_DATA_COPY:
-
- if (pbufRead->pbPixels != NULL)
- sError = ReadDataCopy(pbufRead);
- break;
-
- case FLX_DATA_PSTAMP:
-
-
- break;
-
- default:
-
-
-
- sError = 1;
- break;
- }
-
-
- m_file.Seek(lDataPos + datahdr.lChunkSize, SEEK_SET);
- }
- else
- sError = 1;
- }
-
-
- m_file.Seek(lFramePos + framehdr.lChunkSize, SEEK_SET);
- }
- else
- sError = 1;
-
-
- if (sError == 0)
- {
-
-
- if (++m_sFrameNum == (m_filehdr.sNumFrames + 1))
- {
-
- m_sFrameNum = 1;
-
-
- m_file.Seek(m_filehdr.lOffsetFrame2, SEEK_SET);
- }
- }
-
- return sError;
- }
-
-
- short CFlx::ReadDataColor(FLX_BUF* pbufRead, short sDataType)
- {
-
-
- if (pbufRead->prgbColors == NULL)
- return 1;
- short sError = 0;
-
-
- short sNumPackets;
- m_file.Read(&sNumPackets);
-
- short sColorIndex = 0;
- short sCnt;
- short sColorDo;
- UCHAR bColorSkip;
- UCHAR bVal;
-
- for (short sPack = 0; (sPack < sNumPackets) && (sError == 0); sPack++)
- {
-
- m_file.Read(&bColorSkip);
- sColorIndex = sColorIndex + (short)bColorSkip;
-
-
-
-
- m_file.Read(&bVal);
- if (bVal != 0)
- sColorDo = (short)bVal;
- else
- sColorDo = (short)256;
-
-
- if ((sColorIndex + sColorDo) <= 256)
- {
-
-
- m_file.Read(&(pbufRead->prgbColors[sColorIndex]), 3 * sColorDo);
- if (sDataType == FLX_DATA_COLOR256)
- {
- sColorIndex = sColorIndex + sColorDo;
- }
- else
- {
-
-
- for (sCnt = 0; sCnt < sColorDo; sCnt++)
- {
- pbufRead->prgbColors[sColorIndex].bR <<= 2;
- pbufRead->prgbColors[sColorIndex].bG <<= 2;
- pbufRead->prgbColors[sColorIndex].bB <<= 2;
- sColorIndex++;
- }
- }
- }
- else
- sError = 1;
- }
-
- pbufRead->bColorsModified = TRUE;
-
- if (m_file.Error() != FALSE)
- sError = 1;
-
- return sError;
- }
-
-
- short CFlx::ReadDataBlack(FLX_BUF* pbufRead)
- {
-
-
-
- if ((pbufRead->pbPixels == NULL) || (pbufRead->sPitch <= 0))
- return 1;
-
-
- UCHAR* pbMem = pbufRead->pbPixels;
- for (short y = 0; y < m_filehdr.sHeight; y++)
- {
- memset(pbMem, 0, m_filehdr.sWidth);
- pbMem += (ULONG)pbufRead->sPitch;
- }
-
-
- pbufRead->bPixelsModified = TRUE;
-
- return 0;
- }
-
-
- short CFlx::ReadDataCopy(FLX_BUF* pbufRead)
- {
-
-
-
- if ((pbufRead->pbPixels == NULL) || (pbufRead->sPitch <= 0))
- return 1;
- short sError = 0;
-
-
-
- UCHAR* pbMem = pbufRead->pbPixels;
- for (short y = 0; y < m_filehdr.sHeight; y++)
- {
- m_file.Read(pbMem, m_filehdr.sWidth);
- pbMem += (ULONG)pbufRead->sPitch;
- }
-
- pbufRead->bPixelsModified = TRUE;
-
- if (m_file.Error() != FALSE)
- sError = 1;
-
- return sError;
- }
-
-
- short CFlx::ReadDataBRun(FLX_BUF* pbufRead)
- {
-
-
-
- if ((pbufRead->pbPixels == NULL) || (pbufRead->sPitch <= 0))
- return 1;
-
- short sError = 0;
- UCHAR bVal;
- S8 cVal;
- short sCount;
- short x;
- short y;
- UCHAR* pbRow;
- UCHAR* pbPix;
-
-
-
- pbRow = pbufRead->pbPixels;
- for (y = 0; (y < m_filehdr.sHeight) && (sError == 0); y++)
- {
-
-
- m_file.Read(&cVal);
-
-
- pbPix = pbRow;
- x = 0;
- while ((x < m_filehdr.sWidth) && (sError == 0))
- {
-
-
-
- m_file.Read(&cVal);
-
- if (cVal != 0)
- {
- sCount = (short)cVal;
- if (sCount < 0)
- {
- sCount = -sCount;
- x += sCount;
- m_file.Read(pbPix, sCount);
- pbPix += (ULONG)sCount;
- }
- else
- {
- x += sCount;
- m_file.Read(&bVal);
- memset(pbPix, (int)bVal, (size_t)sCount);
- pbPix += (ULONG)sCount;
- }
- }
- else
- {
- sError = 1;
- }
- }
-
- pbRow += (ULONG)pbufRead->sPitch;
- }
-
-
- if (sError == 1)
- return sError;
-
-
- pbufRead->bPixelsModified = TRUE;
- if (m_file.Error() == FALSE)
- return 0;
- else
- return 1;
- }
-
-
- short CFlx::ReadDataLC(FLX_BUF* pbufRead)
- {
-
-
-
- if ((pbufRead->pbPixels == NULL) || (pbufRead->sPitch <= 0))
- return 1;
- UCHAR bVal;
- S8 cVal;
- short sCount;
- short y;
- short lines;
- short packets;
- UCHAR* pbRow;
- UCHAR* pbPix;
-
-
- m_file.Read(&y);
-
- pbRow = pbufRead->pbPixels + ((ULONG)y * (ULONG)pbufRead->sPitch);
-
- m_file.Read(&lines);
-
-
-
-
- if (lines < 1)
- {
-
- pbufRead->bPixelsModified = FALSE;
- }
- else
- {
-
- pbufRead->bPixelsModified = TRUE;
- }
-
-
- if (m_file.Error() == FALSE)
- {
- while (lines > 0)
- {
-
- pbPix = pbRow;
-
- #if 0
- long lPos = m_file.Tell();
- static UCHAR bData[100];
- m_file.Read(bData, sizeof(bData));
- m_file.Seek(lPos, SEEK_SET);
- #endif
-
-
- m_file.Read(&bVal);
- packets = (short)bVal;
-
- while (packets > 0)
- {
-
-
- m_file.Read(&bVal);
- pbPix = pbPix + (ULONG)bVal;
-
-
-
-
- m_file.Read(&cVal);
- if (cVal == 0)
- cVal = 0;
-
- sCount = (short)cVal;
- if (sCount > 0)
- {
- m_file.Read(pbPix, sCount);
- pbPix += (ULONG)sCount;
- }
- else
- {
- sCount = -sCount;
- m_file.Read(&bVal);
- memset(pbPix, (int)bVal, (size_t)sCount);
- pbPix += (ULONG)sCount;
- }
-
-
- packets--;
- }
-
- pbRow += (ULONG)pbufRead->sPitch;
-
-
- lines--;
- }
- }
- if (m_file.Error() == FALSE)
- return 0;
- else
- return 1;
- }
-
-
- short CFlx::ReadDataSS2(FLX_BUF* pbufRead)
- {
-
-
-
- if ((pbufRead->pbPixels == NULL) || (pbufRead->sPitch <= 0))
- return 1;
-
- UCHAR bVal;
- S8 cVal;
- USHORT wVal;
- short sCount;
- short y;
- short lines;
- short packets;
- UCHAR* pbPix;
- UCHAR byLastByte;
- short bLastByte = FALSE;
-
-
-
- m_file.Read(&lines);
-
-
-
- if (lines < 1)
- {
-
- pbufRead->bPixelsModified = FALSE;
- }
- else
- {
-
- pbufRead->bPixelsModified = TRUE;
- }
-
-
- if (m_file.Error() == FALSE)
- {
-
- y = 0;
-
- while (lines > 0)
- {
- #if 0
- long lPos = m_file.Tell();
- static UCHAR bData[100];
- m_file.Read(bData, sizeof(bData));
- m_file.Seek(lPos, SEEK_SET);
- #endif
-
-
-
- do
- {
- m_file.Read(&wVal);
-
-
-
- switch (wVal & 0xC000)
- {
-
-
-
- case 0x0000:
- break;
-
-
-
-
- case 0x8000:
-
-
-
- if (bLastByte == TRUE)
- return 1;
-
- byLastByte = (UCHAR)(wVal & (USHORT)0x00ff);
- bLastByte = TRUE;
-
- m_file.Read(&wVal);
- break;
-
-
-
-
- case 0xC000:
-
- y += -((short)wVal);
- break;
- }
- } while ((wVal & 0xC000) == 0xC000);
-
- packets = (short)wVal;
-
-
- pbPix = pbufRead->pbPixels + ((ULONG)y * (ULONG)pbufRead->sPitch);
-
- while (packets > 0)
- {
-
-
- m_file.Read(&bVal);
- pbPix = pbPix + (ULONG)bVal;
-
-
-
-
- m_file.Read(&cVal);
- #if 0
- if (cVal == 0)
- cVal = 0;
- #endif
-
- sCount = (short)cVal;
- if (sCount > 0)
- {
- sCount *= sizeof(USHORT);
- m_file.Read(pbPix, sCount);
- pbPix += (ULONG)(sCount);
- }
- else
- {
- sCount = (short)-sCount;
- m_file.Read(&wVal);
- USHORT* pwPix = (USHORT*)pbPix;
- for (short i = 0; i < sCount; i++)
- *pwPix++ = wVal;
- pbPix = (UCHAR*)pwPix;
- }
-
-
- packets--;
- }
-
-
- if (bLastByte == TRUE)
- {
-
- pbPix = pbufRead->pbPixels + (((ULONG)y + 1L) * (ULONG)pbufRead->sPitch) - 1L;
-
- *pbPix = byLastByte;
- bLastByte = FALSE;
- }
-
- lines--;
-
-
- y++;
- }
- }
- if (m_file.Error() == FALSE)
- return 0;
- else
- return 1;
- }
-
-
- short CFlx::DoWriteFrame(FLX_BUF* pbufWrite, FLX_BUF* pbufPrev)
- {
- long lDataChunkSize;
- short sError = 0;
-
- m_sFrameNum++;
-
-
-
- long lFramePos = m_file.Tell();
-
-
- FLX_FRAME_HDR framehdr;
- framehdr.lChunkSize = 16L;
- framehdr.wType = 0xF1FA;
- framehdr.sNumSubChunks = 0;
- memset(framehdr.bReserved, 0, 8);
-
-
- m_file.Write(&framehdr.lChunkSize);
- m_file.Write(&framehdr.wType);
- m_file.Write(&framehdr.sNumSubChunks);
- m_file.Write(framehdr.bReserved, 8);
-
-
-
-
- UCHAR* pBuf = (UCHAR*)malloc((USHORT)m_filehdr.sWidth * (USHORT)m_filehdr.sHeight);
- if (pBuf != NULL)
- {
-
-
-
- sError = WriteColorDelta(pbufWrite, pbufPrev, pBuf, &lDataChunkSize);
- if ((sError == 0) && (lDataChunkSize > 0))
- {
-
- framehdr.lChunkSize += lDataChunkSize;
- framehdr.sNumSubChunks++;
- }
-
-
- sError = WritePixelDelta(pbufWrite, pbufPrev, pBuf, &lDataChunkSize);
- if ((sError == 0) && (lDataChunkSize > 0))
- {
-
- framehdr.lChunkSize += lDataChunkSize;
- framehdr.sNumSubChunks++;
- }
-
-
-
- m_file.Seek(lFramePos, SEEK_SET);
- m_file.Write(&framehdr.lChunkSize);
- m_file.Write(&framehdr.wType);
- m_file.Write(&framehdr.sNumSubChunks);
- m_file.Write(framehdr.bReserved, sizeof(framehdr.bReserved));
- m_file.Seek(lFramePos + framehdr.lChunkSize, SEEK_SET);
-
-
-
- if (m_sFrameNum == 1)
- m_filehdr.lOffsetFrame2 = m_file.Tell();
-
-
-
-
-
- free(pBuf);
-
- }
- else
- sError = 1;
-
- return sError;
- }
-
-
- short CFlx::WriteColorDelta(FLX_BUF* pbufNext, FLX_BUF* pbufPrev, UCHAR* pBuf, long* plChunkSize)
- {
- short sError = 0;
-
- *plChunkSize = 0;
-
- USHORT wType;
- if (m_filehdr.wMagic == FLX_MAGIC_FLC)
- wType = FLX_DATA_COLOR256;
- else
- wType = FLX_DATA_COLOR;
-
-
- FLX_RGB* pNext = pbufNext->prgbColors;
- FLX_RGB* pPrev;
- if (pbufPrev != NULL)
- pPrev = pbufPrev->prgbColors;
-
- UCHAR* pOut = pBuf;
-
-
- USHORT* pwPackets = (USHORT*)pOut;
- pOut = pOut + 2;
- *pwPackets = 0;
-
-
- long lSize = 2;
-
-
-
-
- short sSame;
- short sChanged;
- short sIndex;
- short sStart = 0;
- while (sStart < 256)
- {
-
- if (pbufPrev != NULL)
- {
- for (sSame = 0; (sStart + sSame) < 256; sSame++)
- {
- if ((pNext[sStart + sSame].bR != pPrev[sStart + sSame].bR) ||
- (pNext[sStart + sSame].bG != pPrev[sStart + sSame].bG) ||
- (pNext[sStart + sSame].bB != pPrev[sStart + sSame].bB))
- break;
- }
- }
- else
- sSame = 0;
-
-
- sStart += sSame;
-
-
-
- if (pbufPrev != NULL)
- {
- for (sChanged = 0; (sStart + sChanged) < 256; sChanged++)
- {
- if ((pNext[sStart + sChanged].bR == pPrev[sStart + sChanged].bR) &&
- (pNext[sStart + sChanged].bG == pPrev[sStart + sChanged].bG) &&
- (pNext[sStart + sChanged].bB == pPrev[sStart + sChanged].bB))
- break;
- }
- }
- else
- sChanged = 256;
-
-
- if (sChanged > 0)
- {
-
- (*pwPackets)++;
-
-
-
- *pOut++ = (UCHAR)sSame;
- *pOut++ = (UCHAR)sChanged;
- lSize += 2;
-
-
- for (sIndex = 0; sIndex < sChanged; sIndex++)
- {
-
- if (wType == FLX_DATA_COLOR256)
- {
- *pOut++ = pNext[sStart + sIndex].bR;
- *pOut++ = pNext[sStart + sIndex].bG;
- *pOut++ = pNext[sStart + sIndex].bB;
- }
-
- else
- {
- *pOut++ = (UCHAR)(pNext[sStart + sIndex].bR >> 2) & (UCHAR)0x3f;
- *pOut++ = (UCHAR)(pNext[sStart + sIndex].bG >> 2) & (UCHAR)0x3f;
- *pOut++ = (UCHAR)(pNext[sStart + sIndex].bB >> 2) & (UCHAR)0x3f;
- }
- lSize += 3;
- }
- }
-
-
- sStart += sChanged;
- }
-
-
- if (*pwPackets > 0)
- {
-
- sError = WriteDataChunk(pBuf, lSize, wType, plChunkSize);
- }
- return sError;
- }
-
-
- short CFlx::WritePixelDelta(FLX_BUF* pbufNext, FLX_BUF* pbufPrev, UCHAR* pBuf, long* plChunkSize)
- {
- short sError = 0;
-
- *plChunkSize = 0;
- #if 0
-
- UCHAR* pbSrc = pbufNext->pbPixels;
- UCHAR* pbDst = pBuf;
- for (short y = 0; y < m_filehdr.sHeight; y++)
- {
- memcpy(pbDst, pbSrc, m_filehdr.sWidth);
- pbSrc += (ULONG)pbufNext->sPitch;
- pbDst += (ULONG)m_filehdr.sWidth;
- }
- long lSize = (long)m_filehdr.sWidth * (long)m_filehdr.sHeight;
-
- sError = WriteDataChunk(pBuf, lSize, FLX_DATA_COPY, plChunkSize);
- #endif
- #if 0
- long lSize = CompressBRUN(pbufNext->pbPixels, pbufNext->sPitch,
- 0, 0, m_filehdr.sWidth, m_filehdr.sHeight, pBuf);
-
-
- sError = WriteDataChunk(pBuf, lSize, FLX_DATA_BRUN, plChunkSize);
-
- return sError;
- #endif
-
- if (pbufNext == NULL)
- return 1;
-
- if (pbufPrev == NULL)
- {
-
-
- long lSizeBRUN = CompressBRUN(pbufNext->pbPixels, pbufNext->sPitch,
- 0, 0, m_filehdr.sWidth, m_filehdr.sHeight, pBuf);
- long lSizeCOPY = (long)m_filehdr.sWidth * (long)m_filehdr.sHeight;
-
- if (lSizeBRUN <= lSizeCOPY)
- {
-
-
- sError = WriteDataChunk(pBuf, lSizeBRUN, FLX_DATA_BRUN, plChunkSize);
- }
- else
- {
-
-
-
-
- UCHAR* pbSrc = pbufNext->pbPixels;
- UCHAR* pbDst = pBuf;
- for (short y = 0; y < m_filehdr.sHeight; y++)
- {
- memcpy(pbDst, pbSrc, m_filehdr.sWidth);
- pbSrc += (ULONG)pbufNext->sPitch;
- pbDst += (ULONG)m_filehdr.sWidth;
- }
-
-
- sError = WriteDataChunk(pBuf, lSizeCOPY, FLX_DATA_COPY, plChunkSize);
- }
- }
- else
- {
-
- if (m_filehdr.wMagic == FLX_MAGIC_FLI)
- {
-
- short y;
- long lSize;
- short sFirstYPos = m_filehdr.sHeight-1;
- short sLineCount = 0;
- UCHAR* pbDst = pBuf + 4;
-
- long lSizeLC = 4;
- short sEmptyLineCount = 0;
-
-
- for (y = 0; y < m_filehdr.sHeight; y++)
- {
-
- sError = CompressLineDelta(y, pbufNext, pbufPrev, pbDst, lSize, sizeof(UCHAR), sEmptyLineCount);
-
-
- if (sError == -1)
- return sError;
-
-
- if (sError != 0)
- {
-
-
- if (sLineCount != 0)
- {
-
-
- sEmptyLineCount++;
- }
- }
- else
- {
-
- if (sEmptyLineCount > 0)
- {
- sLineCount += sEmptyLineCount;
- sEmptyLineCount = 0;
- }
- if (sLineCount == 0)
- {
-
- sFirstYPos = y;
- sLineCount++;
- }
- else
- {
-
- sLineCount++;
- }
-
-
- pbDst += lSize;
- lSizeLC += lSize;
- }
- }
-
-
- *(USHORT*)pBuf = (USHORT)sFirstYPos;
- *(USHORT*)(pBuf + 2) = (USHORT)sLineCount;
-
-
- sError = WriteDataChunk(pBuf, lSizeLC, FLX_DATA_LC, plChunkSize);
- }
- else
- {
-
- short y;
- long lSize;
- UCHAR* pbDst = pBuf + 2;
- long lSizeSS2 = 2;
- short sLines = 0;
- short sLineSkipCount = 0;
-
-
- for (y = 0; y < m_filehdr.sHeight; y++)
- {
-
- sError = CompressLineDelta(y, pbufNext, pbufPrev, pbDst, lSize, sizeof(USHORT), sLineSkipCount);
-
-
- if (sError == -1)
- return sError;
-
-
- if (sError != 0)
- {
-
-
- sLineSkipCount++;
- }
- else
- {
-
- sLineSkipCount = 0;
- sLines++;
-
-
- pbDst += lSize;
- lSizeSS2 += lSize;
- }
- }
-
-
- *(short*)pBuf = sLines;
-
-
- sError = WriteDataChunk(pBuf, lSizeSS2, FLX_DATA_SS2, plChunkSize);
- }
- }
- return sError;
- }
- short CFlx::CompressLineDelta(short y,
- FLX_BUF* pbufNext,
- FLX_BUF* pbufPrev,
- UCHAR* pbDst,
- long& lSize,
- short sAlign,
- short sLineSkipCount)
- {
-
- ULONG dwOffset;
- UCHAR* pbSrcNext = pbufNext->pbPixels;
- UCHAR* pbSrcPrev = pbufPrev->pbPixels;
- short sPacket = 0;
- UCHAR* pbPacketCount;
- short x = 0;
- short sAdjustedPitch;
- short sSkipCount;
- UCHAR* pbByteCount;
- short sIndex;
-
-
- lSize = 0;
- sAdjustedPitch = pbufNext->sPitch;
-
-
- if ((pbufNext == NULL) || (pbufPrev == NULL) || (pbDst == NULL))
- return -1;
-
-
- dwOffset = (ULONG)y * (ULONG)pbufNext->sPitch;
- if (memcmp(pbSrcNext + dwOffset, pbSrcPrev + dwOffset, (size_t)pbufNext->sPitch) == 0)
- {
-
- return 1;
- }
-
-
-
-
- if ((sAlign == 1) && (sLineSkipCount != 0))
- {
-
- for (sIndex = 0; sIndex < sLineSkipCount; sIndex++)
- {
- *(pbDst + (ULONG)lSize++) = 0;
- }
- }
- else if (sAlign == 2)
- {
-
- if (sLineSkipCount > 0)
- {
-
- *(short*)(pbDst + (ULONG)lSize) = -sLineSkipCount;
- lSize += 2;
- }
-
-
- dwOffset = ((ULONG)y * (ULONG)pbufNext->sPitch) + (ULONG)(pbufNext->sPitch - 1);
- if (pbSrcNext[dwOffset] != pbSrcPrev[dwOffset])
- {
-
-
- USHORT wLastByte = (USHORT)pbSrcNext[dwOffset];
- wLastByte = wLastByte | 0x8000;
-
-
- *(USHORT*)(pbDst + (ULONG)lSize) = wLastByte;
- lSize += 2;
- }
-
-
- }
-
-
- pbPacketCount = pbDst + (ULONG)lSize;
- if (sAlign == 1)
- lSize++;
- else
- lSize += 2;
-
- sSkipCount = 0;
- x = 0;
- sPacket = 0;
- while (((sAlign == 1) && (x < sAdjustedPitch)) || ((sAlign == 2) && (x < sAdjustedPitch - 1)))
- {
-
- dwOffset = (ULONG)y * (ULONG)pbufNext->sPitch;
- while ((x < sAdjustedPitch) && (pbSrcNext[dwOffset + x] == pbSrcPrev[dwOffset + x]))
- {
-
- x++;
- sSkipCount++;
- }
-
-
- if (((sAlign == 1) && (x < sAdjustedPitch)) || ((sAlign == 2) && (x < sAdjustedPitch - 1)))
- {
-
-
- if (sAlign == 1)
- {
-
- dwOffset = (ULONG)y * (ULONG)pbufNext->sPitch + x - sSkipCount;
-
-
- while (sSkipCount > 255)
- {
-
- *(pbDst + (ULONG)lSize++) = 255;
- *(pbDst + (ULONG)lSize++) = 1;
-
-
- dwOffset += 255;
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset];
-
-
- sPacket++;
- sSkipCount -= 256;
- }
-
-
- *(pbDst + (ULONG)lSize++) = (UCHAR)sSkipCount;
- sSkipCount = 0;
-
-
- UCHAR nBytes = 1;
-
-
- dwOffset = (ULONG)y * (ULONG)pbufNext->sPitch;
- if ((x < (sAdjustedPitch - 1)) && (pbSrcNext[dwOffset + x] == pbSrcNext[dwOffset + x + 1]))
- {
-
- x++;
- while ((nBytes < 127) &&
- (x < sAdjustedPitch) &&
- (pbSrcNext[dwOffset + (x - 1)] == pbSrcNext[dwOffset + x]) &&
- (pbSrcNext[dwOffset + x] != pbSrcPrev[dwOffset + x]))
- {
- x++;
- nBytes++;
- }
-
-
-
- nBytes = 255 - nBytes + 1;
- *(pbDst + (ULONG)lSize++) = nBytes;
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset + (x - 1)];
- sPacket++;
- }
- else
- {
-
- pbByteCount = pbDst + (ULONG)lSize++;
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset + x];
- x++;
-
- while ((nBytes < 127) &&
- (x < sAdjustedPitch) &&
- (pbSrcNext[dwOffset + x] != pbSrcPrev[dwOffset + x]) &&
- !((x < (sAdjustedPitch - 1)) && (pbSrcNext[dwOffset + x] == pbSrcNext[dwOffset + x + 1])))
- {
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset + x];
- x++;
- nBytes++;
- }
-
-
- *pbByteCount = nBytes;
- sPacket++;
- }
- }
- else
- {
-
-
-
- dwOffset = (ULONG)y * (ULONG)pbufNext->sPitch + x - sSkipCount;
-
-
- while (sSkipCount > 255)
- {
-
- *(pbDst + (ULONG)lSize++) = 254;
- *(pbDst + (ULONG)lSize++) = 1;
-
-
- dwOffset += 254;
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset++];
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset++];
-
-
- sPacket++;
- sSkipCount -= 256;
- }
-
-
- *(pbDst + (ULONG)lSize++) = (UCHAR)sSkipCount;
- sSkipCount = 0;
-
-
- UCHAR nBytes = 1;
-
-
- dwOffset = (ULONG)y * (ULONG)pbufNext->sPitch;
- if ((x < (sAdjustedPitch - 3)) &&
- (pbSrcNext[dwOffset + x] == pbSrcNext[dwOffset + x + 2]) &&
- (pbSrcNext[dwOffset + x + 1] == pbSrcNext[dwOffset + x + 3]))
- {
-
- x += 2;
- while ((nBytes < 127) &&
- (x < (sAdjustedPitch - 1)) &&
- (pbSrcNext[dwOffset + x - 2] == pbSrcNext[dwOffset + x]) &&
- (pbSrcNext[dwOffset + x - 1] == pbSrcNext[dwOffset + x + 1]) &&
- (pbSrcNext[dwOffset + x + 1] != pbSrcPrev[dwOffset + x + 1]) &&
- (pbSrcNext[dwOffset + x] != pbSrcPrev[dwOffset + x]))
- {
- x += 2;
- nBytes++;
- }
-
-
-
- nBytes = 255 - nBytes + 1;
- *(pbDst + (ULONG)lSize++) = nBytes;
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset + x - 2];
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset + x - 1];
- sPacket++;
- }
- else
- {
-
- pbByteCount = pbDst + (ULONG)lSize++;
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset + x];
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset + x + 1];
- x += 2;
-
- while ((nBytes < 127) &&
- (x < (sAdjustedPitch - 1)) &&
- ((pbSrcNext[dwOffset + x] != pbSrcPrev[dwOffset + x]) ||
- (pbSrcNext[dwOffset + x + 1] != pbSrcPrev[dwOffset + x + 1])) &&
- !((x < (sAdjustedPitch - 3)) &&
- (pbSrcNext[dwOffset + x] == pbSrcNext[dwOffset + x + 2]) &&
- (pbSrcNext[dwOffset + x + 1] == pbSrcNext[dwOffset + x + 3])))
- {
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset + x];
- *(pbDst + (ULONG)lSize++) = pbSrcNext[dwOffset + x + 1];
- x += 2;
- nBytes++;
- }
-
-
- *pbByteCount = nBytes;
- sPacket++;
- }
- }
- }
- }
-
-
- if (sAlign == 1)
- *pbPacketCount = (UCHAR)sPacket;
- else
- *(USHORT*)pbPacketCount = (USHORT)sPacket;
-
-
- return 0;
- }
-
-
- long CFlx::CompressBRUN(
- UCHAR* pbIn,
- short sPitch,
- short sSrcX,
- short sSrcY,
- short sWidth,
- short sHeight,
- UCHAR* pbOut)
- {
- long lUniqueX;
- long lUniqueCnt;
- long lRepeatCnt;
- UCHAR bRepeatPix;
- long x;
- long y;
- long lOutCnt = 0;
- UCHAR* pbPackets;
-
-
- pbIn = pbIn + ((ULONG)sSrcY * (ULONG)sPitch) + (ULONG)sSrcX;
-
-
- for (y = 0; y < sHeight; y++)
- {
-
-
-
-
-
-
-
- pbPackets = pbOut;
- *pbPackets = 0;
- pbOut++;
- lOutCnt++;
-
-
- lUniqueCnt = 0;
- lUniqueX = 0;
- x = 0;
- do {
-
-
- lRepeatCnt = 0;
- bRepeatPix = pbIn[x];
- lRepeatCnt++;
- while ((x + lRepeatCnt < sWidth) && (lRepeatCnt < 127))
- {
- if (pbIn[x + lRepeatCnt] == bRepeatPix)
- lRepeatCnt++;
- else
- break;
- }
-
-
- if (lRepeatCnt >= 3)
- {
-
- if (lUniqueCnt > 0)
- {
- (*pbPackets)++;
- *pbOut++ = (UCHAR)(-lUniqueCnt);
- lOutCnt++;
- do {
- *pbOut++ = pbIn[lUniqueX++];
- lOutCnt++;
- } while (--lUniqueCnt);
- }
-
- (*pbPackets)++;
- *pbOut++ = (UCHAR)lRepeatCnt;
- lOutCnt++;
- *pbOut++ = bRepeatPix;
- lOutCnt++;
-
-
- x += lRepeatCnt;
-
-
- lUniqueX = x;
- lUniqueCnt = 0;
- }
- else
- {
-
- x++;
-
-
- lUniqueCnt++;
-
-
- if (lUniqueCnt == 127)
- {
- (*pbPackets)++;
- *pbOut++ = (UCHAR)(-lUniqueCnt);
- lOutCnt++;
- do {
- *pbOut++ = pbIn[lUniqueX++];
- lOutCnt++;
- } while (--lUniqueCnt);
- }
- }
- } while (x < sWidth);
-
- if (lUniqueCnt > 0)
- {
- (*pbPackets)++;
- *pbOut++ = (UCHAR)(-lUniqueCnt);
- lOutCnt++;
- do {
- *pbOut++ = pbIn[lUniqueX++];
- lOutCnt++;
- } while (--lUniqueCnt);
- }
-
-
-
-
- pbIn += (ULONG)sPitch;
- }
- return lOutCnt;
- }
- short CFlx::WriteDataChunk(UCHAR* pbData, long lSize, USHORT wType, long* plChunkSize)
- {
- FLX_DATA_HDR datahdr;
-
-
- datahdr.lChunkSize = 6 + lSize;
- datahdr.wType = wType;
-
-
- if (datahdr.lChunkSize & 1)
- datahdr.lChunkSize++;
-
-
- long lDataPos = m_file.Tell();
-
-
- m_file.Write(&datahdr.lChunkSize);
- m_file.Write(&datahdr.wType);
-
-
- if (lSize > 0)
- {
-
-
-
- while(lSize >= 16384L)
- {
- m_file.Write(pbData, (int)16384);
- pbData += (ULONG)16384;
- lSize -= 16384;
- }
- if (lSize > 0)
- m_file.Write(pbData, lSize);
- }
-
-
-
- m_file.Seek(lDataPos + datahdr.lChunkSize, SEEK_SET);
-
-
- *plChunkSize = datahdr.lChunkSize;
-
-
- if (m_file.Error() == FALSE)
- return 0;
- else
- return 1;
- }
-
-
- short CFlx::ReadHeader(void)
- {
-
- m_file.Seek(0, SEEK_SET);
-
-
- m_file.Read(&m_filehdr.lEntireFileSize);
- m_file.Read(&m_filehdr.wMagic);
- m_file.Read(&m_filehdr.sNumFrames);
- m_file.Read(&m_filehdr.sWidth);
- m_file.Read(&m_filehdr.sHeight);
- m_file.Read(&m_filehdr.sDepth);
- m_file.Read(&m_filehdr.sFlags);
-
- if (m_filehdr.wMagic == FLX_MAGIC_FLC)
- {
-
- m_file.Read(&m_filehdr.lMilliPerFrame);
- m_file.Read(&m_filehdr.sReserveA);
- m_file.Read(&m_filehdr.dCreatedTime);
- m_file.Read(&m_filehdr.dCreator);
- m_file.Read(&m_filehdr.dUpdatedTime);
- m_file.Read(&m_filehdr.dUpdater);
- m_file.Read(&m_filehdr.sAspectX);
- m_file.Read(&m_filehdr.sAspectY);
- m_file.Read(m_filehdr.bReservedB, sizeof(m_filehdr.bReservedB));
- m_file.Read(&m_filehdr.lOffsetFrame1);
- m_file.Read(&m_filehdr.lOffsetFrame2);
- m_file.Read(m_filehdr.bReservedC, sizeof(m_filehdr.bReservedC));
-
-
-
-
-
-
-
-
-
-
- m_file.Seek(m_filehdr.lOffsetFrame1, SEEK_SET);
- }
- else
- {
-
-
- short sJiffies;
- m_file.Read(&sJiffies);
- m_filehdr.lMilliPerFrame = (long)( (double)sJiffies * ((double)1000 / (double)70L) + (double)0.5 );
-
-
-
-
- m_filehdr.dCreatedTime = 0;
- m_filehdr.dCreator = 0x464c4942;
- m_filehdr.dUpdatedTime = 0;
- m_filehdr.dUpdater = 0x464c4942;
-
-
- m_filehdr.sAspectX = 6;
- m_filehdr.sAspectY = 5;
-
-
-
- m_file.Seek(128, SEEK_SET);
- m_filehdr.lOffsetFrame1 = m_file.Tell();
-
-
-
- long lSizeFrame1;
- m_file.Read(&lSizeFrame1);
- m_filehdr.lOffsetFrame2 = m_filehdr.lOffsetFrame1 + lSizeFrame1;
-
-
- m_file.Seek(m_filehdr.lOffsetFrame1, SEEK_SET);
- }
-
- if (m_file.Error() == FALSE)
- return 0;
- else
- return 1;
- }
-
-
- short CFlx::WriteHeader(void)
- {
-
- m_file.Seek(0, SEEK_SET);
-
-
- m_file.Write(&m_filehdr.lEntireFileSize);
- m_file.Write(&m_filehdr.wMagic);
- m_file.Write(&m_filehdr.sNumFrames);
- m_file.Write(&m_filehdr.sWidth);
- m_file.Write(&m_filehdr.sHeight);
- m_file.Write(&m_filehdr.sDepth);
- m_file.Write(&m_filehdr.sFlags);
-
- if (m_filehdr.wMagic == FLX_MAGIC_FLC)
- {
-
- m_file.Write(&m_filehdr.lMilliPerFrame);
- m_file.Write(&m_filehdr.sReserveA);
- m_file.Write(&m_filehdr.dCreatedTime);
- m_file.Write(&m_filehdr.dCreator);
- m_file.Write(&m_filehdr.dUpdatedTime);
- m_file.Write(&m_filehdr.dUpdater);
- m_file.Write(&m_filehdr.sAspectX);
- m_file.Write(&m_filehdr.sAspectY);
- m_file.Write(m_filehdr.bReservedB, sizeof(m_filehdr.bReservedB));
- m_file.Write(&m_filehdr.lOffsetFrame1);
- m_file.Write(&m_filehdr.lOffsetFrame2);
- m_file.Write(m_filehdr.bReservedC, sizeof(m_filehdr.bReservedC));
-
-
-
-
-
-
-
- m_file.Seek(128, SEEK_SET);
- }
- else
- {
-
-
- short sJiffies = (short)( (double)m_filehdr.lMilliPerFrame * ((double)70 / (double)1000) + (double)0.5 );
- m_file.Write(&sJiffies);
-
- UCHAR bZero = 0;
- for (short i = 0; i < 110; i++)
- m_file.Write(&bZero);
-
- m_file.Seek(128, SEEK_SET);
- }
-
- if (m_file.Error() == FALSE)
- return 0;
- else
- return 1;
- }
-
-
- void CFlx::ClearHeader(void)
- {
-
- short i;
- m_filehdr.lEntireFileSize = 0;
- m_filehdr.wMagic = 0;
- m_filehdr.sNumFrames = 0;
- m_filehdr.sWidth = 0;
- m_filehdr.sHeight = 0;
- m_filehdr.sDepth = 0;
- m_filehdr.sFlags = 0;
- m_filehdr.lMilliPerFrame = 0;
- m_filehdr.sReserveA = 0;
- m_filehdr.dCreatedTime = 0;
- m_filehdr.dCreator = 0;
- m_filehdr.dUpdatedTime = 0;
- m_filehdr.dUpdater = 0;
- m_filehdr.sAspectX = 0;
- m_filehdr.sAspectY = 0;
- for (i = 0; i < sizeof(m_filehdr.bReservedB); i++)
- m_filehdr.bReservedB[i] = 0;
- m_filehdr.lOffsetFrame1 = 0;
- m_filehdr.lOffsetFrame2 = 0;
- for (i = 0; i < sizeof(m_filehdr.bReservedC); i++)
- m_filehdr.bReservedC[i] = 0;
- }
-
-
- void CFlx::InitBuf(FLX_BUF* pbuf)
- {
-
-
- pbuf->pbPixels = NULL;
- pbuf->prgbColors = NULL;
- }
-
-
- short CFlx::AllocBuf(FLX_BUF* pbuf, short sWidth, short sHeight, short sColors)
- {
-
- pbuf->pbPixels = (UCHAR*)malloc((size_t)sWidth * (size_t)sHeight);
- pbuf->sPitch = sWidth;
-
-
- pbuf->prgbColors = (FLX_RGB*)malloc((size_t)sColors * sizeof(FLX_RGB));
-
-
- if ((pbuf->pbPixels != NULL) && (pbuf->prgbColors != NULL))
- return 0;
-
- else
- {
- FreeBuf(pbuf);
- return 1;
- }
- }
-
-
- void CFlx::FreeBuf(FLX_BUF* pbuf)
- {
- if (pbuf->pbPixels != NULL)
- {
- free(pbuf->pbPixels);
- pbuf->pbPixels = NULL;
- }
- if (pbuf->prgbColors != NULL)
- {
- free(pbuf->prgbColors);
- pbuf->prgbColors = NULL;
- }
- }
-
-
- void CFlx::CopyBuf(FLX_BUF* pbufDst, FLX_BUF* pbufSrc)
- {
-
- UCHAR* pbSrc = pbufSrc->pbPixels;
- UCHAR* pbDst = pbufDst->pbPixels;
- for (short y = 0; y < m_filehdr.sHeight; y++)
- {
- memcpy(pbDst, pbSrc, m_filehdr.sWidth);
- pbSrc += (ULONG)pbufSrc->sPitch;
- pbDst += (ULONG)pbufDst->sPitch;
- }
-
-
- memcpy(pbufDst->prgbColors, pbufSrc->prgbColors, 256 * sizeof(FLX_RGB));
- }
|