*sigh*
I found why it was locking to square roots of 2 - I needed to change
int i = y * width + x * numBytes;
To multiply y by the texture width, not the image width.
So, now the method sort of works for most images. There are two problems, though:
First, I'm getting the right colors but the alpha is still messed up somehow - sections that should be transparent appear black, and, more disturbingly, sections that should be opaque and colored in are showing images behind them.
Secondly, the method seems to break when the cursor gets very small for some reason. If I make the image something like 7 x 12, it starts getting wonky again.
If I make the cursor read the entire image, not just the image on top of it, it works better.