public BufferedImage getBitmap(int id) {
		BufferedImage value;
		if(!low_memory && bmp_loaded != null && (value = bmp_loaded[id]) != null) {
			return value;
		} else {
			long offset = getBitmapOffset(id);
			if(offset == -1)
				throw new NXException("NX file does not this canvas.");
			
			lock();
			try {
				SeekableLittleEndianAccessor slea = getStreamAtOffset(offset);
				
				int width = slea.getUShort();
				int height = slea.getUShort();
				long length = slea.getUInt();
				
				ByteBuffer output = ByteBuffer.allocateDirect(width * height * 4);
				NXCompression.decompress(slea.getBuffer(), offset + 4, length + 4, output, 0);
				output.rewind();
				output.order(ByteOrder.LITTLE_ENDIAN);
				
				//TODO: optimize this without bitshifts.
				value = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
				for (int h = 0; h < height; h++) {
					for (int w = 0; w < width; w++) {
						int b = output.get() & 0xFF;
						int g = output.get() & 0xFF;
						int r = output.get() & 0xFF;
						int a = output.get() & 0xFF;
						value.setRGB(w, h, (a << 24) | (r << 16) | (g << 8) | b);
					}
				}
			} finally { unlock(); }
			
			if(!low_memory) bmp_loaded[id] = value;
			return value;
		}
	}