Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid reflection for FileFormat factories and document tiff-format #1766

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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:
* <dl>
* <dt><code>IMAGE_BMP</code></dt>
* <dt>{@link SWT#IMAGE_BMP}</dt>
* <dd>Windows BMP file format, no compression</dd>
* <dt><code>IMAGE_BMP_RLE</code></dt>
* <dt>{@link SWT#IMAGE_BMP_RLE}</dt>
* <dd>Windows BMP file format, RLE compression if appropriate</dd>
* <dt><code>IMAGE_GIF</code></dt>
* <dt>{@link SWT#IMAGE_GIF}</dt>
* <dd>GIF file format</dd>
* <dt><code>IMAGE_ICO</code></dt>
* <dt>{@link SWT#IMAGE_ICO}</dt>
* <dd>Windows ICO file format</dd>
* <dt><code>IMAGE_JPEG</code></dt>
* <dt>{@link SWT#IMAGE_JPEG}</dt>
* <dd>JPEG file format</dd>
* <dt><code>IMAGE_PNG</code></dt>
* <dt>{@link SWT#IMAGE_PNG}</dt>
* <dd>PNG file format</dd>
* <dt>{@link SWT#IMAGE_TIFF}</dt>
* <dd>TIFF file format</dd>
* </dl>
*
* @param stream the output stream to write the images to
Expand All @@ -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:
* <dl>
* <dt><code>IMAGE_BMP</code></dt>
* <dt>{@link SWT#IMAGE_BMP}</dt>
* <dd>Windows BMP file format, no compression</dd>
* <dt><code>IMAGE_BMP_RLE</code></dt>
* <dt>{@link SWT#IMAGE_BMP_RLE}</dt>
* <dd>Windows BMP file format, RLE compression if appropriate</dd>
* <dt><code>IMAGE_GIF</code></dt>
* <dt>{@link SWT#IMAGE_GIF}</dt>
* <dd>GIF file format</dd>
* <dt><code>IMAGE_ICO</code></dt>
* <dt>{@link SWT#IMAGE_ICO}</dt>
* <dd>Windows ICO file format</dd>
* <dt><code>IMAGE_JPEG</code></dt>
* <dt>{@link SWT#IMAGE_JPEG}</dt>
* <dd>JPEG file format</dd>
* <dt><code>IMAGE_PNG</code></dt>
* <dt>{@link SWT#IMAGE_PNG}</dt>
* <dd>PNG file format</dd>
* <dt>{@link SWT#IMAGE_TIFF}</dt>
* <dd>TIFF file format</dd>
* </dl>
*
* @param filename the name of the file to write the images to
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -15,6 +15,8 @@


import java.io.*;
import java.util.*;
import java.util.function.*;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
Expand All @@ -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<Supplier<FileFormat>> 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.
Expand Down Expand Up @@ -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;
Comment on lines -81 to -82
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can someone explain why some FileFormat implementations could fail to load?
Are there relevant SWT (re-)implementations that have them removed or something like that? Or is this not relevant anymore?

} 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);
}
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,34 +316,37 @@ ImageData[] loadFromFile(String filename) {
*
* It is expressed as one of the following values:
* <dl>
* <dt><code>IMAGE_BMP</code></dt>
* <dt>{@link SWT#IMAGE_BMP}</dt>
* <dd>Windows BMP file format, no compression</dd>
* <dt><code>IMAGE_BMP_RLE</code></dt>
* <dt>{@link SWT#IMAGE_BMP_RLE}</dt>
* <dd>Windows BMP file format, RLE compression if appropriate</dd>
* <dt><code>IMAGE_GIF</code></dt>
* <dt>{@link SWT#IMAGE_GIF}</dt>
* <dd>GIF file format</dd>
* <dt><code>IMAGE_ICO</code></dt>
* <dt>{@link SWT#IMAGE_ICO}</dt>
* <dd>Windows ICO file format</dd>
* <dt><code>IMAGE_JPEG</code></dt>
* <dt>{@link SWT#IMAGE_JPEG}</dt>
* <dd>JPEG file format</dd>
* <dt><code>IMAGE_PNG</code></dt>
* <dt>{@link SWT#IMAGE_PNG}</dt>
* <dd>PNG file format</dd>
* <dt>{@link SWT#IMAGE_TIFF}</dt>
* <dd>TIFF file format</dd>
* </dl>
*/
int getImageFormat(long loader) {
long format = GDK.gdk_pixbuf_loader_get_format(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;
};
}

/**
Expand Down Expand Up @@ -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:
* <dl>
* <dt><code>IMAGE_BMP</code></dt>
* <dt>{@link SWT#IMAGE_BMP}</dt>
* <dd>Windows BMP file format, no compression</dd>
* <dt><code>IMAGE_BMP_RLE</code></dt>
* <dt>{@link SWT#IMAGE_BMP_RLE}</dt>
* <dd>Windows BMP file format, RLE compression if appropriate</dd>
* <dt><code>IMAGE_GIF</code></dt>
* <dt>{@link SWT#IMAGE_GIF}</dt>
* <dd>GIF file format</dd>
* <dt><code>IMAGE_ICO</code></dt>
* <dt>{@link SWT#IMAGE_ICO}</dt>
* <dd>Windows ICO file format</dd>
* <dt><code>IMAGE_JPEG</code></dt>
* <dt>{@link SWT#IMAGE_JPEG}</dt>
* <dd>JPEG file format</dd>
* <dt><code>IMAGE_PNG</code></dt>
* <dt>{@link SWT#IMAGE_PNG}</dt>
* <dd>PNG file format</dd>
* <dt>{@link SWT#IMAGE_TIFF}</dt>
* <dd>TIFF file format</dd>
* </dl>
*
* @param stream the output stream to write the images to
Expand Down Expand Up @@ -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];
Expand All @@ -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:
* <dl>
* <dt><code>IMAGE_BMP</code></dt>
* <dt>{@link SWT#IMAGE_BMP}</dt>
* <dd>Windows BMP file format, no compression</dd>
* <dt><code>IMAGE_BMP_RLE</code></dt>
* <dt>{@link SWT#IMAGE_BMP_RLE}</dt>
* <dd>Windows BMP file format, RLE compression if appropriate</dd>
* <dt><code>IMAGE_GIF</code></dt>
* <dt>{@link SWT#IMAGE_GIF}</dt>
* <dd>GIF file format</dd>
* <dt><code>IMAGE_ICO</code></dt>
* <dt>{@link SWT#IMAGE_ICO}</dt>
* <dd>Windows ICO file format</dd>
* <dt><code>IMAGE_JPEG</code></dt>
* <dt>{@link SWT#IMAGE_JPEG}</dt>
* <dd>JPEG file format</dd>
* <dt><code>IMAGE_PNG</code></dt>
* <dt>{@link SWT#IMAGE_PNG}</dt>
* <dd>PNG file format</dd>
* <dt>{@link SWT#IMAGE_TIFF}</dt>
* <dd>TIFF file format</dd>
* </dl>
*
* @param filename the name of the file to write the images to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
* <dl>
* <dt><code>IMAGE_BMP</code></dt>
* <dt>{@link SWT#IMAGE_BMP}</dt>
* <dd>Windows BMP file format, no compression</dd>
* <dt><code>IMAGE_BMP_RLE</code></dt>
* <dt>{@link SWT#IMAGE_BMP_RLE}</dt>
* <dd>Windows BMP file format, RLE compression if appropriate</dd>
* <dt><code>IMAGE_GIF</code></dt>
* <dt>{@link SWT#IMAGE_GIF}</dt>
* <dd>GIF file format</dd>
* <dt><code>IMAGE_ICO</code></dt>
* <dt>{@link SWT#IMAGE_ICO}</dt>
* <dd>Windows ICO file format</dd>
* <dt><code>IMAGE_JPEG</code></dt>
* <dt>{@link SWT#IMAGE_JPEG}</dt>
* <dd>JPEG file format</dd>
* <dt><code>IMAGE_PNG</code></dt>
* <dt>{@link SWT#IMAGE_PNG}</dt>
* <dd>PNG file format</dd>
* <dt>{@link SWT#IMAGE_TIFF}</dt>
* <dd>TIFF file format</dd>
* </dl>
*
* @param stream the output stream to write the images to
Expand All @@ -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:
* <dl>
* <dt><code>IMAGE_BMP</code></dt>
* <dt>{@link SWT#IMAGE_BMP}</dt>
* <dd>Windows BMP file format, no compression</dd>
* <dt><code>IMAGE_BMP_RLE</code></dt>
* <dt>{@link SWT#IMAGE_BMP_RLE}</dt>
* <dd>Windows BMP file format, RLE compression if appropriate</dd>
* <dt><code>IMAGE_GIF</code></dt>
* <dt>{@link SWT#IMAGE_GIF}</dt>
* <dd>GIF file format</dd>
* <dt><code>IMAGE_ICO</code></dt>
* <dt>{@link SWT#IMAGE_ICO}</dt>
* <dd>Windows ICO file format</dd>
* <dt><code>IMAGE_JPEG</code></dt>
* <dt>{@link SWT#IMAGE_JPEG}</dt>
* <dd>JPEG file format</dd>
* <dt><code>IMAGE_PNG</code></dt>
* <dt>{@link SWT#IMAGE_PNG}</dt>
* <dd>PNG file format</dd>
* <dt>{@link SWT#IMAGE_TIFF}</dt>
* <dd>TIFF file format</dd>
* </dl>
*
* @param filename the name of the file to write the images to
Expand Down
Loading