Java Code Examples for com.google.zxing.LuminanceSource#getWidth()

The following examples show how to use com.google.zxing.LuminanceSource#getWidth() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: HybridBinarizer.java    From analyzer-of-android-for-Apache-Weex with Apache License 2.0 5 votes vote down vote up
/**
 * 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.
 */
@Override
public BitMatrix getBlackMatrix() throws NotFoundException {
  if (matrix != null) {
    return matrix;
  }
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  int height = source.getHeight();
  if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) {
    byte[] luminances = source.getMatrix();
    int subWidth = width >> BLOCK_SIZE_POWER;
    if ((width & BLOCK_SIZE_MASK) != 0) {
      subWidth++;
    }
    int subHeight = height >> BLOCK_SIZE_POWER;
    if ((height & BLOCK_SIZE_MASK) != 0) {
      subHeight++;
    }
    int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);

    BitMatrix newMatrix = new BitMatrix(width, height);
    calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
    matrix = newMatrix;
  } else {
    // If the image is too small, fall back to the global histogram approach.
    matrix = super.getBlackMatrix();
  }
  return matrix;
}
 
Example 2
Source File: GlobalHistogramBinarizer.java    From MiBandDecompiled with Apache License 2.0 5 votes vote down vote up
public BitArray getBlackRow(int i, BitArray bitarray)
{
    int j = 1;
    LuminanceSource luminancesource = getLuminanceSource();
    int k = luminancesource.getWidth();
    byte abyte0[];
    int ai[];
    if (bitarray == null || bitarray.getSize() < k)
    {
        bitarray = new BitArray(k);
    } else
    {
        bitarray.clear();
    }
    a(k);
    abyte0 = luminancesource.getRow(i, d);
    ai = e;
    for (int l = 0; l < k; l++)
    {
        int j2 = (0xff & abyte0[l]) >> 3;
        ai[j2] = 1 + ai[j2];
    }

    int i1 = a(ai);
    int j1 = 0xff & abyte0[0];
    int k1 = 0xff & abyte0[j];
    int l1 = j1;
    while (j < k - 1) 
    {
        int i2 = 0xff & abyte0[j + 1];
        if ((k1 << 2) - l1 - i2 >> 1 < i1)
        {
            bitarray.set(j);
        }
        j++;
        l1 = k1;
        k1 = i2;
    }
    return bitarray;
}
 
Example 3
Source File: GlobalHistogramBinarizer.java    From MiBandDecompiled with Apache License 2.0 5 votes vote down vote up
public BitMatrix getBlackMatrix()
{
    LuminanceSource luminancesource = getLuminanceSource();
    int i = luminancesource.getWidth();
    int j = luminancesource.getHeight();
    BitMatrix bitmatrix = new BitMatrix(i, j);
    a(i);
    int ai[] = e;
    for (int k = 1; k < 5; k++)
    {
        byte abyte1[] = luminancesource.getRow((j * k) / 5, d);
        int l1 = (i << 2) / 5;
        for (int i2 = i / 5; i2 < l1; i2++)
        {
            int j2 = (0xff & abyte1[i2]) >> 3;
            ai[j2] = 1 + ai[j2];
        }

    }

    int l = a(ai);
    byte abyte0[] = luminancesource.getMatrix();
    for (int i1 = 0; i1 < j; i1++)
    {
        int j1 = i1 * i;
        for (int k1 = 0; k1 < i; k1++)
        {
            if ((0xff & abyte0[j1 + k1]) < l)
            {
                bitmatrix.set(k1, i1);
            }
        }

    }

    return bitmatrix;
}
 
Example 4
Source File: HybridBinarizer.java    From reacteu-app with MIT License 5 votes vote down vote up
/**
 * 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.
 */
@Override
public BitMatrix getBlackMatrix() throws NotFoundException {
  if (matrix != null) {
    return matrix;
  }
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  int height = source.getHeight();
  if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) {
    byte[] luminances = source.getMatrix();
    int subWidth = width >> BLOCK_SIZE_POWER;
    if ((width & BLOCK_SIZE_MASK) != 0) {
      subWidth++;
    }
    int subHeight = height >> BLOCK_SIZE_POWER;
    if ((height & BLOCK_SIZE_MASK) != 0) {
      subHeight++;
    }
    int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);

    BitMatrix newMatrix = new BitMatrix(width, height);
    calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
    matrix = newMatrix;
  } else {
    // If the image is too small, fall back to the global histogram approach.
    matrix = super.getBlackMatrix();
  }
  return matrix;
}
 
