Skip to content

Commit d446823

Browse files
committed
Initial commit
0 parents  commit d446823

21 files changed

+695
-0
lines changed

Diff for: .classpath

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="src" path="src"/>
4+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
5+
<classpathentry kind="lib" path="/Util/lib/jsr166y.jar"/>
6+
<classpathentry combineaccessrules="false" kind="src" path="/Util"/>
7+
<classpathentry kind="lib" path="/Util/lib/extra166y.jar"/>
8+
<classpathentry kind="lib" path="/Util/lib/imunit-1.3.jar"/>
9+
<classpathentry kind="output" path="bin"/>
10+
</classpath>

Diff for: .gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
*.class

Diff for: .project

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>Blender</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.eclipse.jdt.core.javanature</nature>
16+
</natures>
17+
</projectDescription>

Diff for: .settings/org.eclipse.jdt.core.prefs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#Sun Sep 18 22:52:07 CDT 2011
2+
eclipse.preferences.version=1
3+
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
4+
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
5+
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6+
org.eclipse.jdt.core.compiler.compliance=1.6
7+
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8+
org.eclipse.jdt.core.compiler.debug.localVariable=generate
9+
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10+
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
11+
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
12+
org.eclipse.jdt.core.compiler.source=1.6

Diff for: README

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
Blend Images
3+
------------
4+
This application "blends" two images producing a third.

Diff for: img/40c.jpg

778 KB
Loading

Diff for: img/a.jpg

261 KB
Loading

Diff for: img/aSmall.jpg

40 KB
Loading

Diff for: img/b.jpg

181 KB
Loading

Diff for: img/bSmall.jpg

31.1 KB
Loading

Diff for: img/blended.jpg

69.8 KB
Loading

Diff for: img/c.jpg

1.65 MB
Loading

Diff for: img/d.jpg

1.14 MB
Loading

Diff for: img/dreamliner.jpg

667 KB
Loading

Diff for: src/blender/Blender.java

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package blender;
2+
3+
import java.awt.image.BufferedImage;
4+
import java.awt.image.MemoryImageSource;
5+
import java.beans.PropertyChangeEvent;
6+
import java.beans.PropertyChangeListener;
7+
import java.util.HashSet;
8+
import java.util.Set;
9+
10+
import util.Timer;
11+
12+
public abstract class Blender implements Runnable{
13+
protected final BufferedImage img1;
14+
protected final BufferedImage img2;
15+
protected final GUI window;
16+
protected int[] imageBuffer;
17+
protected MemoryImageSource imageSource;
18+
protected final int height;
19+
protected final int width;
20+
private long runtime;
21+
22+
protected static final double weight = 0.5;
23+
24+
public Blender(BufferedImage img1, BufferedImage img2, GUI window,
25+
int[] imageBuffer, MemoryImageSource imageSource) {
26+
this.img1 = img1;
27+
this.img2 = img2;
28+
this.window = window;
29+
this.imageBuffer = imageBuffer;
30+
this.imageSource = imageSource;
31+
this.height = img1.getHeight();
32+
this.width = img1.getWidth();
33+
}
34+
35+
@Override
36+
public void run() {
37+
Timer.start();
38+
process();
39+
Timer.stop();
40+
runtime = Timer.getRuntime();
41+
notifyListeners();
42+
}
43+
44+
private void notifyListeners() {
45+
PropertyChangeEvent e = new PropertyChangeEvent(this, "runtime", 0, runtime);
46+
for(PropertyChangeListener l: listeners)
47+
l.propertyChange(e);
48+
}
49+
50+
public abstract void process();
51+
52+
Set<PropertyChangeListener> listeners = new HashSet<PropertyChangeListener>();
53+
54+
public void addPropertyChangeListener(
55+
PropertyChangeListener propertyChangeListener) {
56+
this.listeners.add(propertyChangeListener);
57+
}
58+
}

Diff for: src/blender/GUI.java

