I have a program that changes the DCT coefficients of a JPG image.
This is the code that gives me the DCT coefficients
public int[] quantizeBlock(double inputData[][], int code) {
int outputData[] = new int[blockSize * blockSize];
int i, j;
int index;
index = 0;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
// The second line results in significantly better compression.
outputData[index] = (int) (Math.round(inputData[i][j]
* (((double[]) (Divisors[code]))[index])));
// outputData[index] = (int)(((inputData[i][j] * (((double[])
// (Divisors[code]))[index])) + 16384.5) -16384);
index++;
}
}
return outputData;
}
This is a DCT matrix before modifications
-43 7 0 0 0 0 0 0
-8 1 2 -1 0 0 0 0
-1 -1 -1 1 0 0 0 0
-2 1 0 -1 0 0 0 0
6 0 0 0 0 0 0 0
-2 0 1 0 0 0 0 0
-1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
This is after the modifications
-42 8 0 0 0 0 0 0
-7 1 3 0 0 0 0 0
0 0 0 1 0 0 0 0
-1 1 0 0 0 0 0 0
7 0 0 0 0 0 0 0
-1 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0
After I save the image using image Buffer,I use the created image to get back the modified DCT from it but all I get is:
-41 9 0 0 0 0 0 0
-6 1 4 0 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0
8 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
I've seen a question where the user using a library in IOS did the same thing and had the same problem.Apparently the library recopressed the image and the hidden message was destroyed.
I don't know if this is the case for me.I use Image Buffer to create the image.
A couple things off the top that could be happening. The first is rounding errors. The JPEG process introduces small errors. All your values are one off. This could come from rounding.
The second is quantization. Your values may be quantized (divided). Your example does not indicate the compression stages that may be taking place in between your examples.
Related
I want to change the values of a 2d array from a given starting position (rowPos and colPos) for a certain amount of rows and columns.
So far I have the code below:
int[][] block = new int[10][10];
int rowPos = 3, colPos = 3;
int rows = 4, columns = 4;
for (int i = rowPos; i < rows; i++)
for (int j = colPos; j < columns; j++)
block[i][j] = 1;
for (int[] x : block) {
for (int y : x)
System.out.print(y + " ");
System.out.println();
}
However this gives me the following output:
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
It is only setting the value at rowPos and colPos. This is my expected output:
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
I feel like I'm close but missing something small, please help me!
Change the loops to this:
for (int i = rowPos; i < rows + rowPos; i++)
for (int j = colPos; j < columns + colPos; j++)
block[i][j] = 1;
In your code, you let i and j start at the row and column you want to begin changing the values. That's fine, but it also means your condition doesn't work anymore. Let me show you what happens:
You declare i and set it's value to 3.
You check if i (3) is less than rows (4). Success!
You declare j and set it's value to 3.
You check if j (3) is less than columns (4). Success!
You set block[3][3] to 1.
j is incremented by 1 and is now 4.
You check if j (4) is less than columns (4). Fail!
i is incremented by 1 and is now 4.
You check if i (4) is less than rows (4). Fail!
You print the array's contents.
The problem is that because you start i and j at values greater than 0, you need to keep that in mind when performing the check.
I am creating a Game of Life program that accepts user input patterns, using java.util.Scanner and java.io.File
The main issue is that I cannot seem to get the program to read the pattern.txt file...
I do not see any issue, the pattern.txt is in the same folder as the .java and .class files when I compile them.
Am I using File and Scanner correctly?
I've tried reordering the import statements, changing try & catch structure, and creating a new File(//..Path/../pattern.txt) to directly call the file via the relative path
1.txt is the pattern file:
20 20
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
`
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public static void main(String [] args) throws FileNotFoundException{
String inputFileName = "1.txt"; // Directly setting relative path
int [][] initStates = getInitialStates(inputFileName);
Grid gd = new Grid(initStates);
gd.display();
gd.getStats();
gd.run();
}
public static int [][] getInitialStates(String fileName) {
try {
File file = new File(fileName);
// checks to see if file was created
// if (file.exists())
// System.out.println("FILE EXISTS");
// else
// System.out.println("FILENOTFOUDN");
Scanner input = new Scanner(file); // Create scanner to read file
int[][] states = null;
int rows = input.nextInt(); // get rows and cols values from first values of text file
int cols = input.nextInt();
// states = new int[rows][cols]; // Create 2d array w/ rows and cols
states = new int[rows][cols];
// for (int i = 0; i < rows; i++) {
// states[i] = new int[cols];
// }
// Read initial states from the input file
for (int i = 0; i < states.length; i++) {
for (int j = 0; j < states[0].length; j++) {
states[i][j] = input.nextInt();
}
}
return states;
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
// return states;
}
`
Error output is FileNotFoundException printing the stack trace:
java.io.FileNotFoundException: 1.txt (No such file or directory)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
at java.base/java.util.Scanner.<init>(Scanner.java:639)
at client.getInitialStates(client.java:67)
at client.main(client.java:24)
Exception in thread "main" java.lang.NullPointerException
at Grid.<init>(Grid.java:14)
at client.main(client.java:26)
I get the NullPointerException because the getInitialStates() method isn't returning the 2d array because it cannot read the file.
If as per comment a FileNotFoundException is thrown, it means that the working directory of your program (i.e. directory where java YourMainClassName is invoked) is different from location of the file you're trying to open by its name.
You can check the working directory:
System.out.println("Working Directory = " + System.getProperty("user.dir"));
As described in this answer: https://stackoverflow.com/a/7603444/1083697
i have go through the previous answers but nothing like what i am looking for, specifically in java. here is my code, the block of my code can read a singe character integer only which is not exactly what i intend to do, i intends to reads more than one char integer, it doesn't work. and i want reads only 16 lines and 16 integers in a line from the file even if the file contains more than 16 lines and more than 16 integers per line. can some one share an idea with me please?
Here is sample input data:
13 20 0 0 0 0 0 0 0 0 0 0 11 2
0 0 0 0 0 0 0 0 0 4 5 0 0 11 2
0 0 0 0 0 0 0 0 0 333 4 0 0 0 0
0 0 0 0 0 0 0 0 0 9 10 41 3 5 8
0 0 0 0 0 0 0 0 0 0 11 2 333 4
13 20 0 0 0 0 0 0 0 0 0 0 11 2
0 0 0 0 0 0 0 0 0 4 5 0 0 11 2
0 0 0 0 0 0 0 0 0 333 4 0 0 0 0
0 0 0 0 0 0 0 0 0 9 10 41 3 5 8
0 0 0 0 0 0 0 0 0 0 11 2 333 4
13 20 0 0 0 0 0 0 0 0 0 0 11 2
0 0 0 0 0 0 0 0 0 4 5 0 0 11 2
0 0 0 0 0 0 0 0 0 333 4 0 0 0 0
0 0 0 0 0 0 0 0 0 9 10 41 3 5 8
0 0 0 0 0 0 0 0 0 0 11 2 333 4
13 20 0 0 0 0 0 0 0 0 0 0 11 2
0 0 0 0 0 0 0 0 0 4 5 0 0 11 2
0 0 0 0 0 0 0 0 0 333 4 0 0 0 0
0 0 0 0 0 0 0 0 0 9 10 41 3 5 8
0 0 0 0 0 0 0 0 0 0 11 2 333 4
i just want insert this into the 2dimentional array as you can see in my code, but my array is 16X16 but the file may be more than 16x16 in size, but i just want reads just 16x16 even if the file contains more than that, and ignore the empty line even if it exist.
BufferedReader bufferedReader = new BufferedReader(new FileReader("text.txt"));
String line = null;
int[][] board = new int[16][16];
int k = 0;
while((line = bufferedReader.readLine())!=null) {
String[] newmatrix = line.split(" ");
for(int i=0; i<9; i++) {
board[k][i] = Integer.parseInt(newmatrix[i]);
}
k++;
}
This appears to be "a learning exercise". So, hints / advice only1:
To stop reading after 16 lines, use a counter.
Skip an empty line by testing for an empty line.
Use a Scanner (hasNextInt() and nextInt() to process each line.
It is a good idea to avoid hard-wiring literal constants into your code ... like 9 which you seem to have pulled out of the air.
Use board.length - 1 or board[i].length - 1 for your array bounds when "looping". (See previous)
Also ... your input file seems to only have 14 integers per line, not 16 as the question states.
1 ... because you will learn more by coding this yourself.
The code below should work.
BufferedReader bufferedReader = new BufferedReader(new FileReader("text.txt"));
String line = null;
int[][] board = new int[16][16];
int k = 0;
while((line = bufferedReader.readLine())!=null) {
String[] newmatrix = line.split(" ");
for(int i = 0; i < 16; i++) {
board[k][i] = Integer.parseInt(newmatrix[i]);
}
k++;
if (k == 16)
break;
}
bufferedReader.close();
So I'm trying to implement Dijkstra's algorithm in Java. I know there are different ways to do it but here's the way that I've learned to do it. So I start with a single vertex and I find the shortest path from that vertex to every other vertex. I start with a single vertex (in my case it's zero) and then update my neighborhood by relaxing all the edges connected to that vertex. I then find out what's the smallest edge that connects to the current edge and then I add that vertex to my vertex storage. I keep doing that until all the vertices are in my vertex storage and then I should end up with a type of spanning tree that shows me all the shortest paths.
So in my code, I'm trying to find the shortest path from 0 to 1. I get the graphs from an adjacency matrix. So what I do is I start at the first row (or the 0th row) and traverse through the row and relax the vertices in a matrix called N. I then find the smallest edge coming out of whatever vertices I have stored in my vertex storage and then contnue adding vertices and relaxing the edges. So then I have two main arrays called N (where I store the weights of the shortest paths) and edgeStorage. Here's what it looks like:
static int ShortestPath(int[][] G){
int numVerts = G.length;
int totalWeight = 0;
int minWeight;
int count = 1;
int k = 0;
int l = 0;
int next = 1;
int i = 0;
int[] N = new int[numVerts];
int[] edgeStorage = new int[numVerts];
Arrays.fill(N, 2147483647); //2147483647 is my infinity to represent vertices that haven't yet been relaxed
N[0] = 0;
while (count != numVerts){
for (int j = 0; j < numVerts; j++){
if ((G[i][j] != 0) && (N[i] + G[i][j] < N[j])){
N[j] = N[i] + G[i][j];
}
}
minWeight = 2147483647;
for (int p = 0; p < count; p++){ //find min edge weight for vertices in storage
i = edgeStorage[p];
for (int j = 0; j < numVerts; j++){
if ((G[i][j] != 0) && (G[i][j] < minWeight)){
minWeight = G[i][j];
k = j;
l = i;
}
}
}
G[l][k] = 0; //remove edge since we don't need it anymore
G[k][l] = 0;
edgeStorage[next] = k; //store vertex location in array
i = k;
count++;
next++;
}
totalWeight = N[1];
return totalWeight;
}
The problem is this code works for some graphs but for others it gives me a weight that's bigger than it's supposed to be. I tested it on a graph of 25 vertices which looked like this:
0 0 0 0 0 0 418 0 0 0 0 0 0 0 472 0 0 0 0 0 0 0 0 537 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 191 375 161 0
0 0 0 0 0 0 0 0 0 0 0 0 108 0 0 0 512 0 311 0 0 0 0 0 0
0 0 0 0 0 0 0 0 612 0 0 0 0 0 0 0 0 0 0 0 583 0 0 0 0
0 0 0 0 0 0 365 0 0 0 0 0 0 0 0 262 243 0 0 0 0 617 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 581 0 0 0 0 0 0 0 0 0 0 0
418 0 0 0 365 0 0 0 0 0 0 338 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 320 0 517 0 0 0 0 0 0 0 524 0 314 0 0 0 0
0 0 0 612 0 0 0 320 0 0 0 0 0 0 0 0 577 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 145 414 0 0 35 0 0 0 0 0 0 394 0 0
0 0 0 0 0 0 0 517 0 0 0 0 0 0 0 0 0 353 0 0 0 0 0 0 0
0 0 0 0 0 0 338 0 0 145 0 0 0 0 0 0 0 0 0 344 0 0 0 0 0
0 0 108 0 0 0 0 0 0 414 0 0 0 0 0 0 0 607 0 0 0 0 0 0 0
0 0 0 0 0 581 0 0 0 0 0 0 0 0 0 0 0 0 0 609 0 0 231 0 0
472 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 478 0 0 0 0 0 0 0
0 0 0 0 262 0 0 0 0 35 0 0 0 0 0 0 0 0 0 0 280 0 0 0 0
0 0 512 0 243 0 0 0 577 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 353 0 607 0 478 0 0 0 0 0 0 0 0 594 0
0 0 311 0 0 0 0 524 0 0 0 0 0 0 0 0 0 0 0 0 0 471 0 0 306
0 0 0 0 0 0 0 0 0 0 0 344 0 609 0 0 0 0 0 0 0 0 0 0 0
0 0 0 583 0 0 0 314 0 0 0 0 0 0 0 280 0 0 0 0 0 0 0 0 214
0 191 0 0 617 0 0 0 0 0 0 0 0 0 0 0 0 0 471 0 0 0 0 0 0
0 375 0 0 0 0 0 0 0 394 0 0 0 231 0 0 0 0 0 0 0 0 0 0 0
537 161 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 594 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 306 0 214 0 0 0 0
My N array looked like this:
0 1670 1538 1799 783 2107 418 1530 1603 901 2047 756 1315 1526 472 936 1026 950 1736 1100 1216 1400 1295 537 1430
and my edgeStorage array looked like this:
0 6 11 9 15 4 16 20 24 18 2 12 7 8 19 4 22 13 1 23 21 12 21 14 17
So therefore it returned 1670 as the path between 0 and 1 when it should've returned 698. I have no idea why it gives me the wrong weight for some graphs but the right weight for others. So does anyone know what's wrong with my code?
P.S: I know my implementation is not the most efficient thing right now but I just want to get the basic implementation working and then I'll work on making it more efficient.
I don't understand why this cannot work, if anyone could help that would be great;
for(int i = 0; i < 10 ; i++){
lines = fileL[i];
for(int j = 0; j < lines.length(); j++){
enemySpawningL[i][j] = fileL[i].substring(j*2, 1);
}
}
where enemySpawning[][] has been set as a string and fileL is set as this;
private String[] fileL = {
"1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1",
"1 0 0 0 0 1 0 0 0 0 1 0 0 2 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 2 0 0 1 0 0 0 0 1 0 0 0 0 1",
"1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1",
"1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1",
"1 0 0 0 0 1 0 0 2 0 1 0 0 0 0 1 0 2 0 0 1 0 0 0 0 1 0 0 2 0 1 0 0 0 0 1 0 2 0 0 1 0 0 0 0 1 0 2",
"1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 0 0 1",
"1 0 3 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 0 0 1 0 2 0 1 0 3 0 1",
"1 0 0 0 2 0 0 0 1 0 0 0 3 0 0 0 1 0 0 0 2 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 3 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 2 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 3 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 2 0 0 0 1",
"2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3 0 2 0 0 3",
"2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 2",
};
(I tried using a textfile for it, but I didn't think there was a point cause it's not too important)
EDIT: I'm just trying to make the enemySpawning list be [line number][number in line]
EDIT2: Also the error I'm getting is java.lang.NullPointerException
The error is probably because you didn't initialize enemySpawningL.
String[][] enemySpawningL = new String[rowsNum][columnsNum];
And if I understand correctly what you are trying to do change your code to
for(int i = 0 ; i < 10 ; ++i) {
String[] digits = fileL[i].split(" ");
for(int j = 0 ; j < digits.length ; ++j) {
enemySpawningL[i][j] = digits[j];
}
}
That will give you one digit in every cell. Currently your substring() is wrong as the start point is bigger than the end point for j > 0 and if you change the order you insert string with several digits every time.
"1"
"1 0"
"1 0 0"
....
The problem is, as #guy mentioned, not initializing the array, but there is also another error in here:
enemySpawningL[i][j] = fileL[i].substring(j*2, 1);
Because 'j' can have maximal value of fileL[i] length, if you request index j*2, in half of the loop it will be out of bound. You are also using the substring method in incorrect way. How you want you loop to look like is:
for(int j = 0; j < lines.length(); j += 2){
enemySpawningL[i][j] = fileL[i].substring(j, j+1);
}
The j variable is now incremented by two every iteration (to skip spaces) and substring will return one character from position j of the string file[L]. Which is what you wanted.