Пример #1
0
 public void Read(EXRFile file, IEXRReader reader)
 {
     while (EXRAttribute.Read(file, reader, out EXRAttribute attribute))
     {
         Attributes[attribute.Name] = attribute;
     }
 }
Пример #2
0
        protected void ReadPixelData(IEXRReader reader)
        {
            var linesPerBlock  = EXRFile.GetScanLinesPerBlock(Header.Compression);
            var sortedChannels = (from c in Header.Channels orderby c.Name select c).ToList();

            //var actions = (from offset in Offsets select (Action)(() => {
            //}));
            //Parallel.Invoke(actions.ToArray());
            foreach (var offset in Offsets)
            {
                ReadPixelBlock(reader, offset, linesPerBlock, sortedChannels);
            }
        }
Пример #3
0
        private void ReadPixelDataParallel(ParallelReaderCreationDelegate createReader)
        {
            var linesPerBlock  = EXRFile.GetScanLinesPerBlock(Header.Compression);
            var sortedChannels = (from c in Header.Channels orderby c.Name select c).ToList();

            var actions = (from offset in Offsets select(Action)(() => {
                var reader = createReader();
                ReadPixelBlock(reader, offset, linesPerBlock, sortedChannels);
                reader.Dispose();
            }));

            Parallel.Invoke(actions.ToArray());
        }
Пример #4
0
        public static EXRFile FromReader(IEXRReader reader)
        {
            var img = new EXRFile();

            img.Read(reader);

            img.Parts = new List <EXRPart>();
            for (int i = 0; i < img.Headers.Count; i++)
            {
                var part = new EXRPart(img.Version, img.Headers[i], img.OffsetTables[i]);
                img.Parts.Add(part);
                //part.ReadPixelData(reader);
            }

            return(img);
        }
Пример #5
0
        public float[] GetFloats(ImageSourceFormat srcFormat, ChannelConfiguration channels, bool premultiplied, GammaEncoding gamma)
        {
            ImageDestFormat destFormat;

            if (srcFormat == ImageSourceFormat.HalfRGBA || srcFormat == ImageSourceFormat.SingleRGBA)
            {
                if (premultiplied)
                {
                    destFormat =
                        channels == ChannelConfiguration.BGR ?
                        ImageDestFormat.PremultipliedBGRA32 :
                        ImageDestFormat.PremultipliedRGBA32;
                }
                else
                {
                    destFormat =
                        channels == ChannelConfiguration.BGR ?
                        ImageDestFormat.BGRA32 :
                        ImageDestFormat.RGBA32;
                }
            }
            else
            {
                destFormat =
                    channels == ChannelConfiguration.BGR ?
                    ImageDestFormat.BGR32 :
                    ImageDestFormat.RGB32;
            }

            var bytesPerPixel = EXRFile.GetBytesPerPixel(destFormat);
            var channelCount  =
                srcFormat == ImageSourceFormat.SingleRGB || srcFormat == ImageSourceFormat.HalfRGB ? 3 : 4;

            var bytes = GetBytes(srcFormat, destFormat, gamma, DataWindow.Width * bytesPerPixel);

            float[] floats = new float[bytes.Length / sizeof(float)];
            Buffer.BlockCopy(bytes, 0, floats, 0, bytes.Length);
            return(floats);
        }
Пример #6
0
        public Half[] GetHalfs(ImageSourceFormat srcFormat, ChannelConfiguration channels, bool premultiplied, GammaEncoding gamma)
        {
            ImageDestFormat destFormat;

            if (srcFormat == ImageSourceFormat.HalfRGBA || srcFormat == ImageSourceFormat.SingleRGBA)
            {
                if (premultiplied)
                {
                    destFormat =
                        channels == ChannelConfiguration.BGR ?
                        ImageDestFormat.PremultipliedBGRA16 :
                        ImageDestFormat.PremultipliedRGBA16;
                }
                else
                {
                    destFormat =
                        channels == ChannelConfiguration.BGR ?
                        ImageDestFormat.BGRA16 :
                        ImageDestFormat.RGBA16;
                }
            }
            else
            {
                destFormat =
                    channels == ChannelConfiguration.BGR ?
                    ImageDestFormat.BGR16 :
                    ImageDestFormat.RGB16;
            }

            var bytesPerPixel = EXRFile.GetBytesPerPixel(destFormat);
            var channelCount  =
                srcFormat == ImageSourceFormat.SingleRGB || srcFormat == ImageSourceFormat.HalfRGB ? 3 : 4;

            var bytes = GetBytes(srcFormat, destFormat, gamma, DataWindow.Width * bytesPerPixel);

            Half[] halfs = new Half[bytes.Length / 2];
            Buffer.BlockCopy(bytes, 0, halfs, 0, bytes.Length);
            return(halfs);
        }
