Java tutorial
//package com.java2s; //License from project: LGPL import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; import java.util.ArrayList; public class Main { private static IntBuffer[] generateMipmaps(int[] rgb, int width, int height, int mipmaps) { if (rgb == null) { return null; } else { ArrayList mipmapData = new ArrayList(); IntBuffer buffer = newIntBuffer(width * height * 4); buffer.put(rgb).position(0); int level = 0; while (true) { mipmapData.add(buffer); if (width <= 0 || height <= 0 || level >= mipmaps) { return (IntBuffer[]) mipmapData.toArray(new IntBuffer[mipmapData.size()]); } IntBuffer newBuffer = newIntBuffer(width * height); scaleHalf(buffer, width, height, newBuffer, 0); buffer = newBuffer; ++level; width >>= 1; height >>= 1; } } } private static IntBuffer newIntBuffer(int size) { ByteBuffer buffer = ByteBuffer.allocateDirect(size); buffer.order(ByteOrder.LITTLE_ENDIAN); return buffer.asIntBuffer(); } static void scaleHalf(IntBuffer in, int w, int h, IntBuffer out, int rotate) { for (int i = 0; i < w / 2; ++i) { for (int j = 0; j < h / 2; ++j) { int k = w * 2 * j + 2 * i; int pixel00 = in.get(k); int pixel01 = in.get(k + 1); int pixel10 = in.get(k + w); int pixel11 = in.get(k + w + 1); if (rotate != 0) { pixel00 = Integer.rotateLeft(pixel00, rotate); pixel01 = Integer.rotateLeft(pixel01, rotate); pixel10 = Integer.rotateLeft(pixel10, rotate); pixel11 = Integer.rotateLeft(pixel11, rotate); } int pixel = average4RGBA(pixel00, pixel01, pixel10, pixel11); if (rotate != 0) { pixel = Integer.rotateRight(pixel, rotate); } out.put(w / 2 * j + i, pixel); } } } private static int average4RGBA(int pixel00, int pixel01, int pixel10, int pixel11) { int a00 = pixel00 & 255; int a01 = pixel01 & 255; int a10 = pixel10 & 255; int a11 = pixel11 & 255; switch (a00 << 24 | a01 << 16 | a10 << 8 | a11) { case -16777216: return pixel00; case -16776961: return average2RGBA(pixel00, pixel11); case -16711936: return average2RGBA(pixel00, pixel10); case -65536: return average2RGBA(pixel00, pixel01); case -1: case 0: return average2RGBA(average2RGBA(pixel00, pixel11), average2RGBA(pixel01, pixel10)); case 255: return pixel11; case 65280: return pixel10; case 65535: return average2RGBA(pixel10, pixel11); case 16711680: return pixel01; case 16711935: return average2RGBA(pixel01, pixel11); case 16776960: return average2RGBA(pixel01, pixel10); default: int a = a00 + a01 + a10 + a11; int pixel = a >> 2; for (int i = 8; i < 32; i += 8) { int average = (a00 * (pixel00 >> i & 255) + a01 * (pixel01 >> i & 255) + a10 * (pixel10 >> i & 255) + a11 * (pixel11 >> i & 255)) / a; pixel |= average << i; } return pixel; } } private static int average2RGBA(int a, int b) { return ((a & -16843010) >>> 1) + ((b & -16843010) >>> 1) | a & b & 16843009; } }