Cutting up Heightmaps into smaller squares...

That was very enlightening but doesn’t help me understand how to write integers in Little-Endian format… seems like that has more to do with memory, etc.

What would be the difference in writing in Little Endian vs. Big Endian when I’m writing specifically in this context?

I think it would be something similar to this.
Basically, you are shifting the bytes off the end of the in-memory number and isolating them one at a time so you can store them in reverse order.


static const int bytesInInteger = 4;
static const int bytesInLong = 8;

void outputAsLittleEndian(int bigEndianInt) {
    byte[] bytes = new bytes[bytesInInteger ];
    for (int i = 0 ; i < bytesInInteger ; i++) {
        bytes[i] = (bigEndianInt >> ((i & 7) << 3)) & 0xFF;
    }
    for (i = 0 ; i < bytesInInteger ; i++) {
        System.out.println(bytes[i]);
    }

void outputAsLittleEndian(long bigEndianLong) {
    byte[] bytes = new bytes[bytesInLong ];
    for (int i = 0 ; i < bytesInLong ; i++) {
        bytes[i] = (bigEndianLong >> ((i & 7) << 3)) & 0xFF;
    }
    for (i = 0 ; i < bytesInLong ; i++) {
        System.out.println(bytes[i]);
    }
}

I think I may solve this in a way very specific to what I am doing… I could do an ObjectOutputStream for the height data stored in an array of Integers and that would plug in directly with jME’s RawHeightMap class… somehow.

I just checked, using ObjectOutputStream will not work to write a RAW file.

There’s something below that should work for you for writing an array of ints. Written for clarity: I’m not claiming it’s the bestest & fastest way but it should work fine and it should illustrate endianness. Check the output in a hex editor:


...
        // does not work, will have a header:
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("oos.obj")));
        oos.writeInt(1);
        oos.writeInt(2);
        oos.writeInt(3);
        oos.writeInt(4);
        oos.close();
        
        // below works:
        FileOutputStream fos;
        int[] i = {1,2,3,4};

        // 32bit little endian:
        fos = new FileOutputStream(new File("myints32le.dat"));
        writeLE(i, fos);
        fos.close();

        // 32bit big endian:
        fos = new FileOutputStream(new File("myints32be.dat"));
        writeBE(i, fos);
        fos.close();

        // 16bit little endian:
        fos = new FileOutputStream(new File("myints16le.dat"));
        writeLE16(i, fos);
        fos.close();

        // 16bit big endian:
        fos = new FileOutputStream(new File("myints16be.dat"));
        writeBE16(i, fos);
        fos.close();


...

    private void writeLE(int[] values, OutputStream os) throws IOException {
        for (int i : values) {
            os.write(i & 0xff);
            os.write((i >> 8) & 0xff);
            os.write((i >> 16) & 0xff);
            os.write((i >>> 24) & 0xff);
        }
    }

    private void writeBE(int[] values, OutputStream os) throws IOException {
        for (int i : values) {
            os.write((i >>> 24) & 0xff);
            os.write((i >> 16) & 0xff);
            os.write((i >> 8) & 0xff);
            os.write(i & 0xff);
        }
    }
    
    private void writeLE16(int[] values, OutputStream os) throws IOException {
        for (int i : values) {
            os.write(i & 0xff);
            os.write((i >> 8) & 0xff);
        }
    }

    private void writeBE16(int[] values, OutputStream os) throws IOException {
        for (int i : values) {
            os.write((i >> 8) & 0xff);
            os.write(i & 0xff);
        }
    }

You can use ImageOutputStream implementations (like e.g FileImageOutputStream) and use the setByteOrder() method to set the endianness.

So if I have the height values stored as int[] can I just do fileImageOutputStream.write(int[]), or will that store it in a more complicated way?

You can use writeInts(int[] i, int off, int len) for this.

erikd gave you the code, what else do you need