Example #1
0
        internal EriReader ReadImageData(IBinaryStream stream, EriMetaData meta)
        {
            stream.Position = meta.StreamPos;
            Color[] palette = null;
            using (var input = new EriFile(stream.AsStream))
            {
                for (;;) // ReadSection throws an exception in case of EOF
                {
                    var section = input.ReadSection();
                    if ("Stream  " == section.Id)
                    {
                        continue;
                    }
                    if ("ImageFrm" == section.Id)
                    {
                        break;
                    }
                    if ("Palette " == section.Id && meta.BPP <= 8 && section.Length <= 0x400)
                    {
                        palette = ReadPalette(stream.AsStream, (int)section.Length);
                        continue;
                    }
                    input.BaseStream.Seek(section.Length, SeekOrigin.Current);
                }
            }
            var reader = new EriReader(stream.AsStream, meta, palette);

            reader.DecodeImage();

            if (!string.IsNullOrEmpty(meta.Description))
            {
                var    tags = ParseTagInfo(meta.Description);
                string ref_file;
                if (tags.TryGetValue("reference-file", out ref_file))
                {
                    ref_file = ref_file.TrimEnd(null);
                    if (!string.IsNullOrEmpty(ref_file))
                    {
                        if ((meta.BPP + 7) / 8 < 3)
                        {
                            throw new InvalidFormatException();
                        }

                        ref_file = VFS.CombinePath(VFS.GetDirectoryName(meta.FileName), ref_file);
                        using (var ref_src = VFS.OpenBinaryStream(ref_file))
                        {
                            var ref_info = ReadMetaData(ref_src) as EriMetaData;
                            if (null == ref_info)
                            {
                                throw new FileNotFoundException("Referenced image not found", ref_file);
                            }
                            ref_info.FileName = ref_file;
                            var ref_reader = ReadImageData(ref_src, ref_info);
                            reader.AddImageBuffer(ref_reader);
                        }
                    }
                }
            }
            return(reader);
        }
Example #2
0
        private Stream LoadChunks(EriFile erif)
        {
            uint            current_sample = 0;
            List <MioChunk> chunks         = new List <MioChunk>();

            try
            {
                erif.BaseStream.Position = m_stream_pos;
                for (;;)
                {
                    long chunk_length = erif.FindSection("SoundStm");
                    if (chunk_length > int.MaxValue)
                    {
                        throw new FileSizeException();
                    }
                    var chunk = new MioChunk();
                    chunk.FirstSample = current_sample;
                    chunk.Version     = erif.ReadByte();
                    chunk.Flags       = erif.ReadByte();
                    erif.ReadInt16();
                    chunk.SampleCount = erif.ReadUInt32();
                    chunk.Position    = erif.BaseStream.Position;
                    chunk.Size        = (uint)(chunk_length - 8);
                    current_sample   += chunk.SampleCount;
                    chunks.Add(chunk);
                    erif.BaseStream.Seek(chunk.Size, SeekOrigin.Current);
                }
            }
            catch (EndOfStreamException) { /* ignore EOF errors */ }
            m_total_samples = current_sample;
            if (0 == m_total_samples)
            {
                m_decode_finished = true;
                return(Stream.Null);
            }
            uint sample_bytes = (uint)ChannelCount * BitsPerSample / 8;
            var  total_bytes  = m_total_samples * sample_bytes;

            m_wait_handles = new WaitHandle[2] {
                m_available_chunk, m_decode_complete
            };
            m_chunk_queue = new ConcurrentQueue <byte[]>();
            m_worker      = new BackgroundWorker();
            m_worker.WorkerSupportsCancellation = true;
            m_worker.DoWork += DoWork_Decode;
            m_worker.RunWorkerAsync(chunks);
            return(new MemoryStream((int)total_bytes));
        }
Example #3
0
        void ReadHeader(EriFile erif)
        {
            var section = erif.ReadSection();

            if (section.Id != "Header  " || section.Length <= 0 || section.Length > int.MaxValue)
            {
                return(null);
            }
            m_stream_pos = erif.BaseStream.Position + section.Length;
            section      = erif.ReadSection();
            if (section.Id != "FileHdr" || section.Length < 8)
            {
                return(null);
            }
            var file_hdr = new byte[section.Length];

            erif.Read(file_hdr, 0, file_hdr.Length);
            if (0 == (file_hdr[5] & 1))
            {
                return(null);
            }
            section = erif.ReadSection();
            if (section.Id != "SoundInf" || section.Length < 0x24)
            {
                return(null);
            }

            var info = new EmsacSoundInfo();

            info.Version        = erif.ReadInt32();
            info.Transformation = (CvType)erif.ReadInt32();
            info.Architecture   = (EriCode)erif.ReadInt32();
            info.ChannelCount   = erif.ReadInt32();
            info.SamplesPerSec  = erif.ReadUInt32();
            info.BlocksetCount  = erif.ReadUInt32();
            info.SubbandDegree  = erif.ReadInt32();
            info.AllSampleCount = erif.ReadInt32();
            info.LappedDegree   = erif.ReadInt32();
            SetSoundInfo(info);
            SetWaveFormat(info);

            erif.BaseStream.Position = m_stream_pos;
            var stream_size = erif.FindSection("Stream  ");

            m_stream_pos = erif.BaseStream.Position;
        }
Example #4
0
        public Stream Decode()
        {
            m_input.Position = 0x40;
            using (var erif = new EriFile(m_input))
            {
                ReadHeader(erif);
                int total_bytes = m_info.AllSampleCount * BitsPerSample / 8;
                var output      = new MemoryStream(total_bytes);
                try
                {
                    var buffer  = new byte[0x10000];
                    var decoded = new byte[0x10000];
                    erif.BaseStream.Position = m_stream_pos;
                    while (total_bytes > 0)
                    {
                        var section = erif.ReadSection();
                        if (section.Id != "SoundStm")
                        {
                            break;
                        }
                        int stm_length = (int)section.Length;
                        if (stm_length > buffer.Length)
                        {
                            buffer = new byte[stm_length];
                        }
                        erif.Read(m_buffer, 0, stm_length);
                        int length = m_buffer.ToInt32(4) * m_lappedSubband;
                        if (length > decoded.Length)
                        {
                            decoded = new byte[length];
                        }

                        DecodeBlock(buffer, decoded);
                        length = Math.Min(length, total_bytes);
                        output.Write(decoded, 0, length);
                        total_bytes -= length;
                    }
                }
                catch (EndOfStreamException) { /* ignore EOF errors */ }
                output.Position = 0;
                return(output);
            }
        }
Example #5
0
        }                                                                  // 'Enti'

        public override ImageMetaData ReadMetaData(IBinaryStream stream)
        {
            var header = stream.ReadHeader(0x40);

            if (0x03000100 != header.ToUInt32(8))
            {
                return(null);
            }
            if (!header.AsciiEqual(0x10, "Entis Rasterized Image") &&
                !header.AsciiEqual(0x10, "Moving Entis Image"))
            {
                return(null);
            }
            using (var reader = new EriFile(stream.AsStream))
            {
                var section = reader.ReadSection();
                if (section.Id != "Header  " || section.Length <= 0)
                {
                    return(null);
                }
                int           header_size = (int)section.Length;
                int           stream_pos  = 0x50 + header_size;
                EriFileHeader file_header = null;
                EriMetaData   info        = null;
                string        desc        = null;
                while (header_size > 0x10)
                {
                    section      = reader.ReadSection();
                    header_size -= 0x10;
                    if (section.Length <= 0 || section.Length > header_size)
                    {
                        break;
                    }
                    if ("FileHdr " == section.Id)
                    {
                        file_header = new EriFileHeader {
                            Version = reader.ReadInt32()
                        };
                        if (file_header.Version > 0x00020100)
                        {
                            throw new InvalidFormatException("Invalid ERI file version");
                        }
                        file_header.ContainedFlag = reader.ReadInt32();
                        file_header.KeyFrameCount = reader.ReadInt32();
                        file_header.FrameCount    = reader.ReadInt32();
                        file_header.AllFrameTime  = reader.ReadInt32();
                    }
                    else if ("ImageInf" == section.Id)
                    {
                        int version = reader.ReadInt32();
                        if (version != 0x00020100 && version != 0x00020200)
                        {
                            return(null);
                        }
                        info = new EriMetaData {
                            StreamPos = stream_pos, Version = version
                        };
                        info.Transformation = (CvType)reader.ReadInt32();
                        info.Architecture   = (EriCode)reader.ReadInt32();
                        info.FormatType     = (EriType)reader.ReadInt32();
                        int w = reader.ReadInt32();
                        int h = reader.ReadInt32();
                        info.Width           = (uint)Math.Abs(w);
                        info.Height          = (uint)Math.Abs(h);
                        info.VerticalFlip    = h < 0;
                        info.BPP             = reader.ReadInt32();
                        info.ClippedPixel    = reader.ReadInt32();
                        info.SamplingFlags   = (EriSampling)reader.ReadInt32();
                        info.QuantumizedBits = reader.ReadUInt64();
                        info.AllottedBits    = reader.ReadUInt64();
                        info.BlockingDegree  = reader.ReadInt32();
                        info.LappedBlock     = reader.ReadInt32();
                        info.FrameTransform  = reader.ReadInt32();
                        info.FrameDegree     = reader.ReadInt32();
                    }
                    else if ("descript" == section.Id)
                    {
                        if (0xFEFF == reader.PeekChar())
                        {
                            reader.Read();
                            var desc_chars = reader.ReadChars((int)section.Length / 2 - 1);
                            desc = new string (desc_chars);
                        }
                        else
                        {
                            var desc_chars = reader.ReadBytes((int)section.Length);
                            desc = Encoding.UTF8.GetString(desc_chars);
                        }
                    }
                    else
                    {
                        reader.BaseStream.Seek(section.Length, SeekOrigin.Current);
                    }
                    header_size -= (int)section.Length;
                }
                if (info != null)
                {
                    if (file_header != null)
                    {
                        info.Header = file_header;
                    }
                    if (desc != null)
                    {
                        info.Description = desc;
                    }
                }
                return(info);
            }
        }
