public IList <ImageInfo> Load(Stream input) { using var br = new BinaryReaderX(input); // Read header var header = br.ReadType <CtxbHeader>(); // Read chunks input.Position = header.chunkOffset; var chunks = br.ReadMultiple <CtxbChunk>((int)header.chunkCount); // Read images var infos = new List <ImageInfo>(); for (var i = 0; i < chunks.Count; i++) { foreach (var texture in chunks[i].textures) { var format = (texture.dataType << 16) | texture.imageFormat; input.Position = header.texDataOffset + texture.dataOffset; var imageInfo = new CtxbImageInfo(br.ReadBytes(texture.dataLength), format, new Size(texture.width, texture.height), i, texture) { Name = texture.name }; imageInfo.RemapPixels.With(context => new CtrSwizzle(context)); infos.Add(imageInfo); } } return(infos); }
public IList <ImageInfo> Load(Stream input) { using var br = new BinaryReaderX(input); // Read header var header = br.ReadType <CtxbHeader>(); // Read chunks input.Position = header.chunkOffset; var chunks = br.ReadMultiple <CtxbChunk>((int)header.chunkCount); // Read images var infos = new List <ImageInfo>(); for (var i = 0; i < chunks.Count; i++) { foreach (var texture in chunks[i].textures) { input.Position = header.texDataOffset + texture.dataOffset; // imageFormat is ignored if ETC1(a4) var format = texture.isETC1 ? texture.imageFormat : (texture.dataType << 16) | texture.imageFormat; var bitDepth = CtxbSupport.CtxbFormats[(uint)format].BitDepth; var dataLength = texture.width * texture.height * bitDepth / 8; var imageData = br.ReadBytes(dataLength); // Read mip maps var mipMaps = new byte[texture.mipLvl - 1][]; for (var j = 1; j < texture.mipLvl; j++) { mipMaps[j - 1] = br.ReadBytes((texture.width >> j) * (texture.width >> j) * bitDepth / 8); } var imageInfo = new CtxbImageInfo(imageData, format, new Size(texture.width, texture.height), i, texture) { MipMapData = mipMaps, Name = texture.name, }; imageInfo.RemapPixels.With(context => new CtrSwizzle(context)); infos.Add(imageInfo); } } return(infos); }