I have been trying to hide an image in another image(both of same type) by making changes in the pixels.But it gives an error like this:
Exception in thread "main" java.lang.NumberFormatException: For input
string: "010010101101111111"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Image.main(Image.java:160)**
The code is shown as below:
public class Image {
public static void main(String argv[]) throws Exception
{
String imageFile1 = "C:/Users/Desktop/1.jpg";
String imageFile2 = "C:/Users/Desktop/2.jpg";
File file1 = new File(imageFile1);
FileInputStream fis1 = null;
try {
fis1 = new FileInputStream(imageFile1);
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
File file2 = new File(imageFile2);
FileInputStream fis2 = null;
try {
fis2 = new FileInputStream(imageFile2);
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
BufferedImage oimage1 = ImageIO.read(file1);
BufferedImage oimage2 = ImageIO.read(file2);
ByteArrayOutputStream baos1=new ByteArrayOutputStream();
byte[] buf1 = new byte[1024];
try {
for (int readNum; (readNum = fis1.read(buf1)) != -1;) {
baos1.write(buf1, 0, readNum);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ByteArrayOutputStream baos2=new ByteArrayOutputStream();
byte[] buf2 = new byte[1024];
try {
for (int readNum; (readNum = fis2.read(buf1)) != -1;) {
baos2.write(buf2, 0, readNum);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
final byte[] imageInByte1 = baos1.toByteArray();
final int size1 = imageInByte1.length;
final byte[] imageInByte2 = baos2.toByteArray();
final int size2 = imageInByte2.length;
int width1 = oimage1.getWidth();
int height1 = oimage1.getHeight();
int pixel1 = 0;
int red1,green1,blue1;
int width2 = oimage2.getWidth();
int height2 = oimage2.getHeight();
int pixel2=0,red2,green2,blue2;
final BufferedImage newimg1 = new BufferedImage(width1, height1, BufferedImage.TYPE_INT_ARGB);
final BufferedImage newimg2 = new BufferedImage(width2, height2, BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < width1; i++)
for (int j = 0; j < height1; j++) {
//scan through each pixel
pixel1 = oimage1.getRGB(i, j);
pixel2 = oimage2.getRGB(i, j);
//for red
String redpix1=Integer.toBinaryString(pixel1);
String binaryred1 = redpix1.substring(20,23);
String redpix2=Integer.toBinaryString(pixel2);
String binaryred2=redpix2.substring(20,23);
String newred= binaryred1 + binaryred2;
//for green
String greenpix1=Integer.toBinaryString(pixel1);
String binarygreen1=greenpix1.substring(12,15);
String greenpix2=Integer.toBinaryString(pixel2);
String binarygreen2=greenpix2.substring(12,15);
String newgreen= binarygreen1 + binarygreen2;
//for blue
String bluepix1=Integer.toBinaryString(pixel1);
String binaryblue1=bluepix1.substring(4,7);
String bluepix2=Integer.toBinaryString(pixel2);
String binaryblue2=bluepix2.substring(4,7);
String newblue= binaryblue1 + binaryblue2;
//combining the new values
String spixel=newred +newgreen + newblue;
int newpixel = Integer.parseInt(spixel);
newimg2.setRGB(i,j,newpixel);
}
JFrame f =new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JLabel(new ImageIcon(newimg2)));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
The size of 1.jpg is greater than size of 2.jpg.
Can this code be modified to get output? or is any another easy way to embed the image?
The error message isn’t very explanatory. The NumberFormatExceptiondocumentation isn’t either in this case. It says:
Thrown to indicate that the application has attempted to convert a
string to one of the numeric types, but that the string does not have
the appropriate format.
What happens is an int overflow. The largest int you can have is 2 147 483 647 (10 digits), so 10010101101111111 (17 digits after I removed the leading 0) is way too large. This problem shows as a NumberFormatException.
If you intended that to be a binary number, use Integer.parseInt(spixel, 2) to indicate radix 2 (that is, binary). Then you should be able to parse it since up to 31 binary digits fit in an ìnt (not 32 because it’s signed, so there’s a sign bit).
There is a similar question to this one: What is a NumberFormatException and how can I fix it? However, while the accepted answer to that one does mention overflow (pretty deep down in the answer), it doesn’t cover trying to parse a string with the wrong radix. Still you may want to read through the question and answers and learn.
Related
I'm reading the data from a serial port using InputStream.
One part of the stream I need to convert to String, and the other one to binary data.
I already have two methods, and each one does what is needed, but I need to send the data from the serial port twice for both methods to work
My question is if I can somehow split the stream so I can get all of the data to two methods in one send from the serial port?
private static void readingBytesSN(SerialPort comPort) {
comPort.addDataListener(new SerialPortDataListener() {
#Override
public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
}
#Override
public void serialEvent(SerialPortEvent serialPortEvent) {
InputStream in;
String startSn2 = "110000010011010001101100100011011000100011010000111000010001010";
String newLine2 = "01100000110110010001101100010001101000011100001000101";
String startSn = "27434877273598525669";
String newLine = "12273598525669";
String endOfSn = "12694954545053565052661310";
String endOfData = "1227513232131032131032131032131032131027109275132";
String s1 = "";
String s2 = "";
if (serialPortEvent.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
return;
}
int x = 0;
try {
in = comPort.getInputStream();
Scanner sc = new Scanner(in);
List<String> line = new ArrayList<>();
while (sc.hasNextLine()) {
line.add(sc.next());
if (line.contains("\u001Bm\u001B3")) {
break;
}
}
while (((x = in.read()) != 109)) {
s1 += String.format("%8s", Integer.toBinaryString(x & 0xFF)).replace(' ', '0');
}
} catch (IOException e1) {
e1.printStackTrace();
}
String[] snArray = s1.split(startSn2);
for (int i = 1; i < snArray.length; i++) {
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g2d = img.createGraphics();
Font font = new Font("Arial", Font.PLAIN, 2);
g2d.setFont(font);
int height = g2d.getFontMetrics().getHeight();
g2d.dispose();
img = new BufferedImage(384, 40, BufferedImage.TYPE_INT_RGB);
g2d = img.createGraphics();
g2d.setFont(font);
g2d.setColor(Color.WHITE);
int fontSize = 1;
for (String line : snArray[i].split(newLine2)) {
g2d.drawString(line, 0, height);
height += fontSize;
//System.out.println("Serial number: " + line);
}
//g2d.dispose();
try {
ImageIO.write(img, "png", new File("images\\Text" + i + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
g2d.dispose();
String result = null;
try {
result = SerialOcr("images\\Text" + i + ".png");
} catch (TesseractException e) {
e.printStackTrace();
}
System.out.println(result);
}
}
});
}
I repeated the input stream using this code.
InputStream bufferdInputStream = new BufferedInputStream(myInputStream);
bufferdInputStream.mark(some_value);
//do the first method
bufferdInputStream.reset();
//do the second method
This question already has answers here:
How to combine multiple PNGs into one big PNG file?
(10 answers)
Closed 2 years ago.
My case is what I need to add several barcodes (png) which I generated using Barcode4j library in one png file. I couldn't find any examples, also couldn't make up my mind to solve it. So any help will be appreciated.
Well, I generate barcodes in usual way (throug for) and collecte them in a list of bufferedImages (List). Now I need to glue this images in one.
My code:
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, "image/x-png", 300, BufferedImage.TYPE_BYTE_BINARY, false, 0);
List<BufferedImage> bufferedImageList = new ArrayList<>(); // list for bufferedImages
for (int i = 0; i < barcodesList.size(); i++) {
try {
Code128Bean code128 = new Code128Bean();
code128.setHeight(15f);
code128.setModuleWidth(0.3);
code128.setQuietZone(10);
code128.doQuietZone(true);
code128.generateBarcode(canvas, (String) barcodesList.get(i));
bufferedImageList.add(canvas.getBufferedImage()); // collect images of barcode in cicle
canvas.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
FileOutputStream fos = new FileOutputStream(barcodePath.toString());
// to do smth to make one png from collected images
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
Well, my code which combine several barcodes looks like this
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, "image/x-png", 300, BufferedImage.TYPE_BYTE_BINARY, false, 0);
List<BufferedImage> bufferedImageList = new ArrayList<>(); // list for bufferedImages
int sumHeight = 0;
int sumWhide = 0;
int columns = 2;
int rows = 0;
for (int i = 0; i < barcodesList.size(); i++) {
try {
Code128Bean code128 = new Code128Bean();
code128.setHeight(15f);
code128.setModuleWidth(0.3);
code128.setQuietZone(10);
code128.doQuietZone(true);
code128.generateBarcode(canvas, (String) barcodesList.get(i));
sumHeight = sumHeight + canvas.getBufferedImage().getHeight();
sumWhide = sumWhide + canvas.getBufferedImage().getWidth();
bufferedImageList.add(canvas.getBufferedImage()); // collect images of barcode in cycle
canvas.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
double dbl = barcodesList.size() / (double) columns;
rows = (int)Math.ceil(dbl);
int oneWhide = sumWhide / barcodesList.size();
int imgWhide = oneWhide * columns;
int oneHeight = sumHeight / barcodesList.size();
int imgHeight = oneHeight * rows;
BufferedImage bigImage = new BufferedImage(imgWhide, imgHeight, BufferedImage.TYPE_BYTE_BINARY);
Graphics g = bigImage.getGraphics();
int x = 0;
int y = 0;
for (BufferedImage bufferedImage : bufferedImageList) {
g.drawImage(bufferedImage, x, y, null);
x += oneWhide;
if(x >= bigImage.getWidth()){
x = 0;
y += bufferedImage.getHeight();
}
}
ImageIO.write(bigImage,"png",new File(barcodePath.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
I'm using jpountz LZ4 to try and compress files and I want to read in and output files using Java file input and output streams. I've tried to find a solution online but theres nothing, I found a previous stackoverflow question on how to implement LZ4 correctly and I've taken that and tried to modify it to use the streams, but I'm not sure if this is correct or if it's even working.
When running the compression on a text file it outputs a file which has some characters missing or replaced with symbols
ðHello world Heðo world Hello ðrld Hello worlðHello worl
but when running it with a image file it throws an out of bounds error. I've also been unable to get decompression to work as it throws a Error decoding offset 3 of input buffer.
Here is my code any help would be appreciated thanks
public void LZ4Compress(InputStream in, OutputStream out){
int noBytesRead = 0; //number of bytes read from input
int noBytesProcessed = 0; //number of bytes processed
try {
while ((noBytesRead = in.read(inputBuffer)) >= 0) {
noBytesProcessed = inputBuffer.length;
decompressedLength = inputBuffer.length;
outputBuffer = compress(inputBuffer, decompressedLength);
out.write(outputBuffer, 0, noBytesRead);
}
out.flush();
in.close();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void LZ4decompress(InputStream in, OutputStream out){
int noBytesRead = 0; //number of bytes read from input
try {
while((noBytesRead = in.read(inputBuffer)) >= 0){
noBytesProcessed = inputBuffer.length;
outputBuffer = decompress(inputBuffer);
out.write(outputBuffer, 0, noBytesRead);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static byte[] compress(byte[] src, int srcLen) {
decompressedLength = srcLen;
int maxCompressedLength = compressor.maxCompressedLength(decompressedLength);
byte[] compressed = new byte[maxCompressedLength];
int compressLen = compressor.compress(src, 0, decompressedLength, compressed, 0, maxCompressedLength);
byte[] finalCompressedArray = Arrays.copyOf(compressed, compressLen);
return finalCompressedArray;
}
private static LZ4SafeDecompressor decompressor = factory.safeDecompressor();
public static byte[] decompress(byte[] finalCompressedArray) {
byte[] restored = new byte[finalCompressedArray.length];
restored = decompressor.decompress(finalCompressedArray, finalCompressedArray.length);
return restored;
}
So I solved my problem by using LZ4block input/output streams
public static void LZ4compress(String filename, String lz4file){
byte[] buf = new byte[2048];
try {
String outFilename = lz4file;
LZ4BlockOutputStream out = new LZ4BlockOutputStream(new FileOutputStream(outFilename), 32*1024*1024);
FileInputStream in = new FileInputStream(filename);
int len;
while((len = in.read(buf)) > 0){
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
}
}
public static void LZ4Uncompress(String lz4file, String filename){
byte[] buf = new byte[2048];
try {
String outFilename = filename;
LZ4BlockInputStream in = new LZ4BlockInputStream(new FileInputStream(lz4file));
FileOutputStream out = new FileOutputStream(outFilename);
int len;
while((len = in.read(buf)) > 0){
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
}
}
Looking only at code, I would say you are going wrong here:
outputBuffer = compress(inputBuffer, decompressedLength);
out.write(outputBuffer, 0, noBytesRead);
You have already trimmed outputBuffer in compress. Try:
out.write(outputBuffer);
I am writing an FLV parser in Java and have come up against an issue. The program successfully parses and groups together tags into packets and correctly identifies and assigns a byte array for each tag's body based upon the BodyLength flag in the header. However in my test files it successfully completes this but stops before the last 4 bytes.
The byte sequence left out in the first file is :
00 00 14 C3
And in the second:
00 00 01 46
Clearly it is an issue with the final 4 bytes of both files however I cannot spot the error in my logic. I suspect it might be:
while (in.available() != 0)
However I also doubt this is the case as the program is successfully entering the loop for the final tag however it is just stopping 4 bytes short. Any help is greatly appreciated. (I know proper exception handling is as yet not taking place)
Parser.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Array;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
/**
*
* #author A
*
* Parser class for FLV files
*/
public class Parser {
private static final int HEAD_SIZE = 9;
private static final int TAG_HEAD_SIZE = 15;
private static final byte[] FLVHEAD = { 0x46, 0x4C, 0x56 };
private static final byte AUDIO = 0x08;
private static final byte VIDEO = 0x09;
private static final byte DATA = 0x12;
private static final int TYPE_INDEX = 4;
private File file;
private FileInputStream in;
private ArrayList<Packet> packets;
private byte[] header = new byte[HEAD_SIZE];
Parser() throws FileNotFoundException {
throw new FileNotFoundException();
}
Parser(URI uri) {
file = new File(uri);
init();
}
Parser(File file) {
this.file = file;
init();
}
private void init() {
packets = new ArrayList<Packet>();
}
public void parse() {
boolean test = false;
try {
test = parseHeader();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (test) {
System.out.println("Header Verified");
// Add header packet to beginning of list & then null packet
Packet p = new Packet(PTYPE.P_HEAD);
p.setSize(header.length);
p.setByteArr(header);
packets.add(p);
p = null;
try {
parseTags();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// throw FileNotFoundException because incorrect file
}
}
private boolean parseHeader() throws FileNotFoundException, IOException {
if (file == null)
throw new FileNotFoundException();
in = new FileInputStream(file);
in.read(header, 0, 9);
return Arrays.equals(FLVHEAD, Arrays.copyOf(header, FLVHEAD.length));
}
private void parseTags() throws IOException {
if (file == null)
throw new FileNotFoundException();
byte[] tagHeader = new byte[TAG_HEAD_SIZE];
Arrays.fill(tagHeader, (byte) 0x00);
byte[] body;
byte[] buf;
PTYPE pt;
int OFFSET = 0;
while (in.available() != 0) {
// Read first 5 - bytes, previous tag size + tag type
in.read(tagHeader, 0, 5);
if (tagHeader[TYPE_INDEX] == AUDIO) {
pt = PTYPE.P_AUD;
} else if (tagHeader[TYPE_INDEX] == VIDEO) {
pt = PTYPE.P_VID;
} else if (tagHeader[TYPE_INDEX] == DATA) {
pt = PTYPE.P_DAT;
} else {
// Header should've been dealt with - if previous data types not
// found then throw exception
System.out.println("Unexpected header format: ");
System.out.print(String.format("%02x\n", tagHeader[TYPE_INDEX]));
System.out.println("Last Tag");
packets.get(packets.size()-1).diag();
System.out.println("Number of tags found: " + packets.size());
throw new InputMismatchException();
}
OFFSET = TYPE_INDEX;
// Read body size - 3 bytes
in.read(tagHeader, OFFSET + 1, 3);
// Body size buffer array - padding for 1 0x00 bytes
buf = new byte[4];
Arrays.fill(buf, (byte) 0x00);
// Fill size bytes
buf[1] = tagHeader[++OFFSET];
buf[2] = tagHeader[++OFFSET];
buf[3] = tagHeader[++OFFSET];
// Calculate body size
int bSize = ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN)
.getInt();
// Initialise Array
body = new byte[bSize];
// Timestamp
in.read(tagHeader, ++OFFSET, 3);
Arrays.fill(buf, (byte) 0x00);
// Fill size bytes
buf[1] = tagHeader[OFFSET++];
buf[2] = tagHeader[OFFSET++];
buf[3] = tagHeader[OFFSET++];
int milliseconds = ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN)
.getInt();
// Read padding
in.read(tagHeader, OFFSET, 4);
// Read body
in.read(body, 0, bSize);
// Diagnostics
//printBytes(body);
Packet p = new Packet(pt);
p.setSize(tagHeader.length + body.length);
p.setByteArr(concat(tagHeader, body));
p.setMilli(milliseconds);
packets.add(p);
p = null;
// Zero out for next iteration
body = null;
Arrays.fill(buf, (byte)0x00);
Arrays.fill(tagHeader, (byte)0x00);
milliseconds = 0;
bSize = 0;
OFFSET = 0;
}
in.close();
}
private byte[] concat(byte[] tagHeader, byte[] body) {
int aLen = tagHeader.length;
int bLen = body.length;
byte[] C = (byte[]) Array.newInstance(tagHeader.getClass()
.getComponentType(), aLen + bLen);
System.arraycopy(tagHeader, 0, C, 0, aLen);
System.arraycopy(body, 0, C, aLen, bLen);
return C;
}
private void printBytes(byte[] b) {
System.out.println("\n--------------------");
for (int i = 0; i < b.length; i++) {
System.out.print(String.format("%02x ", b[i]));
if (((i % 8) == 0 ) && i != 0)
System.out.println();
}
}
}
Packet.java
public class Packet {
private PTYPE type = null;
byte[] buf;
int milliseconds;
Packet(PTYPE t) {
this.setType(t);
}
public void setSize(int s) {
buf = new byte[s];
}
public PTYPE getType() {
return type;
}
public void setType(PTYPE type) {
if (this.type == null)
this.type = type;
}
public void setByteArr(byte[] b) {
this.buf = b;
}
public void setMilli(int milliseconds) {
this.milliseconds = milliseconds;
}
public void diag(){
System.out.println("|-- Tag Type: " + type);
System.out.println("|-- Milliseconds: " + milliseconds);
System.out.println("|-- Size: " + buf.length);
System.out.println("|-- Bytes: ");
for(int i = 0; i < buf.length; i++){
System.out.print(String.format("%02x ", buf[i]));
if (((i % 8) == 0 ) && i != 0)
System.out.println();
}
System.out.println();
}
}
jFLV.java
import java.net.URISyntaxException;
public class jFLV {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Parser p = null;
try {
p = new Parser(jFLV.class.getResource("sample.flv").toURI());
} catch (URISyntaxException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
p.parse();
}
}
PTYPE.java
public enum PTYPE {
P_HEAD,P_VID,P_AUD,P_DAT
};
Both your use of available() and your call to read are broken. Admittedly I would have somewhat expected this to be okay for a FileInputStream (until you reach the end of the stream, at which point ignoring the return value for read could still be disastrous) but I personally assume that streams can always return partial data.
available() only tells you whether there's any data available right now. It's very rarely useful - just ignore it. If you want to read until the end of the stream, you should usually keep calling read until it returns -1. It's slightly tricky to combine that with "I'm trying to read the next block", admittedly. (It would be nice if InputStream had a peek() method, but it doesn't. You can wrap it in a BufferedInputStream and use mark/reset to test that at the start of each loop... ugly, but it should work.)
Next, you're ignoring the result of InputStream.read (in multiple places). You should always use the result of this, rather than assuming it has read the amount of data you've asked for. You might want a couple of helper methods, e.g.
static byte[] readExactly(InputStream input, int size) throws IOException {
byte[] data = new byte[size];
readExactly(input, data);
return data;
}
static void readExactly(InputStream input, byte[] data) throws IOException {
int index = 0;
while (index < data.length) {
int bytesRead = input.read(data, index, data.length - index);
if (bytesRead < 0) {
throw new EOFException("Expected more data");
}
}
}
You should use one of the read methods instead of available, as available() "Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream."
It is not designed to check how long you can read.
I've implemented a Huffman coding in java, that works on byte data from an input file. However, it only works when compressing ascii. I'd like to extend it so that it can deal with characters that are larger than 1 byte long, but I'm not sure how to do this exactly.
private static final int CHARS = 256;
private int [] getByteFrequency(File f) throws FileNotFoundException {
try {
FileInputStream fis = new FileInputStream(f);
byte [] bb = new byte[(int) f.length()];
int [] aa = new int[CHARS];
if(fis.read(bb) == bb.length) {
System.out.print("Uncompressed data: ");
for(int i = 0; i < bb.length; i++) {
System.out.print((char) bb[i]);
aa[bb[i]]++;
}
System.out.println();
}
return aa;
} catch (FileNotFoundException e) { throw new FileNotFoundException();
} catch (IOException e) { e.printStackTrace(); }
return null;
}
For example, this is what I'm using to get the frequency of the characters in the file, and obviously it only works on a single byte. If I give it a unicode file, I get an ArrayIndexOutOfBoundsException at aa[bb[i]]++;, and i is normally a negative number. I know this is because aa[bb[i]]++; is only looking at one byte, and the unicode character will be more than one, but I'm not sure on how I can change it.
Can anybody give me some pointers?
Try the following:
private static final int CHARS = 256;
private int [] getByteFrequency(File f) throws FileNotFoundException {
try {
FileInputStream fis = new FileInputStream(f);
byte [] bb = new byte[(int) f.length()];
int [] aa = new int[CHARS];
if(fis.read(bb) == bb.length) {
System.out.print("Uncompressed data: ");
for(int i = 0; i < bb.length; i++) {
System.out.print((char) bb[i]);
aa[((int)bb[i])&0xff]++;
}
System.out.println();
}
return aa;
} catch (FileNotFoundException e) { throw new FileNotFoundException();
} catch (IOException e) { e.printStackTrace(); }
return null;
}
If i'm correct (I haven't tested it), your problem is that byte is a SIGNED value in java. The cast to integer + masking it to 0xff should handle it correctly.