Skip to content

Commit

Permalink
Avoid reflection for FileFormat factories and document tiff-format
Browse files Browse the repository at this point in the history
  • Loading branch information
HannesWell committed Jan 27, 2025
1 parent 56767ec commit 5edc31d
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 98 deletions.
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;
} 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

0 comments on commit 5edc31d

Please sign in to comment.