This is all much simpler if you look at the data in hexadecimal format. 5652 becomes 0x1614, which is clearly bytes 0x16 and 0x14. Or, 0x16 * 0x100 + 0x14
.
The opposite of multiplying with 0x100 should simply be dividing it by 0x100, but to actually cut off the excess, I advise using the AND bit operation.
AND will keep only the bits that are common in both values, so, in binary representation, to keep only the lowest 8 bits, you need to AND it with a value with all 8 bits enabled, which would be 0xFF. The AND between 0x1614 (your "5652" example) and 0xFF, viewed in binary format, would go like this:
00010110 00010100
00000000 11111111
v------AND------v
00000000 00010100
As you see, it effectively cuts off everything higher than the lowest byte, resulting in 00010100b, or 0x14, or 20.
For dividing by multiples of 2, there is another bit operation that is very handy and really efficient: bit shifting. 0x100 is actually '1', shifted up by 8 bits. So to get the original value back, it just needs to be shifted down by 8 bits.
if your colour is B * 0x10000 + G * 0x100 + R
, then to reverse it:
public static Color GetColorFromInterop(Int32 val)
{
// Limit to a value containing only the bits in 0xFF
Int32 r = val & 0xFF;
// Shift down by 8 bits (meaning, divide by 0x100), then limit to 0xFF
Int32 g = (val >> 8) & 0xFF;
// Shift down by 16 bits (meaning, divide by 0x10000), then limit to 0xFF
Int32 b = (val >> 16) & 0xFF;
return Color.FromArgb(r, g, b);
}