示例#1
0
        public override SoundInput TryOpen(IBinaryStream file)
        {
            var header       = file.ReadHeader(0x23);
            int bits1_length = header.ToInt32(0x13);
            int bits2_length = header.ToInt32(0x17);
            var data         = file.ReadBytes(bits1_length + bits2_length);

            CgfDecoder.Decrypt(data, bits1_length);

            int  unpacked_length = header.ToInt32(5);
            uint sample_rate     = header.ToUInt32(0xD);
            int  sample_count    = unpacked_length >> 1;
            var  bits1           = new byte[(sample_count + 7) >> 3];
            var  bits2           = new byte[sample_count >> 1];

            using (var mem = new MemoryStream(data, 4, bits1_length - 4))
                using (var input = new ZLibStream(mem, CompressionMode.Decompress))
                    input.Read(bits1, 0, bits1.Length);

            using (var mem = new MemoryStream(data, bits1_length + 4, bits2_length - 4))
                using (var input = new ZLibStream(mem, CompressionMode.Decompress))
                    input.Read(bits2, 0, bits2.Length);

            short init    = header.ToInt16(0x11);
            var   decoded = new short[sample_count];

            DecodeAdp(bits2, decoded, sample_count, init);

            var  output = new byte[unpacked_length];
            byte bit    = 0x80;
            int  src    = 0;
            int  dst    = 0;

            for (int i = 0; i < decoded.Length; ++i)
            {
                short sample = Math.Max(decoded[i], (short)0);
                if ((bit & bits1[src]) != 0)
                {
                    sample = (short)-sample;
                }
                LittleEndian.Pack(sample, output, dst);
                dst  += 2;
                bit >>= 1;
                if (0 == bit)
                {
                    ++src;
                    bit = 0x80;
                }
            }
            var format = new WaveFormat {
                FormatTag        = 1,
                Channels         = 1,
                SamplesPerSecond = sample_rate,
                BlockAlign       = 2,
                BitsPerSample    = 16,
            };

            format.SetBPS();
            var pcm = new MemoryStream(output);

            return(new RawPcmInput(pcm, format));
        }
示例#2
0
 public byte[] ReadBytes(int count)
 {
     return(m_input.ReadBytes(count));
 }
示例#3
0
文件: ArcPSB.cs 项目: ziyuejun/GARbro
        bool ReadHeader(bool encrypted)
        {
            m_input.Position = 4;

            m_version = m_input.ReadUInt16();
            m_flags   = m_input.ReadUInt16();
            if (encrypted && m_version < 3)
            {
                m_flags = 2;
            }

            int header_size = m_version > 3 ? 0x30 : 0x20;
            var header      = m_input.ReadBytes(header_size);

            if (encrypted && 0 != (m_flags & 1))
            {
                if (m_version > 3)
                {
                    Decrypt(header, 0, 0x24);
                    Decrypt(header, 0x24, 0xC);
                }
                else
                {
                    Decrypt(header, 0, 0x20);
                }
            }

            m_names         = LittleEndian.ToInt32(header, 0x04);  // 0x08
            m_strings       = LittleEndian.ToInt32(header, 0x08);  // 0x0C
            m_strings_data  = LittleEndian.ToInt32(header, 0x0C);  // 0x10
            m_chunk_offsets = LittleEndian.ToInt32(header, 0x10);  // 0x14
            m_chunk_lengths = LittleEndian.ToInt32(header, 0x14);  // 0x18
            m_chunk_data    = LittleEndian.ToInt32(header, 0x18);  // 0x1C
            m_root          = LittleEndian.ToInt32(header, 0x1C);  // 0x20

            if (m_version > 3)
            {
                m_extra_offsets = LittleEndian.ToInt32(header, 0x24);
                m_extra_lengths = LittleEndian.ToInt32(header, 0x28);
                m_extra_data    = LittleEndian.ToInt32(header, 0x2C);
            }

            int buffer_length = (int)m_input.Length;

            if (!(m_names >= 0x28 && m_names < m_chunk_data &&
                  m_strings >= 0x28 && m_strings < m_chunk_data &&
                  m_strings_data >= 0x28 && m_strings_data < m_chunk_data &&
                  m_chunk_offsets >= 0x28 && m_chunk_offsets < m_chunk_data &&
                  m_chunk_lengths >= 0x28 && m_chunk_lengths < m_chunk_data &&
                  m_chunk_data >= 0x28 && m_chunk_data <= buffer_length &&
                  m_root >= 0x28 && m_root < m_chunk_data))
            {
                return(false);
            }

            if (null == m_data || m_data.Length < m_chunk_data)
            {
                m_data = new byte[m_chunk_data];
            }
            int data_pos = (int)m_input.Position;

            m_input.Read(m_data, data_pos, m_chunk_data - data_pos);
            if (encrypted && 0 != (m_flags & 2))
            {
                Decrypt(m_data, m_names, m_chunk_offsets - m_names);
            }
            // root object is a dictionary
            return(0x21 == m_data[m_root]);
        }
示例#4
0
        List <Sample> ReadSamples()
        {
            var header       = m_input.ReadHeader(0x3C);
            int version      = header.ToInt32(4);
            int sample_count = header.ToInt32(8);

            m_sample_header_size = header.ToInt32(0xC);
            m_name_table_size    = header.ToInt32(0x10);
            m_data_size          = header.ToInt32(0x14);
            m_format             = (SoundFormat)header.ToInt32(0x18);
            if (!Supported.Contains(m_format))
            {
                throw new NotSupportedException();
            }

            if (0 == version)
            {
                m_input.ReadInt32();
            }
            var samples = new List <Sample> (sample_count);

            m_header_size = (int)m_input.Position;
            for (int i = 0; i < sample_count; ++i)
            {
                long   raw         = m_input.ReadInt64();
                bool   next_chunk  = 0 != (raw & 1);
                int    sample_rate = (int)((raw >> 1) & 0xF);
                ushort channels    = (ushort)(((raw >> 5) & 1) + 1);
                long   data_offset = ((raw >> 6) & 0xFFFFFFF) * 0x10;
                int    count       = (int)((raw >> 34) & 0x3FFFFFFF);
                var    chunks      = new Dictionary <ChunkType, object>();
                while (next_chunk)
                {
                    int d = m_input.ReadInt32();
                    next_chunk = 0 != (d & 1);
                    int    chunk_size = (d >> 1) & 0xFFFFFF;
                    var    chunk_type = (ChunkType)((d >> 25) & 0x7F);
                    object chunk;
                    switch (chunk_type)
                    {
                    case ChunkType.Channels:
                        chunk = m_input.ReadUInt8();
                        break;

                    case ChunkType.SampleRate:
                        chunk = m_input.ReadInt32();
                        break;

                    case ChunkType.Loop:
                        int v1 = m_input.ReadInt32();
                        int v2 = m_input.ReadInt32();
                        chunk = Tuple.Create(v1, v2);
                        break;

                    case ChunkType.VorbisData:
                        chunk = new VorbisData {
                            Crc32 = m_input.ReadUInt32(),
                            Data  = m_input.ReadBytes(chunk_size - 4) // XXX unused
                        };
                        break;

                    default:
                        chunk = m_input.ReadBytes(chunk_size);
                        break;
                    }
                    chunks[chunk_type] = chunk;
                }
                if (chunks.ContainsKey(ChunkType.SampleRate))
                {
                    sample_rate = (int)chunks[ChunkType.SampleRate];
                }
                else if (SampleRates.ContainsKey(sample_rate))
                {
                    sample_rate = SampleRates[sample_rate];
                }
                else
                {
                    throw new InvalidFormatException("Invalid FSB5 sample rate.");
                }

                var sample = new Sample {
                    SampleRate  = sample_rate,
                    Channels    = channels,
                    DataOffset  = data_offset,
                    SampleCount = count,
                    MetaData    = chunks,
                    Data        = null
                };
                samples.Add(sample);
            }
            return(samples);
        }