+253
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
package blender;
2+
3+
import java.awt.BorderLayout;
4+
import java.awt.Dimension;
5+
import java.awt.Graphics;
6+
import java.awt.Graphics2D;
7+
import java.awt.GridLayout;
8+
import java.awt.Image;
9+
import java.awt.event.ActionEvent;
10+
import java.awt.event.ActionListener;
11+
import java.awt.image.BufferedImage;
12+
import java.awt.image.MemoryImageSource;
13+
import java.beans.PropertyChangeEvent;
14+
import java.beans.PropertyChangeListener;
15+
import java.io.File;
16+
import java.io.IOException;
17+
18+
import javax.imageio.ImageIO;
19+
import javax.swing.ImageIcon;
20+
import javax.swing.JButton;
21+
import javax.swing.JFrame;
22+
import javax.swing.JLabel;
23+
import javax.swing.JPanel;
24+
25+
import util.Timer;
26+
27+
import blender.parallel.BlenderParallel;
28+
import blender.sequential.BlenderSequential;
29+
import blender.thread.pool.BlenderPool;
30+
import blender.threads.BlenderThreads;
31+
32+
public class GUI extends JFrame {
33+
private static final long serialVersionUID = 1L;
34+
35+
/* Configuration */
36+
private Dimension displaySize = new Dimension(400, 300);
37+
private String imgFile1Path = "img/40c.jpg";
38+
private String imgFile2Path = "img/dreamliner.jpg";
39+
/* ************** */
40+
41+
private BufferedImage img1;
42+
private BufferedImage img2;
43+
44+
private Dimension imageSize;
45+
private ImagePanel img1Panel;
46+
private ImagePanel img2Panel;
47+
ImagePanel resultImagePanel;
48+
public ImageIcon icon;
49+
50+
private int[] resultBuffer;
51+
private MemoryImageSource resultImageSource;
52+
53+
public GUI() {
54+
super("Blender");
55+
56+
initFrame();
57+
setVisible(true);
58+
}
59+
60+
public void initFrame() {
61+
62+
try {
63+
setDefaultCloseOperation(EXIT_ON_CLOSE);
64+
setLayout(new BorderLayout());
65+
add(getImagesPanel(), BorderLayout.CENTER);
66+
add(getInfoPanel(), BorderLayout.SOUTH);
67+
68+
pack();
69+
} catch (IOException e) {
70+
// TODO Auto-generated catch block
71+
e.printStackTrace();
72+
}
73+
74+
}
75+
76+
private JPanel getImagesPanel() throws IOException {
77+
JPanel imgPanels = new JPanel();
78+
img1Panel = new ImagePanel();
79+
imgPanels.add(img1Panel);
80+
img2Panel = new ImagePanel();
81+
imgPanels.add(img2Panel);
82+
resultImagePanel = new ImagePanel();
83+
imgPanels.add(resultImagePanel);
84+
85+
initImagePanels();
86+
87+
resultBuffer = new int[imageSize.height * imageSize.width];
88+
resultImageSource = new MemoryImageSource(imageSize.width,
89+
imageSize.height, resultBuffer, 0, imageSize.width);
90+
91+
resultImageSource.setAnimated(true);
92+
resultImagePanel.setImage(resultImagePanel
93+
.createImage(resultImageSource));
94+
95+
resetResultsPanel();
96+
97+
return imgPanels;
98+
}
99+
100+
private JPanel getInfoPanel() {
101+
102+
JPanel infoPanel = new JPanel();
103+
infoPanel.setLayout(new GridLayout(5, 1));
104+
105+
// Sequential
106+
Blender sequentialBlender = new BlenderSequential(img1, img2,
107+
getFrame(), resultBuffer, resultImageSource);
108+
infoPanel.add(getPanelFor("Sequential", sequentialBlender));
109+
110+
// Sequential
111+
Blender threadsBlender = new BlenderThreads(img1, img2, getFrame(),
112+
resultBuffer, resultImageSource);
113+
infoPanel.add(getPanelFor("Threads", threadsBlender));
114+
115+
// Pool
116+
Blender poolBlender = new BlenderPool(img1, img2, getFrame(),
117+
resultBuffer, resultImageSource);
118+
infoPanel.add(getPanelFor("Thread pool", poolBlender));
119+
120+
// Pool
121+
Blender forkJoinBlender = new BlenderPool(img1, img2, getFrame(),
122+
resultBuffer, resultImageSource);
123+
infoPanel.add(getPanelFor("ForkJoin", forkJoinBlender));
124+
125+
Blender parallelBlender = new BlenderParallel(img1, img2, getFrame(),
126+
resultBuffer, resultImageSource);
127+
infoPanel.add(getPanelFor("Parallel", parallelBlender));
128+
129+
return infoPanel;
130+
}
131+
132+
private JPanel getPanelFor(String string, Blender blenderProcess) {
133+
JPanel panel = new JPanel();
134+
135+
JButton button = new JButton(string);
136+
button.setPreferredSize(new Dimension(200, 25));
137+
panel.add(button);
138+
139+
JLabel runtimeLabel = new JLabel();
140+
runtimeLabel.setPreferredSize(new Dimension(100, 25));
141+
panel.add(runtimeLabel);
142+
143+
JLabel speedupLabel = new JLabel();
144+
speedupLabel.setPreferredSize(new Dimension(100, 25));
145+
panel.add(speedupLabel);
146+
147+
ActionListener listener = new ButtonListener(blenderProcess, runtimeLabel, speedupLabel);
148+
button.addActionListener(listener);
149+
150+
return panel;
151+
}
152+
153+
public void resetResultsPanel() {
154+
for (int row = 0; row < imageSize.height; row++) {
155+
for (int col = 0; col < imageSize.width; col++) {
156+
resultBuffer[row * imageSize.width + col] = java.awt.Color.WHITE
157+
.getRGB();
158+
}
159+
}
160+
resultImageSource.newPixels();
161+
}
162+
163+
public void initImagePanels() throws IOException {
164+
img1 = ImageIO.read(new File(imgFile1Path));
165+
img2 = ImageIO.read(new File(imgFile2Path));
166+
167+
168+
Graphics2D g2d = img1.createGraphics();
169+
g2d.drawImage(img1, 0, 0, null);
170+
g2d.dispose();
171+
172+
g2d = img2.createGraphics();
173+
g2d.drawImage(img2, 0, 0, null);
174+
g2d.dispose();
175+
imageSize = new Dimension(img1.getWidth(), img1.getHeight());
176+
177+
img1Panel.setImage(img1);
178+
img2Panel.setImage(img2);
179+
}
180+
181+
public GUI getFrame() {
182+
return this;
183+
}
184+
185+
protected long sequentialRuntime;
186+
private final class ButtonListener implements ActionListener {
187+
private final Blender blenderProcess;
188+
private final JLabel runtimeLabel;
189+
private final JLabel speedupLabel;
190+
191+
public ButtonListener(Blender blenderProcess, JLabel runtimeLabel, JLabel speedupLabel) {
192+
this.runtimeLabel = runtimeLabel;
193+
194+
this.blenderProcess = blenderProcess;
195+
this.speedupLabel = speedupLabel;
196+
197+
runtimeLabel.setText(Timer.getRuntime()+"ms");
198+
}
199+
200+
@Override
201+
public void actionPerformed(ActionEvent arg0) {
202+
resetResultsPanel();
203+
this.blenderProcess.addPropertyChangeListener(new PropertyChangeListener() {
204+
@Override
205+
public void propertyChange(PropertyChangeEvent e) {
206+
Long runtime = (Long) e.getNewValue();
207+
if(e.getSource() instanceof BlenderSequential)
208+
sequentialRuntime = (Long) runtime;
209+
runtimeLabel.setText(runtime+"ms");
210+
if(sequentialRuntime > 0) {
211+
double speedup = sequentialRuntime*1.0/runtime;
212+
String speedupText = String.format("%.2f", speedup);
213+
speedupLabel.setText(speedupText+"x");
214+
}
215+
}
216+
});
217+
Thread t = new Thread(this.blenderProcess);
218+
t.start();
219+
}
220+
}
221+
222+
class ImagePanel extends JPanel {
223+
224+
private static final long serialVersionUID = -6160628506441192086L;
225+
private Image img;
226+
227+
public ImagePanel() {
228+
setPreferredSize(displaySize);
229+
230+
}
231+
232+
public void setImage(Image img) {
233+
this.img = img;
234+
repaint();
235+
}
236+
237+
public void paintComponent(Graphics g) {
238+
if (img != null) {
239+
Dimension size = getSize();
240+
g.drawImage(img, 0, 0, size.width, size.height, 0, 0,
241+
img.getWidth(null), img.getHeight(null), this);
242+
}
243+
}
244+
}
245+
246+
public static void main(String[] args) {
247+
248+
@SuppressWarnings("unused")
249+
GUI window = new GUI();
250+
251+
}
252+
253+
}

0 commit comments

Comments
 (0)