Ignore:
Timestamp:
Aug 28, 2008 10:38:52 PM (6 years ago)
Author:
sam
Message:
  • Rework the convolution template system.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libpipi/trunk/pipi/filter/convolution.c

    r2710 r2793  
    2828#include "pipi_internals.h"
    2929
    30 #define FLAG_GRAY ((FLAGS) & SET_FLAG_GRAY)
    31 #define FLAG_WRAP ((FLAGS) & SET_FLAG_WRAP)
    32 
    33 #define SET_FLAG_GRAY 0x01
    34 #define SET_FLAG_WRAP 0x02
    35 
    36 #undef FUNC1
    37 #undef FUNC2
    38 #undef PIXEL
    39 #undef FLAGS
    40 #define FUNC1 conv_std_rgba_f
    41 #define FUNC2 conv_sep_rgba_f
    42 #define PIXEL float
    43 #define FLAGS 0
    44 #include "convolution_template.h"
    45 
    46 #undef FUNC1
    47 #undef FUNC2
    48 #undef PIXEL
    49 #undef FLAGS
    50 #define FUNC1 conv_std_y_f
    51 #define FUNC2 conv_sep_y_f
    52 #define PIXEL float
    53 #define FLAGS SET_FLAG_GRAY
    54 #include "convolution_template.h"
    55 
    56 #undef FUNC1
    57 #undef FUNC2
    58 #undef PIXEL
    59 #undef FLAGS
    60 #define FUNC1 wrap_std_rgba_f
    61 #define FUNC2 wrap_sep_rgba_f
    62 #define PIXEL float
    63 #define FLAGS SET_FLAG_WRAP
    64 #include "convolution_template.h"
    65 
    66 #undef FUNC1
    67 #undef FUNC2
    68 #undef PIXEL
    69 #undef FLAGS
    70 #define FUNC1 wrap_std_y_f
    71 #define FUNC2 wrap_sep_y_f
    72 #define PIXEL float
    73 #define FLAGS SET_FLAG_GRAY|SET_FLAG_WRAP
    74 #include "convolution_template.h"
     30#if !defined TEMPLATE_FILE /* This file uses the template system */
     31#define TEMPLATE_FLAGS SET_FLAG_GRAY | SET_FLAG_WRAP
     32#define TEMPLATE_FILE "filter/convolution.c"
     33#include "pipi_template.h"
    7534
    7635pipi_image_t *pipi_convolution(pipi_image_t *src, int m, int n, double mat[])
     
    11675                {
    11776                    if(src->wrap)
    118                         return wrap_std_y_f(src, m, n, mat);
    119                     return conv_std_y_f(src, m, n, mat);
     77                        return conv_gray_wrap(src, m, n, mat);
     78                    return conv_gray(src, m, n, mat);
    12079                }
    12180                else
    12281                {
    12382                    if(src->wrap)
    124                         return wrap_std_rgba_f(src, m, n, mat);
    125                     return conv_std_rgba_f(src, m, n, mat);
     83                        return conv_wrap(src, m, n, mat);
     84                    return conv(src, m, n, mat);
    12685                }
    12786            }
     
    14099
    141100    if(src->last_modified == PIPI_PIXELS_Y_F)
    142         ret = src->wrap ? wrap_sep_y_f(src, m, hvec, n, vvec)
    143                         : conv_sep_y_f(src, m, hvec, n, vvec);
     101        ret = src->wrap ? sepconv_gray_wrap(src, m, hvec, n, vvec)
     102                        : sepconv_gray(src, m, hvec, n, vvec);
    144103    else
    145         ret = src->wrap ? wrap_sep_rgba_f(src, m, hvec, n, vvec)
    146                         : conv_sep_rgba_f(src, m, hvec, n, vvec);
     104        ret = src->wrap ? sepconv_wrap(src, m, hvec, n, vvec)
     105                        : sepconv(src, m, hvec, n, vvec);
    147106
    148107    free(hvec);
     
    152111}
    153112
     113#else /* XXX: the following functions use the template system */
     114
     115static pipi_image_t *SUFFIX(conv)(pipi_image_t *src,
     116                                  int m, int n, double mat[])
     117{
     118    pipi_image_t *dst;
     119    pipi_pixels_t *srcp, *dstp;
     120    float *srcdata, *dstdata;
     121    int x, y, i, j, w, h;
     122
     123    w = src->w;
     124    h = src->h;
     125
     126    srcp = FLAG_GRAY ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
     127                     : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
     128    srcdata = (float *)srcp->pixels;
     129
     130    dst = pipi_new(w, h);
     131    dstp = FLAG_GRAY ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
     132                     : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
     133    dstdata = (float *)dstp->pixels;
     134
     135    for(y = 0; y < h; y++)
     136    {
     137        for(x = 0; x < w; x++)
     138        {
     139            if(FLAG_GRAY)
     140            {
     141                double Y = 0.;
     142                int x2, y2;
     143
     144                for(j = 0; j < n; j++)
     145                {
     146                    y2 = y + j - n / 2;
     147                    if(y2 < 0) y2 = FLAG_WRAP ? h - 1 - ((-y2 - 1) % h) : 0;
     148                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
     149
     150                    for(i = 0; i < m; i++)
     151                    {
     152                        x2 = x + i - m / 2;
     153                        if(x2 < 0) x2 = FLAG_WRAP ? w - 1 - ((-x2 - 1) % w) : 0;
     154                        else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
     155
     156                        Y += mat[j * m + i] * srcdata[y2 * w + x2];
     157                    }
     158                }
     159
     160                dstdata[y * w + x] = Y < 0.0 ? 0.0 : Y > 1.0 ? 1.0 : Y;
     161            }
     162            else
     163            {
     164                double R = 0., G = 0., B = 0.;
     165                int x2, y2, off = 4 * (y * w + x);
     166
     167                for(j = 0; j < n; j++)
     168                {
     169                    y2 = y + j - n / 2;
     170                    if(y2 < 0) y2 = FLAG_WRAP ? h - 1 - ((-y2 - 1) % h) : 0;
     171                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
     172
     173                    for(i = 0; i < m; i++)
     174                    {
     175                        double f = mat[j * m + i];
     176
     177                        x2 = x + i - m / 2;
     178                        if(x2 < 0) x2 = FLAG_WRAP ? w - 1 - ((-x2 - 1) % w) : 0;
     179                        else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
     180
     181                        R += f * srcdata[(y2 * w + x2) * 4];
     182                        G += f * srcdata[(y2 * w + x2) * 4 + 1];
     183                        B += f * srcdata[(y2 * w + x2) * 4 + 2];
     184                    }
     185                }
     186
     187                dstdata[off] = R < 0.0 ? 0.0 : R > 1.0 ? 1.0 : R;
     188                dstdata[off + 1] = G < 0.0 ? 0.0 : G > 1.0 ? 1.0 : G;
     189                dstdata[off + 2] = B < 0.0 ? 0.0 : B > 1.0 ? 1.0 : B;
     190            }
     191        }
     192    }
     193
     194    return dst;
     195}
     196
     197static pipi_image_t *SUFFIX(sepconv)(pipi_image_t *src,
     198                            int m, double hvec[], int n, double vvec[])
     199{
     200    pipi_image_t *dst;
     201    pipi_pixels_t *srcp, *dstp;
     202    float *srcdata, *dstdata;
     203    double *buffer;
     204    int x, y, i, j, w, h;
     205
     206    w = src->w;
     207    h = src->h;
     208
     209    srcp = FLAG_GRAY ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
     210                     : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
     211    srcdata = (float *)srcp->pixels;
     212
     213    dst = pipi_new(w, h);
     214    dstp = FLAG_GRAY ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
     215                     : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
     216    dstdata = (float *)dstp->pixels;
     217
     218    buffer = malloc(w * h * (FLAG_GRAY ? 1 : 4) * sizeof(double));
     219
     220    for(y = 0; y < h; y++)
     221    {
     222        for(x = 0; x < w; x++)
     223        {
     224            if(FLAG_GRAY)
     225            {
     226                double Y = 0.;
     227                int x2;
     228
     229                for(i = 0; i < m; i++)
     230                {
     231                    x2 = x + i - m / 2;
     232                    if(x2 < 0) x2 = FLAG_WRAP ? w - 1 - ((-x2 - 1) % w) : 0;
     233                    else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
     234
     235                    Y += hvec[i] * srcdata[y * w + x2];
     236                }
     237
     238                buffer[y * w + x] = Y;
     239            }
     240            else
     241            {
     242                double R = 0., G = 0., B = 0.;
     243                int x2, off = 4 * (y * w + x);
     244
     245                for(i = 0; i < m; i++)
     246                {
     247                    double f = hvec[i];
     248
     249                    x2 = x + i - m / 2;
     250                    if(x2 < 0) x2 = FLAG_WRAP ? w - 1 - ((-x2 - 1) % w) : 0;
     251                    else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
     252
     253                    R += f * srcdata[(y * w + x2) * 4];
     254                    G += f * srcdata[(y * w + x2) * 4 + 1];
     255                    B += f * srcdata[(y * w + x2) * 4 + 2];
     256                }
     257
     258                buffer[off] = R;
     259                buffer[off + 1] = G;
     260                buffer[off + 2] = B;
     261            }
     262        }
     263    }
     264
     265    for(y = 0; y < h; y++)
     266    {
     267        for(x = 0; x < w; x++)
     268        {
     269            if(FLAG_GRAY)
     270            {
     271                double Y = 0.;
     272                int y2;
     273
     274                for(j = 0; j < n; j++)
     275                {
     276                    y2 = y + j - n / 2;
     277                    if(y2 < 0) y2 = FLAG_WRAP ? h - 1 - ((-y2 - 1) % h) : 0;
     278                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
     279
     280                    Y += vvec[j] * buffer[y2 * w + x];
     281                }
     282
     283                dstdata[y * w + x] = Y < 0.0 ? 0.0 : Y > 1.0 ? 1.0 : Y;
     284            }
     285            else
     286            {
     287                double R = 0., G = 0., B = 0.;
     288                int y2, off = 4 * (y * w + x);
     289
     290                for(j = 0; j < n; j++)
     291                {
     292                    double f = vvec[j];
     293
     294                    y2 = y + j - n / 2;
     295                    if(y2 < 0) y2 = FLAG_WRAP ? h - 1 - ((-y2 - 1) % h) : 0;
     296                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
     297
     298                    R += f * buffer[(y2 * w + x) * 4];
     299                    G += f * buffer[(y2 * w + x) * 4 + 1];
     300                    B += f * buffer[(y2 * w + x) * 4 + 2];
     301                }
     302
     303                dstdata[off] = R < 0.0 ? 0.0 : R > 1.0 ? 1.0 : R;
     304                dstdata[off + 1] = G < 0.0 ? 0.0 : G > 1.0 ? 1.0 : G;
     305                dstdata[off + 2] = B < 0.0 ? 0.0 : B > 1.0 ? 1.0 : B;
     306            }
     307        }
     308    }
     309
     310    free(buffer);
     311
     312    return dst;
     313}
     314
     315#endif
     316
Note: See TracChangeset for help on using the changeset viewer.