1. gint fp_median_nxn_filter_process(guchar *src, guchar *dest, gint srcW, gint srcH, gint srcChannels, gint srcRowstride, ...)
  2. {
  3. //Checks
  4. g_return_val_if_fail(src!=NULL, -1);
  5. g_return_val_if_fail(dest!=NULL, -2);
  6.  
  7. //Window
  8. gint N, offset;
  9.  
  10. //Arguments
  11. va_list flags;
  12. va_start(flags, srcRowstride);
  13. N = va_arg(flags, gint);
  14. va_end(flags);
  15. offset = N/2;
  16. if(N%2==0)
  17. printf("WARN: Asymmetric window.\n");
  18.  
  19. //Proper
  20. int x, y, nx, ny, accum_r, accum_g, accum_b, dpix, winsize=N*N;
  21. guchar *s;
  22. for(x=0;x<srcW;x++)
  23. for(y=0;y<srcH;y++)
  24. {
  25. if(x<=N||y<=N||x>=srcW-N||y>=srcH-N)continue; //FIXME: Ignore borders.
  26. accum_r=accum_g=accum_b=0;
  27. for(nx=0;nx<N;nx++)
  28. for(ny=0;ny<N;ny++)
  29. {
  30. s=src+(srcChannels*(x-offset+nx))+(srcRowstride*(y-offset+ny));
  31. accum_r+=s[0];
  32. accum_g+=s[1];
  33. accum_b+=s[2];
  34. }
  35.  
  36. dpix=srcChannels*x+y*srcRowstride;
  37. dest[dpix ]=accum_r/winsize;
  38. dest[dpix+1]=accum_g/winsize;
  39. dest[dpix+2]=accum_b/winsize;
  40. }
  41.  
  42. return 0;
  43. }