From 95e1b8b460f10aa6346a0d82b5f672bc87ae77de Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 21 Aug 2022 19:39:44 -0500 Subject: [PATCH] RGBLuminanceSource --- src/RGBLuminanceSource.java | 136 ----------------------------- src/lib.rs | 168 ++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 136 deletions(-) diff --git a/src/RGBLuminanceSource.java b/src/RGBLuminanceSource.java index 3950ce8..e69de29 100644 --- a/src/RGBLuminanceSource.java +++ b/src/RGBLuminanceSource.java @@ -1,136 +0,0 @@ -/* - * Copyright 2009 ZXing authors - * - * 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. - */ - -package com.google.zxing; - -/** - * This class is used to help decode images from files which arrive as RGB data from - * an ARGB pixel array. It does not support rotation. - * - * @author dswitkin@google.com (Daniel Switkin) - * @author Betaminos - */ -public final class RGBLuminanceSource extends LuminanceSource { - - private final byte[] luminances; - private final int dataWidth; - private final int dataHeight; - private final int left; - private final int top; - - public RGBLuminanceSource(int width, int height, int[] pixels) { - super(width, height); - - dataWidth = width; - dataHeight = height; - left = 0; - top = 0; - - // In order to measure pure decoding speed, we convert the entire image to a greyscale array - // up front, which is the same as the Y channel of the YUVLuminanceSource in the real app. - // - // Total number of pixels suffices, can ignore shape - int size = width * height; - luminances = new byte[size]; - for (int offset = 0; offset < size; offset++) { - int pixel = pixels[offset]; - int r = (pixel >> 16) & 0xff; // red - int g2 = (pixel >> 7) & 0x1fe; // 2 * green - int b = pixel & 0xff; // blue - // Calculate green-favouring average cheaply - luminances[offset] = (byte) ((r + g2 + b) / 4); - } - } - - private RGBLuminanceSource(byte[] pixels, - int dataWidth, - int dataHeight, - int left, - int top, - int width, - int height) { - super(width, height); - if (left + width > dataWidth || top + height > dataHeight) { - throw new IllegalArgumentException("Crop rectangle does not fit within image data."); - } - this.luminances = pixels; - this.dataWidth = dataWidth; - this.dataHeight = dataHeight; - this.left = left; - this.top = top; - } - - @Override - public byte[] getRow(int y, byte[] row) { - if (y < 0 || y >= getHeight()) { - throw new IllegalArgumentException("Requested row is outside the image: " + y); - } - int width = getWidth(); - if (row == null || row.length < width) { - row = new byte[width]; - } - int offset = (y + top) * dataWidth + left; - System.arraycopy(luminances, offset, row, 0, width); - return row; - } - - @Override - public byte[] getMatrix() { - int width = getWidth(); - int height = getHeight(); - - // If the caller asks for the entire underlying image, save the copy and give them the - // original data. The docs specifically warn that result.length must be ignored. - if (width == dataWidth && height == dataHeight) { - return luminances; - } - - int area = width * height; - byte[] matrix = new byte[area]; - int inputOffset = top * dataWidth + left; - - // If the width matches the full width of the underlying data, perform a single copy. - if (width == dataWidth) { - System.arraycopy(luminances, inputOffset, matrix, 0, area); - return matrix; - } - - // Otherwise copy one cropped row at a time. - for (int y = 0; y < height; y++) { - int outputOffset = y * width; - System.arraycopy(luminances, inputOffset, matrix, outputOffset, width); - inputOffset += dataWidth; - } - return matrix; - } - - @Override - public boolean isCropSupported() { - return true; - } - - @Override - public LuminanceSource crop(int left, int top, int width, int height) { - return new RGBLuminanceSource(luminances, - dataWidth, - dataHeight, - this.left + left, - this.top + top, - width, - height); - } - -} diff --git a/src/lib.rs b/src/lib.rs index fff1041..29ae4ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1842,3 +1842,171 @@ impl LuminanceSource for PlanarYUVLuminanceSource{ } } + +/* + * Copyright 2009 ZXing authors + * + * 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. + */ + +//package com.google.zxing; + +/** + * This class is used to help decode images from files which arrive as RGB data from + * an ARGB pixel array. It does not support rotation. + * + * @author dswitkin@google.com (Daniel Switkin) + * @author Betaminos + */ +pub struct RGBLuminanceSource { + + luminances:Vec, + dataWidth:usize, + dataHeight:usize, + left:usize, + top:usize, + width:usize, + height:usize, +} + +impl LuminanceSource for RGBLuminanceSource { + fn new( width:usize, height:usize) -> Self { + let new_ils : Self; + new_ils.width = width; + new_ils.height = height; + + new_ils + } + + fn getRow(&self, y:usize, row:&Vec) -> Vec { + if y < 0 || y >= self.getHeight() { + panic!("Requested row is outside the image: {}" , y); + } + let width = self.getWidth(); + + let offset = (y + self.top) *self. dataWidth + self.left; + row[0..width].clone_from_slice(&self.luminances[offset..width]); + //System.arraycopy(self.luminances, offset, row, 0, width); + return row; + } + + fn getMatrix(&self) -> Vec { + let width =self. getWidth(); + let height = self.getHeight(); + + // If the caller asks for the entire underlying image, save the copy and give them the + // original data. The docs specifically warn that result.length must be ignored. + if (width == self.dataWidth && height == self.dataHeight) { + return self.luminances; + } + + let area = width * height; + let mut matrix = Vec::with_capacity(area); + let mut inputOffset = self.top * self.dataWidth + self.left; + + // If the width matches the full width of the underlying data, perform a single copy. + if (width == self.dataWidth) { + matrix[0..area].clone_from_slice(&self.luminances[inputOffset..area]); + //System.arraycopy(self.luminances, inputOffset, matrix, 0, area); + return matrix; + } + + // Otherwise copy one cropped row at a time. + for y in 0..height{ + //for (int y = 0; y < height; y++) { + let outputOffset = y * width; + matrix[outputOffset..width].clone_from_slice(&self.luminances[inputOffset..width]); + //System.arraycopy(luminances, inputOffset, matrix, outputOffset, width); + inputOffset += self.dataWidth; + } + return matrix; + } + + fn getWidth(&self) -> usize { + self.width + } + + fn getHeight(&self) -> usize { + self.height + } + + fn isCropSupported(&self) -> bool { + return true; + } + + fn crop(&self, left:usize, top:usize, width:usize, height:usize) -> Result { + + match RGBLuminanceSource::new_complex(&self.luminances, + self.dataWidth, + self.dataHeight, + self.left + left, + self.top + top, + width, + height) { + Ok(crop) => Ok(crop), + Err(error) => Err(UnsupportedOperationException::new()), + } + + } + +} + +impl RGBLuminanceSource { + pub fn new_with_width_height_pixels( width:usize, height:usize, pixels:&Vec) -> Self{ + //super(width, height); + + let dataWidth = width; + let dataHeight = height; + let left = 0; + let top = 0; + + // In order to measure pure decoding speed, we convert the entire image to a greyscale array + // up front, which is the same as the Y channel of the YUVLuminanceSource in the real app. + // + // Total number of pixels suffices, can ignore shape + let size = width * height; + let mut luminances:Vec = Vec::with_capacity(size); + for offset in 0..size{ + //for (int offset = 0; offset < size; offset++) { + let pixel = pixels[offset]; + let r = (pixel >> 16) & 0xff; // red + let g2 = (pixel >> 7) & 0x1fe; // 2 * green + let b = pixel & 0xff; // blue + // Calculate green-favouring average cheaply + luminances[offset] = ((r + g2 + b) / 4); + } + Self { luminances, dataWidth, dataHeight, left: left, top: top, width, height } + } + + fn new_complex( pixels:&Vec, + dataWidth:usize, + dataHeight:usize, + left:usize, + top:usize, + width:usize, + height:usize) -> Result{ + + if (left + width > dataWidth || top + height > dataHeight) { + return Err(IllegalArgumentException::new("Crop rectangle does not fit within image data.")); + } + Ok(Self{ + luminances: todo!(), + dataWidth, + dataHeight, + left, + top, + width, + height, + }) + } +} \ No newline at end of file