From fa23beeb40ee49a917ab136bc26cb41bcbdfd6cb Mon Sep 17 00:00:00 2001 From: cxl Date: Tue, 18 Aug 2015 17:56:00 +0000 Subject: [PATCH] CtrlLib, Draw: New UHD scaler, fixed FileSel::SelectDir layout git-svn-id: svn://ultimatepp.org/upp/trunk@8817 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlLib/FileSel.cpp | 4 +- uppsrc/Draw/ImageChOp.cpp | 8 +- uppsrc/Draw/ImageOp.cpp | 12 +++ uppsrc/Draw/ImageOp.h | 2 + uppsrc/Draw/Uhd.cpp | 109 +++++++++++++++++++++++----- uppsrc/Draw/src.tpp/Image$en-us.tpp | 6 ++ 6 files changed, 117 insertions(+), 24 deletions(-) diff --git a/uppsrc/CtrlLib/FileSel.cpp b/uppsrc/CtrlLib/FileSel.cpp index 73d2661ba..a917da358 100644 --- a/uppsrc/CtrlLib/FileSel.cpp +++ b/uppsrc/CtrlLib/FileSel.cpp @@ -1636,13 +1636,13 @@ bool FileSel::Execute(int _mode) { sort_lbl.Hide(); ok.SetLabel(t_("&Select")); Logc p = filename.GetPos().y; - int q = ok.GetPos().y.GetA() + ok.GetPos().y.GetB() + 8; + int q = ok.GetPos().y.GetA() + ok.GetPos().y.GetB() + Zy(8); p.SetA(q); filename.SetPosY(p); filesize.SetPosY(p); filetime.SetPosY(p); p = splitter.Ctrl::GetPos().y; - p.SetB(q + 20); + p.SetB(q + Zy(20)); splitter.SetPosY(p); LogPos ps = search.GetPos(); LogPos pl = sort_lbl.GetPos(); diff --git a/uppsrc/Draw/ImageChOp.cpp b/uppsrc/Draw/ImageChOp.cpp index a0d8bb072..84f1f80dc 100644 --- a/uppsrc/Draw/ImageChOp.cpp +++ b/uppsrc/Draw/ImageChOp.cpp @@ -185,11 +185,11 @@ Image RecreateAlpha(const Image& overwhite, const Image& overblack) RGBA *t = r; RGBA *e = t + r.GetLength(); while(t < e) { - t->a = bs->r - ws->r + 255; + t->a = Saturate255(bs->r - ws->r + 255); if(t->a) { - t->r = bs->r * 255 / t->a; - t->g = bs->g * 255 / t->a; - t->b = bs->b * 255 / t->a; + t->r = Saturate255(bs->r * 255 / t->a); + t->g = Saturate255(bs->g * 255 / t->a); + t->b = Saturate255(bs->b * 255 / t->a); } else t->r = t->g = t->b = 0; diff --git a/uppsrc/Draw/ImageOp.cpp b/uppsrc/Draw/ImageOp.cpp index 933e4cc12..7b9280cae 100644 --- a/uppsrc/Draw/ImageOp.cpp +++ b/uppsrc/Draw/ImageOp.cpp @@ -68,6 +68,13 @@ void Over(ImageBuffer& dest, Point p, const Image& src, const Rect& srect) DstSrcOp(dest, p, src, srect, AlphaBlend); } +Image GetOver(const Image& dest, const Image& src) +{ + Image r = dest; + Over(r, src); + return r; +} + void Fill(ImageBuffer& dest, const Rect& rect, RGBA color) { Rect r = dest.GetSize() & rect; @@ -98,6 +105,11 @@ void Over(Image& dest, Point p, const Image& _src, const Rect& srect) dest = b; } +void Over(Image& dest, const Image& _src) +{ + Over(dest, Point(0, 0), _src, _src.GetSize()); +} + void Fill(Image& dest, const Rect& rect, RGBA color) { ImageBuffer b(dest); diff --git a/uppsrc/Draw/ImageOp.h b/uppsrc/Draw/ImageOp.h index 7aaf5fb0e..e9bfd962c 100644 --- a/uppsrc/Draw/ImageOp.h +++ b/uppsrc/Draw/ImageOp.h @@ -6,11 +6,13 @@ Image WithHotSpots(const Image& m, int x1, int y1, int x2, int y2); Image WithHotSpot(const Image& m, int x1, int y1); void Over(ImageBuffer& dest, Point p, const Image& src, const Rect& srect); +void Over(Image& dest, const Image& src); void Copy(ImageBuffer& dest, Point p, const Image& src, const Rect& srect); void Fill(ImageBuffer& dest, const Rect& rect, RGBA color); void Copy(Image& dest, Point p, const Image& src, const Rect& srect); void Over(Image& dest, Point p, const Image& src, const Rect& srect); +Image GetOver(const Image& dest, const Image& src); void Fill(Image& dest, const Rect& rect, RGBA color); void OverStraightOpaque(ImageBuffer& dest, Point p, const Image& src, const Rect& srect); diff --git a/uppsrc/Draw/Uhd.cpp b/uppsrc/Draw/Uhd.cpp index 08da524bb..df0389145 100644 --- a/uppsrc/Draw/Uhd.cpp +++ b/uppsrc/Draw/Uhd.cpp @@ -2,6 +2,91 @@ namespace Upp { +// Upscale2x is based on xBR filter idea by Hyllian, google search on 'xBR filter' +// should eventually lead you to a forum topic where he made the algorithm public: +// http://board.byuu.org/viewtopic.php?f=10&t=2248 + +namespace Upscale2x_helper { + int d(RGBA c1, RGBA c2) + { + int r = abs(c1.r - c2.r); + int g = abs(c1.g - c2.g); + int b = abs(c1.b - c2.b); + return 48 * (r * 299 + g * 587 + b * 114) + + 7 * (r * -169 + g * -331 + b * 500) + + 6 * (r * 500 + g * -419 + b * -81); + } +}; + +Image Upscale2x(const Image& src, RGBA bg) +{ + using namespace Upscale2x_helper; + Size isz = src.GetSize(); + ImageBuffer dst; + dst.Create(2 * isz); + for(int y = 0; y < isz.cy; y++) + for(int x = 0; x < isz.cx; x++) { + static const int8 cm[] = { + // -2 -1 0 +1 +2 + -1, 0, 1, 2, -1, // -2 + 17, 19, 3, 4, 5, // -1 + 16, 18, -1, 8, 6, // 0 + 15, 14, 13, 9, 7, // +1 + -1, 12, 11, 10, -1, // +2 + }; + + RGBA pp[40]; + const int8 *q = cm; + for(int dy = -2; dy <= 2; dy++) + for(int dx = -2; dx <= 2; dx++) { + if(*q >= 0) { + int xx = x + dx; + int yy = y + dy; + pp[*q] = pp[*q + 20] = xx >= 0 && xx < isz.cx + && yy >= 0 && yy < isz.cy ? src[yy][xx] : bg; + } + q++; + } + + RGBA c = src[y][x]; + RGBA *p = pp; + + for(int rot = 0; rot < 4; rot++) { + RGBA t = c; + if(d(c, p[14]) + d(c, p[4]) + d(p[19], p[16]) + d(p[19], p[1]) + 4 * d(p[18], p[3]) + < d(p[18], p[13]) + d(p[18], p[17]) + d(p[3], p[8]) + d(p[3], p[0]) + 4 * d(c, p[19])) { + RGBA nc = d(c, p[18]) <= d(c, p[3]) ? p[18] : p[3]; + t.r = (nc.r + c.r) >> 1; + t.g = (nc.g + c.g) >> 1; + t.b = (nc.b + c.b) >> 1; + } + // 0 1 + // 3 2 + dst[2 * y + (rot >= 2)][2 * x + (rot == 1 || rot == 2)] = t; + p += 5; + } + } + return dst; +} + +Image Upscale2x(const Image& src) +{ + Size isz = src.GetSize(); + Image s = RecreateAlpha(Upscale2x(GetOver(CreateImage(isz, White()), src), White()), + Upscale2x(GetOver(CreateImage(isz, Black()), src), Black())); + ImageBuffer h(s); + h.SetResolution(IMAGE_RESOLUTION_UHD); + return h; +} + +Image Downscale2x(const Image& src) +{ + Image m = RescaleFilter(src, src.GetSize() / 2, FILTER_LANCZOS3); + ImageBuffer h(m); + h.SetResolution(IMAGE_RESOLUTION_STANDARD); + return h; +} + static bool sUHDMode; void SetUHDMode(bool b) @@ -19,32 +104,20 @@ bool IsUHDMode() Image DPI(const Image& img) { if(IsUHDMode()) { - if(img.GetResolution() == IMAGE_RESOLUTION_STANDARD) { - Image m = CachedRescale(img, 2 * img.GetSize(), FILTER_LANCZOS3); - ImageBuffer h(m); - h.SetResolution(IMAGE_RESOLUTION_UHD); - return h; - } + if(img.GetResolution() == IMAGE_RESOLUTION_STANDARD) + return MakeImage(img, Upscale2x); } else { - if(img.GetResolution() == IMAGE_RESOLUTION_UHD) { - Image m = CachedRescale(img, img.GetSize() - 2, FILTER_LANCZOS3); - ImageBuffer h(m); - h.SetResolution(IMAGE_RESOLUTION_UHD); - return h; - } + if(img.GetResolution() == IMAGE_RESOLUTION_UHD) + return MakeImage(img, Downscale2x); } return img; } Image DPI(const Image& img, int expected) { - if(img.GetSize().cy <= expected && IsUHDMode()) { - Image m = CachedRescale(img, 2 * img.GetSize(), FILTER_LANCZOS3); - ImageBuffer h(m); - h.SetResolution(IMAGE_RESOLUTION_UHD); - return h; - } + if(img.GetSize().cy <= expected && IsUHDMode()) + return MakeImage(img, Upscale2x); return img; } diff --git a/uppsrc/Draw/src.tpp/Image$en-us.tpp b/uppsrc/Draw/src.tpp/Image$en-us.tpp index f028242d5..0b13bdaf7 100644 --- a/uppsrc/Draw/src.tpp/Image$en-us.tpp +++ b/uppsrc/Draw/src.tpp/Image$en-us.tpp @@ -291,6 +291,12 @@ mage][@(0.0.255) `&]_[*@3 dest], [_^Point^ Point]_[*@3 p], [@(0.0.255) const]_[_ into Point [%-*@3 p] of Image [%-*@3 dest].&] [s3;%% &] [s4; &] +[s5;:Upp`:`:Over`(Upp`:`:Image`&`,const Upp`:`:Image`&`): [@(0.0.255) void]_[* Over]([_^Upp`:`:Image^ I +mage][@(0.0.255) `&]_[*@3 dest], [@(0.0.255) const]_[_^Upp`:`:Image^ Image][@(0.0.255) `&]_ +[*@3 src])&] +[s2;%% Same as Over([%-*@3 dest], Point(0, 0), [%-*@3 src], [%-*@3 src].GetSize()).&] +[s3;%% &] +[s4; &] [s5;:Fill`(Image`&`,const Rect`&`,RGBA`): [@(0.0.255) void]_[* Fill]([_^Image^ Image][@(0.0.255) `& ]_[*@3 dest], [@(0.0.255) const]_[_^Rect^ Rect][@(0.0.255) `&]_[*@3 rect], [_^RGBA^ RGBA]_[*@3 color])&]