From 5edc31dddf9ee66a43bc53177672d8df61fd429a Mon Sep 17 00:00:00 2001 From: Hannes Wellmann Date: Sat, 25 Jan 2025 19:25:59 +0100 Subject: [PATCH] Avoid reflection for FileFormat factories and document tiff-format --- .../org/eclipse/swt/graphics/ImageLoader.java | 28 ++++--- .../swt/internal/image/FileFormat.java | 71 ++++++++-------- .../swt/internal/image/WinICOFileFormat.java | 7 +- .../org/eclipse/swt/graphics/ImageLoader.java | 83 ++++++++++--------- .../org/eclipse/swt/graphics/ImageLoader.java | 28 ++++--- 5 files changed, 119 insertions(+), 98 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/ImageLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/ImageLoader.java index 376d18316f0..a7ef9e4d0f0 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/ImageLoader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/ImageLoader.java @@ -187,18 +187,20 @@ public ImageData[] load(String filename) { * Saves the image data in this ImageLoader to the specified stream. * The format parameter can have one of the following values: *
- *
IMAGE_BMP
+ *
{@link SWT#IMAGE_BMP}
*
Windows BMP file format, no compression
- *
IMAGE_BMP_RLE
+ *
{@link SWT#IMAGE_BMP_RLE}
*
Windows BMP file format, RLE compression if appropriate
- *
IMAGE_GIF
+ *
{@link SWT#IMAGE_GIF}
*
GIF file format
- *
IMAGE_ICO
+ *
{@link SWT#IMAGE_ICO}
*
Windows ICO file format
- *
IMAGE_JPEG
+ *
{@link SWT#IMAGE_JPEG}
*
JPEG file format
- *
IMAGE_PNG
+ *
{@link SWT#IMAGE_PNG}
*
PNG file format
+ *
{@link SWT#IMAGE_TIFF}
+ *
TIFF file format
*
* * @param stream the output stream to write the images to @@ -222,18 +224,20 @@ public void save(OutputStream stream, int format) { * Saves the image data in this ImageLoader to a file with the specified name. * The format parameter can have one of the following values: *
- *
IMAGE_BMP
+ *
{@link SWT#IMAGE_BMP}
*
Windows BMP file format, no compression
- *
IMAGE_BMP_RLE
+ *
{@link SWT#IMAGE_BMP_RLE}
*
Windows BMP file format, RLE compression if appropriate
- *
IMAGE_GIF
+ *
{@link SWT#IMAGE_GIF}
*
GIF file format
- *
IMAGE_ICO
+ *
{@link SWT#IMAGE_ICO}
*
Windows ICO file format
- *
IMAGE_JPEG
+ *
{@link SWT#IMAGE_JPEG}
*
JPEG file format
- *
IMAGE_PNG
+ *
{@link SWT#IMAGE_PNG}
*
PNG file format
+ *
{@link SWT#IMAGE_TIFF}
+ *
TIFF file format
*
* * @param filename the name of the file to write the images to diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java index 943cddc9fd4..c3b58ea14c8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -15,6 +15,8 @@ import java.io.*; +import java.util.*; +import java.util.function.*; import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; @@ -24,22 +26,39 @@ * in various image file formats. */ public abstract class FileFormat { - static final String FORMAT_PACKAGE = "org.eclipse.swt.internal.image"; //$NON-NLS-1$ - static final String FORMAT_SUFFIX = "FileFormat"; //$NON-NLS-1$ - static final String[] FORMATS = {"WinBMP", "WinBMP", "GIF", "WinICO", "JPEG", "PNG", "TIFF", "OS2BMP"}; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$//$NON-NLS-5$ //$NON-NLS-6$//$NON-NLS-7$//$NON-NLS-8$ + private static final List> FORMAT_FACTORIES = new ArrayList<>(); + static { + try { + FORMAT_FACTORIES.add(WinBMPFileFormat::new); + } catch (NoClassDefFoundError e) { } // ignore format + try { + FORMAT_FACTORIES.add(WinBMPFileFormat::new); + } catch (NoClassDefFoundError e) { } // ignore format + try { + FORMAT_FACTORIES.add(GIFFileFormat::new); + } catch (NoClassDefFoundError e) { } // ignore format + try { + FORMAT_FACTORIES.add(WinICOFileFormat::new); + } catch (NoClassDefFoundError e) { } // ignore format + try { + FORMAT_FACTORIES.add(JPEGFileFormat::new); + } catch (NoClassDefFoundError e) { } // ignore format + try { + FORMAT_FACTORIES.add(PNGFileFormat::new); + } catch (NoClassDefFoundError e) { } // ignore format + try { + FORMAT_FACTORIES.add(TIFFFileFormat::new); + } catch (NoClassDefFoundError e) { } // ignore format + try { + FORMAT_FACTORIES.add(OS2BMPFileFormat::new); + } catch (NoClassDefFoundError e) { } // ignore format + } LEDataInputStream inputStream; LEDataOutputStream outputStream; ImageLoader loader; int compression; -static FileFormat getFileFormat (LEDataInputStream stream, String format) throws Exception { - Class clazz = Class.forName(FORMAT_PACKAGE + '.' + format + FORMAT_SUFFIX); - FileFormat fileFormat = (FileFormat) clazz.getDeclaredConstructor().newInstance(); - if (fileFormat.isFileFormat(stream)) return fileFormat; - return null; -} - /** * Return whether or not the specified input stream * represents a supported file format. @@ -71,20 +90,11 @@ public ImageData[] loadFromStream(LEDataInputStream stream) { * return the device independent image array represented by the stream. */ public static ImageData[] load(InputStream is, ImageLoader loader) { - FileFormat fileFormat = null; LEDataInputStream stream = new LEDataInputStream(is); - for (int i = 1; i < FORMATS.length; i++) { - if (FORMATS[i] != null) { - try { - fileFormat = getFileFormat (stream, FORMATS[i]); - if (fileFormat != null) break; - } catch (ClassNotFoundException e) { - FORMATS[i] = null; - } catch (Exception e) { - } - } - } - if (fileFormat == null) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT); + FileFormat fileFormat = FORMAT_FACTORIES.stream().skip(1) // + .map(Supplier::get).filter(f -> f.isFileFormat(stream)) // + .findFirst().orElse(null); + if (fileFormat == null) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT); fileFormat.loader = loader; return fileFormat.loadFromStream(stream); } @@ -94,18 +104,13 @@ public static ImageData[] load(InputStream is, ImageLoader loader) { * to the specified output stream using the specified file format. */ public static void save(OutputStream os, int format, ImageLoader loader) { - if (format < 0 || format >= FORMATS.length) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT); - if (FORMATS[format] == null) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT); + if (format < 0 || format >= FORMAT_FACTORIES.size()) { + SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT); + } if (loader.data == null || loader.data.length < 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); LEDataOutputStream stream = new LEDataOutputStream(os); - FileFormat fileFormat = null; - try { - Class clazz = Class.forName(FORMAT_PACKAGE + '.' + FORMATS[format] + FORMAT_SUFFIX); - fileFormat = (FileFormat) clazz.getDeclaredConstructor().newInstance(); - } catch (Exception e) { - SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT); - } + FileFormat fileFormat = FORMAT_FACTORIES.get(format).get(); if (format == SWT.IMAGE_BMP_RLE) { switch (loader.data[0].depth) { case 8: fileFormat.compression = 1; break; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinICOFileFormat.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinICOFileFormat.java index f06baa3bb56..6d6a981dcd5 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinICOFileFormat.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinICOFileFormat.java @@ -14,9 +14,10 @@ package org.eclipse.swt.internal.image; +import java.io.*; + import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; -import java.io.*; public final class WinICOFileFormat extends FileFormat { @@ -130,8 +131,8 @@ ImageData[] loadFromByteStream() { */ ImageData loadIcon(int[] iconHeader) { try { - FileFormat png = getFileFormat(inputStream, "PNG"); - if (png != null) { + FileFormat png = new PNGFileFormat(); + if (png.isFileFormat(inputStream)) { png.loader = this.loader; return png.loadFromStream(inputStream)[0]; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java index 67336de12bc..bc2aaf3bed2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java @@ -316,18 +316,20 @@ ImageData[] loadFromFile(String filename) { * * It is expressed as one of the following values: *
- *
IMAGE_BMP
+ *
{@link SWT#IMAGE_BMP}
*
Windows BMP file format, no compression
- *
IMAGE_BMP_RLE
+ *
{@link SWT#IMAGE_BMP_RLE}
*
Windows BMP file format, RLE compression if appropriate
- *
IMAGE_GIF
+ *
{@link SWT#IMAGE_GIF}
*
GIF file format
- *
IMAGE_ICO
+ *
{@link SWT#IMAGE_ICO}
*
Windows ICO file format
- *
IMAGE_JPEG
+ *
{@link SWT#IMAGE_JPEG}
*
JPEG file format
- *
IMAGE_PNG
+ *
{@link SWT#IMAGE_PNG}
*
PNG file format
+ *
{@link SWT#IMAGE_TIFF}
+ *
TIFF file format
*
*/ int getImageFormat(long loader) { @@ -335,15 +337,16 @@ int getImageFormat(long loader) { long name = GDK.gdk_pixbuf_format_get_name(format); String nameStr = Converter.cCharPtrToJavaString(name, false); OS.g_free(name); - switch (nameStr) { - case "bmp": return SWT.IMAGE_BMP; - case "gif": return SWT.IMAGE_GIF; - case "ico": return SWT.IMAGE_ICO; - case "jpeg": return SWT.IMAGE_JPEG; - case "png": return SWT.IMAGE_PNG; - case "svg": return SWT.IMAGE_SVG; - default: return SWT.IMAGE_UNDEFINED; - } + return switch (nameStr) { + case "bmp" -> SWT.IMAGE_BMP; + case "gif" -> SWT.IMAGE_GIF; + case "ico" -> SWT.IMAGE_ICO; + case "jpeg" -> SWT.IMAGE_JPEG; + case "png" -> SWT.IMAGE_PNG; + case "tiff" -> SWT.IMAGE_TIFF; + case "svg" -> SWT.IMAGE_SVG; + default -> SWT.IMAGE_UNDEFINED; + }; } /** @@ -423,18 +426,20 @@ static long gdk_pixbuf_new_from_file(String filename) { * Saves the image data in this ImageLoader to the specified stream. * The format parameter can have one of the following values: *
- *
IMAGE_BMP
+ *
{@link SWT#IMAGE_BMP}
*
Windows BMP file format, no compression
- *
IMAGE_BMP_RLE
+ *
{@link SWT#IMAGE_BMP_RLE}
*
Windows BMP file format, RLE compression if appropriate
- *
IMAGE_GIF
+ *
{@link SWT#IMAGE_GIF}
*
GIF file format
- *
IMAGE_ICO
+ *
{@link SWT#IMAGE_ICO}
*
Windows ICO file format
- *
IMAGE_JPEG
+ *
{@link SWT#IMAGE_JPEG}
*
JPEG file format
- *
IMAGE_PNG
+ *
{@link SWT#IMAGE_PNG}
*
PNG file format
+ *
{@link SWT#IMAGE_TIFF}
+ *
TIFF file format
*
* * @param stream the output stream to write the images to @@ -539,17 +544,17 @@ public void save(OutputStream stream, int format) { } // Write pixbuf to byte array and then to OutputStream - String typeStr = ""; - switch (format) { - case SWT.IMAGE_BMP_RLE: typeStr = "bmp"; break; - case SWT.IMAGE_BMP: typeStr = "bmp"; break; - case SWT.IMAGE_GIF: typeStr = "gif"; break; - case SWT.IMAGE_ICO: typeStr = "ico"; break; - case SWT.IMAGE_JPEG: typeStr = "jpeg"; break; - case SWT.IMAGE_PNG: typeStr = "png"; break; - case SWT.IMAGE_TIFF: typeStr = "tiff"; break; - case SWT.IMAGE_SVG: typeStr = "svg"; break; - } + String typeStr = switch (format) { + case SWT.IMAGE_BMP_RLE -> "bmp"; + case SWT.IMAGE_BMP -> "bmp"; + case SWT.IMAGE_GIF -> "gif"; + case SWT.IMAGE_ICO -> "ico"; + case SWT.IMAGE_JPEG -> "jpeg"; + case SWT.IMAGE_PNG -> "png"; + case SWT.IMAGE_TIFF -> "tiff"; + case SWT.IMAGE_SVG -> "svg"; + default -> ""; + }; byte [] type = Converter.wcsToMbcs(typeStr, true); long [] buffer = new long [1]; @@ -575,18 +580,20 @@ public void save(OutputStream stream, int format) { * Saves the image data in this ImageLoader to a file with the specified name. * The format parameter can have one of the following values: *
- *
IMAGE_BMP
+ *
{@link SWT#IMAGE_BMP}
*
Windows BMP file format, no compression
- *
IMAGE_BMP_RLE
+ *
{@link SWT#IMAGE_BMP_RLE}
*
Windows BMP file format, RLE compression if appropriate
- *
IMAGE_GIF
+ *
{@link SWT#IMAGE_GIF}
*
GIF file format
- *
IMAGE_ICO
+ *
{@link SWT#IMAGE_ICO}
*
Windows ICO file format
- *
IMAGE_JPEG
+ *
{@link SWT#IMAGE_JPEG}
*
JPEG file format
- *
IMAGE_PNG
+ *
{@link SWT#IMAGE_PNG}
*
PNG file format
+ *
{@link SWT#IMAGE_TIFF}
+ *
TIFF file format
*
* * @param filename the name of the file to write the images to diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/ImageLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/ImageLoader.java index da78f52d244..567bf11f2cd 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/ImageLoader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/ImageLoader.java @@ -187,18 +187,20 @@ public ImageData[] load(String filename) { * Saves the image data in this ImageLoader to the specified stream. * The format parameter can have one of the following values: *
- *
IMAGE_BMP
+ *
{@link SWT#IMAGE_BMP}
*
Windows BMP file format, no compression
- *
IMAGE_BMP_RLE
+ *
{@link SWT#IMAGE_BMP_RLE}
*
Windows BMP file format, RLE compression if appropriate
- *
IMAGE_GIF
+ *
{@link SWT#IMAGE_GIF}
*
GIF file format
- *
IMAGE_ICO
+ *
{@link SWT#IMAGE_ICO}
*
Windows ICO file format
- *
IMAGE_JPEG
+ *
{@link SWT#IMAGE_JPEG}
*
JPEG file format
- *
IMAGE_PNG
+ *
{@link SWT#IMAGE_PNG}
*
PNG file format
+ *
{@link SWT#IMAGE_TIFF}
+ *
TIFF file format
*
* * @param stream the output stream to write the images to @@ -222,18 +224,20 @@ public void save(OutputStream stream, int format) { * Saves the image data in this ImageLoader to a file with the specified name. * The format parameter can have one of the following values: *
- *
IMAGE_BMP
+ *
{@link SWT#IMAGE_BMP}
*
Windows BMP file format, no compression
- *
IMAGE_BMP_RLE
+ *
{@link SWT#IMAGE_BMP_RLE}
*
Windows BMP file format, RLE compression if appropriate
- *
IMAGE_GIF
+ *
{@link SWT#IMAGE_GIF}
*
GIF file format
- *
IMAGE_ICO
+ *
{@link SWT#IMAGE_ICO}
*
Windows ICO file format
- *
IMAGE_JPEG
+ *
{@link SWT#IMAGE_JPEG}
*
JPEG file format
- *
IMAGE_PNG
+ *
{@link SWT#IMAGE_PNG}
*
PNG file format
+ *
{@link SWT#IMAGE_TIFF}
+ *
TIFF file format
*
* * @param filename the name of the file to write the images to