📄 ig_parse.cpp
字号:
load the object definition segment
*/
/* read the object id */
CurObj->VersionNumber = VersionNumber;
ObjStart+=3;
/* get sequence flags, these won't be accurate for mulitPES segments */
CurObj->SeqDesc.FirstInSequenceFlag = ((*ObjStart) & BIT7) >> 7;
CurObj->SeqDesc.LastInSequenceFlag = ((*ObjStart) & BIT6) >> 6;
ObjStart++;
/* read the object data fragment */
CurObj->ObjData.DataLength = (*ObjStart) << 16 | ((*(ObjStart+1)) << 8) | (*(ObjStart+2));
CurObj->ObjData.Width = MAKE_WORD(ObjStart+3); /* could add paranoia check here on do_update */
CurObj->ObjData.Height = MAKE_WORD(ObjStart+5); /* could add paranoia check here on do_update */
ObjStart+=7;
/* how big is the image? */
OutputSize = CurObj->ObjData.Width * CurObj->ObjData.Height;
/* if this is an update then we already malloc'd the space */
if (1 == DoUpdate)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("IGLoadObject(); Doing object update\n"));
#ifdef ALLOW_IG_PROFILING
if (IGStats.Profiling == 1)
{
TickStart = OS_GetTicks();
}
#endif
/* lock the dfb surface buffer for the object and RLE decode into it */
if (DFB_OK != CurObj->SurfaceLUT8->Lock(CurObj->SurfaceLUT8, DSLF_WRITE, &ImgData, &CurObj->pitch))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed to Lock LUT8 Surface\n"));
goto errout;
}
/* RLE decode into the surface */
if (IG_STATUS_SUCCESS != IGRLEDecode(ObjStart, CurObj->ObjData.DataLength-4, (BYTE *)ImgData, OutputSize,
CurObj->pitch, CurObj->ObjData.Width, IGInfo.CoordsHalfWidth))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed to RLE decode the image\n"));
goto errout;
}
/* unlock the surface */
if (DFB_OK != CurObj->SurfaceLUT8->Unlock(CurObj->SurfaceLUT8))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed Unlock LUT8 surface\n"));
goto errout;
}
#ifdef ALLOW_IG_PROFILING
if (IGStats.Profiling == 1)
{
IGStats.TotalRLETicks += OS_GetTicks() - TickStart;
if (IGInfo.CoordsHalfWidth)
{
IGStats.TotalPixelsDecoded += ((CurObj->ObjData.Width+1)/2) * CurObj->ObjData.Height;
}
else
{
IGStats.TotalPixelsDecoded += CurObj->ObjData.Width * CurObj->ObjData.Height;
}
}
#endif
}
else
{
/* fill in the surface pointers */
desc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS | DSDESC_DFBPALETTEHANDLE);
desc.pixelformat = DSPF_LUT8;
if (IGInfo.CoordsHalfWidth == 0)
{
desc.width = CurObj->ObjData.Width;
}
else
{
/* add one to account for odd width images */
desc.width = (CurObj->ObjData.Width+1) / 2;
}
desc.height = CurObj->ObjData.Height;
desc.caps = (DFBSurfaceCapabilities)(DSCAPS_VIDEOONLY | DSCAPS_PREMULTIPLIED);
/* Any palette will do as it will not be used */
desc.dfbpalette = IGPalettes[0].DFBPal;
/* create palettized surface */
if (IG_STATUS_SUCCESS != IGGraphicsCreateLUT8Surface(&desc, CurObj))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed to Create LUT8 Surface\n"));
return IG_STATUS_ERROR;
}
#ifdef ALLOW_IG_PROFILING
if (IGStats.Profiling == 1)
{
TickStart = OS_GetTicks();
}
#endif
/* lock the dfb surface buffer for the object and RLE decode into it */
if (DFB_OK != CurObj->SurfaceLUT8->Lock(CurObj->SurfaceLUT8, DSLF_WRITE, &ImgData, &CurObj->pitch))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed to Lock LUT8 Surface\n"));
return IG_STATUS_ERROR;
}
/* RLE decode into the surface */
if (IG_STATUS_SUCCESS != IGRLEDecode(ObjStart, CurObj->ObjData.DataLength-4, (BYTE *)ImgData, OutputSize,
CurObj->pitch, CurObj->ObjData.Width, IGInfo.CoordsHalfWidth))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed to RLE decode the image\n"));
return IG_STATUS_ERROR;
}
/* unlock the surface */
if (DFB_OK != CurObj->SurfaceLUT8->Unlock(CurObj->SurfaceLUT8))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadObject(): Failed Unlock LUT8 surface\n"));
return IG_STATUS_ERROR;
}
#ifdef ALLOW_IG_PROFILING
if (IGStats.Profiling == 1)
{
IGStats.TotalRLETicks += OS_GetTicks() - TickStart;
if (IGInfo.CoordsHalfWidth)
{
IGStats.TotalPixelsDecoded += ((CurObj->ObjData.Width+1)/2) * CurObj->ObjData.Height;
}
else
{
IGStats.TotalPixelsDecoded += CurObj->ObjData.Width * CurObj->ObjData.Height;
}
}
#endif
gIGDecodedObjectBuffUsed += OutputSize;
}
/* we are using this slot */
CurObj->InUse = 1;
return IG_STATUS_SUCCESS;
errout:
if (CurObj->SurfaceLUT8)
{
CurObj->SurfaceLUT8->Release(CurObj->SurfaceLUT8);
CurObj->SurfaceLUT8 = NULL;
}
CurObj->InUse = 0;
return IG_STATUS_ERROR;
}
/**
* IGFreeObjects - free all the object in IGObjList (and the memory they hold)
*
* @return VOID
*/
void IGFreeObjects()
{
for (int i=0; i<IG_MAX_ODS; i++)
{
if (IGObjList[i].InUse)
{
if (IGObjList[i].SurfaceLUT8)
{
IGObjList[i].SurfaceLUT8->Release(IGObjList[i].SurfaceLUT8);
IGObjList[i].SurfaceLUT8 = NULL;
}
/* clear ODS memory */
memset(&IGObjList[i], 0, sizeof(OBJECT_DEFINITION_SEGMENT));
}
}
/* all of the decoded object buffer is free now */
gIGDecodedObjectBuffUsed = 0;
}
/**
* IGClearPalettes - clear all the palette memory to the Clear Color (0xFF)
*
* @return VOID
*/
void IGClearPalettes()
{
for (int i=0; i<IG_MAX_PALETTES; i++)
{
/* set all palette colors to transparent */
memset(IGPalettes[i].Colors, 0xFF, IG_MAX_PALETTE_COLORS * sizeof(DFBColor));
IGPalettes[i].PaletteVersion = 0;
}
}
/**
* IGFlushParseQ - clear all messages from the parse Queue
*
* @return VOID
*/
IG_STATUS IGFlushParseQ()
{
IG_PARSE_MSG *pMessage;
while (1)
{
/* Get a stream message */
pMessage = (IG_PARSE_MSG *)IGInfo.IGParseQ->Read(OS_NO_WAIT);
if (pMessage)
{
IGInfo.IGParseQ->ReleaseMsg(pMessage);
pMessage=NULL;
}
else
{
break;
}
}
return IG_STATUS_SUCCESS;
}
/**
* IGFlushRenderQ - clear all messages from the render Queue
*
* @return VOID
*/
IG_STATUS IGFlushRenderQ()
{
IG_RENDER_MSG *pMessage;
while (1)
{
/* Get a stream message */
pMessage = (IG_RENDER_MSG *)IGInfo.IGRenderQ->Read(OS_NO_WAIT);
if (pMessage)
{
/* free memory */
if (pMessage->ICS)
{
IGFreeICS(pMessage->ICS);
pMessage->ICS = NULL;
}
IGInfo.IGRenderQ->ReleaseMsg(pMessage);
pMessage = NULL;
}
else
{
break;
}
}
return IG_STATUS_SUCCESS;
}
/**
* IGFlush - called during a IGStop(), clears all object lists and resets the parser
*
* @return VOID
*/
IG_STATUS IGFlush()
{
/* flush the parseQ and RenderQ */
IGFlushParseQ();
IGFlushRenderQ();
/* wait for the parser to be free */
while (gIGParserWaiting == 0)
{
OS_SemGive(IGInfo.RenderWait.WaitSem);
OS_SemGive(IGInfo.ParseWait.WaitSem);
OS_TaskYield();
}
/* no composition or selection timeouts */
IGInfo.CompositionTimeoutPTS = 0;
IGInfo.SelectionTimeoutPTS = 0;
/* take the ics lock to clear the renderer */
OS_SemTake(IGInfo.ICSLock, OS_WAIT_FOREVER);
/* cancel all timers */
OS_TimerStop(IGInfo.TimerAnimation);
OS_TimerStop(IGInfo.TimerUserSelection);
/* clear the IGInfo structure */
if (IGInfo.ICS)
{
/* fire event */
IGToPEICSInValid();
IGFreeICS(IGInfo.ICS);
IGInfo.ICS = NULL;
}
IGInfo.ActivePage = NULL;
IGInfo.SelectedButton = NULL;
/* clear out all the objects in our list */
IGFreeObjects();
/* clear our palettes */
IGClearPalettes();
/* reset the graphics plane */
IGGraphicsClearBuffer(NULL, 0);
OS_TimerSet(IGInfo.TimerFlip, 1);
OS_TaskYield();
OS_SemGive(IGInfo.ICSLock);
return IG_STATUS_SUCCESS;
}
/**
* IGWaitForDTS - wait for a DTS value to show up so we can decode a segment
*
* @return VOID
*/
IG_STATUS IGWaitForDTS(ULONG DTS)
{
/* first check if the time has already passed that we want, if so just return */
if (IGInfo.CurPTS < DTS)
{
if (IGInfo.SyncState == IG_DECODE_SYNC)
{
/* setup the ParseWait IG_WAIT_TIME_SEM to block and wait for the PTS we want */
IGInfo.ParseWait.WaitPTS = DTS;
/* now block wait for the time to show, we awake via UpdateTimeStamp() semgive */
OS_SemTake(IGInfo.ParseWait.WaitSem, OS_WAIT_FOREVER);
IGInfo.ParseWait.WaitPTS = 0;
}
}
return (IG_STATUS_SUCCESS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -