IntegerScaling/
IntegerScaling.rs1#![allow(non_snake_case)]
4
5pub struct Ratios {
6 pub x : u32,
7 pub y : u32
8}
9
10pub struct Size {
11 pub width : u32,
12 pub height : u32
13}
14
15pub fn calculateRatio(areaWidth : u32, areaHeight : u32,
17 imageWidth : u32, imageHeight : u32) -> u32
18{
19 let (areaSize, imageSize);
20
21 if areaHeight * imageWidth < areaWidth * imageHeight {
22 areaSize = areaHeight;
23 imageSize = imageHeight;
24 }
25 else {
26 areaSize = areaWidth;
27 imageSize = imageWidth;
28 }
29
30 let mut ratio = areaSize / imageSize;
31
32 if ratio < 1 {
33 ratio = 1;
34 }
35
36 ratio
37}
38
39pub fn calculateRatios(areaWidth : u32, areaHeight : u32,
42 imageWidth : u32, imageHeight : u32,
43 aspectX : f64, aspectY : f64) -> Ratios
44{
45 if imageWidth as f64 * aspectY == imageHeight as f64 * aspectX {
46 let ratio = calculateRatio(areaWidth, areaHeight, imageWidth, imageHeight);
47
48 return Ratios {
49 x: ratio,
50 y: ratio
51 };
52 }
53
54 let maxRatioX = areaWidth / imageWidth;
55 let maxRatioY = areaHeight / imageHeight;
56 let maxWidth = imageWidth * maxRatioX;
57 let maxHeight = imageHeight * maxRatioY;
58 let maxWidthAspectY = maxWidth as f64 * aspectY;
59 let maxHeightAspectX = maxHeight as f64 * aspectX;
60
61 let mut ratioX : u32;
62 let mut ratioY : u32;
63
64 if maxWidthAspectY == maxHeightAspectX {
65 ratioX = maxRatioX;
66 ratioY = maxRatioY;
67 }
68 else {
69 let maxAspectLessThanTarget = maxWidthAspectY < maxHeightAspectX;
70
71 let (ratioA, maxSizeA, imageSizeB, aspectA, aspectB) : (u32, u32, u32, f64, f64);
72
73 if maxAspectLessThanTarget {
74 ratioA = maxRatioX;
75 maxSizeA = maxWidth;
76 imageSizeB = imageHeight;
77 aspectA = aspectX;
78 aspectB = aspectY;
79 }
80 else {
81 ratioA = maxRatioY;
82 maxSizeA = maxHeight;
83 imageSizeB = imageWidth;
84 aspectA = aspectY;
85 aspectB = aspectX;
86 }
87
88 let ratioBFract = maxSizeA as f64 * aspectB / aspectA / imageSizeB as f64;
89 let ratioBFloor = ratioBFract.floor();
90 let ratioBCeil = ratioBFract.ceil();
91
92 let mut parFloor = ratioBFloor / ratioA as f64;
93 let mut parCeil = ratioBCeil / ratioA as f64;
94
95 if maxAspectLessThanTarget {
96 parFloor = 1.0 / parFloor;
97 parCeil = 1.0 / parCeil;
98 }
99
100 let commonFactor = imageWidth as f64 * aspectY / aspectX / imageHeight as f64;
101 let errorFloor = (1.0 - commonFactor * parFloor).abs();
102 let errorCeil = (1.0 - commonFactor * parCeil).abs();
103
104 let ratioB : u32;
105
106 if (errorFloor - errorCeil).abs() < 0.001 {
107 ratioB = if (ratioA as f64 - ratioBFloor).abs() < (ratioA as f64 - ratioBCeil).abs()
108 {ratioBFloor as u32}
109 else
110 {ratioBCeil as u32};
111 }
112 else {
113 ratioB = if errorFloor < errorCeil
114 {ratioBFloor as u32}
115 else
116 {ratioBCeil as u32};
117 }
118
119 if maxAspectLessThanTarget {
120 ratioX = ratioA;
121 ratioY = ratioB;
122 }
123 else {
124 ratioX = ratioB;
125 ratioY = ratioA;
126 }
127 }
128
129 if ratioX < 1 {
130 ratioX = 1;
131 }
132
133 if ratioY < 1 {
134 ratioY = 1;
135 }
136
137 Ratios {
138 x: ratioX,
139 y: ratioY
140 }
141}
142
143pub fn calculateSize(areaWidth : u32, areaHeight : u32,
146 imageWidth : u32, imageHeight : u32) -> Size
147{
148 let ratio = calculateRatio(areaWidth, areaHeight, imageWidth, imageHeight);
149
150 Size {
151 width : imageWidth * ratio,
152 height : imageHeight * ratio
153 }
154}
155
156pub fn calculateSizeCorrected(areaWidth : u32, areaHeight : u32,
159 imageWidth : u32, imageHeight : u32,
160 aspectX : f64, aspectY : f64) -> Size
161{
162 let ratios = calculateRatios(areaWidth, areaHeight, imageWidth, imageHeight, aspectX, aspectY);
163
164 Size {
165 width : imageWidth * ratios.x,
166 height : imageHeight * ratios.y
167 }
168}
169
170pub fn calculateSizeCorrectedPerfectY(areaWidth : u32, areaHeight : u32,
177 imageHeight : u32,
178 aspectX : f64, aspectY : f64) -> Size
179{
180 let imageWidth = imageHeight as f64 * aspectX / aspectY;
181
182 let imageSize : f64;
183 let areaSize : u32;
184
185 if areaHeight as f64 * imageWidth < areaWidth as f64 * imageHeight as f64 {
186 areaSize = areaHeight;
187 imageSize = imageHeight as f64;
188 }
189 else {
190 areaSize = areaWidth;
191 imageSize = imageWidth;
192 }
193
194 let mut ratio = areaSize / imageSize as u32;
195
196 if ratio < 1 {
197 ratio = 1;
198 }
199
200 let mut width = (imageWidth * ratio as f64).round() as u32;
201
202 if width > areaWidth {
203 width -= 1;
204 }
205
206 Size {
207 width : width,
208 height : imageHeight * ratio
209 }
210}