Example 5
Source File: GlobalHistogramBinarizer.java    From reacteu-app with MIT License 5 votes vote down vote up
@Override
public BitArray getBlackRow(int y, BitArray row) throws NotFoundException {
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  if (row == null || row.getSize() < width) {
    row = new BitArray(width);
  } else {
    row.clear();
  }

  initArrays(width);
  byte[] 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(x);
    }
    left = center;
    center = right;
  }
  return row;
}
 
Example 6
Source File: GlobalHistogramBinarizer.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
@Override
public BitArray getBlackRow(int y, BitArray row) throws NotFoundException {
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  if (row == null || row.getSize() < width) {
    row = new BitArray(width);
  } else {
    row.clear();
  }

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

  if (width < 3) {
    // Special case for very small images
    for (int x = 0; x < width; x++) {
      if ((localLuminances[x] & 0xff) < blackPoint) {
        row.set(x);
      }
    }
  } else {
    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.
      if (((center * 4) - left - right) / 2 < blackPoint) {
        row.set(x);
      }
      left = center;
      center = right;
    }
  }
  return row;
}
 
Example 7
Source File: HybridBinarizer.java    From barcodescanner-lib-aar with MIT License 5 votes vote down vote up
/**
 * 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.
 */
@Override
public BitMatrix getBlackMatrix() throws NotFoundException {
  if (matrix != null) {
    return matrix;
  }
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  int height = source.getHeight();
  if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) {
    byte[] luminances = source.getMatrix();
    int subWidth = width >> BLOCK_SIZE_POWER;
    if ((width & BLOCK_SIZE_MASK) != 0) {
      subWidth++;
    }
    int subHeight = height >> BLOCK_SIZE_POWER;
    if ((height & BLOCK_SIZE_MASK) != 0) {
      subHeight++;
    }
    int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);

    BitMatrix newMatrix = new BitMatrix(width, height);
    calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
    matrix = newMatrix;
  } else {
    // If the image is too small, fall back to the global histogram approach.
    matrix = super.getBlackMatrix();
  }
  return matrix;
}
 
Example 8
Source File: GlobalHistogramBinarizer.java    From barcodescanner-lib-aar with MIT License 5 votes vote down vote up
@Override
public BitArray getBlackRow(int y, BitArray row) throws NotFoundException {
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  if (row == null || row.getSize() < width) {
    row = new BitArray(width);
  } else {
    row.clear();
  }

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

  if (width < 3) {
    // Special case for very small images
    for (int x = 0; x < width; x++) {
      if ((localLuminances[x] & 0xff) < blackPoint) {
        row.set(x);
      }
    }
  } else {
    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.
      if (((center * 4) - left - right) / 2 < blackPoint) {
        row.set(x);
      }
      left = center;
      center = right;
    }
  }
  return row;
}
 
Example 9
Source File: HybridBinarizer.java    From weex with Apache License 2.0 5 votes vote down vote up
/**
 * 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.
 */
@Override
public BitMatrix getBlackMatrix() throws NotFoundException {
  if (matrix != null) {
    return matrix;
  }
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  int height = source.getHeight();
  if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) {
    byte[] luminances = source.getMatrix();
    int subWidth = width >> BLOCK_SIZE_POWER;
    if ((width & BLOCK_SIZE_MASK) != 0) {
      subWidth++;
    }
    int subHeight = height >> BLOCK_SIZE_POWER;
    if ((height & BLOCK_SIZE_MASK) != 0) {
      subHeight++;
    }
    int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);

    BitMatrix newMatrix = new BitMatrix(width, height);
    calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
    matrix = newMatrix;
  } else {
    // If the image is too small, fall back to the global histogram approach.
    matrix = super.getBlackMatrix();
  }
  return matrix;
}
 
