public static Size scale(Size from, Size to) {
        Size current = from;

        if (!to.fitsIn(current)) {
            // Scale up
            while (true) {
                Size scaled150 = current.scale(3, 2);
                Size scaled200 = current.scale(2, 1);
                if (to.fitsIn(scaled150)) {
                    // Scale by 3/2
                    return scaled150;
                } else if (to.fitsIn(scaled200)) {
                    // Scale by 2/1
                    return scaled200;
                } else {
                    // Scale by 2/1 and continue
                    current = scaled200;
                }
            }
        } else {
            // Scale down
            while (true) {
                Size scaled66 = current.scale(2, 3);
                Size scaled50 = current.scale(1, 2);

                if (!to.fitsIn(scaled50)) {
                    if (to.fitsIn(scaled66)) {
                        // Scale by 2/3
                        return scaled66;
                    } else {
                        // No more downscaling
                        return current;
                    }
                } else {
                    // Scale by 1/2
                    current = scaled50;
                }
            }
        }
    }
Scale from so that to.fitsIn(size). Tries to scale by powers of two, or by 3/2. Aspect ratio
is preserved.

These scaling factors will theoretically result in fast scaling with minimal quality loss.

TODO: confirm whether or not this is the case in practice.

@param from the start size
@param to   the minimum desired size
@return the scaled size
zxing-android-embedded/src/com/journeyapps/barcodescanner/camera/LegacyPreviewScalingStrategy.java