public static StructType decode(ByteBuffer buffer, int id) { StructType struct = new StructType(); struct.id = id; for (int opcode = buffer.get() & 0xff; opcode != 0; opcode = buffer.get() & 0xff) { if (opcode == 249) { int count = buffer.get() & 0xff; if (null == struct.values) { struct.values = new HashMap<Integer, Object>(count); } for (int i = 0; i < count; i++) { boolean stringParam = (buffer.get() & 0xff) == 1; int key = ByteBufferUtils.getTriByte(buffer); Object value; if (stringParam) { value = ByteBufferUtils.getString(buffer); } else { value = new Integer(buffer.getInt()); } struct.values.put(key, value); } } } return struct; }
/** * Decodes the {@link Sprite} from the specified {@link ByteBuffer}. * * @param buffer The buffer. * @return The sprite. */ public static Sprite decode(ByteBuffer buffer) { /* find the size of this sprite set */ buffer.position(buffer.limit() - 2); int size = buffer.getShort() & 0xFFFF; /* allocate arrays to store info */ int[] offsetsX = new int[size]; int[] offsetsY = new int[size]; int[] subWidths = new int[size]; int[] subHeights = new int[size]; /* read the width, height and palette size */ buffer.position(buffer.limit() - size * 8 - 7); int width = buffer.getShort() & 0xFFFF; int height = buffer.getShort() & 0xFFFF; int[] palette = new int[(buffer.get() & 0xFF) + 1]; /* and allocate an object for this sprite set */ Sprite set = new Sprite(width, height, size); /* read the offsets and dimensions of the individual sprites */ for (int i = 0; i < size; i++) { offsetsX[i] = buffer.getShort() & 0xFFFF; } for (int i = 0; i < size; i++) { offsetsY[i] = buffer.getShort() & 0xFFFF; } for (int i = 0; i < size; i++) { subWidths[i] = buffer.getShort() & 0xFFFF; } for (int i = 0; i < size; i++) { subHeights[i] = buffer.getShort() & 0xFFFF; } /* read the palette */ buffer.position(buffer.limit() - size * 8 - 7 - (palette.length - 1) * 3); palette[0] = 0; /* transparent colour (black) */ for (int index = 1; index < palette.length; index++) { palette[index] = ByteBufferUtils.getTriByte(buffer); if (palette[index] == 0) palette[index] = 1; } /* read the pixels themselves */ buffer.position(0); for (int id = 0; id < size; id++) { /* grab some frequently used values */ int subWidth = subWidths[id], subHeight = subHeights[id]; int offsetX = offsetsX[id], offsetY = offsetsY[id]; /* create a BufferedImage to store the resulting image */ BufferedImage image = set.frames[id] = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); /* allocate an array for the palette indices */ int[][] indices = new int[subWidth][subHeight]; /* read the flags so we know whether to read horizontally or vertically */ int flags = buffer.get() & 0xFF; /* now read the image */ if (image != null) { /* read the palette indices */ if ((flags & FLAG_VERTICAL) != 0) { for (int x = 0; x < subWidth; x++) { for (int y = 0; y < subHeight; y++) { indices[x][y] = buffer.get() & 0xFF; } } } else { for (int y = 0; y < subHeight; y++) { for (int x = 0; x < subWidth; x++) { indices[x][y] = buffer.get() & 0xFF; } } } /* read the alpha (if there is alpha) and convert values to ARGB */ if ((flags & FLAG_ALPHA) != 0) { if ((flags & FLAG_VERTICAL) != 0) { for (int x = 0; x < subWidth; x++) { for (int y = 0; y < subHeight; y++) { int alpha = buffer.get() & 0xFF; image.setRGB(x + offsetX, y + offsetY, alpha << 24 | palette[indices[x][y]]); } } } else { for (int y = 0; y < subHeight; y++) { for (int x = 0; x < subWidth; x++) { int alpha = buffer.get() & 0xFF; image.setRGB(x + offsetX, y + offsetY, alpha << 24 | palette[indices[x][y]]); } } } } else { for (int x = 0; x < subWidth; x++) { for (int y = 0; y < subHeight; y++) { int index = indices[x][y]; if (index == 0) { image.setRGB(x + offsetX, y + offsetY, 0); } else { image.setRGB(x + offsetX, y + offsetY, 0xFF000000 | palette[index]); } } } } } } return set; }