Example 10
Source File: GlobalHistogramBinarizer.java    From weex with Apache License 2.0 5 votes vote down vote up
@Override
public BitArray getBlackRow(int y, BitArray row) throws NotFoundException {
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  if (row == null || row.getSize() < width) {
    row = new BitArray(width);
  } else {
    row.clear();
  }

  initArrays(width);
  byte[] 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 * 4) - left - right) / 2;
    if (luminance < blackPoint) {
      row.set(x);
    }
    left = center;
    center = right;
  }
  return row;
}
 
Example 11
Source File: GlobalHistogramBinarizer.java    From ScreenCapture with MIT License 5 votes vote down vote up
@Override
public BitArray getBlackRow(int y, BitArray row) throws NotFoundException {
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  if (row == null || row.getSize() < width) {
    row = new BitArray(width);
  } else {
    row.clear();
  }

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

  if (width < 3) {
    // Special case for very small images
    for (int x = 0; x < width; x++) {
      if ((localLuminances[x] & 0xff) < blackPoint) {
        row.set(x);
      }
    }
  } else {
    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.
      if (((center * 4) - left - right) / 2 < blackPoint) {
        row.set(x);
      }
      left = center;
      center = right;
    }
  }
  return row;
}
 
Example 12
Source File: GlobalHistogramBinarizer.java    From analyzer-of-android-for-Apache-Weex with Apache License 2.0 5 votes vote down vote up
@Override
public BitArray getBlackRow(int y, BitArray row) throws NotFoundException {
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  if (row == null || row.getSize() < width) {
    row = new BitArray(width);
  } else {
    row.clear();
  }

  initArrays(width);
  byte[] 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 * 4) - left - right) / 2;
    if (luminance < blackPoint) {
      row.set(x);
    }
    left = center;
    center = right;
  }
  return row;
}
 
Example 13
Source File: HybridBinarizer.java    From ZXing-Orient with Apache License 2.0 5 votes vote down vote up
/**
 * 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.
 */
@Override
public BitMatrix getBlackMatrix() throws NotFoundException {
  if (matrix != null) {
    return matrix;
  }
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  int height = source.getHeight();
  if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) {
    byte[] luminances = source.getMatrix();
    int subWidth = width >> BLOCK_SIZE_POWER;
    if ((width & BLOCK_SIZE_MASK) != 0) {
      subWidth++;
    }
    int subHeight = height >> BLOCK_SIZE_POWER;
    if ((height & BLOCK_SIZE_MASK) != 0) {
      subHeight++;
    }
    int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);

    BitMatrix newMatrix = new BitMatrix(width, height);
    calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
    matrix = newMatrix;
  } else {
    // If the image is too small, fall back to the global histogram approach.
    matrix = super.getBlackMatrix();
  }
  return matrix;
}
 
Example 14
Source File: HybridBinarizer.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * 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.
 */
@Override
public BitMatrix getBlackMatrix() throws NotFoundException {
  if (matrix != null) {
    return matrix;
  }
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  int height = source.getHeight();
  if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) {
    byte[] luminances = source.getMatrix();
    int subWidth = width >> BLOCK_SIZE_POWER;
    if ((width & BLOCK_SIZE_MASK) != 0) {
      subWidth++;
    }
    int subHeight = height >> BLOCK_SIZE_POWER;
    if ((height & BLOCK_SIZE_MASK) != 0) {
      subHeight++;
    }
    int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);

    BitMatrix newMatrix = new BitMatrix(width, height, 1);
    calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
    matrix = newMatrix;
  } else {
    // If the image is too small, fall back to the global histogram approach.
    matrix = super.getBlackMatrix();
  }
  return matrix;
}
 
Example 15
Source File: HybridBinarizer.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * 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.
 */
@Override
public BitMatrix getBlackMatrix() throws NotFoundException {
  if (matrix != null) {
    return matrix;
  }
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  int height = source.getHeight();
  if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) {
    byte[] luminances = source.getMatrix();
    int subWidth = width >> BLOCK_SIZE_POWER;
    if ((width & BLOCK_SIZE_MASK) != 0) {
      subWidth++;
    }
    int subHeight = height >> BLOCK_SIZE_POWER;
    if ((height & BLOCK_SIZE_MASK) != 0) {
      subHeight++;
    }
    int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);

    BitMatrix newMatrix = new BitMatrix(width, height, 1);
    calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
    matrix = newMatrix;
  } else {
    // If the image is too small, fall back to the global histogram approach.
    matrix = super.getBlackMatrix();
  }
  return matrix;
}
 
