public static byte[] MiniEXRWrite(uint _width, uint _height, uint _channels, float[] _rgbaArray) { //const void* rgba16f uint ww = _width - 1; uint hh = _height - 1; byte[] kHeader = { 0x76, 0x2f, 0x31, 0x01, // magic 2, 0, 0, 0, // version, scanline // channels (byte)'c', (byte)'h', (byte)'a', (byte)'n', (byte)'n', (byte)'e', (byte)'l', (byte)'s', 0, (byte)'c', (byte)'h', (byte)'l', (byte)'i', (byte)'s', (byte)'t', 0, 55, 0, 0, 0, (byte)'B', 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, // R, half (byte)'G', 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, // G, half (byte)'R', 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, // B, half 0, // compression (byte)'c', (byte)'o', (byte)'m', (byte)'p', (byte)'r', (byte)'e', (byte)'s', (byte)'s', (byte)'i',(byte)'o', (byte)'n', 0, (byte)'c', (byte)'o', (byte)'m', (byte)'p', (byte)'r', (byte)'e', (byte)'s', (byte)'s', (byte)'i',(byte)'o', (byte)'n', 0, 1, 0, 0, 0, 0, // no compression // dataWindow (byte)'d', (byte)'a', (byte)'t', (byte)'a', (byte)'W', (byte)'i', (byte)'n', (byte)'d', (byte)'o',(byte)'w', 0, (byte)'b', (byte)'o', (byte)'x', (byte)'2', (byte)'i', 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte)(ww & 0xFF), (byte)((ww >> 8) & 0xFF), (byte)((ww >> 16) & 0xFF), (byte)((ww >> 24) & 0xFF), (byte)(hh & 0xFF), (byte)((hh >> 8) & 0xFF), (byte)((hh >> 16) & 0xFF), (byte)((hh >> 24) & 0xFF), // displayWindow (byte)'d', (byte)'i', (byte)'s', (byte)'p', (byte)'l', (byte)'a', (byte)'y', (byte)'W', (byte)'i',(byte)'n', (byte)'d', (byte)'o', (byte)'w', 0, (byte)'b', (byte)'o', (byte)'x', (byte)'2', (byte)'i', 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte)(ww & 0xFF), (byte)((ww >> 8) & 0xFF), (byte)((ww >> 16) & 0xFF), (byte)((ww >> 24) & 0xFF), (byte)(hh & 0xFF), (byte)((hh >> 8) & 0xFF), (byte)((hh >> 16) & 0xFF), (byte)((hh >> 24) & 0xFF), // lineOrder (byte)'l', (byte)'i', (byte)'n', (byte)'e', (byte)'O', (byte)'r', (byte)'d', (byte)'e', (byte)'r', 0, (byte)'l', (byte)'i', (byte)'n', (byte)'e', (byte)'O', (byte)'r', (byte)'d', (byte)'e', (byte)'r', 0, 1, 0, 0, 0, 0, // increasing Y // pixelAspectRatio (byte)'p', (byte)'i', (byte)'x', (byte)'e', (byte)'l', (byte)'A', (byte)'s', (byte)'p', (byte)'e',(byte)'c', (byte)'t', (byte)'R', (byte)'a', (byte)'t', (byte)'i', (byte)'o', 0, (byte)'f', (byte)'l', (byte)'o', (byte)'a', (byte)'t', 0, 4, 0, 0, 0, 0, 0, 0x80, 0x3f, // 1.0f // screenWindowCenter (byte)'s', (byte)'c', (byte)'r', (byte)'e', (byte)'e', (byte)'n', (byte)'W', (byte)'i', (byte)'n',(byte)'d', (byte)'o', (byte)'w', (byte)'C', (byte)'e', (byte)'n', (byte)'t', (byte)'e', (byte)'r',0, (byte)'v', (byte)'2', (byte)'f', 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // screenWindowWidth (byte)'s', (byte)'c', (byte)'r', (byte)'e', (byte)'e', (byte)'n', (byte)'W', (byte)'i', (byte)'n',(byte)'d', (byte)'o', (byte)'w', (byte)'W', (byte)'i', (byte)'d', (byte)'t', (byte)'h', 0, (byte)'f', (byte)'l', (byte)'o', (byte)'a', (byte)'t', 0, 4, 0, 0, 0, 0, 0, 0x80, 0x3f, // 1.0f // end of header 0, }; uint kHeaderSize = (uint)kHeader.Length; uint kScanlineTableSize = 8 * _height; uint pixelRowSize = _width * 3 * 2; uint fullRowSize = pixelRowSize + 8; uint bufSize = kHeaderSize + kScanlineTableSize + _height * fullRowSize; byte[] buf = new byte[bufSize]; // copy in header int bufI = 0; for (int i = 0; i < kHeaderSize; i++) { buf[bufI] = kHeader[i]; bufI++; } // line offset table uint ofs = kHeaderSize + kScanlineTableSize; for (int y = 0; y < _height; ++y) { buf[bufI++] = (byte)(ofs & 0xFF); buf[bufI++] = (byte)((ofs >> 8) & 0xFF); buf[bufI++] = (byte)((ofs >> 16) & 0xFF); buf[bufI++] = (byte)((ofs >> 24) & 0xFF); buf[bufI++] = 0; buf[bufI++] = 0; buf[bufI++] = 0; buf[bufI++] = 0; ofs += fullRowSize; } //Convert float to half float ushort[] srcHalf = new ushort[_rgbaArray.Length]; for (int i = 0; i < _rgbaArray.Length; i++) { //Gamma encode before converting _rgbaArray[i] = Mathf.Pow(_rgbaArray[i], 2.2f); srcHalf[i] = HalfHelper.SingleToHalf(_rgbaArray[i]); } uint srcDataI = 0; for (int y = 0; y < _height; ++y) { // coordinate buf[bufI++] = (byte)(y & 0xFF); buf[bufI++] = (byte)((y >> 8) & 0xFF); buf[bufI++] = (byte)((y >> 16) & 0xFF); buf[bufI++] = (byte)((y >> 24) & 0xFF); // data size buf[bufI++] = (byte)(pixelRowSize & 0xFF); buf[bufI++] = (byte)((pixelRowSize >> 8) & 0xFF); buf[bufI++] = (byte)((pixelRowSize >> 16) & 0xFF); buf[bufI++] = (byte)((pixelRowSize >> 24) & 0xFF); // B, G, R //memcpy (ptr, src, width*6); //Copy first line - 6 bits, 2 bits per channel //First copy a line of B uint tempSrcI = srcDataI; for (int x = 0; x < _width; ++x) { //Blue byte[] halfBytes = System.BitConverter.GetBytes(srcHalf[tempSrcI + 2]); buf[bufI++] = halfBytes[0]; buf[bufI++] = halfBytes[1]; tempSrcI += _channels; } //Then copy a line of G tempSrcI = srcDataI; for (int x = 0; x < _width; ++x) { //Blue byte[] halfBytes = System.BitConverter.GetBytes(srcHalf[tempSrcI + 1]); buf[bufI++] = halfBytes[0]; buf[bufI++] = halfBytes[1]; tempSrcI += _channels; } //Finally copy a line of R tempSrcI = srcDataI; for (int x = 0; x < _width; ++x) { //Blue byte[] halfBytes = System.BitConverter.GetBytes(srcHalf[tempSrcI]); buf[bufI++] = halfBytes[0]; buf[bufI++] = halfBytes[1]; tempSrcI += _channels; } srcDataI += _width * _channels; } return(buf); }
private static byte[] MiniEXRWrite(uint _width, uint _height, uint _channels, float[] _rgbaArray) { uint num = _width - 1u; uint num2 = _height - 1u; byte[] array = new byte[] { 118, 47, 49, 1, 2, 0, 0, 0, 99, 104, 97, 110, 110, 101, 108, 115, 0, 99, 104, 108, 105, 115, 116, 0, 55, 0, 0, 0, 66, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 71, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 82, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 99, 111, 109, 112, 114, 101, 115, 115, 105, 111, 110, 0, 99, 111, 109, 112, 114, 101, 115, 115, 105, 111, 110, 0, 1, 0, 0, 0, 0, 100, 97, 116, 97, 87, 105, 110, 100, 111, 119, 0, 98, 111, 120, 50, 105, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 105, 115, 112, 108, 97, 121, 87, 105, 110, 100, 111, 119, 0, 98, 111, 120, 50, 105, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 105, 110, 101, 79, 114, 100, 101, 114, 0, 108, 105, 110, 101, 79, 114, 100, 101, 114, 0, 1, 0, 0, 0, 0, 112, 105, 120, 101, 108, 65, 115, 112, 101, 99, 116, 82, 97, 116, 105, 111, 0, 102, 108, 111, 97, 116, 0, 4, 0, 0, 0, 0, 0, 128, 63, 115, 99, 114, 101, 101, 110, 87, 105, 110, 100, 111, 119, 67, 101, 110, 116, 101, 114, 0, 118, 50, 102, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 99, 114, 101, 101, 110, 87, 105, 110, 100, 111, 119, 87, 105, 100, 116, 104, 0, 102, 108, 111, 97, 116, 0, 4, 0, 0, 0, 0, 0, 128, 63, 0 }; array[141] = (byte)(num & 255u); array[142] = (byte)(num >> 8 & 255u); array[143] = (byte)(num >> 16 & 255u); array[144] = (byte)(num >> 24 & 255u); array[145] = (byte)(num2 & 255u); array[146] = (byte)(num2 >> 8 & 255u); array[147] = (byte)(num2 >> 16 & 255u); array[148] = (byte)(num2 >> 24 & 255u); array[181] = (byte)(num & 255u); array[182] = (byte)(num >> 8 & 255u); array[183] = (byte)(num >> 16 & 255u); array[184] = (byte)(num >> 24 & 255u); array[185] = (byte)(num2 & 255u); array[186] = (byte)(num2 >> 8 & 255u); array[187] = (byte)(num2 >> 16 & 255u); array[188] = (byte)(num2 >> 24 & 255u); byte[] array2 = array; uint num3 = (uint)array2.Length; uint num4 = 8u * _height; uint num5 = _width * 3u * 2u; uint num6 = num5 + 8u; byte[] array3 = new byte[num3 + num4 + _height * num6]; int num7 = 0; int num8 = 0; while ((long)num8 < (long)((ulong)num3)) { array3[num7] = array2[num8]; num7++; num8++; } uint num9 = num3 + num4; int num10 = 0; while ((long)num10 < (long)((ulong)_height)) { array3[num7++] = (byte)(num9 & 255u); array3[num7++] = (byte)(num9 >> 8 & 255u); array3[num7++] = (byte)(num9 >> 16 & 255u); array3[num7++] = (byte)(num9 >> 24 & 255u); array3[num7++] = 0; array3[num7++] = 0; array3[num7++] = 0; array3[num7++] = 0; num9 += num6; num10++; } ushort[] array4 = new ushort[_rgbaArray.Length]; for (int i = 0; i < _rgbaArray.Length; i++) { _rgbaArray[i] = Mathf.Pow(_rgbaArray[i], 2.2f); array4[i] = HalfHelper.SingleToHalf(_rgbaArray[i]); } uint num11 = 0u; int num12 = 0; while ((long)num12 < (long)((ulong)_height)) { array3[num7++] = (byte)(num12 & 255); array3[num7++] = (byte)(num12 >> 8 & 255); array3[num7++] = (byte)(num12 >> 16 & 255); array3[num7++] = (byte)(num12 >> 24 & 255); array3[num7++] = (byte)(num5 & 255u); array3[num7++] = (byte)(num5 >> 8 & 255u); array3[num7++] = (byte)(num5 >> 16 & 255u); array3[num7++] = (byte)(num5 >> 24 & 255u); uint num13 = num11; int num14 = 0; while ((long)num14 < (long)((ulong)_width)) { byte[] bytes = BitConverter.GetBytes(array4[(int)(num13 + 2u)]); array3[num7++] = bytes[0]; array3[num7++] = bytes[1]; num13 += _channels; num14++; } num13 = num11; int num15 = 0; while ((long)num15 < (long)((ulong)_width)) { byte[] bytes2 = BitConverter.GetBytes(array4[(int)(num13 + 1u)]); array3[num7++] = bytes2[0]; array3[num7++] = bytes2[1]; num13 += _channels; num15++; } num13 = num11; int num16 = 0; while ((long)num16 < (long)((ulong)_width)) { byte[] bytes3 = BitConverter.GetBytes(array4[(int)num13]); array3[num7++] = bytes3[0]; array3[num7++] = bytes3[1]; num13 += _channels; num16++; } num11 += _width * _channels; num12++; } return(array3); }