示例#5
0
文件: ArcABMP.cs 项目: zxc120/GARbro
        public List <Entry> ReadIndex()
        {
            m_input.Position = 0x10;
            int n        = 0;
            var type_buf = new byte[0x10];

            while (0x10 == m_input.Read(type_buf, 0, 0x10))
            {
                if (Binary.AsciiEqual(type_buf, "abdata"))
                {
                    uint size  = m_input.ReadUInt32();
                    var  entry = new Entry {
                        Name   = string.Format("{0}#{1}.dat", m_base_name, n++),
                        Offset = m_input.Position,
                        Size   = size,
                    };
                    m_dir.Add(entry);
                    Skip(size);
                }
                else if (Binary.AsciiEqual(type_buf, "abimage10\0") ||
                         Binary.AsciiEqual(type_buf, "absound10\0"))
                {
                    int count = m_input.ReadByte();
                    for (int i = 0; i < count; ++i)
                    {
                        if (0x10 != m_input.Read(type_buf, 0, 0x10))
                        {
                            break;
                        }
                        var    tag  = Binary.GetCString(type_buf, 0, 0x10, Encoding.ASCII);
                        string name = null;
                        if ("abimgdat15" == tag)
                        {
                            Skip(4);
                            int name_length = m_input.ReadUInt16();
                            if (name_length > 0)
                            {
                                var name_bytes = m_input.ReadBytes(name_length * 2);
                                name = Encoding.Unicode.GetString(name_bytes);
                            }
                            name_length = m_input.ReadUInt16();
                            if (name_length > 0)
                            {
                                if (string.IsNullOrEmpty(name))
                                {
                                    name = m_input.ReadCString(name_length);
                                }
                                else
                                {
                                    Skip((uint)name_length);
                                }
                            }
                            byte type = m_input.ReadUInt8();

                            /*
                             * case 0:   ".bmp"
                             * case 1:   ".jpg"
                             * case 2:
                             * case 3:   ".png"
                             * case 4:   ".m"
                             * case 5:   ".argb"
                             * case 6:   ".b"
                             * case 7:   ".ogv"
                             * case 8:   ".mdl"
                             */
                            Skip(0x11);
                        }
                        else
                        {
                            int name_length = m_input.ReadUInt16();
                            name = m_input.ReadCString(name_length);

                            if (tag != "abimgdat10" && tag != "absnddat10")
                            {
                                Skip(m_input.ReadUInt16());
                                if ("abimgdat13" == tag)
                                {
                                    Skip(0x0C);
                                }
                                else if ("abimgdat14" == tag)
                                {
                                    Skip(0x4C);
                                }
                            }
                            m_input.ReadByte();
                        }
                        var size = m_input.ReadUInt32();
                        if (0 != size)
                        {
                            if (string.IsNullOrEmpty(name))
                            {
                                name = string.Format("{0}#{1}", m_base_name, n++);
                            }
                            else
                            {
                                name = s_InvalidChars.Replace(name, "_");
                            }
                            var entry = new Entry {
                                Name   = name,
                                Type   = tag.StartsWith("abimg") ? "image" : tag.StartsWith("absnd") ? "audio" : "",
                                Offset = m_input.Position,
                                Size   = size,
                            };
                            if (entry.CheckPlacement(m_file.MaxOffset))
                            {
                                DetectFileType(m_file, entry);
                                m_dir.Add(entry);
                            }
                        }
                        Skip(size);
                    }
                }
                else
                {
                    var entry = new Entry {
                        Name   = string.Format("{0}#{1}#{2}", m_base_name, n++, GetTypeName(type_buf)),
                        Offset = m_input.Position,
                        Size   = (uint)(m_file.MaxOffset - m_input.Position),
                    };
                    m_dir.Add(entry);
                    Skip(entry.Size);
                }
            }
            return(m_dir);
        }
示例#6
0
        protected byte[] ReadKey()
        {
            int key_length = m_input.ReadInt32();

            return(m_input.ReadBytes(key_length));
        }
示例#7
0
        void UnpackRefFrame(IBinaryStream input, byte[] output)
        {
            int header_size = input.ReadInt32();

            if (header_size < 4)
            {
                throw new InvalidFormatException();
            }
            var header = input.ReadBytes(header_size - 4);

            using (var chunks = new BinMemoryStream(header))
            {
                int count = 0;
                int last  = -1;
                int dst   = 0;
                while (dst < output.Length)
                {
                    int length = ReadInteger(chunks);
                    if (-1 == length)
                    {
                        break;
                    }
                    while (length-- > 0)
                    {
                        if (0 == count)
                        {
                            input.Read(output, dst, 3);
                            int color = output[dst] | output[dst + 1] << 8 | output[dst + 2] << 16;
                            dst += 3;
                            if (color == last)
                            {
                                count = ReadInteger(input);
                                if (-1 == count)
                                {
                                    return;
                                }
                                if (count > 2)
                                {
                                    count -= 2;
                                }
                                else
                                {
                                    count = 0;
                                }
                            }
                            last = color;
                        }
                        else
                        {
                            count--;
                            output[dst++] = (byte)last;
                            output[dst++] = (byte)(last >> 8);
                            output[dst++] = (byte)(last >> 16);
                        }
                    }
                    length = ReadInteger(chunks);
                    if (-1 == length)
                    {
                        break;
                    }
                    length = Math.Min(length * 3, output.Length - dst);
                    dst   += length;
                }
            }
        }
