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> 
17namespace tImage 
18
19 
20 
21enum 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}; 
49extern const char* tResampleFilterNames[int(tResampleFilter::NumFilters)]; 
50 
51 
52enum class tResampleEdgeMode 
53
54 Clamp
55 Wrap
56 NumEdgeModes 
57}; 
58extern 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. 
69bool 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