1 /* This file is part of MyPaint.
2  * Copyright (C) 2008-2014 by Martin Renold <martinxyz@gmx.ch>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  */
9 
10 #ifndef PIXOPS_HPP
11 #define PIXOPS_HPP
12 
13 
14 #include <Python.h>
15 
16 
17 // Downscales a tile to half its size using bilinear interpolation.  Used for
18 // generating mipmaps for tiledsurface and background.
19 
20 void tile_downscale_rgba16(PyObject *src, PyObject *dst, int dst_x, int dst_y);
21 
22 
23 // Used to e.g. copy the background before starting to composite over it
24 //
25 // Simple array copying (numpy assignment operator) is about 13 times slower,
26 // sadly. The above comment is true when the array is sliced; it's only about
27 // two times faster now, in the current use case.
28 
29 void tile_copy_rgba16_into_rgba16(PyObject *src, PyObject *dst);
30 
31 
32 // Clears a tile.
33 // This zeroes the alpha channel too, so using it on rgbu data
34 // may have unexpected consequences.
35 
36 void tile_clear_rgba16(PyObject *dst);
37 
38 void tile_clear_rgba8(PyObject *dst);
39 
40 
41 // Converts a 15ish-bit tile array to 8bpp RGBA.
42 // Used mainly for saving layers when alpha must be preserved.
43 
44 void tile_convert_rgba16_to_rgba8(PyObject *src, PyObject *dst, const float EOTF);
45 
46 
47 // Converts a 15ish-bit tile array to 8bpp RGB ("ignoring" alpha).
48 
49 void tile_convert_rgbu16_to_rgbu8(PyObject *src, PyObject *dst, const float EOTF);
50 
51 
52 // used mainly for loading layers (transparent PNG)
53 
54 void tile_convert_rgba8_to_rgba16(PyObject *src, PyObject *dst, const float EOTF);
55 
56 
57 // Flatten a premultiplied rgba layer, using "bg" as background.
58 // (bg is assumed to be flat, bg.alpha is ignored)
59 //
60 // dst.color = dst OVER bg.color
61 // dst.alpha = unmodified
62 
63 void tile_rgba2flat(PyObject *dst_obj, PyObject *bg_obj);
64 
65 
66 // Make a flat layer translucent again. When calculating the new color
67 // and alpha, it is assumed that the layer will be displayed OVER the
68 // background "bg". Alpha is increased where required.
69 //
70 // dst.alpha = MIN(dst.alpha, minimum alpha required for correct result)
71 // dst.color = calculated such that (dst_output OVER bg = dst_input.color)
72 
73 void tile_flat2rgba(PyObject * dst_obj, PyObject * bg_obj);
74 
75 
76 // Calculates a 1-bit bitmap of the stroke shape using two snapshots of the
77 // layer (the layer before and after the stroke). Used in strokemap.py
78 //
79 // If the alpha increases a lot, we want the stroke to appear in the strokemap,
80 // even if the color did not change. If the alpha decreases a lot, we want to
81 // ignore the stroke (eraser). If the alpha decreases just a little, but the
82 // color changes a lot (eg. heavy smudging or watercolor brushes) we want the
83 // stroke still to be pickable.
84 //
85 // If the layer alpha was (near) zero, we record the stroke even if it is
86 // barely visible. This gives a bigger target to point-and-select.
87 
88 void tile_perceptual_change_strokemap(PyObject *a_obj, PyObject *b_obj, PyObject *res_obj);
89 
90 
91 // Tile blending & compositing modes
92 
93 enum CombineMode {
94     CombineNormal,
95     CombineMultiply,
96     CombineScreen,
97     CombineOverlay,
98     CombineDarken,
99     CombineLighten,   // lightEN blend mode, and Porter-Duff OVER
100     CombineHardLight,
101     CombineSoftLight,
102     CombineColorBurn,
103     CombineColorDodge,
104     CombineDifference,
105     CombineExclusion,
106     CombineHue,
107     CombineSaturation,
108     CombineColor,
109     CombineLuminosity,
110     CombineLighter,   // normal blend mode, and W3C lightER (Porter-Duff PLUS)
111     CombineDestinationIn,
112     CombineDestinationOut,
113     CombineSourceAtop,
114     CombineDestinationAtop,
115     CombineSpectralWGM,
116     NumCombineModes
117 };
118 
119 
120 // Extracts Python-readable metadata for a blend/composite mode
121 
122 PyObject *
123 combine_mode_get_info(enum CombineMode mode);
124 
125 
126 // Blend and composite one tile, writing into the destination.
127 
128 void
129 tile_combine (enum CombineMode mode,
130               PyObject *src_obj,
131               PyObject *dst_obj,
132               const bool dst_has_alpha,
133               const float src_opacity);
134 
135 
136 #endif // PIXOPS_HPP
137