Exemple #1
0
		public ShpReader(Stream stream)
		{
			imageCount = stream.ReadUInt16();
			stream.Position += 4;
			var width = stream.ReadUInt16();
			var height = stream.ReadUInt16();
			Size = new Size(width, height);

			stream.Position += 4;
			var headers = new ImageHeader[imageCount];
			Frames = headers.AsReadOnly();
			for (var i = 0; i < headers.Length; i++)
				headers[i] = new ImageHeader(stream, this);

			// Skip eof and zero headers
			stream.Position += 16;

			var offsets = headers.ToDictionary(h => h.FileOffset, h => h);
			for (var i = 0; i < imageCount; i++)
			{
				var h = headers[i];
				if (h.Format == Format.Format20)
					h.RefImage = headers[i - 1];
				else if (h.Format == Format.Format40 && !offsets.TryGetValue(h.RefOffset, out h.RefImage))
					throw new InvalidDataException("Reference doesnt point to image data {0}->{1}".F(h.FileOffset, h.RefOffset));
			}

			shpBytesFileOffset = stream.Position;
			shpBytes = stream.ReadBytes((int)(stream.Length - stream.Position));

			foreach (var h in headers)
				Decompress(h);
		}
Exemple #2
0
        void Decompress(Stream stream, ImageHeader h)
        {
            if (recurseDepth > ImageCount)
                throw new InvalidDataException("Format20/40 headers contain infinite loop");

            switch(h.Format)
            {
                case Format.Format20:
                case Format.Format40:
                    {
                        if (h.RefImage.Image == null)
                        {
                            ++recurseDepth;
                            Decompress(stream, h.RefImage);
                            --recurseDepth;
                        }

                        h.Image = CopyImageData(h.RefImage.Image);
                        Format40.DecodeInto(ReadCompressedData(stream, h), h.Image);
                        break;
                    }
                case Format.Format80:
                    {
                        var imageBytes = new byte[Width * Height];
                        Format80.DecodeInto(ReadCompressedData(stream, h), imageBytes);
                        h.Image = imageBytes;
                        break;
                    }
                default:
                    throw new InvalidDataException();
            }
        }
Exemple #3
0
        static byte[] ReadCompressedData(Stream stream, ImageHeader h)
        {
            stream.Position = h.Offset;
            // TODO: Actually, far too big. There's no length field with the correct length though :(
            var compressedLength = (int)(stream.Length - stream.Position);

            var compressedBytes = new byte[ compressedLength ];
            stream.Read( compressedBytes, 0, compressedLength );

            return compressedBytes;
        }
Exemple #4
0
		public static void Write(Stream s, Size size, IEnumerable<byte[]> frames)
		{
			var compressedFrames = frames.Select(f => Format80.Encode(f)).ToList();

			// note: end-of-file and all-zeroes headers
			var dataOffset = 14 + (compressedFrames.Count + 2) * 8;

			using (var bw = new BinaryWriter(s))
			{
				bw.Write((ushort)compressedFrames.Count);
				bw.Write((ushort)0);
				bw.Write((ushort)0);
				bw.Write((ushort)size.Width);
				bw.Write((ushort)size.Height);
				bw.Write((uint)0);

				foreach (var f in compressedFrames)
				{
					var ih = new ImageHeader { Format = Format.Format80, FileOffset = (uint)dataOffset };
					dataOffset += f.Length;

					ih.WriteTo(bw);
				}

				var eof = new ImageHeader { FileOffset = (uint)dataOffset };
				eof.WriteTo(bw);

				var allZeroes = new ImageHeader { };
				allZeroes.WriteTo(bw);

				foreach (var f in compressedFrames)
					bw.Write(f);
			}
		}
Exemple #5
0
		void Decompress(ImageHeader h)
		{
			// No extra work is required for empty frames
			if (h.Size.Width == 0 || h.Size.Height == 0)
				return;

			if (recurseDepth > imageCount)
				throw new InvalidDataException("Format20/40 headers contain infinite loop");

			switch (h.Format)
			{
				case Format.Format20:
				case Format.Format40:
					{
						if (h.RefImage.Data == null)
						{
							++recurseDepth;
							Decompress(h.RefImage);
							--recurseDepth;
						}

						h.Data = CopyImageData(h.RefImage.Data);
						Format40.DecodeInto(shpBytes, h.Data, (int)(h.FileOffset - shpBytesFileOffset));
						break;
					}

				case Format.Format80:
					{
						var imageBytes = new byte[Size.Width * Size.Height];
						Format80.DecodeInto(shpBytes, imageBytes, (int)(h.FileOffset - shpBytesFileOffset));
						h.Data = imageBytes;
						break;
					}

				default:
					throw new InvalidDataException();
			}
		}