📄 imarith.java
字号:
package ergo.ui;
// $Id: ImArith.java,v 1.3 1999/08/15 01:40:28 sigue Exp $
/*
* Copyright (C) 1999 Carl L. Gay and Antranig M. Basman.
* See the file copyright.txt, distributed with this software,
* for further information.
*/
import java.awt.Color;
/**
* Utility class for image arithmetic. Contains only static methods.
* No instances are ever created. Contains deep Felixification.
*/
public final class ImArith {
private ImArith () {} // Disallow instantiaton
static final int tp (Color c, int fac) {
return (c.getRGB() & 0xffffff) | 0x80000000;
}
public static final int getFullColor (Color base, int transpar) {
return (base.getRGB() & 0x00ffffff) | (transpar << 24);
}
/** Interpolate between color a and color b by amount fac; 0 = colora, 255 = colorb
* Prizes for anyone who can demonstrate to me why it works.
*/
public static final int Felixify (int colora, int colorb, int fac) {
return ((( ((((colorb & 0xff0000) - (colora & 0xff0000)) * fac) & 0xff000000) +
((((colorb & 0xff00) - (colora & 0xff00)) * fac) & 0xffff0000) +
(((colorb & 0xff) - (colora & 0xff)) * fac)) >> 8) + colora);
}
/** Apply sub immediate opaque - blit region of size aIm from bIm onto aIm.
*/
public final static RawImage apsubio (RawImage aIm, RawImage bIm, int tlx, int tly) {
int awidth = aIm.width;
int bwidth = bIm.width;
int baddress = tly * bwidth + tlx; // Felixification of address calc.
int aaddress = 0;
int[] a = aIm.data; int[] b = bIm.data;
for (int row = 0; row < aIm.height; ++row) {
System.arraycopy(b, baddress, a, aaddress, awidth);
aaddress += awidth;
baddress += bwidth;
}
return aIm;
}
/** "Correctly" blit bitmap b onto bitmap a, returning new result.
*/
public final static RawImage ap (RawImage aIm, RawImage bIm) {
int RMI = 0xff0000;
int REMI= 0xffff0000;
int GMI = 0x00ff00;
int BMI = 0x0000ff;
int TBI = 0xff000000;
int[] a = aIm.data; int[] b = bIm.data;
int size = a.length;
RawImage resIm = aIm.bclone();
int[] res = resIm.data;
for (int i = size - 1; i >= 0; --i) {
int bi = b[i];
if (bi == 0)
continue;
int fac = b[i] >>> 24;
if (fac == BMI) {
res[i] = bi;
continue;
}
int ai = a[i];
res[i] = ((( ((((bi & RMI) - (ai & RMI)) * fac) & TBI) +
((((bi & GMI) - (ai & GMI)) * fac) & REMI) +
(((bi & BMI) - (ai & BMI)) * fac)) >> 8) + ai) | TBI;
}
return resIm;
}
public final static RawImage api (RawImage aIm, RawImage bIm) {
int RMI = 0xff0000;
int REMI = 0xffff0000;
int GMI = 0x00ff00;
int TBI = 0xff000000;
int BMI = 255;
// ---*** Occasionally I get a NullPointerException on the following line
// when first observing a game. I haven't chased it down yet though.
// Perhaps only on the first ob of the entire Ergo session? -sigue
int[] a = aIm.data;
int[] b = bIm.data;
int size = a.length;
for (int i = size - 1; i >= 0; --i) {
int bi = b[i];
if (bi == 0)
continue;
int fac = bi >>> 24;
int facc = BMI - fac;
if (facc == 0) {
a[i] = bi;
continue;
}
int ai = a[i];
a[i] = ((( ((((bi & RMI) - (ai & RMI)) * fac) & TBI) +
((((bi & GMI) - (ai & GMI)) * fac) & REMI) +
(((bi & BMI) - (ai & BMI)) * fac)) >> 8) + ai) | TBI;
}
return aIm;
}
/** Utility function for apiallo.
* Signalling depends that 0 is not a possible limiting value!
* Positive for limits is right limit, negative is left limit.
* xlim and ylim are given in coordinate system of big enclosing b.
*/
/* --unused
private final static void square (int val, RawImage aIm, int bx, int by,
int xlim, int ylim,
int scale, int ax, int ay) {
int[] a = aIm.data;
int basexa = (xlim < 0 ? -xlim: bx * scale) - ax;
int basexb = (xlim > 0 ? xlim: (bx + 1) * scale) - ax;
int baseya = (ylim < 0 ? -ylim: by * scale) - ay;
int baseyb = (ylim > 0 ? ylim: (by +1) * scale) - ay;
int indbig = baseya * aIm.width + basexa;
for (int y = baseya; y < baseyb; ++y) {
for (int x = basexa; x < basexb; ++x) {
a[indbig++] = val;
}
indbig += (aIm.width - (basexb - basexa)); // end of row.
}
}
*/
/** Opaquely blit image b onto a scaled by n; but the origin of bitmap a in scaled
* b coordinates is at x, y.
* Fooo-low! Mr. Apiaaaalo!
*/
/* Motherfucking piece of shit language. I can't believe everyone thinks
* Gosling is a demigod. Goddamned language doesn't allow nested comments!
* No self-respecting language in the '90s should have a problem with this.
* It's not rocket science. How could Steele, who was a Common Lisp guru,
* allow this to happen?
*/
/* --method unused
public final static void apiallo (RawImage aIm, RawImage bIm, int scale,
int ax, int ay) {
int[] b = bIm.data;
int[] a = aIm.data;
// b is the smaller image - a is the target.
// b when scaled, is much bigger than a.
// x and why, when input are in coordinates rel to scaled b origin.
int b_tlx = (ax + (scale - 1)) / scale; // round up. (forewards).
int b_tly = (ay + (scale - 1)) / scale; // round up.
int b_brpx = (ax + aIm.width) / scale; // round down.
int b_brpy = (ay + aIm.height) / scale; // round down.
b_brpx = Math.min(b_brpx, bIm.width);
b_brpy = Math.min(b_brpy, bIm.height);
System.out.println("Scale: "+scale+" ax: "+ax+" ay: "+ay);
System.out.println("A size: "+aIm.width+" "+aIm.height);
System.out.println("B size: "+bIm.width+" "+bIm.height);
System.out.println("b_tlx: "+b_tlx+" b_tly: "+b_tly+
" b_brpx: "+b_brpx+" b_brpy: "+b_brpy);
aIm.blank(0xff0000ff);
int indsmall = bIm.width * b_tly + b_tlx; // index that points from b.
int indbig = aIm.width * (b_tly * scale - ay) + (b_tlx * scale - ax); // index that points into a.
for (int j = b_tly; j < b_brpy; ++j) {
for (int i = b_tlx; i < b_brpx; ++i) {
// System.out.print(i+ " "+j);
//Debug.assert(indsmall == bIm.width * j + i, "Indsmall should be "+
// (bIm.width * j + i)+ " but = "+indsmall);
int val = b[indsmall];
// System.out.println("Top ingbig: "+indbig);
for (int y = 0; y<scale; ++y) {
for (int x = 0; x<scale; ++x) {
int correctbig = aIm.width * (y + j*scale - ay) + x + i*scale - ax;
// Debug.assert(indbig == correctbig, "Indbig should be "+
// correctbig+ " but = "+indbig+" at b "+i+" "+j+" a "+
// x+" "+y);
try {
a[indbig++] = val;
}
catch (ArrayIndexOutOfBoundsException ae) {
System.out.println("Indbig should be "+
correctbig+ " but = "+indbig+" at b "+i+" "+j+" a "+
x+" "+y);
// throw (new AssertException("Kabloom: "+i+" "+j+", "+x+" "+y));
}
} // end for x
indbig += aIm.width - scale; // next row, next pixel down.
} // end for y
++indsmall; // next pixel across in small image.
indbig -= (aIm.width * scale - scale); // n rows up, 1 pix right.
} // end for i
indsmall += (bIm.width - (b_brpx - b_tlx)); // next row of small image.
indbig += (aIm.width * scale - (b_brpx - b_tlx)*scale); // n rows down, im width left.
} // end for j
boolean offl = b_tlx*scale > ax;
boolean offr = b_brpx*scale < ax + aIm.width;
boolean offt = b_tly*scale > ay;
boolean offb = b_brpy*scale < ay + aIm.height;
if (offl) { // Draw leftern margin
System.out.println("Left: "+ ((b_tlx - 1)*scale) + " to " + ax);
for (int y = b_tly; y < b_brpy ; ++y) {
square( b[ y*bIm.width + b_tlx - 1], aIm, b_tlx - 1, y, -ax, 0, scale, ax, ay);
}
}
if (offt) { // Draw topern margin
System.out.println("Top: "+ ((b_tly - 1)*scale) + " to " + ay);
for (int x = b_tlx; x < b_brpx; ++x) {
square( b[ (b_tly - 1)*bIm.width + x], aIm, x, b_tly - 1, 0, -ay, scale, ax, ay);
}
}
if (offr) { // Draw rightern margin
System.out.println("Right: "+ (b_brpy*scale) + " to " + (ax + aIm.width));
for (int y = b_tly; y < b_brpy; ++y) {
square( b[ y*bIm.width + b_brpx], aIm, b_brpx, y, ax + aIm.width, 0, scale, ax, ay);
}
}
if (offb) { // Draw bottom margin
System.out.println("Bottom: "+ (b_brpy*scale) + " to " + (ay + aIm.height));
for (int x = b_tlx; x < b_brpx; ++x) {
square( b[ b_brpy*bIm.width + x], aIm, x, b_brpy, 0, ay + aIm.height, scale, ax, ay);
}
}
if (offl && offt) { // Draw tl corner: x = tlx - 1, y = tly - 1
square( b[ (b_tly - 1)*bIm.width + b_tlx - 1], aIm,
b_tlx - 1, b_tly - 1, -ax, -ay, scale, ax, ay);
}
if (offt && offr) { // Draw tr corner: x = brpx, y = tly - 1
square( b[ (b_tly - 1)*bIm.width + b_brpx], aIm,
b_brpx, b_tly - 1, ax + aIm.width, -ay, scale, ax, ay);
}
if (offr && offb) { // Draw br corner: x = brpx, y = brpy
square( b[ b_brpy*bIm.width + b_brpx], aIm,
b_brpx, b_brpy, ax + aIm.width, ay + aIm.height, scale, ax, ay);
}
if (offb && offl) { // Draw bl corner: x = tlx - 1, y = brpy
square( b[ b_brpy*bIm.width + b_tlx - 1], aIm,
b_tlx - 1, b_brpy, -ax, ay + aIm.height, scale, ax, ay);
}
} // end apiallo.
*/
/** "Correctly" blit bitmap b scaled by n onto bitmap a, returning modified a.
*/
public final static RawImage apis (RawImage aIm, RawImage bIm, int scale) {
if (scale == 1)
return api(aIm, bIm);
int RMI = 0xff0000;
int REMI = 0xffff0000;
int GMI = 0x00ff00;
int BMI = 0x0000ff;
int TBI = 0xff000000;
int[] a = aIm.data;
int[] b = bIm.data;
int size = b.length;
int smallwidth = bIm.width;
int bigwidth = aIm.width;
int indbig = a.length - 1;
int indsmall = b.length - 1;
for (int j = bIm.height - 1; j >= 0; j--) {
for (int i = bIm.width - 1; i >= 0; i--) {
int bi = b[indsmall];
if (bi == 0)
continue;
int fac = b[indsmall] >>> 24;
int val;
if (fac == BMI)
val = bi;
else {
int ai = a[indbig];
val = ((( ((((bi & RMI) - (ai & RMI)) * fac) & TBI) +
((((bi & GMI) - (ai & GMI)) * fac) & REMI) +
(((bi & BMI) - (ai & BMI)) * fac)) >> 8) + ai) | TBI;
}
for (int y = scale - 1; y >= 0; --y) {
for (int x = scale - 1; x >= 0; --x) {
a[indbig--] = val;
}
indbig -= (bigwidth - scale);
}
indsmall--;
indbig += scale * (bigwidth - 1);
} // end for i - one row of little bitmap
// indsmall is correct.
indbig -= (scale - 1) * bigwidth;
// indbig is also correct!
}
return aIm;
}
public static int[][] dirs = { {0,0}, {0,1}, {1,0}, {1,1}};
/** antialias square bitmap a with size, by factor fac.
*/
public static RawImage antin (RawImage aIm, int fac) {
int RMI = 0xff0000;
int GMI = 0x00ff00;
int BMI = 0x0000ff;
int[] a = aIm.data; // Avoid references.
int width = aIm.width;
int width2 = width / fac;
int height2 = aIm.height / fac;
int fac2 = fac * fac;
int fac1 = fac - 1;
RawImage resIm = new RawImage(width2, height2);
int[] res = resIm.data;
int indbig = ((height2 - 1) * width + width2 - 1) * fac;
int indsmall = height2 * width2 - 1;
for (int j = height2 - 1; j >= 0; j--) {
for (int i = width2 - 1; i >= 0; i--) {
int r, g, b, t;
if (fac == 3) {
int indzap = indbig;
int ai = a[indzap++]; // at 0
r = ai & RMI; g = ai & GMI; b = ai & BMI; t = ai >>> 24;
ai = a[indzap++]; // at 1
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
ai = a[indzap += width]; // at 2
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
ai = a[indzap--]; // at (2,1)
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
ai = a[indzap--]; // at (1,1)
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
ai = a[indzap += width]; // at (0,1)
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
ai = a[indzap++]; // at (0,2)
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
ai = a[indzap++]; // at (1,2)
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
ai = a[indzap]; // at (2,2)
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
}
else if (fac == 2) {
int ai = a[indbig];
r = ai & RMI; g = ai & GMI; b = ai & BMI; t = ai >>> 24;
ai = a[indbig+1];
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
ai = a[indbig+width];
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
ai = a[indbig+width+1];
r += ai & RMI; g += ai & GMI; b += ai & BMI; t += ai >>> 24;
}
else {
r = 0; g = 0; b = 0; t = 0;
int indzap = indbig + fac1 * (width + 1);
for (int x = fac1; x >= 0; --x) {
for (int y = fac1; y >= 0; --y) {
int ai = a[indzap--];
r += ai & RMI;
g += ai & GMI;
b += ai & BMI;
t += ai >>> 24;
} // end for y
indzap -= (width - fac);
} // end for x
}
res[indsmall] = ((r / fac2) & RMI) | ((g / fac2) & GMI) |
((b / fac2) & BMI) | ((t / fac2) << 24);
--indsmall;
indbig -= fac;
} // end for i
indbig -= (fac1) * width;
} // end for j
return resIm;
}
public static RawImage parify (RawImage aIm, int fac) {
RawImage resIm = aIm.bclone();
int[] a = aIm.data;
int[] res = resIm.data;
for (int i = 0; i < a.length; ++i)
res[i] = (a[i] & 0xffffff) | (((a[i] >> 8) * fac) & 0xff000000);
return resIm;
}
} // end class ImArith
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -