Example #1
0
        /// <summary>
        /// Loads the pixels of a frame.
        /// </summary>
        /// <param name="imgPath">The Npk Path of the .img file, with the leading sprite/ if present</param>
        /// <param name="frameIndex"></param>
        /// <returns></returns>
        /// <exception cref="System.IO.FileNotFoundException">The img file does not exist in this .npk file
        /// or no frame with the given index exists in the img file.</exception>
        /// <exception cref="System.IO.IOException">An I/O error occurred.</exception>
        /// <exception cref="Dfo.Npk.NpkException">The .npk file is corrupt or the format changed.</exception>
        public Image GetImage(NpkPath imgPath, int frameIndex)
        {
            imgPath.ThrowIfNull("imgPath");

            try
            {
                PreLoadSpriteMetadata(imgPath);

                IList<FrameInfo> imgFrames = m_frames[imgPath];

                if (frameIndex >= imgFrames.Count || frameIndex < 0)
                {
                    throw new FileNotFoundException("Cannot get frame index {0} of {1}. It only has {2} frames."
                        .F(frameIndex, imgPath, imgFrames.Count));
                }

                FrameInfo frameData = imgFrames[frameIndex];
                int realFrameIndex = frameIndex;

                // Follow frame links
                if (frameData.LinkFrame != null)
                {
                    realFrameIndex = frameData.LinkFrame.Value;
                    if (realFrameIndex >= imgFrames.Count || realFrameIndex < 0)
                    {
                        throw new FileNotFoundException("Cannot get linked frame index {0} of {1}. It only has {2} frames."
                            .F(realFrameIndex, imgPath, imgFrames.Count));
                    }
                    frameData = imgFrames[realFrameIndex];

                    if (frameData.LinkFrame != null)
                    {
                        throw new NpkException(
                            "There is a link frame to another link frame which is not allowed. {0} frame {1} links to frame {2}."
                            .F(imgPath, frameIndex, realFrameIndex));
                    }
                }

                NpkByteRange pixelDataLocation = m_frameLocations[imgPath][realFrameIndex];
                // Seek to the pixel data and read it
                Seek(pixelDataLocation.FileOffset, SeekOrigin.Begin);
                byte[] pixelData = new byte[pixelDataLocation.Size];
                m_npkStream.ReadOrDie(pixelData, pixelData.Length);

                if (frameData.IsCompressed)
                {
                    using (MemoryStream pixelDataMemoryStream = new MemoryStream(pixelData))
                    {
                        try
                        {
                            using (InflaterInputStream decompressStream = new InflaterInputStream(pixelDataMemoryStream))
                            {
                                byte[] decompressedPixelData = decompressStream.ReadFully();
                                pixelData = decompressedPixelData;
                            }
                        }
                        catch (SharpZipBaseException ex)
                        {
                            throw new NpkException(string.Format("Inflate error: {0}", ex.Message), ex);
                        }
                    }
                }

                pixelData = ExpandPixelData(pixelData, frameData);

                return new Image(pixelData, frameData);
            }
            catch (EndOfStreamException ex)
            {
                throw new NpkException("Unexpected end of file.", ex);
            }
        }