diff --git a/images/src/org/intellij/images/fileTypes/impl/ImageFileTypeManagerImpl.java b/images/src/org/intellij/images/fileTypes/impl/ImageFileTypeManagerImpl.java index 3dca4014d13a..c7f603957f4b 100644 --- a/images/src/org/intellij/images/fileTypes/impl/ImageFileTypeManagerImpl.java +++ b/images/src/org/intellij/images/fileTypes/impl/ImageFileTypeManagerImpl.java @@ -26,7 +26,6 @@ import icons.ImagesIcons; import org.intellij.images.ImagesBundle; import org.intellij.images.fileTypes.ImageFileTypeManager; import org.intellij.images.vfs.IfsUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import javax.imageio.ImageIO; @@ -39,7 +38,7 @@ import java.util.Set; */ final class ImageFileTypeManagerImpl extends ImageFileTypeManager { - @NonNls private static final String IMAGE_FILE_TYPE_NAME = "Images"; + private static final String IMAGE_FILE_TYPE_NAME = "Image"; private static final String IMAGE_FILE_TYPE_DESCRIPTION = ImagesBundle.message("images.filetype.description"); private static final UserFileType imageFileType; diff --git a/images/src/org/intellij/images/index/ImageInfoIndex.java b/images/src/org/intellij/images/index/ImageInfoIndex.java index f2db1b48fc33..90131f92f6c5 100644 --- a/images/src/org/intellij/images/index/ImageInfoIndex.java +++ b/images/src/org/intellij/images/index/ImageInfoIndex.java @@ -16,6 +16,7 @@ package org.intellij.images.index; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.indexing.*; @@ -33,14 +34,7 @@ import java.io.IOException; * @author spleaner */ public class ImageInfoIndex extends SingleEntryFileBasedIndexExtension { - private static final int ourMaxImageSize; - static { - int maxImageSize = 200; - try { - maxImageSize = Integer.parseInt(System.getProperty("idea.max.image.filesize", Integer.toString(maxImageSize)), 10); - } catch (NumberFormatException ex) {} - ourMaxImageSize = maxImageSize; - } + private static final long ourMaxImageSize = (long)(Registry.get("ide.index.image.max.size").asDouble() * 1024 * 1024); public static final ID INDEX_ID = ID.create("ImageFileInfoIndex"); @@ -94,17 +88,15 @@ public class ImageInfoIndex extends SingleEntryFileBasedIndexExtension it = ImageIO.getImageReaders(iis); + ImageReader reader = it.hasNext() ? it.next() : null; + if (reader != null) { + reader.setInput(iis, true); + int w = reader.getWidth(0); + int h = reader.getHeight(0); + int bpp = reader.getRawImageType(0).getColorModel().getPixelSize(); + return new Info(w, h, bpp); } } catch (IOException e) { - return null; + LOG.warn(e); } - } - - @Nullable - private static Info read(@NotNull final byte[] data) { - final DataInputStream is = new DataInputStream(new UnsyncByteArrayInputStream(data)); - try { - return readFileData(is); - } - catch (IOException e) { - return null; - } - finally { - try { - is.close(); - } - catch (IOException e) { - // nothing - } - } - } - - - @Nullable - private static Info readFileData(@NotNull final DataInput di) throws IOException { - final int b1 = di.readUnsignedByte(); - final int b2 = di.readUnsignedByte(); - - if (b1 == 0x47 && b2 == 0x49) { - return readGif(di); - } - - if (b1 == 0x89 && b2 == 0x50) { - return readPng(di); - } - - if (b1 == 0xff && b2 == 0xd8) { - return readJpeg(di); - } - - //if (b1 == 0x42 && b2 == 0x4d) { - // return readBmp(raf); - //} - return null; } - @Nullable - private static Info readGif(DataInput di) throws IOException { - final byte[] GIF_MAGIC_87A = {0x46, 0x38, 0x37, 0x61}; - final byte[] GIF_MAGIC_89A = {0x46, 0x38, 0x39, 0x61}; - byte[] a = new byte[11]; // 4 from the GIF signature + 7 from the global header - - di.readFully(a); - if ((!eq(a, 0, GIF_MAGIC_89A, 0, 4)) && (!eq(a, 0, GIF_MAGIC_87A, 0, 4))) { - return null; - } - - final int width = getShortLittleEndian(a, 4); - final int height = getShortLittleEndian(a, 6); - - int flags = a[8] & 0xff; - final int bpp = ((flags >> 4) & 0x07) + 1; - - return new Info(width, height, bpp); - } - - private static Info readBmp(RandomAccessFile raf) throws IOException { - byte[] a = new byte[44]; - if (raf.read(a) != a.length) { - return null; - } - - final int width = getIntLittleEndian(a, 16); - final int height = getIntLittleEndian(a, 20); - - if (width < 1 || height < 1) { - return null; - } - - final int bpp = getShortLittleEndian(a, 26); - if (bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 & bpp != 32) { - return null; - } - - return new Info(width, height, bpp); - } - - @Nullable - private static Info readJpeg(DataInput di) throws IOException { - byte[] a = new byte[13]; - while (true) { - di.readFully(a, 0, 4); - - int marker = getShortBigEndian(a, 0); - final int size = getShortBigEndian(a, 2); - - if ((marker & 0xff00) != 0xff00) { - return null; - } - - if (marker == 0xffe0) { - if (size < 14) { - di.skipBytes(size - 2); - continue; - } - - di.readFully(a, 0, 12); - di.skipBytes(size - 14); - } - else if (marker >= 0xffc0 && marker <= 0xffcf && marker != 0xffc4 && marker != 0xffc8) { - di.readFully(a, 0, 6); - - final int bpp = (a[0] & 0xff) * (a[5] & 0xff); - final int width = getShortBigEndian(a, 3); - final int height = getShortBigEndian(a, 1); - - return new Info(width, height, bpp); - } - else { - di.skipBytes(size - 2); - } - } - } - - @Nullable - private static Info readPng(DataInput di) throws IOException { - final byte[] PNG_MAGIC = {0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}; - byte[] a = new byte[27]; - - di.readFully(a); - if (!eq(a, 0, PNG_MAGIC, 0, 6)) { - return null; - } - - final int width = getIntBigEndian(a, 14); - final int height = getIntBigEndian(a, 18); - int bpp = a[22] & 0xff; - int colorType = a[23] & 0xff; - if (colorType == 2 || colorType == 6) { - bpp *= 3; - } - - return new Info(width, height, bpp); - } - - private static int getShortBigEndian(byte[] a, int offset) { - return (a[offset] & 0xff) << 8 | (a[offset + 1] & 0xff); - } - - private static boolean eq(byte[] a1, int offset1, byte[] a2, int offset2, int num) { - while (num-- > 0) { - if (a1[offset1++] != a2[offset2++]) { - return false; - } - } - - return true; - } - - private static int getIntBigEndian(byte[] a, int offset) { - return (a[offset] & 0xff) << 24 | (a[offset + 1] & 0xff) << 16 | (a[offset + 2] & 0xff) << 8 | a[offset + 3] & 0xff; - } - - private static int getIntLittleEndian(byte[] a, int offset) { - return (a[offset + 3] & 0xff) << 24 | (a[offset + 2] & 0xff) << 16 | (a[offset + 1] & 0xff) << 8 | a[offset] & 0xff; - } - - private static int getShortLittleEndian(byte[] a, int offset) { - return (a[offset] & 0xff) | (a[offset + 1] & 0xff) << 8; - } - public static class Info { public int width; public int height; diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 86c899dfbe48..034ee7f554d6 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -97,6 +97,8 @@ ide.javafx.tips.description=(Experimental) Use JavaFX Browser for 'Tips of the D ide.svg.icon=true ide.svg.icon.description=Load & auto-scale svg version of an icon if present +ide.index.image.max.size=10 +ide.index.image.max.size.description=Max size of an image to index, in megabytes ide.cached.image.max.size=1.5 ide.cached.image.max.size.description=Max size of an image to cache, in megabytes diff --git a/platform/util/src/com/intellij/util/ImageLoader.java b/platform/util/src/com/intellij/util/ImageLoader.java index 2760a8f010dd..5c3020602c4e 100644 --- a/platform/util/src/com/intellij/util/ImageLoader.java +++ b/platform/util/src/com/intellij/util/ImageLoader.java @@ -46,12 +46,13 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentMap; -import static com.intellij.util.ui.JBUI.ScaleType.*; +import static com.intellij.util.ui.JBUI.ScaleType.PIX_SCALE; +import static com.intellij.util.ui.JBUI.ScaleType.SYS_SCALE; public class ImageLoader implements Serializable { private static final Logger LOG = Logger.getInstance("#com.intellij.util.ImageLoader"); - public static final int CACHED_IMAGE_MAX_SIZE = (int)Math.round(Registry.doubleValue("ide.cached.image.max.size") * 1024 * 1024); + public static final long CACHED_IMAGE_MAX_SIZE = (long)(Registry.doubleValue("ide.cached.image.max.size") * 1024 * 1024); private static final ConcurrentMap ourCache = ContainerUtil.createConcurrentSoftValueMap(); @SuppressWarnings({"UnusedDeclaration"}) // set from com.intellij.internal.IconsLoadTime