Search code examples
javaimagergbrace-conditioncompiler-bug

Possible bug in Java 8 Update 45 on Windows 8


This code takes an input image and produces an output image dimensioned twice as large. The first four lines in the inner loop write four identical-sized copies of the original, the last four lines should overwrite the small images with one copy of the input image twice as large as the original.

The code compiles and runs without error on Java 8 Update 45 on Windows 8. The resulting image is not, as expected, one large copy of the input. The lower half of the output is as expected, but the upper half consists of the two original-sized copies of the input written by the first two lines inside the loop. Commenting out these two lines leads to the initally expected result, so it seems that the first two lines get executed last, not first, despite appearing first in the source code.

Is this a compiler bug, a race condition in the runtime, or a brain fart on my behalf?

If requested, I'll put up examples somewhere.

import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
class HelloWorldApp {
    public static void main(String[] orgs) throws IOException {

        BufferedImage pic = ImageIO.read(new File("cat.jpg"));

        int w=pic.getWidth(),h=pic.getHeight();
        BufferedImage out = new BufferedImage(w+w,h+h,pic.getType());
        for (int y=0;y<h;y++) {
            for (int x=0;x<w;x++) {
                int pixel = pic.getRGB(x,y);
                // write four small copies
                out.setRGB(x    ,y    ,pixel); // these two lines apparently are
                out.setRGB(x+w  ,y    ,pixel); // executed after the remaining six
                out.setRGB(x    ,y+h  ,pixel);
                out.setRGB(x+w  ,y+h  ,pixel);
                // overwrite with one large copy
                out.setRGB(x+x  ,y+y  ,pixel);
                out.setRGB(x+x+1,y+y  ,pixel);
                out.setRGB(x+x  ,y+y+1,pixel);
                out.setRGB(x+x+1,y+y+1,pixel);
            }
        }

        ImageIO.write(out, "bmp", new File("./cat.bmp"));

    }
}

Solution

  • It's a brain fart I'm afraid. Becaue you're doing everything in the same loop, executing the initial four lines (small copies) in later iterations ends up overwriting the pixels that were written by the last four lines (large copy) in earlier iterations.

    I'm not sure I worded that brilliantly but hopefully you'll see what I mean.