HW1b Hints:

1. Java does not have unsigned values, so the byte type is actually an 8-bit signed value ranging from -128 to 127. So when bytes are converted to ints for the alpha-compositing calculations, Java automatically sign-extends the value, which is probably not what you want.
To get rid of the sign extension, you can mask off the most-significant 24 bits, leaving just the original 8-bit value. The mask can be applied by using a bitwise AND with the value 255 (or 0x00ff in hexadecimal).
Here's an example:

byte b = (byte)255;// need to type-cast because 255 is out of the range of signed bytes
int i1 = b; // i1 == -1
int i2 = b & 0x00ff; // i2 == 255

2. There is no need to create a new brush every time applyBrush() or applyEraser() is called. Instead, you could create and store a brush image in the recomputeBrush() function, which is called whenever the user moves the sliders. The brush image only has to store the alpha channel, since the color is constant for the whole brush image.

3. The member variables brushExp and brushRad contain the brush's exponent value and radius respectively. They are automatically updated when the uesr moves the silders. You could use them, as well as the getter functions getBrushColor() and getBrushOpacity() to retrieve the parameters for the brush.

4. The only paint image you need to modify in applyBrush() and applyEraser() is currentPaintImage. This is a pointer to the currently selected layer and changes whenever the user selects the background or foreground layer.