Exemplo n.º 1
0
        private bool Initalize(Bitmap source, GimPaletteFormat paletteFormat, GimDataFormat dataFormat)
        {
            // Make sure this bitmap's dimensions are valid
            if (!HasValidDimensions(source.Width, source.Height))
            {
                return(false);
            }

            textureWidth  = (ushort)source.Width;
            textureHeight = (ushort)source.Height;

            // Set default values
            hasMetadata = true;
            metadata    = new GimMetadata();

            // Set the data format and palette format and load the appropiate codecs
            this.dataFormat = dataFormat;
            dataCodec       = GimDataCodec.GetDataCodec(dataFormat);

            // Make sure the data codec exists and we can encode to it
            if (dataCodec == null || !dataCodec.CanEncode)
            {
                return(false);
            }

            // Only palettized formats require a pixel codec.
            if (dataCodec.PaletteEntries != 0)
            {
                this.paletteFormat = paletteFormat;
                pixelCodec         = GimPixelCodec.GetPixelCodec(paletteFormat);

                // Make sure the pixel codec exists and we can encode to it
                if (pixelCodec == null || !pixelCodec.CanEncode)
                {
                    return(false);
                }

                dataCodec.PixelCodec = pixelCodec;

                // Convert the bitmap to an array containing indicies.
                decodedData = BitmapToRawIndexed(source, dataCodec.PaletteEntries, out texturePalette);
            }
            else
            {
                this.paletteFormat = GimPaletteFormat.Unknown;
                pixelCodec         = null;

                // Convert the bitmap to an array
                decodedData = BitmapToRaw(source);
            }

            return(true);
        }
Exemplo n.º 2
0
        private void Initalize()
        {
            // Check to see if what we are dealing with is a GIM texture
            if (!Is(encodedData))
            {
                throw new NotAValidTextureException("This is not a valid GIM texture.");
            }

            // Initalize some things
            paletteFormat = GimPaletteFormat.Unknown;
            dataFormat    = GimDataFormat.Unknown;

            paletteEntries = 0;
            paletteOffset  = -1;
            dataOffset     = -1;

            hasMetadata = false;

            // A GIM is constructed of different chunks. They do not necessarily have to be in order.
            int eofOffset = -1;

            int offset         = 0x10;
            int previousOffset = offset;

            while (offset < encodedData.Length)
            {
                // EOF offset chunk
                if (encodedData[offset] == 0x02)
                {
                    eofOffset = BitConverter.ToInt32(encodedData, offset + 0x04) + 16;

                    // Go to the next chunk
                    offset += BitConverter.ToInt32(encodedData, offset + 0x08);
                }

                // Metadata offset chunk
                else if (encodedData[offset] == 0x03)
                {
                    // Skip this chunk. It's not necessary for decoding this texture.
                    offset += BitConverter.ToInt32(encodedData, offset + 0x08);
                }

                // Texture data
                else if (encodedData[offset] == 0x04)
                {
                    // Get the data format
                    dataFormat = (GimDataFormat)encodedData[offset + 0x14];

                    // Get the data codec and make sure we can decode using it
                    dataCodec = GimDataCodec.GetDataCodec(dataFormat);

                    // Check to see if the texture data is swizzled
                    swizzled = (BitConverter.ToUInt16(encodedData, offset + 0x16) == 1);

                    // Get the texture's width and height
                    textureWidth  = BitConverter.ToUInt16(encodedData, offset + 0x18);
                    textureHeight = BitConverter.ToUInt16(encodedData, offset + 0x1A);

                    // Some textures do not have a width that is a multiple or 16 or a height that is a multiple of 8.
                    // We'll just do it the lazy way and set their width/height to a multiple of 16/8.
                    if (textureWidth % 16 != 0)
                    {
                        textureWidth = (ushort)PTMethods.RoundUp(textureWidth, 16);
                    }
                    if (textureHeight % 8 != 0)
                    {
                        textureHeight = (ushort)PTMethods.RoundUp(textureHeight, 8);
                    }

                    // Set the offset of the texture data
                    dataOffset = offset + 0x50;

                    // Go to the next chunk
                    offset += BitConverter.ToInt32(encodedData, offset + 0x08);
                }

                // Palette data
                else if (encodedData[offset] == 0x05)
                {
                    // Get the palette format
                    paletteFormat = (GimPaletteFormat)encodedData[offset + 0x14];

                    // Get the pixel codec and make sure we can decode using it
                    pixelCodec = GimPixelCodec.GetPixelCodec(paletteFormat);

                    // Get the number of entries in the palette
                    paletteEntries = BitConverter.ToUInt16(encodedData, offset + 0x18);

                    // Set the offset of the palette data
                    paletteOffset = offset + 0x50;

                    // Go to the next chunk
                    offset += BitConverter.ToInt32(encodedData, offset + 0x08);
                }

                // Metadata chunk
                else if (encodedData[offset] == 0xFF)
                {
                    // Read in some metadata
                    hasMetadata = true;
                    metadata    = new GimMetadata();

                    int metadataOffset = 0x10;

                    metadata.OriginalFilename = PTMethods.StringFromBytes(encodedData, offset + metadataOffset);
                    metadataOffset           += metadata.OriginalFilename.Length + 1;

                    metadata.User   = PTMethods.StringFromBytes(encodedData, offset + metadataOffset);
                    metadataOffset += metadata.User.Length + 1;

                    metadata.Timestamp = PTMethods.StringFromBytes(encodedData, offset + metadataOffset);
                    metadataOffset    += metadata.Timestamp.Length + 1;

                    metadata.Program = PTMethods.StringFromBytes(encodedData, offset + metadataOffset);
                    metadataOffset  += metadata.Program.Length + 1;

                    // Go to the next chunk
                    offset += BitConverter.ToInt32(encodedData, offset + 0x08);
                }

                // Invalid chunk
                else
                {
                    return;
                }

                // Make sure we are actually advancing in the file, so we don't end up reaching a negative offset
                // or ending up in an infinite loop
                if (offset <= previousOffset)
                {
                    return;
                }
                previousOffset = offset;
            }

            // If all went well, offset should be equal to eofOffset
            if (offset != eofOffset)
            {
                return;
            }

            // If this is a non-palettized format, make sure we have a data codec
            if (dataCodec != null && dataCodec.PaletteEntries == 0)
            {
                canDecode = true;
            }

            // If this is a palettized format, make sure we have a palette codec, a data codec,
            // and that the number of palette entires is less than or equal to what this data format supports
            if (dataCodec != null && dataCodec.PaletteEntries != 0 && pixelCodec != null && paletteEntries <= dataCodec.PaletteEntries)
            {
                // Set the data format's pixel codec
                dataCodec.PixelCodec = pixelCodec;

                canDecode = true;
            }

            initalized = true;
        }