Example #1
0
        public static bool writeHDR(ref Color[] pixels, int width, int height, string fullPath)
        {
            FileStream   fs     = new FileStream(fullPath, FileMode.Create);
            BinaryWriter stream = new BinaryWriter(fs);

            writeCString(ref stream, "#?RADIANCE\n");
            writeCString(ref stream, "# Organically grown in Marmoset Skyshop for Unity\n");
            writeCString(ref stream, "FORMAT=32-bit_rle_rgbe\n");
            writeCString(ref stream, "EXPOSURE=1.0\n\n");

            string Y;
            bool   flipY = true;           //Photoshop and HDRshop happily ignore this flag and expect a flipped Y

            if (flipY)
            {
                Y = "+Y ";
            }
            else
            {
                Y = "+Y ";
            }
            writeCString(ref stream, Y + height + " +X " + width + "\n");

            byte[] rowHeader = new byte[4];
            for (int r = 0; r < height; ++r)
            {
                rowHeader[0] = 2;
                rowHeader[1] = 2;
                rowHeader[2] = (byte)(width >> 8);
                rowHeader[3] = (byte)(width & 255);
                stream.Write(rowHeader);

                int rowOffset;
                if (flipY)
                {
                    rowOffset = (height - r - 1) * width;
                }
                else
                {
                    rowOffset = r * width;
                }
                for (int c = 0; c < 4; ++c)
                {
                    int i = 0;
                    while (i < width)
                    {
                        //HACK: always dump, no RLE compression
                        byte n = (byte)Mathf.Min(width - i, 128);
                        stream.Write(n);
                        for (byte dump = 0; dump < n; ++dump)
                        {
                            Color32 rgbe = new Color32();
                            RGB.toRGBE(ref rgbe, pixels[rowOffset + i]);
                            if (c == 0)
                            {
                                stream.Write(rgbe.r);
                            }
                            else if (c == 1)
                            {
                                stream.Write(rgbe.g);
                            }
                            else if (c == 2)
                            {
                                stream.Write(rgbe.b);
                            }
                            else
                            {
                                stream.Write(rgbe.a);
                            }
                            ++i;
                        }
                    }
                }
            }
            stream.Close();
            fs.Close();
            return(true);
        }
Example #2
0
        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);
        }
Example #3
0
        //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);
        }