public EriMultiImage(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, EriMetaData info, Color[] palette) : base(arc, impl, dir) { Info = info; Palette = palette; Frames = new byte[dir.Count][]; }
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); }
void AddImageBuffer(EriMetaData dst_info, byte[] dst_img, EriMetaData src_info, byte[] src_img) { int src_bpp = (src_info.BPP + 7) / 8; int dst_bpp = (dst_info.BPP + 7) / 8; bool has_alpha = src_bpp == 4 && src_bpp == dst_bpp; int dst = 0; int src = 0; while (dst < dst_img.Length) { dst_img[dst] += src_img[src]; dst_img[dst + 1] += src_img[src + 1]; dst_img[dst + 2] += src_img[src + 2]; if (has_alpha) { dst_img[dst + 3] += src_img[src + 3]; } dst += dst_bpp; src += src_bpp; } }
public EriMultiImage(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, EriMetaData info, Color[] palette) : base(arc, impl, dir) { Info = info; Palette = palette; Frames = new byte[dir.Count][]; if (8 == Info.BPP) { if (null == Palette) { Format = PixelFormats.Gray8; } else { Format = PixelFormats.Indexed8; } } else if (32 == Info.BPP) { if (0 == (Info.FormatType & EriType.WithAlpha)) { Format = PixelFormats.Bgr32; } else { Format = PixelFormats.Bgra32; } } else if (16 == Info.BPP) { Format = PixelFormats.Bgr555; } else { Format = PixelFormats.Bgr24; } }
} // '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); } }
public EriReader (Stream stream, EriMetaData info, Color[] palette, byte[] key_frame = null) { m_info = info; m_src_frame = key_frame; switch (m_info.Architecture) { case EriCode.Nemesis: case EriCode.RunlengthHuffman: case EriCode.RunlengthGamma: if (CvType.Lossless_ERI == m_info.Transformation && 0 == m_info.BlockingDegree) throw new InvalidFormatException(); break; case EriCode.ArithmeticCode: if (CvType.Lossless_ERI != m_info.Transformation) throw new InvalidFormatException(); break; default: throw new InvalidFormatException(); } switch (m_info.FormatType & EriType.Mask) { case EriType.RGB: if (m_info.BPP <= 8) m_nChannelCount = 1; else if (0 == (m_info.FormatType & EriType.WithAlpha)) m_nChannelCount = 3; else m_nChannelCount = 4; break; case EriType.Gray: m_nChannelCount = 1; break; default: throw new InvalidFormatException(); } if (CvType.Lossless_ERI == m_info.Transformation) InitializeLossless(); else if (CvType.LOT_ERI == m_info.Transformation || CvType.DCT_ERI == m_info.Transformation) InitializeLossy(); else throw new NotSupportedException ("Not supported ERI compression"); if (null != palette) Palette = new BitmapPalette (palette); CreateImageBuffer(); m_context.AttachInputFile (stream); m_pfnColorOperation = new PtrProcedure[0x10] { ColorOperation0000, ColorOperation0000, ColorOperation0000, ColorOperation0000, ColorOperation0000, ColorOperation0101, ColorOperation0110, ColorOperation0111, ColorOperation0000, ColorOperation1001, ColorOperation1010, ColorOperation1011, ColorOperation0000, ColorOperation1101, ColorOperation1110, ColorOperation1111 }; }
void AddImageBuffer(EriMetaData dst_info, byte[] dst_img, EriMetaData src_info, byte[] src_img) { int src_bpp = (src_info.BPP + 7) / 8; int dst_bpp = (dst_info.BPP + 7) / 8; bool has_alpha = src_bpp == 4 && src_bpp == dst_bpp; int dst = 0; int src = 0; while (dst < dst_img.Length) { dst_img[dst ] += src_img[src ]; dst_img[dst+1] += src_img[src+1]; dst_img[dst+2] += src_img[src+2]; if (has_alpha) dst_img[dst+3] += src_img[src+3]; dst += dst_bpp; src += src_bpp; } }
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; }
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; } }