Пример #7
0
        private bool ReadChannel(EXRFile file, IEXRReader reader, out Channel channel, out int bytesRead)
        {
            var start = reader.Position;

            var name = reader.ReadNullTerminatedString(255);

            if (name == "")
            {
                channel   = null;
                bytesRead = reader.Position - start;
                return(false);
            }

            channel = new Channel(
                name,
                (PixelType)reader.ReadInt32(),
                reader.ReadByte() != 0,
                reader.ReadByte(), reader.ReadByte(), reader.ReadByte(),
                reader.ReadInt32(), reader.ReadInt32());

            bytesRead = reader.Position - start;
            return(true);
        }
Пример #8
0
        public void Read(EXRFile file, IEXRReader reader, int size)
        {
            var     totalSize = 0;
            Channel channel;
            int     bytesRead;

            while (ReadChannel(file, reader, out channel, out bytesRead))
            {
                Channels.Add(channel);
                totalSize += bytesRead;

                if (totalSize > size)
                {
                    throw new EXRFormatException("Read " + totalSize + " bytes but Size was " + size + ".");
                }
            }
            totalSize += bytesRead;

            if (totalSize != size)
            {
                throw new EXRFormatException("Read " + totalSize + " bytes but Size was " + size + ".");
            }
        }
Пример #9
0
        /// <summary>
        /// Returns true unless this is the end of the header
        /// </summary>
        public bool Read(EXRFile file, IEXRReader reader)
        {
            var maxLen = file.Version.MaxNameLength;

            try
            {
                Name = reader.ReadNullTerminatedString(maxLen);
            }
            catch (Exception e)
            {
                throw new EXRFormatException("Invalid or corrupt EXR header attribute name: " + e.Message, e);
            }
            if (Name == "")
            {
                return(false);
            }

            try
            {
                Type = reader.ReadNullTerminatedString(maxLen);
            }
            catch (Exception e)
            {
                throw new EXRFormatException("Invalid or corrupt EXR header attribute type for '" + Name + "': " + e.Message, e);
            }
            if (Type == "")
            {
                throw new EXRFormatException("Invalid or corrupt EXR header attribute type for '" + Name + "': Cannot be an empty string.");
            }

            Size = reader.ReadInt32();

            switch (Type)
            {
            case "box2i":
                if (Size != 16)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type box2i: Size must be 16 bytes, was " + Size + ".");
                }
                Value = new Box2I(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32());
                break;

            case "box2f":
                if (Size != 16)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type box2f: Size must be 16 bytes, was " + Size + ".");
                }
                Value = new Box2F(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                break;

            case "chromaticities":
                if (Size != 32)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type chromaticities: Size must be 32 bytes, was " + Size + ".");
                }
                Value = new Chromaticities(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                break;

            case "compression":
                if (Size != 1)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type compression: Size must be 1 byte, was " + Size + ".");
                }
                Value = (EXRCompression)reader.ReadByte();
                break;

            case "double":
                if (Size != 8)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type double: Size must be 8 bytes, was " + Size + ".");
                }
                Value = reader.ReadDouble();
                break;

            case "envmap":
                if (Size != 1)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type envmap: Size must be 1 byte, was " + Size + ".");
                }
                Value = (EnvMap)reader.ReadByte();
                break;

            case "float":
                if (Size != 4)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type float: Size must be 4 bytes, was " + Size + ".");
                }
                Value = reader.ReadSingle();
                break;

            case "int":
                if (Size != 4)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type int: Size must be 4 bytes, was " + Size + ".");
                }
                Value = reader.ReadInt32();
                break;

            case "keycode":
                if (Size != 28)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type keycode: Size must be 28 bytes, was " + Size + ".");
                }
                Value = new KeyCode(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32());
                break;

            case "lineOrder":
                if (Size != 1)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type lineOrder: Size must be 1 byte, was " + Size + ".");
                }
                Value = (LineOrder)reader.ReadByte();
                break;

            case "m33f":
                if (Size != 36)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type m33f: Size must be 36 bytes, was " + Size + ".");
                }
                Value = new M33F(
                    reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                    reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                    reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                break;

            case "m44f":
                if (Size != 64)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type m44f: Size must be 64 bytes, was " + Size + ".");
                }
                Value = new M44F(
                    reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                    reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                    reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                    reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                break;

            case "rational":
                if (Size != 8)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type rational: Size must be 8 bytes, was " + Size + ".");
                }
                Value = new Rational(reader.ReadInt32(), reader.ReadUInt32());
                break;

            case "string":
                if (Size < 0)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type string: Invalid Size, was " + Size + ".");
                }
                Value = reader.ReadString(Size);
                break;

            case "stringvector":
                if (Size == 0)
                {
                    Value = new List <string>();
                }
                else if (Size < 4)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type stringvector: Size must be at least 4 bytes or 0 bytes, was " + Size + ".");
                }
                else
                {
                    var strings = new List <string>();
                    Value = strings;
                    var bytesRead = 0;

                    while (bytesRead < Size)
                    {
                        var loc = reader.Position;
                        var str = reader.ReadString();
                        strings.Add(str);
                        bytesRead += reader.Position - loc;
                    }

                    if (bytesRead != Size)
                    {
                        throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type stringvector: Read " + bytesRead + " bytes but Size was " + Size + ".");
                    }
                }
                break;

            case "tiledesc":
                if (Size != 9)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type tiledesc: Size must be 9 bytes, was " + Size + ".");
                }
                Value = new TileDesc(reader.ReadUInt32(), reader.ReadUInt32(), reader.ReadByte());
                break;

            case "timecode":
                if (Size != 8)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type timecode: Size must be 8 bytes, was " + Size + ".");
                }
                Value = new TimeCode(reader.ReadUInt32(), reader.ReadUInt32());
                break;

            case "v2i":
                if (Size != 8)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type v2i: Size must be 8 bytes, was " + Size + ".");
                }
                Value = new V2I(reader.ReadInt32(), reader.ReadInt32());
                break;

            case "v2f":
                if (Size != 8)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type v2f: Size must be 8 bytes, was " + Size + ".");
                }
                Value = new V2F(reader.ReadSingle(), reader.ReadSingle());
                break;

            case "v3i":
                if (Size != 12)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type v3i: Size must be 12 bytes, was " + Size + ".");
                }
                Value = new V3I(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32());
                break;

            case "v3f":
                if (Size != 12)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type v3f: Size must be 12 bytes, was " + Size + ".");
                }
                Value = new V3F(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                break;

            case "chlist":
                var chlist = new ChannelList();
                try
                {
                    chlist.Read(file, reader, Size);
                }
                catch (Exception e)
                {
                    throw new EXRFormatException("Invalid or corrupt EXR header attribute '" + Name + "' of type chlist: " + e.Message, e);
                }
                Value = chlist;
                break;

            case "preview":
            default:
                Value = reader.ReadBytes(Size);
                break;
            }

            return(true);
        }
