blob: 1babb597c6b03aaa0eb6decd943e45d72429f688 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.pdfbox.jbig2.image;
import java.awt.image.WritableRaster;
import org.apache.pdfbox.jbig2.Bitmap;
final class BitmapScanline extends Scanline {
private Bitmap bitmap;
private WritableRaster raster;
private int[] lineBuffer;
public BitmapScanline(final Bitmap src, final WritableRaster dst, final int width) {
super(width);
this.bitmap = src;
this.raster = dst;
lineBuffer = new int[length];
}
@Override
protected void clear() {
lineBuffer = new int[length];
}
@Override
protected void fetch(int x, final int y) {
lineBuffer = new int[length]; // really required?
int srcByteIdx = bitmap.getByteIndex(x, y);
while (x < length) {
final byte srcByte = (byte) ~bitmap.getByte(srcByteIdx++);
final int bits = bitmap.getWidth() - x > 8 ? 8 : bitmap.getWidth() - x;
for (int bitPosition = bits - 1; bitPosition >= 0; bitPosition--, x++) {
if (((srcByte >> bitPosition) & 0x1) != 0)
lineBuffer[x] = 255;
}
}
}
@Override
protected void filter(final int[] preShift, final int[] postShift, final Weighttab[] tabs, final Scanline dst) {
final BitmapScanline dstBitmapScanline = (BitmapScanline) dst;
final int dstLength = dst.length;
// start sum at 1 << shift - 1 for rounding
final int start = 1 << postShift[0] - 1;
final int srcBuffer[] = lineBuffer;
final int dstBuffer[] = dstBitmapScanline.lineBuffer;
// the next two blocks are duplicated except for the missing shift operation if preShift == 0.
final int preShift0 = preShift[0];
final int postShift0 = postShift[0];
if (preShift0 != 0) {
for (int dstIndex = 0, tab = 0; tab < dstLength; tab++) {
final Weighttab weightTab = tabs[tab];
final int weights = weightTab.weights.length;
int sum = start;
for (int weightIndex = 0, srcIndex = weightTab.i0; weightIndex < weights && srcIndex < srcBuffer.length; weightIndex++) {
sum += weightTab.weights[weightIndex] * (srcBuffer[srcIndex++] >> preShift0);
}
final int t = sum >> postShift0;
dstBuffer[dstIndex++] = t < 0 ? 0 : t > 255 ? 255 : t;
}
} else {
for (int dstIndex = 0, tab = 0; tab < dstLength; tab++) {
final Weighttab weightTab = tabs[tab];
final int weights = weightTab.weights.length;
int sum = start;
for (int weightIndex = 0, srcIndex = weightTab.i0; weightIndex < weights && srcIndex < srcBuffer.length; weightIndex++) {
sum += weightTab.weights[weightIndex] * srcBuffer[srcIndex++];
}
dstBuffer[dstIndex++] = sum >> postShift0;
}
}
}
@Override
protected void accumulate(final int weight, final Scanline dst) {
final BitmapScanline dstBitmapScanline = (BitmapScanline) dst;
final int srcBuffer[] = lineBuffer;
final int dstBuffer[] = dstBitmapScanline.lineBuffer;
for (int b = 0; b < dstBuffer.length; b++)
dstBuffer[b] += weight * srcBuffer[b];
}
@Override
protected void shift(final int[] shift) {
final int shift0 = shift[0];
final int half = 1 << shift0 - 1;
final int srcBuffer[] = lineBuffer;
for (int b = 0; b < srcBuffer.length; b++) {
final int pixel = srcBuffer[b] + half >> shift0;
srcBuffer[b] = pixel < 0 ? 0 : pixel > 255 ? 255 : pixel;
}
}
@Override
protected void store(final int x, final int y) {
raster.setSamples(x, y, length, 1, 0, lineBuffer);
}
}