Beispiel #1
0
 byte[] ReadBaseImage(Stream file, RctMetaData meta)
 {
     file.Position = meta.DataOffset;
     byte[] name_bin = new byte[meta.AddSize];
     if (name_bin.Length != file.Read(name_bin, 0, name_bin.Length))
     {
         throw new EndOfStreamException();
     }
     try
     {
         string name     = Encodings.cp932.GetString(name_bin, 0, name_bin.Length - 1);
         string dir_name = Path.GetDirectoryName(meta.FileName);
         name = VFS.CombinePath(dir_name, name);
         if (VFS.FileExists(name))
         {
             using (var base_file = VFS.OpenSeekableStream(name))
             {
                 var base_info = ReadMetaData(base_file) as RctMetaData;
                 if (null != base_info && 0 == base_info.AddSize &&
                     meta.Width == base_info.Width && meta.Height == base_info.Height)
                 {
                     base_info.FileName = name;
                     return(ReadPixelsData(base_file, base_info));
                 }
             }
         }
     }
     catch { /* ignore baseline image read errors */ }
     return(null);
 }
Beispiel #2
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(Path.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);
        }
Beispiel #3
0
        public override ImageData Read(Stream stream, ImageMetaData info)
        {
            var          meta = (DifMetaData)info;
            BitmapSource base_bitmap;

            using (var input = VFS.OpenSeekableStream(meta.BaseEntry))
            {
                var image = meta.BaseFormat.Read(input, meta.BaseInfo);
                base_bitmap = image.Bitmap;
            }
            stream.Position = 0x7C;
            var index = new byte[meta.IndexSize];

            using (var input = new LzssStream(stream, LzssMode.Decompress, true))
                if (index.Length != input.Read(index, 0, index.Length))
                {
                    throw new EndOfStreamException();
                }

            if (base_bitmap.Format.BitsPerPixel != 24)
            {
                base_bitmap = new FormatConvertedBitmap(base_bitmap, PixelFormats.Bgr24, null, 0);
            }

            int src_stride = base_bitmap.PixelWidth * 3; // XXX
            int dst_stride = (src_stride + 3) & ~3;
            var pixels     = new byte[dst_stride * base_bitmap.PixelHeight];
            int row_offset = 0;
            var rect       = new Int32Rect(0, base_bitmap.PixelHeight, base_bitmap.PixelWidth, 1);

            for (rect.Y = base_bitmap.PixelHeight - 1; rect.Y >= 0; --rect.Y)
            {
                base_bitmap.CopyPixels(rect, pixels, src_stride, row_offset);
                row_offset += dst_stride;
            }

            stream.Position = 0x7C + meta.PackedIndexSize;
            using (var diff = new LzssStream(stream, LzssMode.Decompress, true))
            {
                int index_src = 0;
                for (int i = 0; i < meta.DiffCount; ++i)
                {
                    int offset = LittleEndian.ToInt32(index, index_src);
                    int size   = LittleEndian.ToInt32(index, index_src + 4);
                    index_src += 8;
                    diff.Read(pixels, offset, size);
                }
                return(ImageData.CreateFlipped(info, PixelFormats.Bgr24, null, pixels, dst_stride));
            }
        }
Beispiel #4
0
        public override ImageMetaData ReadMetaData(Stream stream)
        {
            var header = new byte[0x7C];

            if (header.Length != stream.Read(header, 0, header.Length))
            {
                return(null);
            }
            var base_name = Binary.GetCString(header, 4, 100);

            if (string.IsNullOrEmpty(base_name))
            {
                return(null);
            }
            var files = VFS.GetFiles(base_name + ".*");

            if (!files.Any())
            {
                throw new FileNotFoundException(string.Format("Base image '{0}' not found", base_name));
            }
            var base_entry = files.First();

            using (var input = VFS.OpenSeekableStream(base_entry))
            {
                // ReadMetaData isn't supplied with a filename being processed, so infinite recursion can't be
                // prevented here unless we save state in a static member.
                var format = ImageFormat.FindFormat(input, base_entry.Name);
                if (null == format)
                {
                    throw new InvalidFormatException(string.Format("Unable to interpret base image '{0}'", base_name));
                }
                format.Item2.FileName = base_entry.Name;
                return(new DifMetaData
                {
                    Width = format.Item2.Width,
                    Height = format.Item2.Height,
                    BPP = 24,
                    BaseEntry = base_entry,
                    BaseFormat = format.Item1,
                    BaseInfo = format.Item2,
                    PackedIndexSize = LittleEndian.ToInt32(header, 0x68),
                    IndexSize = LittleEndian.ToInt32(header, 0x6C),
                    PackedDiffSize = LittleEndian.ToInt32(header, 0x70),
                    DiffDataSize = LittleEndian.ToInt32(header, 0x74),
                    DiffCount = LittleEndian.ToInt32(header, 0x78),
                });
            }
        }
Beispiel #5
0
        byte[] LoadBaseImage(string name)
        {
            // judging by the code, files with "pb3" extension could as well contain PNG or BMP images,
            // so we couldn't just shortcut to another instance of Pb3Reader here.

            var path = Path.GetDirectoryName(m_info.FileName);

            name = VFS.CombinePath(path, name);
            if (name.Equals(m_info.FileName, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new InvalidFormatException();
            }
            // two files referencing each other still could create infinite recursion
            using (var base_file = VFS.OpenSeekableStream(name))
            {
                var image_data = ImageFormat.Read(name, base_file);
                int stride     = image_data.Bitmap.PixelWidth * 4;
                var pixels     = new byte[stride * image_data.Bitmap.PixelHeight];
                image_data.Bitmap.CopyPixels(pixels, stride, 0);
                return(pixels);
            }
        }
Beispiel #6
0
 Stream OpenPreviewStream(PreviewFile preview)
 {
     return(VFS.OpenSeekableStream(preview.Entry));
 }