Changeset 8d3512f1 in mainline for uspace/lib/softrend/filter.c


Ignore:
Timestamp:
2014-08-31T14:53:51Z (10 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
00ddb40
Parents:
c6c39d4f
Message:

Implement a bilinear filter and use it when compositing windows.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/softrend/filter.c

    rc6c39d4f r8d3512f1  
    11/*
    22 * Copyright (c) 2012 Petr Koupy
     3 * Copyright (c) 2014 Martin Sucha
    34 * All rights reserved.
    45 *
     
    3536
    3637#include "filter.h"
     38#include <io/pixel.h>
     39
     40static long round(double val)
     41{
     42        return val > 0 ? (long) (val + 0.5) : (long) (val - 0.5);
     43}
     44
     45static long floor(double val)
     46{
     47        long lval = (long) val;
     48        if (val < 0 && lval != val)
     49                return lval - 1;
     50        return lval;
     51}
     52
     53static long ceil(double val)
     54{
     55        long lval = (long) val;
     56        if (val > 0 && lval != val)
     57                return lval + 1;
     58        return lval;
     59}
     60
     61static pixel_t get_pixel(pixelmap_t *pixmap, sysarg_t x, sysarg_t y, bool tile)
     62{
     63        if (tile) {
     64                x %= pixmap->width;
     65                y %= pixmap->height;
     66        }
     67
     68        return pixelmap_get_pixel(pixmap, (sysarg_t) x, (sysarg_t) y);
     69}
     70
     71static inline pixel_t blend_pixels(size_t count, float *weights,
     72    pixel_t *pixels)
     73{
     74        float alpha = 0, red = 0, green = 0, blue = 0;
     75        for (size_t index = 0; index < count; index++) {
     76                alpha += weights[index] * ALPHA(pixels[index]);
     77                red   += weights[index] *   RED(pixels[index]);
     78                green += weights[index] * GREEN(pixels[index]);
     79                blue  += weights[index] *  BLUE(pixels[index]);
     80        }
     81       
     82        return PIXEL((uint8_t) alpha, (uint8_t) red, (uint8_t) green,
     83            (uint8_t) blue);
     84}
    3785
    3886pixel_t filter_nearest(pixelmap_t *pixmap, double x, double y, bool tile)
    3987{
    40         long _x = x > 0 ? (long) (x + 0.5) : (long) (x - 0.5);
    41         long _y = y > 0 ? (long) (y + 0.5) : (long) (y - 0.5);
    42 
    43         if (tile) {
    44                 _x %= pixmap->width;
    45                 _y %= pixmap->height;
    46         }
    47 
    48         return pixelmap_get_pixel(pixmap, (sysarg_t) _x, (sysarg_t) _y);
     88        return get_pixel(pixmap, round(x), round(y), tile);
    4989}
    5090
    5191pixel_t filter_bilinear(pixelmap_t *pixmap, double x, double y, bool tile)
    5292{
    53         // TODO
    54         return 0;
     93        long x1 = floor(x);
     94        long x2 = ceil(x);
     95        long y1 = floor(y);
     96        long y2 = ceil(y);
     97       
     98        if (y1 == y2 && x1 == x2) {
     99                return get_pixel(pixmap, (sysarg_t) x1, (sysarg_t) y1,
     100                    tile);
     101        }
     102       
     103        double x_delta = x - x1;
     104        double y_delta = y - y1;
     105       
     106        pixel_t pixels[4];
     107        pixels[0] = get_pixel(pixmap, x1, y1, tile);
     108        pixels[1] = get_pixel(pixmap, x2, y1, tile);
     109        pixels[2] = get_pixel(pixmap, x1, y2, tile);
     110        pixels[3] = get_pixel(pixmap, x2, y2, tile);
     111       
     112        float weights[4];
     113        weights[0] = (1 - x_delta) * (1 - y_delta);
     114        weights[1] = (    x_delta) * (1 - y_delta);
     115        weights[2] = (1 - x_delta) * (    y_delta);
     116        weights[3] = (    x_delta) * (    y_delta);
     117       
     118        return blend_pixels(4, weights, pixels);
    55119}
    56120
Note: See TracChangeset for help on using the changeset viewer.