Example 16
Source File: GlobalHistogramBinarizer.java    From QrCodeScanner with GNU General Public License v3.0 5 votes vote down vote up
@Override
public BitArray getBlackRow(int y, BitArray row) throws NotFoundException {
  LuminanceSource source = getLuminanceSource();
  int width = source.getWidth();
  if (row == null || row.getSize() < width) {
    row = new BitArray(width);
  } else {
    row.clear();
  }

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

  if (width < 3) {
    // Special case for very small images
    for (int x = 0; x < width; x++) {
      if ((localLuminances[x] & 0xff) < blackPoint) {
        row.set(x);
      }
    }
  } else {
    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.
      if (((center * 4) - left - right) / 2 < blackPoint) {
        row.set(x);
      }
      left = center;
      center = right;
    }
  }
  return row;
}
 
Example 17
Source File: HybridBinarizer.java    From MiBandDecompiled with Apache License 2.0 5 votes vote down vote up
public BitMatrix getBlackMatrix()
{
    if (e != null)
    {
        return e;
    }
    LuminanceSource luminancesource = getLuminanceSource();
    if (luminancesource.getWidth() >= 40 && luminancesource.getHeight() >= 40)
    {
        byte abyte0[] = luminancesource.getMatrix();
        int i = luminancesource.getWidth();
        int j = luminancesource.getHeight();
        int k = i >> 3;
        if ((i & 7) != 0)
        {
            k++;
        }
        int l = j >> 3;
        if ((j & 7) != 0)
        {
            l++;
        }
        int ai[][] = a(abyte0, k, l, i, j);
        BitMatrix bitmatrix = new BitMatrix(i, j);
        a(abyte0, k, l, i, j, ai, bitmatrix);
        e = bitmatrix;
    } else
    {
        e = super.getBlackMatrix();
    }
    return e;
}
 
Example 18
Source File: HybridBinarizer.java    From RipplePower with Apache License 2.0 5 votes vote down vote up
/**
 * 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.
 */
@Override
public BitMatrix getBlackMatrix() throws NotFoundException {
	if (matrix != null) {
		return matrix;
	}
	LuminanceSource source = getLuminanceSource();
	int width = source.getWidth();
	int height = source.getHeight();
	if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) {
		byte[] luminances = source.getMatrix();
		int subWidth = width >> BLOCK_SIZE_POWER;
		if ((width & BLOCK_SIZE_MASK) != 0) {
			subWidth++;
		}
		int subHeight = height >> BLOCK_SIZE_POWER;
		if ((height & BLOCK_SIZE_MASK) != 0) {
			subHeight++;
		}
		int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);

		BitMatrix newMatrix = new BitMatrix(width, height);
		calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
		matrix = newMatrix;
	} else {
		// If the image is too small, fall back to the global histogram
		// approach.
		matrix = super.getBlackMatrix();
	}
	return matrix;
}
 
Example 19
Source File: DecodeHandler.java    From appinventor-extensions with Apache License 2.0 5 votes vote down vote up
private static Bitmap toBitmap(LuminanceSource source, int[] pixels) {
  int width = source.getWidth();
  int height = source.getHeight();
  Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
  bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  return bitmap;
}
 
Example 20
Source File: GlobalHistogramBinarizer.java    From RipplePower with Apache License 2.0 5 votes vote down vote up
@Override
public BitArray getBlackRow(int y, BitArray row) throws NotFoundException {
	LuminanceSource source = getLuminanceSource();
	int width = source.getWidth();
	if (row == null || row.getSize() < width) {
		row = new BitArray(width);
	} else {
		row.clear();
	}

	initArrays(width);
	byte[] 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 * 4) - left - right) / 2;
		if (luminance < blackPoint) {
			row.set(x);
		}
		left = center;
		center = right;
	}
	return row;
}