From 767cbb9a98b89a6d2ad44300ef897928f87bb3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net> Date: Thu, 13 May 2021 20:59:10 -0400 Subject: [PATCH] Many X11 scaling improvements... 1) Initialize the r2y array for xBR so it actually works. 2) Add a vertical (only) interpolation scaler for aspect ratio enforcement 3) Add a simple muliplier scaler, so that can be removed from x_event.c 4) Use a new graphics buffer free list, which allows tracking last drawn screen instead of last bitmap rectangle, removing various hacks 5) Share the Y'CbCr <-> R'dG'dB'd tables between xBR and scale.c --- src/conio/bitmap_con.c | 2 + src/conio/scale.c | 361 +++++++++++++++++++++++++++++++++-------- src/conio/scale.h | 17 +- src/conio/x_events.c | 143 +++++++--------- src/conio/xbr.c | 10 +- 5 files changed, 378 insertions(+), 155 deletions(-) diff --git a/src/conio/bitmap_con.c b/src/conio/bitmap_con.c index 9187c52a79..7f5615ddff 100644 --- a/src/conio/bitmap_con.c +++ b/src/conio/bitmap_con.c @@ -11,6 +11,7 @@ #include "genwrap.h" #include "dirwrap.h" #include "xpbeep.h" +#include "scale.h" #if (defined CIOLIB_IMPORTS) #undef CIOLIB_IMPORTS @@ -1664,6 +1665,7 @@ int bitmap_drv_init(void (*drawrect_cb) (struct rectlist *data) pthread_mutex_init(&screenb.screenlock, NULL); pthread_mutex_init(&free_rect_lock, NULL); pthread_mutex_lock(&vstatlock); + init_r2y(); vstat.vmem=NULL; vstat.flags = VIDMODES_FLAG_PALETTE_VMEM; pthread_mutex_lock(&screena.screenlock); diff --git a/src/conio/scale.c b/src/conio/scale.c index ff9fc37c58..880822e38c 100644 --- a/src/conio/scale.c +++ b/src/conio/scale.c @@ -1,34 +1,113 @@ #include "scale.h" #include "xbr.h" +uint32_t r2y[1<<24]; +uint32_t y2r[1<<24]; +static int r2y_inited; + static void pointy_scale3(uint32_t* src, uint32_t* dest, int width, int height); static void pointy_scale5(uint32_t* src, uint32_t* dest, int width, int height); +static void interpolate_height(uint32_t* src, uint32_t* dst, int width, int height, int newheight); +static void multiply_scale(uint32_t* src, uint32_t* dst, int width, int height, int xmult, int ymult); + +static struct graphics_buffer *free_list; + +#define CLAMP(x) do { \ + if (x < 0) \ + x = 0; \ + else if (x > 255) \ + x = 255; \ +} while(0) + +void +init_r2y(void) +{ + int r, g, b; + int y, u, v; + const double luma = 255.0 / 219; + const double col = 255.0 / 224; + + if (r2y_inited) + return; + for (r = 0; r < 256; r++) { + for (g = 0; g < 256; g++) { + for (b = 0; b < 256; b++) { + y = 16 + ( 65.738 * r + 129.057 * g + 25.064 * b + 128) / 256; + CLAMP(y); + u = 128 + (-37.945 * r - 74.494 * g + 112.439 * b + 128) / 256; + CLAMP(u); + v = 128 + (112.439 * r - 94.154 * g - 18.285 * b + 128) / 256; + CLAMP(v); + + r2y[(r<<16) | (g<<8) | b] = (y<<16)|(u<<8)|v; + } + } + } + for (y = 0; y < 256; y++) { + for (u = 0; u < 256; u++) { + for (v = 0; v < 256; v++) { + const int c = y - 16; + const int d = u - 128; + const int e = v - 128; + r = luma * c + col * 1.402 * e; + CLAMP(r); + g = luma * c - col * 1.772 * (0.114 / 0.587) * d - col * 1.402 * (0.299 / 0.587) * e; + CLAMP(g); + b = luma * c + col * 1.772 * d; + CLAMP(b); -uint32_t* -do_scale(struct rectlist* rect, uint32_t **target, size_t *targetsz, int* xscale, int* yscale, int* w, int* h) + y2r[(y<<16) | (u<<8) | v] = (r<<16)|(g<<8)|b; + } + } + } + r2y_inited = 1; +} + +struct graphics_buffer * +get_buffer(void) { + struct graphics_buffer* ret = NULL; + + if (free_list) { + ret = free_list; + free_list = free_list->next; + ret->next = NULL; + return ret; + } + + ret = calloc(1, sizeof(struct graphics_buffer)); + return ret; +} + +void +release_buffer(struct graphics_buffer *buf) +{ + buf->next = free_list; + free_list = buf; +} + +struct graphics_buffer * +do_scale(struct rectlist* rect, int* xscale, int* yscale, double ratio) +{ + struct graphics_buffer* ret1 = get_buffer(); + struct graphics_buffer* ret2 = get_buffer(); int pointy5 = 0; int pointy3 = 0; int xbr2 = 0; int xbr4 = 0; + int ymult = 1; + int xmult = 1; int newscale = 1; - int total_scaling = 1; - static uint32_t *tmptarget = NULL; - static size_t tmptargetsz = 0; - uint32_t *ctarget; - uint32_t *csrc = rect->data; + int total_xscaling = 1; + int total_yscaling = 1; + struct graphics_buffer *ctarget; + struct graphics_buffer *csrc; uint32_t* nt; - int swidth = rect->rect.width; - int sheight = rect->rect.height; - - *w = rect->rect.width; - *h = rect->rect.height; - // As a first pass, only do equal integer scaling - if (*xscale != *yscale) - return rect->data; + int fheight; + switch (*xscale) { case 1: - return rect->data; + break; case 2: xbr2 = 1; break; @@ -45,105 +124,155 @@ do_scale(struct rectlist* rect, uint32_t **target, size_t *targetsz, int* xscale pointy3 = 1; xbr2 = 1; break; + case 7: // TODO: Do we want a pointy7 and pointy11? + xmult = 7; + ymult = 7; + break; default: - total_scaling = *xscale; + total_xscaling = *xscale; *xscale = 1; - while (total_scaling > 1 && ((total_scaling % 5) == 0)) { + total_yscaling = *yscale; + *yscale = 1; + while (total_xscaling > 1 && ((total_xscaling % 5) == 0) && ((total_yscaling % 5) == 0)) { pointy5++; - total_scaling /= 5; + total_xscaling /= 5; *xscale *= 5; + total_yscaling /= 5; + *yscale *= 5; } - while (total_scaling > 1 && ((total_scaling % 3) == 0)) { + while (total_xscaling > 1 && ((total_xscaling % 3) == 0) && ((total_yscaling % 3) == 0)) { pointy3++; - total_scaling /= 3; + total_xscaling /= 3; *xscale *= 3; + total_yscaling /= 3; + *yscale *= 3; } - while (total_scaling > 1 && ((total_scaling % 4) == 0)) { + while (total_xscaling > 1 && ((total_xscaling % 4) == 0) && ((total_yscaling % 4) == 0)) { xbr4++; - total_scaling /= 4; + total_xscaling /= 4; *xscale *= 4; + total_yscaling /= 4; + *yscale *= 4; } - while (total_scaling > 1 && ((total_scaling % 2) == 0)) { + while (total_xscaling > 1 && ((total_xscaling % 2) == 0) && ((total_yscaling % 2) == 0)) { xbr2++; - total_scaling /= 2; + total_xscaling /= 2; *xscale *= 2; + total_yscaling /= 2; + *yscale *= 2; } - if (*xscale == 1) - return rect->data; break; } + if (*xscale != *yscale) { + if (*yscale == *xscale * 2) + ymult *= 2; + else + return NULL; + } + + // Calculate the scaled height from ratio... + fheight = lround((double)(rect->rect.height * (*yscale)) / ratio); + // Now make sure target is big enough... - size_t needsz = rect->rect.width * rect->rect.height * (*xscale) * (*xscale) * sizeof(uint32_t); - if (needsz > *targetsz) { - nt = realloc(*target, needsz); + size_t needsz = rect->rect.width * (*xscale) * fheight * sizeof(uint32_t); + if (needsz > ret1->sz) { + nt = realloc(ret1->data, needsz); if (nt == NULL) - return rect->data; - *target = nt; - *targetsz = needsz; + return NULL; + ret1->data = nt; + ret1->sz = needsz; } - ctarget = *target; - - // And if we need an extra target, do the same there... - if (pointy3 + pointy5 + xbr4 + xbr2 > 1) { - if (needsz > tmptargetsz) { - nt = realloc(tmptarget, needsz); - if (nt == NULL) - return rect->data; - tmptarget = nt; - tmptargetsz = needsz; - } + + if (needsz > ret2->sz) { + nt = realloc(ret2->data, needsz); + if (nt == NULL) + return NULL; + ret2->data = nt; + ret2->sz = needsz; } - // And finally, scale... + // Copy rect into first buffer + // TODO: Unify bitmap rects and scaling buffers so this can just whomp on over. + csrc = ret1; + ctarget = ret2; + memcpy(csrc->data, rect->data, rect->rect.width * rect->rect.height * sizeof(rect->data[0])); + csrc->w = rect->rect.width; + csrc->h = rect->rect.height; + + // And scale... + if (ymult != 1 || xmult != 1) { + multiply_scale(csrc->data, ctarget->data, csrc->w, csrc->h, xmult, ymult); + ctarget->w = csrc->w * xmult; + ctarget->h = csrc->h * ymult; + ymult = 1; + xmult = 1; + csrc = ctarget; + if (ctarget == ret1) + ctarget = ret2; + else + ctarget = ret1; + } while (xbr4 > 0) { - xbr_filter(csrc, ctarget, swidth, sheight, 4); + xbr_filter(csrc->data, ctarget->data, csrc->w, csrc->h, 4); xbr4--; - swidth *= 4; - sheight *= 4; + ctarget->w = csrc->w * 4; + ctarget->h = csrc->h * 4; csrc = ctarget; - if (ctarget == tmptarget) - ctarget = *target; + if (ctarget == ret1) + ctarget = ret2; else - ctarget = tmptarget; + ctarget = ret1; } while (xbr2 > 0) { - xbr_filter(csrc, ctarget, swidth, sheight, 2); + xbr_filter(csrc->data, ctarget->data, csrc->w, csrc->h, 2); xbr2--; - swidth *= 2; - sheight *= 2; + ctarget->w = csrc->w * 2; + ctarget->h = csrc->h * 2; csrc = ctarget; - if (ctarget == tmptarget) - ctarget = *target; + if (ctarget == ret1) + ctarget = ret2; else - ctarget = tmptarget; + ctarget = ret1; } while (pointy5 > 0) { - pointy_scale5(csrc, ctarget, swidth, sheight); + pointy_scale5(csrc->data, ctarget->data, csrc->w, csrc->h); pointy5--; - swidth *= 5; - sheight *= 5; + ctarget->w = csrc->w * 5; + ctarget->h = csrc->h * 5; csrc = ctarget; - if (ctarget == tmptarget) - ctarget = *target; + if (ctarget == ret1) + ctarget = ret2; else - ctarget = tmptarget; + ctarget = ret1; } while (pointy3 > 0) { - pointy_scale3(csrc, ctarget, swidth, sheight); + pointy_scale3(csrc->data, ctarget->data, csrc->w, csrc->h); pointy3--; - swidth *= 3; - sheight *= 3; + ctarget->w = csrc->w * 3; + ctarget->h = csrc->h * 3; csrc = ctarget; - if (ctarget == tmptarget) - ctarget = *target; + if (ctarget == ret1) + ctarget = ret2; else - ctarget = tmptarget; + ctarget = ret1; } - *w *= *xscale; - *h *= *xscale; + + // And finally, interpolate if needed + if (ratio != 1) { + interpolate_height(csrc->data, ctarget->data, csrc->w, csrc->h, fheight); + ctarget->h = fheight; + ctarget->w = csrc->w; + csrc = ctarget; + if (ctarget == ret1) + ctarget = ret2; + else + ctarget = ret1; + } + *xscale = newscale; *yscale = newscale; + release_buffer(ctarget); return csrc; } @@ -339,3 +468,93 @@ pointy_scale3(uint32_t* src, uint32_t* dest, int width, int height) prevline = -width; } } + +static __attribute__((always_inline)) +uint32_t blend(const uint32_t c1, const uint32_t c2, const double weight) +{ + uint8_t yuv1[4]; + uint8_t yuv2[4]; + int y, u, v; + const double iw = 1.0 - weight; + + *(uint32_t *)yuv1 = r2y[c1]; + *(uint32_t *)yuv2 = r2y[c2]; +#ifdef __BIG_ENDIAN__ + y = yuv1[1] * iw + yuv2[1] * weight; + u = yuv1[2] * iw + yuv2[2] * weight; + v = yuv1[3] * iw + yuv2[3] * weight; +#else + y = yuv1[2] * iw + yuv2[2] * weight; + u = yuv1[1] * iw + yuv2[1] * weight; + v = yuv1[0] * iw + yuv2[0] * weight; +#endif + CLAMP(y); + CLAMP(u); + CLAMP(v); + + return y2r[(y<<16)|(u<<8)|v]; +} + +/* + * This does non-integer *height* scaling. It does not scale in the other + * direction. This does the interpolation using Y'UV to prevent dimming of + * pixels. + */ +static void +interpolate_height(uint32_t* src, uint32_t* dst, int width, int height, int newheight) +{ + int x, y; + const double mult = (double)height / newheight; + + for (y = 0; y < newheight; y++) { + for (x = 0; x < width; x++) { + // First, calculate which two pixels this is between. + const double ypos = mult * y; + const int yposi = ypos; + if (y == ypos) { + // Exact match! + *dst = src[width * yposi + x]; + } + else { + const double weight = ypos - yposi; + // Now pick the two pixels + const uint32_t pix1 = src[yposi * width + x] & 0xffffff; + uint32_t pix2; + if (yposi < height - 1) + pix2 = src[(yposi + 1) * width + x] & 0xffffff; + else + pix2 = src[yposi * width + x] & 0xffffff; + if (pix1 == pix2) + *dst = pix1; + else { + *dst = blend(pix1, pix2, weight); + } + } + dst++; + } + } +} + +static void +multiply_scale(uint32_t* src, uint32_t* dst, int width, int height, int xmult, int ymult) +{ + int nheight = height * ymult; + int nwidth = width * xmult; + int x, y; + int mx, my; + uint32_t* slstart; + + for (y = 0; y < height; y++) { + slstart = src; + for (my = 0; my < ymult; my++) { + src = slstart; + for (x = 0; x < width; x++) { + for (mx = 0; mx < xmult; mx++) { + *dst = *src; + dst++; + } + src++; + } + } + } +} diff --git a/src/conio/scale.h b/src/conio/scale.h index b867d034b6..2d30202adf 100644 --- a/src/conio/scale.h +++ b/src/conio/scale.h @@ -1,3 +1,18 @@ #include "bitmap_con.h" -uint32_t* do_scale(struct rectlist* rect, uint32_t **target, size_t *targetsz, int* xscale, int* yscale, int* w, int* h); +struct graphics_buffer { + uint32_t* data; + size_t sz; + size_t w; + size_t h; + struct graphics_buffer *next; +}; + +extern uint32_t r2y[1<<24]; +extern uint32_t y2r[1<<24]; + +struct graphics_buffer * get_buffer(void); +void release_buffer(struct graphics_buffer *); +void init_r2y(void); + +struct graphics_buffer * do_scale(struct rectlist* rect, int* xscale, int* yscale, double ratio); diff --git a/src/conio/x_events.c b/src/conio/x_events.c index e3014eedf5..bd21f53cc8 100644 --- a/src/conio/x_events.c +++ b/src/conio/x_events.c @@ -85,7 +85,7 @@ static unsigned long base_pixel; static int r_shift; static int g_shift; static int b_shift; -static struct rectlist *last = NULL; +static struct graphics_buffer *last = NULL; /* Array of Graphics Contexts */ static GC gc; @@ -208,9 +208,13 @@ static struct { static void resize_xim(void) { + int width = bitmap_width * x_cvstat.scaling; + double ratio = (double)x_cvstat.scale_numerator / x_cvstat.scale_denominator; + int height = lround((double)(bitmap_height * x_cvstat.scaling * x_cvstat.vmultiplier) / ratio); + if (xim) { - if (bitmap_width*x_cvstat.scaling == xim->width - && bitmap_height*x_cvstat.scaling*x_cvstat.vmultiplier == xim->height) { + if (width == xim->width + && height == xim->height) { return; } #ifdef XDestroyImage @@ -220,11 +224,11 @@ static void resize_xim(void) #endif } if (last) { - bitmap_drv_free_rect(last); + release_buffer(last); last = NULL; } - xim=x11.XCreateImage(dpy,&visual,depth,ZPixmap,0,NULL,bitmap_width*x_cvstat.scaling,bitmap_height*x_cvstat.scaling*x_cvstat.vmultiplier,32,0); - xim->data=(char *)malloc(xim->bytes_per_line*xim->height); + xim = x11.XCreateImage(dpy, &visual, depth, ZPixmap, 0, NULL, width, height, 32, 0); + xim->data=(char *)calloc(1, xim->bytes_per_line*xim->height); } /* Swiped from FreeBSD libc */ @@ -346,6 +350,7 @@ static int init_window() static void map_window() { XSizeHints *sh; + int scaled_height; sh = x11.XAllocSizeHints(); if (sh == NULL) { @@ -357,7 +362,9 @@ static void map_window() sh->base_height = bitmap_height*x_cvstat.scaling*x_cvstat.vmultiplier; sh->min_width = sh->width_inc = sh->min_aspect.x = sh->max_aspect.x = bitmap_width; - sh->min_height = sh->height_inc = sh->min_aspect.y = sh->max_aspect.y = bitmap_height; + + scaled_height = ceil((double)bitmap_height*x_cvstat.vmultiplier / ((double)x_cvstat.scale_numerator / x_cvstat.scale_denominator)); + sh->min_height = sh->height_inc = sh->min_aspect.y = sh->max_aspect.y = scaled_height; sh->flags = USSize | PMinSize | PSize | PResizeInc | PAspect; x11.XSetWMNormalHints(dpy, win, sh); @@ -371,10 +378,11 @@ static void map_window() /* Resize the window. This function is called after a mode change. */ static void resize_window() { - x11.XResizeWindow(dpy, win, bitmap_width*x_cvstat.scaling, bitmap_height*x_cvstat.scaling*x_cvstat.vmultiplier); - resize_xim(); + int scaled_height = ceil((double)bitmap_height*x_cvstat.scaling*x_cvstat.vmultiplier / ((double)x_cvstat.scale_numerator / x_cvstat.scale_denominator)); + x11.XResizeWindow(dpy, win, bitmap_width*x_cvstat.scaling, scaled_height); + resize_xim(); - return; + return; } static void init_mode_internal(int mode) @@ -386,7 +394,7 @@ static void init_mode_internal(int mode) pthread_mutex_lock(&blinker_lock); pthread_mutex_lock(&vstatlock); if (last) { - bitmap_drv_free_rect(last); + release_buffer(last); last = NULL; } bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height); @@ -451,7 +459,6 @@ static void local_draw_rect(struct rectlist *rect) { int x,y,xscale,yscale,xoff=0,yoff=0; int xscaling, yscaling; - int rxscaling, ryscaling; unsigned int r, g, b; unsigned long pixel; int cleft; @@ -459,14 +466,9 @@ static void local_draw_rect(struct rectlist *rect) int ctop; int cbottom = -1; int idx; - int ridx; - int ridx_part; uint32_t last_pixel = 0x55555555; - static uint32_t* target = NULL; - size_t targetsz = 0; - uint32_t* source; - int width, height; - int lheight, lines; + struct graphics_buffer *source; + int lines; if (bitmap_width != rect->rect.width || bitmap_height != rect->rect.height) return; @@ -481,23 +483,32 @@ static void local_draw_rect(struct rectlist *rect) // Scale... xscaling = x_cvstat.scaling; yscaling = x_cvstat.scaling*x_cvstat.vmultiplier; - source = do_scale(rect, &target, &targetsz, &xscaling, &yscaling, &width, &height); - rxscaling = width / rect->rect.width; - ryscaling = height / rect->rect.height; - cleft = width; - ctop = height; + source = do_scale(rect, &xscaling, &yscaling, (double)x_cvstat.scale_numerator / x_cvstat.scale_denominator); + bitmap_drv_free_rect(rect); + if (source == NULL) + return; + cleft = source->w; + ctop = source->h; lines = 0; - lheight = x_cvstat.charheight * ryscaling; + + xoff = (x11_window_width - source->w) / 2; + if (xoff < 0) + xoff = 0; + yoff = (x11_window_height - source->h) / 2; + if (yoff < 0) + yoff = 0; + + if (last && (last->w != source->w || last->h != source->h)) { + release_buffer(last); + last = NULL; + } /* TODO: Translate into local colour depth */ - for(y=0;y<height;y++) { - idx = y * width; - ridx = y / ryscaling * rect->rect.width; - ridx_part = 0; - for(x=0; x<width; x++) { + idx = 0; + for (y = 0; y < source->h; y++) { + for (x = 0; x < source->w; x++) { if (last) { - // TODO: Based on source pixel, not target pixel. :( - if (last->data[ridx] != rect->data[ridx]) { + if (last->data[idx] != source->data[idx]) { if (x < cleft) cleft = x; if (x > cright) @@ -508,29 +519,15 @@ static void local_draw_rect(struct rectlist *rect) cbottom = y; } else { - if (source == rect->data) { - idx += (rxscaling); - x += (rxscaling - 1); - ridx++; - continue; - } - else { - if (cright < x - rxscaling * 2 - && (x >= width - (rxscaling * 3) - || last->data[ridx + 1] == rect->data[ridx + 1])) { - idx += (rxscaling); - x += (rxscaling - 1); - ridx++; - continue; - } - } + idx++; + continue; } } - if (last_pixel != source[idx]) { - last_pixel = source[idx]; - r = source[idx] >> 16 & 0xff; - g = source[idx] >> 8 & 0xff; - b = source[idx] & 0xff; + if (last_pixel != source->data[idx]) { + last_pixel = source->data[idx]; + r = source->data[idx] >> 16 & 0xff; + g = source->data[idx] >> 8 & 0xff; + b = source->data[idx] & 0xff; r = (r<<8)|r; g = (g<<8)|g; b = (b<<8)|b; @@ -560,54 +557,36 @@ static void local_draw_rect(struct rectlist *rect) } } idx++; - ridx_part++; - if (ridx_part >= rxscaling) { - ridx_part = 0; - ridx++; - } } lines++; /* This line was changed */ - if (last && ((lines == lheight) || (y == height - 1)) && cright >= 0) { -#ifdef USE_XBRZ - if (source != rect->data) { - cleft -= 2 * rxscaling; - if (cleft < 0) - cleft = 0; - cright += 2 * rxscaling; - if (cright >= width) - cright = width - 1; - } -#endif + // TODO: Previously this did one update per display line... + if (last && (cbottom != y || y == source->h - 1) && cright >= 0) { lines = 0; x11.XPutImage(dpy, win, gc, xim, cleft * xscaling, ctop * yscaling , cleft * xscaling + xoff, ctop * yscaling + yoff , (cright - cleft + 1) * xscaling, (cbottom - ctop + 1) * yscaling); - cleft = width; + cleft = source->w; cright = cbottom = -100; - ctop = height; + ctop = source->h; } } if (last == NULL) - x11.XPutImage(dpy, win, gc, xim, rect->rect.x*xscaling, rect->rect.y*yscaling, rect->rect.x*xscaling + xoff, rect->rect.y*yscaling + yoff, width * xscaling, height * yscaling); + x11.XPutImage(dpy, win, gc, xim, rect->rect.x*xscaling, rect->rect.y*yscaling, rect->rect.x*xscaling + xoff, rect->rect.y*yscaling + yoff, source->w * xscaling, source->h * yscaling); else - bitmap_drv_free_rect(last); - last = rect; + release_buffer(last); + last = source; } static void handle_resize_event(int width, int height) { int newFSH=1; int newFSW=1; - - // No change - if((width == x_cvstat.charwidth * x_cvstat.cols * x_cvstat.scaling) - && (height == x_cvstat.charheight * x_cvstat.rows * x_cvstat.scaling*x_cvstat.vmultiplier)) - return; + double ratio = (double)x_cvstat.scale_numerator / x_cvstat.scale_denominator; newFSH=width/bitmap_width; - newFSW=height/bitmap_height; + newFSW=floor((double)height / bitmap_height * ratio); if(newFSW<1) newFSW=1; if(newFSH<1) @@ -627,9 +606,11 @@ static void handle_resize_event(int width, int height) */ if (newFSH != newFSW) resize_window(); +#if 0 // TODO: Is this even worth looking at? else if((width % (x_cvstat.charwidth * x_cvstat.cols) != 0) || (height % (x_cvstat.charheight * x_cvstat.rows) != 0)) resize_window(); +#endif else resize_xim(); bitmap_drv_request_pixels(); @@ -680,7 +661,7 @@ static void expose_rect(int x, int y, int width, int height) /* Since we're exposing, we *have* to redraw */ if (last) { - bitmap_drv_free_rect(last); + release_buffer(last); last = NULL; bitmap_drv_request_some_pixels(sx, sy, ex-sx+1, ey-sy+1); } diff --git a/src/conio/xbr.c b/src/conio/xbr.c index 64211daea2..60331c2b7d 100644 --- a/src/conio/xbr.c +++ b/src/conio/xbr.c @@ -30,6 +30,7 @@ #include <inttypes.h> #include <stdlib.h> +#include "scale.h" #define LB_MASK 0x00FEFEFE #define RED_BLUE_MASK 0x00FF00FF @@ -39,8 +40,6 @@ #undef PI #endif -uint32_t r2y[1<<24]; - static uint32_t pixel_diff(uint32_t x, uint32_t y) { #define YMASK 0xff0000 @@ -190,6 +189,13 @@ static uint32_t pixel_diff(uint32_t x, uint32_t y) } \ } while (0) +#define CLAMP(x) do { \ + if (x < 0) \ + x = 0; \ + else if (x > 255) \ + x = 255; \ +} while(0) + void xbr_filter(uint32_t *data, uint32_t *out, int width, int height, int n) { -- GitLab