From 8768a9c3219e462ab5c7ca93eba5589d31f4fa64 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 27 Mar 2011 11:50:17 +0200 Subject: [PATCH] Added anti-aliasing when upscaling bitmaps --- HISTORY | 4 +++- osd.c | 54 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/HISTORY b/HISTORY index 6bc949b7..00422aab 100644 --- a/HISTORY +++ b/HISTORY @@ -6557,7 +6557,7 @@ Video Disk Recorder Revision History - The original display size of subtitles is now used to scale them properly when displaying them on an HD OSD. -2011-03-21: Version 1.7.18 +2011-03-27: Version 1.7.18 - Changed -O2 to -O3 in Make.config.template (reported by Matti Lehtimäki). - Added a missing 'default' case in cPixmapMemory::DrawEllipse(). @@ -6573,3 +6573,5 @@ Video Disk Recorder Revision History - Fixed cUnbufferedFile::Seek() in case it is compiled without USE_FADVISE (thanks to Juergen Lock). - Fixed the Language header of the Serbian translation file (thanks to Ville Skyttä). +- Added anti-aliasing when upscaling bitmaps (improves the display of SD subtitles + when replayed on an HD OSD). diff --git a/osd.c b/osd.c index 132974ab..7e9bacc4 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 2.18 2011/03/13 13:52:01 kls Exp $ + * $Id: osd.c 2.19 2011/03/27 11:48:39 kls Exp $ */ #include "osd.h" @@ -503,8 +503,7 @@ void cBitmap::DrawPixel(int x, int y, tColor Color) { x -= x0; y -= y0; - if (0 <= x && x < width && 0 <= y && y < height) - SetIndex(x, y, Index(Color)); + SetIndex(x, y, Index(Color)); } void cBitmap::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool ReplacePalette, bool Overlay) @@ -815,19 +814,42 @@ cBitmap *cBitmap::Scale(double FactorX, double FactorY) b->Replace(*this); // copy palette int RatioX = (Width() << 16) / b->Width(); int RatioY = (Height() << 16) / b->Height(); - tIndex *DestRow = b->bitmap; - int SourceY = 0; - for (int y = 0; y < b->Height(); y++) { - int SourceX = 0; - tIndex *SourceRow = bitmap + (SourceY >> 16) * Width(); - tIndex *Dest = DestRow; - for (int x = 0; x < b->Width(); x++) { - *Dest++ = SourceRow[SourceX >> 16]; - SourceX += RatioX; - } - SourceY += RatioY; - DestRow += b->Width(); - } + if (FactorX <= 1.0 && FactorY <= 1.0) { + // Downscaling - no anti-aliasing: + tIndex *DestRow = b->bitmap; + int SourceY = 0; + for (int y = 0; y < b->Height(); y++) { + int SourceX = 0; + tIndex *SourceRow = bitmap + (SourceY >> 16) * Width(); + tIndex *Dest = DestRow; + for (int x = 0; x < b->Width(); x++) { + *Dest++ = SourceRow[SourceX >> 16]; + SourceX += RatioX; + } + SourceY += RatioY; + DestRow += b->Width(); + } + } + else { + // Upscaling - anti-aliasing: + b->SetBpp(8); + int SourceY = 0; + for (int y = 0; y < b->Height() - 1; y++) { + int SourceX = 0; + int sy = SourceY >> 16; + uint8_t BlendY = 0xFF - ((SourceY >> 8) & 0xFF); + for (int x = 0; x < b->Width() - 1; x++) { + int sx = SourceX >> 16; + uint8_t BlendX = 0xFF - ((SourceX >> 8) & 0xFF); + tColor c1 = b->Blend(GetColor(sx, sy), GetColor(sx + 1, sy), BlendX); + tColor c2 = b->Blend(GetColor(sx, sy + 1), GetColor(sx + 1, sy + 1), BlendX); + tColor c3 = b->Blend(c1, c2, BlendY); + b->DrawPixel(x + X0(), y + Y0(), c3); + SourceX += RatioX; + } + SourceY += RatioY; + } + } return b; }