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); }
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); }
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)); } }
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), }); } }
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); } }
Stream OpenPreviewStream(PreviewFile preview) { return(VFS.OpenSeekableStream(preview.Entry)); }