📄 ig_graphics.cpp
字号:
/*****************************************************************************
******************************************************************************
** **
** Copyright (c) 2005-2006 Videon Central, Inc. **
** All rights reserved. **
** **
** The computer program contained herein contains proprietary information **
** which is the property of Videon Central, Inc. The program may be used **
** and/or copied only with the written permission of Videon Central, Inc. **
** or in accordance with the terms and conditions stipulated in the **
** agreement/contract under which the programs have been supplied. **
** **
******************************************************************************
*****************************************************************************/
/**
* @file ig_graphics.cpp
*
* $Revision: 1.3 $
*
* IG graphics drawing routines
*
*/
#include "ig_api.h"
#include "directfb.h"
#include "ig_util.h"
#include "ig_defs.h"
#include "ig_graphics.h"
#define DEBUG_IG_GRAPHICS DBG_ERROR
#define DBG_ON(x) (DEBUG_IG_GRAPHICS >= x)
/* stuff from another file */
extern PALETTE IGPalettes[IG_MAX_PALETTES];
extern OBJECT_DEFINITION_SEGMENT IGObjList[IG_MAX_ODS];
extern IGINFO IGInfo;
extern IGSTATS IGStats;
/* locals */
DFBRegion gIGFlipRegion;
extern ULONG gIGImageIndex;
extern DFBRectangle IGCleanupList[IG_MAX_VISIBLE_ODS]; /* our list of objects to clean on screen */
IG_STATUS IGAddtoCleanupList(int X, int Y, int Width, int Height);
/**
* IGGraphicsDrawCompObj - draw the given composition object on screen, cropped images also
*
* @param COMPOSITION_OBJECT *CompObj - The Composition object to draw
* @param int ClearObject - set to 1 if the object should be erased
*
* @return IG_STATUS
*/
IG_STATUS IGGraphicsDrawCompObj(COMPOSITION_OBJECT *CompObj, int ClearObject)
{
OBJECT_DEFINITION_SEGMENT *Img=NULL;
USHORT DrawX, DrawY, DrawW, DrawH;
USHORT ScreenMaxX, ScreenMaxY;
#ifdef ALLOW_IG_PROFILING
ULONG TickStart = 0;
#endif
/* grab the object from the list */
Img = &IGObjList[CompObj->ObjectIDRef];
if (0 == Img->InUse)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): Could not render object it is not available id %d\n", CompObj->ObjectIDRef));
return IG_STATUS_ERROR;
}
/* we need to create a new surface */
int imgsize = Img->ObjData.Width * Img->ObjData.Height;
if (0 == imgsize)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): imgsize was zero\n"));
return IG_STATUS_ERROR;
}
/* check to see if the image is big enough to render */
if ((Img->ObjData.Width < 8) || (Img->ObjData.Height < 8))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): Could not render object id %d, too small\n", CompObj->ObjectIDRef));
return IG_STATUS_ERROR;
}
if (ClearObject)
{
IGInfo.IGDFBInfo.PrimarySurface->SetColorIndex(IGInfo.IGDFBInfo.PrimarySurface, 0xff); // all transparent
DFBRectangle r;
r.y = CompObj->YPosition;
r.h = Img->ObjData.Height;
if (IGInfo.CoordsHalfWidth == 0)
{
r.x = CompObj->XPosition;
r.w = Img->ObjData.Width;
}
else
{
r.x = CompObj->XPosition/2;
r.w = (Img->ObjData.Width+1)/2;
}
IGInfo.IGDFBInfo.PrimarySurface->FillRectangle(IGInfo.IGDFBInfo.PrimarySurface, r.x, r.y, r.w, r.h);
IGAddtoCleanupList(r.x, r.y, r.w, r.h);
return IG_STATUS_SUCCESS;
}
/* load drawing params, if we are drawing half width cut all x coords in half */
if (IGInfo.CoordsHalfWidth == 0)
{
DrawX = CompObj->XPosition;
DrawY = CompObj->YPosition;
DrawW = Img->ObjData.Width;
DrawH = Img->ObjData.Height;
ScreenMaxX = MAX_GRFX_WIDTH;
ScreenMaxY = MAX_GRFX_HEIGHT;
}
else
{
DrawX = CompObj->XPosition/2;
DrawY = CompObj->YPosition;
DrawW = (Img->ObjData.Width+1)/2;
DrawH = Img->ObjData.Height;
ScreenMaxX = MAX_GRFX_WIDTH/2;
ScreenMaxY = MAX_GRFX_HEIGHT;
}
/* see if the image is cropped */
if (0 == CompObj->CroppedFlag)
{
/* check that we do not go outside screen space */
if ((DrawX <= ScreenMaxX) && (DrawY <= ScreenMaxY) &&
((DrawX + DrawW) <= ScreenMaxX) && ((DrawY + DrawH) <= ScreenMaxY))
{
/* image is not cropped */
#ifdef ALLOW_IG_PROFILING
if (IGStats.Profiling == 1)
{
TickStart = OS_GetTicks();
}
#endif
if (IGInfo.IGDFBInfo.PrimarySurface->Blit(IGInfo.IGDFBInfo.PrimarySurface,
Img->SurfaceLUT8, NULL, DrawX, DrawY) == DFB_OK)
{
#ifdef ALLOW_IG_PROFILING
if (IGStats.Profiling == 1)
{
IGStats.TotalBlitTicks += OS_GetTicks() - TickStart;
}
#endif
IGAddtoCleanupList(DrawX, DrawY, DrawW, DrawH);
}
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): image tried to draw out of bounds %d %d %d %d\n",
DrawX, DrawY, DrawX + DrawW, DrawY + DrawH));
}
}
else
{
/* img is cropped */
DFBRectangle Rect;
Rect.y = CompObj->Rect.Y;
Rect.h = CompObj->Rect.Height;
if (IGInfo.CoordsHalfWidth == 0)
{
Rect.x = CompObj->Rect.X;
Rect.w = CompObj->Rect.Width;
}
else
{
Rect.x = CompObj->Rect.X/2;
Rect.w = (CompObj->Rect.Width+1)/2;
}
/* draw the image */
if ((DrawX <= ScreenMaxX) && (DrawY <= ScreenMaxY) &&
((DrawX + Rect.w) <= ScreenMaxX) && ((DrawY + Rect.h) <= ScreenMaxY))
{
#ifdef ALLOW_IG_PROFILING
if (IGStats.Profiling == 1)
{
TickStart = OS_GetTicks();
}
#endif
if (IGInfo.IGDFBInfo.PrimarySurface->Blit(IGInfo.IGDFBInfo.PrimarySurface, Img->SurfaceLUT8,
&Rect, DrawX, DrawY) == DFB_OK)
{
#ifdef ALLOW_IG_PROFILING
if (IGStats.Profiling == 1)
{
IGStats.TotalBlitTicks += OS_GetTicks() - TickStart;
}
#endif
IGAddtoCleanupList(DrawX, DrawY, Rect.w, Rect.h);
}
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): image tried to draw out of bounds %d %d %d %d\n",
DrawX, DrawY, DrawX + Rect.w, DrawY + Rect.h));
}
}
return IG_STATUS_SUCCESS;
}
/**
* IGAddtoCleanupList - add to list of objects to be cleaned up on an animation
*
* @param int X - X coord of image
* @param int Y - Y coord of image
* @param int Width - Width of image
* @param int Height - Height of image
*
* @return IG_STATUS
*/
IG_STATUS IGAddtoCleanupList(int X, int Y, int Width, int Height)
{
/* stretch the flipping region to fit the new coords,
* do this here because we may flip a region of the
* screen but not clear all of it */
if (X < gIGFlipRegion.x1)
{
gIGFlipRegion.x1 = X;
}
if (Y < gIGFlipRegion.y1)
{
gIGFlipRegion.y1 = Y;
}
if (X+Width > gIGFlipRegion.x2)
{
gIGFlipRegion.x2 = X+Width;
}
if (Y+Height > gIGFlipRegion.y2)
{
gIGFlipRegion.y2 = Y+Height;
}
/* loop looking for a match */
for (ULONG i=0; i<gIGImageIndex; i++)
{
/* see if we match inputs */
if ((IGCleanupList[i].h == Height) &&
(IGCleanupList[i].w == Width) &&
(IGCleanupList[i].x == X) &&
(IGCleanupList[i].y == Y))
{
/* input matches one in the list, don't add */
return IG_STATUS_SUCCESS;
}
}
if (gIGImageIndex >= IG_MAX_VISIBLE_ODS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGAddToCleanupList(): failed, too many images on screen!!\n\n"));
return IG_STATUS_ERROR;
}
/* if we didn't find a match in the list, we got here, so add it */
IGCleanupList[gIGImageIndex].h = Height;
IGCleanupList[gIGImageIndex].w = Width;
IGCleanupList[gIGImageIndex].x = X;
IGCleanupList[gIGImageIndex].y = Y;
DBGPRINT(DBG_ON(DBG_TRACE), ("IG Image: (%d, %d) w=%d, h=%d\n",
IGCleanupList[gIGImageIndex].x, IGCleanupList[gIGImageIndex].y,
IGCleanupList[gIGImageIndex].w, IGCleanupList[gIGImageIndex].h));
gIGImageIndex++;
return IG_STATUS_SUCCESS;
}
/**
* IGGraphicsSetPalette - update the palette for the currently displayed surface
*
* @param PALETTE *Pal - The palette to set on DirectFB
*
* @return IG_STATUS
*/
IG_STATUS IGGraphicsSetPalette(PALETTE *Pal)
{
/* set the palette */
DFBResult res;
if (Pal == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsSetPalette(): Null Pal\n"));
return IG_STATUS_ERROR;
}
if (Pal->DFBPal == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsSetPalette(): Null DFBPal\n"));
return IG_STATUS_ERROR;
}
/* call create palette with the entries we give here */
if (Pal->DFBPal->SetEntries(Pal->DFBPal, Pal->Colors, IG_MAX_PALETTE_COLORS, 0) != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsSetPalette(): SetEntries Failed\n"));
return IG_STATUS_ERROR;
}
res = IGInfo.IGDFBInfo.PrimarySurface->SetPalette(IGInfo.IGDFBInfo.PrimarySurface, Pal->DFBPal);
if (res != DFB_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsSetPalette(): Failed to set palette, error %d\n", res));
return IG_STATUS_ERROR;
}
return IG_STATUS_SUCCESS;
}
/**
* IGGraphicsCreatePalette - update the palette for the currently displayed surface
*
* @param int PaletteNumber - the palette number that is getting new colors
* @param BYTE *DataPtr - the palette color information from the stream
* @param int NumEntries - the number of entries that are in the stream
*
* @return IG_STATUS
*/
IG_STATUS IGGraphicsSetPaletteColors(int PaletteNumber, BYTE *DataPtr, BYTE NumEntries, BYTE fClearPalette, IG_COLOR_SPACE ColorSpace)
{
int PalColor;
ULONG Color;
BYTE *ClrBytes = (BYTE *)&Color;
PALETTE *CurPal = &IGPalettes[PaletteNumber];
/* we are clearing the palette before setting entries */
if (fClearPalette)
{
memset(CurPal->Colors, 0, IG_MAX_PALETTE_COLORS * sizeof(DFBColor));
}
for (int i=0; i<NumEntries; i++)
{
PalColor = *DataPtr;
DataPtr++; /* move to color area, past palette_entry_id */
/* convert all colors to ARGB, 601 or 709 colorspace */
if (ColorSpace == REC_709)
{
Color = IGMakeARGBfromYCrCb709(*DataPtr++, // y
*DataPtr++, //cr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -