Search code examples
c#xnatexture2dheightmap

Big-Endian Conversion from a texture


I am trying to extract the height from a file like this: http://visibleearth.nasa.gov/view.php?id=73934

The pixels are loaded into an Int32 array

    private Int16[] heights;
    private int Width, Height;

    public TextureData(Texture2D t)
    {
        Int32[] data = new Int32[t.Width * t.Height];
        t.GetData<Int32>(data);
        Width = t.Width;
        Height = t.Height;
        t.Dispose();
        heights= new Int16[t.Width * t.Height];
        for (int i = 0; i < data.Length; ++i)
        {
            heights[i] = ReverseBytes(data[i]);
        }
    }

    // reverse byte order (16-bit)
    public static Int16 ReverseBytes(Int32 value)
    {
        return (Int16)( ((value << 8) | (value >> 8)) );
    }

I dont know why but the heights are not correct... I think the Big Endian conversion is wrong, can you help me please?

this is the result, the heights are higher than expected... https://i.sstatic.net/LTGjp.png

EDIT:

    public static int ReverseBytes(int value)
    {
        int sign = (value & 0x8000) >> 15;
        int msb = (value & 0x7F) >> 7;
        int lsb = (value & 0xFF) << 8;
        return (msb | lsb | sign);
    }

is this ok? I don't know why but it is still wrong...


Solution

  • int refers to a 32 bit signed integer but your byte-reverser is written for a 16 bit signed integer so it will only work for positive values up to 32767. If you have any values higher than that you will need to shift and then mask one byte at a time before "orring" them together.