public override void Read(BinaryReader br, List <AoWBitmap> imageList)
        {
            // length of this header
            UInt32 dword = br.ReadUInt32();

            if (dword != length)
            {
                throw new Exception(string.Format("Wrong header v3 length ({0})", dword));
            }

            numPalette = br.ReadUInt32();
            Debug.Assert(numPalette == 0);

            // read info data
            AoWBitmap model = PersistentData.Data.AoW1Default;
            AoWBitmap elem  = null;

            while (true)
            {
                elem = new AoW1Bitmap(model);
                if (!elem.ReadImageInfo(br))
                {
                    // End description section
                    Debug.Assert(elem.ImageNumber == -1);                     // 0xFFFFFFFF);
                    break;
                }
                // be sure there is enough space
                while (elem.ImageNumber >= imageList.Count)
                {
                    imageList.Add(null);
                }
                imageList[elem.ImageNumber] = elem;
            }
            // no ReadImageData, because header v3 should have no distinct sections
        }
        }         // end ReadImageData

        public override bool WriteImage(BinaryWriter infoStream, BinaryWriter imageStream)
        {
            // write the unique image number
            infoStream.Write((UInt32)_imageNumber);
            // if composite, write 0x100
            if (_subImageList.Count > 0)
            {
                infoStream.Write(0x100u);
            }

            WriteImageData(imageStream);
            WriteImageInfo(infoStream);

            if (_subImageList.Count > 0)
            {
                // if there are sub images, then write their data too
                foreach (AoWBitmap elem in _subImageList)
                {
                    AoW1Bitmap elem1 = (AoW1Bitmap)elem;
                    elem1.WriteImageData(imageStream);
                    elem1.WriteImageInfo(infoStream);
                }

                // write end of composite sequence
                infoStream.Write(0x0u);
            }
            // Write end , always -1
            infoStream.Write(0xFFFFFFFFu);

            return(true);
        }         // end WriteToStreams
        public override void Read(BinaryReader br, List <AoWBitmap> imageList)
        {
            // length of this header
            UInt32 dword = br.ReadUInt32();

            if (dword != length)
            {
                throw new Exception(string.Format("Wrong header v4 length ({0})", dword));
            }

            imageDataOffset = br.ReadUInt32();
            ilbFileSize     = br.ReadUInt32();
            Trace.WriteLine(string.Format("Ilb File Size {0}", ilbFileSize));

            numPalette = br.ReadUInt32();
            List <ColorPalette> palettes = new List <ColorPalette>();

            for (UInt32 i = 0; i < numPalette; ++i)
            {
                palettes.Add(ReadPalette(br));
            }
            Trace.WriteLine(string.Format("Read {0} palettes", palettes.Count));
            // Logger.LogMessage(MsgLevel.DEBUG, string.Format("Ilb contains {0} palettes", palettes.Count));
            Debug.WriteLine(string.Format("Ilb contains {0} palettes", palettes.Count));

            // read info data
            AoWBitmap model = PersistentData.Data.AoW1Default;

            AoWBitmap elem = null;

            while (true)
            {
                elem = new AoW1Bitmap(model);
                if (!elem.ReadImageInfo(br))
                {
                    // End description section
                    if (elem.ImageNumber == -1)                     // 0xFFFFFFFF);
                    {
                        break;
                    }
                    else
                    {
                        // read a blank image probably
                        br.ReadUInt32();                         // throw away next dword
                        continue;
                    }
                }
                // be sure there is enough space
                while (elem.ImageNumber >= imageList.Count)
                {
                    imageList.Add(null);
                }
                imageList[elem.ImageNumber] = elem;
            }

            foreach (AoWBitmap elem1 in imageList)
            {
                if (elem1 != null)
                {
                    elem1.ReadImageData(br, palettes);
                }
            }
        }
        protected bool ReadImageInfoMain(BinaryReader br)
        {
            bool isComposite = false;
            // Read image type:
            UInt32 dword = br.ReadUInt32();

            if (dword == 0x100)
            {
                isComposite = true;
                Trace.WriteLine("Found a composite image");
                //Logger.LogMessage(MsgLevel.DEBUG, "Found a composite image");
                Debug.WriteLine("Found a composite image");
                dword = br.ReadUInt32();
            }
            else if (dword == 0x0)
            {
                Trace.WriteLine(string.Format("Found end of composite image ({0})", _imageNumber));
                // Logger.LogMessage(MsgLevel.DEBUG, string.Format("Found end of composite image ({0})", _imageNumber));
                Debug.WriteLine(string.Format("Found end of composite image ({0})", _imageNumber));
                _imageNumber = 0;
                return(false);
            }

            switch (dword)
            {
            case 0x01: _imageType = AoWImageType.Type01_Picture08_0x01;             break;

            case 0x02: _imageType = AoWImageType.Type02_RLESprite08_0x02;   break;

            case 0x03: _imageType = AoWImageType.Type03_Sprite08_0x03;              break;

            case 0x10: _imageType = AoWImageType.Type16_Picture16_0x10;             break;

            case 0x11: _imageType = AoWImageType.Type17_RLESprite16_0x11;   break;

            case 0x12: _imageType = AoWImageType.Type18_TransparentRLESprite16_0x12; break;

            case 0x16: _imageType = AoWImageType.Type22_Sprite16_0x16;              break;

            default:
                throw new Exception(string.Format("Found unsupported type of image (0x{0:X})", dword));
            }

            // Read record format:
            byte subId = br.ReadByte();

            switch (subId)
            {
            // convert subtype 1 to 2
            case 1: _subType = AoWImageSubType.SubType02; break;

            case 2: _subType = AoWImageSubType.SubType02; break;

            case 3: _subType = AoWImageSubType.SubType03; break;

            default:
                throw new Exception(string.Format("Found unsupported subtype (0x{0:X}) of image {1}", subId, _imageNumber));
            }

            // Read bitmap filename:
            dword = br.ReadUInt32();
            StringBuilder strb = new StringBuilder();

            for (UInt32 i = 0; i < dword; ++i)
            {
                strb.Append((char)br.ReadSByte());
            }
            _name = strb.ToString();

            // Read image size:
            _cX = br.ReadInt32();
            _cY = br.ReadInt32();

            // Read image offset:
            _xShift = br.ReadInt32();
            _yShift = br.ReadInt32();

            // Read instance number:
            _instanceNumber = br.ReadInt32();

            /*Logger.LogMessage(MsgLevel.DEBUG,
             *      string.Format("Image {0}({1}): '{2}', {3}, sub {4}, {5}x{6}", _imageNumber, _instanceNumber, _name, _imageType, subId, _cX, _cY));*/
            Debug.WriteLine(string.Format("Image {0}({1}): '{2}', {3}, sub {4}, {5}x{6}", _imageNumber, _instanceNumber, _name, _imageType, subId, _cX, _cY));

            // Read LoadMode byte:
            dword = br.ReadByte();
            switch (dword)
            {
            case 0: _loadMode = AoWLoadMode.lmInstant; break;

            case 1: _loadMode = AoWLoadMode.lmWhenUsed; break;

            case 2: _loadMode = AoWLoadMode.lmOnDemand; break;

            case 3: _loadMode = AoWLoadMode.lmWhenReferenced; break;

            default: _loadMode = AoWLoadMode.lmWhenUsed; break;
            }

            // Read image data size:
            _imageDataSize = br.ReadInt32();
            if (_imageDataSize < 0)
            {
                throw new Exception(string.Format("Invalid data size of image {0})", _imageNumber));
            }

            // Read image data offset:
            // Not here if InfoByte is 1
            if (subId != 1)
            {
                dword = br.ReadUInt32();                 // I think I'll not use it
            }
            // Read image size again:
            dword = br.ReadUInt32();
            //Debug.Assert((int)dword == _cX + _xShift);
            dword = br.ReadUInt32();
            //Debug.Assert((int)dword == _cY + _yShift);

            if (Is8bpp())
            {
                // Read unknownB byte:
                dword = br.ReadByte();
                Trace.WriteLine(string.Format("unknownB (0x{0:X})of image {1}", dword, _imageNumber));

                if (_subType == AoWImageSubType.SubType03)
                {
                    // Read unknownC int:
                    dword = br.ReadUInt32();
                    Trace.WriteLine(string.Format("unknownC (0x{0:X})of image {1}", dword, _imageNumber));
                    // Read unknownD int:
                    dword = br.ReadUInt32();
                    Trace.WriteLine(string.Format("unknownD (0x{0:X})of image {1}", dword, _imageNumber));
                }
            }
            else
            {
                if (_subType == AoWImageSubType.SubType03)
                {
                    // Read drawMode:
                    UInt32 drawMode = br.ReadUInt32();
                    // Read blendValue:
                    _blendValue = br.ReadInt32();

                    UInt32 showMode  = drawMode & 0x000000FF;
                    UInt32 blendMode = (drawMode & 0x0000FF00) >> 8;
                    switch (showMode)
                    {
                    case 0x0: _showMode = AoWShowMode.smOpaque; break;

                    case 0x1: _showMode = AoWShowMode.smTransparent; break;

                    case 0x2: _showMode = AoWShowMode.smBlended; break;

                    default:
                        throw new Exception(string.Format("Invalid ShowMode 0x{0:X} of image {1})", showMode, _imageNumber));
                    }
                    switch (blendMode)
                    {
                    case 0x0: _blendMode = AoWBlendMode.bmUser; break;

                    case 0x1: _blendMode = AoWBlendMode.bmAlpha; break;

                    case 0x2: _blendMode = AoWBlendMode.bmBrighten; break;

                    case 0x3: _blendMode = AoWBlendMode.bmIntensity; break;

                    case 0x4: _blendMode = AoWBlendMode.bmShadow; break;

                    case 0x5: _blendMode = AoWBlendMode.bmLinearAlpha; break;
                    }
                }
            }
            if (Is8bpp())
            {
                // Read palette index
                if (subId != 1)
                {
                    _numPalette = br.ReadInt32();
                }
            }
            else
            {
                // Read pixelFormat:
                dword = br.ReadUInt32();
                if (dword != 0x56509310u)
                {
                    throw new Exception(string.Format("Invalid PixelFormat 0x{0:X} of image {1})", dword, _imageNumber));
                }
            }

            // See if there should be a bounding box present.
            switch (_imageType)
            {
            case AoWImageType.Type02_RLESprite08_0x02:
            case AoWImageType.Type03_Sprite08_0x03:
            case AoWImageType.Type17_RLESprite16_0x11:
            case AoWImageType.Type18_TransparentRLESprite16_0x12:
            case AoWImageType.Type22_Sprite16_0x16:
            {
                // Read bounding box:
                Int32 bbWidth   = br.ReadInt32();
                Int32 bbHeight  = br.ReadInt32();
                Int32 bbXOffset = br.ReadInt32();
                Int32 bbYOffset = br.ReadInt32();
                _boundingBox.Set(bbYOffset, bbXOffset, bbWidth + bbXOffset - 1, bbHeight + bbYOffset - 1);

                // Read background colour
                _originalBackgroundColour = br.ReadUInt32();                                 //RGB565 or index
            }
            break;
            }

            // See if there should be clip_x
            switch (_imageType)
            {
            case AoWImageType.Type02_RLESprite08_0x02:
                // Read clip_x, seem useless, set to 0
                dword = br.ReadUInt32();
                Trace.WriteLine(string.Format("clip_x (0x{0:X})of image {1}", dword, _imageNumber));
                break;

            case AoWImageType.Type17_RLESprite16_0x11:
            case AoWImageType.Type18_TransparentRLESprite16_0x12:
            {
                dword = br.ReadUInt32();
                switch (dword)
                {
                case 0: _clipXHack = AoWClipXHack.None; break;

                //case AoW1Constants.clip_X_Structure:	_clipXHack = AoWClipXHack.AsStructure; break;
                //case AoW1Constants.clip_X_Mountain:	_clipXHack = AoWClipXHack.AsMountain; break;
                case AoW1Constants.clip_X_Item:                 _clipXHack = AoWClipXHack.AsItem; break;

                case AoW1Constants.clip_X_ShieldsM:             _clipXHack = AoWClipXHack.AsShieldsM; break;

                case AoW1Constants.clip_X_TCMap:                _clipXHack = AoWClipXHack.AsTCMap; break;

                default:
                    _clipXHack = AoWClipXHack.None;
                    // Logger.LogMessage( MsgLevel.DEBUG, string.Format("unknown clip_x (0x{0:X8})of image {1}", dword, _imageNumber));
                    Debug.WriteLine(string.Format("unknown clip_x (0x{0:X8})of image {1}", dword, _imageNumber));
                    break;
                }
            }
            break;
            }

            // Read image data if subtype == 1
            if (subId == 1)
            {
                List <ColorPalette> palettes = null;
                if (Is8bpp())
                {
                    // I think there should be the palette
                    palettes = new List <ColorPalette>();
                    palettes.Add(AoW1Header.ReadPalette(br));
                }
                ReadImageData(br, palettes);
            }

            if (isComposite)
            {
                // read composite images
                // read info data
                AoW1Bitmap elem = null;
                while (true)
                {
                    elem             = new AoW1Bitmap();
                    elem.ImageNumber = _imageNumber;
                    if (!elem.ReadImageInfoMain(br))
                    {
                        // End composite section
                        Debug.Assert(elem.ImageNumber == 0);
                        break;
                    }
                    _subImageList.Add(elem);
                }
            }

            return(true);
        }         // end ReadImageInfo
