Good, more diagrams, and you got the code tags - excellent![smile]
What I thought you might not fully understand is that bilinear interpolation of images is exactly the same process as it is for generating smoothed map data.
This is known as point sampling:
+---+---+---+|555|111|444||555|111|444||555|111|444|+---+---+---+|999|555|222||999|555|222||999|555|222|+---+---+---+|333|888|777||333|888|777||333|888|777|+---+---+---+
All well and good.
Here is the sample as you probably imagine it, without any of the interpolated pixels calculated:
+---+---+---+|???|???|???||?5?|?1?|?4?||???|???|???|+---+---+---+|???|???|???||?9?|?5?|?2?||???|???|???|+---+---+---+|???|???|???||?3?|?8?|?7?||???|???|???|+---+---+---+
Now, if you expect those grid points with numbers in them to be exactly as shown with the interpolation, how would you plan to calculate the numbers in say the position of the top-left question mark? It's not located between the 5 and the 1 horizontally, nor is it located between the 5 and the 9 vertically. You'd need to calculate it via extrapolation if this is how you imagined it. This is the difficult way, and it really doesn't work nicely for what you want.
On the other hand you can start out like:
+---+---+---+|5??|?1?|??4||???|???|???||???|???|???|+---+---+---+|???|???|???||9??|?5?|??2||???|???|???|+---+---+---+|???|???|???||???|???|???||3??|?8?|??7|+---+---+---+
What I've done here is stretch the source image out by
almost one "source pixel". The numbers at the positions shown are the final values. Now you can clearly calculate the values for all of the question marks because they are all located between known values. For example the first three question marks on the top row would be 4, 3, and 2, correct?
Okay, if this is how you want to do it it's easy:
Iterate over every "destination pixel" (ahem grid tile or whatever) and calculate the exact fractional position that that position refers to on the source "image". when performing lookups. For the question mark in the sixth row and the second column it's source coordinates are 1.25 and 0.25. You use the whole numbers to look up the source pixels, and the whole numbers plus one. So that's source positions (1, 0) (1, 1) (2, 0) and (2, 1).
Now you perform the interpolation using the fractional parts. In this case it's 0.25 of the lower two samples and 0.75 of the upper two. Ditto for the horizontal interpolation.
("1"*0.75 + "4"*0.25)*0.75 + ("5"*0.75 + "2"*0.25)*0.25 = Bingo!
Or you can start with one extra row and column of data like this:
+---+---+---+|5??|1??|4??|8|???|???|???|X|???|???|???|X+---+---+---+-|9??|5??|2??|2|???|???|???|X|???|???|???|X+---+---+---+-|3??|8??|7??|6|???|???|???|X|???|???|???|X+---+---+---+-|0XX|3XX|2XX|5
Again you can calculate the value for every question mark square because it is actually between known values. This method puts each nown value in the same place and makes the interpolation potentially faster, but requires an extra row and column of data.
For the question mark in the sixth row and the second column it's source coordinates are now 1.667 and 0.333. The integer portions are the same here so you still read the values 1, 4, 5 and 2, but now you take slightly different portions of each to fill in that grid position.
Note that the easy way to get one extra row and column is to make it wrap around for the rightmost column such that it actually reads the value from the leftmost column again. I.e:
+---+---+---+|5??|1??|4??|5|???|???|???|X|???|???|???|X+---+---+---+-|9??|5??|2??|9|???|???|???|X|???|???|???|X+---+---+---+-|3??|8??|7??|3|???|???|???|X|???|???|???|X+---+---+---+-|5XX|1XX|4XX|5
This also makes the resulting map tileable, and it's the method usually used in texture bilinear filtering.
Hmm well that's all I have time for right now. I'll let you digest all that for now as you probably need to adjust your thinking somewhat. I suspect that you're either not sure which one of these methods your using, which has led the the problem, or you're trying the method that would require extrapolation.
Edit: Oh one last thing I just realised, it looks like you might be trying to interpolate the values in one destination pixel from the values of the source pixels above, below, left, and right of the desintation pixel. If so, that is definitely wrong and although it makes some sense to someone who is new to interpolation, it will not work and probably explains why you're getting what you're getting.