3 __constant__ float masque[256] ;
4 /* noyau gaussien 3x3 *//*
5 __constant__ float noyau[] = {1.0/16,2.0/16,1.0/16,
7 1.0/16,2.0/16,1.0/16} ;
8 __constant__ int rnoyau = 1 ;*/
10 /* noyau gaussien 5x5 *//*
11 __constant__ int noyau[] = {1,4,6,4,1, 4,16,24,16,4, 6,24,36,24,6, 4,16,24,16,4, 1,4,6,4,1} ;
12 __constant__ int sumNoyau = 256 ;
13 __constant__ int rnoyau = 2 ;
14 __constant__ int NNoyau = 25 ;
17 __constant__ float noyau[] = {1.0/25,1.0/25,1.0/25,1.0/25,1.0/25,
18 1.0/25,1.0/25,1.0/25,1.0/25,1.0/25,
19 1.0/25,1.0/25,1.0/25,1.0/25,1.0/25,
20 1.0/25,1.0/25,1.0/25,1.0/25,1.0/25,
21 1.0/25,1.0/25,1.0/25,1.0/25,1.0/25} ;
22 __constant__ int rnoyau = 2 ;
25 __device__ __constant__ float noyau[] = {1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,
26 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,
27 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,
28 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,
29 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,
30 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,
31 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49} ;
32 __device__ __constant__ int rnoyau = 3 ;
34 //__device__ __constant__ int NNoyau = 49 ;
36 __device__ __constant__ int noyauH[] = {1,1,1,1,1,1,1} ;
37 __device__ __constant__ int sumNoyauH = 7 ;
38 __device__ __constant__ int rnoyauH = 3 ;
41 __device__ __constant__ int noyauV[] = {1,1,1,1,1,1,1} ;
42 __device__ __constant__ int sumNoyauV = 7 ;
43 __device__ __constant__ int rnoyauV = 3 ;
46 __device__ __constant__ int noyauV[] = {1,4,6,4,1} ;
47 __device__ __constant__ int rnoyauV = 2 ;
48 __constant__ int sumKV = 16 ;
49 //__device__ __constant__ int noyauV[] = {1,1,1} ;
50 //__constant__ int sumNoyauV = 16 ;
52 // declarations des textures
53 texture<int, 2, cudaReadModeElementType> tex_img_in ;
54 texture<unsigned short, 2, cudaReadModeElementType> tex_img_ins ;
55 texture<unsigned char, 2, cudaReadModeElementType> tex_img_inc ;
56 texture<int, 2, cudaReadModeElementType> tex_img_estim ;
57 texture<float, 1, cudaReadModeElementType> tex_noyau ;
58 texture<float, 1, cudaReadModeElementType> tex_noyauConvof ;
59 texture<short, 1, cudaReadModeElementType> tex_noyauConvos ;
60 texture<int, 1, cudaReadModeElementType> tex_kern ;
63 /***************************************************************
64 * kernel identite pour mesures de debit max effectif possible
65 ***************************************************************/
66 __global__ void kernel_ident( unsigned short*output, int i_dim, int j_dim)
68 // coordonnees absolues du point de base
69 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
70 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
71 int idx = __mul24(i, j_dim) + j ; // indice dans l'image
73 output[ idx ] = tex2D(tex_img_ins, j, i) ;
77 __global__ void kernel_ident2p( unsigned short *output, int i_dim, int j_dim)
79 // coordonnees absolues du point de base
80 int j = __umul24(__umul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
81 int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ;
83 output[ __umul24(i, j_dim) + j ] = tex2D(tex_img_inc, j, i) ;
84 output[ __umul24(i, j_dim) + j +1 ] = tex2D(tex_img_inc, j+1, i) ;
89 __global__ void kernel_ident( unsigned char *output, int i_dim, int j_dim)
91 // coordonnees absolues du point de base
92 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
93 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
95 output[ __umul24(i, j_dim) + j ] = tex2D(tex_img_inc, j, i) ;
99 __global__ void kernel_ident2p( unsigned char *output, int i_dim, int j_dim)
101 // coordonnees absolues du point de base
102 int j = __umul24(__umul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
103 int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ;
105 output[ __umul24(i, j_dim) + j ] = tex2D(tex_img_inc, j, i) ;
106 output[ __umul24(i, j_dim) + j +1 ] = tex2D(tex_img_inc, j+1, i) ;
112 * \brief calcule l'estimation initiale
115 * \param[in] L Largeur de l'image
116 * \param[in] i_dim Hauteur de l'image
117 * \param[in] j_dim coté de la fenêtre de moyenneage
119 * \param[out] output Image estimee initiale
121 * Version texture : l'img originale est supposée en texture.
122 * L'estimation réalisée correspond a un moyenneur de 'rayon' r
123 * Execution sur des blocs de threads 2D et une grille 2D
124 * selon les dimensions de l'image.
128 __global__ void kernel_moyenne_shtex( unsigned int *output, unsigned int i_dim, unsigned int j_dim, unsigned int r)
131 //coordonnées ds le bloc
132 int ib = threadIdx.y ;
133 int jb = threadIdx.x ;
134 int idb_row = __mul24(ib,blockDim.x) + jb ; // indice dans le bloc
136 // coordonnees absolues du point
137 int j = __mul24(blockIdx.x,blockDim.x) + jb ;
138 int i = __mul24(blockIdx.y,blockDim.y) + ib ;
139 int idx = __mul24(i,j_dim) + j ; // indice dans l'image
140 int off = __mul24(r,blockDim.x) ; // offset du bloc dans le buffer en sh mem
143 extern __shared__ unsigned int shmem[] ;
144 volatile unsigned int * buffer = shmem ;
145 volatile unsigned int * bufferV = &buffer[ blockDim.x*blockDim.y + 2*off ] ;
148 /***********************************************************************************
150 ***********************************************************************************/
151 // charge les pixels de la bande au dessus du bloc
154 buffer[ idb_row ] = 0 ;
155 for (idc=j-r ; idc<=j+r ; idc++ )
156 buffer[ idb_row ] += tex2D(tex_img_in, idc, i-r) ;
159 // charge les pixels de la bande en dessous du bloc
160 if (ib>=(blockDim.y-r))
162 buffer[ idb_row + 2*off ] = 0 ;
163 for (idc=j-r ; idc<=j+r ; idc++ )
164 buffer[ idb_row + 2*off ] += tex2D(tex_img_in, idc, i+r) ;
167 // charge les pixels du bloc
168 buffer[ idb_row + off ] = 0 ;
169 for (idc=j-r ; idc<=j+r ; idc++ )
170 buffer[ idb_row + off ] += tex2D(tex_img_in, idc, i) ;
173 /*****************************************************************************
175 *****************************************************************************/
176 bufferV[ idb_row ] = 0 ;
177 for (idl=0 ; idl<=2*r ; idl++ )
178 bufferV[ idb_row ] += buffer[ (ib+idl)*blockDim.x + jb ] ;
182 output[idx] = bufferV[ idb_row ]/((2*r+1)*(2*r+1)) ; //pas juste sur les bords, mais c'est pô grave !
188 * \brief calcule la convolution avec un noyau carre
191 * \param[in] L Largeur de l'image
192 * \param[in] i_dim Hauteur de l'image
193 * \param[in] j_dim coté de la fenêtre de moyenneage
195 * \param[out] output Image estimee initiale
197 * Version texture : l'img originale est supposée en texture.
198 * Execution sur des blocs de threads 2D et une grille 2D
199 * correspondant aux dimensions de l'image.
203 // convolution non separable
204 // image en texture et noyau en mem constante
205 __global__ void kernel_convoGene8( unsigned char *output, int i_dim, int j_dim)
212 // coordonnees absolues du point de base
213 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
214 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
216 for (ic=0 ; ic<L ; ic++)
217 for(jc=0 ; jc<L ; jc++)
218 outval0 += masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic) ;
221 output[ __mul24(i, j_dim) + j ] = outval0 ;
224 // convolution non separable 2 pixels/thread
225 // image en texture et noyau en mem constante
226 __global__ void kernel_convoGene8x2p( unsigned char *output, int i_dim, int j_dim )
231 float outval0=0.0, outval1=0.0, outval2=0.0 ;
233 // coordonnees absolues du point de base
234 int j = __mul24( __mul24(blockIdx.x,blockDim.x) + threadIdx.x, 2) ;
235 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
237 for (ic=0 ; ic<L ; ic++)
239 for(jc=1 ; jc<L-1 ; jc++)
241 outval0 += masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic) ;
246 for (ic=0 ; ic<L ; ic++)
248 outval1 += masque[ __mul24(ic,L) ]*tex2D(tex_img_inc, j-r, i-r+ic) ;
249 outval2 += masque[ __mul24(ic,L)+L-1 ]*tex2D(tex_img_inc, j-r+L, i-r+ic) ;
252 output[ __mul24(i, j_dim) + j ] = outval1 ;
253 output[ __mul24(i, j_dim) + j+1 ] = outval2 ;
256 // convolution non separable 2 pixels/thread
257 // image en texture et noyau en mem constante
258 __global__ void kernel_convoGene8rx2p( unsigned char *output, int j_dim, int r )
262 //unsigned char pix ;
263 float outval0=0.0, outval1=0.0 ;
265 // coordonnees absolues du point de base
266 int j = __umul24( __umul24(blockIdx.x,blockDim.x) + threadIdx.x, 2) ;
267 int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ;
268 int idx=__umul24(i, j_dim) + j ;
270 for (ic=0 ; ic<L ; ic++)
272 outval0 += masque[ __umul24(ic,L) ]*tex2D(tex_img_inc, j-r, i-r+ic) ; //bande gauche
274 for(jc=1 ; jc<L ; jc++)
276 //pix = tex2D(tex_img_inc, j-r+jc, i-r+ic) ;
277 outval0 += masque[ __umul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic) ;
278 outval1 += masque[ __umul24(ic,L)+jc-1 ]*tex2D(tex_img_inc, j-r+jc, i-r+ic) ;
280 outval1 += masque[ __umul24(ic,L)+L-1 ]*tex2D(tex_img_inc, j-r+L, i-r+ic) ; // bande droite
282 output[ idx ] = outval0 ;
283 output[ idx+1 ] = outval1 ;
286 // convolution non separable 4 pixels/thread
287 // image en texture et noyau en mem constante
288 __global__ void kernel_convoGene8rx4p( unsigned char *output, int j_dim, int r )
293 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ;
295 // coordonnees absolues du point de base en haut a gauche
296 int j = __mul24( __umul24( blockIdx.x, blockDim.x) + threadIdx.x, 2) ;
297 int i = __mul24( __umul24( blockIdx.y, blockDim.y) + threadIdx.y, 2) ;
300 //forme generique contrib pixel => masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic)
301 for (ic=1 ; ic<L ; ic++)
303 for(jc=1 ; jc<L ; jc++)
305 pix = tex2D(tex_img_inc, j-r+jc, i-r+ic) ;
306 outval0 += masque[ __umul24(ic,L) +jc ]*pix ;
307 outval1 += masque[ __umul24(ic,L) +jc-1 ]*pix ;
308 outval2 += masque[ __umul24(ic-1,L)+jc ]*pix ;
309 outval3 += masque[ __umul24(ic-1,L)+jc-1 ]*pix ;
312 // les blocs peripheriques verticaux
313 for (ic=1 ; ic<L ; ic++)
315 outval0 += masque[ __umul24(ic,L) ]*tex2D(tex_img_inc, j-r, i-r+ic) ; // bande A pour b0
316 outval2 += masque[ __umul24(ic-1,L) ]*tex2D(tex_img_inc, j-r, i-r+ic) ; // bande A pour b2
318 outval1 += masque[ __umul24(ic,L) +L-1 ]*tex2D(tex_img_inc, j+r+1, i-r+ic) ; //bande C pour b1
319 outval3 += masque[ __umul24(ic-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+1, i-r+ic) ; //bande C pour b3
321 // les blocs peripheriques horizontaux
322 for (jc=1 ; jc<L ; jc++)
324 outval0 += masque[ jc ]*tex2D(tex_img_inc, j-r+jc, i-r) ; // bande B pour b0
325 outval1 += masque[ jc-1 ]*tex2D(tex_img_inc, j-r+jc, i-r) ; // bande B pour b1
327 outval2 += masque[ __umul24(L-1,L) +jc ]*tex2D(tex_img_inc, j-r+jc, i+r+1) ; //bande D pour b2
328 outval3 += masque[ __umul24(L-1,L) +jc-1 ]*tex2D(tex_img_inc, j-r+jc, i+r+1) ; //bande D pour b3
333 outval0 += masque[ 0 ]*tex2D(tex_img_inc, j-r , i-r) ; // haut gauche pour b0
334 outval1 += masque[ L-1 ]*tex2D(tex_img_inc, j+r+1, i-r) ; // haut droit pour b1
335 outval2 += masque[ __umul24(L-1,L) ]*tex2D(tex_img_inc, j-r , i+r+1) ; // bas gauche pour b2
336 outval3 += masque[ __umul24(L-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+1, i+r+1) ; //bas droit pour b3
340 // les 2 pixels hauts
341 output[ __umul24(i, j_dim) + j ] = outval0 ;
342 output[ __umul24(i, j_dim) + j+1 ] = outval1 ;
344 output[ __umul24(i+1, j_dim) + j ] = outval2 ;
345 output[ __umul24(i+1, j_dim) + j+1 ] = outval3 ;
348 // convolution non separable 4 pixels/thread
349 // image en texture et noyau en mem constante
350 __global__ void kernel_convoGene8rx8p( unsigned char *output, int j_dim, int r )
355 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ;
356 float outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
358 // coordonnees absolues du point de base en haut a gauche
359 int j = ( __umul24( blockIdx.x, blockDim.x) + threadIdx.x)<< 2 ;
360 int i = ( __umul24( blockIdx.y, blockDim.y) + threadIdx.y)<< 1 ;
363 //forme generique contrib pixel => masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic)
364 for (ic=1 ; ic<L ; ic++)
366 for(jc=1 ; jc<L ; jc++)
368 pix = tex2D(tex_img_inc, j-r+jc, i-r+ic) ;
369 outval0 += masque[ __umul24(ic,L) +jc ]*pix ;
370 outval1 += masque[ __umul24(ic,L) +jc-1 ]*pix ;
371 outval2 += masque[ __umul24(ic-1,L)+jc ]*pix ;
372 outval3 += masque[ __umul24(ic-1,L)+jc-1 ]*pix ;
374 pix = tex2D(tex_img_inc, j-r+jc+2, i-r+ic) ;
375 outval4 += masque[ __umul24(ic,L) +jc ]*pix ;
376 outval5 += masque[ __umul24(ic,L) +jc-1 ]*pix ;
377 outval6 += masque[ __umul24(ic-1,L)+jc ]*pix ;
378 outval7 += masque[ __umul24(ic-1,L)+jc-1 ]*pix ;
382 // les blocs peripheriques verticaux
383 for (ic=1 ; ic<L ; ic++)
385 outval0 += masque[ __umul24(ic,L) ]*tex2D(tex_img_inc, j-r, i-r+ic) ; // bande A pour b0
386 outval2 += masque[ __umul24(ic-1,L) ]*tex2D(tex_img_inc, j-r, i-r+ic) ; // bande A pour b2
388 outval1 += masque[ __umul24(ic,L) +L-1 ]*tex2D(tex_img_inc, j+r+1, i-r+ic) ; //bande C pour b1
389 outval3 += masque[ __umul24(ic-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+1, i-r+ic) ; //bande C pour b3
391 outval4 += masque[ __umul24(ic,L) ]*tex2D(tex_img_inc, j-r+2, i-r+ic) ; // bande A pour b0
392 outval5 += masque[ __umul24(ic-1,L) ]*tex2D(tex_img_inc, j-r+2, i-r+ic) ; // bande A pour b2
394 outval6 += masque[ __umul24(ic,L) +L-1 ]*tex2D(tex_img_inc, j+r+3, i-r+ic) ; //bande C pour b1
395 outval7 += masque[ __umul24(ic-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+3, i-r+ic) ; //bande C pour b3
397 // les blocs peripheriques horizontaux
398 for (jc=1 ; jc<L ; jc++)
400 outval0 += masque[ jc ]*tex2D(tex_img_inc, j-r+jc, i-r) ; // bande B pour b0
401 outval1 += masque[ jc-1 ]*tex2D(tex_img_inc, j-r+jc, i-r) ; // bande B pour b1
403 outval2 += masque[ __umul24(L-1,L) +jc ]*tex2D(tex_img_inc, j-r+jc, i+r+1) ; //bande D pour b2
404 outval3 += masque[ __umul24(L-1,L) +jc-1 ]*tex2D(tex_img_inc, j-r+jc, i+r+1) ; //bande D pour b3
406 outval4 += masque[ jc ]*tex2D(tex_img_inc, j-r+jc+2, i-r) ; // bande B pour b0
407 outval5 += masque[ jc-1 ]*tex2D(tex_img_inc, j-r+jc+2, i-r) ; // bande B pour b1
409 outval6 += masque[ __umul24(L-1,L) +jc ]*tex2D(tex_img_inc, j-r+jc+2, i+r+1) ; //bande D pour b2
410 outval7 += masque[ __umul24(L-1,L) +jc-1 ]*tex2D(tex_img_inc, j-r+jc+2, i+r+1) ; //bande D pour b3
415 outval0 += masque[ 0 ]*tex2D(tex_img_inc, j-r , i-r) ; // haut gauche pour b0
416 outval1 += masque[ L-1 ]*tex2D(tex_img_inc, j+r+1, i-r) ; // haut droit pour b1
417 outval2 += masque[ __umul24(L-1,L) ]*tex2D(tex_img_inc, j-r , i+r+1) ; // bas gauche pour b2
418 outval3 += masque[ __umul24(L-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+1, i+r+1) ; //bas droit pour b3
420 outval4 += masque[ 0 ]*tex2D(tex_img_inc, j-r+2, i-r) ; // haut gauche pour b0
421 outval5 += masque[ L-1 ]*tex2D(tex_img_inc, j+r+3, i-r) ; // haut droit pour b1
422 outval6 += masque[ __umul24(L-1,L) ]*tex2D(tex_img_inc, j-r+2, i+r+1) ; // bas gauche pour b2
423 outval7 += masque[ __umul24(L-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+3, i+r+1) ; //bas droit pour b3
427 // les 2 pixels hauts
428 output[ __umul24(i, j_dim) + j ] = outval0 ;
429 output[ __umul24(i, j_dim) + j+1 ] = outval1 ;
430 output[ __umul24(i, j_dim) + j+2 ] = outval4 ;
431 output[ __umul24(i, j_dim) + j+3 ] = outval5 ;
433 output[ __umul24(i+1, j_dim) + j ] = outval2 ;
434 output[ __umul24(i+1, j_dim) + j+1 ] = outval3 ;
435 output[ __umul24(i+1, j_dim) + j+2 ] = outval6 ;
436 output[ __umul24(i+1, j_dim) + j+3 ] = outval7 ;
440 // convolution non separable 8 pixels/thread
441 // image en texture et noyau en mem constante
442 __global__ void kernel_convoGene8x8pL3( unsigned char *output, int j_dim )
447 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ;
448 float outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
450 // coordonnees absolues du point de base en haut a gauche
451 int j = ( __umul24( blockIdx.x, blockDim.x) + threadIdx.x)<< 3 ;
452 int i = ( __umul24( blockIdx.y, blockDim.y) + threadIdx.y) ;
455 //forme generique contrib pixel => masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic)
456 for (ic=0 ; ic<L ; ic++)
458 base = __umul24(ic,L) ;
459 pix = tex2D(tex_img_inc, j+1, i-1+ic) ;
460 outval0 += masque[ base +2 ]*pix ;
461 outval1 += masque[ base +1 ]*pix ;
462 outval2 += masque[ base ]*pix ;
463 pix = tex2D(tex_img_inc, j+2, i-1+ic) ;
464 outval1 += masque[ base +2 ]*pix ;
465 outval2 += masque[ base +1 ]*pix ;
466 outval3 += masque[ base ]*pix ;
467 pix = tex2D(tex_img_inc, j+3, i-1+ic) ;
468 outval2 += masque[ base +2 ]*pix ;
469 outval3 += masque[ base +1 ]*pix ;
470 outval4 += masque[ base ]*pix ;
471 pix = tex2D(tex_img_inc, j+4, i-1+ic) ;
472 outval3 += masque[ base +2 ]*pix ;
473 outval4 += masque[ base +1 ]*pix ;
474 outval5 += masque[ base ]*pix ;
475 pix = tex2D(tex_img_inc, j+5, i-1+ic) ;
476 outval4 += masque[ base +2 ]*pix ;
477 outval5 += masque[ base +1 ]*pix ;
478 outval6 += masque[ base ]*pix ;
479 pix = tex2D(tex_img_inc, j+6, i-1+ic) ;
480 outval5 += masque[ base +2 ]*pix ;
481 outval6 += masque[ base +1 ]*pix ;
482 outval7 += masque[ base ]*pix ;
484 pix = tex2D(tex_img_inc, j, i-1+ic) ;
485 outval0 += masque[ base +1 ]*pix ;
486 outval1 += masque[ base ]*pix ;
487 pix = tex2D(tex_img_inc, j-1, i-1+ic) ;
488 outval0 += masque[ base ]*pix ;
490 pix = tex2D(tex_img_inc, j+7, i-1+ic) ;
491 outval6 += masque[ base +2 ]*pix ;
492 outval7 += masque[ base +1 ]*pix ;
493 pix = tex2D(tex_img_inc, j+8, i-1+ic) ;
494 outval7 += masque[ base +2 ]*pix ;
497 // les 2 pixels hauts
498 base = __umul24(i, j_dim) + j ;
499 output[ base++ ] = outval0 ;
500 output[ base++ ] = outval1 ;
501 output[ base++ ] = outval2 ;
502 output[ base++ ] = outval3;
503 output[ base++ ] = outval4;
504 output[ base++ ] = outval5;
505 output[ base++ ] = outval6 ;
506 output[ base++ ] = outval7 ;
514 // convolution non separable 8 pixels/thread
515 // image en texture et noyau en mem constante
516 __global__ void kernel_convoGene8x8pL5( unsigned char *output, int j_dim )
521 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ;
522 float outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
524 // coordonnees absolues du point de base en haut a gauche
525 int j = ( __umul24( blockIdx.x, blockDim.x) + threadIdx.x)<< 3 ;
526 int i = ( __umul24( blockIdx.y, blockDim.y) + threadIdx.y) ;
529 //forme generique contrib pixel => masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic)
530 for (ic=0 ; ic<L ; ic++)
532 base = __umul24(ic,L) ;
533 pix = tex2D(tex_img_inc, j+2, i-2+ic) ;
534 outval0 += masque[ base +4 ]*pix ;
535 outval1 += masque[ base +3 ]*pix ;
536 outval2 += masque[ base +2 ]*pix ;
537 outval3 += masque[ base +1 ]*pix ;
538 outval4 += masque[ base ]*pix ;
539 pix = tex2D(tex_img_inc, j+3, i-2+ic) ;
540 outval1 += masque[ base +4 ]*pix ;
541 outval2 += masque[ base +3 ]*pix ;
542 outval3 += masque[ base +2 ]*pix ;
543 outval4 += masque[ base +1 ]*pix ;
544 outval5 += masque[ base ]*pix ;
545 pix = tex2D(tex_img_inc, j+4, i-2+ic) ;
546 outval2 += masque[ base +4 ]*pix ;
547 outval3 += masque[ base +3 ]*pix ;
548 outval4 += masque[ base +2 ]*pix ;
549 outval5 += masque[ base +1 ]*pix ;
550 outval6 += masque[ base ]*pix ;
551 pix = tex2D(tex_img_inc, j+5, i-2+ic) ;
552 outval3 += masque[ base +4 ]*pix ;
553 outval4 += masque[ base +3 ]*pix ;
554 outval5 += masque[ base +2 ]*pix ;
555 outval6 += masque[ base +1 ]*pix ;
556 outval7 += masque[ base ]*pix ;
558 pix = tex2D(tex_img_inc, j+1, i-2+ic) ;
559 outval0 += masque[ base +3 ]*pix ;
560 outval1 += masque[ base +2 ]*pix ;
561 outval2 += masque[ base +1 ]*pix ;
562 outval3 += masque[ base ]*pix ;
564 pix = tex2D(tex_img_inc, j, i-2+ic) ;
565 outval0 += masque[ base +2 ]*pix ;
566 outval1 += masque[ base +1 ]*pix ;
567 outval2 += masque[ base ]*pix ;
569 pix = tex2D(tex_img_inc, j-1, i-2+ic) ;
570 outval0 += masque[ base +1 ]*pix ;
571 outval1 += masque[ base ]*pix ;
573 pix = tex2D(tex_img_inc, j-2, i-2+ic) ;
574 outval0 += masque[ base ]*pix ;
576 pix = tex2D(tex_img_inc, j+6, i-2+ic) ;
577 outval7 += masque[ base +1 ]*pix ;
578 outval6 += masque[ base +2 ]*pix ;
579 outval5 += masque[ base +3 ]*pix ;
580 outval4 += masque[ base +4 ]*pix ;
582 pix = tex2D(tex_img_inc, j+7, i-2+ic) ;
583 outval7 += masque[ base +2 ]*pix ;
584 outval6 += masque[ base +3 ]*pix ;
585 outval5 += masque[ base +4 ]*pix ;
587 pix = tex2D(tex_img_inc, j+8, i-2+ic) ;
588 outval7 += masque[ base +3 ]*pix ;
589 outval6 += masque[ base +4 ]*pix ;
591 pix = tex2D(tex_img_inc, j+9, i-2+ic) ;
592 outval7 += masque[ base +4 ]*pix ;
596 base = __umul24(i, j_dim) + j ;
597 output[ base++ ] = outval0 ;
598 output[ base++ ] = outval1 ;
599 output[ base++ ] = outval2 ;
600 output[ base++ ] = outval3;
601 output[ base++ ] = outval4;
602 output[ base++ ] = outval5;
603 output[ base++ ] = outval6 ;
604 output[ base++ ] = outval7 ;
608 __global__ void kernel_convoGene8x8pL7( unsigned char *output, int j_dim )
613 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ;
614 float outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
616 // coordonnees absolues du point de base en haut a gauche
617 int j = ( __umul24( blockIdx.x, blockDim.x) + threadIdx.x)<< 3 ;
618 int i = ( __umul24( blockIdx.y, blockDim.y) + threadIdx.y) ;
621 //forme generique contrib pixel => masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic)
622 for (ic=0 ; ic<L ; ic++)
624 base = __umul24(ic,L) ;
625 pix = tex2D(tex_img_inc, j+3, i-3+ic) ;
626 outval0 += masque[ base +6 ]*pix ;
627 outval1 += masque[ base +5 ]*pix ;
628 outval2 += masque[ base +4 ]*pix ;
629 outval3 += masque[ base +3 ]*pix ;
630 outval4 += masque[ base +2 ]*pix ;
631 outval5 += masque[ base +1 ]*pix ;
632 outval6 += masque[ base ]*pix ;
633 pix = tex2D(tex_img_inc, j+4, i-3+ic) ;
634 outval1 += masque[ base +6 ]*pix ;
635 outval2 += masque[ base +5 ]*pix ;
636 outval3 += masque[ base +4 ]*pix ;
637 outval4 += masque[ base +3 ]*pix ;
638 outval5 += masque[ base +2 ]*pix ;
639 outval6 += masque[ base +1 ]*pix ;
640 outval7 += masque[ base ]*pix ;
642 pix = tex2D(tex_img_inc, j+2, i-3+ic) ;
643 outval0 += masque[ base +5 ]*pix ;
644 outval1 += masque[ base +4 ]*pix ;
645 outval2 += masque[ base +3 ]*pix ;
646 outval3 += masque[ base +2 ]*pix ;
647 outval4 += masque[ base +1 ]*pix ;
648 outval5 += masque[ base ]*pix ;
649 pix = tex2D(tex_img_inc, j+1, i-3+ic) ;
650 outval0 += masque[ base +4 ]*pix ;
651 outval1 += masque[ base +3 ]*pix ;
652 outval2 += masque[ base +2 ]*pix ;
653 outval3 += masque[ base +1 ]*pix ;
654 outval4 += masque[ base ]*pix ;
655 pix = tex2D(tex_img_inc, j, i-3+ic) ;
656 outval0 += masque[ base +3 ]*pix ;
657 outval1 += masque[ base +2 ]*pix ;
658 outval2 += masque[ base +1 ]*pix ;
659 outval3 += masque[ base ]*pix ;
660 pix = tex2D(tex_img_inc, j-1, i-3+ic) ;
661 outval0 += masque[ base +2 ]*pix ;
662 outval1 += masque[ base +1 ]*pix ;
663 outval2 += masque[ base ]*pix ;
664 pix = tex2D(tex_img_inc, j-2, i-3+ic) ;
665 outval0 += masque[ base +1 ]*pix ;
666 outval1 += masque[ base ]*pix ;
667 pix = tex2D(tex_img_inc, j-3, i-3+ic) ;
668 outval0 += masque[ base ]*pix ;
671 pix = tex2D(tex_img_inc, j+5, i-3+ic) ;
672 outval7 += masque[ base +1 ]*pix ;
673 outval6 += masque[ base +2 ]*pix ;
674 outval5 += masque[ base +3 ]*pix ;
675 outval4 += masque[ base +4 ]*pix ;
676 outval3 += masque[ base +5 ]*pix ;
677 outval2 += masque[ base +6 ]*pix ;
678 pix = tex2D(tex_img_inc, j+6, i-3+ic) ;
679 outval7 += masque[ base +2 ]*pix ;
680 outval6 += masque[ base +3 ]*pix ;
681 outval5 += masque[ base +4 ]*pix ;
682 outval4 += masque[ base +5 ]*pix ;
683 outval3 += masque[ base +6 ]*pix ;
684 pix = tex2D(tex_img_inc, j+7, i-3+ic) ;
685 outval7 += masque[ base +3 ]*pix ;
686 outval6 += masque[ base +4 ]*pix ;
687 outval5 += masque[ base +5 ]*pix ;
688 outval4 += masque[ base +6 ]*pix ;
689 pix = tex2D(tex_img_inc, j+8, i-3+ic) ;
690 outval7 += masque[ base +4 ]*pix ;
691 outval6 += masque[ base +5 ]*pix ;
692 outval5 += masque[ base +6 ]*pix ;
693 pix = tex2D(tex_img_inc, j+9, i-3+ic) ;
694 outval7 += masque[ base +5 ]*pix ;
695 outval6 += masque[ base +6 ]*pix ;
696 pix = tex2D(tex_img_inc, j+10, i-3+ic) ;
697 outval7 += masque[ base +6 ]*pix ;
702 base = __umul24(i, j_dim) + j ;
703 output[ base++ ] = outval0 ;
704 output[ base++ ] = outval1 ;
705 output[ base++ ] = outval2 ;
706 output[ base++ ] = outval3;
707 output[ base++ ] = outval4;
708 output[ base++ ] = outval5;
709 output[ base++ ] = outval6 ;
710 output[ base++ ] = outval7 ;
715 // convolution non separable 4 pixels/thread
716 // image en texture et noyau en mem constante
717 __global__ void kernel_convoGene8rx16p( unsigned char *output, int j_dim, int r )
720 int L=2*r+1, baseIdx ;
722 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ;
723 float outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
724 float outval8=0.0, outval9=0.0, outval10=0.0, outval11=0.0 ;
725 float outval12=0.0, outval13=0.0, outval14=0.0, outval15=0.0 ;
727 // coordonnees absolues du point de base en haut a gauche
728 int j = ( __umul24( blockIdx.x, blockDim.x) + threadIdx.x)<< 3 ;
729 int i = ( __umul24( blockIdx.y, blockDim.y) + threadIdx.y)<< 1 ;
732 //forme generique contrib pixel => masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic)
733 for (ic=1 ; ic<L ; ic++)
735 for(jc=1 ; jc<L ; jc++)
737 pix = tex2D(tex_img_inc, j-r+jc, i-r+ic) ;
738 baseIdx = __umul24(ic-1,L)+jc-1 ;
739 outval0 += masque[ baseIdx+L+1 ]*pix ;
740 outval1 += masque[ baseIdx+L ]*pix ;
741 outval2 += masque[ baseIdx+1 ]*pix ;
742 outval3 += masque[ baseIdx ]*pix ;
744 pix = tex2D(tex_img_inc, j-r+jc+2, i-r+ic) ;
745 outval4 += masque[ baseIdx+L+1 ]*pix ;
746 outval5 += masque[ baseIdx+L ]*pix ;
747 outval6 += masque[ baseIdx+1 ]*pix ;
748 outval7 += masque[ baseIdx ]*pix ;
750 pix = tex2D(tex_img_inc, j-r+jc+4, i-r+ic) ;
751 outval8 += masque[ baseIdx+L+1 ]*pix ;
752 outval9 += masque[ baseIdx+L ]*pix ;
753 outval10+= masque[ baseIdx+1 ]*pix ;
754 outval11+= masque[ baseIdx ]*pix ;
756 pix = tex2D(tex_img_inc, j-r+jc+6, i-r+ic) ;
757 outval12 += masque[ baseIdx+L+1 ]*pix ;
758 outval13 += masque[ baseIdx+L ]*pix ;
759 outval14 += masque[ baseIdx+1 ]*pix ;
760 outval15 += masque[ baseIdx ]*pix ;
764 // les blocs peripheriques verticaux
765 for (ic=1 ; ic<L ; ic++)
767 outval0 += masque[ __umul24(ic,L) ]*tex2D(tex_img_inc, j-r, i-r+ic) ; // bande A pour b0
768 outval2 += masque[ __umul24(ic-1,L) ]*tex2D(tex_img_inc, j-r, i-r+ic) ; // bande A pour b2
770 outval1 += masque[ __umul24(ic,L) +L-1 ]*tex2D(tex_img_inc, j+r+1, i-r+ic) ; //bande C pour b1
771 outval3 += masque[ __umul24(ic-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+1, i-r+ic) ; //bande C pour b3
773 outval4 += masque[ __umul24(ic,L) ]*tex2D(tex_img_inc, j-r+2, i-r+ic) ; // bande A pour b0
774 outval6 += masque[ __umul24(ic-1,L) ]*tex2D(tex_img_inc, j-r+2, i-r+ic) ; // bande A pour b2
776 outval5 += masque[ __umul24(ic,L) +L-1 ]*tex2D(tex_img_inc, j+r+3, i-r+ic) ; //bande C pour b1
777 outval7 += masque[ __umul24(ic-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+3, i-r+ic) ; //bande C pour b3
779 outval8 += masque[ __umul24(ic,L) ]*tex2D(tex_img_inc, j-r+4, i-r+ic) ; // bande A pour b0
780 outval10 += masque[ __umul24(ic-1,L) ]*tex2D(tex_img_inc, j-r+4, i-r+ic) ; // bande A pour b2
782 outval9 += masque[ __umul24(ic,L) +L-1 ]*tex2D(tex_img_inc, j+r+5, i-r+ic) ; //bande C pour b1
783 outval11 += masque[ __umul24(ic-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+5, i-r+ic) ; //bande C pour b3
785 outval12 += masque[ __umul24(ic,L) ]*tex2D(tex_img_inc, j-r+6, i-r+ic) ; // bande A pour b0
786 outval14 += masque[ __umul24(ic-1,L) ]*tex2D(tex_img_inc, j-r+6, i-r+ic) ; // bande A pour b2
788 outval13 += masque[ __umul24(ic,L) +L-1 ]*tex2D(tex_img_inc, j+r+7, i-r+ic) ; //bande C pour b1
789 outval15 += masque[ __umul24(ic-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+7, i-r+ic) ; //bande C pour b3
791 // les blocs peripheriques horizontaux
792 for (jc=1 ; jc<L ; jc++)
794 outval0 += masque[ jc ]*tex2D(tex_img_inc, j-r+jc, i-r) ; // bande B pour b0
795 outval1 += masque[ jc-1 ]*tex2D(tex_img_inc, j-r+jc, i-r) ; // bande B pour b1
797 outval2 += masque[ __umul24(L-1,L) +jc ]*tex2D(tex_img_inc, j-r+jc, i+r+1) ; //bande D pour b2
798 outval3 += masque[ __umul24(L-1,L) +jc-1 ]*tex2D(tex_img_inc, j-r+jc, i+r+1) ; //bande D pour b3
800 outval4 += masque[ jc ]*tex2D(tex_img_inc, j-r+jc+2, i-r) ; // bande B pour b0
801 outval5 += masque[ jc-1 ]*tex2D(tex_img_inc, j-r+jc+2, i-r) ; // bande B pour b1
803 outval6 += masque[ __umul24(L-1,L) +jc ]*tex2D(tex_img_inc, j-r+jc+2, i+r+1) ; //bande D pour b2
804 outval7 += masque[ __umul24(L-1,L) +jc-1 ]*tex2D(tex_img_inc, j-r+jc+2, i+r+1) ; //bande D pour b3
806 outval8 += masque[ jc ]*tex2D(tex_img_inc, j-r+jc+4, i-r) ; // bande B pour b0
807 outval9 += masque[ jc-1 ]*tex2D(tex_img_inc, j-r+jc+4, i-r) ; // bande B pour b1
809 outval10 += masque[ __umul24(L-1,L) +jc ]*tex2D(tex_img_inc, j-r+jc+4, i+r+1) ; //bande D pour b2
810 outval11 += masque[ __umul24(L-1,L) +jc-1 ]*tex2D(tex_img_inc, j-r+jc+4, i+r+1) ; //bande D pour b3
812 outval12 += masque[ jc ]*tex2D(tex_img_inc, j-r+jc+6, i-r) ; // bande B pour b0
813 outval13 += masque[ jc-1 ]*tex2D(tex_img_inc, j-r+jc+6, i-r) ; // bande B pour b1
815 outval14 += masque[ __umul24(L-1,L) +jc ]*tex2D(tex_img_inc, j-r+jc+6, i+r+1) ; //bande D pour b2
816 outval15 += masque[ __umul24(L-1,L) +jc-1 ]*tex2D(tex_img_inc, j-r+jc+6, i+r+1) ; //bande D pour b3
821 outval0 += masque[ 0 ]*tex2D(tex_img_inc, j-r , i-r) ; // haut gauche pour b0
822 outval1 += masque[ L-1 ]*tex2D(tex_img_inc, j+r+1, i-r) ; // haut droit pour b1
823 outval2 += masque[ __umul24(L-1,L) ]*tex2D(tex_img_inc, j-r , i+r+1) ; // bas gauche pour b2
824 outval3 += masque[ __umul24(L-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+1, i+r+1) ; //bas droit pour b3
826 outval4 += masque[ 0 ]*tex2D(tex_img_inc, j-r+2, i-r) ; // haut gauche pour b0
827 outval5 += masque[ L-1 ]*tex2D(tex_img_inc, j+r+3, i-r) ; // haut droit pour b1
828 outval6 += masque[ __umul24(L-1,L) ]*tex2D(tex_img_inc, j-r+2, i+r+1) ; // bas gauche pour b2
829 outval7 += masque[ __umul24(L-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+3, i+r+1) ; //bas droit pour b3
831 outval8 += masque[ 0 ]*tex2D(tex_img_inc, j-r+4, i-r) ; // haut gauche pour b0
832 outval9 += masque[ L-1 ]*tex2D(tex_img_inc, j+r+5, i-r) ; // haut droit pour b1
833 outval10 += masque[ __umul24(L-1,L) ]*tex2D(tex_img_inc, j-r+4, i+r+1) ; // bas gauche pour b2
834 outval11 += masque[ __umul24(L-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+5, i+r+1) ; //bas droit pour b3
836 outval12 += masque[ 0 ]*tex2D(tex_img_inc, j-r+6, i-r) ; // haut gauche pour b0
837 outval13 += masque[ L-1 ]*tex2D(tex_img_inc, j+r+7, i-r) ; // haut droit pour b1
838 outval14 += masque[ __umul24(L-1,L) ]*tex2D(tex_img_inc, j-r+6, i+r+1) ; // bas gauche pour b2
839 outval15 += masque[ __umul24(L-1,L)+L-1 ]*tex2D(tex_img_inc, j+r+7, i+r+1) ; //bas droit pour b3
843 // les 2 pixels hauts
844 int base = __umul24(i, j_dim) +j ;
845 output[ base++ ] = outval0 ;
846 output[ base++ ] = outval1 ;
847 output[ base++ ] = outval4 ;
848 output[ base++ ] = outval5 ;
849 output[ base++ ] = outval8 ;
850 output[ base++ ] = outval9 ;
851 output[ base++ ] = outval12 ;
852 output[ base++ ] = outval13 ;
854 base = __umul24(i+1, j_dim) +j ;
855 output[ base++ ] = outval2 ;
856 output[ base++ ] = outval3 ;
857 output[ base++ ] = outval6 ;
858 output[ base++ ] = outval7 ;
859 output[ base++ ] = outval10 ;
860 output[ base++ ] = outval11 ;
861 output[ base++ ] = outval14 ;
862 output[ base++ ] = outval15 ;
868 // convolution non separable
869 // image en texture et noyau en mem constante
870 __global__ void kernel_convoGene8r( unsigned char *output, int i_dim, int j_dim, int r)
876 // coordonnees absolues du point de base
877 int j = __mul24( blockIdx.x,blockDim.x ) + threadIdx.x ;
878 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
880 for (ic=-r ; ic<=r ; ic++)
881 for(jc=-r ; jc<=r ; jc++)
882 outval0 += masque[ __umul24(ic,L)+jc+r ]*tex2D(tex_img_inc, j+jc, i+ic) ;
885 output[ __umul24(i, j_dim) + j ] = outval0 ;
888 // convolution non separable
889 // image en texture et noyau en mem constante
890 __global__ void kernel_convoGeneTex8r( unsigned char *output, int i_dim, int j_dim, int r)
896 // coordonnees absolues du point de base
897 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
898 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
900 for (ic=0 ; ic<L ; ic++)
901 for(jc=0 ; jc<L ; jc++)
902 outval0 += tex1D(tex_noyau, __mul24(ic,L)+jc )*tex2D(tex_img_inc, j-r+jc, i-r+ic) ;
904 output[ __mul24(i, j_dim) + j ] = outval0 ;
908 __global__ void kernel_convoGene3Reg8( unsigned char *output, int i_dim, int j_dim )
911 float n0,n1,n2,n3,n4,n5,n6,n7,n8 ;
923 // coordonnees absolues du point de base
924 int j = __mul24(blockIdx.x, blockDim.x) + threadIdx.x ;
925 int i = __mul24(blockIdx.y, blockDim.y) + threadIdx.y ;
927 outval0 = n8*tex2D(tex_img_inc, j-1, i-1 )
928 + n7*tex2D(tex_img_inc, j , i-1 )
929 + n6*tex2D(tex_img_inc, j+1, i-1 )
930 + n5*tex2D(tex_img_inc, j-1, i )
931 + n4*tex2D(tex_img_inc, j , i )
932 + n3*tex2D(tex_img_inc, j+1, i )
933 + n2*tex2D(tex_img_inc, j-1, i+1 )
934 + n1*tex2D(tex_img_inc, j , i+1 )
935 + n0*tex2D(tex_img_inc, j+1, i+1 ) ;
937 output[ __mul24(i, j_dim) + j ] = (unsigned char) outval0 ;
941 // convolution non separable
942 // image en texture et noyau en registres
943 __global__ void kernel_convoGene5Reg8( unsigned char *output, int i_dim, int j_dim)
946 float n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24 ;
974 // coordonnees absolues du point de base
975 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
976 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
978 outval0 = n0*tex2D(tex_img_inc, j-2, i-2 )
979 + n1*tex2D(tex_img_inc, j-1, i-2 )
980 + n2*tex2D(tex_img_inc, j , i-2 )
981 + n3*tex2D(tex_img_inc, j+1, i-2 )
982 + n4*tex2D(tex_img_inc, j+2, i-2 )
983 + n5*tex2D(tex_img_inc, j-2, i-1 )
984 + n6*tex2D(tex_img_inc, j-1, i-1 )
985 + n7*tex2D(tex_img_inc, j , i-1 )
986 + n8*tex2D(tex_img_inc, j+1, i-1 )
987 + n9*tex2D(tex_img_inc, j+2, i-1 )
988 + n10*tex2D(tex_img_inc, j-2, i )
989 + n11*tex2D(tex_img_inc, j-1, i )
990 + n12*tex2D(tex_img_inc, j , i )
991 + n13*tex2D(tex_img_inc, j+1, i )
992 + n14*tex2D(tex_img_inc, j+2, i )
993 + n15*tex2D(tex_img_inc, j-2, i+1 )
994 + n16*tex2D(tex_img_inc, j-1, i+1 )
995 + n17*tex2D(tex_img_inc, j , i+1 )
996 + n18*tex2D(tex_img_inc, j+1, i+1 )
997 + n19*tex2D(tex_img_inc, j+2, i+1 )
998 + n20*tex2D(tex_img_inc, j-2, i+2 )
999 + n21*tex2D(tex_img_inc, j-1, i+2 )
1000 + n22*tex2D(tex_img_inc, j , i+2 )
1001 + n23*tex2D(tex_img_inc, j+1, i+2 )
1002 + n24*tex2D(tex_img_inc, j+2, i+2 ) ;
1004 output[ __mul24(i, j_dim) + j ] = outval0 ;
1007 // convolution non separable
1008 // image en texture et noyau en registres
1009 __global__ void kernel_convoGene7Reg8( unsigned char *output, int i_dim, int j_dim)
1012 float n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24 ;
1013 float n25,n26,n27,n28,n29,n30,n31,n32,n33,n34,n35,n36,n37,n38,n39,n40,n41,n42,n43,n44,n45,n46,n47,n48 ;
1068 // coordonnees absolues du point de base
1069 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
1070 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1073 n0*tex2D(tex_img_inc, j-3, i-3 )
1074 + n1*tex2D(tex_img_inc, j-2, i-3 )
1075 + n2*tex2D(tex_img_inc, j-1, i-3 )
1076 + n3*tex2D(tex_img_inc, j , i-3 )
1077 + n4*tex2D(tex_img_inc, j+1, i-3 )
1078 + n5*tex2D(tex_img_inc, j+2, i-3 )
1079 + n6*tex2D(tex_img_inc, j+3, i-3 )
1080 + n7*tex2D(tex_img_inc, j-3, i-2 )
1081 + n8*tex2D(tex_img_inc, j-2, i-2 )
1082 + n9*tex2D(tex_img_inc, j-1, i-2 )
1083 + n10*tex2D(tex_img_inc, j , i-2 )
1084 + n11*tex2D(tex_img_inc, j+1, i-2 )
1085 + n12*tex2D(tex_img_inc, j+2, i-2 )
1086 + n13*tex2D(tex_img_inc, j+3, i-2 )
1087 + n14*tex2D(tex_img_inc, j-3, i-1 )
1088 + n15*tex2D(tex_img_inc, j-2, i-1 )
1089 + n16*tex2D(tex_img_inc, j-1, i-1 )
1090 + n17*tex2D(tex_img_inc, j , i-1 )
1091 + n18*tex2D(tex_img_inc, j+1, i-1 )
1092 + n19*tex2D(tex_img_inc, j+2, i-1 )
1093 + n20*tex2D(tex_img_inc, j+3, i-1 )
1094 + n21*tex2D(tex_img_inc, j-3, i )
1095 + n22*tex2D(tex_img_inc, j-2, i )
1096 + n23*tex2D(tex_img_inc, j-1, i )
1097 + n24*tex2D(tex_img_inc, j , i )
1098 + n25*tex2D(tex_img_inc, j+1, i )
1099 + n26*tex2D(tex_img_inc, j+2, i )
1100 + n27*tex2D(tex_img_inc, j+3, i )
1101 + n28*tex2D(tex_img_inc, j-3, i+1 )
1102 + n29*tex2D(tex_img_inc, j-2, i+1 )
1103 + n30*tex2D(tex_img_inc, j-1, i+1 )
1104 + n31*tex2D(tex_img_inc, j , i+1 )
1105 + n32*tex2D(tex_img_inc, j+1, i+1 )
1106 + n33*tex2D(tex_img_inc, j+2, i+1 )
1107 + n34*tex2D(tex_img_inc, j+3, i+1 )
1108 + n35*tex2D(tex_img_inc, j-3, i+2 )
1109 + n36*tex2D(tex_img_inc, j-2, i+2 )
1110 + n37*tex2D(tex_img_inc, j-1, i+2 )
1111 + n38*tex2D(tex_img_inc, j , i+2 )
1112 + n39*tex2D(tex_img_inc, j+1, i+2 )
1113 + n40*tex2D(tex_img_inc, j+2, i+2 )
1114 + n41*tex2D(tex_img_inc, j+3, i+2 )
1115 + n42*tex2D(tex_img_inc, j-3, i+3 )
1116 + n43*tex2D(tex_img_inc, j-2, i+3 )
1117 + n44*tex2D(tex_img_inc, j-1, i+3 )
1118 + n45*tex2D(tex_img_inc, j , i+3 )
1119 + n46*tex2D(tex_img_inc, j+1, i+3 )
1120 + n47*tex2D(tex_img_inc, j+2, i+3 )
1121 + n48*tex2D(tex_img_inc, j+3, i+3 ) ;
1124 output[ __mul24(i, j_dim) + j ] = outval0 ;
1128 __global__ void kernel_convoNonSep16( unsigned short*output, int i_dim, int j_dim)
1136 // coordonnees absolues du point de base
1137 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
1138 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1140 for (idb=0 ; idb< N ; idb++)
1143 jc = j-r + idb - (idb/L)*L ;
1144 outval0 += ( noyau[ idb ]*tex2D(tex_img_in, jc, ic)) ;
1147 output[ __mul24(i, j_dim) + j ] = outval0 ;
1150 // convolution non separable
1151 // image en texture et noyau en mem constante
1152 // prefetch des pixels en smem
1153 // 1 pixel par thread
1154 __global__ void kernel_convoNonSepSh( unsigned short*output, int i_dim, int j_dim)
1157 int L = 2*rnoyau+1 ;
1160 // coordonnees absolues du point de base
1161 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
1162 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1163 int idx = __mul24(i,j_dim) + j ; // indice dans l'image
1165 // chargement en smem
1166 int idrow = threadIdx.y*(blockDim.x+2*rnoyau) ;
1168 extern __shared__ int roi[];
1170 // bloc 0 (en haut \E0 gauche)
1171 roi[ idrow + threadIdx.x ] = tex2D(tex_img_ins, j-rnoyau, i-rnoyau) ;
1172 // bloc 1 (en haut \E0 droite)...
1173 if ( threadIdx.x < L-1 ) //...ou plutot ce qu'il en manque
1174 roi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-rnoyau, i-rnoyau ) ;
1175 // bloc 2 ( en bas \E0 gauche)
1176 if ( threadIdx.y < L-1 )
1178 idrow = (threadIdx.y+blockDim.y)*(blockDim.x+L-1) ;
1179 roi[ idrow + threadIdx.x ] = tex2D( tex_img_ins, j-rnoyau, i+blockDim.y-rnoyau ) ;
1180 //bloc 4 ( en bas \E0 doite )...
1181 if ( threadIdx.x < L-1 ) //...ou ce qu'il en manque
1182 roi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-rnoyau, i+blockDim.y-rnoyau ) ;
1186 // calculs de convolution
1187 for (ic=0 ; ic<L ; ic++)
1188 for( jc=0 ; jc<L ; jc++)
1189 outval0 += ( noyau[ ic*L+jc ]*roi[ __mul24(ic+threadIdx.y,(blockDim.x+L-1)) + jc+threadIdx.x]) ;
1191 // 1 pixel par thread --> global mem
1192 output[ idx ] = outval0 ;
1196 __global__ void kernel_convoNonSepSh_2p(unsigned short *output, int i_dim, int j_dim)
1199 int L = 2*rnoyau+1 ;
1200 float outval0=0.0, outval1=0.0 ;
1201 int bdimX = blockDim.x<<1 ;
1202 int tidX = threadIdx.x<<1 ;
1204 // coordonnees absolues du point de base
1205 int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
1206 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1207 int idx = __mul24(i,j_dim) + j ; // indice dans l'image
1209 // chargement en smem
1210 int idrow = threadIdx.y*(bdimX+L-1) ;
1212 extern __shared__ int roi[];
1214 // bloc 0 (en haut \E0 gauche)
1215 roi[ idrow + tidX ] = tex2D(tex_img_ins, j-rnoyau, i-rnoyau) ;
1216 roi[ idrow + tidX +1] = tex2D(tex_img_ins, j-rnoyau+1, i-rnoyau) ;
1218 // bloc 1 (en haut \E0 droite)...
1219 if ( threadIdx.x < rnoyau ) //...ou plutot ce qu'il en manque
1221 roi[ idrow + tidX+bdimX ] = tex2D( tex_img_ins, j+bdimX-rnoyau, i-rnoyau ) ;
1222 roi[ idrow + tidX+bdimX +1] = tex2D( tex_img_ins, j+bdimX-rnoyau+1, i-rnoyau ) ;
1225 // bloc 2 ( en bas \E0 gauche)
1226 if ( threadIdx.y < L-1 )
1228 idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ;
1229 roi[ idrow + tidX ] = tex2D( tex_img_ins, j-rnoyau, i+blockDim.y-rnoyau ) ;
1230 roi[ idrow + tidX +1] = tex2D( tex_img_ins, j-rnoyau+1, i+blockDim.y-rnoyau ) ;
1231 //bloc 4 ( en bas \E0 doite )...
1233 if ( 2*threadIdx.x < L-1 ) //...ou ce qu'il en manque
1235 roi[ idrow + tidX+bdimX ] = tex2D( tex_img_ins, j+bdimX-rnoyau, i+blockDim.y-rnoyau ) ;
1236 roi[ idrow + tidX+bdimX +1] = tex2D( tex_img_ins, j+bdimX-rnoyau+1, i+blockDim.y-rnoyau ) ;
1241 // calculs de convolution
1242 for (ic=0 ; ic<L ; ic++)
1243 for( jc=0 ; jc<L ; jc++)
1245 outval0 += (noyau[ ic*L+jc ]*roi[ __mul24(ic+threadIdx.y,(2*blockDim.x+L-1)) + jc+2*threadIdx.x]) ;
1246 outval1 += (noyau[ ic*L+jc ]*roi[ __mul24(ic+threadIdx.y,(2*blockDim.x+L-1)) + jc+2*threadIdx.x+1]) ;
1249 // 1 pixel par thread --> global mem
1250 output[ idx ] = outval0 ;
1251 output[ idx+1 ] = outval1 ;
1254 __global__ void kernel_convoNonSepSh_2p(unsigned char *output, int i_dim, int j_dim, int r)
1258 float outval0=0.0, outval1=0.0 ;
1259 int bdimX = blockDim.x<<1 ;
1260 int tidX = threadIdx.x<<1 ;
1262 // coordonnees absolues du point de base
1263 int j = __umul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
1264 int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1265 int idx = __umul24(i,j_dim) + j ; // indice dans l'image
1267 // chargement en smem
1268 int idrow = threadIdx.y*(bdimX+L-1) ;
1270 extern __shared__ int roi[];
1272 // bloc 0 (en haut \E0 gauche)
1273 roi[ idrow + tidX ] = tex2D( tex_img_inc, j-r , i-r) ;
1274 roi[ idrow + tidX +1 ] = tex2D( tex_img_inc, j-r+1, i-r) ;
1276 // bloc 1 (en haut \E0 droite)...
1277 if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque
1279 roi[ idrow + bdimX + tidX ] = tex2D( tex_img_inc, j+bdimX-r , i-r ) ;
1280 roi[ idrow + bdimX + tidX +1 ] = tex2D( tex_img_inc, j+bdimX-r+1, i-r ) ;
1283 // bloc 2 ( en bas \E0 gauche)
1284 if ( threadIdx.y < L-1 )
1286 idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ;
1287 roi[ idrow + tidX ] = tex2D( tex_img_inc, j-r, i+blockDim.y-r ) ;
1288 roi[ idrow + tidX +1] = tex2D( tex_img_inc, j-r+1, i+blockDim.y-r ) ;
1289 //bloc 4 ( en bas \E0 doite )...
1291 if ( threadIdx.x < r ) //...ou ce qu'il en manque
1293 roi[ idrow + tidX+bdimX ] = tex2D( tex_img_inc, j+bdimX-r , i+blockDim.y-r ) ;
1294 roi[ idrow + tidX+bdimX +1] = tex2D( tex_img_inc, j+bdimX-r+1, i+blockDim.y-r ) ;
1299 // calculs de convolution
1300 for (ic=0 ; ic<L ; ic++)
1301 for( jc=0 ; jc<L ; jc++)
1303 outval0 += (masque[ ic*L+jc ]*roi[ __mul24(ic+threadIdx.y,(bdimX+L-1)) + jc+tidX]) ;
1304 outval1 += (masque[ ic*L+jc ]*roi[ __mul24(ic+threadIdx.y,(bdimX+L-1)) + jc+tidX+1]) ;
1307 // 1 pixel par thread --> global mem
1308 output[ idx ] = outval0 ;
1309 output[ idx+1 ] = outval1 ;
1312 //4 pixels en ligne par thread
1313 __global__ void kernel_convoNonSepSh_4p(unsigned char *output, int i_dim, int j_dim, int r)
1317 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ;
1318 int bdimX = blockDim.x<<2 ;
1319 int tidX = threadIdx.x<<2 ;
1321 // coordonnees absolues du point de base
1322 int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<2 ;
1323 int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1324 int j0= __umul24(blockIdx.x,blockDim.x)<<2 ;
1326 int idx = __umul24(i,j_dim) + j ; // indice dans l'image
1329 // chargement en smem
1330 int idrow = threadIdx.y*(bdimX+L-1) ;
1332 extern __shared__ unsigned char roi4p[];
1334 // bloc 0 (en haut \E0 gauche)
1335 roi4p[ idrow + tidX ] = tex2D(tex_img_inc, j-r , i-r) ;
1336 roi4p[ idrow + tidX +1] = tex2D(tex_img_inc, j-r+1, i-r) ;
1337 roi4p[ idrow + tidX +2] = tex2D(tex_img_inc, j-r+2, i-r) ;
1338 roi4p[ idrow + tidX +3] = tex2D(tex_img_inc, j-r+3, i-r) ;
1340 // bloc 1 (en haut \E0 droite)...
1341 if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque
1343 roi4p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ;
1344 roi4p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ;
1346 // bloc 2 ( en bas \E0 gauche)
1347 if ( threadIdx.y < L-1 )
1349 idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ;
1350 roi4p[ idrow + tidX ] = tex2D( tex_img_inc, j-r , i+blockDim.y-r ) ;
1351 roi4p[ idrow + tidX +1] = tex2D( tex_img_inc, j-r+1, i+blockDim.y-r ) ;
1352 roi4p[ idrow + tidX +2] = tex2D( tex_img_inc, j-r+2, i+blockDim.y-r ) ;
1353 roi4p[ idrow + tidX +3] = tex2D( tex_img_inc, j-r+3, i+blockDim.y-r ) ;
1355 //bloc 4 ( en bas \E0 doite )...
1356 if ( threadIdx.x < r ) //...ou ce qu'il en manque
1358 roi4p[ idrow + bdimX +threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x, i+blockDim.y-r ) ;
1359 roi4p[ idrow + bdimX +threadIdx.x +r] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x, i+blockDim.y-r ) ;
1364 // calculs de convolution
1365 for (ic=0 ; ic<L ; ic++)
1366 for( jc=0 ; jc<L ; jc++)
1368 int baseRoi = __umul24(ic+threadIdx.y,(bdimX+L-1)) + jc+tidX ;
1369 float valMask = masque[ __umul24(ic,L)+jc ] ;
1371 outval0 += valMask*roi4p[ baseRoi ] ;
1372 outval1 += valMask*roi4p[ baseRoi +1 ] ;
1373 outval2 += valMask*roi4p[ baseRoi +2 ] ;
1374 outval3 += valMask*roi4p[ baseRoi +3 ] ;
1377 // 1 pixel par thread --> global mem
1378 output[ idx ] = outval0 ;
1379 output[ idx+1 ] = outval1 ;
1380 output[ idx+2 ] = outval2 ;
1381 output[ idx+3 ] = outval3 ;
1385 //4 pixels en carre par thread
1386 __global__ void kernel_convoNonSepSh_4pcarre(unsigned char *output, int i_dim, int j_dim, int r)
1390 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ;
1391 int bdimX = blockDim.x<<1 ;
1392 int tidX = threadIdx.x<<1 ;
1393 int bdimY = blockDim.y<<1 ;
1394 int tidY = threadIdx.y<<1 ;
1396 // coordonnees absolues du point de base
1397 int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<1 ;
1398 int i = (__umul24( blockIdx.y, blockDim.y) + threadIdx.y)<<1 ;
1399 int j0= __umul24(blockIdx.x,blockDim.x)<<1 ;
1400 int i0= __umul24(blockIdx.y,blockDim.y)<<1 ;
1402 int idx = __umul24(i,j_dim) + j ; // indice dans l'image
1405 // chargement en smem
1406 int idrowBase = tidY*(bdimX+L-1) ;
1407 int idrowSecond = (tidY+1)*(bdimX+L-1) ;
1410 extern __shared__ unsigned char roi4p2[];
1412 // bloc 0 (en haut \E0 gauche)
1413 roi4p2[ idrowBase + tidX ] = tex2D(tex_img_inc, j-r , i-r ) ;
1414 roi4p2[ idrowBase + tidX +1] = tex2D(tex_img_inc, j-r+1, i-r ) ;
1415 roi4p2[ idrowSecond+ tidX ] = tex2D(tex_img_inc, j-r , i-r+1) ;
1416 roi4p2[ idrowSecond+ tidX +1] = tex2D(tex_img_inc, j-r+1, i-r+1) ;
1418 // bloc 1 (en haut \E0 droite)...
1419 if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque
1421 roi4p2[ idrowBase + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ;
1422 roi4p2[ idrowBase + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ;
1423 roi4p2[ idrowSecond + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r+1 ) ;
1424 roi4p2[ idrowSecond + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r+1 ) ;
1426 // bloc 2 ( en bas \E0 gauche)
1427 if ( threadIdx.y < L-1 )
1429 idrowBase = (bdimY + threadIdx.y)*(bdimX+L-1) ;
1430 roi4p2[ idrowBase + tidX ] = tex2D( tex_img_inc, j-r , i0-r +bdimY +threadIdx.y ) ;
1431 roi4p2[ idrowBase + tidX +1] = tex2D( tex_img_inc, j-r+1, i0-r +bdimY +threadIdx.y ) ;
1433 //bloc 4 ( en bas \E0 doite )...
1434 if ( threadIdx.x < r ) //...ou ce qu'il en manque
1436 roi4p2[ idrowBase + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x , i0-r +bdimY +threadIdx.y ) ;
1437 roi4p2[ idrowBase + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x , i0-r +bdimY +threadIdx.y ) ;
1442 // calculs de convolution
1443 for (ic=0 ; ic<L ; ic++)
1444 for( jc=0 ; jc<L ; jc++)
1446 int baseRoi = __umul24(ic+tidY,(bdimX+L-1)) + jc+tidX ;
1447 float valMask = masque[ __umul24(ic,L)+jc ] ;
1449 outval0 += valMask*roi4p2[ baseRoi ] ;
1450 outval1 += valMask*roi4p2[ baseRoi +1 ] ;
1451 outval2 += valMask*roi4p2[ baseRoi +bdimX+L-1 ] ;
1452 outval3 += valMask*roi4p2[ baseRoi +bdimX+L ] ;
1455 // 1 pixel par thread --> global mem
1456 output[ idx ] = outval0 ;
1457 output[ idx+1 ] = outval1 ;
1458 output[ idx+j_dim ] = outval2 ;
1459 output[ idx+j_dim+1 ] = outval3 ;
1463 //8 pixels en ligne par thread
1464 __global__ void kernel_convoNonSepSh_8p(unsigned char *output, int i_dim, int j_dim, int r)
1468 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
1469 int bdimX = blockDim.x<<3 ;
1470 int tidX = threadIdx.x<<3 ;
1472 // coordonnees absolues du point de base
1473 int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ;
1474 int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1475 int j0= __umul24(blockIdx.x,blockDim.x)<<3 ;
1477 int idx = __umul24(i,j_dim) + j ; // indice dans l'image
1480 // chargement en smem
1481 int idrow = threadIdx.y*(bdimX+L-1) ;
1483 extern __shared__ unsigned char roi8p[];
1485 // bloc 0 (en haut \E0 gauche)
1486 for (int p=0; p<8; p++)
1487 roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i-r) ;
1489 // bloc 1 (en haut \E0 droite)...
1490 if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque
1492 roi8p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ;
1493 roi8p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ;
1495 // bloc 2 ( en bas \E0 gauche)
1496 if ( threadIdx.y < L-1 )
1498 idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ;
1499 for (int p=0; p<8; p++)
1500 roi8p[ idrow + tidX +p ] = tex2D( tex_img_inc, j-r+p , i+blockDim.y-r ) ;
1502 //bloc 4 ( en bas \E0 doite )...
1503 if ( threadIdx.x < r ) //...ou ce qu'il en manque
1505 roi8p[ idrow + bdimX +threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x, i+blockDim.y-r ) ;
1506 roi8p[ idrow + bdimX +threadIdx.x +r] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x, i+blockDim.y-r ) ;
1511 // calculs de convolution
1512 for (ic=0 ; ic<L ; ic++)
1513 for( jc=0 ; jc<L ; jc++)
1515 int baseRoi = __umul24(ic+threadIdx.y,(bdimX+L-1)) + jc+tidX ;
1516 float valMask = masque[ __umul24(ic,L)+jc ] ;
1517 outval0 += valMask*roi8p[ baseRoi ] ;
1518 outval1 += valMask*roi8p[ baseRoi +1 ] ;
1519 outval2 += valMask*roi8p[ baseRoi +2 ] ;
1520 outval3 += valMask*roi8p[ baseRoi +3 ] ;
1521 outval4 += valMask*roi8p[ baseRoi +4 ] ;
1522 outval5 += valMask*roi8p[ baseRoi +5 ] ;
1523 outval6 += valMask*roi8p[ baseRoi +6 ] ;
1524 outval7 += valMask*roi8p[ baseRoi +7 ] ;
1527 // 1 pixel par thread --> global mem
1528 output[ idx ] = outval0 ;
1529 output[ idx+1 ] = outval1 ;
1530 output[ idx+2 ] = outval2 ;
1531 output[ idx+3 ] = outval3 ;
1532 output[ idx+4 ] = outval4 ;
1533 output[ idx+5 ] = outval5 ;
1534 output[ idx+6 ] = outval6 ;
1535 output[ idx+7 ] = outval7 ;
1539 //16 pixels en ligne par thread
1540 __global__ void kernel_convoNonSepSh_16p(unsigned char *output, int i_dim, int j_dim, int r)
1544 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
1545 float outval8=0.0, outval9=0.0, outval10=0.0, outval11=0.0, outval12=0.0, outval13=0.0, outval14=0.0, outval15=0.0 ;
1546 int bdimX = blockDim.x<<4 ;
1547 int tidX = threadIdx.x<<4 ;
1549 // coordonnees absolues du point de base
1550 int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<4 ;
1551 int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1552 int j0= __umul24(blockIdx.x,blockDim.x)<<4 ;
1554 int idx = __umul24(i,j_dim) + j ; // indice dans l'image
1557 // chargement en smem
1558 int idrow = threadIdx.y*(bdimX+L-1) ;
1560 extern __shared__ unsigned char roi16p[];
1562 // bloc 0 (en haut \E0 gauche)
1563 for (int p=0; p<16; p++)
1564 roi16p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i-r) ;
1566 // bloc 1 (en haut \E0 droite)...
1567 if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque
1569 roi16p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ;
1570 roi16p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ;
1572 // bloc 2 ( en bas \E0 gauche)
1573 if ( threadIdx.y < L-1 )
1575 idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ;
1576 for (int p=0; p<16; p++)
1577 roi16p[ idrow + tidX +p ] = tex2D( tex_img_inc, j-r+p , i+blockDim.y-r ) ;
1579 //bloc 4 ( en bas \E0 doite )...
1580 if ( threadIdx.x < r ) //...ou ce qu'il en manque
1582 roi16p[ idrow + bdimX +threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x, i+blockDim.y-r ) ;
1583 roi16p[ idrow + bdimX +threadIdx.x +r] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x, i+blockDim.y-r ) ;
1588 // calculs de convolution
1589 for (ic=0 ; ic<L ; ic++)
1590 for( jc=0 ; jc<L ; jc++)
1592 int baseRoi = __umul24(ic+threadIdx.y,(bdimX+L-1)) + jc+tidX ;
1593 float valMask = masque[ __umul24(ic,L)+jc ] ;
1594 outval0 += valMask*roi16p[ baseRoi ] ;
1595 outval1 += valMask*roi16p[ baseRoi +1 ] ;
1596 outval2 += valMask*roi16p[ baseRoi +2 ] ;
1597 outval3 += valMask*roi16p[ baseRoi +3 ] ;
1598 outval4 += valMask*roi16p[ baseRoi +4 ] ;
1599 outval5 += valMask*roi16p[ baseRoi +5 ] ;
1600 outval6 += valMask*roi16p[ baseRoi +6 ] ;
1601 outval7 += valMask*roi16p[ baseRoi +7 ] ;
1602 outval8 += valMask*roi16p[ baseRoi +8] ;
1603 outval9 += valMask*roi16p[ baseRoi +9 ] ;
1604 outval10 += valMask*roi16p[ baseRoi +10 ] ;
1605 outval11 += valMask*roi16p[ baseRoi +11 ] ;
1606 outval12 += valMask*roi16p[ baseRoi +12 ] ;
1607 outval13 += valMask*roi16p[ baseRoi +13 ] ;
1608 outval14 += valMask*roi16p[ baseRoi +14 ] ;
1609 outval15 += valMask*roi16p[ baseRoi +15 ] ;
1612 // 1 pixel par thread --> global mem
1613 output[ idx ] = outval0 ;
1614 output[ idx+1 ] = outval1 ;
1615 output[ idx+2 ] = outval2 ;
1616 output[ idx+3 ] = outval3 ;
1617 output[ idx+4 ] = outval4 ;
1618 output[ idx+5 ] = outval5 ;
1619 output[ idx+6 ] = outval6 ;
1620 output[ idx+7 ] = outval7 ;
1621 output[ idx+8 ] = outval8 ;
1622 output[ idx+9 ] = outval9 ;
1623 output[ idx+10 ] = outval10 ;
1624 output[ idx+11 ] = outval11 ;
1625 output[ idx+12 ] = outval12 ;
1626 output[ idx+13 ] = outval13 ;
1627 output[ idx+14 ] = outval14 ;
1628 output[ idx+15 ] = outval15 ;
1633 // convolution non separable
1634 // image en texture et noyau en mem constante
1635 // fetch direct des pixels
1636 // 2 pixels traités par thread => meilleur débit
1637 __global__ void kernel_convoNonSep_2p( int *output, int i_dim, int j_dim)
1643 float outval0=0, outval1=0 ;
1645 // coordonnees absolues du point de base
1646 int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x, 2) ;
1647 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1648 int idx = __mul24(i, j_dim) + j ; // indice dans l'image
1651 for (idb=0 ; idb< N ; idb++)
1654 jc = j-r + idb - (idb/L)*L ;
1655 outval0 += ( noyau[ idb ]*tex2D(tex_img_in, jc, ic)) ;
1656 outval1 += ( noyau[ idb ]*tex2D(tex_img_in, jc+1, ic)) ;
1659 output[ idx ] = outval0 ;
1660 output[ idx+1 ] = outval1 ;
1666 // convolution non separable
1667 // image en texture et noyau en mem constante
1668 // fetch direct des pixels
1669 // 2 pixels traités par thread => meilleur débit
1670 __global__ void kernel_convoNonSep_2p_s( unsigned short*output, int i_dim, int j_dim)
1676 float outval0=0, outval1=0 ;
1678 // coordonnees absolues du point de base
1679 int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x, 2) ;
1680 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1681 int idx = __mul24(i, j_dim) + j ; // indice dans l'image
1684 for (idb=0 ; idb< N ; idb++)
1687 jc = j-r + idb - (idb/L)*L ;
1688 outval0 += ( noyau[ idb ]*tex2D(tex_img_ins, jc, ic)) ;
1689 outval1 += ( noyau[ idb ]*tex2D(tex_img_ins, jc+1, ic)) ;
1692 output[ idx ] = outval0 ;
1693 output[ idx+1 ] = outval1 ;
1699 // convolution separable
1700 // image en texture et noyau en mem constante
1701 __global__ void kernel_convoSep8V( unsigned char *output, int i_dim, int j_dim, int r)
1707 // coordonnees absolues du point de base
1708 int j = __mul24( blockIdx.x, blockDim.x ) + threadIdx.x ;
1709 int i = __mul24( blockIdx.y, blockDim.y ) + threadIdx.y ;
1712 for (ic=0 ; ic<L ; ic++)
1713 outval0 += masque[ ic ]*tex2D(tex_img_inc, j, i-r+ic) ;
1715 output[ __mul24(i, j_dim) + j ] = outval0 ;
1721 __global__ void kernel_convoSep8H( unsigned char *output, int i_dim, int j_dim, int r)
1727 // coordonnees absolues du point de base
1728 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
1729 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
1732 for (jc=0 ; jc<L ; jc++)
1733 outval0 += masque[ L+jc ]*tex2D(tex_img_inc, j-r+jc, i) ;
1735 output[ __mul24(i, j_dim) + j ] = outval0 ;
1738 // convolution separable
1739 // image en texture et noyau en mem constante
1740 __global__ void kernel_convoSep8Vx8p( unsigned char *output, int i_dim, int j_dim, int r)
1744 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
1746 // coordonnees absolues du point de base
1747 int j = (__mul24( blockIdx.x, blockDim.x ) + threadIdx.x)<<3 ;
1748 int i = __mul24( blockIdx.y, blockDim.y ) + threadIdx.y ;
1751 for (ic=0 ; ic<L ; ic++)
1753 float valMask = masque[ ic ] ;
1754 outval0 += valMask*tex2D(tex_img_inc, j , i-r+ic) ;
1755 outval1 += valMask*tex2D(tex_img_inc, j+1, i-r+ic) ;
1756 outval2 += valMask*tex2D(tex_img_inc, j+2, i-r+ic) ;
1757 outval3 += valMask*tex2D(tex_img_inc, j+3, i-r+ic) ;
1758 outval4 += valMask*tex2D(tex_img_inc, j+4, i-r+ic) ;
1759 outval5 += valMask*tex2D(tex_img_inc, j+5, i-r+ic) ;
1760 outval6 += valMask*tex2D(tex_img_inc, j+6, i-r+ic) ;
1761 outval7 += valMask*tex2D(tex_img_inc, j+7, i-r+ic) ;
1764 baseIdx = __mul24(i , j_dim) + j ;
1765 output[ baseIdx++ ] = outval0 ;
1766 output[ baseIdx++ ] = outval1 ;
1767 output[ baseIdx++ ] = outval2 ;
1768 output[ baseIdx++ ] = outval3 ;
1769 output[ baseIdx++ ] = outval4 ;
1770 output[ baseIdx++ ] = outval5 ;
1771 output[ baseIdx++ ] = outval6 ;
1772 output[ baseIdx++ ] = outval7 ;
1777 // convolution separable
1778 // image en texture et noyau en mem constante
1779 __global__ void kernel_convoSep8HL3x8p( unsigned char *output, int i_dim, int j_dim)
1783 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
1785 // coordonnees absolues du point de base
1786 int j = (__mul24( blockIdx.x, blockDim.x ) + threadIdx.x)<<3 ;
1787 int i = __mul24( blockIdx.y, blockDim.y ) + threadIdx.y ;
1790 val = tex2D(tex_img_inc, j-1 , i) ;
1792 outval0 += masque[0]*val ;
1794 val = tex2D(tex_img_inc, j , i) ;
1795 outval0 += masque[1]*val ;
1796 outval1 += masque[0]*val ;
1798 val = tex2D(tex_img_inc, j+1 , i) ;
1799 outval0 += masque[2]*val ;
1800 outval1 += masque[1]*val ;
1801 outval2 += masque[0]*val ;
1803 val = tex2D(tex_img_inc, j+2 , i) ;
1804 outval1 += masque[2]*val ;
1805 outval2 += masque[1]*val ;
1806 outval3 += masque[0]*val ;
1808 val = tex2D(tex_img_inc, j+3 , i) ;
1809 outval2 += masque[2]*val ;
1810 outval3 += masque[1]*val ;
1811 outval4 += masque[0]*val ;
1813 val = tex2D(tex_img_inc, j+4 , i) ;
1814 outval3 += masque[2]*val ;
1815 outval4 += masque[1]*val ;
1816 outval5 += masque[0]*val ;
1818 val = tex2D(tex_img_inc, j+5 , i) ;
1819 outval4 += masque[2]*val ;
1820 outval5 += masque[1]*val ;
1821 outval6 += masque[0]*val ;
1823 val = tex2D(tex_img_inc, j+6 , i) ;
1824 outval5 += masque[2]*val ;
1825 outval6 += masque[1]*val ;
1826 outval7 += masque[0]*val ;
1828 val = tex2D(tex_img_inc, j+7 , i) ;
1829 outval6 += masque[2]*val ;
1830 outval7 += masque[1]*val ;
1832 val = tex2D(tex_img_inc, j+8 , i) ;
1833 outval7 += masque[2]*val ;
1835 baseIdx = __mul24(i , j_dim) + j ;
1836 output[ baseIdx++ ] = outval0 ;
1837 output[ baseIdx++ ] = outval1 ;
1838 output[ baseIdx++ ] = outval2 ;
1839 output[ baseIdx++ ] = outval3 ;
1840 output[ baseIdx++ ] = outval4 ;
1841 output[ baseIdx++ ] = outval5 ;
1842 output[ baseIdx++ ] = outval6 ;
1843 output[ baseIdx++ ] = outval7 ;
1847 // convolution separable
1848 // image en texture et noyau en mem constante
1849 __global__ void kernel_convoSep8HL3x8pG( unsigned char *input, unsigned char *output, int i_dim, int j_dim)
1851 int jc, baseIdx, id ;
1853 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
1855 // coordonnees absolues du point de base
1856 int j = (__mul24( blockIdx.x, blockDim.x ) + threadIdx.x)<<3 ;
1857 int i = __mul24( blockIdx.y, blockDim.y ) + threadIdx.y ;
1860 baseIdx = __mul24(i , j_dim) + j ;
1861 if (baseIdx >0 ) id = baseIdx-1 ; else id = baseIdx ;
1864 outval0 += masque[0]*val ;
1866 val = input[baseIdx++] ;
1867 outval0 += masque[1]*val ;
1868 outval1 += masque[0]*val ;
1870 val = input[baseIdx++] ;
1871 outval0 += masque[2]*val ;
1872 outval1 += masque[1]*val ;
1873 outval2 += masque[0]*val ;
1875 val = input[baseIdx++] ;
1876 outval1 += masque[2]*val ;
1877 outval2 += masque[1]*val ;
1878 outval3 += masque[0]*val ;
1880 val = input[baseIdx++] ;
1881 outval2 += masque[2]*val ;
1882 outval3 += masque[1]*val ;
1883 outval4 += masque[0]*val ;
1885 val = input[baseIdx++] ;
1886 outval3 += masque[2]*val ;
1887 outval4 += masque[1]*val ;
1888 outval5 += masque[0]*val ;
1890 val = input[baseIdx++] ;
1891 outval4 += masque[2]*val ;
1892 outval5 += masque[1]*val ;
1893 outval6 += masque[0]*val ;
1895 val = input[baseIdx++] ;
1896 outval5 += masque[2]*val ;
1897 outval6 += masque[1]*val ;
1898 outval7 += masque[0]*val ;
1900 val = input[baseIdx++] ;
1901 outval6 += masque[2]*val ;
1902 outval7 += masque[1]*val ;
1904 val = input[baseIdx++] ;
1905 outval7 += masque[2]*val ;
1907 baseIdx = __mul24(i , j_dim) + j ;
1908 output[ baseIdx++ ] = outval0 ;
1909 output[ baseIdx++ ] = outval1 ;
1910 output[ baseIdx++ ] = outval2 ;
1911 output[ baseIdx++ ] = outval3 ;
1912 output[ baseIdx++ ] = outval4 ;
1913 output[ baseIdx++ ] = outval5 ;
1914 output[ baseIdx++ ] = outval6 ;
1915 output[ baseIdx++ ] = outval7 ;
1918 // convolution separable
1919 // image en texture et noyau en mem constante
1920 __global__ void kernel_convoSep8HL5x8pG( unsigned char *input, unsigned char *output, int i_dim, int j_dim)
1922 int jc, baseIdx, id ;
1923 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
1925 // coordonnees absolues du point de base
1926 int j = (__mul24( blockIdx.x, blockDim.x ) + threadIdx.x)<<3 ;
1927 int i = __mul24( blockIdx.y, blockDim.y ) + threadIdx.y ;
1930 baseIdx = __mul24(i , j_dim) + j ;
1931 if (baseIdx >1 ) id = baseIdx-2 ; else id = baseIdx ;
1934 outval0 += masque[0]*val ;
1936 if (baseIdx >0 ) id = baseIdx-1 ; else id = baseIdx ;
1938 outval0 += masque[1]*val ;
1939 outval1 += masque[0]*val ;
1941 val = input[baseIdx++] ;
1942 outval0 += masque[2]*val ;
1943 outval1 += masque[1]*val ;
1944 outval2 += masque[0]*val ;
1946 val = input[baseIdx++] ;
1947 outval0 += masque[3]*val ;
1948 outval1 += masque[2]*val ;
1949 outval2 += masque[1]*val ;
1950 outval3 += masque[0]*val ;
1952 val = input[baseIdx++] ;
1953 outval0 += masque[4]*val ;
1954 outval1 += masque[3]*val ;
1955 outval2 += masque[2]*val ;
1956 outval3 += masque[1]*val ;
1957 outval4 += masque[0]*val ;
1959 val = input[baseIdx++] ;
1960 outval1 += masque[4]*val ;
1961 outval2 += masque[3]*val ;
1962 outval3 += masque[2]*val ;
1963 outval4 += masque[1]*val ;
1964 outval5 += masque[0]*val ;
1966 val = input[baseIdx++] ;
1967 outval2 += masque[4]*val ;
1968 outval3 += masque[3]*val ;
1969 outval4 += masque[2]*val ;
1970 outval5 += masque[1]*val ;
1971 outval6 += masque[0]*val ;
1973 val = input[baseIdx++] ;
1974 outval3 += masque[4]*val ;
1975 outval4 += masque[3]*val ;
1976 outval5 += masque[2]*val ;
1977 outval6 += masque[1]*val ;
1978 outval7 += masque[0]*val ;
1980 val = input[baseIdx++] ;
1981 outval4 += masque[4]*val ;
1982 outval5 += masque[3]*val ;
1983 outval6 += masque[2]*val ;
1984 outval7 += masque[1]*val ;
1986 val = input[baseIdx++] ;
1987 outval5 += masque[4]*val ;
1988 outval6 += masque[3]*val ;
1989 outval7 += masque[2]*val ;
1991 val = input[baseIdx++] ;
1992 outval6 += masque[4]*val ;
1993 outval7 += masque[3]*val ;
1995 val = input[baseIdx++] ;
1996 outval7 += masque[4]*val ;
1999 baseIdx = __mul24(i , j_dim) + j ;
2000 output[ baseIdx++ ] = outval0 ;
2001 output[ baseIdx++ ] = outval1 ;
2002 output[ baseIdx++ ] = outval2 ;
2003 output[ baseIdx++ ] = outval3 ;
2004 output[ baseIdx++ ] = outval4 ;
2005 output[ baseIdx++ ] = outval5 ;
2006 output[ baseIdx++ ] = outval6 ;
2007 output[ baseIdx++ ] = outval7 ;
2010 // convolution separable
2011 // image en texture et noyau en mem constante
2012 __global__ void kernel_convoSep8HL7x8pG( unsigned char *input, unsigned char *output, int i_dim, int j_dim)
2014 int jc, baseIdx, id ;
2015 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
2017 // coordonnees absolues du point de base
2018 int j = (__mul24( blockIdx.x, blockDim.x ) + threadIdx.x)<<3 ;
2019 int i = __mul24( blockIdx.y, blockDim.y ) + threadIdx.y ;
2022 baseIdx = __mul24(i , j_dim) + j ;
2023 if (baseIdx >2 ) id = baseIdx-3 ; else id = baseIdx ;
2026 outval0 += masque[0]*val ;
2028 if (baseIdx >1 ) id = baseIdx-2 ; else id = baseIdx ;
2030 outval0 += masque[1]*val ;
2031 outval1 += masque[0]*val ;
2033 if (baseIdx >0 ) id = baseIdx-1 ; else id = baseIdx ;
2035 outval0 += masque[2]*val ;
2036 outval1 += masque[1]*val ;
2037 outval2 += masque[0]*val ;
2039 val = input[baseIdx++] ;
2040 outval0 += masque[3]*val ;
2041 outval1 += masque[2]*val ;
2042 outval2 += masque[1]*val ;
2043 outval3 += masque[0]*val ;
2045 val = input[baseIdx++] ;
2046 outval0 += masque[4]*val ;
2047 outval1 += masque[3]*val ;
2048 outval2 += masque[2]*val ;
2049 outval3 += masque[1]*val ;
2050 outval4 += masque[0]*val ;
2052 val = input[baseIdx++] ;
2053 outval0 += masque[5]*val ;
2054 outval1 += masque[4]*val ;
2055 outval2 += masque[3]*val ;
2056 outval3 += masque[2]*val ;
2057 outval4 += masque[1]*val ;
2058 outval5 += masque[0]*val ;
2060 val = input[baseIdx++] ;
2061 outval0 += masque[6]*val ;
2062 outval1 += masque[5]*val ;
2063 outval2 += masque[4]*val ;
2064 outval3 += masque[3]*val ;
2065 outval4 += masque[2]*val ;
2066 outval5 += masque[1]*val ;
2067 outval6 += masque[0]*val ;
2069 val = input[baseIdx++] ;
2070 outval1 += masque[6]*val ;
2071 outval2 += masque[5]*val ;
2072 outval3 += masque[4]*val ;
2073 outval4 += masque[3]*val ;
2074 outval5 += masque[2]*val ;
2075 outval6 += masque[1]*val ;
2076 outval7 += masque[0]*val ;
2078 val = input[baseIdx++] ;
2079 outval2 += masque[6]*val ;
2080 outval3 += masque[5]*val ;
2081 outval4 += masque[4]*val ;
2082 outval5 += masque[3]*val ;
2083 outval6 += masque[2]*val ;
2084 outval7 += masque[1]*val ;
2086 val = input[baseIdx++] ;
2087 outval3 += masque[6]*val ;
2088 outval4 += masque[5]*val ;
2089 outval5 += masque[4]*val ;
2090 outval6 += masque[3]*val ;
2091 outval7 += masque[2]*val ;
2093 val = input[baseIdx++] ;
2094 outval4 += masque[6]*val ;
2095 outval5 += masque[5]*val ;
2096 outval6 += masque[4]*val ;
2097 outval7 += masque[3]*val ;
2099 val = input[baseIdx++] ;
2100 outval5 += masque[6]*val ;
2101 outval6 += masque[5]*val ;
2102 outval7 += masque[4]*val ;
2104 val = input[baseIdx++] ;
2105 outval6 += masque[6]*val ;
2106 outval7 += masque[5]*val ;
2108 val = input[baseIdx++] ;
2109 outval7 += masque[6]*val ;
2111 baseIdx = __mul24(i , j_dim) + j ;
2112 output[ baseIdx++ ] = outval0 ;
2113 output[ baseIdx++ ] = outval1 ;
2114 output[ baseIdx++ ] = outval2 ;
2115 output[ baseIdx++ ] = outval3 ;
2116 output[ baseIdx++ ] = outval4 ;
2117 output[ baseIdx++ ] = outval5 ;
2118 output[ baseIdx++ ] = outval6 ;
2119 output[ baseIdx++ ] = outval7 ;
2123 //8 pixels en ligne par thread
2124 __global__ void kernel_convoSepShx8pV(unsigned char *output, int i_dim, int j_dim, int r)
2128 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
2129 int bdimX = blockDim.x<<3 ;
2130 int tidX = threadIdx.x<<3 ;
2132 // coordonnees absolues du point de base
2133 int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ;
2134 int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ;
2136 int idx = __umul24(i,j_dim) + j ; // indice dans l'image
2139 // chargement en smem
2140 int idrow = threadIdx.y*bdimX ;
2142 extern __shared__ unsigned char roi8p[];
2146 roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j+p , i-r) ;
2150 if ( threadIdx.y < L-1 )
2152 idrow = (threadIdx.y+blockDim.y)*bdimX ;
2153 for (int p=0; p<8; p++)
2154 roi8p[ idrow + tidX +p ] = tex2D( tex_img_inc, j+p , i+blockDim.y-r ) ;
2159 // calculs de convolution
2161 for (ic=0 ; ic<L ; ic++)
2163 int baseRoi = __umul24(ic+threadIdx.y,bdimX) + tidX ;
2164 float valMask = masque[ ic ] ;
2165 outval0 += valMask*roi8p[ baseRoi ] ;
2166 outval1 += valMask*roi8p[ baseRoi +1 ] ;
2167 outval2 += valMask*roi8p[ baseRoi +2 ] ;
2168 outval3 += valMask*roi8p[ baseRoi +3 ] ;
2169 outval4 += valMask*roi8p[ baseRoi +4 ] ;
2170 outval5 += valMask*roi8p[ baseRoi +5 ] ;
2171 outval6 += valMask*roi8p[ baseRoi +6 ] ;
2172 outval7 += valMask*roi8p[ baseRoi +7 ] ;
2175 // 8 pixel par thread --> global mem
2176 output[ idx ] = outval0 ;
2177 output[ idx+1 ] = outval1 ;
2178 output[ idx+2 ] = outval2 ;
2179 output[ idx+3 ] = outval3 ;
2180 output[ idx+4 ] = outval4 ;
2181 output[ idx+5 ] = outval5 ;
2182 output[ idx+6 ] = outval6 ;
2183 output[ idx+7 ] = outval7 ;
2186 //8 pixels en ligne par thread
2187 __global__ void kernel_convoSepShx8pVG(unsigned char *input, unsigned char *output, int i_dim, int j_dim, int r)
2191 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
2192 int bdimX = blockDim.x<<3 ;
2193 int tidX = threadIdx.x<<3 ;
2195 // coordonnees absolues du point de base
2196 int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ;
2197 int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ;
2199 int idx = __umul24(i,j_dim) + j ; // indice dans l'image
2202 // chargement en smem
2203 int idrow = threadIdx.y*bdimX ;
2205 extern __shared__ unsigned char roi8p[];
2209 roi8p[ idrow + tidX +p ] = input[ (i-r)*j_dim + j+p ] ;
2213 if ( threadIdx.y < L-1 )
2215 idrow = (threadIdx.y+blockDim.y)*bdimX ;
2216 for (int p=0; p<8; p++)
2217 roi8p[ idrow + tidX +p ] = input[ (i+blockDim.y-r)*j_dim + j+p ] ;
2222 // calculs de convolution
2224 for (ic=0 ; ic<L ; ic++)
2226 int baseRoi = __umul24(ic+threadIdx.y,bdimX) + tidX ;
2227 float valMask = masque[ ic ] ;
2228 outval0 += valMask*roi8p[ baseRoi ] ;
2229 outval1 += valMask*roi8p[ baseRoi +1 ] ;
2230 outval2 += valMask*roi8p[ baseRoi +2 ] ;
2231 outval3 += valMask*roi8p[ baseRoi +3 ] ;
2232 outval4 += valMask*roi8p[ baseRoi +4 ] ;
2233 outval5 += valMask*roi8p[ baseRoi +5 ] ;
2234 outval6 += valMask*roi8p[ baseRoi +6 ] ;
2235 outval7 += valMask*roi8p[ baseRoi +7 ] ;
2238 // 8 pixel par thread --> global mem
2239 output[ idx ] = outval0 ;
2240 output[ idx+1 ] = outval1 ;
2241 output[ idx+2 ] = outval2 ;
2242 output[ idx+3 ] = outval3 ;
2243 output[ idx+4 ] = outval4 ;
2244 output[ idx+5 ] = outval5 ;
2245 output[ idx+6 ] = outval6 ;
2246 output[ idx+7 ] = outval7 ;
2250 __global__ void kernel_convoSepShx8pH(unsigned char *output, int i_dim, int j_dim, int r)
2254 float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ;
2255 int bdimX = blockDim.x<<3 ;
2256 int tidX = threadIdx.x<<3 ;
2258 // coordonnees absolues du point de base
2259 int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ;
2260 int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ;
2261 int j0= __umul24(blockIdx.x,blockDim.x)<<3 ;
2262 int idx = __umul24(i,j_dim) + j ; // indice dans l'image
2265 // chargement en smem
2266 int idrow = threadIdx.y*(bdimX+L-1) ;
2268 extern __shared__ unsigned char roi8p[];
2270 // bloc 0 (a gauche)
2272 roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i) ;
2275 if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque
2277 roi8p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i ) ;
2278 roi8p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i ) ;
2283 // calculs de convolution
2284 // passe horizontale
2285 for (jc=0 ; jc<L ; jc++)
2287 int baseRoi = idrow + tidX +jc ;
2288 float valMask = masque[ jc ] ;
2289 outval0 += valMask*roi8p[ baseRoi ] ;
2290 outval1 += valMask*roi8p[ baseRoi +1 ] ;
2291 outval2 += valMask*roi8p[ baseRoi +2 ] ;
2292 outval3 += valMask*roi8p[ baseRoi +3 ] ;
2293 outval4 += valMask*roi8p[ baseRoi +4 ] ;
2294 outval5 += valMask*roi8p[ baseRoi +5 ] ;
2295 outval6 += valMask*roi8p[ baseRoi +6 ] ;
2296 outval7 += valMask*roi8p[ baseRoi +7 ] ;
2299 // 1 pixel par thread --> global mem
2300 output[ idx ] = outval0 ;
2301 output[ idx+1 ] = outval1 ;
2302 output[ idx+2 ] = outval2 ;
2303 output[ idx+3 ] = outval3 ;
2304 output[ idx+4 ] = outval4 ;
2305 output[ idx+5 ] = outval5 ;
2306 output[ idx+6 ] = outval6 ;
2307 output[ idx+7 ] = outval7 ;
2311 /*************************************************************************************************
2312 ***********************************************************************************************
2314 FIN DES kERNELS de CONVOLUTION
2316 ***********************************************************************************************
2317 *************************************************************************************************/
2318 // kernel de la libjacket
2319 // Exchange trick: Morgan McGuire, ShaderX 2008
2320 #define s2(a,b) { float tmp = a; a = min(a,b); b = max(tmp,b); }
2321 #define mn3(a,b,c) s2(a,b); s2(a,c);
2322 #define mx3(a,b,c) s2(b,c); s2(a,c);
2324 #define mnmx3(a,b,c) mx3(a,b,c); s2(a,b); // 3 exchanges
2325 #define mnmx4(a,b,c,d) s2(a,b); s2(c,d); s2(a,c); s2(b,d); // 4 exchanges
2326 #define mnmx5(a,b,c,d,e) s2(a,b); s2(c,d); mn3(a,c,e); mx3(b,d,e); // 6 exchanges
2327 #define mnmx6(a,b,c,d,e,f) s2(a,d); s2(b,e); s2(c,f); mn3(a,b,c); mx3(d,e,f); // 7 exchanges
2329 #define IN(X,Y) ((0 <= (X) && (X) < nx && 0 <= (Y) && (Y) < ny) ? d_in[(Y)*nx+(X)] : 0)
2331 __global__ static void kernel_medjacket(int nx, int ny, unsigned short*d_out, unsigned short*d_in)
2333 int x = __mul24(blockIdx.x , blockDim.x) + threadIdx.x;
2334 int y = __mul24(blockIdx.y , blockDim.y) + threadIdx.y;
2336 // pull top six from image
2337 float v[6] = { IN(x-1, y-1), IN(x , y-1), IN(x+1, y-1),
2338 IN(x-1, y ), IN(x , y ), IN(x+1, y ) };
2340 // with each pass, remove min and max values and add new value
2341 mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]);
2342 v[5] = IN(x-1, y+1); // add new contestant
2343 mnmx5(v[1], v[2], v[3], v[4], v[5]);
2344 v[5] = IN(x , y+1); // add new contestant
2345 mnmx4(v[2], v[3], v[4], v[5]);
2346 v[5] = IN(x+1, y+1); // add last contenstant
2347 mnmx3(v[3], v[4], v[5]);
2349 // pick the middle one
2350 d_out[y*nx + x] = v[4];
2354 /***************************************************************
2355 * fonction de tri de 2 valeurs entieres (min en premier)
2356 ***************************************************************/
2357 __device__ inline void s(int* a, int* b)
2369 __device__ inline void s(unsigned short * a, unsigned short* b)
2372 unsigned short tmp ;
2381 __device__ inline void s(unsigned char * a, unsigned char * b)
2384 unsigned short tmp ;
2393 /***************************************************************
2394 * fonction de min-max d'un tableau de n valeurs entieres
2395 ***************************************************************/
2396 __device__ void minmaxN(unsigned short* v, int n)
2398 for (int i=1; i< n; i++)
2400 for (int i=n-2; i>0; i--)
2404 /***************************************************************
2405 * fonction de tri naif d'un tableau de n valeurs entieres
2406 ***************************************************************/
2407 __device__ void bubTriN(int * v, int n)
2409 for (int i=0; i< n-1; i++)
2410 for (int j=i+1; j<n; j++)
2415 /*****************************************************************************************
2416 * MACROS pour tri min-max utilisant la fonction de tri s(a,b) ci-dessus
2417 *****************************************************************************************/
2418 #define min3(a, b, c) s(a, b); s(a, c);
2419 #define max3(a, b, c) s(b, c); s(a, c);
2420 #define minmax3(a, b, c) max3(a, b, c); s(a, b); // max 3
2421 #define minmax4(a, b, c, d) s(a, b); s(c, d); s(a, c); s(b, d); //max 4
2422 #define minmax5(a, b, c, d, e) s(a, b); s(c, d); min3(a, c, e); max3(b, d, e); //max 6
2423 #define minmax6(a, b, c, d, e, f) s(a,d); s(b, e); s(c, f); min3(a, b, c); max3(d, e, f); //max 7
2425 /***************************************************************
2426 * fonction de tri de 9 valeurs entieres
2427 ***************************************************************/
2428 #define bubTriReg9(a, b, c, d, e, f, g, h, i) s(a,b);s(c,d);s(e,f);minmax3(g,h,i);s(a,c);s(e,g);s(a,e);s(b,c);s(d,e);s(f,g);s(b,d);s(f,h);s(b,f);s(c,d);s(e,f);minmax3(g,h,i);s(c,e);s(c,g);s(d,e);s(f,g);s(d,f);s(d,h);s(e,f);minmax3(g,h,i);s(e,g);
2431 __global__ void kernel_bubMedian3( unsigned short*output, int i_dim, int j_dim)
2434 // coordonnees absolues du point
2435 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
2436 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
2438 /**************************************************************************
2440 **************************************************************************/
2441 int a0, a1, a2, a3, a4, a5, a6, a7, a8 ;
2443 /********************************************************************************
2444 * affectation des valeurs
2445 ********************************************************************************/
2446 a0 = tex2D(tex_img_ins, j-1, i-1) ;
2447 a1 = tex2D(tex_img_ins, j , i-1) ;
2448 a2 = tex2D(tex_img_ins, j+1, i-1) ;
2449 a3 = tex2D(tex_img_ins, j-1, i) ;
2450 a4 = tex2D(tex_img_ins, j , i) ;
2451 a5 = tex2D(tex_img_ins, j+1, i) ;
2452 a6 = tex2D(tex_img_ins, j-1, i+1) ;
2453 a7 = tex2D(tex_img_ins, j , i+1) ;
2454 a8 = tex2D(tex_img_ins, j+1, i+1) ;
2457 bubTriReg9(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8);
2459 //median au milieu !
2460 output[ __mul24(i, j_dim) +j ] = a4 ;
2463 __global__ void kernel_median3( unsigned short*output, int i_dim, int j_dim)
2466 // coordonnees absolues du point
2467 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
2468 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
2470 /**************************************************************************
2472 **************************************************************************/
2473 int a0, a1, a2, a3, a4, a5 ;
2475 /********************************************************************************
2476 * les six premieres valeurs (suffisant pour median 3x3 par forgetfull selection)
2477 ********************************************************************************/
2478 a0 = tex2D(tex_img_ins, j-1, i-1) ;
2479 a1 = tex2D(tex_img_ins, j, i-1) ;
2480 a2 = tex2D(tex_img_ins, j+1, i-1) ;
2481 a3 = tex2D(tex_img_ins, j-1, i) ;
2482 a4 = tex2D(tex_img_ins, j, i) ;
2483 a5 = tex2D(tex_img_ins, j+1, i) ;
2486 //min max aux extremites
2487 minmax6(&a0, &a1, &a2, &a3, &a4, &a5) ;
2489 /********************************************
2490 * les deux valeurs suivantes aux extremites
2491 ********************************************/
2492 a5 = tex2D(tex_img_in, j-1, i+1) ;
2494 minmax5(&a1, &a2, &a3, &a4, &a5) ;
2496 /********************************************
2497 * la derniere valeur a la fin
2498 ********************************************/
2500 a5 = tex2D(tex_img_ins, j, i+1) ;
2502 minmax4(&a2, &a3, &a4, &a5) ;
2504 a5 = tex2D(tex_img_ins, j+1, i+1) ;
2505 minmax3(&a3, &a4, &a5) ;
2508 //median au milieu !
2509 output[ __mul24(i, j_dim) +j ] = a4 ;
2513 __global__ void kernel_median3Sh( unsigned short*output, int i_dim, int j_dim)
2518 // coordonnees absolues du point de base
2519 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
2520 int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ;
2521 int idx = __mul24(i,j_dim) + j ; // indice dans l'image
2523 // chargement en smem
2524 int idrow = threadIdx.y*(blockDim.x+2) ;
2526 extern __shared__ int medRoi[];
2528 // bloc 0 (en haut \E0 gauche)
2529 medRoi[ idrow + threadIdx.x ] = tex2D(tex_img_ins, j-1, i-1) ;
2530 // bloc 1 (en haut \E0 droite)...
2531 if ( threadIdx.x < L-1 ) //...ou plutot ce qu'il en manque
2532 medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-1, i-1 ) ;
2533 // bloc 2 ( en bas \E0 gauche)
2534 if ( threadIdx.y < L-1 )
2536 idrow = (threadIdx.y+blockDim.y)*(blockDim.x+L-1) ;
2537 medRoi[ idrow + threadIdx.x ] = tex2D( tex_img_ins, j-1, i+blockDim.y-1 ) ;
2538 //bloc 4 ( en bas \E0 doite )...
2539 if ( threadIdx.x < L-1 ) //...ou ce qu'il en manque
2540 medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-1, i+blockDim.y-1 ) ;
2544 /**************************************************************************
2546 **************************************************************************/
2547 int a0, a1, a2, a3, a4, a5 ;
2549 /********************************************************************************
2550 * les six premieres valeurs (suffisant pour median 3x3 par forgetfull selection)
2551 ********************************************************************************/
2552 // l'index dans medRoi est du type (threadIdx.y+ic)*(blockDim.X+L-1)+ (threadIdx.x+jc)
2553 // ou ic,jc sont les coordonnees du point dans le noyau 3x3
2554 a0 = medRoi[ (threadIdx.y)*(blockDim.x+L-1)+ (threadIdx.x+1) ] ;
2555 a1 = medRoi[ (threadIdx.y)*(blockDim.x+L-1)+ (threadIdx.x+2) ] ;
2556 a2 = medRoi[ (threadIdx.y+1)*(blockDim.x+L-1)+ (threadIdx.x+1)] ;
2557 a3 = medRoi[ (threadIdx.y+1)*(blockDim.x+L-1)+ (threadIdx.x+2)] ;
2558 a4 = medRoi[ (threadIdx.y+2)*(blockDim.x+L-1)+ (threadIdx.x+1)] ;
2559 a5 = medRoi[ (threadIdx.y+2)*(blockDim.x+L-1)+ (threadIdx.x+2)] ;
2562 //min max aux extremites
2563 minmax6(&a0, &a1, &a2, &a3, &a4, &a5) ;
2565 /********************************************
2566 * les deux valeurs suivantes aux extremites
2567 ********************************************/
2568 a5 = medRoi[ (threadIdx.y)*(blockDim.x+L-1)+ (threadIdx.x)] ;
2570 minmax5(&a1, &a2, &a3, &a4, &a5) ;
2572 /********************************************
2573 * la derniere valeur a la fin
2574 ********************************************/
2576 a5 = medRoi[ (threadIdx.y+1)*(blockDim.x+L-1)+ (threadIdx.x)] ;
2578 minmax4(&a2, &a3, &a4, &a5) ;
2580 a5 = medRoi[ (threadIdx.y+2)*(blockDim.x+L-1)+ (threadIdx.x)] ;
2581 minmax3(&a3, &a4, &a5) ;
2584 //median au milieu !
2585 output[ __mul24(i, j_dim) +j ] = a4 ;
2589 /************************************************
2590 * version qui gere 2 pxels par thread
2591 * Objectif plus déebit en cachant la latence
2592 * minimiser les acces en texture
2593 * defaut = plus de registres
2594 ************************************************/
2595 __global__ void kernel_median3_2pix( unsigned short*output, int i_dim, int j_dim)
2598 // coordonnees absolues du point
2599 int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
2600 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
2602 /**************************************************************************
2604 **************************************************************************/
2605 int a0, a1, a2, a3, a4, a5 ;
2606 int b0, b1, b2, b3, b4, b5 ;
2608 /********************************************************************************
2609 * les six premieres valeurs (suffisant pour median 3x3 par forgetfull selection)
2610 ********************************************************************************/
2611 a0 = tex2D(tex_img_ins, j , i-1) ;
2612 a1 = tex2D(tex_img_ins, j+1, i-1) ;
2613 a2 = tex2D(tex_img_ins, j , i ) ;
2614 a3 = tex2D(tex_img_ins, j+1, i ) ;
2615 a4 = tex2D(tex_img_ins, j , i+1) ;
2616 a5 = tex2D(tex_img_ins, j+1, i+1) ;
2619 //min max aux extremites
2620 minmax6(&a0, &a1, &a2, &a3, &a4, &a5) ;
2622 b0=a0; b1=a1; b2=a2; b3=a3; b4=a4; b5=a5;
2624 /********************************************
2625 * la valeur suivante au bout
2626 ********************************************/
2627 a5 = tex2D(tex_img_ins, j-1, i ) ;
2628 b5 = tex2D(tex_img_ins, j+2, i ) ;
2630 minmax5(&a1, &a2, &a3, &a4, &a5) ;
2631 minmax5(&b1, &b2, &b3, &b4, &b5) ;
2633 /********************************************
2634 * la derniere valeur a la fin
2635 ********************************************/
2636 a5 = tex2D(tex_img_ins, j-1, i-1) ;
2637 b5 = tex2D(tex_img_ins, j+2, i-1) ;
2639 minmax4(&a2, &a3, &a4, &a5) ;
2640 minmax4(&b2, &b3, &b4, &b5) ;
2642 a5 = tex2D(tex_img_ins, j-1, i+1) ;
2643 b5 = tex2D(tex_img_ins, j+2, i+1) ;
2645 minmax3(&a3, &a4, &a5) ;
2646 minmax3(&b3, &b4, &b5) ;
2648 //median au milieu !
2649 output[ __mul24(i, j_dim) +j ] = a4 ;
2650 output[ __mul24(i, j_dim) +j+1 ] = b4 ;
2654 __global__ void kernel_median3_2pix8( unsigned char *output, int i_dim, int j_dim)
2657 // coordonnees absolues du point
2658 int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
2659 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
2661 /**************************************************************************
2663 **************************************************************************/
2664 int a0, a1, a2, a3, a4, a5 ;
2665 int b0, b1, b2, b3, b4, b5 ;
2667 /********************************************************************************
2668 * les six premieres valeurs (suffisant pour median 3x3 par forgetfull selection)
2669 ********************************************************************************/
2670 a0 = tex2D(tex_img_inc, j , i-1) ;
2671 a1 = tex2D(tex_img_inc, j+1, i-1) ;
2672 a2 = tex2D(tex_img_inc, j , i ) ;
2673 a3 = tex2D(tex_img_inc, j+1, i ) ;
2674 a4 = tex2D(tex_img_inc, j , i+1) ;
2675 a5 = tex2D(tex_img_inc, j+1, i+1) ;
2678 //min max aux extremites
2679 minmax6(&a0, &a1, &a2, &a3, &a4, &a5) ;
2681 b0=a0; b1=a1; b2=a2; b3=a3; b4=a4; b5=a5;
2683 /********************************************
2684 * la valeur suivante au bout
2685 ********************************************/
2686 a5 = tex2D(tex_img_inc, j-1, i ) ;
2687 b5 = tex2D(tex_img_inc, j+2, i ) ;
2689 minmax5(&a1, &a2, &a3, &a4, &a5) ;
2690 minmax5(&b1, &b2, &b3, &b4, &b5) ;
2692 /********************************************
2693 * la derniere valeur a la fin
2694 ********************************************/
2695 a5 = tex2D(tex_img_inc, j-1, i-1) ;
2696 b5 = tex2D(tex_img_inc, j+2, i-1) ;
2698 minmax4(&a2, &a3, &a4, &a5) ;
2699 minmax4(&b2, &b3, &b4, &b5) ;
2701 a5 = tex2D(tex_img_inc, j-1, i+1) ;
2702 b5 = tex2D(tex_img_inc, j+2, i+1) ;
2704 minmax3(&a3, &a4, &a5) ;
2705 minmax3(&b3, &b4, &b5) ;
2707 //median au milieu !
2708 output[ __mul24(i, j_dim) +j ] = a4 ;
2709 output[ __mul24(i, j_dim) +j+1 ] = b4 ;
2714 #define minmax7(a,b,c,d,e,f,g) s(a,b);s(c,d);s(e,f);s(a,c);s(e,g);s(a,e);s(b,d);s(f,g);s(d,g);//max 9
2715 #define minmax8(a,b,c,d,e,f,g,h) s(a,b);s(c,d);s(e,f);s(g,h);s(a,c);s(e,g);s(a,e);s(b,d);s(f,h);s(d,h);//max 10
2716 #define minmax9(a,b,c,d,e,f,g,h,i) s(a,b);s(c,d);s(e,f);minmax3(g,h,i);s(a,c);s(e,g);s(a,e);s(b,d);s(f,i);s(d,i);//max 12
2717 #define minmax10(a,b,c,d,e,f,g,h,i,j) s(a,b);s(c,d);s(e,f);s(g,h);s(i,j);s(a,c);min3(e,g,i);s(a,e);s(b,d);max3(f,h,j);s(d,j);//max 13
2718 #define minmax11(a,b,c,d,e,f,g,h,i,j,k) s(a,b);s(c,d);s(e,f);s(g,h);min3(i,j,k);s(a,c);min3(e,g,i);s(a,e);s(b,d);max3(f,h,k);s(d,k);//max 14
2719 #define minmax12(a,b,c,d,e,f,g,h,i,j,k,l) s(a,b);s(c,d);s(e,f);s(g,h);s(i,j);s(k,l);s(a,c);s(e,g);s(i,k);min3(a,e,i);s(b,d);s(f,h);s(j,l);max3(d,h,l); //max 16
2720 #define minmax13(a,b,c,d,e,f,g,h,i,j,k,l,m) s(a,b);s(c,d);s(e,f);s(g,h);s(i,j);min3(k,l,m);s(a,c);s(e,g);s(i,k);min3(a,e,i);s(b,d);s(f,h);max3(j,l,m);max3(d,h,m); // max 18 !!
2721 #define min14(a,b,c,d,e,f,g,h,i,j,k,l,m,n) s(a,b);s(c,d);s(e,f);s(g,h);s(i,j);s(k,l);s(m,n);s(a,c);s(e,g);s(i,k);s(a,e);s(i,m);s(a,i); // 13 mouvts max
2722 #define max14(a,b,c,d,e,f,g,h,i,j,k,l,m,n) s(a,b);s(c,d);s(e,f);s(g,h);s(i,j);s(k,l);s(m,n);s(b,d);s(f,h);s(j,l);s(d,h);s(l,n);s(h,n); // 13 mouvts max
2723 #define minmax14(a,b,c,d,e,f,g,h,i,j,k,l,m,n) min14(a,b,c,d,e,f,g,h,i,j,k,l,m,n); s(b,d);s(f,h);s(j,l);s(d,h);s(l,n);s(h,n); // 19 mouvts max
2725 #define m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) s(a,b);s(c,d);s(e,f);s(g,h);s(i,j);s(k,l);s(a,c);s(e,g);s(i,k);s(b,d);s(f,h);s(j,l); // max 12
2726 #define minmax15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);minmax3(m,n,o);s(a,e);s(i,m);s(d,h);s(l,o);s(a,i);s(h,o); //max 21
2727 #define minmax16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);s(o,p);s(m,o);s(a,e);s(i,m);s(n,p);s(d,h);s(l,p);s(a,i);s(h,p);//max 22
2728 #define minmax17(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);minmax3(o,p,q);s(a,e);s(d,h);s(i,m);min3(a,i,o);max3(h,n,q);//max 24
2729 #define minmax18(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);s(o,p);s(q,r);minmax3(m,o,q);minmax3(n,p,r);s(a,e);s(m,n);s(q,r);s(i,m);s(d,h);s(l,r);s(a,i);s(h,r); //max 29 !!!
2730 #define minmax19(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,ss) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);s(o,p);minmax3(q,r,ss);s(m,o);s(n,p);s(a,e);s(i,m);s(d,h);s(l,p);min3(a,i,q);max3(h,p,ss);//max 28
2731 #define minmax20(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,ss,t) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);s(o,p);s(q,r);s(ss,t);s(m,o);s(q,ss);s(n,p);s(r,t);s(a,e);s(i,m);s(d,h);s(l,p);min3(a,i,q);max3(h,p,t);//max 29
2732 #define minmax21(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,ss,t,u) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);s(o,p);s(q,r);minmax3(ss,t,u);s(m,o);s(q,ss);s(n,p);s(r,u);s(a,e);s(i,m);s(d,h);s(l,p);min3(a,i,q);max3(h,p,u); //max 30
2733 #define minmax22(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,ss,t,u,v) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);s(o,p);s(q,r);s(ss,t);s(u,v);s(m,o);min3(q,ss,u);s(n,p);max3(r,t,v);s(a,e);s(i,m);s(d,h);s(l,p);min3(a,i,q);max3(h,p,v); //max31
2734 #define minmax23(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,ss,t,u,v,w) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);s(o,p);s(q,r);s(ss,t);minmax3(u,v,w);s(m,o);s(q,ss);s(n,p);s(r,t);s(a,e);s(i,m);s(q,u);s(d,h);s(l,p);s(t,w);min3(a,i,q);max3(h,p,w); //max 33
2735 #define minmax24(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,ss,t,u,v,w,x) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);s(o,p);s(q,r);s(ss,t);s(u,v);s(w,x);s(m,o);s(q,ss);s(u,w);s(n,p);s(r,t);s(v,x);s(a,e);s(i,m);s(q,u);s(d,h);s(l,p);s(t,x);min3(a,i,q);max3(h,p,x); //max 34
2736 #define minmax25(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,ss,t,u,v,w,x,y) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);s(o,p);s(q,r);s(ss,t);s(u,v);minmax3(w,x,y);s(m,o);s(q,ss);s(u,w);s(n,p);s(r,t);s(v,y);s(a,e);s(i,m);s(q,u);s(d,h);s(l,p);s(t,y);min3(a,i,q);max3(h,p,y); //max 36
2737 #define minmax26(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,ss,t,u,v,w,x,y,z) m15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);s(m,n);s(o,p);s(q,r);s(ss,t);s(u,v);s(w,x);s(y,z);s(m,o);s(q,ss);min3(u,w,y);s(n,p);s(r,t);max3(v,x,z);s(a,e);s(i,m);s(q,u);s(d,h);s(l,p);s(t,z);min3(a,i,q);max3(h,p,z);//max 37
2740 __global__ void kernel_median5( unsigned short*output, int i_dim, int j_dim)
2743 // coordonnees absolues du point
2744 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
2745 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
2747 /**************************************************************************
2749 **************************************************************************/
2750 int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 ;
2752 /********************************************************************************
2753 * les 14 premieres valeurs (suffisant pour median 5x5 par forgetfull selection)
2754 ********************************************************************************/
2756 a0 = tex2D(tex_img_ins, j-2, i-2) ;
2757 a1 = tex2D(tex_img_ins, j-1, i-2) ;
2758 a2 = tex2D(tex_img_ins, j , i-2) ;
2759 a3 = tex2D(tex_img_ins, j+1, i-2) ;
2760 a4 = tex2D(tex_img_ins, j+2, i-2) ;
2762 a5 = tex2D(tex_img_ins, j-2, i-1) ;
2763 a6 = tex2D(tex_img_ins, j-1, i-1) ;
2764 a7 = tex2D(tex_img_ins, j , i-1) ;
2765 a8 = tex2D(tex_img_ins, j+1, i-1) ;
2766 a9 = tex2D(tex_img_ins, j+2, i-1) ;
2767 //les 4 premiers de la troisieme ligne
2768 a10 = tex2D(tex_img_ins, j-2, i) ;
2769 a11 = tex2D(tex_img_ins, j-1, i) ;
2770 a12 = tex2D(tex_img_ins, j , i) ;
2771 a13 = tex2D(tex_img_ins, j+1, i) ;
2773 //min max aux extremites
2774 minmax14(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2776 //chargement valeurs suivante (15)
2777 a13 = tex2D(tex_img_ins, j+2, i);
2778 //minmax aux extremites
2779 minmax13(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2782 //chargement valeur suivante (16)
2783 a13 = tex2D(tex_img_ins, j-2, i+1);
2784 //minmax aux extremites
2785 minmax12(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2787 //chargement valeur suivante (17)
2788 a13 = tex2D(tex_img_ins, j-1, i+1);
2789 //minmax aux extremites
2790 minmax11(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2792 //chargement valeur suivante (18)
2793 a13 = tex2D(tex_img_ins, j , i+1);
2794 //minmax aux extremites
2795 minmax10(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2797 //chargement valeur suivante (19)
2798 a13 = tex2D(tex_img_ins, j+1, i+1);
2799 //minmax aux extremites
2800 minmax9(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2802 //chargement valeur suivante (20)
2803 a13 = tex2D(tex_img_ins, j+2, i+1);
2804 //minmax aux extremites
2805 minmax8(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2807 //chargement valeur suivante (21)
2808 a13 = tex2D(tex_img_ins, j-2, i+2);
2809 //minmax aux extremites
2810 minmax7(&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2812 //chargement valeur suivante (22)
2813 a13 = tex2D(tex_img_ins, j-1, i+2);
2814 //minmax aux extremites
2815 minmax6(&a8,&a9,&a10,&a11,&a12,&a13);
2817 //chargement valeur suivante (23)
2818 a13 = tex2D(tex_img_ins, j , i+2);
2819 //minmax aux extremites
2820 minmax5(&a9,&a10,&a11,&a12,&a13);
2822 //chargement valeur suivante (24)
2823 a13 = tex2D(tex_img_ins, j+1 , i+2);
2824 //minmax aux extremites
2825 minmax4(&a10,&a11,&a12,&a13);
2827 //chargement valeur suivante (25)
2828 a13 = tex2D(tex_img_ins, j+2 , i+2);
2829 //minmax aux extremites
2830 minmax3(&a11,&a12,&a13);
2833 //median au milieu !
2834 output[ __mul24(i, j_dim) +j ] = a12 ;
2838 __global__ void kernel_median5_sh( unsigned short*output, int i_dim, int j_dim)
2841 // coordonnees absolues du point
2842 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
2843 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
2845 int idx = __mul24(i,j_dim) + j ; // indice dans l'image
2847 // chargement en smem
2848 int idrow = threadIdx.y*(blockDim.x+4) ;
2850 extern __shared__ int medRoi[];
2852 // bloc 0 (en haut \E0 gauche)
2853 medRoi[ idrow + threadIdx.x ] = tex2D(tex_img_ins, j-2, i-2) ;
2854 // bloc 1 (en haut \E0 droite)...
2855 if ( threadIdx.x < L-1 ) //...ou plutot ce qu'il en manque
2856 medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-2, i-2 ) ;
2857 // bloc 2 ( en bas \E0 gauche)
2858 if ( threadIdx.y < L-1 )
2860 idrow = (threadIdx.y+blockDim.y)*(blockDim.x+L-1) ;
2861 medRoi[ idrow + threadIdx.x ] = tex2D( tex_img_ins, j-2, i+blockDim.y-2 ) ;
2862 //bloc 4 ( en bas \E0 doite )...
2863 if ( threadIdx.x < L-1 ) //...ou ce qu'il en manque
2864 medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-2, i+blockDim.y-2 ) ;
2868 /**************************************************************************
2870 **************************************************************************/
2871 int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 ;
2873 /********************************************************************************
2874 * les 14 premieres valeurs (suffisant pour median 5x5 par forgetfull selection)
2875 ********************************************************************************/
2876 // l'index dans medRoi est du type (threadIdx.y+ic)*(blockDim.x+L-1)+ (threadIdx.x+jc)
2877 // ou ic,jc sont les coordonnees du point dans le noya
2879 a0 = medRoi[ (threadIdx.y )*(blockDim.x+L-1)+ (threadIdx.x ) ] ; //tex2D(tex_img_ins, j-2, i-2) ;
2880 a1 = medRoi[ (threadIdx.y )*(blockDim.x+L-1)+ (threadIdx.x +1) ] ; //tex2D(tex_img_ins, j-1, i-2) ;
2881 a2 = medRoi[ (threadIdx.y )*(blockDim.x+L-1)+ (threadIdx.x +2) ] ; //tex2D(tex_img_ins, j , i-2) ;
2882 a3 = medRoi[ (threadIdx.y )*(blockDim.x+L-1)+ (threadIdx.x +3) ] ; //tex2D(tex_img_ins, j+1, i-2) ;
2883 a4 = medRoi[ (threadIdx.y )*(blockDim.x+L-1)+ (threadIdx.x +4) ] ; //tex2D(tex_img_ins, j+2, i-2) ;
2885 a5 = medRoi[ (threadIdx.y +1)*(blockDim.x+L-1)+ (threadIdx.x ) ] ; //tex2D(tex_img_ins, j-2, i-1) ;
2886 a6 = medRoi[ (threadIdx.y +1)*(blockDim.x+L-1)+ (threadIdx.x +1) ] ; //tex2D(tex_img_ins, j-1, i-1) ;
2887 a7 = medRoi[ (threadIdx.y +1)*(blockDim.x+L-1)+ (threadIdx.x +2) ] ; //tex2D(tex_img_ins, j , i-1) ;
2888 a8 = medRoi[ (threadIdx.y +1)*(blockDim.x+L-1)+ (threadIdx.x +3) ] ; //tex2D(tex_img_ins, j+1, i-1) ;
2889 a9 = medRoi[ (threadIdx.y +1)*(blockDim.x+L-1)+ (threadIdx.x +4) ] ; //tex2D(tex_img_ins, j+2, i-1) ;
2890 //les 4 premiers de la troisieme ligne
2891 a10 = medRoi[ (threadIdx.y +2)*(blockDim.x+L-1)+ (threadIdx.x ) ] ; //tex2D(tex_img_ins, j-2, i) ;
2892 a11 = medRoi[ (threadIdx.y +2)*(blockDim.x+L-1)+ (threadIdx.x +1) ] ; //tex2D(tex_img_ins, j-1, i) ;
2893 a12 = medRoi[ (threadIdx.y +2)*(blockDim.x+L-1)+ (threadIdx.x +2) ] ; //tex2D(tex_img_ins, j , i) ;
2894 a13 = medRoi[ (threadIdx.y +2)*(blockDim.x+L-1)+ (threadIdx.x +3) ] ; //tex2D(tex_img_ins, j+1, i) ;
2896 //min max aux extremites
2897 minmax14(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2899 //chargement valeurs suivante (15)
2900 a13 = medRoi[ (threadIdx.y +2)*(blockDim.x+L-1)+ (threadIdx.x +4) ] ; //tex2D(tex_img_ins, j+2, i);
2901 //minmax aux extremites
2902 minmax13(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2905 //chargement valeur suivante (16)
2906 a13 = medRoi[ (threadIdx.y +3)*(blockDim.x+L-1)+ (threadIdx.x ) ] ; //tex2D(tex_img_ins, j-2, i+1);
2907 //minmax aux extremites
2908 minmax12(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2910 //chargement valeur suivante (17)
2911 a13 = medRoi[ (threadIdx.y +3)*(blockDim.x+L-1)+ (threadIdx.x +1) ] ; //tex2D(tex_img_ins, j-1, i+1);
2912 //minmax aux extremites
2913 minmax11(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2915 //chargement valeur suivante (18)
2916 a13 = medRoi[ (threadIdx.y +3)*(blockDim.x+L-1)+ (threadIdx.x +2) ] ; //tex2D(tex_img_ins, j , i+1);
2917 //minmax aux extremites
2918 minmax10(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2920 //chargement valeur suivante (19)
2921 a13 = medRoi[ (threadIdx.y +3)*(blockDim.x+L-1)+ (threadIdx.x +3) ] ; //tex2D(tex_img_ins, j+1, i+1);
2922 //minmax aux extremites
2923 minmax9(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2925 //chargement valeur suivante (20)
2926 a13 = medRoi[ (threadIdx.y +3)*(blockDim.x+L-1)+ (threadIdx.x +4) ] ; //tex2D(tex_img_ins, j+2, i+1);
2927 //minmax aux extremites
2928 minmax8(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2930 //chargement valeur suivante (21)
2931 a13 = medRoi[ (threadIdx.y +4)*(blockDim.x+L-1)+ (threadIdx.x ) ] ; //tex2D(tex_img_ins, j-2, i+2);
2932 //minmax aux extremites
2933 minmax7(&a7,&a8,&a9,&a10,&a11,&a12,&a13);
2935 //chargement valeur suivante (22)
2936 a13 = medRoi[ (threadIdx.y +4)*(blockDim.x+L-1)+ (threadIdx.x +1) ] ; //tex2D(tex_img_ins, j-1, i+2);
2937 //minmax aux extremites
2938 minmax6(&a8,&a9,&a10,&a11,&a12,&a13);
2940 //chargement valeur suivante (23)
2941 a13 = medRoi[ (threadIdx.y +4)*(blockDim.x+L-1)+ (threadIdx.x +2) ] ; //tex2D(tex_img_ins, j , i+2);
2942 //minmax aux extremites
2943 minmax5(&a9,&a10,&a11,&a12,&a13);
2945 //chargement valeur suivante (24)
2946 a13 = medRoi[ (threadIdx.y +4)*(blockDim.x+L-1)+ (threadIdx.x +3) ] ; //tex2D(tex_img_ins, j+1 , i+2);
2947 //minmax aux extremites
2948 minmax4(&a10,&a11,&a12,&a13);
2950 //chargement valeur suivante (25)
2951 a13 = medRoi[ (threadIdx.y +4)*(blockDim.x+L-1)+ (threadIdx.x +4) ] ; //tex2D(tex_img_ins, j+2 , i+2);
2952 //minmax aux extremites
2953 minmax3(&a11,&a12,&a13);
2956 //median au milieu !
2957 output[ __mul24(i, j_dim) +j ] = a12 ;
2962 __global__ void kernel_median5_sh_loc( unsigned short*output, int i_dim, int j_dim)
2965 // coordonnees absolues du point
2966 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
2967 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
2968 // int idx = __mul24(i,j_dim) + j ; // indice dans l'image
2970 // chargement en smem
2971 int idrow = threadIdx.y*(blockDim.x+4) ;
2973 extern __shared__ int medRoi[];
2975 // bloc 0 (en haut \E0 gauche)
2976 medRoi[ idrow + threadIdx.x ] = tex2D(tex_img_ins, j-2, i-2) ;
2977 // bloc 1 (en haut \E0 droite)...
2978 if ( threadIdx.x < 4 ) //...ou plutot ce qu'il en manque
2979 medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-2, i-2 ) ;
2980 // bloc 2 ( en bas \E0 gauche)
2981 if ( threadIdx.y < 4 )
2983 idrow = (threadIdx.y+blockDim.y)*(blockDim.x+4) ;
2984 medRoi[ idrow + threadIdx.x ] = tex2D( tex_img_ins, j-2, i+blockDim.y-2 ) ;
2985 //bloc 4 ( en bas \E0 doite )...
2986 if ( threadIdx.x < 4 ) //...ou ce qu'il en manque
2987 medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-2, i+blockDim.y-2 ) ;
2991 /**************************************************************************
2993 **************************************************************************/
2994 /********************************************************************************
2995 * les 14 premieres valeurs (suffisant pour median 5x5 par forgetfull selection)
2996 ********************************************************************************/
2997 // l'index dans medRoi est du type (threadIdx.y+ic)*(blockDim.x+L-1)+ (threadIdx.x+jc)
2998 // ou ic,jc sont les coordonnees du point dans le noyau
3000 int a[] = { medRoi[ (threadIdx.y )*(blockDim.x+4)+ (threadIdx.x ) ],
3001 medRoi[ (threadIdx.y )*(blockDim.x+4)+ (threadIdx.x +1) ],
3002 medRoi[ (threadIdx.y )*(blockDim.x+4)+ (threadIdx.x +2) ],
3003 medRoi[ (threadIdx.y )*(blockDim.x+4)+ (threadIdx.x +3) ],
3004 medRoi[ (threadIdx.y )*(blockDim.x+4)+ (threadIdx.x +4) ],
3005 medRoi[ (threadIdx.y +1)*(blockDim.x+4)+ (threadIdx.x ) ],
3006 medRoi[ (threadIdx.y +1)*(blockDim.x+4)+ (threadIdx.x +1) ],
3007 medRoi[ (threadIdx.y +1)*(blockDim.x+4)+ (threadIdx.x +2) ],
3008 medRoi[ (threadIdx.y +1)*(blockDim.x+4)+ (threadIdx.x +3) ],
3009 medRoi[ (threadIdx.y +1)*(blockDim.x+4)+ (threadIdx.x +4) ],
3010 medRoi[ (threadIdx.y +2)*(blockDim.x+4)+ (threadIdx.x ) ],
3011 medRoi[ (threadIdx.y +2)*(blockDim.x+4)+ (threadIdx.x +1) ],
3012 medRoi[ (threadIdx.y +2)*(blockDim.x+4)+ (threadIdx.x +2) ],
3013 medRoi[ (threadIdx.y +2)*(blockDim.x+4)+ (threadIdx.x +3) ]};
3016 //min max aux extremites
3017 minmax14(&a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3019 //chargement valeurs suivante (15)
3020 a[13] = medRoi[ (threadIdx.y +2)*(blockDim.x+4)+ (threadIdx.x +4) ] ; //tex2D(tex_img_ins, j+2, i);
3021 //minmax aux extremites
3022 minmax13(&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3025 //chargement valeur suivante (16)
3026 a[13] = medRoi[ (threadIdx.y +3)*(blockDim.x+4)+ (threadIdx.x ) ] ; //tex2D(tex_img_ins, j-2, i+1);
3027 //minmax aux extremites
3028 minmax12(&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3030 //chargement valeur suivante (17)
3031 a[13] = medRoi[ (threadIdx.y +3)*(blockDim.x+4)+ (threadIdx.x +1) ] ; //tex2D(tex_img_ins, j-1, i+1);
3032 //minmax aux extremites
3033 minmax11(&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3035 //chargement valeur suivante (18)
3036 a[13] = medRoi[ (threadIdx.y +3)*(blockDim.x+4)+ (threadIdx.x +2) ] ; //tex2D(tex_img_ins, j , i+1);
3037 //minmax aux extremites
3038 minmax10(&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3040 //chargement valeur suivante (19)
3041 a[13] = medRoi[ (threadIdx.y +3)*(blockDim.x+4)+ (threadIdx.x +3) ] ; //tex2D(tex_img_ins, j+1, i+1);
3042 //minmax aux extremites
3043 minmax9(&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3045 //chargement valeur suivante (20)
3046 a[13] = medRoi[ (threadIdx.y +3)*(blockDim.x+4)+ (threadIdx.x +4) ] ; //tex2D(tex_img_ins, j+2, i+1);
3047 //minmax aux extremites
3048 minmax8(&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3050 //chargement valeur suivante (21)
3051 a[13] = medRoi[ (threadIdx.y +4)*(blockDim.x+4)+ (threadIdx.x ) ] ; //tex2D(tex_img_ins, j-2, i+2);
3052 //minmax aux extremites
3053 minmax7(&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3055 //chargement valeur suivante (22)
3056 a[13] = medRoi[ (threadIdx.y +4)*(blockDim.x+4)+ (threadIdx.x +1) ] ; //tex2D(tex_img_ins, j-1, i+2);
3057 //minmax aux extremites
3058 minmax6(&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3060 //chargement valeur suivante (23)
3061 a[13] = medRoi[ (threadIdx.y +4)*(blockDim.x+4)+ (threadIdx.x +2) ] ; //tex2D(tex_img_ins, j , i+2);
3062 //minmax aux extremites
3063 minmax5(&a[9],&a[10],&a[11],&a[12],&a[13]);
3065 //chargement valeur suivante (24)
3066 a[13] = medRoi[ (threadIdx.y +4)*(blockDim.x+4)+ (threadIdx.x +3) ] ; //tex2D(tex_img_ins, j+1 , i+2);
3067 //minmax aux extremites
3068 minmax4(&a[10],&a[11],&a[12],&a[13]);
3070 //chargement valeur suivante (25)
3071 a[13] = medRoi[ (threadIdx.y +4)*(blockDim.x+4)+ (threadIdx.x +4) ] ; //tex2D(tex_img_ins, j+2 , i+2);
3072 //minmax aux extremites
3073 minmax3(&a[11],&a[12],&a[13]);
3076 //median au milieu !
3077 output[ __mul24(i, j_dim) +j ] = a[12] ;
3081 __global__ void kernel_median5_sh_loc_2p( unsigned short*output, int i_dim, int j_dim)
3084 // coordonnees absolues du point
3085 int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
3086 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
3087 // int idx = __mul24(i,j_dim) + j ; // indice dans l'image
3088 int bdimX = blockDim.x<<1 ;
3089 int tidX = threadIdx.x<<1 ;
3091 // chargement en smem
3092 int idrow = threadIdx.y*(bdimX+2*2) ;
3094 extern __shared__ int medRoi[];
3096 // bloc 0 (en haut \E0 gauche)
3097 medRoi[ idrow + tidX ] = tex2D(tex_img_ins, j-2, i-2) ;
3098 medRoi[ idrow + tidX +1] = tex2D(tex_img_ins, j-1, i-2) ;
3099 // bloc 1 (en haut \E0 droite)...
3100 if ( tidX < 4 ) //...ou plutot ce qu'il en manque
3102 medRoi[ idrow + tidX + bdimX ] = tex2D( tex_img_ins, j+bdimX-2, i-2 ) ;
3103 medRoi[ idrow + tidX + bdimX +1] = tex2D( tex_img_ins, j+bdimX-1, i-2 ) ;
3105 // bloc 2 ( en bas \E0 gauche)
3106 if ( threadIdx.y < 4 )
3108 idrow = (threadIdx.y+blockDim.y)*(bdimX+4) ;
3109 medRoi[ idrow + tidX ] = tex2D( tex_img_ins, j-2, i+blockDim.y-2 ) ;
3110 medRoi[ idrow + tidX +1] = tex2D( tex_img_ins, j-1, i+blockDim.y-2 ) ;
3111 //bloc 4 ( en bas \E0 doite )...
3112 if ( tidX < 4 ) //...ou ce qu'il en manque
3114 medRoi[ idrow + tidX + bdimX ] = tex2D( tex_img_ins, j+bdimX-2, i+blockDim.y-2 ) ;
3115 medRoi[ idrow + tidX + bdimX +1] = tex2D( tex_img_ins, j+bdimX-1, i+blockDim.y-2 ) ;
3120 /**************************************************************************
3122 **************************************************************************/
3123 /********************************************************************************
3124 * les 14 premieres valeurs (suffisant pour median 5x5 par forgetfull selection)
3125 ********************************************************************************/
3126 // l'index dans medRoi est du type (threadIdx.y+ic)*(bdimX+L-1)+ (tidX+jc)
3127 // ou ic,jc sont les coordonnees du point dans le noyau
3129 //on commence le tri avec les pixels du voisinage commun aux 2 pixels \E0 calculer
3131 int a[] = { medRoi[ (threadIdx.y )*(bdimX+4)+ (tidX +1) ],
3132 medRoi[ (threadIdx.y )*(bdimX+4)+ (tidX +2) ],
3133 medRoi[ (threadIdx.y )*(bdimX+4)+ (tidX +3) ],
3134 medRoi[ (threadIdx.y )*(bdimX+4)+ (tidX +4) ],
3136 medRoi[ (threadIdx.y +1)*(bdimX+4)+ (tidX +1) ],
3137 medRoi[ (threadIdx.y +1)*(bdimX+4)+ (tidX +2) ],
3138 medRoi[ (threadIdx.y +1)*(bdimX+4)+ (tidX +3) ],
3139 medRoi[ (threadIdx.y +1)*(bdimX+4)+ (tidX +4) ],
3141 medRoi[ (threadIdx.y +2)*(bdimX+4)+ (tidX +1) ],
3142 medRoi[ (threadIdx.y +2)*(bdimX+4)+ (tidX +2) ],
3143 medRoi[ (threadIdx.y +2)*(bdimX+4)+ (tidX +3) ],
3144 medRoi[ (threadIdx.y +2)*(bdimX+4)+ (tidX +4) ],
3146 medRoi[ (threadIdx.y +3)*(bdimX+4)+ (tidX +1) ],
3147 medRoi[ (threadIdx.y +3)*(bdimX+4)+ (tidX +2) ]
3150 //min max aux extremites
3151 minmax14(&a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3153 //chargement valeurs suivante (15)
3154 a[13] = medRoi[ (threadIdx.y +3)*(bdimX+4)+ (tidX +3) ] ;
3155 //minmax aux extremites
3156 minmax13(&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3159 //chargement valeur suivante (16)
3160 a[13] = medRoi[ (threadIdx.y +3)*(bdimX+4)+ (tidX +4) ] ;
3161 //minmax aux extremites
3162 minmax12(&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3164 //chargement valeur suivante (17)
3165 a[13] = medRoi[ (threadIdx.y +4)*(bdimX+4)+ (tidX +1) ] ;
3166 //minmax aux extremites
3167 minmax11(&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3169 //chargement valeur suivante (18)
3170 a[13] = medRoi[ (threadIdx.y +4)*(bdimX+4)+ (tidX +2) ] ;
3171 //minmax aux extremites
3172 minmax10(&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3174 //chargement valeur suivante (19)
3175 a[13] = medRoi[ (threadIdx.y +4)*(bdimX+4)+ (tidX +3) ] ;
3176 //minmax aux extremites
3177 minmax9(&a[5],&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3179 //chargement valeur suivante (20)
3180 a[13] = medRoi[ (threadIdx.y +4)*(bdimX+4)+ (tidX +4) ] ;
3181 //minmax aux extremites
3182 minmax8(&a[6],&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3184 // fin des pixels communs. la suite doit se faire en 2 tris distincts.
3185 int b[] = { a[7], a[8], a[9], a[10], a[11], a[12], a[13]};
3187 //chargement valeur suivante (21)
3188 a[13] = medRoi[ (threadIdx.y +4)*(bdimX+4)+ (tidX ) ] ;
3189 b[6 ] = medRoi[ (threadIdx.y +4)*(bdimX+4)+ (tidX +5) ] ;
3190 //minmax aux extremites
3191 minmax7(&a[7],&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3192 minmax7(&b[0],&b[1],&b[2],&b[3],&b[4],&b[5],&b[6]);
3194 //chargement valeur suivante (22)
3195 a[13] = medRoi[ (threadIdx.y +3)*(bdimX+4)+ (tidX ) ] ;
3196 b[6 ] = medRoi[ (threadIdx.y +3)*(bdimX+4)+ (tidX +5) ] ;
3197 //minmax aux extremites
3198 minmax6(&a[8],&a[9],&a[10],&a[11],&a[12],&a[13]);
3199 minmax6(&b[1],&b[2],&b[3],&b[4],&b[5],&b[6]);
3201 //chargement valeur suivante (23)
3202 a[13] = medRoi[ (threadIdx.y +2)*(bdimX+4)+ (tidX ) ] ;
3203 b[6 ] = medRoi[ (threadIdx.y +2)*(bdimX+4)+ (tidX +5) ] ;
3204 //minmax aux extremites
3205 minmax5(&a[9],&a[10],&a[11],&a[12],&a[13]);
3206 minmax5(&b[2],&b[3],&b[4],&b[5],&b[6]);
3208 //chargement valeur suivante (24)
3209 a[13] = medRoi[ (threadIdx.y +1)*(bdimX+4)+ (tidX ) ] ;
3210 b[6 ] = medRoi[ (threadIdx.y +1)*(bdimX+4)+ (tidX +5) ] ;
3212 //minmax aux extremites
3213 minmax4(&a[10],&a[11],&a[12],&a[13]);
3214 minmax4(&b[3],&b[4],&b[5],&b[6]);
3216 //chargement valeur suivante (25)
3217 a[13] = medRoi[ (threadIdx.y )*(bdimX+4)+ (tidX ) ] ;
3218 b[6 ] = medRoi[ (threadIdx.y )*(bdimX+4)+ (tidX +5) ] ;
3219 //minmax aux extremites
3220 minmax3(&a[11],&a[12],&a[13]);
3221 minmax3(&b[4],&b[5],&b[6]);
3223 //median au milieu !
3224 output[ __mul24(i, j_dim) +j ] = a[12] ;
3225 output[ __mul24(i, j_dim) +j+1 ] = b[5] ;
3230 __global__ void kernel_medianR( unsigned short * output, int i_dim, int j_dim, int r)
3232 // coordonnees absolues du point
3233 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
3234 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
3235 unsigned short cpt ;
3236 unsigned short ic, jc ;
3238 unsigned short hist[256] ;
3239 for (ic =0; ic<256; ic++) hist[ic]=0; // init histogramme
3240 //for (ic =0; ic<25; ic++) hist[ic]=1; // init histogramme
3242 //generation histogramme
3243 for(ic=i-r; ic<=i+r; ic++ )
3244 for(jc=j-r; jc<=j+r; jc++)
3245 hist[tex2D(tex_img_ins, jc, ic)]++ ;
3247 //parcours histogramme
3249 for(ic=0; ic<256; ic++)
3252 //selection de la valeur du percentile (ici 50%=SUM/2)
3253 if ( cpt > ((2*r+1)*(2*r+1))>>1 ) break ;
3256 output[ __mul24(i, j_dim) +j ] = ic ;
3259 __global__ void kernel_medianRSH( unsigned short * output, int i_dim, int j_dim, int r)
3261 // coordonnees absolues du point
3262 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
3263 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
3264 unsigned short cpt ;
3265 unsigned short ic, jc ;
3267 // chargement en smem
3268 int idrow = threadIdx.y*(blockDim.x+2*r) ;
3270 extern __shared__ int medRoi[];
3272 // bloc 0 (en haut \E0 gauche)
3273 medRoi[ idrow + threadIdx.x ] = tex2D(tex_img_ins, j-r, i-r) ;
3274 // bloc 1 (en haut \E0 droite)...
3275 if ( threadIdx.x < 2*r ) //...ou plutot ce qu'il en manque
3276 medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-r, i-r ) ;
3277 // bloc 2 ( en bas \E0 gauche)
3278 if ( threadIdx.y < 2*r )
3280 idrow = (threadIdx.y+blockDim.y)*(blockDim.x+2*r) ;
3281 medRoi[ idrow + threadIdx.x ] = tex2D( tex_img_ins, j-r, i+blockDim.y-r ) ;
3282 //bloc 4 ( en bas \E0 doite )...
3283 if ( threadIdx.x < 2*r ) //...ou ce qu'il en manque
3284 medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-r, i+blockDim.y-r ) ;
3289 for (ic =0; ic<256; ic++) hist[ic]=0; // init histogramme
3291 //generation histogramme
3292 for(ic=0; ic<=2*r; ic++ )
3293 for(jc=0; jc<=2*r; jc++)
3294 hist[medRoi[(threadIdx.y+ic)*(blockDim.x+2*r)+ (threadIdx.x+jc)]]++ ;
3296 //parcours histogramme
3298 for(ic=0; ic<256; ic++)
3301 //selection de la valeur du percentile (ici 50%=SUM/2)
3302 if ( cpt > (((2*r+1)*(2*r+1))>>1) ) break ;
3305 output[ __mul24(i, j_dim) +j ] = ic ;
3309 __global__ void kernel_median5_2pix( unsigned short*output, int i_dim, int j_dim)
3312 // coordonnees absolues du point
3313 int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
3314 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
3316 /**************************************************************************
3318 **************************************************************************/
3319 int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 ;
3320 int b7, b8, b9, b10, b11, b12, b13 ;
3322 /********************************************************************************
3323 * les 14 premieres valeurs (suffisant pour median 5x5 par forgetfull selection)
3324 ********************************************************************************/
3326 a0 = tex2D(tex_img_ins, j-1, i-2) ;
3327 a1 = tex2D(tex_img_ins, j , i-2) ;
3328 a2 = tex2D(tex_img_ins, j+1, i-2) ;
3329 a3 = tex2D(tex_img_ins, j+2, i-2) ;
3331 a4 = tex2D(tex_img_ins, j-1, i-1) ;
3332 a5 = tex2D(tex_img_ins, j , i-1) ;
3333 a6 = tex2D(tex_img_ins, j+1, i-1) ;
3334 a7 = tex2D(tex_img_ins, j+2, i-1) ;
3336 a8 = tex2D(tex_img_ins, j-1, i) ;
3337 a9 = tex2D(tex_img_ins, j , i) ;
3338 a10 = tex2D(tex_img_ins, j+1, i) ;
3339 a11 = tex2D(tex_img_ins, j+2, i) ;
3340 //les 2 premiers de la 4eme ligne
3341 a12 = tex2D(tex_img_ins, j-1, i+1) ;
3342 a13 = tex2D(tex_img_ins, j , i+1) ;
3344 //min max aux extremites
3345 minmax14(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3347 //chargement valeurs suivante (15)
3348 a13 = tex2D(tex_img_ins, j+1, i+1);
3349 //minmax aux extremites
3350 minmax13(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3352 //chargement valeur suivante (16)
3353 a13 = tex2D(tex_img_ins, j+2, i+1);
3354 //minmax aux extremites
3355 minmax12(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3357 //chargement valeur suivante (17)
3358 a13 = tex2D(tex_img_ins, j-1, i+2);
3359 //minmax aux extremites
3360 minmax11(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3362 //chargement valeur suivante (18)
3363 a13 = tex2D(tex_img_ins, j , i+2);
3364 //minmax aux extremites
3365 minmax10(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3367 //chargement valeur suivante (19)
3368 a13 = tex2D(tex_img_ins, j+1, i+2);
3369 //minmax aux extremites
3370 minmax9(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3372 //chargement valeur suivante (20)
3373 a13 = tex2D(tex_img_ins, j+2, i+2);
3374 //minmax aux extmites
3375 minmax8(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3377 // fin des pixels voisins communs deux pixels centraux
3378 b7=a7; b8=a8; b9=a9; b10=a10; b11=a11; b12=a12; b13=a13;
3380 //chargement valeur suivante (21)
3381 a13 = tex2D(tex_img_ins, j-2, i-2);
3382 b13 = tex2D(tex_img_ins, j+3, i-2);
3383 //minmax aux extremites
3384 minmax7(&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3385 minmax7(&b7,&b8,&b9,&b10,&b11,&b12,&b13);
3387 //chargement valeur suivante (22)
3388 a13 = tex2D(tex_img_ins, j-2, i-1);
3389 b13 = tex2D(tex_img_ins, j+3, i-1);
3390 //minmax aux extremites
3391 minmax6(&a8,&a9,&a10,&a11,&a12,&a13);
3392 minmax6(&b8,&b9,&b10,&b11,&b12,&b13);
3394 //chargement valeur suivante (23)
3395 a13 = tex2D(tex_img_ins, j-2, i );
3396 b13 = tex2D(tex_img_ins, j+3, i );
3397 //minmax aux extremites
3398 minmax5(&a9,&a10,&a11,&a12,&a13);
3399 minmax5(&b9,&b10,&b11,&b12,&b13);
3401 //chargement valeur suivante (24)
3402 a13 = tex2D(tex_img_ins, j-2, i+1);
3403 b13 = tex2D(tex_img_ins, j+3, i+1);
3404 //minmax aux extremites
3405 minmax4(&a10,&a11,&a12,&a13);
3406 minmax4(&b10,&b11,&b12,&b13);
3408 //chargement valeur suivante (25)
3409 a13 = tex2D(tex_img_ins, j-2, i+2);
3410 b13 = tex2D(tex_img_ins, j+3, i+2);
3411 //minmax aux extremites
3412 minmax3(&a11,&a12,&a13);
3413 minmax3(&b11,&b12,&b13);
3415 //median au milieu !
3416 output[ __mul24(i, j_dim) +j ] = a12 ;
3417 output[ __mul24(i, j_dim) +j+1 ] = b12 ;
3422 __global__ void kernel_median5_2pix( unsigned char *output, int i_dim, int j_dim)
3425 // coordonnees absolues du point
3426 int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
3427 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
3429 /**************************************************************************
3431 **************************************************************************/
3432 int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 ;
3433 int b7, b8, b9, b10, b11, b12, b13 ;
3435 /********************************************************************************
3436 * les 14 premieres valeurs (suffisant pour median 5x5 par forgetfull selection)
3437 ********************************************************************************/
3439 a0 = tex2D(tex_img_inc, j-1, i-2) ;
3440 a1 = tex2D(tex_img_inc, j , i-2) ;
3441 a2 = tex2D(tex_img_inc, j+1, i-2) ;
3442 a3 = tex2D(tex_img_inc, j+2, i-2) ;
3444 a4 = tex2D(tex_img_inc, j-1, i-1) ;
3445 a5 = tex2D(tex_img_inc, j , i-1) ;
3446 a6 = tex2D(tex_img_inc, j+1, i-1) ;
3447 a7 = tex2D(tex_img_inc, j+2, i-1) ;
3449 a8 = tex2D(tex_img_inc, j-1, i) ;
3450 a9 = tex2D(tex_img_inc, j , i) ;
3451 a10 = tex2D(tex_img_inc, j+1, i) ;
3452 a11 = tex2D(tex_img_inc, j+2, i) ;
3453 //les 2 premiers de la 4eme ligne
3454 a12 = tex2D(tex_img_inc, j-1, i+1) ;
3455 a13 = tex2D(tex_img_inc, j , i+1) ;
3457 //min max aux extremites
3458 minmax14(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3460 //chargement valeurs suivante (15)
3461 a13 = tex2D(tex_img_inc, j+1, i+1);
3462 //minmax aux extremites
3463 minmax13(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3465 //chargement valeur suivante (16)
3466 a13 = tex2D(tex_img_inc, j+2, i+1);
3467 //minmax aux extremites
3468 minmax12(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3470 //chargement valeur suivante (17)
3471 a13 = tex2D(tex_img_inc, j-1, i+2);
3472 //minmax aux extremites
3473 minmax11(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3475 //chargement valeur suivante (18)
3476 a13 = tex2D(tex_img_inc, j , i+2);
3477 //minmax aux extremites
3478 minmax10(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3480 //chargement valeur suivante (19)
3481 a13 = tex2D(tex_img_inc, j+1, i+2);
3482 //minmax aux extremites
3483 minmax9(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3485 //chargement valeur suivante (20)
3486 a13 = tex2D(tex_img_inc, j+2, i+2);
3487 //minmax aux extmites
3488 minmax8(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3490 // fin des pixels voisins communs deux pixels centraux
3491 b7=a7; b8=a8; b9=a9; b10=a10; b11=a11; b12=a12; b13=a13;
3493 //chargement valeur suivante (21)
3494 a13 = tex2D(tex_img_inc, j-2, i-2);
3495 b13 = tex2D(tex_img_inc, j+3, i-2);
3496 //minmax aux extremites
3497 minmax7(&a7,&a8,&a9,&a10,&a11,&a12,&a13);
3498 minmax7(&b7,&b8,&b9,&b10,&b11,&b12,&b13);
3500 //chargement valeur suivante (22)
3501 a13 = tex2D(tex_img_inc, j-2, i-1);
3502 b13 = tex2D(tex_img_inc, j+3, i-1);
3503 //minmax aux extremites
3504 minmax6(&a8,&a9,&a10,&a11,&a12,&a13);
3505 minmax6(&b8,&b9,&b10,&b11,&b12,&b13);
3507 //chargement valeur suivante (23)
3508 a13 = tex2D(tex_img_inc, j-2, i );
3509 b13 = tex2D(tex_img_inc, j+3, i );
3510 //minmax aux extremites
3511 minmax5(&a9,&a10,&a11,&a12,&a13);
3512 minmax5(&b9,&b10,&b11,&b12,&b13);
3514 //chargement valeur suivante (24)
3515 a13 = tex2D(tex_img_inc, j-2, i+1);
3516 b13 = tex2D(tex_img_inc, j+3, i+1);
3517 //minmax aux extremites
3518 minmax4(&a10,&a11,&a12,&a13);
3519 minmax4(&b10,&b11,&b12,&b13);
3521 //chargement valeur suivante (25)
3522 a13 = tex2D(tex_img_inc, j-2, i+2);
3523 b13 = tex2D(tex_img_inc, j+3, i+2);
3524 //minmax aux extremites
3525 minmax3(&a11,&a12,&a13);
3526 minmax3(&b11,&b12,&b13);
3528 //median au milieu !
3529 output[ __mul24(i, j_dim) +j ] = a12 ;
3530 output[ __mul24(i, j_dim) +j+1 ] = b12 ;
3535 __global__ void kernel_median7( unsigned short*output, int i_dim, int j_dim)
3538 // coordonnees absolues du point
3539 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
3540 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
3542 /**************************************************************************
3544 **************************************************************************/
3545 int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25 ;
3547 /****************************************
3548 * les 26 premieres valeurs
3549 ****************************************/
3551 a0 = tex2D(tex_img_ins, j-2, i-3) ;
3552 a1 = tex2D(tex_img_ins, j-1, i-3) ;
3553 a2 = tex2D(tex_img_ins, j , i-3) ;
3554 a3 = tex2D(tex_img_ins, j+1, i-3) ;
3555 a4 = tex2D(tex_img_ins, j+2, i-3) ;
3556 a5 = tex2D(tex_img_ins, j+3, i-3) ;
3558 a6 = tex2D(tex_img_ins, j-2, i-2) ;
3559 a7 = tex2D(tex_img_ins, j-1, i-2) ;
3560 a8 = tex2D(tex_img_ins, j , i-2) ;
3561 a9 = tex2D(tex_img_ins, j+1, i-2) ;
3562 a10 = tex2D(tex_img_ins, j+2, i-2) ;
3563 a11 = tex2D(tex_img_ins, j+3, i-2) ;
3565 a12 = tex2D(tex_img_ins, j-2, i-1) ;
3566 a13 = tex2D(tex_img_ins, j-1, i-1) ;
3567 a14 = tex2D(tex_img_ins, j , i-1) ;
3568 a15 = tex2D(tex_img_ins, j+1, i-1) ;
3569 a16 = tex2D(tex_img_ins, j+2, i-1) ;
3570 a17 = tex2D(tex_img_ins, j+3, i-1) ;
3572 a18 = tex2D(tex_img_ins, j-2, i ) ;
3573 a19 = tex2D(tex_img_ins, j-1, i ) ;
3574 a20 = tex2D(tex_img_ins, j , i ) ;
3575 a21 = tex2D(tex_img_ins, j+1, i ) ;
3576 a22 = tex2D(tex_img_ins, j+2, i ) ;
3577 a23 = tex2D(tex_img_ins, j+3, i ) ;
3579 a24 = tex2D(tex_img_ins, j-2, i+1) ;
3580 a25 = tex2D(tex_img_ins, j-1, i+1) ;
3582 //min max aux extremites
3583 minmax26(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3585 //chargement valeurs suivante (26)
3586 a25 = tex2D(tex_img_ins, j , i+1);
3587 //minmax aux extremites
3588 minmax25(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3590 //chargement valeur suivante (27)
3591 a25 = tex2D(tex_img_ins, j+1, i+1);
3592 //minmax aux extremites
3593 minmax24(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3595 //chargement valeur suivante (28)
3596 a25 = tex2D(tex_img_ins, j+2, i+1);
3597 //minmax aux extremites
3598 minmax23(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3600 //chargement valeur suivante (29)
3601 a25 = tex2D(tex_img_ins, j+3, i+1);
3602 //minmax aux extremites
3603 minmax22(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3605 //chargement valeur suivante (30)
3606 a25 = tex2D(tex_img_ins, j-2, i+2);
3607 //minmax aux extremites
3608 minmax21(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3610 //chargement valeur suivante (31)
3611 a25 = tex2D(tex_img_ins, j-1, i+2);
3612 //minmax aux extmites
3613 minmax20(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3615 //chargement valeur suivante (32)
3616 a25 = tex2D(tex_img_ins, j , i+2);
3617 //minmax aux extmites
3618 minmax19(&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3620 //chargement valeur suivante (33)
3621 a25 = tex2D(tex_img_ins, j+1, i+2);
3622 //minmax aux extmites
3623 minmax18(&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3625 //chargement valeur suivante (34)
3626 a25 = tex2D(tex_img_ins, j+2, i+2);
3627 //minmax aux extmites
3628 minmax17(&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3630 //chargement valeur suivante (35)
3631 a25 = tex2D(tex_img_ins, j+3, i+2);
3632 //minmax aux extmites
3633 minmax16(&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3635 //chargement valeur suivante (36)
3636 a25 = tex2D(tex_img_ins, j-2, i+3);
3637 //minmax aux extmites
3638 minmax15(&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3640 //chargement valeur suivante (37)
3641 a25 = tex2D(tex_img_ins, j-1, i+3);
3642 //minmax aux extmites
3644 minmax14(&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3645 //chargement valeur suivante (38)
3646 a25 = tex2D(tex_img_ins, j , i+3);
3647 //minmax aux extmites
3648 minmax13(&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3650 //chargement valeur suivante (39)
3651 a25 = tex2D(tex_img_ins, j+1, i+3);
3652 //minmax aux extmites
3653 minmax12(&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3655 //chargement valeur suivante (40)
3656 a25 = tex2D(tex_img_ins, j+2, i+3);
3657 //minmax aux extmites
3658 minmax11(&a15, &a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3660 //chargement valeur suivante (41)
3661 a25 = tex2D(tex_img_ins, j+3, i+3);
3662 //minmax aux extmites
3663 minmax10(&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3665 //chargement valeurs suivantes
3666 a25 = tex2D(tex_img_ins, j-3, i+3);
3667 //minmax aux extremites
3668 minmax9(&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3670 //chargement valeurs suivantes
3671 a25 = tex2D(tex_img_ins, j-3, i+2);
3672 //minmax aux extremites
3673 minmax8(&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3675 //chargement valeurs suivantes
3676 a25 = tex2D(tex_img_ins, j-3, i+1);
3677 //minmax aux extremites
3678 minmax7(&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3680 //chargement valeurs suivantes
3681 a25 = tex2D(tex_img_ins, j-3, i);
3682 //minmax aux extremites
3683 minmax6(&a20,&a21,&a22,&a23,&a24,&a25);
3685 //chargement valeurs suivantes
3686 a25 = tex2D(tex_img_ins, j-3, i-1);
3687 //minmax aux extremites
3688 minmax5(&a21,&a22,&a23,&a24,&a25);
3690 //chargement valeurs suivantes
3691 a25 = tex2D(tex_img_ins, j-3, i-2);
3692 //minmax aux extremites
3693 minmax4(&a22,&a23,&a24,&a25);
3695 //chargement valeurs suivantes
3696 a25 = tex2D(tex_img_ins, j-3, i-3);
3697 //minmax aux extremites
3698 minmax3(&a23,&a24,&a25);
3700 //medians au milieu !
3701 output[ __mul24(i, j_dim) +j ] = a24 ;
3707 __global__ void kernel_median7_2pix( unsigned short*output, int i_dim, int j_dim)
3710 // coordonnees absolues du point
3711 int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
3712 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
3714 /**************************************************************************
3716 **************************************************************************/
3717 int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25 ;
3718 int b17,b18,b19,b20,b21,b22,b23,b24,b25;
3720 /****************************************
3721 * les 26 premieres valeurs
3722 ****************************************/
3724 a0 = tex2D(tex_img_ins, j-2, i-3) ;
3725 a1 = tex2D(tex_img_ins, j-1, i-3) ;
3726 a2 = tex2D(tex_img_ins, j , i-3) ;
3727 a3 = tex2D(tex_img_ins, j+1, i-3) ;
3728 a4 = tex2D(tex_img_ins, j+2, i-3) ;
3729 a5 = tex2D(tex_img_ins, j+3, i-3) ;
3731 a6 = tex2D(tex_img_ins, j-2, i-2) ;
3732 a7 = tex2D(tex_img_ins, j-1, i-2) ;
3733 a8 = tex2D(tex_img_ins, j , i-2) ;
3734 a9 = tex2D(tex_img_ins, j+1, i-2) ;
3735 a10 = tex2D(tex_img_ins, j+2, i-2) ;
3736 a11 = tex2D(tex_img_ins, j+3, i-2) ;
3738 a12 = tex2D(tex_img_ins, j-2, i-1) ;
3739 a13 = tex2D(tex_img_ins, j-1, i-1) ;
3740 a14 = tex2D(tex_img_ins, j , i-1) ;
3741 a15 = tex2D(tex_img_ins, j+1, i-1) ;
3742 a16 = tex2D(tex_img_ins, j+2, i-1) ;
3743 a17 = tex2D(tex_img_ins, j+3, i-1) ;
3745 a18 = tex2D(tex_img_ins, j-2, i ) ;
3746 a19 = tex2D(tex_img_ins, j-1, i ) ;
3747 a20 = tex2D(tex_img_ins, j , i ) ;
3748 a21 = tex2D(tex_img_ins, j+1, i ) ;
3749 a22 = tex2D(tex_img_ins, j+2, i ) ;
3750 a23 = tex2D(tex_img_ins, j+3, i ) ;
3752 a24 = tex2D(tex_img_ins, j-2, i+1) ;
3753 a25 = tex2D(tex_img_ins, j-1, i+1) ;
3755 //min max aux extremites
3756 minmax26(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3758 //chargement valeurs suivante (26)
3759 a25 = tex2D(tex_img_ins, j , i+1);
3760 //minmax aux extremites
3761 minmax25(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3763 //chargement valeur suivante (27)
3764 a25 = tex2D(tex_img_ins, j+1, i+1);
3765 //minmax aux extremites
3766 minmax24(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3768 //chargement valeur suivante (28)
3769 a25 = tex2D(tex_img_ins, j+2, i+1);
3770 //minmax aux extremites
3771 minmax23(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3773 //chargement valeur suivante (29)
3774 a25 = tex2D(tex_img_ins, j+3, i+1);
3775 //minmax aux extremites
3776 minmax22(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3778 //chargement valeur suivante (30)
3779 a25 = tex2D(tex_img_ins, j-2, i+2);
3780 //minmax aux extremites
3781 minmax21(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3783 //chargement valeur suivante (31)
3784 a25 = tex2D(tex_img_ins, j-1, i+2);
3785 //minmax aux extmites
3786 minmax20(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3788 //chargement valeur suivante (32)
3789 a25 = tex2D(tex_img_ins, j , i+2);
3790 //minmax aux extmites
3791 minmax19(&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3793 //chargement valeur suivante (33)
3794 a25 = tex2D(tex_img_ins, j+1, i+2);
3795 //minmax aux extmites
3796 minmax18(&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3798 //chargement valeur suivante (34)
3799 a25 = tex2D(tex_img_ins, j+2, i+2);
3800 //minmax aux extmites
3801 minmax17(&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3803 //chargement valeur suivante (35)
3804 a25 = tex2D(tex_img_ins, j+3, i+2);
3805 //minmax aux extmites
3806 minmax16(&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3808 //chargement valeur suivante (36)
3809 a25 = tex2D(tex_img_ins, j-2, i+3);
3810 //minmax aux extmites
3811 minmax15(&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3813 //chargement valeur suivante (37)
3814 a25 = tex2D(tex_img_ins, j-1, i+3);
3815 //minmax aux extmites
3817 minmax14(&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3818 //chargement valeur suivante (38)
3819 a25 = tex2D(tex_img_ins, j , i+3);
3820 //minmax aux extmites
3821 minmax13(&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3823 //chargement valeur suivante (39)
3824 a25 = tex2D(tex_img_ins, j+1, i+3);
3825 //minmax aux extmites
3826 minmax12(&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3828 //chargement valeur suivante (40)
3829 a25 = tex2D(tex_img_ins, j+2, i+3);
3830 //minmax aux extmites
3831 minmax11(&a15, &a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3833 //chargement valeur suivante (41)
3834 a25 = tex2D(tex_img_ins, j+3, i+3);
3835 //minmax aux extmites
3836 minmax10(&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3838 // fin des pixels voisins communs deux pixels centraux
3839 b17=a17; b18=a18; b19=a19; b20=a20; b21=a21; b22=a22; b23=a23; b24=a24; b25=a25;
3841 //chargement valeurs suivantes
3842 a25 = tex2D(tex_img_ins, j-3, i+3);
3843 b25 = tex2D(tex_img_ins, j+4, i+3);
3844 //minmax aux extremites
3845 minmax9(&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3846 minmax9(&b17,&b18,&b19,&b20,&b21,&b22,&b23,&b24,&b25);
3848 //chargement valeurs suivantes
3849 a25 = tex2D(tex_img_ins, j-3, i+2);
3850 b25 = tex2D(tex_img_ins, j+4, i+2);
3851 //minmax aux extremites
3852 minmax8(&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3853 minmax8(&b18,&b19,&b20,&b21,&b22,&b23,&b24,&b25);
3855 //chargement valeurs suivantes
3856 a25 = tex2D(tex_img_ins, j-3, i+1);
3857 b25 = tex2D(tex_img_ins, j+4, i+1);
3858 //minmax aux extremites
3859 minmax7(&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3860 minmax7(&b19,&b20,&b21,&b22,&b23,&b24,&b25);
3862 //chargement valeurs suivantes
3863 a25 = tex2D(tex_img_ins, j-3, i);
3864 b25 = tex2D(tex_img_ins, j+4, i);
3865 //minmax aux extremites
3866 minmax6(&a20,&a21,&a22,&a23,&a24,&a25);
3867 minmax6(&b20,&b21,&b22,&b23,&b24,&b25);
3869 //chargement valeurs suivantes
3870 a25 = tex2D(tex_img_ins, j-3, i-1);
3871 b25 = tex2D(tex_img_ins, j+4, i-1);
3872 //minmax aux extremites
3873 minmax5(&a21,&a22,&a23,&a24,&a25);
3874 minmax5(&b21,&b22,&b23,&b24,&b25);
3876 //chargement valeurs suivantes
3877 a25 = tex2D(tex_img_ins, j-3, i-2);
3878 b25 = tex2D(tex_img_ins, j+4, i-2);
3879 //minmax aux extremites
3880 minmax4(&a22,&a23,&a24,&a25);
3881 minmax4(&b22,&b23,&b24,&b25);
3883 //chargement valeurs suivantes
3884 a25 = tex2D(tex_img_ins, j-3, i-3);
3885 b25 = tex2D(tex_img_ins, j+4, i-3);
3886 //minmax aux extremites
3887 minmax3(&a23,&a24,&a25);
3888 minmax3(&b23,&b24,&b25);
3890 //medians au milieu !
3891 output[ __mul24(i, j_dim) +j ] = a24 ;
3892 output[ __mul24(i, j_dim) +j+1 ] = b24 ;
3897 __global__ void kernel_median7_2pix( unsigned char *output, int i_dim, int j_dim)
3900 // coordonnees absolues du point
3901 int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ;
3902 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
3904 /**************************************************************************
3906 **************************************************************************/
3907 int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25 ;
3908 int b17,b18,b19,b20,b21,b22,b23,b24,b25;
3910 /****************************************
3911 * les 26 premieres valeurs
3912 ****************************************/
3914 a0 = tex2D(tex_img_inc, j-2, i-3) ;
3915 a1 = tex2D(tex_img_inc, j-1, i-3) ;
3916 a2 = tex2D(tex_img_inc, j , i-3) ;
3917 a3 = tex2D(tex_img_inc, j+1, i-3) ;
3918 a4 = tex2D(tex_img_inc, j+2, i-3) ;
3919 a5 = tex2D(tex_img_inc, j+3, i-3) ;
3921 a6 = tex2D(tex_img_inc, j-2, i-2) ;
3922 a7 = tex2D(tex_img_inc, j-1, i-2) ;
3923 a8 = tex2D(tex_img_inc, j , i-2) ;
3924 a9 = tex2D(tex_img_inc, j+1, i-2) ;
3925 a10 = tex2D(tex_img_inc, j+2, i-2) ;
3926 a11 = tex2D(tex_img_inc, j+3, i-2) ;
3928 a12 = tex2D(tex_img_inc, j-2, i-1) ;
3929 a13 = tex2D(tex_img_inc, j-1, i-1) ;
3930 a14 = tex2D(tex_img_inc, j , i-1) ;
3931 a15 = tex2D(tex_img_inc, j+1, i-1) ;
3932 a16 = tex2D(tex_img_inc, j+2, i-1) ;
3933 a17 = tex2D(tex_img_inc, j+3, i-1) ;
3935 a18 = tex2D(tex_img_inc, j-2, i ) ;
3936 a19 = tex2D(tex_img_inc, j-1, i ) ;
3937 a20 = tex2D(tex_img_inc, j , i ) ;
3938 a21 = tex2D(tex_img_inc, j+1, i ) ;
3939 a22 = tex2D(tex_img_inc, j+2, i ) ;
3940 a23 = tex2D(tex_img_inc, j+3, i ) ;
3942 a24 = tex2D(tex_img_inc, j-2, i+1) ;
3943 a25 = tex2D(tex_img_inc, j-1, i+1) ;
3945 //min max aux extremites
3946 minmax26(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3948 //chargement valeurs suivante (26)
3949 a25 = tex2D(tex_img_inc, j , i+1);
3950 //minmax aux extremites
3951 minmax25(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3953 //chargement valeur suivante (27)
3954 a25 = tex2D(tex_img_inc, j+1, i+1);
3955 //minmax aux extremites
3956 minmax24(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3958 //chargement valeur suivante (28)
3959 a25 = tex2D(tex_img_inc, j+2, i+1);
3960 //minmax aux extremites
3961 minmax23(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3963 //chargement valeur suivante (29)
3964 a25 = tex2D(tex_img_inc, j+3, i+1);
3965 //minmax aux extremites
3966 minmax22(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3968 //chargement valeur suivante (30)
3969 a25 = tex2D(tex_img_inc, j-2, i+2);
3970 //minmax aux extremites
3971 minmax21(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3973 //chargement valeur suivante (31)
3974 a25 = tex2D(tex_img_inc, j-1, i+2);
3975 //minmax aux extmites
3976 minmax20(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3978 //chargement valeur suivante (32)
3979 a25 = tex2D(tex_img_inc, j , i+2);
3980 //minmax aux extmites
3981 minmax19(&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3983 //chargement valeur suivante (33)
3984 a25 = tex2D(tex_img_inc, j+1, i+2);
3985 //minmax aux extmites
3986 minmax18(&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3988 //chargement valeur suivante (34)
3989 a25 = tex2D(tex_img_inc, j+2, i+2);
3990 //minmax aux extmites
3991 minmax17(&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3993 //chargement valeur suivante (35)
3994 a25 = tex2D(tex_img_inc, j+3, i+2);
3995 //minmax aux extmites
3996 minmax16(&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
3998 //chargement valeur suivante (36)
3999 a25 = tex2D(tex_img_inc, j-2, i+3);
4000 //minmax aux extmites
4001 minmax15(&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
4003 //chargement valeur suivante (37)
4004 a25 = tex2D(tex_img_inc, j-1, i+3);
4005 //minmax aux extmites
4007 minmax14(&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
4008 //chargement valeur suivante (38)
4009 a25 = tex2D(tex_img_inc, j , i+3);
4010 //minmax aux extmites
4011 minmax13(&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
4013 //chargement valeur suivante (39)
4014 a25 = tex2D(tex_img_inc, j+1, i+3);
4015 //minmax aux extmites
4016 minmax12(&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
4018 //chargement valeur suivante (40)
4019 a25 = tex2D(tex_img_inc, j+2, i+3);
4020 //minmax aux extmites
4021 minmax11(&a15, &a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
4023 //chargement valeur suivante (41)
4024 a25 = tex2D(tex_img_inc, j+3, i+3);
4025 //minmax aux extmites
4026 minmax10(&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
4028 // fin des pixels voisins communs deux pixels centraux
4029 b17=a17; b18=a18; b19=a19; b20=a20; b21=a21; b22=a22; b23=a23; b24=a24; b25=a25;
4031 //chargement valeurs suivantes
4032 a25 = tex2D(tex_img_inc, j-3, i+3);
4033 b25 = tex2D(tex_img_inc, j+4, i+3);
4034 //minmax aux extremites
4035 minmax9(&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
4036 minmax9(&b17,&b18,&b19,&b20,&b21,&b22,&b23,&b24,&b25);
4038 //chargement valeurs suivantes
4039 a25 = tex2D(tex_img_inc, j-3, i+2);
4040 b25 = tex2D(tex_img_inc, j+4, i+2);
4041 //minmax aux extremites
4042 minmax8(&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25);
4043 minmax8(&b18,&b19,&b20,&b21,&b22,&b23,&b24,&b25);
4045 //chargement valeurs suivantes
4046 a25 = tex2D(tex_img_inc, j-3, i+1);
4047 b25 = tex2D(tex_img_inc, j+4, i+1);
4048 //minmax aux extremites
4049 minmax7(&a19,&a20,&a21,&a22,&a23,&a24,&a25);
4050 minmax7(&b19,&b20,&b21,&b22,&b23,&b24,&b25);
4052 //chargement valeurs suivantes
4053 a25 = tex2D(tex_img_inc, j-3, i);
4054 b25 = tex2D(tex_img_inc, j+4, i);
4055 //minmax aux extremites
4056 minmax6(&a20,&a21,&a22,&a23,&a24,&a25);
4057 minmax6(&b20,&b21,&b22,&b23,&b24,&b25);
4059 //chargement valeurs suivantes
4060 a25 = tex2D(tex_img_inc, j-3, i-1);
4061 b25 = tex2D(tex_img_inc, j+4, i-1);
4062 //minmax aux extremites
4063 minmax5(&a21,&a22,&a23,&a24,&a25);
4064 minmax5(&b21,&b22,&b23,&b24,&b25);
4066 //chargement valeurs suivantes
4067 a25 = tex2D(tex_img_inc, j-3, i-2);
4068 b25 = tex2D(tex_img_inc, j+4, i-2);
4069 //minmax aux extremites
4070 minmax4(&a22,&a23,&a24,&a25);
4071 minmax4(&b22,&b23,&b24,&b25);
4073 //chargement valeurs suivantes
4074 a25 = tex2D(tex_img_inc, j-3, i-3);
4075 b25 = tex2D(tex_img_inc, j+4, i-3);
4076 //minmax aux extremites
4077 minmax3(&a23,&a24,&a25);
4078 minmax3(&b23,&b24,&b25);
4080 //medians au milieu !
4081 output[ __mul24(i, j_dim) +j ] = a24 ;
4082 output[ __mul24(i, j_dim) +j+1 ] = b24 ;
4088 /*****************************************************************************
4089 * median generic shared mem + forgetfull
4090 *****************************************************************************/
4091 __global__ void kernel_medianForgetRSH( unsigned short * output, int i_dim, int j_dim, int r)
4093 // coordonnees absolues du point
4094 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
4095 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
4096 unsigned short ic, jc ;
4097 unsigned short Nreg = ((2*r+1)*(2*r+1))/2 + 2 ;
4099 int bdimX = blockDim.x; //<<1 ; // pour le cas \E0 2 pixels par thread
4100 int tidX = threadIdx.x; //<<1 ;
4102 // chargement en smem
4103 int idrow = threadIdx.y*(blockDim.x+2*r) ;
4105 extern __shared__ int medRoi[];
4107 // bloc 0 (en haut \E0 gauche)
4108 medRoi[ idrow + threadIdx.x ] = tex2D(tex_img_ins, j-r, i-r) ;
4109 // bloc 1 (en haut \E0 droite)...
4110 if ( threadIdx.x < 2*r ) //...ou plutot ce qu'il en manque
4111 medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-r, i-r ) ;
4112 // bloc 2 ( en bas \E0 gauche)
4113 if ( threadIdx.y < 2*r )
4115 idrow = (threadIdx.y+blockDim.y)*(blockDim.x+2*r) ;
4116 medRoi[ idrow + threadIdx.x ] = tex2D( tex_img_ins, j-r, i+blockDim.y-r ) ;
4117 //bloc 4 ( en bas \E0 doite )...
4118 if ( threadIdx.x < 2*r ) //...ou ce qu'il en manque
4119 medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-r, i+blockDim.y-r ) ;
4123 // remplissage du vecteur de tri minmax
4124 unsigned short vect[8066] ;
4126 for (ic=0; ic<2*r+1; ic++)
4128 for (jc=0; jc<2*r+1; jc++)
4130 if ( ic*(2*r+1)+jc < Nreg )
4132 vect[ ic*(2*r+1)+jc ] = medRoi[ (threadIdx.y+ic)*(bdimX+2*r)+ (tidX+jc) ] ;
4135 minmaxN(vect, Freg--) ;
4136 vect[ Nreg-1 ] = medRoi[ (threadIdx.y+ic)*(bdimX+2*r)+ (tidX+jc) ] ;
4140 minmax3(&vect[Nreg-3], &vect[Nreg-2], &vect[Nreg-1])
4142 //medRoi[ (threadIdx.y+ic)*(bdimX+L-1)+ (tidX+jc) ]
4144 output[ __mul24(i, j_dim) +j ] = vect[ Nreg-2 ];
4148 /*****************************************************************************
4149 * median generic shared mem + forgetfull
4150 *****************************************************************************/
4151 __global__ void kernel_medianForgetR( unsigned short * output, int i_dim, int j_dim, int r)
4153 // coordonnees absolues du point
4154 int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ;
4155 int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ;
4156 unsigned short ic, jc ;
4157 unsigned short Nreg = ((2*r+1)*(2*r+1))/2 + 2 ;
4159 // remplissage du vecteur de tri minmax
4160 unsigned short vect[8066] ;
4162 for (ic=0; ic<2*r+1; ic++)
4164 for (jc=0; jc<2*r+1; jc++)
4166 if ( ic*(2*r+1)+jc < Nreg )
4168 vect[ ic*(2*r+1)+jc ] = tex2D(tex_img_ins, j-r+jc, i-r+ic) ;
4171 minmaxN(vect, Freg--) ;
4172 vect[ Nreg-1 ] = tex2D(tex_img_ins, j-r+jc, i-r+ic) ;
4176 minmax3(&vect[Nreg-3], &vect[Nreg-2], &vect[Nreg-1])
4178 //medRoi[ (threadIdx.y+ic)*(bdimX+L-1)+ (tidX+jc) ]
4180 output[ __mul24(i, j_dim) +j ] = vect[ Nreg-2 ];
4185 /**********************************************************************************
4186 * MEDIAN PSEUDO-SEPARABLE POUR GRANDS NOYAUX
4187 **********************************************************************************/
4188 __global__ void kernel_medianSepR( unsigned short *output, int i_dim, int j_dim, int r)
4191 int idc, val, min, max, inf, egal, sup, mxinf, minsup, estim ;
4193 //coordonnées ds le bloc
4194 int ib = threadIdx.y ;
4195 int jb = threadIdx.x ;
4196 //int idx_h = __mul24(ib+r,blockDim.x) + jb ; // index pixel deans shmem (bloc+halo)
4197 //int offset = __mul24(blockDim.x,r) ;
4199 // coordonnees absolues du point
4200 int j = __mul24(blockIdx.x,blockDim.x) + jb ;
4201 int i = __mul24(blockIdx.y,blockDim.y) + ib ;
4203 extern __shared__ int buff[] ;
4204 /***********************************************************************************
4205 * CHARGEMENT DATA EN SHARED MEM
4206 ***********************************************************************************/
4207 for (idc = 0 ; idc < (2*(blockDim.y+r)-1)/blockDim.y; idc++)
4209 if (idc*blockDim.y +ib < i_dim)
4210 buff[ (idc*blockDim.y +ib)*blockDim.x + jb ] = tex2D(tex_img_ins, j, i-r+ idc*blockDim.y) ;
4214 /**********************************************************************************************
4215 * TRI VERTICAL par algo TORBEN MOGENSEN
4216 * (a little bit slow but saves memory => faster !)
4217 **********************************************************************************************/
4218 min = max = buff[ ib*blockDim.x +jb] ;
4220 for (idc= 0 ; idc< 2*r+1 ; idc++ )
4222 val = buff[ __mul24(ib+idc, blockDim.x) +jb ] ;
4223 if ( val < min ) min = val ;
4224 if ( val > max ) max = val ;
4229 estim = (min+max)/2 ;
4230 inf = sup = egal = 0 ;
4233 for (idc =0; idc< 2*r+1 ; idc++)
4235 val = buff[ __mul24(ib+idc, blockDim.x) +jb ] ;
4239 if( val > mxinf) mxinf = val ;
4240 } else if (val > estim)
4243 if( val < minsup) minsup = val ;
4246 if ( (inf <= (r+1))&&(sup <=(r+1)) ) break ;
4247 else if (inf>sup) max = mxinf ;
4251 if ( inf >= r+1 ) val = mxinf ;
4252 else if (inf+egal >= r+1) val = estim ;
4255 output[ __mul24(j, i_dim) +i ] = val ;
4261 * correction de staircase
4263 __global__ void kernel_staircase_reduc3(unsigned int * img_out, unsigned int L, unsigned int H)
4265 // coordonnees du point dans le bloc
4266 //unsigned int iib = threadIdx.x ;
4267 //unsigned int jib = threadIdx.y ;
4268 // coordonnees du point dans l'image
4269 unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
4270 unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
4272 int a, b, c, d, e, f, g, h, i ; // gl des voisins
4273 float wa, wb, wc, wd, we, wf, wg, wh, wi ; // poids
4274 float S1, S2, S11, S22, S12, S0, Sx, Sx1, Sx2 ;
4277 // chargement des valeurs GL des pixels du voisinage
4278 a = tex2D(tex_img_estim, x-1, y-1) ;
4279 b = tex2D(tex_img_estim, x , y-1) ;
4280 c = tex2D(tex_img_estim, x+1, y-1) ;
4281 d = tex2D(tex_img_estim, x-1, y ) ;
4282 e = tex2D(tex_img_estim, x , y ) ;
4283 f = tex2D(tex_img_estim, x+1, y ) ;
4284 g = tex2D(tex_img_estim, x-1, y+1) ;
4285 h = tex2D(tex_img_estim, x , y+1) ;
4286 i = tex2D(tex_img_estim, x+1, y+1) ;
4288 wa = tex1D(tex_noyau, abs(a-e)) ;
4289 wb = tex1D(tex_noyau, abs(b-e)) ;
4290 wc = tex1D(tex_noyau, abs(c-e)) ;
4291 wd = tex1D(tex_noyau, abs(d-e)) ;
4293 wf = tex1D(tex_noyau, abs(f-e)) ;
4294 wg = tex1D(tex_noyau, abs(g-e)) ;
4295 wh = tex1D(tex_noyau, abs(h-e)) ;
4296 wi = tex1D(tex_noyau, abs(i-e)) ;
4299 //construction des elements du systeme lineaire
4300 S0 = wa+wb+wc+wd+we+wf+wg+wh+wi ;
4301 S1 = wc+wf+wi-wa-wd-wg ;
4302 S2 = wg+wh+wi-wa-wb-wc ;
4303 Sx = wa*a + wb*b + wc*c + wd*d + we*e + wf*f + wg*g + wh*h + wi*i ;
4304 Sx1 = wc*c + wf*f + wi*i - wa*a - wd*d - wg*g ;
4305 Sx2 = wg*g + wh*h + wi*i - wa*a - wb*b - wc*c ;
4306 S11 = wc+wf+wi+wa+wd+wg ;
4307 S22 = wg+wh+wi+wa+wb+wc ;
4308 S12 = wa + wi -wc -wg ;
4310 c1 = S22*(S11*Sx-S1*Sx1) + S12*(S1*Sx2-S12*Sx) + S2*(S12*Sx1-S11*Sx2) ;
4311 c2 = S22*(S11*S0-S1*S1) + S12*(S2*S1-S12*S0) + S2*(S1*S12-S2*S11) ;
4312 img_out[y*L + x] = c1/c2 ;