Example #6
0
        public MioInput(Stream file) : base(file)
        {
            file.Position = 0x40;
            using (var erif = new EriFile(file))
            {
                var section = erif.ReadSection();
                if (section.Id != "Header  " || section.Length <= 0 || section.Length > int.MaxValue)
                {
                    throw new InvalidFormatException();
                }
                m_stream_pos = 0x50 + section.Length;
                int header_size = (int)section.Length;
                while (header_size > 0x10)
                {
                    section      = erif.ReadSection();
                    header_size -= 0x10;
                    if (section.Length <= 0 || section.Length > header_size)
                    {
                        break;
                    }
                    if ("SoundInf" == section.Id)
                    {
                        m_info                = new MioInfoHeader();
                        m_info.Version        = erif.ReadInt32();
                        m_info.Transformation = (CvType)erif.ReadInt32();
                        m_info.Architecture   = (EriCode)erif.ReadInt32();
                        m_info.ChannelCount   = erif.ReadInt32();
                        m_info.SamplesPerSec  = erif.ReadUInt32();
                        m_info.BlocksetCount  = erif.ReadUInt32();
                        m_info.SubbandDegree  = erif.ReadInt32();
                        m_info.AllSampleCount = erif.ReadUInt32();
                        m_info.LappedDegree   = erif.ReadUInt32();
                        m_info.BitsPerSample  = erif.ReadUInt32();
                        break;
                    }
                    header_size -= (int)section.Length;
                    erif.BaseStream.Seek(section.Length, SeekOrigin.Current);
                }
                if (null == m_info)
                {
                    throw new InvalidFormatException("MIO sound header not found");
                }

                erif.BaseStream.Position = m_stream_pos;
                var stream_size = erif.FindSection("Stream  ");
                m_stream_pos = erif.BaseStream.Position;

                m_pmiod = new MioDecoder(m_info);
                if (EriCode.Nemesis != m_info.Architecture)
                {
                    m_pmioc = new HuffmanDecodeContext(0x10000);
                }
                else
                {
                    throw new NotImplementedException("MIO Nemesis encoding not implemented");
                }

                int pcm_bitrate = (int)(m_info.SamplesPerSec * BitsPerSample * ChannelCount);
                var format      = new GameRes.WaveFormat();
                format.FormatTag             = 1;
                format.Channels              = (ushort)ChannelCount;
                format.SamplesPerSecond      = m_info.SamplesPerSec;
                format.BitsPerSample         = (ushort)BitsPerSample;
                format.BlockAlign            = (ushort)(BitsPerSample / 8 * format.Channels);
                format.AverageBytesPerSecond = (uint)pcm_bitrate / 8;
                this.Format      = format;
                m_decoded_stream = LoadChunks(erif);

                if (0 != m_total_samples)
                {
                    m_bitrate = (int)(stream_size * 8 * m_info.SamplesPerSec / m_total_samples);
                }
                this.PcmSize = m_total_samples * ChannelCount * BitsPerSample / 8;
                m_decoded_stream.Position = 0;
            }
        }