示例#8
0
文件: AudioWWA.cs 项目: uboaa/GARbro
        }                                                                 // 'WPX'

        public override SoundInput TryOpen(IBinaryStream file)
        {
            var header = file.ReadHeader(0x10);

            if (!header.AsciiEqual(4, "WAV"))
            {
                return(null);
            }
            int count    = header[0xE];
            int dir_size = header[0xF];

            if (1 != header[0xC] || 0 == count || 0 == dir_size)
            {
                return(null);
            }

            file.Position = 0x10;
            var index = file.ReadBytes(count * dir_size);

            var section = WpxSection.Find(index, 0x20, count, dir_size);

            if (null == section || section.UnpackedSize < 0x10 || section.DataFormat != 0x80)
            {
                throw new InvalidFormatException();
            }
            file.Position = section.Offset;
            var fmt = file.ReadBytes(section.UnpackedSize);

            section = WpxSection.Find(index, 0x21, count, dir_size);
            if (null == section)
            {
                throw new InvalidFormatException();
            }

            var reader = new WwaReader(file.AsStream, section);
            var data   = reader.Unpack(section.DataFormat);

            if (null == data)
            {
                throw new InvalidFormatException();
            }

            int total_size = 20 + fmt.Length + data.Length;

            using (var wav_file = new MemoryStream(20 + fmt.Length))
                using (var wav = new BinaryWriter(wav_file))
                {
                    wav.Write(Wav.Signature);
                    wav.Write(total_size);
                    wav.Write(0x45564157); // 'WAVE'
                    wav.Write(0x20746d66); // 'fmt '
                    wav.Write(fmt.Length);
                    wav.Write(fmt);
                    wav.Write(0x61746164); // 'data'
                    wav.Write(data.Length);
                    var wav_header  = wav_file.ToArray();
                    var data_stream = new MemoryStream(data);
                    var source      = new PrefixStream(wav_header, data_stream);
                    var sound       = new WaveInput(source);
                    file.Dispose();
                    return(sound);
                }
        }
示例#9
0
        public override ImageData Read(IBinaryStream file, ImageMetaData info)
        {
            var meta   = (BjrMetaData)info;
            int height = (int)meta.Height;
            int stride = ((int)meta.Width * (meta.BPP / 8) + 3) & ~3;

            file.Position = meta.ImageOffset;
            var source = file.ReadBytes(stride * height);

            var name_bytes = Encodings.cp932.GetBytes(Path.GetFileName(meta.FileName));
            int line_key   = 0;
            int even_key   = 0xFF;
            int odd_key    = 0;

            for (int i = 0; i < name_bytes.Length; ++i)
            {
                line_key ^= name_bytes[i];
                even_key += name_bytes[i];
                odd_key  -= name_bytes[i];
            }

            var pixels = new byte[source.Length];
            int dst    = 0;

            for (int y = 0; y < height; ++y)
            {
                line_key += 7;
                int src = (line_key % height) * stride;
                for (int x = 0; x < stride; ++x)
                {
                    if ((x & 1) == 0)
                    {
                        pixels[dst + x] = (byte)(even_key - source[src + x]);
                    }
                    else
                    {
                        pixels[dst + x] = (byte)(odd_key + source[src + x]);
                    }
                }
                dst += stride;
            }
            PixelFormat format;

            if (24 == meta.BPP)
            {
                format = PixelFormats.Bgr24;
            }
            else if (32 == meta.BPP)
            {
                format = PixelFormats.Bgr32;
            }
            else // FIXME read palette
            {
                format = PixelFormats.Gray8;
            }
            if (meta.IsFlipped)
            {
                return(ImageData.CreateFlipped(info, format, null, pixels, stride));
            }
            else
            {
                return(ImageData.Create(info, format, null, pixels, stride));
            }
        }
