256 lines
6.6 KiB
C++
256 lines
6.6 KiB
C++
#define _WIN32_WINNT 0x0500
|
|
|
|
#include <stdio.h>
|
|
#include <process.h>
|
|
#include <windows.h>
|
|
|
|
|
|
#define THREAD_STACK_SIZE (16384)
|
|
#define CURRENT_VERSION_ZZZ 0
|
|
#include "LibNatal.h"
|
|
#include "./lzo/miniLZO.h"
|
|
|
|
static u32 LLZO_IsInit = 0;
|
|
static u8 LZOWRK[LZO1X_1_MEM_COMPRESS];
|
|
static u8 WorkingBuffer[640*480*3];
|
|
|
|
extern "C" {
|
|
#include "Jpeg\INTERFCE.H"
|
|
};
|
|
#define Header_ReadSave(func)\
|
|
func(&Version, 4 , 1 , pClah->pDst);\
|
|
func(&pClah->W, 4 , 1 , pClah->pDst);\
|
|
func(&pClah->H, 4 , 1 , pClah->pDst);\
|
|
func(&pClah->ThingSize, 4 , 1 , pClah->pDst);\
|
|
|
|
u32 SaveHeader(ZZZ *pClah)
|
|
{
|
|
u32 Version = CURRENT_VERSION_ZZZ;
|
|
Header_ReadSave(fwrite);
|
|
return 0;
|
|
}
|
|
|
|
u32 LoadHeader(ZZZ *pClah)
|
|
{
|
|
u32 Version = CURRENT_VERSION_ZZZ;
|
|
Header_ReadSave(fread);
|
|
if (Version > CURRENT_VERSION_ZZZ) return 0;
|
|
return 1;
|
|
}
|
|
|
|
static u32 PushJPEG(BYTE *pRGB, u32 W,u32 H)
|
|
{
|
|
JPEGDATA jData;
|
|
|
|
memset(&jData, 0, sizeof(jData));
|
|
|
|
jData.width = W;
|
|
jData.height = H;
|
|
jData.quality = 200;
|
|
jData.components = 3;
|
|
jData.ptr = (unsigned char *)pRGB;
|
|
|
|
lJADE_JPEG_INPOUT_FILE_LENGHT = 0;
|
|
ucJADE_JPEG_INPOUT_FILE = (unsigned char *)WorkingBuffer;
|
|
|
|
jData.output_file = (u8*)WorkingBuffer;
|
|
JpegWrite(&jData);
|
|
|
|
return lJADE_JPEG_INPOUT_FILE_LENGHT;
|
|
}
|
|
|
|
|
|
static int popJPEG(u8 *pSRC, u32 Size, u8 *pDST)
|
|
{
|
|
JPEGDATA stJPD;
|
|
memset(&stJPD, 0, sizeof(stJPD));
|
|
|
|
lJADE_JPEG_INPOUT_FILE_LENGHT = Size;
|
|
ucJADE_JPEG_INPOUT_FILE = (unsigned char *)pSRC;
|
|
stJPD.ptr = (u8*)pDST;
|
|
JpegInfo(&stJPD);
|
|
stJPD.ptr = (u8*)pDST;
|
|
lJADE_JPEG_INPOUT_FILE_LENGHT = Size;
|
|
ucJADE_JPEG_INPOUT_FILE = (unsigned char *)pSRC;
|
|
JpegRead(&stJPD);
|
|
return 1;
|
|
}
|
|
|
|
|
|
int _LZO_COMPRESS(u8 *source, int lenght, u8 *dest)
|
|
{
|
|
if (!LLZO_IsInit) lzo_init();
|
|
LLZO_IsInit = 0;
|
|
|
|
lzo_uint Dst;
|
|
lzo1x_1_compress( source, lenght , dest , &Dst , LZOWRK );
|
|
return Dst;
|
|
}
|
|
int _LZO_UNCOMPRESS(u8 *source, int lenght, u8 *dest)
|
|
{
|
|
if (!LLZO_IsInit) lzo_init();
|
|
LLZO_IsInit = 0;
|
|
|
|
lzo_uint Dst;
|
|
lzo1x_decompress( source , lenght , dest , &Dst , NULL);//*/
|
|
return Dst;
|
|
}
|
|
|
|
static volatile u32 IsRunning = 0;
|
|
|
|
unsigned __stdcall AsyncReadThread(void *params)
|
|
{
|
|
u32 T,Size,MustReopen = 0;
|
|
ZZZ *pCom = (ZZZ *)params;
|
|
T = timeGetTime();
|
|
IsRunning = 1;
|
|
while (1)
|
|
{
|
|
if (MustReopen)
|
|
{
|
|
fclose(pCom->pDst);
|
|
fopen_s(&pCom->pDst,pCom->FileName,"rb");
|
|
LoadHeader(pCom);
|
|
}
|
|
MustReopen = 0;
|
|
/* decompress RGB (JPEG) */
|
|
if (fread(&Size, 1 , 4 , pCom->pDst) != 4) MustReopen = 1;
|
|
if (fread(&WorkingBuffer, 1 , Size , pCom->pDst)!= Size) MustReopen = 1;
|
|
if (!MustReopen) popJPEG((u8*)&WorkingBuffer, Size, (u8*)pCom->pColorBuffer);
|
|
|
|
/* DeCompress ZBuffer (ZLIB)*/
|
|
if (fread(&Size, 1 , 4 , pCom->pDst) != 4) MustReopen = 1;
|
|
if (fread(&WorkingBuffer, 1 , Size , pCom->pDst) != Size) MustReopen = 1;
|
|
if (!MustReopen) _LZO_UNCOMPRESS((u8*)&WorkingBuffer, Size,(u8*)pCom->pDepthBuffer);
|
|
|
|
/* DeCompress thing (ZLIB) */
|
|
if (fread(&Size, 1 , 4 , pCom->pDst) != 4) MustReopen = 1;
|
|
if (fread(&WorkingBuffer, 1 , Size , pCom->pDst) != Size) MustReopen = 1;
|
|
if (!MustReopen) _LZO_UNCOMPRESS((u8*)&WorkingBuffer, Size,(u8*)pCom->pThing);
|
|
|
|
//fread(pCom->pThing , 1 , pCom->ThingSize , pCom->pDst);
|
|
u32 LastValid;
|
|
if (fread(&LastValid, 1 , 4 , pCom->pDst) != 4) MustReopen = 1;
|
|
T = timeGetTime() - T;
|
|
//if (T < 1000/15) Sleep(1000/15 - T);
|
|
IsRunning = 0;
|
|
T = timeGetTime();
|
|
pCom->AdvanceCounter++;
|
|
SignalObjectAndWait(pCom->AccesMutexB,pCom->AccesMutexA,INFINITE, FALSE);
|
|
}
|
|
}
|
|
unsigned __stdcall AsyncWriteThread(void *params)
|
|
{
|
|
u32 Size;
|
|
ZZZ *pCom = (ZZZ *)params;
|
|
while (1)
|
|
{
|
|
/* compress RGB (JPEG) */
|
|
Size = PushJPEG((u8*)pCom->pColorBuffer, pCom->W,pCom->H);
|
|
fwrite(&Size, 4 , 1 , pCom->pDst);
|
|
fwrite(&WorkingBuffer, 1 , Size , pCom->pDst);
|
|
|
|
/* Compress ZBuffer (ZLIB) */
|
|
Size = _LZO_COMPRESS((u8*)pCom->pDepthBuffer, pCom->W * pCom->H * 2, (u8*)&WorkingBuffer);
|
|
fwrite(&Size, 4 , 1 , pCom->pDst);
|
|
fwrite(&WorkingBuffer, 1 , Size , pCom->pDst);
|
|
|
|
/* Compress thing (ZLIB) */
|
|
Size = _LZO_COMPRESS((u8*)pCom->pThing, pCom->ThingSize, (u8*)&WorkingBuffer);
|
|
fwrite(&Size, 4 , 1 , pCom->pDst);
|
|
fwrite(&WorkingBuffer, 1 , Size , pCom->pDst);
|
|
|
|
|
|
u32 LastValid = 0xC0DEFECA;
|
|
fwrite(&LastValid, 4 , 1 , pCom->pDst);
|
|
pCom->AdvanceCounter++;
|
|
|
|
SignalObjectAndWait(pCom->AccesMutexB,pCom->AccesMutexA,INFINITE, FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
ZZZ *OpenForRead(char *FileName)
|
|
{
|
|
ZZZ *pClah;
|
|
pClah = (ZZZ *)malloc(sizeof(ZZZ));
|
|
pClah -> AdvanceCounter = 0;
|
|
strcpy_s(pClah->FileName,FileName);
|
|
fopen_s(&pClah->pDst,FileName,"rb");
|
|
if (!pClah->pDst) goto Bad;
|
|
|
|
|
|
if (!LoadHeader(pClah)) goto Bad;
|
|
|
|
pClah->pColorBuffer = (u32*)malloc(pClah->W*pClah->H*3);
|
|
pClah->pDepthBuffer = (u32*)malloc(pClah->W*pClah->H*2);
|
|
pClah->pThing = (u32*)malloc(pClah->ThingSize);
|
|
|
|
pClah->AccesMutexA = CreateSemaphore(NULL, 0, 1,NULL);
|
|
pClah->AccesMutexB = CreateSemaphore(NULL, 0, 1,NULL);
|
|
pClah->ThreadHandle = (HANDLE)_beginthreadex( NULL , THREAD_STACK_SIZE , AsyncReadThread , pClah , 0 , &pClah->ThreadID );
|
|
|
|
return pClah;
|
|
Bad:
|
|
free(pClah);
|
|
return NULL;
|
|
}
|
|
|
|
ZZZ *OpenForWrite(char *FileName,u32 W , u32 H , u32 ThingSize)
|
|
{
|
|
ZZZ *pClah;
|
|
pClah = (ZZZ *)malloc(sizeof(ZZZ));
|
|
fopen_s(&pClah->pDst,FileName,"wb");
|
|
if (!pClah->pDst) goto Bad;
|
|
|
|
pClah->ThingSize = ThingSize;
|
|
pClah->W = W;
|
|
pClah->H = H;
|
|
|
|
pClah->pColorBuffer = (u32*)malloc(W*H*3);
|
|
pClah->pDepthBuffer = (u32*)malloc(W*H*2);
|
|
pClah->pThing = (u32*)malloc(pClah->ThingSize);
|
|
|
|
SaveHeader(pClah);
|
|
|
|
pClah->AccesMutexA = CreateSemaphore(NULL, 0, 1,NULL);
|
|
pClah->AccesMutexB = CreateSemaphore(NULL, 0, 1,NULL);
|
|
pClah->ThreadHandle = (HANDLE)_beginthreadex( NULL , THREAD_STACK_SIZE , AsyncWriteThread , pClah , 0 , &pClah->ThreadID );
|
|
|
|
return pClah;
|
|
Bad:
|
|
free(pClah);
|
|
return NULL;
|
|
}
|
|
|
|
u32 Write(ZZZ *pZZZ , u8 *pColorsRGB , u16 *pDepth , u8 *pThings , u32 SizeofThings)
|
|
{
|
|
WaitForSingleObject(pZZZ->AccesMutexB, INFINITE);
|
|
// Begin time share
|
|
memcpy(pZZZ->pColorBuffer , pColorsRGB , pZZZ->W * pZZZ->H * 3);
|
|
memcpy(pZZZ->pDepthBuffer , pDepth , pZZZ->W * pZZZ->H * 2);
|
|
memcpy(pZZZ->pThing , pThings , pZZZ->ThingSize );
|
|
// End time share
|
|
ReleaseSemaphore(pZZZ->AccesMutexA,1,NULL);
|
|
return 0;
|
|
}
|
|
|
|
u32 Read(ZZZ *pZZZ , u8 *pColorsRGB , u16 *pDepth , u8 *pThings , u32 SizeofThings)
|
|
{
|
|
static u32 T = 0;
|
|
if (T == 0) T = timeGetTime();
|
|
WaitForSingleObject(pZZZ->AccesMutexB, INFINITE);
|
|
|
|
pZZZ->LastValid = T;
|
|
// Begin time share
|
|
memcpy(pColorsRGB , pZZZ->pColorBuffer , pZZZ->W * pZZZ->H * 3);
|
|
memcpy(pDepth , pZZZ->pDepthBuffer , pZZZ->W * pZZZ->H * 2);
|
|
memcpy(pThings , pZZZ->pThing , pZZZ->ThingSize );
|
|
|
|
// End time share
|
|
if (pZZZ->AdvanceCounter) pZZZ->AdvanceCounter--;
|
|
ReleaseSemaphore(pZZZ->AccesMutexA,1,NULL);
|
|
while (timeGetTime() < T + 1000/30) Sleep(1);
|
|
T += 1000/30;
|
|
return 0;
|
|
}
|