-
Enhancement
-
Resolution: Unresolved
-
P3
-
9
-
x86_64
-
linux
A DESCRIPTION OF THE REQUEST :
WritableRaster should provide full information on its internal data structure. This will include the offset, row stride, and pixel stride. This information was previously provided via private Sun API's which are no longer (practically) accessible as of Java 9.
The most important information missing is the offset. The offset inside an image is required for subimages in that it specifies the start of the subimage data. Previously all the children of WritableRaster provided a function to get the offset via getDataOffset(). WritableRaster itself does not provide access to this information. Other information, such as the row stride, cannot be accessed directly like it used to either (via getScanlineStride()) but is estimated using the image width and the getNumDataElements().
JUSTIFICATION :
Prior to Java 9 the internal Sun API was used to access the internal structure of BufferedImages. This was required to read and manipulate BufferedImage data quickly. Access through the high level API is painfully slow and prevents Java from being used in real time applications. Now that (for all practical purposes) the Sun API's are no longer accessible high level interfaces are used to read the internal data stored in a BufferedImage. All the required information can be read directly or inferred besides the offset.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Source code example using the internal API that works. This converts a 3 band color image into a gray scale image by averaging pixel intensity. Not all of the information below is currently available using the higher level WritableRaster class.
public static void bufferedToGray(ByteInterleavedRaster src, byte[] grayImage ) {
// For sake of simplicity, in this example it is assumed that both images and the same width and height
int width = src.getWidth();
int height = src.getHeight();
byte[] srcData = src.getDataStorage();
int srcNumBands = src.getNumBands();
int srcStride = src.getScanlineStride();
int srcOffset = src.getDataOffset(0);
for (int i = 1; i < src.getNumBands(); i++) {
srcOffset = Math.min(srcOffset,src.getDataOffset(i));
}
int srcStrideDiff = srcStride - src.getPixelStride() * width;
if (srcNumBands == 3) {
int indexSrc = srcOffset;
for (int y = 0; y < height; y++) {
int indexDst = width * y;
int indexDstEnd = indexDst + width;
for (; indexDst < indexDstEnd; indexDst++) {
int r = srcData[indexSrc++] & 0xFF;
int g = srcData[indexSrc++] & 0xFF;
int b = srcData[indexSrc++] & 0xFF;
int ave = (r + g + b) / 3;
grayImage[indexDst] = (byte) ave;
}
indexSrc += srcStrideDiff;
}
} else {
throw new RuntimeException("Ignore these cases");
}
}
CUSTOMER SUBMITTED WORKAROUND :
There currently is no workaround for subimages. Access to offset information is required for those.
WritableRaster should provide full information on its internal data structure. This will include the offset, row stride, and pixel stride. This information was previously provided via private Sun API's which are no longer (practically) accessible as of Java 9.
The most important information missing is the offset. The offset inside an image is required for subimages in that it specifies the start of the subimage data. Previously all the children of WritableRaster provided a function to get the offset via getDataOffset(). WritableRaster itself does not provide access to this information. Other information, such as the row stride, cannot be accessed directly like it used to either (via getScanlineStride()) but is estimated using the image width and the getNumDataElements().
JUSTIFICATION :
Prior to Java 9 the internal Sun API was used to access the internal structure of BufferedImages. This was required to read and manipulate BufferedImage data quickly. Access through the high level API is painfully slow and prevents Java from being used in real time applications. Now that (for all practical purposes) the Sun API's are no longer accessible high level interfaces are used to read the internal data stored in a BufferedImage. All the required information can be read directly or inferred besides the offset.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Source code example using the internal API that works. This converts a 3 band color image into a gray scale image by averaging pixel intensity. Not all of the information below is currently available using the higher level WritableRaster class.
public static void bufferedToGray(ByteInterleavedRaster src, byte[] grayImage ) {
// For sake of simplicity, in this example it is assumed that both images and the same width and height
int width = src.getWidth();
int height = src.getHeight();
byte[] srcData = src.getDataStorage();
int srcNumBands = src.getNumBands();
int srcStride = src.getScanlineStride();
int srcOffset = src.getDataOffset(0);
for (int i = 1; i < src.getNumBands(); i++) {
srcOffset = Math.min(srcOffset,src.getDataOffset(i));
}
int srcStrideDiff = srcStride - src.getPixelStride() * width;
if (srcNumBands == 3) {
int indexSrc = srcOffset;
for (int y = 0; y < height; y++) {
int indexDst = width * y;
int indexDstEnd = indexDst + width;
for (; indexDst < indexDstEnd; indexDst++) {
int r = srcData[indexSrc++] & 0xFF;
int g = srcData[indexSrc++] & 0xFF;
int b = srcData[indexSrc++] & 0xFF;
int ave = (r + g + b) / 3;
grayImage[indexDst] = (byte) ave;
}
indexSrc += srcStrideDiff;
}
} else {
throw new RuntimeException("Ignore these cases");
}
}
CUSTOMER SUBMITTED WORKAROUND :
There currently is no workaround for subimages. Access to offset information is required for those.