Пример #5
0
        public override bool OpenIlb(string fileName, List <AoWBitmap> imageList)
        {
            using (FileStream fs = File.OpenRead(fileName))
            {
                BinaryReader br = new BinaryReader(fs);

                // first byte is the number of following word infos
                UInt32 wordFields = br.ReadByte();
                // the format of this header is weird:
                // because the choose to use word,
                // they may be too little to store address offset so dwords may be required.
                // In this case wordFields is 0x8n, and an additional dword follows
                // to specify the number of dword*2 infos
                UInt32 dwordFields = 0;
                if (wordFields > 0x80)
                {
                    wordFields -= 0x80;
                    dwordFields = br.ReadUInt32();
                }

                // the infos are made by two fields
                // 1 - an id
                // 2 - the offset you find their data AFTER this list of info
                SortedList <UInt32, UInt32> infoMap = new SortedList <UInt32, UInt32>();

                // Store them in a container
                for (int i = 0; i < wordFields; ++i)
                {
                    UInt32 id = br.ReadByte();
                    infoMap.Add(id, br.ReadByte());
                }
                for (int i = 0; i < dwordFields; ++i)
                {
                    UInt32 id = br.ReadUInt32();
                    infoMap.Add(id, br.ReadUInt32());
                }

                /*
                 * 0x0A ???
                 * 0x0B max number of elements - dword
                 * 0x0C palettes		-  ?
                 * 0x32+ image header	- vary
                 */
                if (infoMap.ContainsKey(0x0A))
                {
                    UInt32 unknown = br.ReadUInt32();
                    infoMap.Remove(0x0A);
                }

                // read the max number of elements
                // The images may have discontinued id (i.e.: 0 - 1 -3 - 5)
                // so the length of the list that should contain them all
                // should be large to contains gap,
                // then the max is the following dword
                if (infoMap.ContainsKey(0x0B))
                {
                    UInt32 lastElemNumber = br.ReadUInt32();
                    infoMap.Remove(0x0B);
                }

                List <ColorPalette> palettes = new List <ColorPalette>();
                if (infoMap.ContainsKey(0x0C))
                {
                    // read unknown data
                    // For now I've no clue on meaning of interposed data,
                    // but should be the palettes
                    UInt32 unknownLength = infoMap.Values[1] - infoMap[0x0C];
                    br.ReadBytes(0x6);                     // seem useless
                    UInt32 numPalette = br.ReadByte();
                    for (UInt32 i = 0; i < numPalette; ++i)
                    {
                        br.ReadBytes(0xF);                         // seem useless
                        palettes.Add(AoW1Header.ReadPalette(br));
                    }
                    infoMap.Remove(0x0C);
                }

                // read image headers
                AoWBitmap model = PersistentData.Data.AoW1Default;

                foreach (UInt32 id in infoMap.Keys)
                {
                    AoWBitmap elem = new AoW2Bitmap(model);
                    elem.ImageNumber = (int)(id - 0x32u);
                    if (!elem.ReadImageInfo(br))
                    {
                        Debug.Assert(false);
                    }
                    // be sure there is enough space
                    while (elem.ImageNumber >= imageList.Count)
                    {
                        imageList.Add(null);
                    }
                    imageList[elem.ImageNumber] = elem;
                }

                // read image data
                long startOffset = br.BaseStream.Position;
                foreach (AoW2Bitmap elem in imageList)
                {
                    if (elem != null)
                    {
                        if (br.BaseStream.Position != startOffset + (long)elem.ImageOffset)
                        {
                            br.BaseStream.Position = startOffset + (long)elem.ImageOffset;
                        }
                        elem.ReadImageData(br, palettes);
                    }
                }

                // now convert to AoW1 Type
                for (int i = 0; i < imageList.Count; ++i)
                {
                    AoW2Bitmap elem = (AoW2Bitmap)imageList[i];
                    if (elem != null)
                    {
                        // the copy constructor make all the works
                        imageList[i] = new AoW1Bitmap(elem);
                        elem.Dispose();
                    }
                }
            }
            return(true);
        }         // end OpenIlb