bool ReadFromStream(Stream input, int name_length) { m_dir.Clear(); using (var index = new ArcView.Reader(input)) { for (int i = 0; i < m_count; ++i) { if (name_length != index.Read(m_name_buffer, 0, name_length)) { return(false); } var name = Binary.GetCString(m_name_buffer, 0, name_length); if (string.IsNullOrWhiteSpace(name)) { return(false); } var entry = FormatCatalog.Instance.Create <PackedEntry> (name); entry.Offset = index.ReadUInt32(); entry.UnpackedSize = index.ReadUInt32(); entry.Size = index.ReadUInt32(); if (!entry.CheckPlacement(m_file.MaxOffset)) { return(false); } entry.IsPacked = m_pack_type != 0 && (m_pack_type != 4 || entry.Size != entry.UnpackedSize); m_dir.Add(entry); } return(true); } }
List <Entry> ReadIndex(Stream arc, byte[] key, string arc_name) { arc.Position = 8; using (var reader = new ArcView.Reader(arc)) { int count = reader.ReadInt32(); if (!IsSaneCount(count)) { return(null); } uint base_offset = reader.ReadUInt32(); uint index_size = 4u * (uint)count; var max_offset = arc.Length; if (base_offset >= max_offset || base_offset < (0x10 + index_size)) { return(null); } var index = new List <uint> (count); for (int i = 0; i < count; ++i) { uint offset = reader.ReadUInt32(); if (offset != 0xffffffff) { if (offset >= max_offset - base_offset) { return(null); } index.Add(base_offset + offset); } } var name_buffer = new byte[0x20]; var dir = new List <Entry> (index.Count); for (int i = 0; i < index.Count; ++i) { long offset = index[i]; reader.BaseStream.Position = offset; reader.Read(name_buffer, 0, 0x20); string name = Binary.GetCString(name_buffer, 0, 0x20); Entry entry; if (0 == name.Length) { entry = new Entry { Name = string.Format("{0}#{1:D5}", arc_name, i), Type = "image" } } ; else { entry = FormatCatalog.Instance.Create <Entry> (name); } entry.Offset = offset + 0x24; entry.Size = reader.ReadUInt32(); dir.Add(entry); } return(dir); } }
public AgReader(Stream stream, ImageMetaData info) { m_width = (int)info.Width; m_height = (int)info.Height; stream.Position = 0x0c; using (var input = new ArcView.Reader(stream)) { uint offset1 = input.ReadUInt32(); int size1 = input.ReadInt32(); uint offset2 = input.ReadUInt32(); int size2 = input.ReadInt32(); uint offset3 = input.ReadUInt32(); int size3 = input.ReadInt32(); uint offset4 = input.ReadUInt32(); int size4 = input.ReadInt32(); uint offset5 = input.ReadUInt32(); int size5 = input.ReadInt32(); uint offset6 = input.ReadUInt32(); int size6 = input.ReadInt32(); input.Read(m_first, 0, 3); if (size1 != 0) { in1 = ReadSection(stream, offset1, size1); } if (size2 != 0) { in2 = ReadSection(stream, offset2, size2); } if (size3 != 0) { in3 = ReadSection(stream, offset3, size3); } if (size4 != 0) { in4 = ReadSection(stream, offset4, size4); } if (size5 != 0) { in5 = ReadSection(stream, offset5, size5); } if (size6 != 0) { input.BaseStream.Position = offset6; m_alpha = new byte[m_height * m_width]; RleDecode(input, m_alpha); Format = PixelFormats.Bgra32; m_pixel_size = 4; } else { Format = PixelFormats.Bgr24; m_pixel_size = 3; } m_output = new byte[m_width * m_height * m_pixel_size]; } }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(8); if (!IsSaneCount(count)) { return(null); } uint base_offset = file.View.ReadUInt32(0xC); if (base_offset <= 0x18 || base_offset >= file.MaxOffset) { return(null); } uint packed_size = file.View.ReadUInt32(0x10); int index_size = file.View.ReadInt32(0x14); if (packed_size > file.MaxOffset || index_size / IndexEntrySize != count) { return(null); } var name_buffer = new byte[30]; using (var packed = file.CreateStream(0x18, packed_size)) using (var lzss = new LzssStream(packed)) using (var index = new ArcView.Reader(lzss)) { var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { if (name_buffer.Length != index.Read(name_buffer, 0, name_buffer.Length)) { return(null); } var name = Binary.GetCString(name_buffer, 0, name_buffer.Length); var entry = FormatCatalog.Instance.Create <Entry> (name); if (name.EndsWith(".acd", StringComparison.InvariantCultureIgnoreCase)) { entry.Type = "script"; } entry.Offset = index.ReadUInt32() + base_offset; entry.Size = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } return(new ArcFile(file, this, dir)); } }
Stream Unpack(Stream input) { using (var reader = new ArcView.Reader(input)) { var output = new MemoryStream(); var buffer = new byte[0x10000]; for (;;) { int ctl = input.ReadByte(); if (-1 == ctl || 0xFF == ctl) { break; } int count = reader.ReadInt32(); if (3 == ctl) { byte b = reader.ReadByte(); for (int i = 0; i < count; ++i) { output.WriteByte(b); } } else { while (count > 0) { int chunk = Math.Min(count, buffer.Length); int read = reader.Read(buffer, 0, chunk); output.Write(buffer, 0, read); count -= chunk; } } } output.Position = 0; return(output); } }
ImageData ReadV5(Stream stream, TlgMetaData info) { using (var src = new ArcView.Reader(stream)) { int width = (int)info.Width; int height = (int)info.Height; int colors = info.BPP / 8; int blockheight = src.ReadInt32(); int blockcount = (height - 1) / blockheight + 1; // skip block size section src.BaseStream.Seek(blockcount * 4, SeekOrigin.Current); int stride = width * 4; var image_bits = new byte[height * stride]; var text = new byte[4096]; for (int i = 0; i < 4096; ++i) { text[i] = 0; } var inbuf = new byte[blockheight * width + 10]; byte [][] outbuf = new byte[4][]; for (int i = 0; i < colors; i++) { outbuf[i] = new byte[blockheight * width + 10]; } int z = 0; int prevline = -1; for (int y_blk = 0; y_blk < height; y_blk += blockheight) { // read file and decompress for (int c = 0; c < colors; c++) { byte mark = src.ReadByte(); int size; size = src.ReadInt32(); if (mark == 0) { // modified LZSS compressed data if (size != src.Read(inbuf, 0, size)) { return(null); } z = TVPTLG5DecompressSlide(outbuf[c], inbuf, size, text, z); } else { // raw data src.Read(outbuf[c], 0, size); } } // compose colors and store int y_lim = y_blk + blockheight; if (y_lim > height) { y_lim = height; } int outbuf_pos = 0; for (int y = y_blk; y < y_lim; y++) { int current = y * stride; int current_org = current; if (prevline >= 0) { // not first line switch (colors) { case 3: TVPTLG5ComposeColors3To4(image_bits, current, prevline, outbuf, outbuf_pos, width); break; case 4: TVPTLG5ComposeColors4To4(image_bits, current, prevline, outbuf, outbuf_pos, width); break; } } else { // first line switch (colors) { case 3: for (int pr = 0, pg = 0, pb = 0, x = 0; x < width; x++) { int b = outbuf[0][outbuf_pos + x]; int g = outbuf[1][outbuf_pos + x]; int r = outbuf[2][outbuf_pos + x]; b += g; r += g; image_bits[current++] = (byte)(pb += b); image_bits[current++] = (byte)(pg += g); image_bits[current++] = (byte)(pr += r); image_bits[current++] = 0xff; } break; case 4: for (int pr = 0, pg = 0, pb = 0, pa = 0, x = 0; x < width; x++) { int b = outbuf[0][outbuf_pos + x]; int g = outbuf[1][outbuf_pos + x]; int r = outbuf[2][outbuf_pos + x]; int a = outbuf[3][outbuf_pos + x]; b += g; r += g; image_bits[current++] = (byte)(pb += b); image_bits[current++] = (byte)(pg += g); image_bits[current++] = (byte)(pr += r); image_bits[current++] = (byte)(pa += a); } break; } } outbuf_pos += width; prevline = current_org; } } PixelFormat format = 4 == colors ? PixelFormats.Bgra32 : PixelFormats.Bgr32; return(ImageData.Create(info, format, null, image_bits, stride)); } }
ImageData ReadV6(Stream stream, TlgMetaData info) { using (var src = new ArcView.Reader(stream)) { int width = (int)info.Width; int height = (int)info.Height; int colors = info.BPP / 8; int max_bit_length = src.ReadInt32(); int x_block_count = ((width - 1) / TVP_TLG6_W_BLOCK_SIZE) + 1; int y_block_count = ((height - 1) / TVP_TLG6_H_BLOCK_SIZE) + 1; int main_count = width / TVP_TLG6_W_BLOCK_SIZE; int fraction = width - main_count * TVP_TLG6_W_BLOCK_SIZE; var image_bits = new uint[height * width]; var bit_pool = new byte[max_bit_length / 8 + 5]; var pixelbuf = new uint[width * TVP_TLG6_H_BLOCK_SIZE + 1]; var filter_types = new byte[x_block_count * y_block_count]; var zeroline = new uint[width]; var LZSS_text = new byte[4096]; // initialize zero line (virtual y=-1 line) uint zerocolor = 3 == colors ? 0xff000000 : 0x00000000; for (var i = 0; i < width; ++i) { zeroline[i] = zerocolor; } uint[] prevline = zeroline; int prevline_index = 0; // initialize LZSS text (used by chroma filter type codes) int p = 0; for (uint i = 0; i < 32 * 0x01010101; i += 0x01010101) { for (uint j = 0; j < 16 * 0x01010101; j += 0x01010101) { LZSS_text[p++] = (byte)(i & 0xff); LZSS_text[p++] = (byte)(i >> 8 & 0xff); LZSS_text[p++] = (byte)(i >> 16 & 0xff); LZSS_text[p++] = (byte)(i >> 24 & 0xff); LZSS_text[p++] = (byte)(j & 0xff); LZSS_text[p++] = (byte)(j >> 8 & 0xff); LZSS_text[p++] = (byte)(j >> 16 & 0xff); LZSS_text[p++] = (byte)(j >> 24 & 0xff); } } // read chroma filter types. // chroma filter types are compressed via LZSS as used by TLG5. { int inbuf_size = src.ReadInt32(); byte[] inbuf = src.ReadBytes(inbuf_size); if (inbuf_size != inbuf.Length) { return(null); } TVPTLG5DecompressSlide(filter_types, inbuf, inbuf_size, LZSS_text, 0); } // for each horizontal block group ... for (int y = 0; y < height; y += TVP_TLG6_H_BLOCK_SIZE) { int ylim = y + TVP_TLG6_H_BLOCK_SIZE; if (ylim >= height) { ylim = height; } int pixel_count = (ylim - y) * width; // decode values for (int c = 0; c < colors; c++) { // read bit length int bit_length = src.ReadInt32(); // get compress method int method = (bit_length >> 30) & 3; bit_length &= 0x3fffffff; // compute byte length int byte_length = bit_length / 8; if (0 != (bit_length % 8)) { byte_length++; } // read source from input src.Read(bit_pool, 0, byte_length); // decode values // two most significant bits of bitlength are // entropy coding method; // 00 means Golomb method, // 01 means Gamma method (not yet suppoted), // 10 means modified LZSS method (not yet supported), // 11 means raw (uncompressed) data (not yet supported). switch (method) { case 0: if (c == 0 && colors != 1) { TVPTLG6DecodeGolombValuesForFirst(pixelbuf, pixel_count, bit_pool); } else { TVPTLG6DecodeGolombValues(pixelbuf, c * 8, pixel_count, bit_pool); } break; default: throw new InvalidFormatException("Unsupported entropy coding method"); } } // for each line int ft = (y / TVP_TLG6_H_BLOCK_SIZE) * x_block_count; // within filter_types int skipbytes = (ylim - y) * TVP_TLG6_W_BLOCK_SIZE; for (int yy = y; yy < ylim; yy++) { int curline = yy * width; int dir = (yy & 1) ^ 1; int oddskip = ((ylim - yy - 1) - (yy - y)); if (0 != main_count) { int start = ((width < TVP_TLG6_W_BLOCK_SIZE) ? width : TVP_TLG6_W_BLOCK_SIZE) * (yy - y); TVPTLG6DecodeLineGeneric( prevline, prevline_index, image_bits, curline, width, 0, main_count, filter_types, ft, skipbytes, pixelbuf, start, zerocolor, oddskip, dir); } if (main_count != x_block_count) { int ww = fraction; if (ww > TVP_TLG6_W_BLOCK_SIZE) { ww = TVP_TLG6_W_BLOCK_SIZE; } int start = ww * (yy - y); TVPTLG6DecodeLineGeneric( prevline, prevline_index, image_bits, curline, width, main_count, x_block_count, filter_types, ft, skipbytes, pixelbuf, start, zerocolor, oddskip, dir); } prevline = image_bits; prevline_index = curline; // Array.Copy (image_bits, curline, prevline, 0, width); } } unsafe { fixed(void *data = image_bits) { int stride = width * 4; PixelFormat format = 32 == info.BPP ? PixelFormats.Bgra32 : PixelFormats.Bgr32; var bitmap = BitmapSource.Create(width, height, ImageData.DefaultDpiX, ImageData.DefaultDpiY, format, null, (IntPtr)data, height * stride, stride); bitmap.Freeze(); return(new ImageData(bitmap, info)); } } } }