Esempio n. 1
0
        public void Deserialise(System.IO.Stream inStr, int xiExpectedDataSize)
        {
            long lStartOffset = xiExpectedDataSize >= 0 ? inStr.Position : -1;

              // magic number
              BinaryReader bin = new BinaryReader(inStr);
              int lTIMMagicNumber = bin.ReadInt32();
              if (TIM_MAGIC_NUMBER != lTIMMagicNumber)
              {
            throw new DeserialisationException(string.Format("TIM should start with 4 byte magic number 0x10, found 0x{0:x}", lTIMMagicNumber), inStr.Position - 4);
              }

              // bits per pixel
              BPP = (TimBPP)bin.ReadInt32();
              if (BPP != TimBPP._4BPP
            && BPP != TimBPP._8BPP
            && BPP != TimBPP._16BPP)
              {
            throw new TIMTypeNotImplementedException(string.Format("Only 4BPP, 8BPP or 16BPP TIMs are supported. Found 0x{0:x} BPP type", BPP), inStr.Position - 8);
              }

              if (BPP != TimBPP._16BPP)
              {
            // Now the palette header:
            ClutSize = bin.ReadInt32();
            PaletteOrgX = bin.ReadInt16();
            PaletteOrgY = bin.ReadInt16();
            ClutColors = bin.ReadInt16();
            ClutCount = bin.ReadInt16();

            //sanity checks
            if (ClutCount * ClutColors * 2 != ClutSize - 12)
              throw new DeserialisationException("bad TIM: ClutCount*ClutColors*2 != ClutSize - 12", inStr.Position);

            //TODO:
            if (ClutCount != 1)
              throw new DeserialisationException("Multi-clut TIMs are not yet supported. Please extend TIMChunk.cs using info from timgfx.txt");

            //CLUT:
            Palette = new short[ClutCount * ClutColors];
            for (int i = 0; i < Palette.Length; i++)
            {
              Palette[i] = bin.ReadInt16();
            }
              }

              //colour count
              int lPixelsPerTwoBytes;
              switch (BPP)
              {
            case TimBPP._4BPP:
              if (ClutColors != 16) throw new DeserialisationException("bad TIM: ClutColors != 16, but BPP == 4", inStr.Position);
              lPixelsPerTwoBytes = 4;
              break;
            case TimBPP._8BPP:
              if (ClutColors != 256) throw new DeserialisationException("bad TIM: ClutColors != 256, but BPP == 8", inStr.Position);
              lPixelsPerTwoBytes = 2;
              break;
            case TimBPP._16BPP:
              if (ClutColors != 0) throw new DeserialisationException("bad TIM: ClutColors != 0, but BPP == 16", inStr.Position);
              lPixelsPerTwoBytes = 1;
              break;
            default: throw new Exception("unreachable case");
              }

              //Second header:
              ImageDataSize = bin.ReadInt32();
              ImageOrgX = bin.ReadInt16();
              ImageOrgY = bin.ReadInt16();
              //short * short is int !?!
              ImageWidth = (short)(lPixelsPerTwoBytes * bin.ReadInt16());
              ImageHeight = bin.ReadInt16();

              //sanity checks
              //some observed TIMs fail this check:
              if (ImageWidth * ImageHeight / lPixelsPerTwoBytes * 2 != ImageDataSize - 12)
              {
            //throw new DeserialisationException
            System.Diagnostics.Trace.WriteLine(string.Format("bad TIM: ImageWidth * ImageHeight / PixelsPerByte != ImageDataSize - 12, near {0}", inStr.Position));
              }

              //read the image data
              ImageData = bin.ReadBytes(ImageWidth * ImageHeight / lPixelsPerTwoBytes * 2);

              if (xiExpectedDataSize >= 0)
              {
            long lObservedSize = inStr.Position - lStartOffset;
            if (lObservedSize < xiExpectedDataSize)
            {
              ZeroPadding = bin.ReadBytes((int)(xiExpectedDataSize - lObservedSize));
              foreach (byte b in ZeroPadding)
            if (b != 0)
              throw new DeserialisationException(string.Format("Non zero value found in zero-padding section: {0}", b), inStr.Position);
            }
            else if (lObservedSize > xiExpectedDataSize)
            {
              throw new DeserialisationException(string.Format("Expected TIM datasize was {0}, found {1}", xiExpectedDataSize, lObservedSize));
            }
              }
        }
