Initial commit.

This commit is contained in:
Woody Folsom
2012-03-06 11:42:35 -05:00
commit 8e83234a87
124 changed files with 9621 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
/**
* Scale2x.java
*
* Written by Markus Persson of Mojang Specifications for a super mario programming contest.
* Implements the Scale2x algorithm described here: http://scale2x.sourceforge.net/algorithm.html
* Works on any input image size, and uses a fancy border hack to prevent range checking.
* It's fast enough for real time use on smaller images (320x240 and thereabouts)
*
* This code is public domain. Do whatever you want with it.
*/
package dk.itu.mario.engine;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
public class Scale2x
{
private int width;
private int height;
private BufferedImage sourceImage;
private int[] sourcePixels;
private Graphics sourceGraphics;
private BufferedImage targetImage;
private int[] targetPixels;
/**
* Creates a new Scale2x object. The new object will scale images of the specified size to images
* that are twice as large.<br>
*
* @param width The width of the images to be scaled
* @param height The height of the images to be scaled
*/
public Scale2x(int width, int height)
{
this.width = width;
this.height = height;
// A border of one pixel in each direction, and one down, to avoid if statements in the scale loop
sourceImage = new BufferedImage(width + 2, height + 3, BufferedImage.TYPE_INT_RGB);
DataBufferInt sourceDataBuffer = (DataBufferInt) sourceImage.getRaster().getDataBuffer();
sourcePixels = sourceDataBuffer.getData();
sourceGraphics = sourceImage.getGraphics();
targetImage = new BufferedImage(width * 2, height * 2, BufferedImage.TYPE_INT_RGB);
DataBufferInt targetDataBuffer = (DataBufferInt) targetImage.getRaster().getDataBuffer();
targetPixels = targetDataBuffer.getData();
}
/**
* Scales an image and returns a twice as large image.<br>
* This assumes the input image is of the dimensions specified in the Scale2x constructor.<br>
* The returned image is a reference to the internal scale target in this Scale2x, so it
* will get changed if you call this method again, so don't hold on to it for too long.<br>
* In other words:<br>
* <code>Image i0 = scale2x.scale(image0);<br>
* Image i1 = scale2x.scale(image1);<br>
* if (i0 == i1) System.exit(0); // Will always terminate</code><br>
*
* @param img The image to be scaled
* @returns A scaled image. If you want that image to survive the next call to this method, make a copy of it.
*/
public Image scale(Image img)
{
// Offset the image by one pixel so there's a border around it.
// This lets us avoid having to check that A-I are in range of the image before samping them
sourceGraphics.drawImage(img, 1, 1, null);
int line = width + 2;
for (int y = 0; y < height; y++)
{
// Two lines of target pixel pointers
int tp0 = y * width * 4 - 1;
int tp1 = tp0 + width * 2;
// Three lines of source pixel pointers
int sp0 = (y) * line;
int sp1 = (y + 1) * line;
int sp2 = (y + 2) * line;
// Fill the initial A-I values
int A = sourcePixels[sp0];
int B = sourcePixels[++sp0];
int C = sourcePixels[++sp0];
int D = sourcePixels[sp1];
int E = sourcePixels[++sp1];
int F = sourcePixels[++sp1];
int G = sourcePixels[sp2];
int H = sourcePixels[++sp2];
int I = sourcePixels[++sp2];
for (int x = 0; x < width; x++)
{
if (B != H && D != F)
{
targetPixels[++tp0] = D == B ? D : E;
targetPixels[++tp0] = B == F ? F : E;
targetPixels[++tp1] = D == H ? D : E;
targetPixels[++tp1] = H == F ? F : E;
}
else
{
targetPixels[++tp0] = E;
targetPixels[++tp0] = E;
targetPixels[++tp1] = E;
targetPixels[++tp1] = E;
}
// Scroll A-I left
A = B;
B = C;
D = E;
E = F;
G = H;
H = I;
// Resample rightmost edge
C = sourcePixels[++sp0];
F = sourcePixels[++sp1];
I = sourcePixels[++sp2];
}
}
return targetImage;
}
}