// Applies simple sharpening to the row data to improve performance of the 1D Readers.
        public override BitArray getBlackRow(int y, BitArray row)
        {
            LuminanceSource source = LuminanceSource;
            int             width  = source.Width;

            if (row == null || row.Size < width)
            {
                row = new BitArray(width);
            }
            else
            {
                row.clear();
            }

            initArrays(width);
            sbyte[] localLuminances = source.getRow(y, luminances);
            int[]   localBuckets    = buckets;
            for (int x = 0; x < width; x++)
            {
                int pixel = localLuminances[x] & 0xff;
                localBuckets[pixel >> LUMINANCE_SHIFT]++;
            }
            int blackPoint = estimateBlackPoint(localBuckets);

            int left   = localLuminances[0] & 0xff;
            int center = localLuminances[1] & 0xff;

            for (int x = 1; x < width - 1; x++)
            {
                int right = localLuminances[x + 1] & 0xff;
                // A simple -1 4 -1 box filter with a weight of 2.
                int luminance = ((center << 2) - left - right) >> 1;
                if (luminance < blackPoint)
                {
                    row.set_Renamed(x);
                }
                left   = center;
                center = right;
            }
            return(row);
        }
        // Calculates the final BitMatrix once for all requests. This could be called once from the
        // constructor instead, but there are some advantages to doing it lazily, such as making
        // profiling easier, and not doing heavy lifting when callers don't expect it.
        private void  binarizeEntireImage()
        {
            if (matrix == null)
            {
                LuminanceSource source = LuminanceSource;
                if (source.Width >= MINIMUM_DIMENSION && source.Height >= MINIMUM_DIMENSION)
                {
                    sbyte[] luminances  = source.Matrix;
                    int     width       = source.Width;
                    int     height      = source.Height;
                    int     subWidth    = width >> 3;
                    int     subHeight   = height >> 3;
                    int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width);

                    matrix = new BitMatrix(width, height);
                    calculateThresholdForBlock(luminances, subWidth, subHeight, width, blackPoints, matrix);
                }
                else
                {
                    // If the image is too small, fall back to the global histogram approach.
                    matrix = base.BlackMatrix;
                }
            }
        }
		public override Binarizer createBinarizer(LuminanceSource source)
		{
			return new HybridBinarizer(source);
		}
		public HybridBinarizer(LuminanceSource source):base(source)
		{
		}
 public override Binarizer createBinarizer(LuminanceSource source)
 {
     return(new HybridBinarizer(source));
 }
 public HybridBinarizer(LuminanceSource source) : base(source)
 {
 }
		public override Binarizer createBinarizer(LuminanceSource source)
		{
			return new GlobalHistogramBinarizer(source);
		}
		public GlobalHistogramBinarizer(LuminanceSource source):base(source)
		{
		}
 public override Binarizer createBinarizer(LuminanceSource source)
 {
     return(new GlobalHistogramBinarizer(source));
 }
 public GlobalHistogramBinarizer(LuminanceSource source) : base(source)
 {
 }
 public GlobalHistogramBinarizer(LuminanceSource source)
     : base(source)
 {
     luminances = EMPTY;
     buckets = new int[LUMINANCE_BUCKETS];
 }