| 2241 | }; |
| 2242 | |
| 2243 | static void resize( |
| 2244 | const clip_image_u8 & src, |
| 2245 | clip_image_u8 & dst, |
| 2246 | const clip_image_size & target_resolution, |
| 2247 | resize_algo algo, |
| 2248 | bool add_padding = true, // TODO: define the behavior for add_padding = false |
| 2249 | std::array<uint8_t, 3> pad_color = {0, 0, 0}) { |
| 2250 | dst.nx = target_resolution.width; |
| 2251 | dst.ny = target_resolution.height; |
| 2252 | dst.buf.resize(3 * dst.nx * dst.ny); |
| 2253 | |
| 2254 | if (dst.nx == src.nx && dst.ny == src.ny) { |
| 2255 | // no resize needed, simple copy |
| 2256 | dst.buf = src.buf; |
| 2257 | return; |
| 2258 | } |
| 2259 | |
| 2260 | if (!add_padding) { |
| 2261 | // direct resize |
| 2262 | switch (algo) { |
| 2263 | case RESIZE_ALGO_BILINEAR: |
| 2264 | resize_bilinear(src, dst, target_resolution.width, target_resolution.height); |
| 2265 | break; |
| 2266 | case RESIZE_ALGO_BICUBIC: |
| 2267 | resize_bicubic(src, dst, target_resolution.width, target_resolution.height); |
| 2268 | break; |
| 2269 | default: |
| 2270 | throw std::runtime_error("Unsupported resize algorithm"); |
| 2271 | } |
| 2272 | } else { |
| 2273 | // resize with padding |
| 2274 | clip_image_u8 resized_image; |
| 2275 | float scale_w = static_cast<float>(target_resolution.width) / src.nx; |
| 2276 | float scale_h = static_cast<float>(target_resolution.height) / src.ny; |
| 2277 | float scale = std::min(scale_w, scale_h); |
| 2278 | int new_width = std::min(static_cast<int>(std::ceil(src.nx * scale)), target_resolution.width); |
| 2279 | int new_height = std::min(static_cast<int>(std::ceil(src.ny * scale)), target_resolution.height); |
| 2280 | |
| 2281 | switch (algo) { |
| 2282 | case RESIZE_ALGO_BILINEAR: |
| 2283 | resize_bilinear(src, resized_image, new_width, new_height); |
| 2284 | break; |
| 2285 | case RESIZE_ALGO_BICUBIC: |
| 2286 | resize_bicubic(src, resized_image, new_width, new_height); |
| 2287 | break; |
| 2288 | default: |
| 2289 | throw std::runtime_error("Unsupported resize algorithm"); |
| 2290 | } |
| 2291 | |
| 2292 | // fill dst with pad_color |
| 2293 | fill(dst, pad_color); |
| 2294 | |
| 2295 | int offset_x = (target_resolution.width - new_width) / 2; |
| 2296 | int offset_y = (target_resolution.height - new_height) / 2; |
| 2297 | |
| 2298 | composite(dst, resized_image, offset_x, offset_y); |
| 2299 | } |
| 2300 | } |