Last week, I asked the question: What is a trick way to clamp a byte to the range of [0-255] An operation that is needed all the time in image processing. The common strategy to perform this operation is usually a logical check of the form:
if(foo > 255)foo = 255; else if(foo < 0)foo = 0; This is basically the clamping strategy in: com.sun.media.jai.util.ImageUtil.java public static final byte clampByte(int in) { return (in > 0xFF ? (byte)0xFF : (in >= 0 ? (byte)in : (byte)0)); } James Cheng sent me a snippet from com.sun.media.jai.opimage.AddOpImage sum = (s1[s1PixelOffset]&0xFF) + (s2[s2PixelOffset]&0xFF); d[dPixelOffset] = (byte)((((sum<<23) >> 31) | sum) & 0xFF); Which clamps the top end to 255 but leaves the bottom end to dangle negative. Peter West then sent me a mod to the above code -- bar = (((((foo << 23) >> 31) | foo) & 0xFF) & ~(foo>>31))&0xFF; Which clamps the integer to the desired range and is faster quantitatively than the logical test. Peter then improved it with a variant to the shift method above by leaving out the intermediate and trailing mask and cast to byte. bar = (byte)((((foo << 23) >> 31) | foo) & ~(foo>>31)); Which quantitatively tests a bit faster. I've attached the test program used to time the various strategies and post the results below. In summary, the triple shift with no intermediate mask is 30% to 40% faster than the logical test strategy. This can mean a lot when you consider that a bi-cubic interpolation can have 15 clamping ops per pixel -- that's 15,000,000 clamping ops on a 1K x 1K image. Below are the test results: (0)- bar = (((((foo << 23) >> 31) | foo) & 0xFF) & ~(foo>>31))&0xFF; (1)- bar = ((((foo << 23) >> 31) | foo) & ~(foo>>31))&0xFF; (2)- bar = (byte)((((foo << 23) >> 31) | foo) & ~(foo>>31)); (3)- if(foo > 255)foo = 255; else if(foo < 0)foo = 0; shiftTest()... 0:---------------- (0)Time = 160 (1)Time = 120 (2)Time = 130 (3)Time = 221 1:---------------- (0)Time = 150 (1)Time = 190 (2)Time = 151 (3)Time = 270 2:---------------- (0)Time = 190 (1)Time = 141 (2)Time = 130 (3)Time = 210 3:---------------- (0)Time = 160 (1)Time = 120 (2)Time = 131 (3)Time = 220 4:---------------- (0)Time = 200 (1)Time = 160 (2)Time = 151 (3)Time = 250 5:---------------- (0)Time = 190 (1)Time = 171 (2)Time = 160 (3)Time = 250 6:---------------- (0)Time = 190 (1)Time = 141 (2)Time = 170 (3)Time = 250 7:---------------- (0)Time = 191 (1)Time = 160 (2)Time = 160 (3)Time = 250 8:---------------- (0)Time = 191 (1)Time = 160 (2)Time = 160 (3)Time = 260 9:---------------- (0)Time = 161 (1)Time = 160 (2)Time = 160 (3)Time = 251 10:---------------- (0)Time = 180 (1)Time = 170 (2)Time = 160 (3)Time = 251 11:---------------- (0)Time = 200 (1)Time = 160 (2)Time = 150 (3)Time = 251 12:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 160 (3)Time = 231 13:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 161 (3)Time = 250 14:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 161 (3)Time = 250 15:---------------- (0)Time = 190 (1)Time = 171 (2)Time = 160 (3)Time = 250 16:---------------- (0)Time = 190 (1)Time = 141 (2)Time = 170 (3)Time = 250 17:---------------- (0)Time = 190 (1)Time = 141 (2)Time = 160 (3)Time = 250 18:---------------- (0)Time = 181 (1)Time = 170 (2)Time = 150 (3)Time = 250 19:---------------- (0)Time = 171 (1)Time = 170 (2)Time = 150 (3)Time = 250 20:---------------- (0)Time = 171 (1)Time = 160 (2)Time = 160 (3)Time = 251 21:---------------- (0)Time = 190 (1)Time = 170 (2)Time = 160 (3)Time = 251 22:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 170 (3)Time = 231 23:---------------- (0)Time = 180 (1)Time = 160 (2)Time = 150 (3)Time = 231 24:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 161 (3)Time = 260 25:---------------- (0)Time = 180 (1)Time = 160 (2)Time = 151 (3)Time = 250 26:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 151 (3)Time = 250 27:---------------- (0)Time = 190 (1)Time = 161 (2)Time = 160 (3)Time = 250 28:---------------- (0)Time = 190 (1)Time = 151 (2)Time = 160 (3)Time = 260 29:---------------- (0)Time = 180 (1)Time = 160 (2)Time = 160 (3)Time = 250 30:---------------- (0)Time = 191 (1)Time = 160 (2)Time = 170 (3)Time = 260 31:---------------- (0)Time = 161 (1)Time = 170 (2)Time = 160 (3)Time = 251 32:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 160 (3)Time = 261 33:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 150 (3)Time = 231 34:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 150 (3)Time = 231 35:---------------- (0)Time = 190 (1)Time = 170 (2)Time = 151 (3)Time = 250 36:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 151 (3)Time = 250 37:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 131 (3)Time = 250 38:---------------- (0)Time = 180 (1)Time = 171 (2)Time = 150 (3)Time = 250 39:---------------- (0)Time = 190 (1)Time = 141 (2)Time = 150 (3)Time = 250 40:---------------- (0)Time = 190 (1)Time = 141 (2)Time = 150 (3)Time = 260 41:---------------- (0)Time = 191 (1)Time = 160 (2)Time = 160 (3)Time = 250 42:---------------- (0)Time = 181 (1)Time = 160 (2)Time = 160 (3)Time = 250 43:---------------- (0)Time = 181 (1)Time = 160 (2)Time = 170 (3)Time = 251 44:---------------- (0)Time = 200 (1)Time = 160 (2)Time = 160 (3)Time = 251 45:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 170 (3)Time = 231 46:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 160 (3)Time = 241 47:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 171 (3)Time = 250 48:---------------- (0)Time = 180 (1)Time = 170 (2)Time = 141 (3)Time = 260 49:---------------- (0)Time = 180 (1)Time = 161 (2)Time = 160 (3)Time = 250 50:---------------- (0)Time = 190 (1)Time = 151 (2)Time = 150 (3)Time = 250 51:---------------- (0)Time = 190 (1)Time = 141 (2)Time = 160 (3)Time = 260 52:---------------- (0)Time = 191 (1)Time = 170 (2)Time = 160 (3)Time = 260 53:---------------- (0)Time = 171 (1)Time = 170 (2)Time = 160 (3)Time = 250 54:---------------- (0)Time = 171 (1)Time = 160 (2)Time = 170 (3)Time = 251 55:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 160 (3)Time = 251 56:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 170 (3)Time = 241 57:---------------- (0)Time = 190 (1)Time = 170 (2)Time = 161 (3)Time = 260 58:---------------- (0)Time = 190 (1)Time = 190 (2)Time = 161 (3)Time = 250 59:---------------- (0)Time = 190 (1)Time = 161 (2)Time = 160 (3)Time = 310 60:---------------- (0)Time = 191 (1)Time = 170 (2)Time = 150 (3)Time = 260 61:---------------- (0)Time = 181 (1)Time = 170 (2)Time = 190 (3)Time = 260 62:---------------- (0)Time = 171 (1)Time = 160 (2)Time = 170 (3)Time = 251 63:---------------- (0)Time = 190 (1)Time = 170 (2)Time = 170 (3)Time = 241 64:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 160 (3)Time = 231 65:---------------- (0)Time = 200 (1)Time = 160 (2)Time = 161 (3)Time = 250 66:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 141 (3)Time = 260 67:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 141 (3)Time = 250 68:---------------- (0)Time = 190 (1)Time = 161 (2)Time = 170 (3)Time = 250 69:---------------- (0)Time = 190 (1)Time = 141 (2)Time = 180 (3)Time = 250 70:---------------- (0)Time = 191 (1)Time = 160 (2)Time = 160 (3)Time = 250 71:---------------- (0)Time = 161 (1)Time = 170 (2)Time = 150 (3)Time = 250 72:---------------- (0)Time = 181 (1)Time = 170 (2)Time = 160 (3)Time = 251 73:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 180 (3)Time = 251 74:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 170 (3)Time = 231 75:---------------- (0)Time = 190 (1)Time = 170 (2)Time = 150 (3)Time = 231 76:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 161 (3)Time = 260 77:---------------- (0)Time = 180 (1)Time = 160 (2)Time = 131 (3)Time = 250 78:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 141 (3)Time = 260 79:---------------- (0)Time = 180 (1)Time = 171 (2)Time = 150 (3)Time = 250 80:---------------- (0)Time = 190 (1)Time = 151 (2)Time = 160 (3)Time = 250 81:---------------- (0)Time = 190 (1)Time = 151 (2)Time = 150 (3)Time = 260 82:---------------- (0)Time = 181 (1)Time = 170 (2)Time = 170 (3)Time = 250 83:---------------- (0)Time = 171 (1)Time = 160 (2)Time = 170 (3)Time = 250 84:---------------- (0)Time = 171 (1)Time = 160 (2)Time = 150 (3)Time = 261 85:---------------- (0)Time = 180 (1)Time = 170 (2)Time = 160 (3)Time = 251 86:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 170 (3)Time = 231 87:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 171 (3)Time = 250 88:---------------- (0)Time = 190 (1)Time = 170 (2)Time = 141 (3)Time = 250 89:---------------- (0)Time = 190 (1)Time = 170 (2)Time = 141 (3)Time = 250 90:---------------- (0)Time = 190 (1)Time = 171 (2)Time = 160 (3)Time = 260 91:---------------- (0)Time = 190 (1)Time = 141 (2)Time = 170 (3)Time = 250 92:---------------- (0)Time = 191 (1)Time = 160 (2)Time = 150 (3)Time = 250 93:---------------- (0)Time = 181 (1)Time = 160 (2)Time = 160 (3)Time = 250 94:---------------- (0)Time = 171 (1)Time = 160 (2)Time = 170 (3)Time = 261 95:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 160 (3)Time = 251 96:---------------- (0)Time = 190 (1)Time = 170 (2)Time = 160 (3)Time = 231 97:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 160 (3)Time = 231 98:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 161 (3)Time = 260 99:---------------- (0)Time = 190 (1)Time = 160 (2)Time = 151 (3)Time = 250 =========================================================================== To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
package miller; public class Miller { public static void main(String[] args) { shiftTest(); } public static void shiftTest() { System.err.println("shiftTest()..."); int foo = 0; int bar = 0; long t0 = 0l; long t1 = 0l; for(int j = 0; j < 100; j++) { System.err.println(j + ":----------------"); t0 = System.currentTimeMillis(); for(int i = -10000000; i < 10000000; i++) { //foo = (i >>> 31) | (i & 0xFF); //foo = (i & 0xff); foo = i; bar = (((((foo << 23) >> 31) | foo) & 0xFF) & ~(foo>>31))&0xFF; //bar = ((((foo << 23) >> 31) | foo) & ~(foo>>31))&0xFF; //System.err.println(i + ": foo = " + foo + ", bar = " + bar ); } t1 = System.currentTimeMillis(); System.err.println("(0)Time = " +(t1 - t0)); t0 = System.currentTimeMillis(); for(int i = -10000000; i < 10000000; i++) { //foo = (i >>> 31) | (i & 0xFF); //foo = (i & 0xff); foo = i; bar = ((((foo << 23) >> 31) | foo) & ~(foo>>31))&0xFF; //bar = (((((foo << 23) >> 31) | foo) & 0xFF) & ~(foo>>31))&0xFF; //System.err.println(i + ": foo = " + foo + ", bar = " + bar ); } t1 = System.currentTimeMillis(); System.err.println("(1)Time = " +(t1 - t0)); t0 = System.currentTimeMillis(); for(int i = -10000000; i < 10000000; i++) { //foo = (i >>> 31) | (i & 0xFF); //foo = (i & 0xff); foo = i; //bar = ((((foo << 23) >> 31) | foo) & ~(foo>>31))&0xFF; bar = (byte)((((foo << 23) >> 31) | foo) & ~(foo>>31)); //System.err.println(i + ": foo = " + foo + ", bar = " + bar ); } t1 = System.currentTimeMillis(); System.err.println("(2)Time = " +(t1 - t0)); t0 = System.currentTimeMillis(); for(int i = -10000000; i < 10000000; i++) { foo = i; if(foo > 255)foo = 255; else if(foo < 0)foo = 0; //System.err.println(i + ": foo = " + foo + ", bar = " + bar ); } t1 = System.currentTimeMillis(); System.err.println("(3)Time = " +(t1 - t0)); // bar = (byte)((((foo << 23) >> 31) | foo) & ~(foo>>31)); } System.exit(0); } }