示例#10
0
 /// <summary>
 /// Read <paramref name="length"/> bytes from stream and return them in a byte array.
 /// May return less than <paramref name="length"/> bytes if end of file was encountered.
 /// </summary>
 public byte[] ReadBytes(int length)
 {
     return(m_input.ReadBytes(length));
 }
示例#11
0
文件: ArcTCD3.cs 项目: cybort/GARbro
        public List <Entry> ReadIndex()
        {
            if (!ArchiveFormat.IsSaneCount(Count))
            {
                return(null);
            }

            var sections = ReadSections(m_section_count);
            var list     = new List <Entry> (Count);

            foreach (var section in sections)
            {
                m_input.Position = section.IndexOffset;
                var dir_names = m_input.ReadBytes(section.DirNamesSize);
                if (section.DirNamesSize != dir_names.Length)
                {
                    return(null);
                }
                byte section_key = dir_names[section.DirNameLength - 1];
                DecryptNames(dir_names, section_key);

                var dirs = new TcdDirEntry[section.DirCount];
                for (int i = 0; i < dirs.Length; ++i)
                {
                    dirs[i].FileCount   = m_input.ReadInt32();
                    dirs[i].NamesOffset = m_input.ReadInt32();
                    dirs[i].FirstIndex  = m_input.ReadInt32();
                    m_input.ReadInt32();
                }
                var file_names = m_input.ReadBytes(section.FileNamesSize);
                if (file_names.Length != section.FileNamesSize)
                {
                    return(null);
                }
                DecryptNames(file_names, section_key);

                var offsets = new uint[section.FileCount + 1];
                for (int i = 0; i < offsets.Length; ++i)
                {
                    offsets[i] = m_input.ReadUInt32();
                }

                int dir_name_offset = 0;
                foreach (var dir in dirs)
                {
                    string dir_name    = GetName(dir_names, section.DirNameLength, ref dir_name_offset);
                    int    index       = dir.FirstIndex;
                    int    name_offset = dir.NamesOffset;
                    for (int i = 0; i < dir.FileCount; ++i)
                    {
                        string name = GetName(file_names, section.FileNameLength, ref name_offset);
                        name = Path.Combine(dir_name, name);
                        name = Path.ChangeExtension(name, section.Extension);
                        var entry = FormatCatalog.Instance.Create <TcdEntry> (name);
                        entry.Offset = offsets[index];
                        entry.Size   = offsets[index + 1] - offsets[index];
                        entry.Index  = index;
                        ++index;
                        list.Add(entry);
                    }
                }
            }
            return(list);
        }
示例#12
0
        public override ImageMetaData ReadMetaData(IBinaryStream file)
        {
            file.ReadUInt32();
            if (file.ReadUInt32() != 0x0a1a0a0d)
            {
                return(null);
            }
            uint chunk_size = Binary.BigEndian(file.ReadUInt32());

            byte[] chunk_type = file.ReadBytes(4);
            if (!Binary.AsciiEqual(chunk_type, "IHDR"))
            {
                return(null);
            }

            var meta = new ImageMetaData();

            meta.Width  = Binary.BigEndian(file.ReadUInt32());
            meta.Height = Binary.BigEndian(file.ReadUInt32());
            int bpp = file.ReadByte();

            if (bpp != 1 && bpp != 2 && bpp != 4 && bpp != 8 && bpp != 16)
            {
                return(null);
            }
            int color_type = file.ReadByte();

            switch (color_type)
            {
            case 2: meta.BPP = bpp * 3; break;

            case 3: meta.BPP = 24; break;

            case 4: meta.BPP = bpp * 2; break;

            case 6: meta.BPP = bpp * 4; break;

            case 0: meta.BPP = bpp; break;

            default: return(null);
            }
            SkipBytes(file, 7);

            for (;;)
            {
                chunk_size = Binary.BigEndian(file.ReadUInt32());
                file.Read(chunk_type, 0, 4);
                if (Binary.AsciiEqual(chunk_type, "IDAT") || Binary.AsciiEqual(chunk_type, "IEND"))
                {
                    break;
                }
                if (Binary.AsciiEqual(chunk_type, "oFFs"))
                {
                    int x = Binary.BigEndian(file.ReadInt32());
                    int y = Binary.BigEndian(file.ReadInt32());
                    if (0 == file.ReadByte())
                    {
                        meta.OffsetX = x;
                        meta.OffsetY = y;
                    }
                    break;
                }
                SkipBytes(file, chunk_size + 4);
            }
            return(meta);
        }
