コード例 #1
0
        private static void Decode(Stream stream, ShpOffset[] offsets, int width, int height,
                                   byte[][] frames, byte[] src, ref int recdepth)
        {
            if (recdepth > frames.Length)
            {
                throw new NotImplementedException("Format 40/20 frames contain infinite loop!");
            }

            for (uint i = 0; i < frames.Length; i++)
            {
                byte[]    frame    = new byte[width * height];
                byte[]    refframe = null;
                ShpOffset curoff   = offsets[i + 0];
                ShpOffset nxtoff   = offsets[i + 1];
                int       srclen   = (int)(nxtoff.Offset - curoff.Offset);

                stream.Read(src, 0, srclen);

                switch (curoff.OffsetFormat)
                {
                // Format 20
                case 0x20:
                    refframe = frames[i - 1];
                    goto do_format40;

                // Format 40
                case 0x40:
                    int j = Array.FindIndex(offsets, o => o.Offset == curoff.Ref);
                    if (j < 0)
                    {
                        throw new IndexOutOfRangeException("Invalid frame reference!");
                    }
                    refframe = frames[j];
do_format40:
                    if (refframe == null)
                    {
                        recdepth++;
                        Decode(stream, offsets, width, height, frames, src, ref recdepth);
                        recdepth--;
                    }
                    Format40.Decode(src, srclen, frame, refframe);
                    break;

                // Format 80
                case 0x80:
                    Format80.Decode(src, 0, frame, 0, srclen);
                    break;

                // Invalid format
                default:
                    throw new NotImplementedException("Invalid format!");
                }

                frames[i] = frame;
            }
        }
コード例 #2
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();
            }
        }