summaryrefslogtreecommitdiff
path: root/osd.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2007-10-12 14:52:30 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2007-10-12 14:52:30 +0200
commit0c8cda9bd007bba5b6dbae5fabc4d741d1a3ac4c (patch)
treea22c8317f28226d78095534c9c5b1f7119265415 /osd.c
parent3a4b7f065ce64a81214cc837841378f979086481 (diff)
downloadvdr-0c8cda9bd007bba5b6dbae5fabc4d741d1a3ac4c.tar.gz
vdr-0c8cda9bd007bba5b6dbae5fabc4d741d1a3ac4c.tar.bz2
Implemented handling DVB subtitles
Diffstat (limited to 'osd.c')
-rw-r--r--osd.c106
1 files changed, 89 insertions, 17 deletions
diff --git a/osd.c b/osd.c
index 1c91184d..47a11b21 100644
--- a/osd.c
+++ b/osd.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.c 1.74 2007/08/26 09:44:50 kls Exp $
+ * $Id: osd.c 1.75 2007/10/12 12:38:36 kls Exp $
*/
#include "osd.h"
@@ -82,7 +82,7 @@ void cPalette::SetColor(int Index, tColor Color)
}
}
-const tColor *cPalette::Colors(int &NumColors)
+const tColor *cPalette::Colors(int &NumColors) const
{
NumColors = numColors;
return numColors ? color : NULL;
@@ -112,7 +112,7 @@ void cPalette::Replace(const cPalette &Palette)
antiAliasGranularity = Palette.antiAliasGranularity;
}
-tColor cPalette::Blend(tColor ColorFg, tColor ColorBg, uint8_t Level)
+tColor cPalette::Blend(tColor ColorFg, tColor ColorBg, uint8_t Level) const
{
if (antiAliasGranularity > 0)
Level = uint8_t(int(Level / antiAliasGranularity + 0.5) * antiAliasGranularity);
@@ -131,7 +131,7 @@ tColor cPalette::Blend(tColor ColorFg, tColor ColorBg, uint8_t Level)
return (A << 24) | (R << 16) | (G << 8) | B;
}
-int cPalette::ClosestColor(tColor Color, int MaxDiff)
+int cPalette::ClosestColor(tColor Color, int MaxDiff) const
{
int n = 0;
int d = INT_MAX;
@@ -640,6 +640,79 @@ const tIndex *cBitmap::Data(int x, int y)
return &bitmap[y * width + x];
}
+void cBitmap::ReduceBpp(const cPalette &Palette)
+{
+ int NewBpp = Palette.Bpp();
+ if (Bpp() == 4 && NewBpp == 2) {
+ for (int i = width * height; i--; ) {
+ tIndex p = bitmap[i];
+ bitmap[i] = (p >> 2) | ((p & 0x03) != 0);
+ }
+ }
+ else if (Bpp() == 8) {
+ if (NewBpp == 2) {
+ for (int i = width * height; i--; ) {
+ tIndex p = bitmap[i];
+ bitmap[i] = (p >> 6) | ((p & 0x30) != 0);
+ }
+ }
+ else if (NewBpp == 4) {
+ for (int i = width * height; i--; ) {
+ tIndex p = bitmap[i];
+ bitmap[i] = p >> 4;
+ }
+ }
+ else
+ return;
+ }
+ else
+ return;
+ SetBpp(NewBpp);
+ Replace(Palette);
+}
+
+void cBitmap::ShrinkBpp(int NewBpp)
+{
+ int NumOldColors;
+ const tColor *Colors = this->Colors(NumOldColors);
+ if (Colors) {
+ // Find the most frequently used colors and create a map table:
+ int Used[MAXNUMCOLORS] = { 0 };
+ int Map[MAXNUMCOLORS] = { 0 };
+ for (int i = width * height; i--; )
+ Used[bitmap[i]]++;
+ int MaxNewColors = (NewBpp == 4) ? 16 : 4;
+ cPalette NewPalette(NewBpp);
+ for (int i = 0; i < MaxNewColors; i++) {
+ int Max = 0;
+ int Index = -1;
+ for (int n = 0; n < NumOldColors; n++) {
+ if (Used[n] > Max) {
+ Max = Used[n];
+ Index = n;
+ }
+ }
+ if (Index >= 0) {
+ Used[Index] = 0;
+ Map[Index] = i;
+ NewPalette.SetColor(i, Colors[Index]);
+ }
+ else
+ break;
+ }
+ // Complete the map table for all other colors (will be set to closest match):
+ for (int n = 0; n < NumOldColors; n++) {
+ if (Used[n])
+ Map[n] = NewPalette.Index(Colors[n]);
+ }
+ // Do the actual index mapping:
+ for (int i = width * height; i--; )
+ bitmap[i] = Map[bitmap[i]];
+ SetBpp(NewBpp);
+ Replace(NewPalette);
+ }
+}
+
// --- cOsd ------------------------------------------------------------------
int cOsd::osdLeft = 0;
@@ -720,19 +793,18 @@ eOsdError cOsd::CanHandleAreas(const tArea *Areas, int NumAreas)
eOsdError cOsd::SetAreas(const tArea *Areas, int NumAreas)
{
- eOsdError Result = oeUnknown;
- if (numBitmaps == 0) {
- Result = CanHandleAreas(Areas, NumAreas);
- if (Result == oeOk) {
- width = height = 0;
- for (int i = 0; i < NumAreas; i++) {
- bitmaps[numBitmaps++] = new cBitmap(Areas[i].Width(), Areas[i].Height(), Areas[i].bpp, Areas[i].x1, Areas[i].y1);
- width = max(width, Areas[i].x2 + 1);
- height = max(height, Areas[i].y2 + 1);
- }
- }
+ eOsdError Result = CanHandleAreas(Areas, NumAreas);
+ if (Result == oeOk) {
+ while (numBitmaps)
+ delete bitmaps[--numBitmaps];
+ width = height = 0;
+ for (int i = 0; i < NumAreas; i++) {
+ bitmaps[numBitmaps++] = new cBitmap(Areas[i].Width(), Areas[i].Height(), Areas[i].bpp, Areas[i].x1, Areas[i].y1);
+ width = max(width, Areas[i].x2 + 1);
+ height = max(height, Areas[i].y2 + 1);
+ }
}
- if (Result != oeOk)
+ else
esyslog("ERROR: cOsd::SetAreas returned %d", Result);
return Result;
}
@@ -818,7 +890,7 @@ cOsdProvider::~cOsdProvider()
cOsd *cOsdProvider::NewOsd(int Left, int Top, uint Level)
{
- if (Level == 0 && cOsd::IsOpen())
+ if (Level == OSD_LEVEL_DEFAULT && cOsd::IsOpen())
esyslog("ERROR: attempt to open OSD while it is already open - using dummy OSD!");
else if (osdProvider) {
cOsd *ActiveOsd = cOsd::Osds.Size() ? cOsd::Osds[0] : NULL;