Skip to content
Merged
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 @@ -14,13 +14,15 @@
package org.eclipse.swt.graphics;

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

import org.eclipse.swt.internal.DPIUtil.*;
import org.eclipse.swt.internal.image.*;

class InternalImageLoader {

static ImageData[] load(InputStream stream, ImageLoader imageLoader) {
return FileFormat.load(stream, imageLoader);
static List<ElementAtZoom<ImageData>> load(InputStream stream, ImageLoader imageLoader, int fileZoom, int targetZoom) {
return FileFormat.load(stream, imageLoader, fileZoom, targetZoom);
}

static void save(OutputStream stream, int format, ImageLoader imageLoader) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import java.util.*;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.DPIUtil.*;
import org.eclipse.swt.internal.image.*;

/**
* Instances of this class are used to load images from,
Expand Down Expand Up @@ -148,10 +150,16 @@ void reset() {
* </ul>
*/
public ImageData[] load(InputStream stream) {
load(stream, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM);
return data;
}

List<ElementAtZoom<ImageData>> load(InputStream stream, int fileZoom, int targetZoom) {
if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
reset();
data = InternalImageLoader.load(stream, this);
return data;
List<ElementAtZoom<ImageData>> images = InternalImageLoader.load(stream, this, fileZoom, targetZoom);
data = images.stream().map(ElementAtZoom::element).toArray(ImageData[]::new);
return images;
}

/**
Expand All @@ -173,9 +181,14 @@ public ImageData[] load(InputStream stream) {
* </ul>
*/
public ImageData[] load(String filename) {
load(filename, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM);
return data;
}

List<ElementAtZoom<ImageData>> load(String filename, int fileZoom, int targetZoom) {
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
try (InputStream stream = new FileInputStream(filename)) {
return load(stream);
return load(stream, fileZoom, targetZoom);
} catch (IOException e) {
SWT.error(SWT.ERROR_IO, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.DPIUtil.*;

/**
* Abstract factory class for loading/unloading images from files or streams
Expand Down Expand Up @@ -54,27 +55,60 @@ public abstract class FileFormat {
} catch (NoClassDefFoundError e) { } // ignore format
}

public static final int DEFAULT_ZOOM = 100;

private static Optional<FileFormat> determineFileFormat(LEDataInputStream stream) {
return FORMAT_FACTORIES.stream().skip(1).map(Supplier::get).filter(f -> {
try {
return f.isFileFormat(stream);
} catch (IOException e) {
return false;
}
}).findFirst();
}

private static final int MAX_SIGNATURE_BYTES = 18 + 2; // e.g. Win-BMP or OS2-BMP plus a safety-margin

public static boolean isDynamicallySizableFormat(InputStream is) {
Optional<FileFormat> format = determineFileFormat(new LEDataInputStream(is, MAX_SIGNATURE_BYTES));
return format.isPresent() && !(format.get() instanceof StaticImageFileFormat);
}

static abstract class StaticImageFileFormat extends FileFormat {

abstract ImageData[] loadFromByteStream();

@Override
List<ElementAtZoom<ImageData>> loadFromByteStream(int fileZoom, int targetZoom) {
return Arrays.stream(loadFromByteStream()).map(d -> new ElementAtZoom<>(d, fileZoom)).toList();
}
}

LEDataInputStream inputStream;
LEDataOutputStream outputStream;
ImageLoader loader;
int compression;

/**
* Return whether or not the specified input stream
* represents a supported file format.
*/
abstract boolean isFileFormat(LEDataInputStream stream);
/**
* Return whether or not the specified input stream represents a supported file
* format.
*/
abstract boolean isFileFormat(LEDataInputStream stream) throws IOException;

abstract ImageData[] loadFromByteStream();
/**
* Format that do not implement {@link StaticImageFileFormat} MUST return
* {@link ImageData} with the specified {@code targetZoom}.
*/
abstract List<ElementAtZoom<ImageData>> loadFromByteStream(int fileZoom, int targetZoom);

/**
* Read the specified input stream, and return the
* device independent image array represented by the stream.
*/
public ImageData[] loadFromStream(LEDataInputStream stream) {
public List<ElementAtZoom<ImageData>> loadFromStream(LEDataInputStream stream, int fileZoom, int targetZoom) {
try {
inputStream = stream;
return loadFromByteStream();
return loadFromByteStream(fileZoom, targetZoom);
} catch (Exception e) {
if (e instanceof IOException) {
SWT.error(SWT.ERROR_IO, e);
Expand All @@ -89,14 +123,14 @@ public ImageData[] loadFromStream(LEDataInputStream stream) {
* Read the specified input stream using the specified loader, and
* return the device independent image array represented by the stream.
*/
public static ImageData[] load(InputStream is, ImageLoader loader) {
public static List<ElementAtZoom<ImageData>> load(InputStream is, ImageLoader loader, int fileZoom, int targetZoom) {
LEDataInputStream stream = new LEDataInputStream(is);
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 fileFormat = determineFileFormat(stream).orElseGet(() -> {
SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
return null;
});
fileFormat.loader = loader;
return fileFormat.loadFromStream(stream);
return fileFormat.loadFromStream(stream, fileZoom, targetZoom);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2012 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 @@ -14,11 +14,13 @@
package org.eclipse.swt.internal.image;


import java.io.*;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import java.io.*;
import org.eclipse.swt.internal.image.FileFormat.*;

public final class GIFFileFormat extends FileFormat {
public final class GIFFileFormat extends StaticImageFileFormat {
String signature;
int screenWidth, screenHeight, backgroundPixel, bitsPerPixel, defaultDepth;
int disposalMethod = 0;
Expand Down Expand Up @@ -51,15 +53,11 @@ static PaletteData grayRamp(int numGrays) {
}

@Override
boolean isFileFormat(LEDataInputStream stream) {
try {
byte[] signature = new byte[3];
stream.read(signature);
stream.unread(signature);
return signature[0] == 'G' && signature[1] == 'I' && signature[2] == 'F';
} catch (Exception e) {
return false;
}
boolean isFileFormat(LEDataInputStream stream) throws IOException {
byte[] signature = new byte[3];
stream.read(signature);
stream.unread(signature);
return signature[0] == 'G' && signature[1] == 'I' && signature[2] == 'F';
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2014 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 @@ -18,11 +18,13 @@
package org.eclipse.swt.internal.image;


import java.io.*;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import java.io.*;
import org.eclipse.swt.internal.image.FileFormat.*;

public final class JPEGFileFormat extends FileFormat {
public final class JPEGFileFormat extends StaticImageFileFormat {
int restartInterval;
JPEGFrameHeader frameHeader;
int imageWidth, imageHeight;
Expand Down Expand Up @@ -1362,16 +1364,14 @@ void inverseDCT(int[] dataUnit) {
}
}
}
@Override
boolean isFileFormat(LEDataInputStream stream) {
try {

@Override
boolean isFileFormat(LEDataInputStream stream) throws IOException {
JPEGStartOfImage soi = new JPEGStartOfImage(stream);
stream.unread(soi.reference);
return soi.verify(); // we no longer check for appN
} catch (Exception e) {
return false;
return soi.verify(); // we no longer check for appN
}
}

boolean isZeroInColumn(int[] dataUnit, int col) {
return dataUnit[col + 8] == 0 && dataUnit[col + 16] == 0
&& dataUnit[col + 24] == 0 && dataUnit[col + 32] == 0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 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 @@ -14,27 +14,26 @@
package org.eclipse.swt.internal.image;


import java.io.*;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import java.io.*;
import org.eclipse.swt.internal.image.FileFormat.*;

public final class OS2BMPFileFormat extends FileFormat {
public final class OS2BMPFileFormat extends StaticImageFileFormat {
static final int BMPFileHeaderSize = 14;
static final int BMPHeaderFixedSize = 12;
int width, height, bitCount;

@Override
boolean isFileFormat(LEDataInputStream stream) {
try {
@Override
boolean isFileFormat(LEDataInputStream stream) throws IOException {
byte[] header = new byte[18];
stream.read(header);
stream.unread(header);
int infoHeaderSize = (header[14] & 0xFF) | ((header[15] & 0xFF) << 8) | ((header[16] & 0xFF) << 16) | ((header[17] & 0xFF) << 24);
return header[0] == 0x42 && header[1] == 0x4D && infoHeaderSize == BMPHeaderFixedSize;
} catch (Exception e) {
return false;
}
}

byte[] loadData(byte[] infoHeader) {
int stride = (width * bitCount + 7) / 8;
stride = (stride + 3) / 4 * 4; // Round up to 4 byte multiple
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2011 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 @@ -19,8 +19,9 @@

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.image.FileFormat.*;

public final class PNGFileFormat extends FileFormat {
public final class PNGFileFormat extends StaticImageFileFormat {
static final int SIGNATURE_LENGTH = 8;
static final int PRIME = 65521;
PngIhdrChunk headerChunk;
Expand Down Expand Up @@ -151,9 +152,9 @@ void unloadIntoByteStream(ImageLoader loader) {
PngEncoder encoder = new PngEncoder(loader);
encoder.encode(outputStream);
}
@Override
boolean isFileFormat(LEDataInputStream stream) {
try {

@Override
boolean isFileFormat(LEDataInputStream stream) throws IOException {
byte[] signature = new byte[SIGNATURE_LENGTH];
stream.read(signature);
stream.unread(signature);
Expand All @@ -166,10 +167,8 @@ boolean isFileFormat(LEDataInputStream stream) {
if ((signature[6] & 0xFF) != 26) return false; //<CTRL/Z>
if ((signature[7] & 0xFF) != 10) return false; //<LINEFEED>
return true;
} catch (Exception e) {
return false;
}
}

/**
* SWT does not support 16-bit depths. If this image uses
* 16-bit depths, convert the data to an 8-bit depth.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2009 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 @@ -14,19 +14,20 @@
package org.eclipse.swt.internal.image;


import java.io.*;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import java.io.*;
import org.eclipse.swt.internal.image.FileFormat.*;

/**
* Baseline TIFF decoder revision 6.0
* Extension T4-encoding CCITT T.4 1D
*/
public final class TIFFFileFormat extends FileFormat {
public final class TIFFFileFormat extends StaticImageFileFormat {

@Override
boolean isFileFormat(LEDataInputStream stream) {
try {
@Override
boolean isFileFormat(LEDataInputStream stream) throws IOException {
byte[] header = new byte[4];
stream.read(header);
stream.unread(header);
Expand All @@ -36,10 +37,7 @@ boolean isFileFormat(LEDataInputStream stream) {
return false;
}
return true;
} catch (Exception e) {
return false;
}
}

@Override
ImageData[] loadFromByteStream() {
Expand Down
Loading
Loading