diff --git a/.classpath b/.classpath
index eebe9ca..98de9f8 100644
--- a/.classpath
+++ b/.classpath
@@ -3,5 +3,6 @@
+
diff --git a/lib/sanselan-0.97-incubator.jar b/lib/sanselan-0.97-incubator.jar
new file mode 100644
index 0000000..fff931f
Binary files /dev/null and b/lib/sanselan-0.97-incubator.jar differ
diff --git a/src/JpegReader.java b/src/JpegReader.java
new file mode 100644
index 0000000..6e88d20
--- /dev/null
+++ b/src/JpegReader.java
@@ -0,0 +1,174 @@
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorConvertOp;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.imageio.IIOException;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+
+import org.apache.sanselan.ImageReadException;
+import org.apache.sanselan.Sanselan;
+import org.apache.sanselan.common.byteSources.ByteSource;
+import org.apache.sanselan.common.byteSources.ByteSourceFile;
+import org.apache.sanselan.formats.jpeg.JpegImageParser;
+import org.apache.sanselan.formats.jpeg.segments.UnknownSegment;
+
+public class JpegReader {
+
+ public static final int COLOR_TYPE_RGB = 1;
+ public static final int COLOR_TYPE_CMYK = 2;
+ public static final int COLOR_TYPE_YCCK = 3;
+
+ private int colorType = COLOR_TYPE_RGB;
+ private boolean hasAdobeMarker = false;
+
+ public BufferedImage readImage(File file) throws IOException,
+ ImageReadException {
+ colorType = COLOR_TYPE_RGB;
+ hasAdobeMarker = false;
+
+ ImageInputStream stream = ImageIO.createImageInputStream(file);
+ Iterator iter = ImageIO.getImageReaders(stream);
+ while (iter.hasNext()) {
+ ImageReader reader = iter.next();
+ reader.setInput(stream);
+
+ BufferedImage image;
+ ICC_Profile profile = null;
+ try {
+ image = reader.read(0);
+ } catch (IIOException e) {
+ colorType = COLOR_TYPE_CMYK;
+ checkAdobeMarker(file);
+ profile = Sanselan.getICCProfile(file);
+ WritableRaster raster = (WritableRaster) reader.readRaster(0,
+ null);
+ if (colorType == COLOR_TYPE_YCCK)
+ convertYcckToCmyk(raster);
+ if (hasAdobeMarker)
+ convertInvertedColors(raster);
+ image = convertCmykToRgb(raster, profile);
+ }
+
+ return image;
+ }
+
+ return null;
+ }
+
+ public void checkAdobeMarker(File file) throws IOException,
+ ImageReadException {
+ JpegImageParser parser = new JpegImageParser();
+ ByteSource byteSource = new ByteSourceFile(file);
+ @SuppressWarnings("rawtypes")
+ ArrayList segments = parser.readSegments(byteSource,
+ new int[] { 0xffee }, true);
+ if (segments != null && segments.size() >= 1) {
+ UnknownSegment app14Segment = (UnknownSegment) segments.get(0);
+ byte[] data = app14Segment.bytes;
+ if (data.length >= 12 && data[0] == 'A' && data[1] == 'd'
+ && data[2] == 'o' && data[3] == 'b' && data[4] == 'e') {
+ hasAdobeMarker = true;
+ int transform = app14Segment.bytes[11] & 0xff;
+ if (transform == 2)
+ colorType = COLOR_TYPE_YCCK;
+ }
+ }
+ }
+
+ public static void convertYcckToCmyk(WritableRaster raster) {
+ int height = raster.getHeight();
+ int width = raster.getWidth();
+ int stride = width * 4;
+ int[] pixelRow = new int[stride];
+ for (int h = 0; h < height; h++) {
+ raster.getPixels(0, h, width, 1, pixelRow);
+
+ for (int x = 0; x < stride; x += 4) {
+ int y = pixelRow[x];
+ int cb = pixelRow[x + 1];
+ int cr = pixelRow[x + 2];
+
+ int c = (int) (y + 1.402 * cr - 178.956);
+ int m = (int) (y - 0.34414 * cb - 0.71414 * cr + 135.95984);
+ y = (int) (y + 1.772 * cb - 226.316);
+
+ if (c < 0)
+ c = 0;
+ else if (c > 255)
+ c = 255;
+ if (m < 0)
+ m = 0;
+ else if (m > 255)
+ m = 255;
+ if (y < 0)
+ y = 0;
+ else if (y > 255)
+ y = 255;
+
+ pixelRow[x] = 255 - c;
+ pixelRow[x + 1] = 255 - m;
+ pixelRow[x + 2] = 255 - y;
+ }
+
+ raster.setPixels(0, h, width, 1, pixelRow);
+ }
+ }
+
+ public static void convertInvertedColors(WritableRaster raster) {
+ int height = raster.getHeight();
+ int width = raster.getWidth();
+ int stride = width * 4;
+ int[] pixelRow = new int[stride];
+ for (int h = 0; h < height; h++) {
+ raster.getPixels(0, h, width, 1, pixelRow);
+ for (int x = 0; x < stride; x++)
+ pixelRow[x] = 255 - pixelRow[x];
+ raster.setPixels(0, h, width, 1, pixelRow);
+ }
+ }
+
+ public static BufferedImage convertCmykToRgb(Raster cmykRaster,
+ ICC_Profile cmykProfile) throws IOException {
+ if (cmykProfile == null)
+ cmykProfile = ICC_Profile.getInstance(JpegReader.class
+ .getResourceAsStream("/ISOcoated_v2_300_eci.icc"));
+
+ if (cmykProfile.getProfileClass() != ICC_Profile.CLASS_DISPLAY) {
+ byte[] profileData = cmykProfile.getData();
+
+ if (profileData[ICC_Profile.icHdrRenderingIntent] == ICC_Profile.icPerceptual) {
+ intToBigEndian(ICC_Profile.icSigDisplayClass, profileData,
+ ICC_Profile.icHdrDeviceClass); // Header is first
+
+ cmykProfile = ICC_Profile.getInstance(profileData);
+ }
+ }
+
+ ICC_ColorSpace cmykCS = new ICC_ColorSpace(cmykProfile);
+ BufferedImage rgbImage = new BufferedImage(cmykRaster.getWidth(),
+ cmykRaster.getHeight(), BufferedImage.TYPE_INT_RGB);
+ WritableRaster rgbRaster = rgbImage.getRaster();
+ ColorSpace rgbCS = rgbImage.getColorModel().getColorSpace();
+ ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS, rgbCS, null);
+ cmykToRgb.filter(cmykRaster, rgbRaster);
+ return rgbImage;
+ }
+
+ static void intToBigEndian(int value, byte[] array, int index) {
+ array[index] = (byte) (value >> 24);
+ array[index + 1] = (byte) (value >> 16);
+ array[index + 2] = (byte) (value >> 8);
+ array[index + 3] = (byte) (value);
+ }
+}
\ No newline at end of file
diff --git a/src/Main.java b/src/Main.java
index 634e4c1..a6e271a 100644
--- a/src/Main.java
+++ b/src/Main.java
@@ -18,6 +18,7 @@ import java.net.HttpURLConnection;
import java.net.URL;
import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
import javax.swing.JFrame;
import com.google.gson.Gson;
@@ -91,7 +92,7 @@ public class Main extends Canvas implements KeyListener, MouseMotionListener {
for (Image image : response.data) {
if (!(image.nsfw && filterNSFW) && !image.type.equals("image/gif")) {
String url = "http://imgur.com/" + (image.id) + (parseExtension(image.type));
- currentimage = ImageIO.read(new URL(url));
+ currentimage = convertImage(new ImageIcon(new URL(url)).getImage());
currentimage = getScaledImage(currentimage, getWidth(), getHeight());
repaint();
Thread.sleep(SLEEPTIME);
@@ -104,6 +105,12 @@ public class Main extends Canvas implements KeyListener, MouseMotionListener {
}
}
+ private BufferedImage convertImage(java.awt.Image image){
+ BufferedImage buffer = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
+ buffer.getGraphics().drawImage(image, 0, 0, null);
+ return buffer;
+ }
+
private String parseExtension(String type) {
if (type.equals("image/jpeg")) {
return ".jpg";
diff --git a/src/ScrollingMain.java b/src/ScrollingMain.java
index 34bb79d..738803f 100644
--- a/src/ScrollingMain.java
+++ b/src/ScrollingMain.java
@@ -16,13 +16,16 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.ArrayList;
import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
import javax.swing.JFrame;
import com.google.gson.Gson;
-public class ScrollingMain extends Canvas implements KeyListener, MouseMotionListener {
+public class ScrollingMain extends Canvas implements KeyListener,
+ MouseMotionListener {
public static void main(String[] args) {
new ScrollingMain();
}
@@ -43,41 +46,64 @@ public class ScrollingMain extends Canvas implements KeyListener, MouseMotionLis
requestFocus();
// Transparent 16 x 16 pixel cursor image.
- BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
+ BufferedImage cursorImg = new BufferedImage(16, 16,
+ BufferedImage.TYPE_INT_ARGB);
// Create a new blank cursor.
- Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");
+ Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
+ cursorImg, new Point(0, 0), "blank cursor");
// Set the blank cursor to the JFrame.
frame.getContentPane().setCursor(blankCursor);
- int pages = Integer.parseInt(new Variable("imgurscreensaver", "pages", "10", false).getValue());
+ final int pages = Integer.parseInt(new Variable("imgurscreensaver",
+ "pages", "10", false).getValue());
- loopPages(pages, new Variable("imgurscreensaver", "subreddit", "annakendrick", false).getValue());
+ new Thread(new Runnable() {
+ public void run() {
+ loopPages(pages, new Variable("imgurscreensaver", "subreddit",
+ "annakendrick", false).getValue());
+ }
+ }).start();
+ while (true) {
+ try {
+ Thread.sleep(35);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ repaint();
+ }
}
+ private double timeOff = 0;
+
private void loopPages(int pages, String subreddit) {
while (true)
- for (int i = 0; i < pages; i++)
+ for (int page = 0; page < pages; page++)
try {
- String path = "https://api.imgur.com/3/gallery/r/" + subreddit + "/time/" + i + ".json";
+ String path = "https://api.imgur.com/3/gallery/r/"
+ + subreddit + "/time/" + page + ".json";
- HttpURLConnection connection = (HttpURLConnection) ((new URL(path)).openConnection());
+ HttpURLConnection connection = (HttpURLConnection) ((new URL(
+ path)).openConnection());
System.out.println("Connecting...");
connection.setRequestMethod("GET");
// TODO Auto-generated catch block
- connection.addRequestProperty("Authorization", "client-id 76535d44f1f94da");
+ connection.addRequestProperty("Authorization",
+ "client-id 76535d44f1f94da");
connection.connect();
- System.out.println("Response recieved with code " + connection.getResponseCode());
+ System.out.println("Response recieved with code "
+ + connection.getResponseCode());
if (connection.getResponseCode() == 200) {
- InputStream responseStream = connection.getInputStream();
+ InputStream responseStream = connection
+ .getInputStream();
StringBuilder builder = new StringBuilder();
int j = -1;
while ((j = responseStream.read()) != -1)
@@ -86,16 +112,31 @@ public class ScrollingMain extends Canvas implements KeyListener, MouseMotionLis
System.out.println(builder.toString());
Gson gson = new Gson();
- ImageArray response = gson.fromJson(builder.toString(), ImageArray.class);
+ ImageArray response = gson.fromJson(builder.toString(),
+ ImageArray.class);
- for (Image image : response.data) {
- if (!(image.nsfw && filterNSFW) && !image.type.equals("image/gif")) {
- String url = "http://imgur.com/" + (image.id) + (parseExtension(image.type));
- currentimage = ImageIO.read(new URL(url));
- currentimage = getScaledImage(currentimage, getWidth(), getHeight());
- repaint();
+ for (int imageCounter = 0; imageCounter < response.data.length;) {
+
+ Image image = response.data[imageCounter];
+
+ if(image.type.equals("image/gif")) imageCounter ++;
+
+ else if (!(image.nsfw && filterNSFW)
+ && images.size() < 6) {
+ String url = "http://imgur.com/" + (image.id)
+ + (parseExtension(image.type));
+ BufferedImage toAdd = convertImage(new ImageIcon(
+ new URL(url)).getImage());
+ toAdd = getScaledImage(toAdd, getWidth(),
+ getHeight());
+ synchronized (images) {
+ images.add(toAdd);
+ }
+ imageCounter++;
+ } else {
Thread.sleep(SLEEPTIME);
}
+
}
}
@@ -104,6 +145,13 @@ public class ScrollingMain extends Canvas implements KeyListener, MouseMotionLis
}
}
+ private BufferedImage convertImage(java.awt.Image image) {
+ BufferedImage buffer = new BufferedImage(image.getWidth(null),
+ image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
+ buffer.getGraphics().drawImage(image, 0, 0, null);
+ return buffer;
+ }
+
private String parseExtension(String type) {
if (type.equals("image/jpeg")) {
return ".jpg";
@@ -116,9 +164,12 @@ public class ScrollingMain extends Canvas implements KeyListener, MouseMotionLis
}
}
- private boolean filterNSFW = Boolean.parseBoolean(new Variable("imgurscreensaver", "filterNSFW", "true", false).getValue());
- private BufferedImage currentimage;
- private static final long SLEEPTIME = Long.parseLong(new Variable("imgurscreensaver", "SLEEPTIME", "1300", false).getValue());
+ private ArrayList images = new ArrayList();
+
+ private boolean filterNSFW = Boolean.parseBoolean(new Variable(
+ "imgurscreensaver", "filterNSFW", "true", false).getValue());
+
+ private static final long SLEEPTIME = 500;
public void update(Graphics g) {
java.awt.Image buffer = createImage(getWidth(), getHeight());
@@ -127,7 +178,8 @@ public class ScrollingMain extends Canvas implements KeyListener, MouseMotionLis
g.drawImage(buffer, 0, 0, null);
}
- private BufferedImage getScaledImage(BufferedImage image, int width, int height) throws IOException {
+ private BufferedImage getScaledImage(BufferedImage image, int width,
+ int height) throws IOException {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
@@ -136,44 +188,41 @@ public class ScrollingMain extends Canvas implements KeyListener, MouseMotionLis
double scaleX = (double) width / imageWidth;
double aspect = (double) imageWidth / imageHeight;
- double screenAspect = ((double)getWidth()/getHeight());
+ double screenAspect = ((double) getWidth() / getHeight());
System.out.println("" + aspect + "\n" + screenAspect);
// fill or fit bit
-
- if (aspect < screenAspect || aspect > 2)
- if (scaleX > scaleY)
- scaleX = scaleY;
- else
- scaleY = scaleX;
-
- //this is fill. fill if aspect is between screen aspect and 2
+
+ if (scaleX > scaleY)
+ scaleX = scaleY;
else
- if (scaleX < scaleY)
- scaleX = scaleY;
- else
- scaleY = scaleX;
+ scaleY = scaleX;
// give us the transform object thing
- AffineTransform scaleTransform = AffineTransform.getScaleInstance(scaleX, scaleY);
+ AffineTransform scaleTransform = AffineTransform.getScaleInstance(
+ scaleX, scaleY);
// then make the scaling algorithm thing.
- AffineTransformOp bilinearScaleOp = new AffineTransformOp(scaleTransform, AffineTransformOp.TYPE_BILINEAR);
+ AffineTransformOp bilinearScaleOp = new AffineTransformOp(
+ scaleTransform, AffineTransformOp.TYPE_BILINEAR);
// out new image that we need to crop onto the buffer with the right
// dimensions.
- BufferedImage newImage = bilinearScaleOp.filter(image, new BufferedImage((int) (imageWidth * scaleX), (int) (imageHeight * scaleY), image.getType()));
+ BufferedImage newImage = bilinearScaleOp.filter(image,
+ new BufferedImage((int) (imageWidth * scaleX),
+ (int) (imageHeight * scaleY), image.getType()));
// Image newImage = image.getScaledInstance((int) (imageWidth * scaleX),
// (int) (imageWidth * scaleY), Image.SCALE_SMOOTH);
// make the buffer
- BufferedImage buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ BufferedImage buffer = new BufferedImage((int) (imageWidth * scaleX),
+ (int) (imageHeight * scaleY), BufferedImage.TYPE_INT_ARGB);
Graphics g = buffer.getGraphics();
int newImageWidth = newImage.getWidth(null);
int newImageHeight = newImage.getHeight(null);
// do math, shove it on.
- g.drawImage(newImage, (width - newImageWidth) / 2, (height - newImageHeight) / 2, null);
+ g.drawImage(newImage, 0, 0, null);
// return dat
return buffer;
@@ -188,12 +237,24 @@ public class ScrollingMain extends Canvas implements KeyListener, MouseMotionLis
try {
// BufferedImage image = (BufferedImage) ImageIO.read(new
// URL(currentURL));
+ if (images.size() > 0) {
+ g.setColor(Color.BLACK);
+ g.fillRect(0, 0, getWidth(), getHeight());
- g.setColor(Color.BLACK);
- g.fillRect(0, 0, getWidth(), getHeight());
-
- g.drawImage(currentimage, 0, 0, null);
-
+ int xPos = (int) (0 - timeOff);
+ synchronized (images) {
+ for (BufferedImage image : images) {
+ g.drawImage(image, xPos, 0, null);
+ xPos += image.getWidth();
+ }
+ timeOff += 5d;
+ int firstWidth = images.get(0).getWidth();
+ if (timeOff > firstWidth) {
+ timeOff -= firstWidth;
+ images.remove(0);
+ }
+ }
+ }
} catch (Exception e) {
e.printStackTrace();
}