/// <summary>
        /// Calculates FrameDouble, CropSource, CropAfter and OutputWidth values.
        /// </summary>
        /// <param name="force">When false, this call is ignored when AutoCalculateSize is false.</param>
        private void CalculateSize(bool force) {
            if (!force && !AutoCalculateSize)
                return;

            if (!SourceWidth.HasValue || !SourceHeight.HasValue || OutputHeight > 10000) {
                OutputWidth = null;
                return;
            }

            // Calculate CropSource and CropAfter values.
            if (Crop) {
                // CropSource must be a factor of 4.
                CropSource = new Rect(
                    CropLeft / 4 * 4,
                    CropTop / 4 * 4,
                    CropRight / 4 * 4,
                    CropBottom / 4 * 4);
            } else
                CropSource = new Rect();

            FrameDouble = 0;
            int ScaleFactor = 1;
            int FrameDoubleX = 0, FrameDoubleY = 0;
            int ScaleFactorX = 1, ScaleFactorY = 1;
            // Calculate scale factor based on height
            while ((SourceHeight - CropSource.Top - CropSource.Bottom) * ScaleFactorY < OutputHeight) {
                FrameDoubleY += 1;
                ScaleFactorY *= 2;
            }
            // Calculate scale factor based on width
            while ((SourceWidth - CropSource.Left - CropSource.Right) * ScaleFactorX * SourceAspectRatio < OutputWidth) {
                FrameDoubleX += 1;
                ScaleFactorX *= 2;
            }
            // Take highest ratio
            FrameDouble = FrameDoubleX > FrameDoubleY ? FrameDoubleX : FrameDoubleY;
            ScaleFactor = ScaleFactorX > ScaleFactorY ? ScaleFactorX : ScaleFactorY;

            if (Crop) {
                CropAfter = new Rect(
                    (CropLeft - CropSource.Left) * ScaleFactor,
                    (CropTop - CropSource.Top) * ScaleFactor,
                    (CropRight - CropSource.Right) * ScaleFactor,
                    (CropBottom - CropSource.Bottom) * ScaleFactor);
            } else
                CropAfter = new Rect();
            int CropHeight = ((SourceHeight.Value - CropSource.Top - CropSource.Bottom) * ScaleFactor);
            int CropWidth = ((SourceWidth.Value - CropSource.Left - CropSource.Right) * ScaleFactor);
            if (CropAfter.HasValue) {
                CropHeight = CropHeight - CropAfter.Top - CropAfter.Bottom;
                CropWidth = CropWidth - CropAfter.Left - CropAfter.Right;
            }
            // Make width divisible by 4 without distorting pixels
            float TotalWidth = (float)CropWidth * SourceAspectRatio / CropHeight * OutputHeight;
            OutputWidth = (int)Math.Round(TotalWidth / 4) * 4;
            if (TotalWidth >= OutputWidth.Value) {
                float WidthAdjust = TotalWidth - OutputWidth.Value;
                int WidthAdjustInt = (int)Math.Round(WidthAdjust / 2);
                CropAfter.Left += WidthAdjustInt;
                CropAfter.Right += WidthAdjustInt;
            } else {
                float HeightAdjust = (OutputWidth.Value - TotalWidth) / SourceAspectRatio;
                int HeightAdjustInt = (int)Math.Round(HeightAdjust / 2);
                CropAfter.Top += HeightAdjustInt;
                CropAfter.Bottom += HeightAdjustInt;
            }
        }