Example #7
0
        internal EriReader ReadImageData(Stream stream, EriMetaData meta)
        {
            stream.Position = meta.StreamPos;
            Color[] palette = null;
            using (var input = new EriFile (stream))
            {
                for (;;) // ReadSection throws an exception in case of EOF
                {
                    var section = input.ReadSection();
                    if ("Stream  " == section.Id)
                        continue;
                    if ("ImageFrm" == section.Id)
                        break;
                    if ("Palette " == section.Id && meta.BPP <= 8 && section.Length <= 0x400)
                    {
                        palette = ReadPalette (stream, (int)section.Length);
                        continue;
                    }
                    input.BaseStream.Seek (section.Length, SeekOrigin.Current);
                }
            }
            var reader = new EriReader (stream, meta, palette);
            reader.DecodeImage();

            if (!string.IsNullOrEmpty (meta.Description))
            {
                var tags = ParseTagInfo (meta.Description);
                string ref_file;
                if (tags.TryGetValue ("reference-file", out ref_file))
                {
                    ref_file = ref_file.TrimEnd (null);
                    if (!string.IsNullOrEmpty (ref_file))
                    {
                        if ((meta.BPP + 7) / 8 < 3)
                            throw new InvalidFormatException();

                        ref_file = VFS.CombinePath (VFS.GetDirectoryName (meta.FileName), ref_file);
                        using (var ref_src = VFS.OpenSeekableStream (ref_file))
                        {
                            var ref_info = ReadMetaData (ref_src) as EriMetaData;
                            if (null == ref_info)
                                throw new FileNotFoundException ("Referenced image not found");
                            ref_info.FileName = ref_file;
                            var ref_reader = ReadImageData (ref_src, ref_info);
                            AddImageBuffer (meta, reader.Data, ref_info, ref_reader.Data);
                        }
                    }
                }
            }
            return reader;
        }
Example #8
0
 public override ImageMetaData ReadMetaData(Stream stream)
 {
     byte[] header = new byte[0x40];
     if (header.Length != stream.Read (header, 0, header.Length))
         return null;
     if (0x03000100 != LittleEndian.ToUInt32 (header, 8))
         return null;
     if (!Binary.AsciiEqual (header, 0x10, "Entis Rasterized Image")
         && !Binary.AsciiEqual (header, 0x10, "Moving Entis Image"))
         return null;
     using (var reader = new EriFile (stream))
     {
         var section = reader.ReadSection();
         if (section.Id != "Header  " || section.Length <= 0)
             return null;
         int header_size = (int)section.Length;
         int stream_pos = 0x50 + header_size;
         EriFileHeader file_header = null;
         EriMetaData info = null;
         string desc = null;
         while (header_size > 0x10)
         {
             section = reader.ReadSection();
             header_size -= 0x10;
             if (section.Length <= 0 || section.Length > header_size)
                 break;
             if ("FileHdr " == section.Id)
             {
                 file_header = new EriFileHeader { Version = reader.ReadInt32() };
                 if (file_header.Version > 0x00020100)
                     throw new InvalidFormatException ("Invalid ERI file version");
                 file_header.ContainedFlag    = reader.ReadInt32();
                 file_header.KeyFrameCount    = reader.ReadInt32();
                 file_header.FrameCount       = reader.ReadInt32();
                 file_header.AllFrameTime     = reader.ReadInt32();
             }
             else if ("ImageInf" == section.Id)
             {
                 int version = reader.ReadInt32();
                 if (version != 0x00020100 && version != 0x00020200)
                     return null;
                 info = new EriMetaData { StreamPos = stream_pos, Version = version };
                 info.Transformation = (CvType)reader.ReadInt32();
                 info.Architecture = (EriCode)reader.ReadInt32();
                 info.FormatType = (EriType)reader.ReadInt32();
                 int w = reader.ReadInt32();
                 int h = reader.ReadInt32();
                 info.Width  = (uint)Math.Abs (w);
                 info.Height = (uint)Math.Abs (h);
                 info.VerticalFlip = h < 0;
                 info.BPP = reader.ReadInt32();
                 info.ClippedPixel = reader.ReadInt32();
                 info.SamplingFlags = (EriSampling)reader.ReadInt32();
                 info.QuantumizedBits = reader.ReadUInt64();
                 info.AllottedBits = reader.ReadUInt64();
                 info.BlockingDegree = reader.ReadInt32();
                 info.LappedBlock = reader.ReadInt32();
                 info.FrameTransform = reader.ReadInt32();
                 info.FrameDegree = reader.ReadInt32();
             }
             else if ("descript" == section.Id)
             {
                 if (0xFEFF == reader.PeekChar())
                 {
                     reader.Read();
                     var desc_chars = reader.ReadChars ((int)section.Length/2 - 1);
                     desc = new string (desc_chars);
                 }
                 else
                 {
                     var desc_chars = reader.ReadBytes ((int)section.Length);
                     desc = Encoding.UTF8.GetString (desc_chars);
                 }
             }
             else
             {
                 reader.BaseStream.Seek (section.Length, SeekOrigin.Current);
             }
             header_size -= (int)section.Length;
         }
         if (info != null)
         {
             if (file_header != null)
                 info.Header = file_header;
             if (desc != null)
                 info.Description = desc;
         }
         return info;
     }
 }