protected override void Setup(DXTBlockWrapper <DXT5Block> pBlock) { base.Setup(pBlock); GetBlockColors(m_pBlock, m_colors, IsDXT1); var block = m_pBlock.Value.alpha; m_alphas[0] = block.alpha[0]; m_alphas[1] = block.alpha[1]; if (m_alphas[0] > m_alphas[1]) { // 8 alpha block for (var i = 0; i < 6; i++) { m_alphas[i + 2] = (uint)((6 - i) * m_alphas[0] + (1 + i) * m_alphas[1] + 3) / 7; } } else { // 6 alpha block for (var i = 0; i < 4; i++) { m_alphas[i + 2] = (uint)((4 - i) * m_alphas[0] + (1 + i) * m_alphas[1] + 2) / 5; } m_alphas[6] = 0; m_alphas[7] = 0xFF; } }
protected unsafe virtual void DecodeDXTBlock(byte *pbDst, DXTBlockWrapper <TBlock> block, int dstPitch, int bw, int bh) { Setup(block); for (var y = 0; y < bh; y++) { var dst = pbDst + y * dstPitch; SetY(y); for (var x = 0; x < bw; x++) { var color = GetColor(x, y); * dst = color.r; dst++; *dst = color.g; dst++; *dst = color.b; dst++; *dst = color.a; dst++; } } }
protected void GetBlockColors(DXTBlockWrapper <TBlock> block, Color8888[] colors, bool isDXT1) { int i; for (i = 0; i < 2; i++) { colors[i].a = 0xff; colors[i].r = (byte)(block.Colors[i].R * 0xff / 0x1f); colors[i].g = (byte)(block.Colors[i].G * 0xff / 0x3f); colors[i].b = (byte)(block.Colors[i].B * 0xff / 0x1f); } // WORD *wCol = (WORD *)block.colors; // if (wCol[0] > wCol[1] || !isDXT1) { if (block.Value.Color.colors[0].clr565 > block.Value.Color.colors[1].clr565 || !isDXT1) { // 4 color block for (i = 0; i < 2; i++) { colors[i + 2].a = 0xff; colors[i + 2].r = (byte)(((ushort)(colors[0].r) * (2 - i) + (ushort)(colors[1].r) * (1 + i)) / 3); colors[i + 2].g = (byte)(((ushort)(colors[0].g) * (2 - i) + (ushort)(colors[1].g) * (1 + i)) / 3); colors[i + 2].b = (byte)(((ushort)(colors[0].b) * (2 - i) + (ushort)(colors[1].b) * (1 + i)) / 3); } } else { // 3 color block, number 4 is transparent colors[2].a = 0xff; colors[2].r = (byte)(((ushort)(colors[0].r) + (ushort)(colors[1].r)) / 2); colors[2].g = (byte)(((ushort)(colors[0].g) + (ushort)(colors[1].g)) / 2); colors[2].b = (byte)(((ushort)(colors[0].b) + (ushort)(colors[1].b)) / 2); colors[3].a = 0x00; colors[3].g = 0x00; colors[3].b = 0x00; colors[3].r = 0x00; } }
public Bitmap Decode(DDSURFACEDESC2 desc, Stream stream) { var width = (int)desc.dwWidth & ~3; var height = (int)desc.dwHeight & ~3; // allocate a 32-bit dib var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); var bpp = 4; // bytes per pixel var line = width * bpp; var reader = new BinaryReader(stream); var blocks = new DXTBlockWrapper <TBlock> [(width + 3) / 4]; var widthRest = (int)width & 3; var heightRest = (int)height & 3; var inputLine = (width + 3) / 4; var y = 0; var bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bmp.PixelFormat); var ptrPixels = bitmapData.Scan0; unsafe { // Get the pointer to the image bits. var stride = bitmapData.Stride; byte *pBits; if (stride > 0) { pBits = (byte *)ptrPixels.ToPointer(); } else { pBits = (byte *)ptrPixels.ToPointer() + stride * (height - 1); } /* if (false) * { * if (stride > 0) * pBits = (byte*)ptrPixels.ToPointer() + stride * (height - 1); * else * pBits = (byte*)ptrPixels.ToPointer(); * stride = -stride; * } */ if (height >= 4) { for (; y < height; y += 4) { for (var j = 0; j < blocks.Length; j++) { var streamPos = stream.Position; blocks[j] = new DXTBlockWrapper <TBlock>((TBlock)reader.ReadStruct(typeof(TBlock))); stream.Position = streamPos + BytesPerBlock; } var pbDst = pBits + y * stride; // pbDst = pBits + (height - y - 1) * stride; var blockPos = 0; if (width >= 4) { for (var x = 0; x < width; x += 4) { DecodeDXTBlock(pbDst, blocks[blockPos++], stride, 4, 4); //pbSrc += INFO::bytesPerBlock; pbDst += 4 * 4; } } if (widthRest > 0) { DecodeDXTBlock(pbDst, blocks[blockPos++], stride, widthRest, 4); } } } if (heightRest > 0) { for (var j = 0; j < blocks.Length; j++) { var streamPos = stream.Position; blocks[j] = new DXTBlockWrapper <TBlock>((TBlock)reader.ReadStruct(typeof(TBlock))); stream.Position = streamPos + BytesPerBlock; } var pbDst = pBits + y * stride; // pbDst = pBits + (height - y - 1) * stride; var blockPos = 0; if (width >= 4) { for (var x = 0; x < width; x += 4) { DecodeDXTBlock(pbDst, blocks[blockPos++], stride, 4, heightRest); // pbSrc += INFO::bytesPerBlock; pbDst += 4 * 4; } } if (widthRest > 0) { DecodeDXTBlock(pbDst, blocks[blockPos++], stride, widthRest, heightRest); } } } // unsafe bmp.UnlockBits(bitmapData); return(bmp); }
protected virtual void Setup(DXTBlockWrapper <TBlock> pBlock) { m_pBlock = pBlock; }
protected override void Setup(DXTBlockWrapper <DXT3Block> pBlock) { base.Setup(pBlock); GetBlockColors(m_pBlock, m_colors, IsDXT1); }