Skip to content
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
192 changes: 154 additions & 38 deletions src/java.desktop/share/classes/java/awt/image/Raster.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -267,6 +267,10 @@ public static WritableRaster createInterleavedRaster(int dataType,
* @throws IllegalArgumentException if {@code scanlineStride}
* is less than 0
* @throws IllegalArgumentException if {@code pixelStride} is less than 0
* @throws IllegalArgumentException if {@code w * pixelStride} is greater
* than {@code scanlineStride}
Copy link
Member

Choose a reason for hiding this comment

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

Is it still a valid point even for a single-line image, where scanlineStride would not be used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes.

* @throws IllegalArgumentException if the data size need to store all
* lines of the image is greater than {@code Integer.MAX_VALUE}
* @throws NullPointerException if {@code bandOffsets} is null
*/
public static WritableRaster createInterleavedRaster(int dataType,
Expand All @@ -291,8 +295,19 @@ public static WritableRaster createInterleavedRaster(int dataType,
if (scanlineStride < 0) {
throw new IllegalArgumentException("scanlineStride is < 0");
}
int size = scanlineStride * (h - 1) + // first (h - 1) scans
pixelStride * w; // last scan
if (bandOffsets == null) {
throw new NullPointerException("bandOffsets is null");
}
lsz = (long)w * pixelStride;
if (lsz > scanlineStride) {
throw new IllegalArgumentException("w * pixelStride is too large");
}
lsz = (long)scanlineStride * (long)(h - 1) + // first (h - 1) scans
(long)pixelStride * (long)w; // last scan
if (lsz > Integer.MAX_VALUE) {
throw new IllegalArgumentException("size too large to store image");
}
int size = (int)lsz;
Copy link
Member

Choose a reason for hiding this comment

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

Isn't it strange that in this method we reject "empty" images by requiring w and h to be greater than 0, but at the same time accept 0 as scanlineStride and pixelStride? This may result in empty image as well (size == 0), I think it will be rejected later but still should we check it here as well?


if (location == null) {
location = new Point(0, 0);
Expand Down Expand Up @@ -415,6 +430,8 @@ public static WritableRaster createBandedRaster(int dataType,
* is less than 0
* @throws ArrayIndexOutOfBoundsException if {@code bankIndices}
* is {@code null}
* @throws IllegalArgumentException if the data size need to store all
* lines of a bank of the image is greater than {@code Integer.MAX_VALUE}
* @throws NullPointerException if {@code bandOffsets} is {@code null}
*/
public static WritableRaster createBandedRaster(int dataType,
Expand All @@ -423,9 +440,6 @@ public static WritableRaster createBandedRaster(int dataType,
int[] bankIndices,
int[] bandOffsets,
Point location) {
DataBuffer d;
int bands = bandOffsets.length;

if (w <= 0 || h <= 0) {
throw new IllegalArgumentException("w and h must be positive");
}
Expand All @@ -440,7 +454,7 @@ public static WritableRaster createBandedRaster(int dataType,
}
if (bandOffsets == null) {
throw new
ArrayIndexOutOfBoundsException("Band offsets array is null");
NullPointerException("Band offsets array is null");
}
if (location != null) {
if ((w + location.getX() > Integer.MAX_VALUE) ||
Expand All @@ -451,6 +465,9 @@ public static WritableRaster createBandedRaster(int dataType,
}
}

DataBuffer d;
int bands = bandOffsets.length;

// Figure out the #banks and the largest band offset
int maxBank = bankIndices[0];
int maxBandOff = bandOffsets[0];
Expand All @@ -463,9 +480,15 @@ public static WritableRaster createBandedRaster(int dataType,
}
}
int banks = maxBank + 1;
int size = maxBandOff +
scanlineStride * (h - 1) + // first (h - 1) scans
w; // last scan

lsz = (long) maxBandOff +
(long)scanlineStride * (h - 1) + // first (h - 1) scans
w; // last scan
if (lsz > Integer.MAX_VALUE) {
throw new IllegalArgumentException("storage size is too large");
}

int size = (int)lsz;

switch(dataType) {
case DataBuffer.TYPE_BYTE:
Expand Down Expand Up @@ -508,11 +531,14 @@ public static WritableRaster createBandedRaster(int dataType,
* @param location the upper-left corner of the {@code Raster}
* @return a WritableRaster object with the specified data type,
* width, height, and band masks.
* @throws RasterFormatException if {@code w} or {@code h}
* is less than or equal to zero, or computing either
* @throws NullPointerException if {@code bandMasks} is null
* @throws IllegalArgumentException if {@code w} and {@code h}
* are not both greater than 0
* @throws IllegalArgumentException if the product of {@code w}
* and {@code h} is greater than {@code Integer.MAX_VALUE}
* @throws RasterFormatException if computing either
* {@code location.x + w} or
* {@code location.y + h} results in integer
* overflow
* {@code location.y + h} results in integer overflow
* @throws IllegalArgumentException if {@code dataType} is not
* one of the supported data types, which are
* {@code DataBuffer.TYPE_BYTE},
Expand All @@ -525,6 +551,24 @@ public static WritableRaster createPackedRaster(int dataType,
Point location) {
DataBuffer d;

if (w <= 0 || h <= 0) {
throw new IllegalArgumentException("w and h must be positive");
}
long lsz = (long)w * h;
if (lsz > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Dimensions (width="+w+
" height="+h+") are too large");
}

if (location != null) {
if ((w + location.getX() > Integer.MAX_VALUE) ||
(h + location.getY() > Integer.MAX_VALUE)) {
throw new RasterFormatException(
"location.x + w and location.y + h " +
" cannot exceed Integer.MAX_VALUE");
}
}

switch(dataType) {
case DataBuffer.TYPE_BYTE:
d = new DataBufferByte(w*h);
Expand Down Expand Up @@ -573,17 +617,19 @@ public static WritableRaster createPackedRaster(int dataType,
* @param location the upper-left corner of the {@code Raster}
* @return a WritableRaster object with the specified data type,
* width, height, number of bands, and bits per band.
* @throws RasterFormatException if {@code w} or {@code h}
* is less than or equal to zero, or computing either
* {@code location.x + w} or
* {@code location.y + h} results in integer
* overflow
* @throws IllegalArgumentException if {@code bitsPerBand} or
* {@code bands} is not greater than zero
* @throws IllegalArgumentException if the product of
* {@code bitsPerBand} and {@code bands} is
* greater than the number of bits held by
* {@code dataType}
* @throws IllegalArgumentException if {@code bitsPerBand} or
* {@code bands} is not greater than zero
* @throws IllegalArgumentException if {@code w} and {@code h}
* are not both greater than 0
* @throws IllegalArgumentException if the product of {@code w}
* and {@code h} is greater than {@code Integer.MAX_VALUE}
* @throws RasterFormatException if computing either
* {@code location.x + w} or
* {@code location.y + h} results in integer overflow
* @throws IllegalArgumentException if {@code dataType} is not
* one of the supported data types, which are
* {@code DataBuffer.TYPE_BYTE},
Expand All @@ -607,18 +653,37 @@ public static WritableRaster createPackedRaster(int dataType,
") must be greater than 0");
}

if (w <= 0 || h <= 0) {
throw new IllegalArgumentException("w and h must be positive");
}
long lsz = (long)w * h;
if (lsz > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Dimensions (width="+w+
" height="+h+") are too large");
}

if (location != null) {
if ((w + location.getX() > Integer.MAX_VALUE) ||
(h + location.getY() > Integer.MAX_VALUE)) {
throw new RasterFormatException(
"location.x + w and location.y + h " +
" cannot exceed Integer.MAX_VALUE");
}
}

int shift = (bands-1)*bitsPerBand;

/* Make sure the total mask size will fit in the data type */
if (shift+bitsPerBand > DataBuffer.getDataTypeSize(dataType)) {
throw new IllegalArgumentException("bitsPerBand("+
bitsPerBand+") * bands is "+
" greater than data type "+
"size.");
}
if (bands != 1) {
int[] masks = new int[bands];
int mask = (1 << bitsPerBand) - 1;
int shift = (bands-1)*bitsPerBand;

/* Make sure the total mask size will fit in the data type */
if (shift+bitsPerBand > DataBuffer.getDataTypeSize(dataType)) {
throw new IllegalArgumentException("bitsPerBand("+
bitsPerBand+") * bands is "+
" greater than data type "+
"size.");
}

switch(dataType) {
case DataBuffer.TYPE_BYTE:
case DataBuffer.TYPE_USHORT:
Expand Down Expand Up @@ -883,11 +948,14 @@ public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
* @return a WritableRaster object with the specified
* {@code DataBuffer}, width, height, scanline stride,
* and band masks.
* @throws RasterFormatException if {@code w} or {@code h}
* is less than or equal to zero, or computing either
* @throws NullPointerException if {@code bandMasks} is null
* @throws IllegalArgumentException if {@code w} and {@code h}
* are not both greater than 0
* @throws IllegalArgumentException if the product of {@code w}
* and {@code h} is greater than {@code Integer.MAX_VALUE}
* @throws RasterFormatException if computing either
* {@code location.x + w} or
* {@code location.y + h} results in integer
* overflow
* {@code location.y + h} results in integer overflow
* @throws IllegalArgumentException if {@code dataBuffer} is not
* one of the supported data types, which are
* {@code DataBuffer.TYPE_BYTE},
Expand All @@ -906,6 +974,25 @@ public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
if (dataBuffer == null) {
throw new NullPointerException("DataBuffer cannot be null");
}

if (w <= 0 || h <= 0) {
throw new IllegalArgumentException("w and h must be positive");
}
long lsz = (long)w * h;
if (lsz > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Dimensions (width="+w+
" height="+h+") are too large");
}

if (location != null) {
if ((w + location.getX() > Integer.MAX_VALUE) ||
(h + location.getY() > Integer.MAX_VALUE)) {
throw new RasterFormatException(
"location.x + w and location.y + h " +
" cannot exceed Integer.MAX_VALUE");
}
}

if (location == null) {
location = new Point(0,0);
}
Expand Down Expand Up @@ -960,18 +1047,22 @@ public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
* @return a WritableRaster object with the specified
* {@code DataBuffer}, width, height, and
* bits per pixel.
* @throws RasterFormatException if {@code w} or {@code h}
* is less than or equal to zero, or computing either
* @throws IllegalArgumentException if {@code w} and {@code h}
* are not both greater than 0
* @throws IllegalArgumentException if the product of {@code w}
* and {@code h} is greater than {@code Integer.MAX_VALUE}
* @throws RasterFormatException if computing either
* {@code location.x + w} or
* {@code location.y + h} results in integer
* overflow
* {@code location.y + h} results in integer overflow
* @throws IllegalArgumentException if {@code dataType} is not
* one of the supported data types, which are
* {@code DataBuffer.TYPE_BYTE},
* {@code DataBuffer.TYPE_USHORT}
* or {@code DataBuffer.TYPE_INT}
* @throws RasterFormatException if {@code dataBuffer} has more
* than one bank.
* @throws RasterFormatException if {@code bitsPixel} is less than 1 or
* not a power of 2 or exceeds the {@code dataBuffer} element size.
* @throws NullPointerException if {@code dataBuffer} is null
*/
public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
Expand All @@ -982,6 +1073,25 @@ public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
if (dataBuffer == null) {
throw new NullPointerException("DataBuffer cannot be null");
}
if (w <= 0 || h <= 0) {
throw new IllegalArgumentException("w and h must be positive");
}
long lsz = (long)w * h;

if (lsz > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Dimensions (width="+w+
" height="+h+") are too large");
}

if (location != null) {
if ((w + location.getX() > Integer.MAX_VALUE) ||
(h + location.getY() > Integer.MAX_VALUE)) {
throw new RasterFormatException(
"location.x + w and location.y + h " +
" cannot exceed Integer.MAX_VALUE");
}
}

if (location == null) {
location = new Point(0,0);
}
Expand All @@ -1000,6 +1110,12 @@ public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
" must only have 1 bank.");
}

if ((bitsPerPixel < 1) || (bitsPerPixel > DataBuffer.getDataTypeSize(dataType))) {
// NB MPPSM checks power of 2 condition
throw new
RasterFormatException("bitsPerPixel must be > 0 and a power of 2 that " +
"does not exceed data buffer element size");
}
MultiPixelPackedSampleModel mppsm =
new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);

Expand Down
Loading