public TextureBundle(BinaryReader reader, SceGxtHeader header, SceGxtTextureInfo info) { reader.BaseStream.Seek(info.DataOffset, SeekOrigin.Begin); Width = info.GetWidth(); Height = info.GetHeight(); PaletteIndex = info.PaletteIndex; RawLineSize = (int)(info.DataSize / info.GetHeightRounded()); TextureFormat = info.GetTextureFormat(); RoundedWidth = info.GetWidthRounded(); RoundedHeight = info.GetHeightRounded(); if (!PixelDataProviders.PixelFormatMap.ContainsKey(TextureFormat) || !PixelDataProviders.ProviderFunctions.ContainsKey(TextureFormat)) { throw new FormatNotImplementedException(TextureFormat); } PixelFormat = PixelDataProviders.PixelFormatMap[TextureFormat]; PixelData = PixelDataProviders.ProviderFunctions[TextureFormat](reader, info); SceGxmTextureBaseFormat textureBaseFormat = info.GetTextureBaseFormat(); // TODO: is this right? PVRTC/PVRTC2 doesn't need this, but everything else does? if (textureBaseFormat != SceGxmTextureBaseFormat.PVRT2BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRT4BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRTII2BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRTII4BPP) { SceGxmTextureType textureType = info.GetTextureType(); switch (textureType) { case SceGxmTextureType.Linear: // Nothing to be done! break; case SceGxmTextureType.Tiled: // TODO: verify me! PixelData = PostProcessing.UntileTexture(PixelData, info.GetWidthRounded(), info.GetHeightRounded(), PixelFormat); break; case SceGxmTextureType.Swizzled: case SceGxmTextureType.Cube: // TODO: is cube really the same as swizzled? seems that way from CS' *env* files... PixelData = PostProcessing.UnswizzleTexture(PixelData, info.GetWidthRounded(), info.GetHeightRounded(), PixelFormat); break; case (SceGxmTextureType)0xA0000000: // TODO: mehhhhh PixelData = PostProcessing.UnswizzleTexture(PixelData, info.GetWidthRounded(), info.GetHeightRounded(), PixelFormat); break; default: throw new TypeNotImplementedException(textureType); } } }
public static byte[] Decompress(BinaryReader reader, SceGxtTextureInfo info) { byte[] pixelData = new byte[info.DataSize * 8]; int pixelOffset = 0; for (int y = 0; y < info.GetHeightRounded(); y += 4) { for (int x = 0; x < info.GetWidthRounded(); x += 4) { byte[] decodedBlock = DecompressDxtBlock(reader, info.GetTextureBaseFormat()); for (int b = 0; b < dxtOrder.Length; b++) { Buffer.BlockCopy(decodedBlock, b * 4, pixelData, pixelOffset + (dxtOrder[b] * 4), 4); } pixelOffset += decodedBlock.Length; } } return(pixelData); }
private Bitmap CreateBitmap(int infoIdx, int forcePaletteIdx = -1) { SceGxtTextureInfo info = TextureInfos[infoIdx]; ImageBinary imageBinary = new ImageBinary(); imageBinary.Width = info.GetWidth(); imageBinary.Height = info.GetHeight(); imageBinary.InputPixelFormat = PSVita.GetPixelDataFormat(info.GetTextureFormat()); imageBinary.InputEndianness = Endian.LittleEndian; imageBinary.AddInputPixels(PixelData[infoIdx]); // TODO: verify all this crap, GXT conversion wrt image [dimension/format/type] is fragile as all hell SceGxmTextureBaseFormat textureBaseFormat = info.GetTextureBaseFormat(); SceGxmTextureType textureType = info.GetTextureType(); if (textureType == SceGxmTextureType.Linear && textureBaseFormat != SceGxmTextureBaseFormat.UBC1 && textureBaseFormat != SceGxmTextureBaseFormat.UBC2 && textureBaseFormat != SceGxmTextureBaseFormat.UBC3 && textureBaseFormat != SceGxmTextureBaseFormat.PVRT2BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRT4BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRTII2BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRTII4BPP) { imageBinary.PhysicalWidth = (int)(((info.DataSize / imageBinary.Height) * 8) / PSVita.GetBitsPerPixel(textureBaseFormat)); imageBinary.PhysicalHeight = info.GetHeight(); } else { imageBinary.PhysicalWidth = info.GetWidthRounded(); imageBinary.PhysicalHeight = info.GetHeightRounded(); } if (textureBaseFormat != SceGxmTextureBaseFormat.PVRT2BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRT4BPP) { switch (textureType) { case SceGxmTextureType.Linear: // Nothing to be done! break; case SceGxmTextureType.Tiled: // TODO: verify me! imageBinary.InputPixelFormat |= PixelDataFormat.PixelOrderingTiled3DS; break; case SceGxmTextureType.Swizzled: case SceGxmTextureType.Cube: // TODO: is cube really the same as swizzled? seems that way from CS' *env* files... imageBinary.InputPixelFormat |= PixelDataFormat.PixelOrderingSwizzledVita; break; case (SceGxmTextureType)0xA0000000: // TODO: this is odd and needs investigation, found ex. in Odin Sphere, Puyo Puyo Tetris, ... imageBinary.InputPixelFormat |= PixelDataFormat.PixelOrderingSwizzledVita; break; } } if (textureBaseFormat == SceGxmTextureBaseFormat.P4 || textureBaseFormat == SceGxmTextureBaseFormat.P8) { imageBinary.InputPaletteFormat = PSVita.GetPaletteFormat(info.GetTextureFormat()); if (textureBaseFormat == SceGxmTextureBaseFormat.P4) { foreach (byte[] paletteData in P4Palettes) { imageBinary.AddInputPalette(paletteData); } } else if (textureBaseFormat == SceGxmTextureBaseFormat.P8) { foreach (byte[] paletteData in P8Palettes) { imageBinary.AddInputPalette(paletteData); } } } return(imageBinary.GetBitmap(0, forcePaletteIdx != -1 ? forcePaletteIdx : info.PaletteIndex)); }