From c5426028d29aec65fa51e1d2f29934cc245eb9a2 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Wed, 22 Nov 2006 15:18:32 +0000 Subject: 2006-11-22 Roman Kennke * java/awt/image/ImageFilter.java Reformat whole class. (getFilterInstance): Don't touch the consumer field. Don't check consumer. (imageComplete): Don't check consumer. (setColorModel): Don't check consumer. (setDimensions): Don't check consumer. (setHints): Don't check consumer. (setPixels): Don't check consumer. (setProperties): Pass the original property too. * java/awt/image/IndexColorModel.java (IndexColorModel(int,int,byte[],byte[],byte[],int)): Set the transparent pixel by calling the new helper method. (IndexColorModel(int,int,byte[],int,boolean,int)): Set the transparent pixel by calling the new helper method. (IndexColorModel(int,int,int[],int,boolean,int,int)): Set the transparent pixel by calling the new helper method. (coerceData): Removed. This is not needed. (getAlpha): Simply return value from color map. The transparent pixel has to be there. (setTransparentPixel): New helper method. Inserts the transparent pixel. * java/awt/image/RGBImageFilter.java Reformat whole class. (convertColorModelToDefault): Removed. No longer needed. (filterIndexColorModel): Don't handle transparent pixels separately. (filterRGBPixels): Set pixels on consumer already. (makeColor): Removed. No longer needed. * java/awt/image/ReplicateScaleFilter.java (replicatePixels): Removed. (setDimension): Correctly compute destination size, avoid double calculations. (setPixels): Avoid double calculations. Fixed some boundary cases. (setupSources): New helper method. * java/awt/image/SampleModel.java (setDataElements): Also handle TYPE_SHORT, TYPE_FLOAT and TYPE_DOUBLE. * java/awt/image/SinglePixelPackedSampleModel.java (setDataElements(int,int,int,int,Object,DataBuffer)): Removed. This is not needed as the superclass already copies line by line. (setDataElements(int,int,Object,DataBuffer)): Simplified code, removed some checks that the RI also doesn't perform. Call DataBuffer.setElem(). --- ChangeLog | 48 +++ java/awt/image/ImageFilter.java | 349 ++++++++++--------- java/awt/image/IndexColorModel.java | 59 ++-- java/awt/image/RGBImageFilter.java | 416 +++++++++++------------ java/awt/image/ReplicateScaleFilter.java | 144 ++++---- java/awt/image/SampleModel.java | 29 +- java/awt/image/SinglePixelPackedSampleModel.java | 121 ++----- 7 files changed, 569 insertions(+), 597 deletions(-) diff --git a/ChangeLog b/ChangeLog index a8769aca7..e2fd016d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,51 @@ +2006-11-22 Roman Kennke + + * java/awt/image/ImageFilter.java + Reformat whole class. + (getFilterInstance): Don't touch the consumer field. Don't check + consumer. + (imageComplete): Don't check consumer. + (setColorModel): Don't check consumer. + (setDimensions): Don't check consumer. + (setHints): Don't check consumer. + (setPixels): Don't check consumer. + (setProperties): Pass the original property too. + * java/awt/image/IndexColorModel.java + (IndexColorModel(int,int,byte[],byte[],byte[],int)): Set the + transparent pixel by calling the new helper method. + (IndexColorModel(int,int,byte[],int,boolean,int)): Set the + transparent pixel by calling the new helper method. + (IndexColorModel(int,int,int[],int,boolean,int,int)): Set the + transparent pixel by calling the new helper method. + (coerceData): Removed. This is not needed. + (getAlpha): Simply return value from color map. The transparent + pixel has to be there. + (setTransparentPixel): New helper method. Inserts the transparent + pixel. + * java/awt/image/RGBImageFilter.java + Reformat whole class. + (convertColorModelToDefault): Removed. No longer needed. + (filterIndexColorModel): Don't handle transparent pixels + separately. + (filterRGBPixels): Set pixels on consumer already. + (makeColor): Removed. No longer needed. + * java/awt/image/ReplicateScaleFilter.java + (replicatePixels): Removed. + (setDimension): Correctly compute destination size, avoid double + calculations. + (setPixels): Avoid double calculations. Fixed some boundary cases. + (setupSources): New helper method. + * java/awt/image/SampleModel.java + (setDataElements): Also handle TYPE_SHORT, TYPE_FLOAT + and TYPE_DOUBLE. + * java/awt/image/SinglePixelPackedSampleModel.java + (setDataElements(int,int,int,int,Object,DataBuffer)): Removed. + This is not needed as the superclass already copies line + by line. + (setDataElements(int,int,Object,DataBuffer)): Simplified code, + removed some checks that the RI also doesn't perform. Call + DataBuffer.setElem(). + 2006-11-22 Roman Kennke * java/awt/text/TextLayout.java diff --git a/java/awt/image/ImageFilter.java b/java/awt/image/ImageFilter.java index c39c4a428..d5eb8bf47 100644 --- a/java/awt/image/ImageFilter.java +++ b/java/awt/image/ImageFilter.java @@ -49,180 +49,179 @@ import java.util.Hashtable; */ public class ImageFilter implements ImageConsumer, Cloneable { - /** - * The consumer this filter is filtering an image data stream for. - * It is initialized in the method getFilterInstance. - */ - protected ImageConsumer consumer = null; - - /** - * The ImageConsumer can use this method to request - * the pixels be delivered in top-down, left-right order. - *
- * The filter can respond in three different ways. - *
    - *
  • The default behavior is to forward the request to the - * ImageProducer - * using the method requestTopDownLeftRightResend - * and using the filter as the consumer.
  • - *
  • The filter has the pixels and can retransmit them in the - * top-down, left-right order.
  • - *
  • The filter can do nothing when this method is called.
  • - *
- */ - public void resendTopDownLeftRight(ImageProducer ip) - { - ip.requestTopDownLeftRightResend(this); - } - - /** - * By default, returns a shallow copy of the object created by - * Object.clone() - * - * @see java.lang.Object#clone () - */ - public Object clone() - { - try - { - return super.clone(); - } - catch (CloneNotSupportedException e) - { - // This should never happen as this class implements the - // Cloneable interface. - throw new InternalError (); - } - } - - /** - * This is the only method which can set the - * ImageConsumer for this filter. By default a clone - * of this filter with the appropriate consumer set is returned. - * - * @see #clone () - */ - public ImageFilter getFilterInstance(ImageConsumer ic) - { - if ( ic == null ) - throw new IllegalArgumentException("null argument for ImageFilter.getFilterInstance(ImageConsumer)"); - - consumer = ic; - ImageFilter f = (ImageFilter)clone(); - consumer = null; - return f; - } - - /** - * An ImageProducer indicates the size of the image - * being produced using this method. A filter can override this - * method to intercept these calls from the producer in order to - * change either the width or the height before in turn calling - * the consumer's setDimensions method. - * - * @param width the width of the image - * @param height the height of the image - */ - public void setDimensions(int width, int height) - { - if (consumer != null) - consumer.setDimensions(width, height); - } - - /** - * An ImageProducer can set a list of properties - * associated with this image by using this method. - * - * @param props the list of properties associated with this image - */ - public void setProperties(Hashtable props) - { - props.put("filters", "ImageFilter"); - if (consumer != null) - consumer.setProperties(props); - } - - /** - * Override this method to process calls to this method from the - * ImageProducer. By default the setColorModel - * method of the consumer is called with the specified model. - * - * @param model the color model to be used most often by setPixels - * @see ColorModel */ - public void setColorModel(ColorModel model) - { - if (consumer != null) - consumer.setColorModel(model); - } - - /** - * The ImageProducer should call this method with a - * bit mask of hints from any of RANDOMPIXELORDER, - * TOPDOWNLEFTRIGHT, COMPLETESCANLINES, - * SINGLEPASS, SINGLEFRAME from the - * ImageConsumer interface. - * - * @param flags a bit mask of hints - * @see ImageConsumer - */ - public void setHints(int flags) - { - if (consumer != null) - consumer.setHints(flags); - } - - /** - * This function delivers a rectangle of pixels where any - * pixel(m,n) is stored in the array as a byte at - * index (n * scansize + m + offset). - * - * @param x the x coordinate of the rectangle - * @param y the y coordinate of the rectangle - * @param w the width of the rectangle - * @param h the height of the rectangle - * @param model the ColorModel used to translate the pixels - * @param pixels the array of pixel values - * @param offset the index of the first pixels in the pixels array - * @param scansize the width to use in extracting pixels from the pixels array - */ - public void setPixels(int x, int y, int w, int h, - ColorModel model, byte[] pixels, int offset, int scansize) - { - if (consumer != null) - consumer.setPixels(x, y, w, h, model, pixels, offset, scansize); - } - - /** - * This function delivers a rectangle of pixels where any - * pixel(m,n) is stored in the array as an int at - * index (n * scansize + m + offset). - * - * @param x the x coordinate of the rectangle - * @param y the y coordinate of the rectangle - * @param w the width of the rectangle - * @param h the height of the rectangle - * @param model the ColorModel used to translate the pixels - * @param pixels the array of pixel values - * @param offset the index of the first pixels in the pixels array - * @param scansize the width to use in extracting pixels from the pixels array - */ - public void setPixels(int x, int y, int w, int h, - ColorModel model, int[] pixels, int offset, int scansize) - { - if (consumer != null) - consumer.setPixels(x, y, w, h, model, pixels, offset, scansize); - } - - /** - * The ImageProducer calls this method to indicate a - * single frame or the entire image is complete. The method is - * also used to indicate an error in loading or producing the - * image. - */ - public void imageComplete(int status) - { - if (consumer != null) - consumer.imageComplete(status); - } + /** + * The consumer this filter is filtering an image data stream for. + * It is initialized in the method getFilterInstance. + */ + protected ImageConsumer consumer = null; + + /** + * The ImageConsumer can use this method to request + * the pixels be delivered in top-down, left-right order. + *
+ * The filter can respond in three different ways. + *
    + *
  • The default behavior is to forward the request to the + * ImageProducer + * using the method requestTopDownLeftRightResend + * and using the filter as the consumer.
  • + *
  • The filter has the pixels and can retransmit them in the + * top-down, left-right order.
  • + *
  • The filter can do nothing when this method is called.
  • + *
+ */ + public void resendTopDownLeftRight(ImageProducer ip) + { + ip.requestTopDownLeftRightResend(this); + } + + /** + * By default, returns a shallow copy of the object created by + * Object.clone() + * + * @see java.lang.Object#clone () + */ + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + // This should never happen as this class implements the + // Cloneable interface. + throw new InternalError (); + } + } + + /** + * This is the only method which can set the + * ImageConsumer for this filter. By default a clone + * of this filter with the appropriate consumer set is returned. + * + * @see #clone () + */ + public ImageFilter getFilterInstance(ImageConsumer ic) + { + ImageFilter f = (ImageFilter)clone(); + f.consumer = ic; + return f; + } + + /** + * An ImageProducer indicates the size of the image + * being produced using this method. A filter can override this + * method to intercept these calls from the producer in order to + * change either the width or the height before in turn calling + * the consumer's setDimensions method. + * + * @param width the width of the image + * @param height the height of the image + */ + public void setDimensions(int width, int height) + { + consumer.setDimensions(width, height); + } + + /** + * An ImageProducer can set a list of properties + * associated with this image by using this method. + * + * @param props the list of properties associated with this image + */ + public void setProperties(Hashtable props) + { + Hashtable copy = (Hashtable) props.clone(); + Object o = copy.get("filters"); + if (o == null) + copy.put("filters", toString()); + else if (o instanceof String) + copy.put("filters", ((String) o) + toString()); + + consumer.setProperties(copy); + } + + /** + * Override this method to process calls to this method from the + * ImageProducer. By default the setColorModel + * method of the consumer is called with the specified model. + * + * @param model the color model to be used most often by setPixels + * + * @see ColorModel + */ + public void setColorModel(ColorModel model) + { + consumer.setColorModel(model); + } + + /** + * The ImageProducer should call this method with a + * bit mask of hints from any of RANDOMPIXELORDER, + * TOPDOWNLEFTRIGHT, COMPLETESCANLINES, + * SINGLEPASS, SINGLEFRAME from the + * ImageConsumer interface. + * + * @param flags a bit mask of hints + * @see ImageConsumer + */ + public void setHints(int flags) + { + consumer.setHints(flags); + } + + /** + * This function delivers a rectangle of pixels where any + * pixel(m,n) is stored in the array as a byte at + * index (n * scansize + m + offset). + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @param model the ColorModel used to translate the pixels + * @param pixels the array of pixel values + * @param offset the index of the first pixels in the pixels array + * @param scansize the width to use in extracting pixels from the pixels array + */ + public void setPixels(int x, int y, int w, int h, + ColorModel model, byte[] pixels, int offset, + int scansize) + { + consumer.setPixels(x, y, w, h, model, pixels, offset, scansize); + } + + /** + * This function delivers a rectangle of pixels where any + * pixel(m,n) is stored in the array as an int at + * index (n * scansize + m + offset). + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @param model the ColorModel used to translate the pixels + * @param pixels the array of pixel values + * @param offset the index of the first pixels in the pixels array + * @param scansize the width to use in extracting pixels from the pixels array + */ + public void setPixels(int x, int y, int w, int h, + ColorModel model, int[] pixels, int offset, + int scansize) + { + consumer.setPixels(x, y, w, h, model, pixels, offset, scansize); + } + + /** + * The ImageProducer calls this method to indicate a + * single frame or the entire image is complete. The method is + * also used to indicate an error in loading or producing the + * image. + */ + public void imageComplete(int status) + { + consumer.imageComplete(status); + } } diff --git a/java/awt/image/IndexColorModel.java b/java/awt/image/IndexColorModel.java index a16c01b69..46879cc98 100644 --- a/java/awt/image/IndexColorModel.java +++ b/java/awt/image/IndexColorModel.java @@ -134,10 +134,6 @@ public class IndexColorModel extends ColorModel if (size < 1) throw new IllegalArgumentException("size < 1"); map_size = size; - if (0 <= trans && trans < size) { - this.trans = trans; - transparency = BITMASK; - } rgb = new int[size]; for (int i = 0; i < size; i++) { @@ -146,6 +142,9 @@ public class IndexColorModel extends ColorModel | ((greens[i] & 0xff) << 8) | (blues[i] & 0xff)); } + + setTransparentPixel(trans); + // Generate a bigint with 1's for every pixel validBits = validBits.setBit(size).subtract(BigInteger.ONE); } @@ -275,8 +274,6 @@ public class IndexColorModel extends ColorModel throw new IllegalArgumentException("size < 1"); map_size = size; opaque = !hasAlpha; - if (0 <= trans && trans < size) - this.trans = trans; rgb = new int[size]; if (hasAlpha) @@ -318,6 +315,8 @@ public class IndexColorModel extends ColorModel transparency = BITMASK; } + setTransparentPixel(trans); + // Generate a bigint with 1's for every pixel validBits = validBits.setBit(size).subtract(BigInteger.ONE); } @@ -361,9 +360,6 @@ public class IndexColorModel extends ColorModel throw new IllegalArgumentException("size < 1"); map_size = size; opaque = !hasAlpha; - if (0 <= trans && trans < size) - this.trans = trans; - rgb = new int[size]; if (!hasAlpha) for (int i = 0; i < size; i++) @@ -371,6 +367,8 @@ public class IndexColorModel extends ColorModel else System.arraycopy(cmap, start, rgb, 0, size); + setTransparentPixel(trans); + // Generate a bigint with 1's for every pixel validBits = validBits.setBit(size).subtract(BigInteger.ONE); } @@ -584,12 +582,7 @@ public class IndexColorModel extends ColorModel */ public final int getAlpha(int pixel) { - if (opaque && pixel != trans) - return 255; - if ((pixel == trans && trans != -1) || pixel >= map_size) - return 0; - - return (0xFF000000 & rgb[pixel]) >> 24; + return (rgb[pixel] >> 24) & 0xFF; } /** @@ -694,23 +687,6 @@ public class IndexColorModel extends ColorModel return im; } - - public ColorModel coerceData (WritableRaster raster, - boolean isAlphaPremultiplied) - { - if (this.isAlphaPremultiplied == isAlphaPremultiplied || !hasAlpha()) - return this; - - /* TODO: provide better implementation based on the - assumptions we can make due to the specific type of the - color model. */ - super.coerceDataWorker(raster, isAlphaPremultiplied); - - ColorModel cm = new IndexColorModel(pixel_bits, map_size, rgb, 0, hasAlpha, trans, - transferType); - cm.isAlphaPremultiplied = !(cm.isAlphaPremultiplied); - return cm; - } /** * Creates a {@link SampleModel} that is compatible to this color model. @@ -731,4 +707,23 @@ public class IndexColorModel extends ColorModel sm = new ComponentSampleModel(transferType, w, h, 1, w, new int[]{0}); return sm; } + + /** + * Sets the transparent pixel. This is called by the various constructors. + * + * @param t the transparent pixel + */ + private void setTransparentPixel(int t) + { + if (t >= 0 && t < map_size) + { + rgb[t] &= 0xffffff; // Make the value transparent. + trans = t; + if (transparency == OPAQUE) + { + transparency = BITMASK; + hasAlpha = true; + } + } + } } diff --git a/java/awt/image/RGBImageFilter.java b/java/awt/image/RGBImageFilter.java index ecfed0674..c777fecd9 100644 --- a/java/awt/image/RGBImageFilter.java +++ b/java/awt/image/RGBImageFilter.java @@ -46,228 +46,220 @@ package java.awt.image; */ public abstract class RGBImageFilter extends ImageFilter { - protected ColorModel origmodel; + protected ColorModel origmodel; - protected ColorModel newmodel; + protected ColorModel newmodel; - /** - Specifies whether to apply the filter to the index entries of the - IndexColorModel. Subclasses should set this to true if the filter - does not depend on the pixel's coordinate. - */ - protected boolean canFilterIndexColorModel = false; + /** + * Specifies whether to apply the filter to the index entries of the + * IndexColorModel. Subclasses should set this to true if the filter + * does not depend on the pixel's coordinate. + */ + protected boolean canFilterIndexColorModel = false; - /** - Construct new RGBImageFilter. - */ - public RGBImageFilter() - { - } + /** + * Construct new RGBImageFilter. + */ + public RGBImageFilter() + { + } - /** - * Sets the ColorModel used to filter with. If the specified ColorModel is IndexColorModel - * and canFilterIndexColorModel is true, we subsitute the ColorModel for a filtered one - * here and in setPixels whenever the original one appears. Otherwise overrides the default - * ColorModel of ImageProducer and specifies the default RGBColorModel - * - * @param model the color model to be used most often by setPixels - * @see ColorModel */ - public void setColorModel(ColorModel model) - { - origmodel = model; - newmodel = model; + /** + * Sets the ColorModel used to filter with. If the specified ColorModel is + * IndexColorModel and canFilterIndexColorModel is true, we subsitute the + * ColorModel for a filtered one here and in setPixels whenever the original + * one appears. Otherwise overrides the default ColorModel of ImageProducer + * and specifies the default RGBColorModel + * + * @param model the color model to be used most often by setPixels + * + * @see ColorModel + */ + public void setColorModel(ColorModel model) + { + if ((model instanceof IndexColorModel) && canFilterIndexColorModel) + { + ColorModel newCM = filterIndexColorModel((IndexColorModel) model); + substituteColorModel(model, newCM); + consumer.setColorModel(newmodel); + } + else + { + consumer.setColorModel(ColorModel.getRGBdefault()); + } + } - if( ( model instanceof IndexColorModel) && canFilterIndexColorModel ) { - newmodel = filterIndexColorModel( (IndexColorModel) model ); - if (consumer != null) - consumer.setColorModel(newmodel); - } - else { - if (consumer != null) - consumer.setColorModel(ColorModel.getRGBdefault()); - } - } - - /** - Registers a new ColorModel to subsitute for the old ColorModel when - setPixels encounters the a pixel with the old ColorModel. The pixel - remains unchanged except for a new ColorModel. - - @param oldcm the old ColorModel - @param newcm the new ColorModel - */ - public void substituteColorModel(ColorModel oldcm, - ColorModel newcm) - { - origmodel = oldcm; - newmodel = newcm; - } - - /** - Filters an IndexColorModel through the filterRGB function. Uses - coordinates of -1 to indicate its filtering an index and not a pixel. - - @param icm an IndexColorModel to filter - */ - public IndexColorModel filterIndexColorModel(IndexColorModel icm) - { - int len = icm.getMapSize(), rgb; - byte reds[] = new byte[len], greens[] = new byte[len], blues[] = new byte[len], alphas[] = new byte[len]; - - icm.getAlphas( alphas ); - icm.getReds( reds ); - icm.getGreens( greens ); - icm.getBlues( blues ); - - for( int i = 0; i < len; i++ ) - { - rgb = filterRGB( -1, -1, makeColor ( alphas[i], reds[i], greens[i], blues[i] ) ); - alphas[i] = (byte)(( 0xff000000 & rgb ) >> 24); - reds[i] = (byte)(( 0xff0000 & rgb ) >> 16); - greens[i] = (byte)(( 0xff00 & rgb ) >> 8); - blues[i] = (byte)(0xff & rgb); - } - return new IndexColorModel( icm.getPixelSize(), len, reds, greens, blues, alphas ); - } - - private int makeColor( byte a, byte r, byte g, byte b ) - { - return ( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b ); - } - - /** - This functions filters a set of RGB pixels through filterRGB. - - @param x the x coordinate of the rectangle - @param y the y coordinate of the rectangle - @param w the width of the rectangle - @param h the height of the rectangle - @param pixels the array of pixel values - @param offset the index of the first pixels in the pixels array - @param scansize the width to use in extracting pixels from the pixels array - */ - public void filterRGBPixels(int x, int y, int w, int h, int[] pixels, - int offset, int scansize) - { - for (int yp = 0; yp < h; yp++) - { - for (int xp = 0; xp < w; xp++) - { - pixels[offset + xp] = filterRGB(xp + x, yp + y, pixels[offset + xp]); - } - offset += scansize; - } - } - - - /** - * If the ColorModel is the same ColorModel which as already converted - * then it converts it the converted ColorModel. Otherwise it passes the - * array of pixels through filterRGBpixels. - * - * @param x the x coordinate of the rectangle - * @param y the y coordinate of the rectangle - * @param w the width of the rectangle - * @param h the height of the rectangle - * @param model the ColorModel used to translate the pixels - * @param pixels the array of pixel values - * @param offset the index of the first pixels in the pixels array - * @param scansize the width to use in extracting pixels from the pixels array - */ - public void setPixels(int x, int y, int w, int h, - ColorModel model, byte[] pixels, - int offset, int scansize) - { - if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel) - { - if (consumer != null) - consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize); - } - else - { - int intPixels[] = - convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize ); - filterRGBPixels( x, y, w, h, intPixels, offset, scansize ); - if (consumer != null) - consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), intPixels, offset, scansize); - } - } - - /** - * This function delivers a rectangle of pixels where any - * pixel(m,n) is stored in the array as an int at - * index (n * scansize + m + offset). - * - * @param x the x coordinate of the rectangle - * @param y the y coordinate of the rectangle - * @param w the width of the rectangle - * @param h the height of the rectangle - * @param model the ColorModel used to translate the pixels - * @param pixels the array of pixel values - * @param offset the index of the first pixels in the pixels array - * @param scansize the width to use in extracting pixels from the pixels array - */ - public void setPixels(int x, int y, int w, int h, - ColorModel model, int[] pixels, - int offset, int scansize) - { - if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel) - { - if (consumer != null) - consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize); - } - else - { - //FIXME: Store the filtered pixels in a separate temporary buffer? - convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize ); - filterRGBPixels( x, y, w, h, pixels, offset, scansize ); - if (consumer != null) - consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, offset, scansize); - } - } - - private int[] convertColorModelToDefault(int x, int y, int w, int h, - ColorModel model, byte pixels[], - int offset, int scansize) - { - int intPixels[] = new int[pixels.length]; - for (int i = 0; i < pixels.length; i++) - intPixels[i] = makeColorbyDefaultCM(model, pixels[i]); - return intPixels; - } + /** + * Registers a new ColorModel to subsitute for the old ColorModel when + * setPixels encounters the a pixel with the old ColorModel. The pixel + * remains unchanged except for a new ColorModel. + * + * @param oldcm the old ColorModel + * @param newcm the new ColorModel + */ + public void substituteColorModel(ColorModel oldcm, ColorModel newcm) + { + origmodel = oldcm; + newmodel = newcm; + } - private void convertColorModelToDefault(int x, int y, int w, int h, - ColorModel model, int pixels[], - int offset, int scansize) - { - for (int i = 0; i < pixels.length; i++) - pixels[i] = makeColorbyDefaultCM(model, pixels[i]); - } + /** + * Filters an IndexColorModel through the filterRGB function. Uses + * coordinates of -1 to indicate its filtering an index and not a pixel. + * + * @param icm an IndexColorModel to filter + */ + public IndexColorModel filterIndexColorModel(IndexColorModel icm) + { + int len = icm.getMapSize(); + byte[] reds = new byte[len]; + byte[] greens = new byte[len]; + byte[] blues = new byte[len]; + byte[] alphas = new byte[len]; - private int makeColorbyDefaultCM(ColorModel model, byte rgb) - { - return makeColor( model.getAlpha( rgb ) * 4, model.getRed( rgb ) * 4, model.getGreen( rgb ) * 4, model.getBlue( rgb ) * 4 ); - } + icm.getAlphas( alphas ); + icm.getReds( reds ); + icm.getGreens( greens ); + icm.getBlues( blues ); - private int makeColorbyDefaultCM(ColorModel model, int rgb) - { - return makeColor( model.getAlpha( rgb ), model.getRed( rgb ), model.getGreen( rgb ), model.getBlue( rgb ) ); - } + int transparent = icm.getTransparentPixel(); + boolean needAlpha = false; + for( int i = 0; i < len; i++ ) + { + int rgb = filterRGB(-1, -1, icm.getRGB(i)); + alphas[i] = (byte) (rgb >> 24); + if (alphas[i] != ((byte) 0xff) && i != transparent) + needAlpha = true; + reds[i] = (byte) (rgb >> 16); + greens[i] = (byte) (rgb >> 8); + blues[i] = (byte) (rgb); + } + IndexColorModel newIcm; + if (needAlpha) + newIcm = new IndexColorModel(icm.getPixelSize(), len, reds, greens, + blues, alphas); + else + newIcm = new IndexColorModel(icm.getPixelSize(), len, reds, greens, + blues, transparent); + return newIcm; + } - private int makeColor( int a, int r, int g, int b ) - { - return (int)( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b ); - } + /** + * This functions filters a set of RGB pixels through filterRGB. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @param pixels the array of pixel values + * @param offset the index of the first pixels in the + * pixels array + * @param scansize the width to use in extracting pixels from the + * pixels array + */ + public void filterRGBPixels(int x, int y, int w, int h, int[] pixels, + int offset, int scansize) + { + int index = offset; + for (int yp = 0; yp < h; yp++) + { + for (int xp = 0; xp < w; xp++) + { + pixels[index] = filterRGB(xp + x, yp + y, pixels[index]); + index++; + } + index += scansize - w; + } + consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, offset, + scansize); + } + /** + * If the ColorModel is the same ColorModel which as already converted + * then it converts it the converted ColorModel. Otherwise it passes the + * array of pixels through filterRGBpixels. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @param model the ColorModel used to translate the pixels + * @param pixels the array of pixel values + * @param offset the index of the first pixels in the pixels + * array + * @param scansize the width to use in extracting pixels from the + * pixels array + */ + public void setPixels(int x, int y, int w, int h, ColorModel model, + byte[] pixels, int offset, int scansize) + { + if (model == origmodel) + { + consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize); + } + else + { + int[] filtered = new int[w]; + int index = offset; + for (int yp = 0; yp < h; yp++) + { + for (int xp = 0; xp < w; xp++) + { + filtered[xp] = model.getRGB((pixels[index] & 0xff)); + index++; + } + index += scansize - w; + filterRGBPixels(x, y + yp, w, 1, filtered, 0, w); + } + } + } - /** - Filters a single pixel from the default ColorModel. + /** + * This function delivers a rectangle of pixels where any + * pixel(m,n) is stored in the array as an int at + * index (n * scansize + m + offset). + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @param model the ColorModel used to translate the pixels + * @param pixels the array of pixel values + * @param offset the index of the first pixels in the pixels + * array + * @param scansize the width to use in extracting pixels from the + * pixels array + */ + public void setPixels(int x, int y, int w, int h, ColorModel model, + int[] pixels, int offset, int scansize) + { + if (model == origmodel) + { + consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize); + } + else + { + int[] filtered = new int[w]; + int index = offset; + for (int yp = 0; yp < h; yp++) + { + for (int xp = 0; xp < w; xp++) + { + filtered[xp] = model.getRGB((pixels[index] & 0xff)); + index++; + } + index += scansize - w; + filterRGBPixels(x, y + yp, w, 1, filtered, 0, w); + } + } + } - @param x x-coordinate - @param y y-coordinate - @param rgb color - */ - public abstract int filterRGB(int x, - int y, - int rgb); + /** + * Filters a single pixel from the default ColorModel. + * + * @param x x-coordinate + * @param y y-coordinate + * @param rgb color + */ + public abstract int filterRGB(int x, int y, int rgb); } diff --git a/java/awt/image/ReplicateScaleFilter.java b/java/awt/image/ReplicateScaleFilter.java index 6d5099dea..8048838ae 100644 --- a/java/awt/image/ReplicateScaleFilter.java +++ b/java/awt/image/ReplicateScaleFilter.java @@ -46,6 +46,7 @@ import java.util.Hashtable; * exact method is not defined by Sun but some sort of fast Box filter should * probably be correct. *
+ * Currently this filter does nothing and needs to be implemented. * * @author C. Brian Jones (cbj@gnu.org) */ @@ -116,11 +117,11 @@ public class ReplicateScaleFilter extends ImageFilter } else if (destWidth < 0) { - destWidth = (int) (width * ((double) destHeight / srcHeight)); + destWidth = width * destHeight / srcHeight; } else if (destHeight < 0) { - destHeight = (int) (height * ((double) destWidth / srcWidth)); + destHeight = height * destWidth / srcWidth; } if (consumer != null) @@ -157,19 +158,35 @@ public class ReplicateScaleFilter extends ImageFilter public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int offset, int scansize) { - double rx = ((double) srcWidth) / destWidth; - double ry = ((double) srcHeight) / destHeight; - - int destScansize = (int) Math.round(scansize / rx); - - byte[] destPixels = replicatePixels(x, y, w, h, - model, pixels, offset, scansize, - rx, ry, destScansize); - - if (consumer != null) - consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry), - (int) Math.ceil(w/rx), (int) Math.ceil(h/ry), - model, destPixels, 0, destScansize); + if (srcrows == null || srccols == null) + setupSources(); + int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * destWidth); + int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * destHeight); + byte[] pix; + if (outpixbuf != null && outpixbuf instanceof byte[]) + { + pix = (byte[]) outpixbuf; + } + else + { + pix = new byte[destWidth]; + outpixbuf = pix; + } + int sy, sx; + for (int yy = dy1; (sy = srcrows[yy]) < y + h; yy++) + { + int offs = offset + scansize * (sy - y); + int xx; + for (xx = dx1; (sx = srccols[xx]) < x + w; xx++) + { + pix[xx] = pixels[offs + sx - x]; + } + if (xx > dx1) + { + consumer.setPixels(dx1, yy, xx - dx1, 1, model, pix, dx1, + destWidth); + } + } } /** @@ -189,59 +206,52 @@ public class ReplicateScaleFilter extends ImageFilter public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int offset, int scansize) { - double rx = ((double) srcWidth) / destWidth; - double ry = ((double) srcHeight) / destHeight; - - int destScansize = (int) Math.round(scansize / rx); - - int[] destPixels = replicatePixels(x, y, w, h, - model, pixels, offset, scansize, - rx, ry, destScansize); - - if (consumer != null) - consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry), - (int) Math.ceil(w/rx), (int) Math.ceil(h/ry), - model, destPixels, 0, destScansize); - } - - private byte[] replicatePixels(int srcx, int srcy, int srcw, int srch, - ColorModel model, byte[] srcPixels, - int srcOffset, int srcScansize, - double rx, double ry, int destScansize) - { - byte[] destPixels = - new byte[(int) Math.ceil(srcw/rx) * (int) Math.ceil(srch/ry)]; - - int a, b; - for (int i = 0; i < destPixels.length; i++) - { - a = (int) ((int) ( ((double) i) / destScansize) * ry) * srcScansize; - b = (int) ((i % destScansize) * rx); - if ((a + b + srcOffset) < srcPixels.length) - destPixels[i] = srcPixels[a + b + srcOffset]; - } - - return destPixels; + if (srcrows == null || srccols == null) + setupSources(); + int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * destWidth); + int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * destHeight); + int[] pix; + if (outpixbuf != null && outpixbuf instanceof int[]) + { + pix = (int[]) outpixbuf; + } + else + { + pix = new int[destWidth]; + outpixbuf = pix; + } + int sy, sx; + for (int yy = dy1; (sy = srcrows[yy]) < y + h; yy++) + { + int offs = offset + scansize * (sy - y); + int xx; + for (xx = dx1; (sx = srccols[xx]) < x + w; xx++) + { + pix[xx] = pixels[offs + sx - x]; + } + if (xx > dx1) + { + consumer.setPixels(dx1, yy, xx - dx1, 1, model, pix, dx1, + destWidth); + } + } } - private int[] replicatePixels(int srcx, int srcy, int srcw, int srch, - ColorModel model, int[] srcPixels, - int srcOffset, int srcScansize, - double rx, double ry, int destScansize) - { - int[] destPixels = - new int[(int) Math.ceil(srcw/rx) * (int) Math.ceil(srch/ry)]; - - int a, b; - for (int i = 0; i < destPixels.length; i++) - { - a = (int) ((int) ( ((double) i) / destScansize) * ry) * srcScansize; - b = (int) ((i % destScansize) * rx); - if ((a + b + srcOffset) < srcPixels.length) - destPixels[i] = srcPixels[a + b + srcOffset]; - } - - return destPixels; - } + /** + * Sets up the srcrows and srccols arrays. + */ + private void setupSources() + { + srcrows = new int[destHeight + 1]; + for (int y = 0; y <= destHeight; y++) + { + srcrows[y] = (2 * y * srcHeight + srcHeight) / (2 * destHeight); + } + srccols = new int[destWidth + 1]; + for (int x = 0; x <= destWidth; x++) + { + srccols[x] = (2 * x * srcWidth + srcWidth) / (2 * destWidth); + } + } } diff --git a/java/awt/image/SampleModel.java b/java/awt/image/SampleModel.java index cb352bb4d..506e78a9b 100644 --- a/java/awt/image/SampleModel.java +++ b/java/awt/image/SampleModel.java @@ -246,9 +246,7 @@ public abstract class SampleModel public void setDataElements(int x, int y, int w, int h, Object obj, DataBuffer data) { - int size = w * h; int numDataElements = getNumDataElements(); - int dataSize = numDataElements * size; Object pixelData; switch (getTransferType()) @@ -257,25 +255,34 @@ public abstract class SampleModel pixelData = new byte[numDataElements]; break; case DataBuffer.TYPE_USHORT: + case DataBuffer.TYPE_SHORT: pixelData = new short[numDataElements]; break; case DataBuffer.TYPE_INT: pixelData = new int[numDataElements]; break; + case DataBuffer.TYPE_FLOAT: + pixelData = new float[numDataElements]; + break; + case DataBuffer.TYPE_DOUBLE: + pixelData = new double[numDataElements]; + break; default: - // Seems like the only sensible thing to do. - throw new ClassCastException(); + // The RI silently igores invalid types. + pixelData = null; } - int inOffset = 0; - for (int yy = y; yy < (y + h); yy++) + int inOffset = 0; + if (pixelData != null) { - for (int xx = x; xx < (x + w); xx++) + for (int yy=y; yy<(y+h); yy++) { - System.arraycopy(obj, inOffset, pixelData, 0, - numDataElements); - setDataElements(xx, yy, pixelData, data); - inOffset += numDataElements; + for (int xx=x; xx<(x+w); xx++) + { + System.arraycopy(obj, inOffset, pixelData, 0, numDataElements); + setDataElements(xx, yy, pixelData, data); + inOffset += numDataElements; + } } } } diff --git a/java/awt/image/SinglePixelPackedSampleModel.java b/java/awt/image/SinglePixelPackedSampleModel.java index a37fc0bba..9ed948c54 100644 --- a/java/awt/image/SinglePixelPackedSampleModel.java +++ b/java/awt/image/SinglePixelPackedSampleModel.java @@ -412,110 +412,31 @@ public class SinglePixelPackedSampleModel extends SampleModel return (samples & bitMasks[b]) >>> bitOffsets[b]; } - /** - * This method implements a more efficient way to set data elements than the - * default implementation of the super class. It sets the data elements line - * by line instead of pixel by pixel. - * - * @param x The x-coordinate of the data elements in obj. - * @param y The y-coordinate of the data elements in obj. - * @param w The width of the data elements in obj. - * @param h The height of the data elements in obj. - * @param obj The primitive array containing the data elements to set. - * @param data The DataBuffer to store the data elements into. - * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, - * java.lang.Object, java.awt.image.DataBuffer) - */ - public void setDataElements(int x, int y, int w, int h, - Object obj, DataBuffer data) - { - - Object pixelData; - switch (getTransferType()) - { - case DataBuffer.TYPE_BYTE: - pixelData = ((DataBufferByte) data).getData(); - break; - case DataBuffer.TYPE_USHORT: - pixelData = ((DataBufferUShort) data).getData(); - break; - case DataBuffer.TYPE_INT: - pixelData = ((DataBufferInt) data).getData(); - break; - default: - // Seems like the only sensible thing to do. - throw new ClassCastException(); - } - - int inOffset = 0; - int dataOffset = scanlineStride*y + x + data.getOffset(); - for (int yy=y; yy<(y+h); yy++) - { - System.arraycopy(obj,inOffset,pixelData,dataOffset,w); - dataOffset += scanlineStride; - inOffset += w; - } - } - - public void setDataElements(int x, int y, Object obj, DataBuffer data) { - int offset = scanlineStride*y + x + data.getOffset(); int transferType = getTransferType(); - if (getTransferType() != data.getDataType()) - { - throw new IllegalArgumentException("transfer type ("+ - getTransferType()+"), "+ - "does not match data "+ - "buffer type (" + - data.getDataType() + - ")."); - } - - try - { - switch (transferType) - { - case DataBuffer.TYPE_BYTE: - { - DataBufferByte out = (DataBufferByte) data; - byte[] in = (byte[]) obj; - out.getData()[offset] = in[0]; - return; - } - case DataBuffer.TYPE_USHORT: - { - DataBufferUShort out = (DataBufferUShort) data; - short[] in = (short[]) obj; - out.getData()[offset] = in[0]; - return; - } - case DataBuffer.TYPE_INT: - { - DataBufferInt out = (DataBufferInt) data; - int[] in = (int[]) obj; - out.getData()[offset] = in[0]; - return; - } - // FIXME: Fill in the other possible types. - default: - throw new InternalError(); - } - } - catch (ArrayIndexOutOfBoundsException aioobe) - { - String msg = "While writing data elements" + - ", x="+x+", y="+y+ - ", width="+width+", height="+height+ - ", scanlineStride="+scanlineStride+ - ", offset="+offset+ - ", data.getSize()="+data.getSize()+ - ", data.getOffset()="+data.getOffset()+ - ": " + - aioobe; - throw new ArrayIndexOutOfBoundsException(msg); - } + switch (transferType) + { + case DataBuffer.TYPE_BYTE: + { + byte[] in = (byte[]) obj; + data.setElem(y * scanlineStride + x, ((int) in[0]) & 0xff); + break; + } + case DataBuffer.TYPE_USHORT: + { + short[] in = (short[]) obj; + data.setElem(y * scanlineStride + x, ((int) in[0]) & 0xffff); + break; + } + case DataBuffer.TYPE_INT: + { + int[] in = (int[]) obj; + data.setElem(y * scanlineStride + x, in[0]); + break; + } + } } /** -- cgit v1.2.1