private void ReadPixelBlock(IEXRReader reader, uint offset, int linesPerBlock, List <Channel> sortedChannels) { reader.Position = (int)offset; if (Version.IsMultiPart) { // we don't use this. should we? i dunno. probably not reader.ReadUInt32(); reader.ReadUInt32(); } var startY = reader.ReadInt32(); var endY = Math.Min(DataWindow.Height, startY + linesPerBlock); var startIndex = startY * DataWindow.Width; var dataSize = reader.ReadInt32(); if (Header.Compression != EXRCompression.None) { throw new NotImplementedException("Compressed images are currently not supported"); } foreach (var channel in sortedChannels) { float[] floatArr = null; Half[] halfArr = null; if (channel.Type == PixelType.Float) { floatArr = FloatChannels[channel.Name]; } else if (channel.Type == PixelType.Half) { halfArr = HalfChannels[channel.Name]; } else { throw new NotImplementedException(); } var index = startIndex; for (int y = startY; y < endY; y++) { for (int x = 0; x < DataWindow.Width; x++, index++) { if (channel.Type == PixelType.Float) { floatArr[index] = reader.ReadSingle(); } else if (channel.Type == PixelType.Half) { halfArr[index] = reader.ReadHalf(); } else { throw new NotImplementedException(); } } } } }
public void Read(EXRFile file, IEXRReader reader) { while (EXRAttribute.Read(file, reader, out EXRAttribute attribute)) { Attributes[attribute.Name] = attribute; } }
public void Read(IEXRReader reader, int count) { for (int i = 0; i < count; i++) { Offsets.Add(reader.ReadUInt32()); reader.ReadUInt32(); // skip 4 bytes because we're using uints not ulongs } }
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); } }
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); }
public static int Uncompress(IEXRReader reader, int count, byte[] uncompressed) { var end = reader.Position + count; var maxLen = uncompressed.Length; var offset = 0; while (reader.Position < end) { int runcount = (sbyte)reader.ReadByte(); if (runcount < 0) { // raw runcount = -runcount; if (offset + runcount >= maxLen) { reader.Position -= 1; return(0); } reader.CopyBytes(uncompressed, offset, runcount); offset += runcount; } else { // run length if (offset + runcount + 1 >= maxLen) { reader.Position -= 1; return(0); } var value = reader.ReadByte(); MemSet(uncompressed, offset, value, runcount + 1); offset += runcount + 1; } } return(offset); }
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); }
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 + "."); } }
/// <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); }
public static bool Read(EXRFile file, IEXRReader reader, out EXRAttribute attribute) { attribute = new EXRAttribute(); return(attribute.Read(file, reader)); }
public void Open(IEXRReader reader) { hasData = true; ReadPixelData(reader); }
public void Read(IEXRReader reader) { // first four bytes of an OpenEXR file are always 0x76, 0x2f, 0x31 and 0x01 or 20000630 var magicNumber = reader.ReadInt32(); if (magicNumber != 20000630) { throw new EXRFormatException("Invalid or corrupt EXR layout: First four bytes were not 20000630."); } var versionValue = reader.ReadInt32(); Version = new EXRVersion(versionValue); Headers = new List <EXRHeader>(); if (Version.IsMultiPart) { while (true) { var header = new EXRHeader(); header.Read(this, reader); if (header.IsEmpty) { break; } Headers.Add(header); } throw new NotImplementedException("Multi part EXR files are not currently supported"); } else { if (Version.IsSinglePartTiled) { throw new NotImplementedException("Tiled EXR files are not currently supported"); } var header = new EXRHeader(); header.Read(this, reader); Headers.Add(header); } OffsetTables = new List <OffsetTable>(); foreach (var header in Headers) { int offsetTableSize; if (Version.IsMultiPart) { offsetTableSize = header.ChunkCount; } else if (Version.IsSinglePartTiled) { // TODO: Implement offsetTableSize = 0; } else { var compression = header.Compression; var dataWindow = header.DataWindow; var linesPerBlock = GetScanLinesPerBlock(compression); var blockCount = (int)Math.Ceiling(dataWindow.Height / (double)linesPerBlock); offsetTableSize = blockCount; } var table = new OffsetTable(offsetTableSize); table.Read(reader, offsetTableSize); OffsetTables.Add(table); } }