@ -44,7 +44,9 @@ public class DefaultImageRaster extends ImageRaster {
private final ImageCodec codec ;
private final int width ;
private final int height ;
private final int offset ;
private final byte [ ] temp ;
private final boolean convertToLinear ;
private int slice ;
private void rangeCheck ( int x , int y ) {
@ -53,13 +55,40 @@ public class DefaultImageRaster extends ImageRaster {
}
}
public DefaultImageRaster ( Image image , int slice ) {
public DefaultImageRaster ( Image image , int slice , int mipMapLevel , boolean convertToLinear ) {
int [ ] mipMapSizes = image . getMipMapSizes ( ) ;
int availableMips = mipMapSizes ! = null ? mipMapSizes . length : 1 ;
if ( mipMapLevel > = availableMips ) {
throw new IllegalStateException ( "Cannot create image raster for mipmap level #" + mipMapLevel + ". "
+ "Image only has " + availableMips + " mipmap levels." ) ;
}
if ( image . hasMipmaps ( ) ) {
this . width = Math . max ( 1 , image . getWidth ( ) > > mipMapLevel ) ;
this . height = Math . max ( 1 , image . getHeight ( ) > > mipMapLevel ) ;
int mipOffset = 0 ;
for ( int i = 0 ; i < mipMapLevel ; i + + ) {
mipOffset + = mipMapSizes [ i ] ;
}
this . offset = mipOffset ;
} else {
this . width = image . getWidth ( ) ;
this . height = image . getHeight ( ) ;
this . offset = 0 ;
}
this . image = image ;
this . slice = slice ;
// Conversion to linear only needed if image's color space is sRGB.
this . convertToLinear = convertToLinear & & image . getColorSpace ( ) = = ColorSpace . sRGB ;
this . buffer = image . getData ( slice ) ;
this . codec = ImageCodec . lookup ( image . getFormat ( ) ) ;
this . width = image . getWidth ( ) ;
this . height = image . getHeight ( ) ;
if ( codec instanceof ByteAlignedImageCodec | | codec instanceof ByteOffsetImageCodec ) {
this . temp = new byte [ codec . bpp ] ;
} else {
@ -86,6 +115,12 @@ public class DefaultImageRaster extends ImageRaster {
public void setPixel ( int x , int y , ColorRGBA color ) {
rangeCheck ( x , y ) ;
if ( convertToLinear ) {
// Input is linear, needs to be converted to sRGB before writing
// into image.
color = color . getAsSrgb ( ) ;
}
// Check flags for grayscale
if ( codec . isGray ) {
float gray = color . r * 0 . 27f + color . g * 0 . 67f + color . b * 0 . 06f ;
@ -113,7 +148,7 @@ public class DefaultImageRaster extends ImageRaster {
components [ 3 ] = Math . min ( ( int ) ( color . b * codec . maxBlue + 0 . 5f ) , codec . maxBlue ) ;
break ;
}
codec . writeComponents ( getBuffer ( ) , x , y , width , 0 , components , temp ) ;
codec . writeComponents ( getBuffer ( ) , x , y , width , offset , components , temp ) ;
image . setUpdateNeeded ( ) ;
}
@ -128,7 +163,7 @@ public class DefaultImageRaster extends ImageRaster {
public ColorRGBA getPixel ( int x , int y , ColorRGBA store ) {
rangeCheck ( x , y ) ;
codec . readComponents ( getBuffer ( ) , x , y , width , 0 , components , temp ) ;
codec . readComponents ( getBuffer ( ) , x , y , width , offset , components , temp ) ;
if ( store = = null ) {
store = new ColorRGBA ( ) ;
}
@ -169,6 +204,12 @@ public class DefaultImageRaster extends ImageRaster {
store . a = 1 ;
}
}
if ( convertToLinear ) {
// Input image is sRGB, need to convert to linear.
store . setAsSrgb ( store . r , store . g , store . b , store . a ) ;
}
return store ;
}
}