public static Texture ReadTexture(ChunkReader reader, TextureType type)
        {
            var tex			= new Texture(type);
            var header_size = reader.ReadUInt16();
            using (var headerReader = reader.GetSubChunk(header_size))
            {
                // ordinal string
                tex.ord = headerReader.ReadString();

                // process subchunks as they're encountered
                while (headerReader.BytesLeft > 0)
                {
                    var subchunk_id		= headerReader.ReadID<TextureDataType>();
                    var subchunk_size	= headerReader.ReadUInt16();
                    subchunk_size += (ushort)(subchunk_size & 1);
                    using (var subChunkReader = headerReader.GetSubChunk(subchunk_size))
                    {
                        switch (subchunk_id)
                        {
                            case TextureDataType.ID_CHAN:
                                tex.Channel = subChunkReader.ReadID<TextureChannel>();
                                break;

                            case TextureDataType.ID_OPAC:
                                tex.opac_type = subChunkReader.ReadUInt16();
                                tex.opacity.value = subChunkReader.ReadSingle();
                                tex.opacity.envelope_index = subChunkReader.ReadVariableLengthIndex();
                                break;

                            case TextureDataType.ID_ENAB:
                                tex.enabled = subChunkReader.ReadUInt16();
                                break;

                            case TextureDataType.ID_NEGA:
                                tex.negative = subChunkReader.ReadUInt16();
                                break;

                            case TextureDataType.ID_AXIS:
                                tex.axis = subChunkReader.ReadUInt16();
                                break;

                            default:
                                Console.WriteLine("Unknown texture header type " + reader.GetIDString((uint)subchunk_id));
                                break;
                        }
                    }
                }
            }

            if (reader.BytesLeft > 0)
            {
                using (var blockReader = reader.GetSubChunk((uint)reader.BytesLeft))
                {
                    switch (type)
                    {
                        case TextureType.ID_IMAP: tex.ReadImageMap(blockReader); break;
                        case TextureType.ID_PROC: tex.ReadProcedural(blockReader); break;
                        case TextureType.ID_GRAD: tex.ReadGradient(blockReader); break;
                        default:
                            Console.WriteLine("Unknown texture type " + reader.GetIDString((uint)type));
                            break;
                    }
                }
            }
            return tex;
        }
        //======================================================================
        // ParseTexture()
        //
        // Create a new texture for BTEX, CTEX, etc. subchunks.
        //======================================================================
        static Texture ParseTexture(string src)
        {
            var pos = src.IndexOf("Image Map");
            if (pos != -1)
            {
                var tex = new Texture(TextureType.ID_IMAP);

                if		(src.Contains("Planar"))		tex.imap.projection = ProjectionType.PROJ_PLANAR;
                else if (src.Contains("Cylindrical"))	tex.imap.projection = ProjectionType.PROJ_CYLINDRICAL;
                else if (src.Contains("Spherical"))		tex.imap.projection = ProjectionType.PROJ_SPHERICAL;
                else if (src.Contains("Cubic"))			tex.imap.projection = ProjectionType.PROJ_CUBIC;
                else if (src.Contains("Front"))			tex.imap.projection = ProjectionType.PROJ_FRONT;
                tex.imap.aa_strength = 1.0f;
                tex.imap.amplitude.value = 1.0f;
                return tex;
            } else
            {
                var tex = new Texture(TextureType.ID_PROC);
                tex.proc.name = src;
                return tex;
            }
        }