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.