3838import java .awt .image .ColorModel ;
3939import java .awt .image .ImageConsumer ;
4040import java .awt .image .IndexColorModel ;
41+ import java .io .File ;
4142import java .net .URL ;
4243import java .util .Hashtable ;
4344import java .util .LinkedList ;
@@ -59,55 +60,89 @@ public class GifComparison {
5960 * if ImageIO and ToolkitImage produce different BufferedImage renderings.
6061 *
6162 * @param srcURL the URL of the image to inspect
63+ * @param frameDir an optional directory to write frames to as PNG images.
64+ * The frames should render identically whether we use
65+ * the ImageIO model or the ToolkitImage model. If they're
66+ * identical, then we only output one image, such as
67+ * "frame_0.png". If they're different then we'll
68+ * output two images: "frame_0_iio.png" and
69+ * "frame_0_awt.png".
6270 *
6371 * @return the last frame encoded as a TYPE_INT_ARGB image.
6472 * <p>
6573 * Unit tests may further inspect this image to make sure certain
6674 * conditions are met.
6775 */
68- public static BufferedImage run (URL srcURL ) throws Throwable {
76+ public static BufferedImage run (URL srcURL , File frameDir )
77+ throws Throwable {
6978 System .out .println ("Comparing ImageIO vs ToolkitImage rendering of " +
7079 srcURL );
7180 ImageIOModel ioModel = new ImageIOModel (srcURL );
7281 AWTModel awtModel = new AWTModel (srcURL );
7382
7483 BufferedImage lastImage = null ;
7584
76- int a = ioModel .frames .size () - 1 ;
77- BufferedImage ioImg = ioModel .getFrame (a );
78- BufferedImage awtImage = awtModel .getFrame (a );
79-
80- lastImage = awtImage ;
81-
82- if (!(ioImg .getWidth () == awtImage .getWidth () &&
83- ioImg .getHeight () == awtImage .getHeight ()))
84- throw new Error ("These images are not the same size: " +
85- ioImg .getWidth () + "x" + ioImg .getHeight () + " vs " +
86- awtImage .getWidth () + "x" + awtImage .getHeight ());
87-
88- for (int y = 0 ; y < ioImg .getHeight (); y ++) {
89- for (int x = 0 ; x < ioImg .getWidth (); x ++) {
90- int argb1 = ioImg .getRGB (x , y );
91- int argb2 = awtImage .getRGB (x , y );
92-
93- int alpha1 = (argb1 & 0xff000000 ) >> 24 ;
94- int alpha2 = (argb2 & 0xff000000 ) >> 24 ;
95- if (alpha1 == 0 && alpha2 == 0 ) {
96- continue ;
97- } else if (alpha1 == 0 || alpha2 == 0 ) {
98- throw new Error ("pixels at (" + x + ", " + y +
99- ") have different opacities: " +
100- Integer .toUnsignedString (argb1 , 16 ) + " vs " +
101- Integer .toUnsignedString (argb2 , 16 ));
85+ // if frameDir exists: test & export all frames.
86+ // Otherwise: only test the last frame
87+ int startIndex = frameDir == null ? ioModel .frames .size () - 1 : 0 ;
88+
89+ for (int a = startIndex ; a < ioModel .frames .size (); a ++) {
90+ BufferedImage ioImg = ioModel .getFrame (a );
91+ BufferedImage awtImage = awtModel .getFrame (a );
92+
93+ lastImage = awtImage ;
94+
95+ try {
96+ if (!(ioImg .getWidth () == awtImage .getWidth () &&
97+ ioImg .getHeight () == awtImage .getHeight ()))
98+ throw new Error ("These images are not the same size: " +
99+ ioImg .getWidth () + "x" + ioImg .getHeight () +
100+ " vs " +
101+ awtImage .getWidth () + "x" + awtImage .getHeight ());
102+
103+ for (int y = 0 ; y < ioImg .getHeight (); y ++) {
104+ for (int x = 0 ; x < ioImg .getWidth (); x ++) {
105+ int argb1 = ioImg .getRGB (x , y );
106+ int argb2 = awtImage .getRGB (x , y );
107+
108+ int alpha1 = (argb1 & 0xff000000 ) >> 24 ;
109+ int alpha2 = (argb2 & 0xff000000 ) >> 24 ;
110+ if (alpha1 == 0 && alpha2 == 0 ) {
111+ continue ;
112+ } else if (alpha1 == 0 || alpha2 == 0 ) {
113+ throw new Error ("pixels at (" + x + ", " + y +
114+ ") have different opacities: " +
115+ Integer .toUnsignedString (argb1 , 16 ) +
116+ " vs " +
117+ Integer .toUnsignedString (argb2 , 16 ));
118+ }
119+ int rgb1 = argb1 & 0xffffff ;
120+ int rgb2 = argb2 & 0xffffff ;
121+ if (rgb1 != rgb2 ) {
122+ throw new Error ("pixels at (" + x + ", " + y +
123+ ") have different opaque RGB values: " +
124+ Integer .toUnsignedString (rgb1 , 16 ) +
125+ " vs " +
126+ Integer .toUnsignedString (rgb2 , 16 ));
127+ }
128+ }
129+ }
130+
131+ if (frameDir != null ) {
132+ // the two models are identical, so simply write one image:
133+ File pngFile = new File (frameDir , "frame_" + a + ".png" );
134+ ImageIO .write (ioImg , "png" , pngFile );
135+ System .out .println ("\t Wrote " + pngFile );
102136 }
103- int rgb1 = argb1 & 0xffffff ;
104- int rgb2 = argb2 & 0xffffff ;
105- if ( rgb1 != rgb2 ) {
106- throw new Error ( "pixels at (" + x + ", " + y +
107- ") have different opaque RGB values: " +
108- Integer . toUnsignedString ( rgb1 , 16 ) + " vs " +
109- Integer . toUnsignedString ( rgb2 , 16 ) );
137+ } catch ( Throwable t ) {
138+ if ( frameDir != null ) {
139+ File f1 = new File ( frameDir , "frame_" + + a + "_iio.png" );
140+ File f2 = new File ( frameDir , "frame_" + + a + "_awt.png" );
141+ ImageIO . write ( ioImg , "png" , f1 );
142+ ImageIO . write ( awtImage , "png" , f2 );
143+ System . out . println ( " \t Wrote " + f1 + " vs " + f2 );
110144 }
145+ throw t ;
111146 }
112147 }
113148 System .out .println ("Passed" );
0 commit comments