private void applyShadow(BufferedImage image) {
		int dstWidth = image.getWidth();
		int dstHeight = image.getHeight();

		int left = (shadowSize - 1) >> 1;
		int right = shadowSize - left;
		int xStart = left;
		int xStop = dstWidth - right;
		int yStart = left;
		int yStop = dstHeight - right;

		int shadowRgb = shadowColor.getRGB() & 0x00FFFFFF;

		int[] aHistory = new int[shadowSize];
		int historyIdx = 0;

		int aSum;

		int[] dataBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
		int lastPixelOffset = right * dstWidth;
		float sumDivider = shadowOpacity / shadowSize;

		// horizontal pass

		for (int y = 0, bufferOffset = 0; y < dstHeight; y++, bufferOffset = y * dstWidth) {
			aSum = 0;
			historyIdx = 0;
			for (int x = 0; x < shadowSize; x++, bufferOffset++) {
				int a = dataBuffer[bufferOffset] >>> 24;
		aHistory[x] = a;
		aSum += a;
			}

			bufferOffset -= right;

			for (int x = xStart; x < xStop; x++, bufferOffset++) {
				int a = (int) (aSum * sumDivider);
				dataBuffer[bufferOffset] = a << 24 | shadowRgb;

				// substract the oldest pixel from the sum
				aSum -= aHistory[historyIdx];

				// get the lastest pixel
				a = dataBuffer[bufferOffset + right] >>> 24;
				aHistory[historyIdx] = a;
				aSum += a;

				if (++historyIdx >= shadowSize) {
					historyIdx -= shadowSize;
				}
			}
		}

		// vertical pass
		for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) {
			aSum = 0;
			historyIdx = 0;
			for (int y = 0; y < shadowSize; y++, bufferOffset += dstWidth) {
				int a = dataBuffer[bufferOffset] >>> 24;
		aHistory[y] = a;
		aSum += a;
			}

			bufferOffset -= lastPixelOffset;

			for (int y = yStart; y < yStop; y++, bufferOffset += dstWidth) {
				int a = (int) (aSum * sumDivider);
				dataBuffer[bufferOffset] = a << 24 | shadowRgb;

				// substract the oldest pixel from the sum
				aSum -= aHistory[historyIdx];

				// get the lastest pixel
				a = dataBuffer[bufferOffset + lastPixelOffset] >>> 24;
				aHistory[historyIdx] = a;
				aSum += a;

				if (++historyIdx >= shadowSize) {
					historyIdx -= shadowSize;
				}
			}
		}
	}