Пример #10
0
 public static bool Read(EXRFile file, IEXRReader reader, out EXRAttribute attribute)
 {
     attribute = new EXRAttribute();
     return(attribute.Read(file, reader));
 }
Пример #11
0
        public byte[] GetBytes(ImageSourceFormat srcFormat, ImageDestFormat destFormat, GammaEncoding gamma, int stride)
        {
            CheckHasData();

            int bytesPerPixel = EXRFile.GetBytesPerPixel(destFormat);
            int bitsPerPixel  = EXRFile.GetBitsPerPixel(destFormat);

            if (stride < bytesPerPixel * DataWindow.Width)
            {
                throw new ArgumentException("Stride was lower than minimum", "stride");
            }
            byte[] buffer = new byte[stride * DataWindow.Height];

            var padding = stride - bytesPerPixel * DataWindow.Width;

            bool isHalf           = srcFormat == ImageSourceFormat.HalfRGB || srcFormat == ImageSourceFormat.HalfRGBA;
            bool sourceAlpha      = false;
            bool destinationAlpha =
                destFormat == ImageDestFormat.BGRA16 ||
                destFormat == ImageDestFormat.BGRA32 ||
                destFormat == ImageDestFormat.BGRA8 ||
                destFormat == ImageDestFormat.PremultipliedBGRA16 ||
                destFormat == ImageDestFormat.PremultipliedBGRA32 ||
                destFormat == ImageDestFormat.PremultipliedBGRA8 ||
                destFormat == ImageDestFormat.PremultipliedRGBA16 ||
                destFormat == ImageDestFormat.PremultipliedRGBA32 ||
                destFormat == ImageDestFormat.PremultipliedRGBA8 ||
                destFormat == ImageDestFormat.RGBA16 ||
                destFormat == ImageDestFormat.RGBA32 ||
                destFormat == ImageDestFormat.RGBA8;
            bool premultiplied =
                destFormat == ImageDestFormat.PremultipliedBGRA16 ||
                destFormat == ImageDestFormat.PremultipliedBGRA32 ||
                destFormat == ImageDestFormat.PremultipliedBGRA8 ||
                destFormat == ImageDestFormat.PremultipliedRGBA16 ||
                destFormat == ImageDestFormat.PremultipliedRGBA32 ||
                destFormat == ImageDestFormat.PremultipliedRGBA8;
            bool bgra =
                destFormat == ImageDestFormat.BGR16 ||
                destFormat == ImageDestFormat.BGR32 ||
                destFormat == ImageDestFormat.BGR8 ||
                destFormat == ImageDestFormat.BGRA16 ||
                destFormat == ImageDestFormat.BGRA32 ||
                destFormat == ImageDestFormat.BGRA8 ||
                destFormat == ImageDestFormat.PremultipliedBGRA16 ||
                destFormat == ImageDestFormat.PremultipliedBGRA32 ||
                destFormat == ImageDestFormat.PremultipliedBGRA8;

            Half[]  hr, hg, hb, ha;
            float[] fr, fg, fb, fa;
            hr = hg = hb = ha = null;
            fr = fg = fb = fa = null;

            if (isHalf)
            {
                if (!HalfChannels.ContainsKey("R"))
                {
                    throw new ArgumentException("Half type channel R not found", "srcFormat");
                }
                if (!HalfChannels.ContainsKey("G"))
                {
                    throw new ArgumentException("Half type channel G not found", "srcFormat");
                }
                if (!HalfChannels.ContainsKey("B"))
                {
                    throw new ArgumentException("Half type channel B not found", "srcFormat");
                }
                hr = HalfChannels["R"];
                hg = HalfChannels["G"];
                hb = HalfChannels["B"];

                if (srcFormat == ImageSourceFormat.HalfRGBA)
                {
                    if (!HalfChannels.ContainsKey("A"))
                    {
                        throw new ArgumentException("Half type channel A not found", "srcFormat");
                    }
                    ha          = HalfChannels["A"];
                    sourceAlpha = true;
                }
            }
            else
            {
                if (!FloatChannels.ContainsKey("R"))
                {
                    throw new ArgumentException("Single type channel R not found", "srcFormat");
                }
                if (!FloatChannels.ContainsKey("G"))
                {
                    throw new ArgumentException("Single type channel G not found", "srcFormat");
                }
                if (!FloatChannels.ContainsKey("B"))
                {
                    throw new ArgumentException("Single type channel B not found", "srcFormat");
                }
                fr = FloatChannels["R"];
                fg = FloatChannels["G"];
                fb = FloatChannels["B"];

                if (srcFormat == ImageSourceFormat.HalfRGBA)
                {
                    if (!FloatChannels.ContainsKey("A"))
                    {
                        throw new ArgumentException("Single type channel A not found", "srcFormat");
                    }
                    fa          = FloatChannels["A"];
                    sourceAlpha = true;
                }
            }


            // !PARALLEL

            /*
             * int srcIndex = 0;
             * int destIndex = 0;
             *
             * BinaryWriter writer = new BinaryWriter(new MemoryStream(buffer));
             *
             * for (int y = 0; y < DataWindow.Height; y++, destIndex += padding) {
             *  GetScanlineBytes(bytesPerPixel, destIndex, srcIndex, isHalf, destinationAlpha, sourceAlpha,
             *      hr, hg, hb, ha, fr, fg, fb, fa,
             *      bitsPerPixel, gamma, premultiplied, bgra, buffer, writer);
             *  destIndex += DataWindow.Width * bytesPerPixel;
             *  srcIndex += DataWindow.Width;
             * }
             *
             * writer.Dispose();
             * writer.BaseStream.Dispose();
             */

            var actions = (from y in Enumerable.Range(0, DataWindow.Height)
                           select(Action)(() =>
            {
                var destIndex = stride * y;
                var srcIndex = DataWindow.Width * y;

                using var stream = new MemoryStream(buffer);
                using var writer = new BinaryWriter(stream);

                GetScanlineBytes(bytesPerPixel, destIndex, srcIndex, isHalf, destinationAlpha, sourceAlpha,
                                 hr, hg, hb, ha, fr, fg, fb, fa,
                                 bitsPerPixel, gamma, premultiplied, bgra, buffer, writer);
            })).ToArray();

            Parallel.Invoke(actions);


            return(buffer);
        }
Пример #12
0
 public byte[] GetBytes(ImageSourceFormat srcFormat, ImageDestFormat destFormat, GammaEncoding gamma)
 {
     return(GetBytes(srcFormat, destFormat, gamma, DataWindow.Width * EXRFile.GetBytesPerPixel(destFormat)));
 }