Esempio n. 2
0
        public void Deserialise(System.IO.Stream inStr, int xiExpectedDataSize)
        {
            long lStartOffset = xiExpectedDataSize >= 0 ? inStr.Position : -1;

            // magic number
            BinaryReader bin             = new BinaryReader(inStr);
            int          lTIMMagicNumber = bin.ReadInt32();

            if (TIM_MAGIC_NUMBER != lTIMMagicNumber)
            {
                throw new DeserialisationException(string.Format("TIM should start with 4 byte magic number 0x10, found 0x{0:x}", lTIMMagicNumber), inStr.Position - 4);
            }

            // bits per pixel
            BPP = (TimBPP)bin.ReadInt32();
            if (BPP != TimBPP._4BPP &&
                BPP != TimBPP._8BPP &&
                BPP != TimBPP._16BPP)
            {
                throw new TIMTypeNotImplementedException(string.Format("Only 4BPP, 8BPP or 16BPP TIMs are supported. Found 0x{0:x} BPP type", BPP), inStr.Position - 8);
            }

            if (BPP != TimBPP._16BPP)
            {
                // Now the palette header:
                ClutSize    = bin.ReadInt32();
                PaletteOrgX = bin.ReadInt16();
                PaletteOrgY = bin.ReadInt16();
                ClutColors  = bin.ReadInt16();
                ClutCount   = bin.ReadInt16();

                //sanity checks
                if (ClutCount * ClutColors * 2 != ClutSize - 12)
                {
                    throw new DeserialisationException("bad TIM: ClutCount*ClutColors*2 != ClutSize - 12", inStr.Position);
                }

                //TODO:
                if (ClutCount != 1)
                {
                    throw new DeserialisationException("Multi-clut TIMs are not yet supported. Please extend TIMChunk.cs using info from timgfx.txt");
                }

                //CLUT:
                Palette = new short[ClutCount * ClutColors];
                for (int i = 0; i < Palette.Length; i++)
                {
                    Palette[i] = bin.ReadInt16();
                }
            }

            //colour count
            int lPixelsPerTwoBytes;

            switch (BPP)
            {
            case TimBPP._4BPP:
                if (ClutColors != 16)
                {
                    throw new DeserialisationException("bad TIM: ClutColors != 16, but BPP == 4", inStr.Position);
                }
                lPixelsPerTwoBytes = 4;
                break;

            case TimBPP._8BPP:
                if (ClutColors != 256)
                {
                    throw new DeserialisationException("bad TIM: ClutColors != 256, but BPP == 8", inStr.Position);
                }
                lPixelsPerTwoBytes = 2;
                break;

            case TimBPP._16BPP:
                if (ClutColors != 0)
                {
                    throw new DeserialisationException("bad TIM: ClutColors != 0, but BPP == 16", inStr.Position);
                }
                lPixelsPerTwoBytes = 1;
                break;

            default: throw new Exception("unreachable case");
            }

            //Second header:
            ImageDataSize = bin.ReadInt32();
            ImageOrgX     = bin.ReadInt16();
            ImageOrgY     = bin.ReadInt16();
            //short * short is int !?!
            ImageWidth  = (short)(lPixelsPerTwoBytes * bin.ReadInt16());
            ImageHeight = bin.ReadInt16();

            //sanity checks
            //some observed TIMs fail this check:
            if (ImageWidth * ImageHeight / lPixelsPerTwoBytes * 2 != ImageDataSize - 12)
            {
                //throw new DeserialisationException
                System.Diagnostics.Trace.WriteLine(string.Format("bad TIM: ImageWidth * ImageHeight / PixelsPerByte != ImageDataSize - 12, near {0}", inStr.Position));
            }

            //read the image data
            ImageData = bin.ReadBytes(ImageWidth * ImageHeight / lPixelsPerTwoBytes * 2);

            if (xiExpectedDataSize >= 0)
            {
                long lObservedSize = inStr.Position - lStartOffset;
                if (lObservedSize < xiExpectedDataSize)
                {
                    ZeroPadding = bin.ReadBytes((int)(xiExpectedDataSize - lObservedSize));
                    foreach (byte b in ZeroPadding)
                    {
                        if (b != 0)
                        {
                            throw new DeserialisationException(string.Format("Non zero value found in zero-padding section: {0}", b), inStr.Position);
                        }
                    }
                }
                else if (lObservedSize > xiExpectedDataSize)
                {
                    throw new DeserialisationException(string.Format("Expected TIM datasize was {0}, found {1}", xiExpectedDataSize, lObservedSize));
                }
            }
        }