示例#13
0
文件: ImageGBP.cs 项目: zxc120/GARbro
        void UnpackFlat()
        {
            var channel = new byte[m_width * m_height];

            for (int i = 0; i < 3; ++i)
            {
                m_input.Position = bits_pos[i];
                var bits = m_input.ReadBytes(bits_pos[i + 1] - bits_pos[i]);
                m_input.Position = data_pos[i];
                if (1 == m_info.Method)
                {
                    int bits_src = 0;
                    int bit_mask = 0x80;
                    int cdst     = 0;
                    while (cdst < channel.Length)
                    {
                        if (0 == bit_mask)
                        {
                            ++bits_src;
                            bit_mask = 0x80;
                        }
                        if ((bits[bits_src] & bit_mask) != 0)
                        {
                            int offset = m_input.ReadUInt16();
                            int count  = (offset & 0xF) + 3;
                            offset = (offset >> 4) + 1;
                            Binary.CopyOverlapped(channel, cdst - offset, cdst, count);
                            cdst += count;
                        }
                        else
                        {
                            channel[cdst++] = m_input.ReadUInt8();
                        }
                        bit_mask >>= 1;
                    }
                }
                else if (2 == m_info.Method)
                {
                    LzssUnpack(bits, 0, channel, channel.Length);
                }
                int  dst   = i;
                byte accum = 0;
                for (int csrc = 0; csrc < channel.Length; ++csrc)
                {
                    accum        += channel[csrc];
                    m_output[dst] = accum;
                    dst          += 4;
                }
            }
            if (4 == m_channels)
            {
                m_input.Position = data_pos[3];
                int dst = 3;
                while (dst < m_output.Length)
                {
                    byte a     = m_input.ReadUInt8();
                    int  count = 1;
                    if (a == 0 || a == 0xFF)
                    {
                        count += m_input.ReadUInt8();
                    }
                    while (count-- > 0)
                    {
                        m_output[dst] = a;
                        dst          += 4;
                    }
                }
            }
        }
示例#14
0
 void UnpackV0()
 {
     Format   = 3 == m_channels ? PixelFormats.Bgr24 : PixelFormats.Bgra32;
     m_stride = m_width * m_channels;
     m_output = m_input.ReadBytes(m_stride * m_height);
 }
示例#15
0
文件: ImagePX.cs 项目: zxc120/GARbro
        public override ImageMetaData ReadMetaData(IBinaryStream stream)
        {
            var header = stream.ReadHeader(0x20);
            int type   = header.ToUInt16(0x10);

            if (0x0C == type)
            {
                int count = header.ToInt32(0);
                if (!ArchiveFormat.IsSaneCount(count))
                {
                    return(null);
                }
                int block_size = header.ToInt32(4);
                if (block_size <= 0)
                {
                    return(null);
                }
                int  bpp    = header.ToUInt16(0x12);
                uint width  = header.ToUInt16(0x14);
                uint height = header.ToUInt16(0x16);
                if (bpp != 32 || 0 == width || 0 == height)
                {
                    return(null);
                }
                return(new PxMetaData
                {
                    Width = width,
                    Height = height,
                    BPP = bpp,
                    Type = type,
                    FrameCount = count,
                    BlockSize = block_size,
                    BlocksWidth = header.ToUInt16(0x1C),
                    BlocksHeight = header.ToUInt16(0x1E),
                });
            }
            else if (0x90 == type)
            {
                if (!header.AsciiEqual(0x14, "Leaf"))
                {
                    return(null);
                }
                int count = header.ToInt32(4);
                if (!ArchiveFormat.IsSaneCount(count))
                {
                    return(null);
                }
                var header_ex = stream.ReadBytes(0x20);
                if (0x20 != header_ex.Length)
                {
                    return(null);
                }
                if (0x0A != LittleEndian.ToUInt16(header_ex, 0x10))
                {
                    return(null);
                }
                return(new PxMetaData
                {
                    Width = LittleEndian.ToUInt32(header_ex, 0),
                    Height = LittleEndian.ToUInt32(header_ex, 4),
                    BPP = LittleEndian.ToUInt16(header_ex, 0x12),
                    Type = type,
                    FrameCount = count,
                });
            }
            else if (0x40 == type || 0x44 == type)
            {
                int count = header.ToInt32(0);
                if (!ArchiveFormat.IsSaneCount(count))
                {
                    return(null);
                }
                return(new PxMetaData
                {
                    Width = header.ToUInt32(0x14),
                    Height = header.ToUInt32(0x18),
                    Type = 0x40,
                    BPP = 32,
                    FrameCount = count,
                });
            }
            else if (1 == type || 4 == type || 7 == type)
            {
                int bpp = header.ToUInt16(0x12);
                if (bpp != 32 && bpp != 8)
                {
                    return(null);
                }
                return(new PxMetaData
                {
                    Width = header.ToUInt32(0x14),
                    Height = header.ToUInt32(0x18),
                    Type = type,
                    BPP = bpp,
                    FrameCount = 1,
                });
            }
            return(null);
        }
