Ejemplo n.º 1
0
        public static bool autocrop(out CropValues cropValues, IVideoReader reader, bool signalAR, mod16Method cropMethod, modValue mValue)
        {
            cropValues = Autocrop.autocrop(reader);

            if (signalAR)
            {
                if (cropMethod == mod16Method.overcrop)
                {
                    ScriptServer.overcrop(ref cropValues, mValue);
                }
                else if (cropMethod == mod16Method.mod4Horizontal)
                {
                    ScriptServer.cropMod4Horizontal(ref cropValues);
                }
                else if (cropMethod == mod16Method.undercrop)
                {
                    ScriptServer.undercrop(ref cropValues, mValue);
                }
            }

            if (cropValues.left < 0)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Ejemplo n.º 2
0
        public static CropValues autocrop(IVideoReader reader)
        {
            int pos        = reader.FrameCount / 4;
            int tenPercent = reader.FrameCount / 20;

            CropValues[] cropValues = new CropValues[10];
            for (int i = 0; i < 10; i++)
            {
                Bitmap b = reader.ReadFrameBitmap(pos);
                cropValues[i] = getAutoCropValues(b);
                pos          += tenPercent;
            }
            bool       error = false;
            CropValues final = getFinalAutocropValues(cropValues);

            if (!error)
            {
                return(final);
            }
            else
            {
                final.left   = -1;
                final.right  = -1;
                final.top    = -1;
                final.bottom = -1;
                return(final);
            }
        }
Ejemplo n.º 3
0
        public static CropValues autocrop(IVideoReader reader)
        {
            // start at 10% of the video, then advance by 6,66% and analyze 11 frames in total
            int pos  = reader.FrameCount / 10;
            int step = reader.FrameCount / 15;

            CropValues[] cropValues = new CropValues[11];
            for (int i = 0; i < 11; i++)
            {
                using (Bitmap b = reader.ReadFrameBitmap(pos))
                    cropValues[i] = getAutoCropValues(b);
                pos += step;
            }
            bool       error = false;
            CropValues final = getFinalAutocropValues(cropValues);

            if (!error)
            {
                return(final);
            }
            else
            {
                final.left   = -1;
                final.right  = -1;
                final.top    = -1;
                final.bottom = -1;
                return(final);
            }
        }
Ejemplo n.º 4
0
        private void testCropping(string file, int left, int right, int top, int bottom)
        {
            using (AvsFile f = AvsFile.ParseScript(file))
            {
                IVideoReader r = f.GetVideoReader();
                CropValues   c = Autocrop.autocrop(r);

                Expect(c.left, EqualTo(left));
                Expect(c.right, EqualTo(right));
                Expect(c.top, EqualTo(top));
                Expect(c.bottom, EqualTo(bottom));
            }
        }
Ejemplo n.º 5
0
        public void SaveLogoCrop([FromBody] CropValues cropValues, string practiceLocationId)
        {
            using (var ms = new MemoryStream())
            {
                var settings = new Instructions
                {
                    Format        = "png",
                    CropRectangle = new double[] { cropValues.X1, cropValues.Y1, cropValues.X2, cropValues.Y2 },
                    Width         = cropValues.Width,
                    Height        = cropValues.Height
                };

                byte[] logo;
                string contentType;
                this.officeIt2Manager.GetOfficeLogo(practiceLocationId, out logo, out contentType);
                new ImageJob(logo, ms, settings).Build();
                ms.Position = 0;
                this.officeIt2Manager.SaveOfficeLogo(practiceLocationId, ms.ToArray(), "image/png");
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// gets the desired resolution based on input settings
        /// </summary>
        /// <param name="sourceWidth">the complete width of the input file without cropping</param>
        /// <param name="sourceHeight">the complete height of the input file without cropping</param>
        /// <param name="inputDAR">the input DAR value</param>
        /// <param name="cropValues">the crop values</param>
        /// <param name="cropEnabled">true if crop values must be used</param>
        /// <param name="mod">the mod value used for the final resize values</param>
        /// <param name="resizeEnabled">true if resize can be used</param>
        /// <param name="upsizingEnabled">true if upsizing can be used</param>
        /// <param name="signalAR">whether or not ar signalling is to be used for the output
        /// (depending on this parameter, resizing changes to match the source AR)</param>
        /// <param name="suggestHeight">true if height should be calculated</param>
        /// <param name="acceptableAspectErrorPercent">acceptable aspect error if signalAR is true</param>
        /// <param name="xTargetDevice">x264 Target Device - may limit the output resolution</param>
        /// <param name="fps">the frames per second of the source</param>
        /// <param name="outputWidth">the calculated output width</param>
        /// <param name="outputHeight">the calculated output height</param>
        /// <param name="paddingValues">the padding values</param>
        /// <param name="outputDar">the output DAR value</param>
        /// <param name="_log">the log item</param>
        public static void GetResolution(int sourceWidth, int sourceHeight, Dar inputDar,
                                         ref CropValues cropValues, bool cropEnabled, int mod, ref bool resizeEnabled, bool upsizingAllowed,
                                         bool signalAR, bool suggestHeight, decimal acceptableAspectErrorPercent,
                                         x264Device xTargetDevice, Double fps, ref int outputWidth, ref int outputHeight,
                                         out CropValues paddingValues, out Dar?outputDar, LogItem _log)
        {
            paddingValues = new CropValues();

            getResolution(sourceWidth, sourceHeight, inputDar,
                          cropValues, cropEnabled, mod, resizeEnabled, upsizingAllowed,
                          signalAR, suggestHeight, acceptableAspectErrorPercent,
                          ref outputWidth, ref outputHeight,
                          out outputDar, _log);

            bool settingsChanged;

            if (isResolutionDeviceCompliant(xTargetDevice, outputWidth, outputHeight, out settingsChanged, ref resizeEnabled, ref cropEnabled, _log) == true)
            {
                if (!cropEnabled)
                {
                    cropValues = new CropValues();
                }
                return;
            }

            if (settingsChanged)
            {
                getResolution(sourceWidth, sourceHeight, inputDar,
                              cropValues, cropEnabled, mod, resizeEnabled, upsizingAllowed,
                              signalAR, suggestHeight, acceptableAspectErrorPercent,
                              ref outputWidth, ref outputHeight,
                              out outputDar, _log);

                // check if the resolution is now compliant
                if (isResolutionDeviceCompliant(xTargetDevice, outputWidth, outputHeight, out settingsChanged, ref resizeEnabled, ref cropEnabled, null) == true)
                {
                    if (!cropEnabled)
                    {
                        cropValues = new CropValues();
                    }
                    return;
                }
            }
            if (!cropEnabled)
            {
                cropValues = new CropValues();
            }

            // adjust horizontal resolution if width or height are too large
            int outputHeightIncludingPadding = 0;
            int outputWidthIncludingPadding  = 0;

            if (xTargetDevice.BluRay)
            {
                if (outputWidth >= 1920)
                {
                    outputWidth = 1920;
                    outputHeightIncludingPadding = 1080;
                }
                else if (outputWidth >= 1280)
                {
                    outputWidth = 1280;
                    outputHeightIncludingPadding = 720;
                }
                else
                {
                    outputWidth = 720;
                    if (fps == 25)
                    {
                        outputHeightIncludingPadding = 576;
                    }
                    else
                    {
                        outputHeightIncludingPadding = 480;
                    }
                }
                outputWidthIncludingPadding = outputWidth;
                if (_log != null)
                {
                    _log.LogEvent("Force resolution of " + outputWidth + "x" + outputHeightIncludingPadding + " as required for " + xTargetDevice.Name);
                }
            }
            else if (xTargetDevice.Width > 0 && outputWidth > xTargetDevice.Width)
            {
                outputWidth = xTargetDevice.Width;
                _log.LogEvent("Set resolution width to " + outputWidth + " as required for " + xTargetDevice.Name);
            }

            // adjust cropped vertical resolution
            getResolution(sourceWidth, sourceHeight, inputDar,
                          cropValues, cropEnabled, mod, resizeEnabled, upsizingAllowed,
                          signalAR, suggestHeight, acceptableAspectErrorPercent,
                          ref outputWidth, ref outputHeight,
                          out outputDar, _log);
            while ((xTargetDevice.Height > 0 && outputHeight > xTargetDevice.Height) || (xTargetDevice.BluRay && outputHeight > outputHeightIncludingPadding))
            {
                outputWidth -= mod;
                getResolution(sourceWidth, sourceHeight, inputDar,
                              cropValues, cropEnabled, mod, resizeEnabled, upsizingAllowed,
                              signalAR, suggestHeight, acceptableAspectErrorPercent,
                              ref outputWidth, ref outputHeight,
                              out outputDar, _log);
            }

            paddingValues.left   = Convert.ToInt32(Math.Floor((outputWidthIncludingPadding - outputWidth) / 2.0));
            paddingValues.right  = Convert.ToInt32(Math.Ceiling((outputWidthIncludingPadding - outputWidth) / 2.0));
            paddingValues.bottom = Convert.ToInt32(Math.Floor((outputHeightIncludingPadding - outputHeight) / 2.0));
            paddingValues.top    = Convert.ToInt32(Math.Ceiling((outputHeightIncludingPadding - outputHeight) / 2.0));

            outputWidth  = outputWidthIncludingPadding;
            outputHeight = outputHeightIncludingPadding;

            if (!cropEnabled)
            {
                cropValues = new CropValues();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// calculates the aspect ratio error
        /// </summary>
        /// <param name="inputWidth">height of the source (without cropping!)</param>
        /// <param name="inputHeight">width of the source (without cropping!)</param>
        /// <param name="outputWidth">the desired width of the output</param>
        /// <param name="outputHeight">the desired height of the output</param>
        /// <param name="Cropping">the crop values for the source</param>
        /// <param name="inputDar">custom input display aspect ratio to be taken into account</param>
        /// <param name="signalAR">whether or not we're going to signal the aspect ratio (influences the resizing)</param>
        /// <param name="outputDar">custom output display aspect ratio to be taken into account</param>
        /// <returns>the aspect ratio error in percent</returns>
        public static decimal GetAspectRatioError(int inputWidth, int inputHeight, int outputWidth, int outputHeight, CropValues Cropping, Dar?inputDar, bool signalAR, Dar?outputDar)
        {
            if (inputHeight <= 0 || inputWidth <= 0 || outputHeight <= 0 || outputWidth <= 0)
            {
                return(0);
            }

            // get input dimension with SAR 1:1
            int     iHeight = inputHeight - Cropping.top - Cropping.bottom;
            decimal iWidth  = inputWidth - Cropping.left - Cropping.right;

            if (inputDar.HasValue)
            {
                Sar s = inputDar.Value.ToSar(inputWidth, inputHeight);
                iWidth = iWidth * s.X / s.Y;
            }

            // get output dimension with SAR 1:1
            int     oHeight = outputHeight;
            decimal oWidth  = outputWidth;

            if (signalAR && outputDar.HasValue)
            {
                Sar s = outputDar.Value.ToSar(outputWidth, outputHeight);
                oWidth = oWidth * s.X / s.Y;
            }

            return((iHeight * oWidth) / (iWidth * oHeight) - 1);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// calculates the ideal mod vertical resolution that matches the desired horizontal resolution
        /// </summary>
        /// <param name="readerHeight">height of the source</param>
        /// <param name="readerWidth">width of the source</param>
        /// <param name="customDAR">custom display aspect ratio to be taken into account for resizing</param>
        /// <param name="cropping">the crop values for the source</param>
        /// <param name="horizontalResolution">the desired horizontal resolution of the output</param>
        /// <param name="signalAR">whether or not we're going to signal the aspect ratio (influences the resizing)</param>
        /// <param name="sarX">horizontal pixel aspect ratio (used when signalAR = true)</param>
        /// <param name="sarY">vertical pixel aspect ratio (used when signalAR = true)</param>
        /// <param name="mod">the MOD value</param>
        /// <returns>the suggested horizontal resolution</returns>
        public static int SuggestVerticalResolution(double readerHeight, double readerWidth, Dar inputDAR, CropValues cropping, int horizontalResolution,
                                                    bool signalAR, out Dar?dar, int mod, decimal acceptableAspectErrorPercent)
        {
            int scriptVerticalResolution;

            decimal fractionOfWidth            = ((decimal)readerWidth - (decimal)cropping.left - (decimal)cropping.right) / (decimal)readerWidth;
            decimal sourceHorizontalResolution = (decimal)readerHeight * inputDAR.AR * fractionOfWidth;
            decimal sourceVerticalResolution   = (decimal)readerHeight - (decimal)cropping.top - (decimal)cropping.bottom;
            decimal resizedVerticalResolution  = (decimal)horizontalResolution / (sourceHorizontalResolution / sourceVerticalResolution);

            if (signalAR)
            {
                decimal inputWidthOnHeight = ((decimal)readerWidth - (decimal)cropping.left - (decimal)cropping.right) /
                                             ((decimal)readerHeight - (decimal)cropping.top - (decimal)cropping.bottom);
                decimal realAspectRatio = getAspectRatio(inputDAR.AR, sourceHorizontalResolution / sourceVerticalResolution, acceptableAspectErrorPercent); // the aspect ratio of the video
                resizedVerticalResolution = (decimal)horizontalResolution / inputWidthOnHeight;                                                             // Scale vertical resolution appropriately
                scriptVerticalResolution  = ((int)Math.Round(resizedVerticalResolution / (decimal)mod) * mod);

                if (inputDAR.AR != realAspectRatio)
                {
                    int     parX     = 0;
                    int     parY     = 0;
                    int     iLimit   = 101;
                    decimal distance = 999999;
                    if (acceptableAspectErrorPercent == 0)
                    {
                        iLimit = 100001;
                    }
                    for (int i = 1; i < iLimit; i++)
                    {
                        // We create a fraction with integers, and then convert back to a decimal, and see how big the rounding error is
                        decimal fractionApproximation   = (decimal)Math.Round(realAspectRatio * ((decimal)i)) / (decimal)i;
                        decimal approximationDifference = Math.Abs(realAspectRatio - fractionApproximation);
                        if (approximationDifference < distance)
                        {
                            distance = approximationDifference;
                            parY     = i;
                            parX     = (int)Math.Round(realAspectRatio * ((decimal)parY));
                        }
                    }
                    Debug.Assert(parX > 0 && parY > 0);
                    dar = new Dar((ulong)parX, (ulong)parY);
                }
                else
                {
                    dar = inputDAR;
                }
            }
            else
            {
                scriptVerticalResolution = ((int)Math.Round(resizedVerticalResolution / (decimal)mod)) * mod;
                dar = null;
            }

            return(scriptVerticalResolution);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// gets the desired resolution based on input settings
        /// </summary>
        /// <param name="sourceWidth">the complete width of the input file without cropping</param>
        /// <param name="sourceHeight">the complete height of the input file without cropping</param>
        /// <param name="inputDAR">the input DAR value</param>
        /// <param name="cropping">the crop values</param>
        /// <param name="mod">the mod value used for the final resize values</param>
        /// <param name="resizeEnabled">true if resize can be used</param>
        /// <param name="upsizingEnabled">true if upsizing can be used</param>
        /// <param name="signalAR">whether or not ar signalling is to be used for the output
        /// (depending on this parameter, resizing changes to match the source AR)</param>
        /// <param name="suggestHeight">true if height should be calculated</param>
        /// <param name="acceptableAspectErrorPercent">acceptable aspect error if signalAR is true</param>
        /// <param name="outputWidth">the calculated output width</param>
        /// <param name="outputHeight">the calculated output height</param>
        /// <param name="outputDar">the output DAR value</param>
        /// <param name="_log">the log item</param>
        private static void getResolution(int sourceWidth, int sourceHeight, Dar inputDar,
                                          CropValues cropValues, bool cropEnabled, int mod, bool resizeEnabled,
                                          bool upsizingAllowed, bool signalAR, bool suggestHeight,
                                          decimal acceptableAspectErrorPercent, ref int outputWidth,
                                          ref int outputHeight, out Dar?outputDar, LogItem _log)
        {
            outputDar = null;

            CropValues cropping = new CropValues();

            if (cropEnabled)
            {
                cropping = cropValues.Clone();
            }

            // remove upsizing if not allowed
            if (!upsizingAllowed && sourceWidth - cropping.left - cropping.right < outputWidth)
            {
                outputWidth = sourceWidth - cropping.left - cropping.right;
                if (_log != null)
                {
                    _log.LogEvent("Lowering output width resolution to " + outputWidth + " to avoid upsizing");
                }
            }

            // correct hres if not mod compliant
            if (outputWidth % mod != 0)
            {
                int diff = outputWidth % mod;
                if (outputWidth - diff > 0)
                {
                    outputWidth -= diff;
                }
                else
                {
                    outputWidth = mod;
                }
            }

            if (suggestHeight)
            {
                int scriptVerticalResolution = Resolution.SuggestVerticalResolution(sourceHeight, sourceWidth, inputDar, cropping,
                                                                                    outputWidth, signalAR, out outputDar, mod, acceptableAspectErrorPercent);

                int iMaximum = 9999;
                if (!upsizingAllowed)
                {
                    iMaximum = sourceHeight - cropping.top - cropping.bottom;
                }

                // Reduce horizontal resolution until a fit is found
                while (scriptVerticalResolution > iMaximum && outputWidth > mod)
                {
                    outputWidth -= mod;
                    scriptVerticalResolution = Resolution.SuggestVerticalResolution(sourceHeight, sourceWidth, inputDar, cropping,
                                                                                    outputWidth, signalAR, out outputDar, mod, acceptableAspectErrorPercent);
                }
                outputHeight = scriptVerticalResolution;
            }
            else if (!resizeEnabled)
            {
                outputHeight = sourceHeight - cropping.top - cropping.bottom;
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// iterates through a set of CropValues and tries to find a majority of matching crop values.
        /// if a match is found, the crop values are returned
        /// if not, the minimum found value is returned for the value in question
        /// </summary>
        /// <param name="values">the CropValues array to be analyzed</param>
        /// <returns>the final CropValues</returns>
        private static CropValues getFinalAutocropValues(CropValues[] values)
        {
            CropValues            retval       = values[0].Clone();
            Dictionary <int, int> topValues    = new Dictionary <int, int>();
            Dictionary <int, int> leftValues   = new Dictionary <int, int>();
            Dictionary <int, int> rightValues  = new Dictionary <int, int>();
            Dictionary <int, int> bottomValues = new Dictionary <int, int>();

            // group crop values
            for (int i = 0; i < values.Length; i++)
            {
                if (leftValues.ContainsKey(values[i].left))
                {
                    leftValues[values[i].left]++;
                }
                else
                {
                    leftValues.Add(values[i].left, 1);
                }
                if (topValues.ContainsKey(values[i].top))
                {
                    topValues[values[i].top]++;
                }
                else
                {
                    topValues.Add(values[i].top, 1);
                }
                if (rightValues.ContainsKey(values[i].right))
                {
                    rightValues[values[i].right]++;
                }
                else
                {
                    rightValues.Add(values[i].right, 1);
                }
                if (bottomValues.ContainsKey(values[i].bottom))
                {
                    bottomValues[values[i].bottom]++;
                }
                else
                {
                    bottomValues.Add(values[i].bottom, 1);
                }

                // set min values found
                if (values[i].left < retval.left)
                {
                    retval.left = values[i].left;
                }
                if (values[i].top < retval.top)
                {
                    retval.top = values[i].top;
                }
                if (values[i].right < retval.right)
                {
                    retval.right = values[i].right;
                }
                if (values[i].bottom < retval.bottom)
                {
                    retval.bottom = values[i].bottom;
                }
            }

            // get "best match" values
            foreach (KeyValuePair <int, int> kvp in leftValues)
            {
                if (kvp.Value > values.Length / 2) // we have more than 50% matching values, use value found
                {
                    retval.left = kvp.Key;
                    break;
                }
            }
            foreach (KeyValuePair <int, int> kvp in topValues)
            {
                if (kvp.Value > values.Length / 2) // we have more than 50% matching values, use value found
                {
                    retval.top = kvp.Key;
                    break;
                }
            }
            foreach (KeyValuePair <int, int> kvp in rightValues)
            {
                if (kvp.Value > values.Length / 2) // we have more than 50% matching values, use value found
                {
                    retval.right = kvp.Key;
                    break;
                }
            }
            foreach (KeyValuePair <int, int> kvp in bottomValues)
            {
                if (kvp.Value > values.Length / 2) // we have more than 50% matching values, use value found
                {
                    retval.bottom = kvp.Key;
                    break;
                }
            }

            return(retval);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// iterates through the lines and columns of the bitmap and compares the pixel values with the value of the upper left corner pixel
        /// if a pixel that doesn't have the same color value is found, it is assumed that this is the first line that does not need to be cropped away
        /// </summary>
        /// <param name="b">the bitmap to be analyzed</param>
        /// <returns>struct containing the number of lines to be cropped away from the left, top, right and bottom</returns>
        public static unsafe CropValues getAutoCropValues(Bitmap b)
        {
            // When locking the pixels into memory, they are currently being converted from 24bpp to 32bpp. This incurs a small (5%) speed penalty,
            // but means that pixel management is easier, because each pixel is a 4-byte int.
            BitmapData image = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            int *      pointer = (int *)image.Scan0.ToPointer();
            int *      lineBegin, pixel;
            int        stride                  = image.Stride / 4;
            CropValues retval                  = new CropValues();
            bool       lineFound               = false;
            int        badPixelThreshold       = 50;
            int        widthBadPixelThreshold  = b.Width / badPixelThreshold;
            int        heightBadPixelThreshold = b.Height / badPixelThreshold;
            int        nbBadPixels             = 0;

            lineBegin = pointer;
            for (int i = 0; i < b.Width; i++)
            {
                pixel = lineBegin;
                for (int j = 0; j < b.Height; j++)
                {
                    //if (b.GetPixel(i, j) != prevColor)
                    //if (isBadPixel(b.GetPixel(i, j)))
                    if (isBadPixel(*pixel))
                    {
                        nbBadPixels++;
                    }
                    if (nbBadPixels > heightBadPixelThreshold)
                    {
                        retval.left = i;
                        if (retval.left < 0)
                        {
                            retval.left = 0;
                        }
                        if (retval.left % 2 != 0)
                        {
                            retval.left++;
                        }
                        lineFound = true;
                        break;
                    }
                    pixel += stride;
                }
                nbBadPixels = 0;
                if (lineFound)
                {
                    break;
                }
                lineBegin += 1; // 4-byte Argb
            }
            nbBadPixels = 0;
            lineFound   = false;
            lineBegin   = pointer;
            for (int i = 0; i < b.Height; i++)
            {
                pixel = lineBegin;
                for (int j = 0; j < b.Width; j++)
                {
                    //if (b.GetPixel(j, i) != prevColor)
                    //if (isBadPixel(b.GetPixel(j, i)))
                    if (isBadPixel(*pixel))
                    {
                        nbBadPixels++;
                    }
                    if (nbBadPixels > widthBadPixelThreshold)
                    {
                        retval.top = i;
                        if (retval.top < 0)
                        {
                            retval.top = 0;
                        }
                        if (retval.top % 2 != 0)
                        {
                            retval.top++;
                        }
                        lineFound = true;
                        break;
                    }
                    pixel += 1; // 4-byte Argb
                }
                nbBadPixels = 0;
                if (lineFound)
                {
                    break;
                }
                lineBegin += stride;
            }
            nbBadPixels = 0;
            lineFound   = false;
            lineBegin   = pointer + b.Width - 1;
            for (int i = b.Width - 1; i >= 0; i--)
            {
                pixel = lineBegin;
                for (int j = 0; j < b.Height; j++)
                {
                    //if (b.GetPixel(i, j) != prevColor)
                    //if (isBadPixel(b.GetPixel(i, j)))
                    if (isBadPixel(*pixel))
                    {
                        nbBadPixels++;
                    }
                    if (nbBadPixels > heightBadPixelThreshold)
                    {
                        retval.right = b.Width - i - 1;
                        if (retval.right < 0)
                        {
                            retval.right = 0;
                        }
                        if (retval.right % 2 != 0)
                        {
                            retval.right++;
                        }
                        lineFound = true;
                        break;
                    }
                    pixel += stride;
                }
                nbBadPixels = 0;
                if (lineFound)
                {
                    break;
                }
                lineBegin -= 1; // Backwards across 4-byte Argb
            }
            nbBadPixels = 0;
            lineFound   = false;
            lineBegin   = pointer + stride * (b.Height - 1);
            for (int i = b.Height - 1; i >= 0; i--)
            {
                pixel = lineBegin;
                for (int j = 0; j < b.Width; j++)
                {
                    //if (b.GetPixel(j, i) != prevColor)
                    //if (isBadPixel(b.GetPixel(j, i)))
                    if (isBadPixel(*pixel))
                    {
                        nbBadPixels++;
                    }
                    if (nbBadPixels > widthBadPixelThreshold)
                    {
                        retval.bottom = b.Height - i - 1;
                        if (retval.bottom < 0)
                        {
                            retval.bottom = 0;
                        }
                        if (retval.bottom % 2 != 0)
                        {
                            retval.bottom++;
                        }
                        lineFound = true;
                        break;
                    }
                    pixel += 1;// 4-byte Argb
                }
                nbBadPixels = 0;
                if (lineFound)
                {
                    break;
                }
                lineBegin -= stride;
            }
            return(retval);
        }
Ejemplo n.º 12
0
        public static void undercrop(ref CropValues crop)
        {
            if (crop.left % 2 != 0 && crop.top % 2 != 0 && crop.bottom % 2 != 0 && crop.right % 2 != 0)
                throw new Exception("Cropping by odd numbers not supported in undercropping to mod16");

            while ((crop.left + crop.right) % 16 > 0)
            {
                if (crop.left > crop.right)
                {
                    if (crop.left > 1)
                        crop.left -= 2;
                    else
                        crop.left = 0;
                }
                else
                {
                    if (crop.right > 1)
                        crop.right -= 2;
                    else
                        crop.right = 0;
                }
            }
            while ((crop.top + crop.bottom) % 16 > 0)
            {
                if (crop.top > crop.bottom)
                {
                    if (crop.top > 1)
                        crop.top -= 2;
                    else
                        crop.top = 0;
                }
                else
                {
                    if (crop.bottom > 1)
                        crop.bottom -= 2;
                    else
                        crop.bottom = 0;
                }
            }
        }
Ejemplo n.º 13
0
        private void parseFile(StreamReader filestream)
        {
            Regex r    = new Regex(_lineRegex, RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);
            Regex rEOL = new Regex(_endLineRegex);

            string line;

            while (!filestream.EndOfStream)
            {
                line = filestream.ReadLine().Trim();
                Match m = r.Match(line);
                if (!m.Success)
                {
                    continue; //skip
                }
                CropValues cv = new CropValues();
                cv.Subject        = m.Groups[1].Value.ToUpper();
                cv.PositionNumber = Int32.Parse(m.Groups[2].Value);
                cv.Side           = m.Groups[3].Value.Equals("L") ? WristFilesystem.Sides.LEFT : WristFilesystem.Sides.RIGHT;
                cv.MinX           = Int32.Parse(m.Groups[4].Value);
                cv.MaxX           = Int32.Parse(m.Groups[5].Value);
                cv.MinY           = Int32.Parse(m.Groups[6].Value);
                cv.MaxY           = Int32.Parse(m.Groups[7].Value);
                cv.MinZ           = Int32.Parse(m.Groups[8].Value);
                cv.MaxZ           = Int32.Parse(m.Groups[9].Value);
                cv.SizeX          = cv.MaxX - cv.MinX + 1; //need to add 1 because we include end pixels
                cv.SizeY          = cv.MaxY - cv.MinY + 1;
                cv.SizeZ          = cv.MaxZ - cv.MinZ + 1;
                cv.VoxelX         = Double.Parse(m.Groups[10].Value);
                cv.VoxelY         = cv.VoxelX;

                //rest of line, optional parameters
                string          lineEnd = m.Groups[11].Value;
                MatchCollection m2      = rEOL.Matches(lineEnd);
                if (m2.Count >= 1)
                {
                    cv.VoxelZ = Double.Parse(m2[0].Value);
                }
                else
                {
                    cv.VoxelZ = 1.0; //default voxel size is 1 if undefined
                }
                if (m2.Count >= 2)
                {
                    cv.RadialStyloid = Int32.Parse(m2[1].Value);
                }
                else
                {
                    cv.RadialStyloid = -1; //not used yet
                }
                cv.Key = generatePositionKey(cv.PositionNumber, cv.Side);

                //if this is the first, then we can just save
                if (_subject.Length == 0)
                {
                    _subject = cv.Subject;
                }
                if (_cropData.ContainsKey(cv.Key))
                {
                    throw new ArgumentOutOfRangeException("Duplicate entry in crop values for series & side: " + cv.Key);
                }

                _cropData.Add(cv.Key, cv);
                _numPositions++;
            }
        }
Ejemplo n.º 14
0
        public static void overcrop(ref CropValues crop)
        {
            if (crop.left % 2 != 0 && crop.top % 2 != 0 && crop.bottom % 2 != 0 && crop.right % 2 != 0)
                throw new Exception("Cropping by odd numbers not supported in overcropping to mod16");

            bool doLeftNext = true;
            while ((crop.left + crop.right) % 16 != 0)
            {
                if (doLeftNext)
                    crop.left += 2;
                else
                    crop.right += 2;
                doLeftNext = !doLeftNext;
            }

            bool doTopNext = true;
            while ((crop.top + crop.bottom) % 16 != 0)
            {
                if (doTopNext)
                    crop.top += 2;
                else
                    crop.bottom += 2;
                doTopNext = !doTopNext;
            }
        }
Ejemplo n.º 15
0
 public static string GetCropLine(bool crop, CropValues cropValues)
 {
     return GetCropLine(crop, cropValues.left, cropValues.top, cropValues.right, cropValues.bottom);
 }
Ejemplo n.º 16
0
 public static void cropMod4Horizontal(ref CropValues crop)
 {
     if (crop.left % 2 != 0 && crop.top % 2 != 0 && crop.bottom % 2 != 0 && crop.right % 2 != 0)
         throw new Exception("Cropping by odd numbers not supported in mod4 horizontal cropping");
     while ((crop.left + crop.right) % 4 > 0)
     {
         if (crop.left > crop.right)
         {
             if (crop.left > 1)
             {
                 crop.left -= 2;
             }
             else
             {
                 crop.left = 0;
             }
         }
         else
         {
             if (crop.right > 1)
             {
                 crop.right -= 2;
             }
             else
             {
                 crop.right = 0;
             }
         }
     }
 }
Ejemplo n.º 17
0
        /// <summary>
        /// opens a dgindex script
        /// if the file can be properly opened, auto-cropping is performed, then depending on the AR settings
        /// the proper resolution for automatic resizing, taking into account the derived cropping values
        /// is calculated, and finally the avisynth script is written and its name returned
        /// </summary>
        /// <param name="path">dgindex script</param>
        /// <param name="aspectRatio">aspect ratio selection to be used</param>
        /// <param name="customDAR">custom display aspect ratio for this source</param>
        /// <param name="horizontalResolution">desired horizontal resolution of the output</param>
        /// <param name="settings">the codec settings (used only for x264)</param>
        /// <param name="sarX">pixel aspect ratio X</param>
        /// <param name="sarY">pixel aspect ratio Y</param>
        /// <param name="height">the final height of the video</param>
        /// <param name="signalAR">whether or not ar signalling is to be used for the output 
        /// (depending on this parameter, resizing changes to match the source AR)</param>
        /// <param name="autoCrop">whether or not autoCrop is used for the input</param>
        /// <returns>the name of the AviSynth script created, empty of there was an error</returns>
        private string openVideo(string path, Dar? AR, int horizontalResolution,
            bool signalAR, LogItem log, AviSynthSettings avsSettings, bool autoDeint,
            VideoCodecSettings settings, out Dar? dar, bool autoCrop, bool keepInputResolution, bool useChaptersMarks)
        {
            dar = null;
            CropValues final = new CropValues();
            Dar customDAR;

            IMediaFile d2v = new d2vFile(path);
            IVideoReader reader = d2v.GetVideoReader();
            if (reader.FrameCount < 1)
            {
                log.Error("DGDecode reported 0 frames in this file. This is a fatal error. Please recreate the DGIndex project");
                return "";
            }

            if (!keepInputResolution)
            {
                //Autocrop
                final = Autocrop.autocrop(reader);

                if (signalAR)
                {
                    if (avsSettings.Mod16Method == mod16Method.overcrop)
                        ScriptServer.overcrop(ref final);
                    else if (avsSettings.Mod16Method == mod16Method.mod4Horizontal)
                        ScriptServer.cropMod4Horizontal(ref final);
                    else if (avsSettings.Mod16Method == mod16Method.undercrop)
                        ScriptServer.undercrop(ref final);
                }

                if (autoCrop)
                {
                    bool error = (final.left == -1);
                    if (!error)
                        log.LogValue("Autocrop values", final);
                    else
                    {
                        log.Error("Autocrop failed, aborting now");
                        return "";
                    }
                }
            }

            log.LogValue("Auto-detect aspect ratio now", AR == null);
            //Check if AR needs to be autodetected now
            if (AR == null) // it does
            {
                customDAR = d2v.Info.DAR;
                if (customDAR.ar > 0)
                    log.LogValue("Aspect ratio", customDAR);
                else
                {
                    customDAR = Dar.ITU16x9PAL;
                    log.Warn(string.Format("No aspect ratio found, defaulting to {0}.", customDAR));
                }
            }
            else
                customDAR = AR.Value;

            if (keepInputResolution)
            {
                horizontalResolution = (int)d2v.Info.Width;
                dar = customDAR;
            }
            else
            {
                // Minimise upsizing
                int sourceHorizontalResolution = (int)d2v.Info.Width - final.right - final.left;
                if (autoCrop)
                    sourceHorizontalResolution = (int)d2v.Info.Width;

                if (horizontalResolution > sourceHorizontalResolution)
                {
                    if (avsSettings.Mod16Method == mod16Method.resize)
                        while (horizontalResolution > sourceHorizontalResolution + 16)
                            horizontalResolution -= 16;
                    else
                        horizontalResolution = sourceHorizontalResolution;
                }
            }

            //Suggest a resolution (taken from AvisynthWindow.suggestResolution_CheckedChanged)
            int scriptVerticalResolution = 0;
            if (keepInputResolution)
            {
                scriptVerticalResolution = (int)d2v.Info.Height;
                log.LogValue("Output resolution", horizontalResolution + "x" + scriptVerticalResolution);
            }
            else
            {
                scriptVerticalResolution = Resolution.suggestResolution(d2v.Info.Height, d2v.Info.Width, (double)customDAR.ar,
                final, horizontalResolution, signalAR, mainForm.Settings.AcceptableAspectErrorPercent, out dar);
                log.LogValue("Output resolution", horizontalResolution + "x" + scriptVerticalResolution);
                if (settings != null && settings is x264Settings) // verify that the video corresponds to the chosen avc level, if not, change the resolution until it does fit
                {
                    x264Settings xs = (x264Settings)settings;
                    if (xs.Level != 15)
                    {
                        AVCLevels al = new AVCLevels();
                        log.LogValue("AVC level", al.getLevels()[xs.Level]);

                        int compliantLevel = 15;
                        while (!this.al.validateAVCLevel(horizontalResolution, scriptVerticalResolution, d2v.Info.FPS, xs, out compliantLevel))
                        { // resolution not profile compliant, reduce horizontal resolution by 16, get the new vertical resolution and try again
                            string levelName = al.getLevels()[xs.Level];
                            horizontalResolution -= 16;
                            scriptVerticalResolution = Resolution.suggestResolution(d2v.Info.Height, d2v.Info.Width, (double)customDAR.ar,
                                final, horizontalResolution, signalAR, mainForm.Settings.AcceptableAspectErrorPercent, out dar);
                        }
                        log.LogValue("Resolution adjusted for AVC Level", horizontalResolution + "x" + scriptVerticalResolution);
                    }
                    if (useChaptersMarks)
                    {
                        qpfile = job.PostprocessingProperties.ChapterFile;
                        if ((Path.GetExtension(qpfile).ToLower()) == ".txt")
                            qpfile = VideoUtil.convertChaptersTextFileTox264QPFile(job.PostprocessingProperties.ChapterFile, d2v.Info.FPS);
                        if (File.Exists(qpfile))
                        {
                            xs.UseQPFile = true;
                            xs.QPFile = qpfile;
                        }
                    }
                }
            }

            //Generate the avs script based on the template
            string inputLine = "#input";
            string deinterlaceLines = "#deinterlace";
            string denoiseLines = "#denoise";
            string cropLine = "#crop";
            string resizeLine = "#resize";

            inputLine = ScriptServer.GetInputLine(path, false, PossibleSources.d2v,
                false, false, false, 0, false);

            log.LogValue("Automatic deinterlacing", autoDeint);
            if (autoDeint)
            {
                string d2vPath = path;
                SourceDetector sd = new SourceDetector(inputLine, d2vPath, false,
                    mainForm.Settings.SourceDetectorSettings,
                    new UpdateSourceDetectionStatus(analyseUpdate),
                    new FinishedAnalysis(finishedAnalysis));
                finished = false;
                sd.analyse();
                waitTillAnalyseFinished();
                deinterlaceLines = filters[0].Script;
                log.LogValue("Deinterlacing used", deinterlaceLines);
            }

            inputLine = ScriptServer.GetInputLine(path, interlaced, PossibleSources.d2v, avsSettings.ColourCorrect, avsSettings.MPEG2Deblock, false, 0, false);

            if (autoCrop)
                cropLine = ScriptServer.GetCropLine(true, final);
            else
                cropLine = ScriptServer.GetCropLine(false, final);

            denoiseLines = ScriptServer.GetDenoiseLines(avsSettings.Denoise, (DenoiseFilterType)avsSettings.DenoiseMethod);

            if (!keepInputResolution)
                resizeLine = ScriptServer.GetResizeLine(!signalAR || avsSettings.Mod16Method == mod16Method.resize, horizontalResolution, scriptVerticalResolution, (ResizeFilterType)avsSettings.ResizeMethod);

            string newScript = ScriptServer.CreateScriptFromTemplate(avsSettings.Template, inputLine, cropLine, resizeLine, denoiseLines, deinterlaceLines);

            if (dar.HasValue)
                newScript = string.Format("global MeGUI_darx = {0}\r\nglobal MeGUI_dary = {1}\r\n{2}", dar.Value.X, dar.Value.Y, newScript);

            log.LogValue("Generated Avisynth script", newScript);
            try
            {
                StreamWriter sw = new StreamWriter(Path.ChangeExtension(path, ".avs"),false, System.Text.Encoding.Default);
                sw.Write(newScript);
                sw.Close();
            }
            catch (IOException i)
            {
                log.LogValue("Error saving AviSynth script", i, ImageType.Error);
                return "";
            }
            return Path.ChangeExtension(path, ".avs");
        }
Ejemplo n.º 18
0
 public void crop(CropValues cropping)
 {
     crop(cropping.left, cropping.top, cropping.right, cropping.bottom);
 }
Ejemplo n.º 19
0
        /// <summary>
        /// iterates through a set of CropValues and tries to find a majority of matching crop values. If a match is found, the crop values are returned
        /// if not, the minimum found value is returned for the value in question
        /// </summary>
        /// <param name="values">the CropValues array to be analyzed</param>
        /// <returns>the final CropValues</returns>
        public static CropValues getFinalAutocropValues(CropValues[] values)
        {
            int        matchingLeftValues = 0, matchingTopValues = 0, matchingRightValues = 0, matchingBottomValues = 0;
            int        minLeft = values[0].left, minTop = values[0].top, minRight = values[0].right, minBottom = values[0].bottom;
            CropValues retval = values[0].Clone();

            for (int i = 1; i < values.Length; i++)
            {
                if (values[i].left == values[i - 1].left)
                {
                    retval.left = values[i].left;
                    matchingLeftValues++;
                }
                if (values[i].top == values[i - 1].top)
                {
                    retval.top = values[i].top;
                    matchingTopValues++;
                }
                if (values[i].right == values[i - 1].right)
                {
                    retval.right = values[i].right;
                    matchingRightValues++;
                }
                if (values[i].bottom == values[i - 1].bottom)
                {
                    retval.bottom = values[i].bottom;
                    matchingBottomValues++;
                }
                if (values[i].left < minLeft)
                {
                    minLeft = values[i].left;
                }
                if (values[i].top < minTop)
                {
                    minTop = values[i].top;
                }
                if (values[i].right < minRight)
                {
                    minRight = values[i].right;
                }
                if (values[i].bottom < minBottom)
                {
                    minBottom = values[i].bottom;
                }
            }
            if (matchingLeftValues < values.Length / 2) // we have less than 50% matching values, use minimum found
            {
                retval.left = minLeft;
            }
            if (matchingTopValues < values.Length / 2)
            {
                retval.top = minTop;
            }
            if (matchingRightValues < values.Length / 2)
            {
                retval.right = minRight;
            }
            if (matchingBottomValues < values.Length / 2)
            {
                retval.bottom = minBottom;
            }
            return(retval);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// if enabled, each change of the horizontal resolution triggers this method
        /// it calculates the ideal mod 16 vertical resolution that matches the desired horizontal resolution
        /// </summary>
        /// <param name="readerHeight">height of the source</param>
        /// <param name="readerWidth">width of the source</param>
        /// <param name="customDAR">custom display aspect ratio to be taken into account for resizing</param>
        /// <param name="cropping">the crop values for the source</param>
        /// <param name="horizontalResolution">the desired horizontal resolution of the output</param>
        /// <param name="signalAR">whether or not we're going to signal the aspect ratio (influences the resizing)</param>
        /// <param name="sarX">horizontal pixel aspect ratio (used when signalAR = true)</param>
        /// <param name="sarY">vertical pixel aspect ratio (used when signalAR = true)</param>
        /// <returns>the suggested horizontal resolution</returns>
        public static int suggestResolution(double readerHeight, double readerWidth, double customDAR, CropValues cropping, int horizontalResolution,
                                            bool signalAR, int acceptableAspectError, out Dar?dar)
        {
            double fractionOfWidth    = (readerWidth - (double)cropping.left - (double)cropping.right) / readerWidth;
            double inputWidthOnHeight = (readerWidth - (double)cropping.left - (double)cropping.right) /
                                        (readerHeight - (double)cropping.top - (double)cropping.bottom);
            double sourceHorizontalResolution = readerHeight * customDAR * fractionOfWidth;
            double sourceVerticalResolution   = readerHeight - (double)cropping.top - (double)cropping.bottom;
            double realAspectRatio            = sourceHorizontalResolution / sourceVerticalResolution; // the real aspect ratio of the video

            realAspectRatio = getAspectRatio(realAspectRatio, acceptableAspectError);                  // Constrains DAR to a set of limited possibilities
            double resizedVerticalResolution = (double)horizontalResolution / realAspectRatio;

            int scriptVerticalResolution = ((int)Math.Round(resizedVerticalResolution / 16.0)) * 16;

            if (signalAR)
            {
                resizedVerticalResolution = (double)horizontalResolution / inputWidthOnHeight; // Scale vertical resolution appropriately
                scriptVerticalResolution  = ((int)Math.Round(resizedVerticalResolution / 16.0) * 16);

                int    parX     = 0;
                int    parY     = 0;
                double distance = 999999;
                for (int i = 1; i < 101; i++)
                {
                    // We create a fraction with integers, and then convert back to a double, and see how big the rounding error is
                    double fractionApproximation   = (double)Math.Round(realAspectRatio * ((double)i)) / (double)i;
                    double approximationDifference = Math.Abs(realAspectRatio - fractionApproximation);
                    if (approximationDifference < distance)
                    {
                        distance = approximationDifference;
                        parY     = i;
                        parX     = (int)Math.Round(realAspectRatio * ((double)parY));
                    }
                }
                Debug.Assert(parX > 0 && parY > 0);
                dar = new Dar((ulong)parX, (ulong)parY);

                return(scriptVerticalResolution);
            }
            else
            {
                dar = null;
                return(scriptVerticalResolution);
            }
        }