mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
git-svn-id: https://zxing.googlecode.com/svn/trunk@472 59b500cc-1b3d-0410-9834-0bbf25fbcc57
120 lines
3.9 KiB
C++
120 lines
3.9 KiB
C++
/*
|
|
* MonochromeBitmapSource.cpp
|
|
* zxing
|
|
*
|
|
* Created by Christian Brunschen on 12/05/2008.
|
|
* Copyright 2008 Google UK. All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "MonochromeBitmapSource.h"
|
|
#include "BlackPointEstimator.h"
|
|
#include "ReaderException.h"
|
|
#include <limits>
|
|
|
|
#define LUMINANCE_BITS (5)
|
|
#define LUMINANCE_SHIFT (8 - LUMINANCE_BITS)
|
|
#define LUMINANCE_BUCKETS (1 << LUMINANCE_BITS)
|
|
|
|
using namespace std;
|
|
|
|
MonochromeBitmapSource::MonochromeBitmapSource() :
|
|
blackPoint_(numeric_limits<unsigned char>::max()),
|
|
lastEstimationMethod_(BlackPointEstimationMethod_None),
|
|
lastEstimationArgument_(-1) {
|
|
}
|
|
|
|
|
|
bool MonochromeBitmapSource::isBlack(size_t x, size_t y) {
|
|
return getPixel(x, y) < blackPoint_;
|
|
}
|
|
|
|
Ref<BitArray> MonochromeBitmapSource::getBlackRow(size_t y,
|
|
Ref<BitArray> row,
|
|
size_t startX,
|
|
size_t getWidth) {
|
|
Ref<BitArray> result(row ? row : new BitArray(getWidth));
|
|
if (row) {
|
|
result->clear();
|
|
}
|
|
valarray<unsigned char> pixelRow(getWidth);
|
|
for (size_t i = 0; i < getWidth; i++) {
|
|
pixelRow[i] = getPixel(startX + i, y);
|
|
}
|
|
|
|
// If the current decoder calculated the blackPoint based on one row,
|
|
// assume we're trying to decode a 1D barcode, and apply some sharpening.
|
|
if (lastEstimationMethod_ == BlackPointEstimationMethod_RowSampling) {
|
|
unsigned int left = pixelRow[0];
|
|
unsigned int center = pixelRow[1];
|
|
for (size_t i = 1; i < getWidth - 1; i++) {
|
|
unsigned int right = pixelRow[i+1];
|
|
// Simple -1 4 -1 box filter with a weight of 2
|
|
unsigned int luminance = ((center << 2) - left - right) >> 1;
|
|
if (luminance < blackPoint_) {
|
|
result->set(i);
|
|
}
|
|
left = center;
|
|
center = right;
|
|
}
|
|
} else {
|
|
for (size_t i = 0; i < getWidth; i++) {
|
|
if (pixelRow[i] < blackPoint_) {
|
|
result->set(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void MonochromeBitmapSource::
|
|
estimateBlackPoint(BlackPointEstimationMethod method, int arg) {
|
|
size_t width = getWidth();
|
|
size_t height = getHeight();
|
|
if (method != lastEstimationMethod_ || arg != lastEstimationArgument_) {
|
|
valarray<int> histogram(LUMINANCE_BUCKETS);
|
|
if (method == BlackPointEstimationMethod_2D) {
|
|
size_t minDimension = width < height ? width : height;
|
|
size_t startX = (width - minDimension) >> 1;
|
|
size_t startY = (height - minDimension) >> 1;
|
|
for (size_t n = 0; n < minDimension; n++) {
|
|
unsigned char pixel = getPixel(startX + n, startY + n);
|
|
histogram[pixel >> LUMINANCE_SHIFT]++;
|
|
}
|
|
} else if (method == BlackPointEstimationMethod_RowSampling) {
|
|
if (arg < 0 || arg >= (int)height) {
|
|
throw new IllegalArgumentException
|
|
("black point estimation argument out of range");
|
|
}
|
|
size_t y = static_cast<size_t> (arg);
|
|
for (size_t x = 0; x < width; x++) {
|
|
histogram[getPixel(x, y) >> LUMINANCE_SHIFT]++;
|
|
}
|
|
} else {
|
|
throw new IllegalArgumentException
|
|
("unknown black point estimation method");
|
|
}
|
|
|
|
blackPoint_ = BlackPointEstimator::estimate(histogram) << LUMINANCE_SHIFT;
|
|
lastEstimationMethod_ = method;
|
|
lastEstimationArgument_ = arg;
|
|
}
|
|
}
|
|
|
|
BlackPointEstimationMethod MonochromeBitmapSource::getLastEstimationMethod() {
|
|
return lastEstimationMethod_;
|
|
}
|
|
|