filters/gp_filter_resize_alloc: Check w and h
[gfxprim.git] / doc / filters.txt
blob459ba98604fd052a5d38de553c720e6988b4e0b3
1 Pixmap filters
2 ---------------
4 Pixel filters for 'gp_pixmap'.
6 The pixmap filter is basically a function that operates on pixmap pixels.
7 The result may be stored into a new bitmap or placed to bitmap passed as
8 argument or, in some cases, the filter could be used 'in place' so the result
9 is stored into the same pixmap as the one passed as filter source.
11 Common filter API
12 ~~~~~~~~~~~~~~~~~
14 For convenience, the filters API is unified:
16 * There are two functions for each filter
17   - first one takes destination as an argument
18   - second one allocates the destination and returns pointer to it
19 * First argument(s) are always source(s)
20 * Then, in case of second variant, destination
21 * Other parameters follow
22 * And the last argument is link:progress_callback.html[progress callback]
24 When using allocating version of the filter, pointer to the newly allocated
25 pixmap is returned, or in case of failure NULL is returned.
27 If 'malloc()' has failed NULL is returned.
29 If filter has been interrupted by a callback, all allocated memory is freed,
30 and NULL is returned.
32 When using non-allocating variant of the filter, the destination pixmap must
33 have correct pixel type and the size must be big enough to store the result.
34 The return value from such filter is either zero, in case of success, or
35 non-zero when filter was interrupted by a callback.
37 For filters that work 'in-place' (which is explicitly said for each filter)
38 the source and the destination could be the same pixmap. Note that this is not
39 expected to work if you do several overlapping sub-pixmaps and pass these as
40 arguments. Filter used 'in-place' may also cause the filter to run
41 single-threaded which is explicit limitation for all but point filters.
43 [source,c]
44 -------------------------------------------------------------------------------
46  * Filter common API.
47  */
48 int gp_filter_foo(const gp_pixmap *src, gp_pixmap *dst,
49                   foo params ...,
50                   gp_progress_cb *callback);
52 gp_pixmap *gp_filter_foo_alloc(const gp_pixmap *src,
53                                foo params ...,
54                                gp_progress_cb *callback);
55 -------------------------------------------------------------------------------
58 Point Filters
59 ~~~~~~~~~~~~~
61 Point operations are filters that works with pixels as with independent values
62 (the value of destination pixel depends only on the pixel on the same
63 coordinates in source image). All of these filters works 'in-place' and the
64 result has always the same size as the source.
66 Invert
67 ^^^^^^
69 [source,c]
70 -------------------------------------------------------------------------------
71 #include <gfxprim.h>
72 /* or */
73 #include <filters/GP_Point.h>
75 int gp_filter_invert(const gp_pixmap *src, gp_pixmap *dst,
76                      gp_progress_cb *callback);
78 gp_pixmap *gp_filter_invert_alloc(const gp_pixmap *src,
79                                   gp_progress_cb *callback);
80 -------------------------------------------------------------------------------
82 The pixel channel values are counted as +chann_max - val+.
84 include::images/invert/images.txt[]
86 Brightness
87 ^^^^^^^^^^
89 [source,c]
90 -------------------------------------------------------------------------------
91 #include <gfxprim.h>
92 /* or */
93 #include <filters/GP_Point.h>
95 int gp_filter_brightness(const gp_pixmap *src, gp_pixmap *dst,
96                          float p, gp_progress_cb *callback);
98 gp_pixmap *gp_filter_brightness_alloc(const gp_pixmap *src, float p,
99                                       gp_progress_cb *callback);
100 -------------------------------------------------------------------------------
102 The pixel channel values are counted as +val + chann_max * p+.
104 include::images/brightness/images.txt[]
106 Contrast
107 ^^^^^^^^
109 [source,c]
110 -------------------------------------------------------------------------------
111 #include <gfxprim.h>
112 /* or */
113 #include <filters/GP_Point.h>
115 int gp_filter_contrast(const gp_pixmap *src, gp_pixmap *dst,
116                        float p, gp_progress_cb *callback);
118 gp_pixmap *gp_filter_contrast_alloc(const gp_pixmap *src, float p,
119                                     gp_progress_cb *callback);
120 -------------------------------------------------------------------------------
122 The pixel channel values are counted as +val * p+.
124 include::images/contrast/images.txt[]
126 BrightnessContrast
127 ^^^^^^^^^^^^^^^^^^
129 [source,c]
130 -------------------------------------------------------------------------------
131 #include <gfxprim.h>
132 /* or */
133 #include <filters/GP_Point.h>
135 int gp_filter_brightness_contrast(const gp_pixmap *src, gp_pixmap *dst,
136                                 float b, float c,
137                                 gp_progress_cb *callback);
139 gp_pixmap *gp_filter_brightness_contrast_alloc(const gp_pixmap *src,
140                                                float b, float c,
141                                                gp_progress_cb *callback);
142 -------------------------------------------------------------------------------
144 The pixel channel values are counted as +val * c + chann_max * b+.
146 include::images/brightness_contrast/images.txt[]
148 Posterize
149 ^^^^^^^^^
151 [source,c]
152 -------------------------------------------------------------------------------
153 #include <gfxprim.h>
154 /* or */
155 #include <filters/GP_Point.h>
157 int gp_filter_posterize(const gp_pixmap *src, gp_pixmap *dst,
158                         unsigned int levels, gp_progress_cb *callback);
160 gp_pixmap *gp_filter_posterize_alloc(const gp_pixmap *src, unsigned int levels,
161                                      gp_progress_cb *callback);
162 -------------------------------------------------------------------------------
164 The pixel channel values are quantized into number of levels.
166 include::images/posterize/images.txt[]
169 Gaussian additive noise filter
170 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
172 [source,c]
173 -------------------------------------------------------------------------------
174 #include <gp_filter_s.h>
175 /* or */
176 #include <filters/GP_GaussianNoise.h>
178 int gp_filter_gaussian_noise_add_ex(const gp_pixmap *src,
179                                     gp_coord x_src, gp_coord y_src,
180                                     gp_size w_src, gp_size h_src,
181                                     gp_pixmap *dst,
182                                     gp_coord x_dst, gp_coord y_dst,
183                                     float sigma, float mu,
184                                     gp_progress_cb *callback);
186 gp_pixmap *gp_filter_gaussian_noise_add_ex_alloc(const gp_pixmap *src,
187                                                  gp_coord x_src, gp_coord y_src,
188                                                  gp_size w_src, gp_size h_src,
189                                                  float sigma, float mu,
190                                                  gp_progress_cb *callback);
192 static inline int gp_filter_gaussian_noise_add(const gp_pixmap *src,
193                                                gp_pixmap *dst,
194                                                float sigma, float mu,
195                                                gp_progress_cb *callback);
197 static inline gp_pixmap *
198 gp_filter_gaussian_noise_add_alloc(const gp_pixmap *src,
199                                    float sigma, float mu,
200                                    gp_progress_cb *callback);
201 -------------------------------------------------------------------------------
203 Gaussian additive noise filter adds gaussian distributed noise to an image
204 with a defined sigma and mu. Both sigma and mu weights mapped to [0,1]
205 interval.
207 TIP: See the link:example_gaussian_noise.html[gaussian noise example].
209 include::images/gaussian_noise/images.txt[]
211 Arithmetic filters
212 ~~~~~~~~~~~~~~~~~~
214 Arithmetic filters do take two pixmaps as an input and combines them into one
215 output pixmap.
217 The pixel type of both input pixmaps must match.
219 If size of the input pixmaps differs, minimum is used.
221 [source,c]
222 -------------------------------------------------------------------------------
223 #include <filters/GP_Arithmetic.h>
224 /* or */
225 #include <gfxprim.h>
227 int gp_filter_addition(const gp_pixmap *src_a,
228                        const gp_pixmap *src_b,
229                        gp_pixmap *dst,
230                        gp_progress_cb *callback);
232 gp_pixmap *gp_filter_addition_alloc(const gp_pixmap *src_a,
233                                     const gp_pixmap *src_b,
234                                     gp_progress_cb *callback);
235 -------------------------------------------------------------------------------
237 Produces saturated (clamped) addition of two pixmaps.
239 [source,c]
240 -------------------------------------------------------------------------------
241 #include <filters/GP_Arithmetic.h>
242 /* or */
243 #include <gfxprim.h>
245 int gp_filter_multiply(const gp_pixmap *src_a,
246                        const gp_pixmap *src_b,
247                        gp_pixmap *dst,
248                        gp_progress_cb *callback);
250 gp_pixmap *gp_filter_multiply_alloc(const gp_pixmap *src_a,
251                                     const gp_pixmap *src_b,
252                                     gp_progress_cb *callback);
253 -------------------------------------------------------------------------------
255 Produces saturated (clamped) multiplication of two pixmaps.
257 [source,c]
258 -------------------------------------------------------------------------------
259 #include <filters/GP_Arigthmetic.h>
260 /* or */
261 #include <gfxprim.h>
263 int gp_filter_difference(const gp_pixmap *src_a,
264                          const gp_pixmap *src_b,
265                          gp_pixmap *dst,
266                          gp_progress_cb *callback);
268 gp_pixmap *gp_filter_difference_alloc(const gp_pixmap *src_a,
269                                       const gp_pixmap *src_b,
270                                       gp_progress_cb *callback);
272 -------------------------------------------------------------------------------
274 Produces symmetric difference (i.e. abs(a - b)).
276 [source,c]
277 -------------------------------------------------------------------------------
278 #include <filters/GP_Arigthmetic.h>
279 /* or */
280 #include <gfxprim.h>
282 int gp_filter_max(const gp_pixmap *src_a,
283                   const gp_pixmap *src_b,
284                   gp_pixmap *dst,
285                   gp_progress_cb *callback);
287 gp_pixmap *gp_filter_max_alloc(const gp_pixmap *src_a,
288                                const gp_pixmap *src_b,
289                                gp_progress_cb *callback);
291 int gp_filter_min(const gp_pixmap *src_a,
292                   const gp_pixmap *src_b,
293                   gp_pixmap *dst,
294                   gp_progress_cb *callback);
296 gp_pixmap *gp_filter_min_alloc(const gp_pixmap *src_a,
297                                const gp_pixmap *src_b,
298                                gp_progress_cb *callback);
299 -------------------------------------------------------------------------------
301 Maximum and minimum filter.
303 Rotation and Symmetry filters
304 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
306 [source,c]
307 -------------------------------------------------------------------------------
308 #include <filters/GP_Rotate.h>
309 /* or */
310 #include <gfxprim.h>
312 int gp_filter_mirror_h(const gp_pixmap *src, gp_pixmap *dst,
313                        gp_progress_cb *callback);
315 gp_pixmap *gp_filter_mirror_h_alloc(const gp_pixmap *src,
316                                     gp_progress_cb *callback);
317 -------------------------------------------------------------------------------
319 Mirrors pixmap horizontally.
321 Works 'in-place'.
323 The destination has to have the same pixel type and the size must be at least
324 as large as source.
326 include::images/mirror_h/images.txt[]
328 [source,c]
329 -------------------------------------------------------------------------------
330 #include <filters/GP_Rotate.h>
331 /* or */
332 #include <gfxprim.h>
334 int gp_filter_mirror_v(const gp_pixmap *src, gp_pixmap *dst,
335                        gp_progress_cb *callback);
337 gp_pixmap *gp_filter_mirror_v_alloc(const gp_pixmap *src,
338                                     gp_progress_cb *callback);
339 -------------------------------------------------------------------------------
341 Mirrors pixmap vertically.
343 Works 'in-place'.
345 The destination has to have the same pixel type and the size must be at least
346 as large as source.
348 include::images/mirror_v/images.txt[]
350 [source,c]
351 -------------------------------------------------------------------------------
352 #include <filters/GP_Rotate.h>
353 /* or */
354 #include <gfxprim.h>
356 int gp_filter_rotate_90(const gp_pixmap *src, gp_pixmap *dst,
357                         gp_progress_cb *callback);
359 gp_pixmap *gp_filter_rotate_90_alloc(const gp_pixmap *src,
360                                      gp_progress_cb *callback);
361 -------------------------------------------------------------------------------
363 Rotate pixmap by 90 degrees.
365 Doesn't work 'in-place' (yet).
367 The destination has to have the same pixel type and size must be large enough to
368 fit rotated pixmap (i.e. W and H are swapped).
370 include::images/rotate_90/images.txt[]
372 [source,c]
373 -------------------------------------------------------------------------------
374 #include <filters/GP_Rotate.h>
375 /* or */
376 #include <gfxprim.h>
378 int gp_filter_rotate_180(const gp_pixmap *src, gp_pixmap *dst,
379                          gp_progress_cb *callback);
381 gp_pixmap *gp_filter_rotate_180_alloc(const gp_pixmap *src,
382                                       gp_progress_cb *callback);
383 -------------------------------------------------------------------------------
385 Rotate pixmap by 180 degrees.
387 Doesn't work 'in-place' (yet).
389 The destination has to have the same pixel type and the size must be at least
390 as large as source.
392 include::images/rotate_180/images.txt[]
394 [source,c]
395 -------------------------------------------------------------------------------
396 #include <filters/GP_Rotate.h>
397 /* or */
398 #include <gfxprim.h>
400 int gp_filter_rotate_270(const gp_pixmap *src, gp_pixmap *dst,
401                          gp_progress_cb *callback);
403 gp_pixmap *gp_filter_rotate_270_alloc(const gp_pixmap *src,
404                                       gp_progress_cb *callback);
405 -------------------------------------------------------------------------------
407 Rotate pixmap by 270 degrees.
409 Doesn't work 'in-place' (yet).
411 The destination has to have the same pixel type and destination size must be
412 large enough to fit rotated pixmap (i.e. W and H are swapped).
414 include::images/rotate_270/images.txt[]
416 [source,c]
417 -------------------------------------------------------------------------------
418 #include <filters/GP_Rotate.h>
419 /* or */
420 #include <gfxprim.h>
422 typedef enum gp_filter_symmetries {
423         GP_ROTATE_90,
424         GP_ROTATE_CW = GP_ROTATE_90,
425         GP_ROTATE_180,
426         GP_ROTATE_270,
427         GP_ROTATE_CCW = GP_ROTATE_270,
428         GP_MIRROR_H,
429         GP_MIRROR_V,
430 } gp_filter_symmetries;
432 gp_pixmap *gp_filter_symmetry_alloc(const gp_pixmap *src,
433                                     gp_filter_symmetries symmetry,
434                                     gp_progress_cb *callback);
436 int gp_filter_symmetry(const gp_pixmap *src, gp_pixmap *dst,
437                        gp_filter_symmetries symmetry,
438                        gp_progress_cb *callback);
439 -------------------------------------------------------------------------------
441 Catch all function for symmetry filters.
444 Linear filters
445 ~~~~~~~~~~~~~~
447 Linear filters family consists of filters based on discrete linear
448 convolution, that means that computed pixel value depends on linear
449 combination of the image pixels.
451 It's defined as:
452 [latex, discrete_linear_convolution.png, 140]
453 -------------------------------------------------------------------------------
455 O(x,y)=\sum_{i=-\infty}^{\infty}\sum_{j=-\infty}^{\infty}I(x+i,y+j) \cdot K(i,j)
457 -------------------------------------------------------------------------------
459 The K denotes convolution kernel and in practice, due to computational
460 complexity i and j are bounded in relatively small intervals. For example i
461 and j are in (-1,1) and the kernel size is 3x3.
463 Note that pixel values outside the image are undefined. The linear convolution
464 in GFXprim simply uses the closest border pixel values for all pixels outside
465 the image.
467 Particular convolution kernel is called separable if it could be decomposed
468 into two one dimensional kernels (these when combined yields back the original
469 kernel). Such convolution then could be applied as two one dimensional
470 convolutions which is faster operation (especially for big kernels).
472 Bilinear Convolution
473 ^^^^^^^^^^^^^^^^^^^^
475 Following paragraph describes linear convolution implementation as well as a
476 little of the math background skip it if you just need to use one of the
477 ready-to-use filters.
479 [source,c]
480 -------------------------------------------------------------------------------
481 #include <filters/GP_Linear.h>
482 /* or */
483 #include <gfxprim.h>
485 int gp_filter_linear_convolution_raw(const gp_pixmap *src,
486                                      gp_coord x_src, gp_coord y_src,
487                                      gp_size w_src, gp_size h_src,
488                                      gp_pixmap *dst,
489                                      gp_coord x_dst, gp_coord y_dst,
490                                      float kernel[], uint32_t kw, uint32_t kh,
491                                      float kern_div, gp_progress_cb *callback);
492 -------------------------------------------------------------------------------
494 Internal generic convolution filter, this is a base for all linear convolution
495 filters with non-separable kernel.
497 The src coordinate and sizes denotes rectangle in the source pixmap that the
498 filter operates on.
500 The dst coordinates defines offset into the dst pixmap.
502 The kernel is two-dimensional array of a size kw * kh indexed as
503 kernel[x + y*kw].
505 The kern_div is a coefficient that is used to divide the resulting values often
506 used to normalize the result.
508 This filter works 'in-place'.
510 The pixel value is computed as:
511 [latex, discrete_linear_convolution_alg1.png, 140]
512 -------------------------------------------------------------------------------
514 O(x,y)={1 \over kern\_div} \cdot \sum_{i=0}^{kw - 1}\sum_{j=0}^{kh - 1}
515        I(x + i - \lfloor kw/2 \rfloor, y + j - \lfloor kh/2 \rfloor)
516        \cdot kernel(i,j)
518 -------------------------------------------------------------------------------
520 Which is the same as:
522 [latex, discrete_linear_convolution_alg2.png, 140]
523 -------------------------------------------------------------------------------
525 O(x,y)={1 \over kern\_div} \cdot
526        \sum_{i=-\lfloor kw/2 \rfloor}^{\lfloor kw/2 \rfloor}
527        \sum_{j=-\lfloor kh/2 \rfloor}^{\lfloor kh/2 \rfloor}
528        I(x + i, y + j)
529        \cdot kernel(i + \lfloor kw/2 \rfloor, j + \lfloor kh/2 \rfloor)
531 -------------------------------------------------------------------------------
533 NOTE: The number of kernel rows and columns is expected to be odd number.
535 include::images/convolution/images.txt[]
537 [source,c]
538 -------------------------------------------------------------------------------
539 #include <filters/GP_Linear.h>
540 /* or */
541 #include <gfxprim.h>
543 int gp_filter_hlinear_convolution_raw(const gp_pixmap *src,
544                                       gp_coord x_src, gp_coord y_src,
545                                       gp_size w_src, gp_size h_src,
546                                       gp_pixmap *dst,
547                                       gp_coord x_dst, gp_coord y_dst,
548                                       float kernel[], uint32_t kw, float kern_div,
549                                       gp_progress_cb *callback);
551 int gp_filter_vlinear_convolution_raw(const gp_pixmap *src,
552                                       gp_coord x_src, gp_coord y_src,
553                                       gp_size w_src, gp_size h_src,
554                                       gp_pixmap *dst,
555                                       gp_coord x_dst, gp_coord y_dst,
556                                       float kernel[], uint32_t kh, float kern_div,
557                                       gp_progress_cb *callback);
559 int gp_filter_vhlinear_convolution_raw(const gp_pixmap *src,
560                                        gp_coord x_src, gp_coord y_src,
561                                        gp_size w_src, gp_size h_src,
562                                        gp_pixmap *dst,
563                                        gp_coord x_dst, gp_coord y_dst,
564                                        float hkernel[], uint32_t kw, float hkern_div,
565                                        float vkernel[], uint32_t kh, float vkern_div,
566                                        gp_progress_cb *callback);
568 void gp_filter_kernel_print_raw(float kernel[], int kw, int kh, float kern_div);
569 -------------------------------------------------------------------------------
571 Internal special functions for one dimensional vertical and horizontal
572 convolution these two functions are base for all separable convolution filters.
574 The src coordinate and sizes denotes rectangle in the source pixmap that the
575 filter operates on.
577 The dst coordinates are offset into the dst.
579 The kernel is one-dimensional array of floats of size kw or kh.
581 The kern_div is a coefficient that is used to divide the resulting values.
583 The last function does both vertical and horizontal convolution and takes care
584 of correct progress callback.
586 These filters work 'in-place'.
588 The pixel value is computed as:
589 [latex, discrete_linear_1D_convolution_alg1.png, 140]
590 -------------------------------------------------------------------------------
592 O(x,y)={1 \over kern\_div} \cdot \sum_{i=0}^{kw - 1}
593        I(x + i - \lfloor kw/2 \rfloor, y)
594        \cdot kernel(i)
598 O(x,y)={1 \over kern\_div} \cdot \sum_{j=0}^{kw - 1}
599        I(x, y + j - \lfloor kh/2 \rfloor)
600        \cdot kernel(j)
602 -------------------------------------------------------------------------------
604 Which is the same as:
606 [latex, discrete_linear_1D_convolution_alg2.png, 140]
607 -------------------------------------------------------------------------------
609 O(x,y)={1 \over kern\_div} \cdot
610        \sum_{i=-\lfloor kw/2 \rfloor}^{\lfloor kw/2 \rfloor}
611        I(x + i, y)
612        \cdot kernel(i + \lfloor kw/2 \rfloor)
616 O(x,y)={1 \over kern\_div} \cdot
617        \sum_{j=-\lfloor kh/2 \rfloor}^{\lfloor kh/2 \rfloor}
618        I(x, y + j)
619        \cdot kernel(i, j + \lfloor kh/2 \rfloor)
621 -------------------------------------------------------------------------------
623 NOTE: The number of kernel rows and columns is expected to be odd number.
625 NOTE: The linear convolutions are internally implemented using integer
626       arithmetics, which works fine, but you need to take a care not to
627       overflow 32bit signed integer. If the pixel channel size is 8bit
628       long and 10bits are used for the fixed point part of the number
629       the rest must fit into about 10 bits to be safe.
631 [source,c]
632 -------------------------------------------------------------------------------
633 #include <filters/GP_Convolution.h>
634 /* or */
635 #include <gfxprim.h>
637 typedef struct gp_filter_kernel_2d {
638         unsigned int w;
639         unsigned int h;
640         float div;
641         float *kernel;
642 } gp_filter_kernel_2d;
644 int gp_filter_convolution_ex(const gp_pixmap *src,
645                              gp_coord x_src, gp_coord y_src,
646                              gp_size w_src, gp_coord h_src,
647                              gp_pixmap *dst,
648                              gp_coord x_dst, gp_coord y_dst,
649                              const gp_filter_Kernel2D *kernel,
650                              gp_progress_cb *callback);
652 gp_pixmap *gp_filter_convolution_ex_alloc(const gp_pixmap *src,
653                                           gp_coord x_src, gp_coord y_src,
654                                           gp_size w_src, gp_size h_src,
655                                           const gp_filter_Kernel2D *kernel,
656                                           gp_progress_cb *callback);
658 int gp_filter_convolution(const gp_pixmap *src, gp_pixmap *dst,
659                           const gp_filter_Kernel2D *kernel,
660                           gp_progress_cb *callback);
662 gp_pixmap *gp_filter_convolution_alloc(const gp_pixmap *src,
663                                        const gp_filter_Kernel2D *kernel,
664                                        gp_progress_cb *callback);
666 void gp_filter_kernel_2d_print(const gp_filter_kernel_2d *kernel);
667 -------------------------------------------------------------------------------
669 Linear convolution filters, you should preferably use this API over the _Raw
670 variants.
672 The _ex variants takes a rectangle on which the filter should operate as well
673 as offset into the destination. The destination must be large enough so that
674 starting with offset there is at least w_dst and h_dst pixels.
676 The kernel is a pointer to a structure initialized with the kernel size, divider
677 and array of kernel values.
679 The last function prints convolution kernel in human-readable format into the
680 stdout.
682 WARNING: If filter is executed in-place the work cannot be distributed between
683          threads (as some of the threads will overwrite values read by other
684          threads). In this case convolution filters runs in one thread
685          regardless of if threads are eanbled or not.
687 [source,c]
688 -------------------------------------------------------------------------------
689 #include <gfxprim.h>
692  * _example box smoothing filter.
693  */
694 static void box_smoothing(gp_pixmap *img)
696         float box_filter[] = {
697                 1, 1, 1,
698                 1, 1, 1,
699                 1, 1, 1,
700         };
702         gp_filter_kernel_2d box_kernel = {
703                 .w = 3,
704                 .h = 3,
705                 .div = 9,
706                 .kernel = box_filter,
707         };
709         gp_filter_convolution(img, img, &box_kernel, NULL);
711 -------------------------------------------------------------------------------
713 _example function that implements simple 'in-place' smoothing filter.
715 Laplace Filter
716 ^^^^^^^^^^^^^^
718 [source,c]
719 -------------------------------------------------------------------------------
720 #include <gp_filter_s.h>
721 /* or */
722 #include <gfxprim.h>
724 int gp_filter_laplace(const gp_pixmap *src, gp_pixmap *dst,
725                       gp_progress_cb *callback);
727 gp_pixmap *gp_filter_laplace_alloc(const gp_pixmap *src,
728                                    gp_progress_cb *callback);
729 -------------------------------------------------------------------------------
731 Discrete Laplace filter that produces a second derivative of the original
732 image.
734 The convolution kernel is defined as:
736 [latex, laplacian_kernel.png, 130]
737 -------------------------------------------------------------------------------
739 \begin{bmatrix}
740 0  &  1  &  0 \\
741 0  & -2  &  0 \\
742 0  &  1  &  0
743 \end{bmatrix}
745 \begin{bmatrix}
746 0  &  0  &  0 \\
747 1  & -2  &  1 \\
748 0  &  0  &  0
749 \end{bmatrix}
751 \begin{bmatrix}
752 0  &  1  &  0 \\
753 1  & -4  &  1 \\
754 0  &  1  &  0
755 \end{bmatrix}
757 -------------------------------------------------------------------------------
759 NOTE: This filter is not separable but could be written as a sum of two one
760       dimensional filters as the kernel definition suggests.
762 Laplacian Edge Sharpening
763 ^^^^^^^^^^^^^^^^^^^^^^^^^
765 [source,c]
766 -------------------------------------------------------------------------------
767 #include <gp_filter_s.h>
768 /* or */
769 #include <gfxprim.h>
771 int gp_filter_edge_sharpening(const gp_pixmap *src, gp_pixmap *dst,
772                               float w, gp_progress_cb *callback);
774 gp_pixmap *gp_filter_edge_sharpening_alloc(const gp_pixmap *src, float w,
775                                            gp_progress_cb *callback);
776 -------------------------------------------------------------------------------
778 Laplace based edge sharpening filter, subtracts weighted second derivative
779 from the original image.
781 The w paramerter is multiplicative weight applied on the second derivative.
782 Reasonable results are when the parameter is between '0.1' and '1'.
784 [latex, laplacian_edge_sharpening.png, 140]
785 -------------------------------------------------------------------------------
787 O(x,y) = I(x,y) - w * I''(x,y)
789 -------------------------------------------------------------------------------
791 include::images/edge_sharpening/images.txt[]
793 Gaussian Blur
794 ^^^^^^^^^^^^^
796 [source,c]
797 -------------------------------------------------------------------------------
798 #include <filters/GP_Blur.h>
799 /* or */
800 #include <gfxprim.h>
802 int gp_filter_gaussian_blur_ex(const gp_pixmap *src,
803                                gp_coord x_src, gp_coord y_src,
804                                gp_size w_src, gp_size h_src,
805                                gp_pixmap *dst,
806                                gp_coord x_dst, gp_coord y_dst,
807                                float x_sigma, float y_sigma,
808                                gp_progress_cb *callback);
810 gp_pixmap *gp_filter_gaussian_blur_ex_alloc(const gp_pixmap *src,
811                                             gp_coord x_src, gp_coord y_src,
812                                             gp_size w_src, gp_size h_src,
813                                             float x_sigma, float y_sigma,
814                                             gp_progress_cb *callback);
816 int gp_filter_gaussian_blur(const gp_pixmap *src, gp_pixmap *dst,
817                             float x_sigma, float y_sigma,
818                             gp_progress_cb *callback)
820 gp_pixmap *gp_filter_gaussian_blur_alloc(const gp_pixmap *src,
821                                          float x_sigma, float y_sigma,
822                                          gp_progress_cb *callback)
823 -------------------------------------------------------------------------------
825 Gaussian blur (low pass) filters implemented as bilinear separable
826 convolution.
828 The sigma denotes amount of the blur (the radius is computed accordingly
829 automatically).
831 The sigma values can be set for vertical and horizontal direction
832 independently which may be useful when Gaussian blur is used as a low pass
833 filter before image is resampled non proportionally.
835 include::images/blur/images.txt[]
837 Interpolation filters
838 ~~~~~~~~~~~~~~~~~~~~~
840 Filters to link:filters_resize.html[resize image].
842 Nearest Neighbour Interpolation
843 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
845 Fast, but produces "pixelated" images. May however work better for images with
846 sharp edges mostly consisting of big one color regions (it doesn't blur the
847 result on upscaling).
849 Also is commonly used to show preview before you resample the image correctly.
851 Bilinear Interpolation
852 ^^^^^^^^^^^^^^^^^^^^^^
854 Bilinear is faster than bicubic interpolation and produces quite good results
855 especially the low pass variant doesn't need additional filter on down-sampling.
857 Bicubic Interpolation
858 ^^^^^^^^^^^^^^^^^^^^^
860 Works well as is on image upscaling. To get decent result on downscaling
861 low-pass filter (Gaussian blur) must be used on original image before actual
862 downscaling. To do this reasonably fast we could cheat a little: first resize
863 big images a little without the low-pass filter, then apply low-pass filter and
864 finally downscale it to desired size.
866 [[Dithering]]
867 Dithering
868 ~~~~~~~~~
870 link:filters_dithering.html[Dithering filters] are filters for better loosy
871 (source pixel type has more bits to represent color or grayscale value) pixel
872 type conversions.
874 Median
875 ~~~~~~
877 [source,c]
878 -------------------------------------------------------------------------------
879 #include <filters/GP_Median.h>
880 /* or */
881 #include <gfxprim.h>
883 int gp_filter_median_ex(const gp_pixmap *src,
884                         gp_coord x_src, gp_coord y_src,
885                         gp_size w_src, gp_size h_src,
886                         gp_pixmap *dst,
887                         gp_coord x_dst, gp_coord y_dst,
888                         int xmed, int ymed,
889                         gp_progress_cb *callback);
891 gp_pixmap *gp_filter_median_ex_alloc(const gp_pixmap *src,
892                                      gp_coord x_src, gp_coord y_src,
893                                      gp_size w_src, gp_size h_src,
894                                      int xmed, int ymed,
895                                      gp_progress_cb *callback);
897 int gp_filter_median(const gp_pixmap *src,
898                      gp_pixmap *dst,
899                      int xmed, int ymed,
900                      gp_progress_cb *callback);
902 gp_pixmap *gp_filter_median_alloc(const gp_pixmap *src,
903                                   int xmed, int ymed,
904                                   gp_progress_cb *callback);
905 -------------------------------------------------------------------------------
907 Constant time median filter (the computational complexity is independent of
908 radius size).
910 The xmed and ymed are radius values for x and y. The algorithm uses xmed
911 respectively ymed pixel neighbors from each side so the result is median of
912 rectangle of 2 * xmed + 1 x 2 * ymed + 1 pixels.
914 include::images/median/images.txt[]