1 | // tResample.h  |
2 | //  |
3 | // Resample an image using various filers like nearest-neighbour, box, bilinear, and various bicubics.  |
4 | //  |
5 | // Copyright (c) 2020 Tristan Grimmer.  |
6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby  |
7 | // granted, provided that the above copyright notice and this permission notice appear in all copies.  |
8 | //  |
9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL  |
10 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,  |
11 | // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN  |
12 | // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR  |
13 | // PERFORMANCE OF THIS SOFTWARE.  |
14 |   |
15 | #pragma once  |
16 | #include <Math/tColour.h>  |
17 | namespace tImage  |
18 | {  |
19 |   |
20 |   |
21 | enum class tResampleFilter  |
22 | {  |
23 | Nearest,  |
24 | Box,  |
25 | Bilinear,  |
26 |   |
27 | // The bicubic filter coefficients (b,c) and names are described here:  |
28 | // https://entropymine.com/imageworsener/bicubic/  |
29 | // The order in which the cubic filters are list below matches my opinion of overall quality.  |
30 | Bicubic_Standard, // Cardinal. B=0 C=3/4  |
31 | Bicubic_CatmullRom, // Cardinal. B=0 C=1/2  |
32 | Bicubic_Mitchell, // Balanced. B=1/3 C=1/3  |
33 | Bicubic_Cardinal, // Pure Cardinal. B=0 C=1  |
34 | Bicubic_BSpline, // Pure BSpline. Blurry. B=1 C=0  |
35 |   |
36 | // Lanczos is useful for cases where increased contrast is needed, esp at edges. Overall is a bit 'ringy'.  |
37 | // See https://en.wikipedia.org/wiki/Lanczos_resampling for a description of the Lanczos kernel.  |
38 | Lanczos_Narrow, // Sinc-based. A = 2  |
39 | Lanczos_Normal, // Sinc-based. A = 3  |
40 | Lanczos_Wide, // Sinc-based. A = 4  |
41 |   |
42 | Invalid,  |
43 | NumFilters = Invalid,  |
44 |   |
45 | // Aliaes.  |
46 | Bicubic = Bicubic_Standard,  |
47 | Lanczos = Lanczos_Normal  |
48 | };  |
49 | extern const char* tResampleFilterNames[int(tResampleFilter::NumFilters)];  |
50 |   |
51 |   |
52 | enum class tResampleEdgeMode  |
53 | {  |
54 | Clamp,  |
55 | Wrap,  |
56 | NumEdgeModes  |
57 | };  |
58 | extern const char* tResampleEdgeModeNames[int(tResampleEdgeMode::NumEdgeModes)];  |
59 |   |
60 |   |
61 | // Resample the image using the supplied filter. All channels are treated equally. With some resamplers the alpha  |
62 | // channels gets multiplied into the colours, we do not. This simplicity has some repercussions -- specifically the  |
63 | // texture author should extend the colours into the areas where the alpha is 0 to make sure rescaling near these  |
64 | // borders does not introduce colour artifacts when upscaling.  |
65 | //  |
66 | // The edge mode is either clamp or wrap. In wrap node if a pixel to the right (or up) is needed for the resample and  |
67 | // we are at the edge of the image, it is taken from the other side. Some libraries also support a 'reflect' mode but  |
68 | // since I'm not sure when this is useful, it is being excluded.  |
69 | bool Resample  |
70 | (  |
71 | tPixel* src, int srcW, int srcH,  |
72 | tPixel* dst, int dstW, int dstH,  |
73 | tResampleFilter = tResampleFilter::Bilinear,  |
74 | tResampleEdgeMode = tResampleEdgeMode::Clamp  |
75 | );  |
76 |   |
77 |   |
78 | }  |
79 | |