public static void encode(ref Color32[] dst, Color[] src, ColorMode outMode, bool useGamma) { if (outMode == ColorMode.RGBM8) { for (int i = 0; i < src.Length; ++i) { RGB.toRGBM(ref dst[i], src[i], useGamma); } } else { if (useGamma) { mset.Util.applyGamma(ref src, src, Gamma.toSRGB); } pixelCopy(ref dst, 0, src, 0, src.Length); } }
public static bool readHDR(ref Texture2D tex, string path) { string fullPath = Application.dataPath + "/" + path.Substring(7); FileStream fs = new FileStream(fullPath, FileMode.Open); BinaryReader stream = new BinaryReader(fs); string properMagic = "#?RADIANCE"; char[] magic = stream.ReadChars(properMagic.Length); string magicStr = new string(magic, 0, magic.Length); if (!magicStr.Equals(properMagic)) { Debug.LogError("Invalid .hdr file, magic: " + magic); return(false); } //read in our parameters bool xyz = false; float exposure = 1f; //bool flipX=false; //Yeah no we're not doing that. --Andres bool flipY = false; int width = -1; int height = -1; string name = ""; string val = ""; //HEADER - terminated by a blank line while (stream.PeekChar() != -1 && (width == -1 || height == -1)) { readPair(ref stream, ref name, ref val); name = name.ToLowerInvariant(); val = val.ToLowerInvariant(); if (name.Equals("format")) { if (val.Equals("32-bit_rle_rgbe")) { xyz = false; } else if (val.Equals("32-bit_rle_xyze")) { xyz = true; } } else if (name.Equals("exposure")) { exposure = Convert.ToSingle(val); } if (name.Equals("+x")) { //flipX = false; width = Convert.ToInt32(val); } else if (name.Equals("-x")) { //flipX = true; width = Convert.ToInt32(val); } else if (name.Equals("+y")) { flipY = false; height = Convert.ToInt32(val); } else if (name.Equals("-y")) { flipY = true; height = Convert.ToInt32(val); } else { //do not want } } //Wat? some .HDR files do this and break everything. if (exposure <= 0f) { exposure = 1f; } if (width <= 0 || height <= 0) { Debug.LogError("Invalid dimensions found in .hdr file (" + width + " x " + height + ")"); return(false); } tex.Resize(width, height, TextureFormat.ARGB32, false); Color[] pixels = tex.GetPixels(); byte[] rowHeader = null; for (int r = 0; r < height; ++r) { int rowOffset = r * width; rowHeader = stream.ReadBytes(4); if (rowHeader[0] != 2 || rowHeader[1] != 2 || (256 * rowHeader[2] + rowHeader[3]) != width) { Debug.LogError("Invalid row header data found in .hdr file"); return(false); } for (int c = 0; c < 4; ++c) { int i = 0; while (i < width) { byte n = stream.ReadByte(); if (n > 128) { //run, duplicate the next byte 'n' times n -= 128; if (i + (int)n > width) { Debug.LogError("invalid row size found in hdr file (corrupt or otherwise odd file?)"); return(false); } byte b = stream.ReadByte(); float f = (float)b; for (byte run = 0; run < n; ++run) { pixels[rowOffset + i][c] = f; ++i; } } else { //dump, read the next 'n' components if (i + n > width) { Debug.LogError("invalid row size found in hdr file (corrupt or otherwise odd file?)"); return(false); } for (int dump = 0; dump < n; ++dump) { byte b = stream.ReadByte(); float f = (float)b; pixels[rowOffset + i][c] = f; ++i; } } } } } stream.Close(); fs.Close(); Color32[] dst = new Color32[pixels.Length]; //convert the row to real color for (int r = 0; r < height; ++r) { int rowOffset = r * width; int dstOffset = rowOffset; if (flipY) { dstOffset = (height - r - 1) * width; } int src_i, dst_i; float e, scale; for (int c = 0; c < width; ++c) { src_i = rowOffset + c; dst_i = dstOffset + c; e = pixels[src_i][3] - 128f; scale = exposure * Mathf.Pow(2f, e) / 255f; pixels[src_i][0] = pixels[src_i][0] * scale; pixels[src_i][1] = pixels[src_i][1] * scale; pixels[src_i][2] = pixels[src_i][2] * scale; pixels[src_i][3] = 1f; if (xyz) { RGB.fromXYZ(ref pixels[src_i], pixels[src_i]); } RGB.toRGBM(ref dst[dst_i], pixels[src_i], true); } } tex.SetPixels32(dst); tex.Apply(false); return(true); }
//LOADERS public static bool readPFM(ref Texture2D tex, string path) { string fullPath = Application.dataPath + "/" + path.Substring(7); FileStream fs = new FileStream(fullPath, FileMode.Open); BinaryReader stream = new BinaryReader(fs); string [] line = new string[4]; char c; for (int i = 0; i < 4; ++i) { do //read up to whitespace { c = stream.ReadChar(); line[i] += c; } while(c != '\n' && c != '\t' && c != ' ' && c != '\r'); //in between lines kill the whitespace if (i < 3) { while (c != '\n' && c != '\t' && c != ' ' && c != '\r') { c = stream.ReadChar(); } } } int mComponentSize, mComponentCount; bool float32 = false; bool float16 = false; if (line[0][0] == 'P') { mComponentSize = 4; float32 = true; } else if (line[0][0] == 'p') { mComponentSize = 2; float16 = true; } else { Debug.LogError("image not in PFM format\n"); return(false); } if (line[0][1] == 'F') { mComponentCount = 3; } else if (line[0][1] == 'f') { mComponentCount = 1; } else { Debug.LogError("image not in PFM format\n"); return(false); } if (float16) { Debug.LogError("float16 PFMs not supported, please convert to float32\n"); return(false); } int mWidth = Convert.ToInt32(line[1]); int mHeight = Convert.ToInt32(line[2]); float scale = Convert.ToSingle(line[3]); int mDataSize = mComponentSize * mComponentCount * mWidth * mHeight; float[] floatData = new float[mDataSize / 4]; for (int i = 0; i < mDataSize / 4; ++i) { floatData[i] = stream.ReadSingle(); } stream.Close(); fs.Close(); tex.Resize(mWidth, mHeight, TextureFormat.ARGB32, false); Color32[] pixels32 = tex.GetPixels32(); //apply scale scale = Mathf.Abs(scale); if (float32) { Color pixel = new Color(); for (int x = 0; x < mWidth; ++x) { for (int y = 0; y < mHeight; ++y) { int i = x + y * mWidth; int j = x + (mHeight - y - 1) * mWidth; pixel.r = scale * floatData[j * mComponentCount]; pixel.g = scale * floatData[j * mComponentCount + 1]; pixel.b = scale * floatData[j * mComponentCount + 2]; RGB.toRGBM(ref pixels32[i], pixel, true); } } } else if (float16) { //float16 pfms are something we made up for toolbag apparently. } tex.SetPixels32(pixels32); tex.Apply(false); return(true); }