# Description of Changes Please provide a summary of the changes, including: This PR refactors multiple instances of type casting throughout the codebase by replacing them with Java's pattern matching for `instanceof`. This approach eliminates redundant type casting, improves code readability, and reduces the chances of `ClassCastException`. The changes primarily affect authentication handling, PDF processing, and certificate validation. ### Key Changes: - Replaced traditional `instanceof` checks followed by explicit casting with pattern matching. - Improved readability and maintainability of type-related operations. - Applied changes across security modules, PDF utilities, and image processing functions. This refactor does not introduce new functionality but enhances the robustness and clarity of the existing code. pending until #2818 is published --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details.
123 lines
4.5 KiB
Java
123 lines
4.5 KiB
Java
package stirling.software.SPDF.utils;
|
|
|
|
import java.awt.geom.AffineTransform;
|
|
import java.awt.image.*;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.nio.ByteBuffer;
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
import com.drew.imaging.ImageMetadataReader;
|
|
import com.drew.imaging.ImageProcessingException;
|
|
import com.drew.metadata.Metadata;
|
|
import com.drew.metadata.MetadataException;
|
|
import com.drew.metadata.exif.ExifSubIFDDirectory;
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
@Slf4j
|
|
public class ImageProcessingUtils {
|
|
|
|
static BufferedImage convertColorType(BufferedImage sourceImage, String colorType) {
|
|
BufferedImage convertedImage;
|
|
switch (colorType) {
|
|
case "greyscale":
|
|
convertedImage =
|
|
new BufferedImage(
|
|
sourceImage.getWidth(),
|
|
sourceImage.getHeight(),
|
|
BufferedImage.TYPE_BYTE_GRAY);
|
|
convertedImage.getGraphics().drawImage(sourceImage, 0, 0, null);
|
|
break;
|
|
case "blackwhite":
|
|
convertedImage =
|
|
new BufferedImage(
|
|
sourceImage.getWidth(),
|
|
sourceImage.getHeight(),
|
|
BufferedImage.TYPE_BYTE_BINARY);
|
|
convertedImage.getGraphics().drawImage(sourceImage, 0, 0, null);
|
|
break;
|
|
default: // full color
|
|
convertedImage = sourceImage;
|
|
break;
|
|
}
|
|
return convertedImage;
|
|
}
|
|
|
|
public static byte[] getImageData(BufferedImage image) {
|
|
DataBuffer dataBuffer = image.getRaster().getDataBuffer();
|
|
if (dataBuffer instanceof DataBufferByte dataBufferByte) {
|
|
return dataBufferByte.getData();
|
|
} else if (dataBuffer instanceof DataBufferInt dataBufferInt) {
|
|
int[] intData = dataBufferInt.getData();
|
|
ByteBuffer byteBuffer = ByteBuffer.allocate(intData.length * 4);
|
|
byteBuffer.asIntBuffer().put(intData);
|
|
return byteBuffer.array();
|
|
} else {
|
|
int width = image.getWidth();
|
|
int height = image.getHeight();
|
|
byte[] data = new byte[width * height * 3];
|
|
int index = 0;
|
|
for (int y = 0; y < height; y++) {
|
|
for (int x = 0; x < width; x++) {
|
|
int rgb = image.getRGB(x, y);
|
|
data[index++] = (byte) ((rgb >> 16) & 0xFF); // Red
|
|
data[index++] = (byte) ((rgb >> 8) & 0xFF); // Green
|
|
data[index++] = (byte) (rgb & 0xFF); // Blue
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
}
|
|
|
|
public static double extractImageOrientation(InputStream is) throws IOException {
|
|
try {
|
|
Metadata metadata = ImageMetadataReader.readMetadata(is);
|
|
ExifSubIFDDirectory directory =
|
|
metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
|
|
if (directory == null) {
|
|
return 0;
|
|
}
|
|
int orientationTag = directory.getInt(ExifSubIFDDirectory.TAG_ORIENTATION);
|
|
switch (orientationTag) {
|
|
case 1:
|
|
return 0;
|
|
case 6:
|
|
return 90;
|
|
case 3:
|
|
return 180;
|
|
case 8:
|
|
return 270;
|
|
default:
|
|
log.warn("Unknown orientation tag: {}", orientationTag);
|
|
return 0;
|
|
}
|
|
} catch (ImageProcessingException | MetadataException e) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public static BufferedImage applyOrientation(BufferedImage image, double orientation) {
|
|
if (orientation == 0) {
|
|
return image;
|
|
}
|
|
AffineTransform transform =
|
|
AffineTransform.getRotateInstance(
|
|
Math.toRadians(orientation),
|
|
image.getWidth() / 2.0,
|
|
image.getHeight() / 2.0);
|
|
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
|
|
return op.filter(image, null);
|
|
}
|
|
|
|
public static BufferedImage loadImageWithExifOrientation(MultipartFile file)
|
|
throws IOException {
|
|
BufferedImage image = ImageIO.read(file.getInputStream());
|
|
double orientation = extractImageOrientation(file.getInputStream());
|
|
return applyOrientation(image, orientation);
|
|
}
|
|
}
|