aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl/osdependent/windows/ImageConverter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/java/sip/communicator/impl/osdependent/windows/ImageConverter.java')
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/windows/ImageConverter.java172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/net/java/sip/communicator/impl/osdependent/windows/ImageConverter.java b/src/net/java/sip/communicator/impl/osdependent/windows/ImageConverter.java
new file mode 100644
index 0000000..99754d3
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/osdependent/windows/ImageConverter.java
@@ -0,0 +1,172 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Copyright 2000-2016 JetBrains s.r.o.
+ * Copyright @ 2015 Atlassian Pty Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */package net.java.sip.communicator.impl.osdependent.windows;
+
+import java.awt.image.*;
+import java.nio.*;
+
+import com.sun.jna.*;
+import com.sun.jna.platform.win32.*;
+import com.sun.jna.platform.win32.WinDef.*;
+
+/**
+ * Image conversion utilities.
+ *
+ * Parts of this code are based on AppIcon.java from IntelliJ community.
+ * Licensed under Apache 2.0, Copyright 2000-2016 JetBrains s.r.o.
+ */
+public class ImageConverter
+{
+ /**
+ * Converts the <tt>BufferedImage</tt> to an ICONDIR structure.
+ * @param src The source image to convert
+ * @return an ICONDIR structure with the data of the passed source image
+ */
+ public static byte[] writeTransparentIcoImage(BufferedImage src)
+ {
+ int bitCount = 32;
+
+ int scanline_size = (bitCount * src.getWidth() + 7) / 8;
+ if ((scanline_size % 4) != 0)
+ scanline_size += 4 - (scanline_size % 4); // pad scanline to 4 byte
+ // size.
+ int t_scanline_size = (src.getWidth() + 7) / 8;
+ if ((t_scanline_size % 4) != 0)
+ t_scanline_size += 4 - (t_scanline_size % 4); // pad scanline to 4
+ // byte size.
+ int imageSize = 40 + src.getHeight() * scanline_size
+ + src.getHeight() * t_scanline_size;
+
+ // sizeof(ICONDIR)
+ // + sizeof(ICONDIRENTRY)
+ // + (sizeof(BITMAPINFOHEADER)+data)
+ ByteBuffer bos = ByteBuffer.allocate(6 + 16 + imageSize);
+ bos.order(ByteOrder.LITTLE_ENDIAN);
+
+ // ICONDIR
+ bos.putShort((short) 0); // reserved
+ bos.putShort((short) 1); // 1=ICO, 2=CUR
+ bos.putShort((short) 1); // count
+
+ // ICONDIRENTRY
+ int iconDirEntryWidth = src.getWidth();
+ int iconDirEntryHeight = src.getHeight();
+ if (iconDirEntryWidth > 255 || iconDirEntryHeight > 255)
+ {
+ iconDirEntryWidth = 0;
+ iconDirEntryHeight = 0;
+ }
+ bos.put((byte) iconDirEntryWidth);
+ bos.put((byte) iconDirEntryHeight);
+ bos.put((byte) 0);
+ bos.put((byte) 0); // reserved
+ bos.putShort((short) 1); // color planes
+ bos.putShort((short) bitCount);
+ bos.putInt(imageSize);
+ bos.putInt(22); // image offset
+
+ // BITMAPINFOHEADER
+ bos.putInt(40); // size
+ bos.putInt(src.getWidth());
+ bos.putInt(2 * src.getHeight());
+ bos.putShort((short) 1); // planes
+ bos.putShort((short) bitCount);
+ bos.putInt(0); // compression
+ bos.putInt(0); // image size
+ bos.putInt(0); // x pixels per meter
+ bos.putInt(0); // y pixels per meter
+ bos.putInt(0); // colors used, 0 = (1 << bitCount) (ignored)
+ bos.putInt(0); // colors important
+
+ int bit_cache = 0;
+ int bits_in_cache = 0;
+ int row_padding = scanline_size - (bitCount * src.getWidth() + 7) / 8;
+ for (int y = src.getHeight() - 1; y >= 0; y--)
+ {
+ for (int x = 0; x < src.getWidth(); x++)
+ {
+ int argb = src.getRGB(x, y);
+
+ bos.put((byte) (0xff & argb));
+ bos.put((byte) (0xff & (argb >> 8)));
+ bos.put((byte) (0xff & (argb >> 16)));
+ bos.put((byte) (0xff & (argb >> 24)));
+ }
+
+ for (int x = 0; x < row_padding; x++)
+ bos.put((byte) 0);
+ }
+
+ int t_row_padding = t_scanline_size - (src.getWidth() + 7) / 8;
+ for (int y = src.getHeight() - 1; y >= 0; y--)
+ {
+ for (int x = 0; x < src.getWidth(); x++)
+ {
+ int argb = src.getRGB(x, y);
+ int alpha = 0xff & (argb >> 24);
+ bit_cache <<= 1;
+ if (alpha == 0)
+ bit_cache |= 1;
+ bits_in_cache++;
+ if (bits_in_cache >= 8)
+ {
+ bos.put((byte) (0xff & bit_cache));
+ bit_cache = 0;
+ bits_in_cache = 0;
+ }
+ }
+
+ if (bits_in_cache > 0)
+ {
+ bit_cache <<= (8 - bits_in_cache);
+ bos.put((byte) (0xff & bit_cache));
+ bit_cache = 0;
+ bits_in_cache = 0;
+ }
+
+ for (int x = 0; x < t_row_padding; x++)
+ bos.put((byte) 0);
+ }
+
+ byte[] result = new byte[bos.position()];
+ System.arraycopy(bos.array(), 0, result, 0, bos.position());
+ return result;
+ }
+
+ /**
+ * Converts an ICONDIR ico to an HICON handle
+ * @param ico the image data
+ * @return A Windows HICON handle
+ */
+ public static HICON createIcon(byte[] ico)
+ {
+ Memory buffer = new Memory(ico.length);
+ buffer.write(0, ico, 0, ico.length);
+ int nSize = 100;
+ int offset = User32Ex.INSTANCE.LookupIconIdFromDirectoryEx(buffer, true,
+ nSize, nSize, 0);
+ if (offset != 0)
+ {
+ return User32Ex.INSTANCE.CreateIconFromResourceEx(
+ buffer.share(offset), new WinDef.DWORD(0), true,
+ new WinDef.DWORD(0x00030000), nSize, nSize, 0);
+ }
+
+ return null;
+ }
+}