示例#16
0
        void CopyV0(int data_size)
        {
            int plane_size = (int)Info.Width * (int)Info.Height;

            if (plane_size == data_size)
            {
                Info.BPP = 8;
                m_output = m_input.ReadBytes(data_size);
            }
            else if (3 * plane_size == data_size)
            {
                Info.BPP = 24;
                m_output = m_input.ReadBytes(data_size);
            }
            else if (4 * plane_size == data_size)
            {
                Info.BPP = 32;
                m_output = m_input.ReadBytes(data_size);
            }
            else
            {
                Info.BPP = 24;
                int dst_stride = (int)Info.Width * 3;
                int src_stride = (dst_stride + 3) & ~3;
                if (src_stride * (int)Info.Height != data_size)
                {
                    throw new InvalidFormatException();
                }
                m_output = new byte[dst_stride * (int)Info.Height];
                var gap = new byte[src_stride - dst_stride];
                int dst = 0;
                for (uint y = 0; y < Info.Height; ++y)
                {
                    m_input.Read(m_output, dst, dst_stride);
                    m_input.Read(gap, 0, gap.Length);
                    dst += dst_stride;
                }
            }
        }
示例#17
0
        byte[] Unpack8bpp()
        {
            if (8 == Info.BPP)
            {
                Format  = PixelFormats.Indexed8;
                Palette = DefaultPalette;
            }
            else
            {
                Format = PixelFormats.BlackWhite;
            }
            int pixel_count = Info.iHeight * Stride;

            if (m_info.IsCompressed)
            {
                return(m_input.ReadBytes(pixel_count));
            }

            var output = new byte[pixel_count];
            int dst    = 0;

            byte[] frame = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xFF };

            int count       = pixel_count;
            int extra_count = pixel_count;

            while (pixel_count > 0)
            {
                byte pixel;
                int  frame_pos;
                byte ctl = m_input.ReadUInt8();
                int  hi  = ctl >> 4;
                int  lo  = ctl & 0xF;
                if (hi != 0)
                {
                    frame_pos = hi - 1;
                    pixel     = frame[frame_pos];
                    count     = lo + 1;
                }
                else
                {
                    switch (lo)
                    {
                    default:
                        count = lo + 1;
                        break;

                    case 10:
                        count = m_input.ReadUInt8() + 11;
                        break;

                    case 11:
                        count = m_input.ReadUInt16() + 267;
                        break;

                    case 12:
                        count = m_input.ReadInt32() + 65803;
                        break;

                    case 13:
                        extra_count = 0x10;
                        count       = m_input.ReadUInt8();
                        break;

                    case 14:
                        extra_count = 0x120;
                        count       = m_input.ReadUInt16();
                        break;

                    case 15:
                        extra_count = 0x10130;
                        count       = m_input.ReadInt32();
                        break;
                    }
                    pixel = m_input.ReadUInt8();
                    if (lo < 13)
                    {
                        frame_pos = 14;
                    }
                    else
                    {
                        lo        = pixel & 0xF;
                        frame_pos = (pixel >> 4) - 1;
                        pixel     = frame[frame_pos];
                        count     = extra_count + 16 * count + lo + 1;
                    }
                }
                if (count > pixel_count)
                {
                    count = pixel_count;
                }
                pixel_count -= count;
                for (int i = 0; i < count; ++i)
                {
                    output[dst++] = pixel;
                }
                Buffer.BlockCopy(frame, 0, frame, 1, frame_pos);
                frame[0] = pixel;
            }
            return(output);
        }