public override byte[] Decode(byte[] input, int offset, int width, int height, VrPixelCodec PixelCodec) { byte[] output = new byte[width * height * 4]; for (int y = 0; y < height; y += 4) { for (int x = 0; x < width; x += 4) { for (int y2 = 0; y2 < 4; y2++) { for (int x2 = 0; x2 < 4; x2++) { ushort pixel = PTMethods.ToUInt16BE(input, offset); //output[((((y + y2) * width) + (x + x2)) * 4) + 3] = 0xFF; //output[((((y + y2) * width) + (x + x2)) * 4) + 2] = (byte)(((pixel >> 11) & 0x1F) << 11); //output[((((y + y2) * width) + (x + x2)) * 4) + 1] = (byte)(((pixel >> 5) & 0x3F) << 10); //output[((((y + y2) * width) + (x + x2)) * 4) + 0] = (byte)(((pixel >> 0) & 0x1F) << 11); output[((((y + y2) * width) + (x + x2)) * 4) + 3] = 0xFF; output[((((y + y2) * width) + (x + x2)) * 4) + 2] = (byte)(((pixel >> 11) & 0x1F) * 0xFF / 0x1F); output[((((y + y2) * width) + (x + x2)) * 4) + 1] = (byte)(((pixel >> 5) & 0x3F) * 0xFF / 0x3F); output[((((y + y2) * width) + (x + x2)) * 4) + 0] = (byte)(((pixel >> 0) & 0x1F) * 0xFF / 0x1F); offset += 2; } } } } return(output); }
public override void DecodePixel(byte[] source, int sourceIndex, byte[] destination, int destinationIndex) { ushort pixel = PTMethods.ToUInt16BE(source, sourceIndex); destination[destinationIndex + 3] = 0xFF; destination[destinationIndex + 2] = (byte)(((pixel >> 11) & 0x1F) * 0xFF / 0x1F); destination[destinationIndex + 1] = (byte)(((pixel >> 5) & 0x3F) * 0xFF / 0x3F); destination[destinationIndex + 0] = (byte)(((pixel >> 0) & 0x1F) * 0xFF / 0x1F); }
public override byte[] Decode(byte[] input, int offset, int width, int height, VrPixelCodec PixelCodec) { byte[] output = new byte[width * height * 4]; for (int y = 0; y < height; y += 4) { for (int x = 0; x < width; x += 4) { for (int y2 = 0; y2 < 4; y2++) { for (int x2 = 0; x2 < 4; x2++) { ushort pixel = PTMethods.ToUInt16BE(input, offset); if ((pixel & 0x8000) != 0) // Rgb555 { output[((((y + y2) * width) + (x + x2)) * 4) + 3] = 0xFF; output[((((y + y2) * width) + (x + x2)) * 4) + 2] = (byte)(((pixel >> 10) & 0x1F) * 0xFF / 0x1F); output[((((y + y2) * width) + (x + x2)) * 4) + 1] = (byte)(((pixel >> 5) & 0x1F) * 0xFF / 0x1F); output[((((y + y2) * width) + (x + x2)) * 4) + 0] = (byte)(((pixel >> 0) & 0x1F) * 0xFF / 0x1F); //output[((((y + y2) * width) + (x + x2)) * 4) + 3] = 0xFF; //output[((((y + y2) * width) + (x + x2)) * 4) + 2] = (byte)(((pixel >> 10) & 0x1F) << 11); //output[((((y + y2) * width) + (x + x2)) * 4) + 1] = (byte)(((pixel >> 5) & 0x1F) << 11); //output[((((y + y2) * width) + (x + x2)) * 4) + 0] = (byte)(((pixel >> 0) & 0x1F) << 11); } else // Argb3444 { output[((((y + y2) * width) + (x + x2)) * 4) + 3] = (byte)(((pixel >> 12) & 0x07) * 0xFF / 0x07); output[((((y + y2) * width) + (x + x2)) * 4) + 2] = (byte)(((pixel >> 8) & 0x0F) * 0xFF / 0x0F); output[((((y + y2) * width) + (x + x2)) * 4) + 1] = (byte)(((pixel >> 4) & 0x0F) * 0xFF / 0x0F); output[((((y + y2) * width) + (x + x2)) * 4) + 0] = (byte)(((pixel >> 0) & 0x0F) * 0xFF / 0x0F); //output[((((y + y2) * width) + (x + x2)) * 4) + 3] = (byte)(((pixel >> 12) & 0x07) << 13); //output[((((y + y2) * width) + (x + x2)) * 4) + 2] = (byte)(((pixel >> 8) & 0x0F) << 12); //output[((((y + y2) * width) + (x + x2)) * 4) + 1] = (byte)(((pixel >> 4) & 0x0F) << 12); //output[((((y + y2) * width) + (x + x2)) * 4) + 0] = (byte)(((pixel >> 0) & 0x0F) << 12); } offset += 2; } } } } return(output); }
public override void DecodePixel(byte[] source, int sourceIndex, byte[] destination, int destinationIndex) { ushort pixel = PTMethods.ToUInt16BE(source, sourceIndex); if ((pixel & 0x8000) != 0) // Rgb555 { destination[destinationIndex + 3] = 0xFF; destination[destinationIndex + 2] = (byte)(((pixel >> 10) & 0x1F) * 0xFF / 0x1F); destination[destinationIndex + 1] = (byte)(((pixel >> 5) & 0x1F) * 0xFF / 0x1F); destination[destinationIndex + 0] = (byte)(((pixel >> 0) & 0x1F) * 0xFF / 0x1F); } else // Argb3444 { destination[destinationIndex + 3] = (byte)(((pixel >> 12) & 0x07) * 0xFF / 0x07); destination[destinationIndex + 2] = (byte)(((pixel >> 8) & 0x0F) * 0xFF / 0x0F); destination[destinationIndex + 1] = (byte)(((pixel >> 4) & 0x0F) * 0xFF / 0x0F); destination[destinationIndex + 0] = (byte)(((pixel >> 0) & 0x0F) * 0xFF / 0x0F); } }
protected override bool Initalize() { // Check to see if what we are dealing with is a GVP palette if (!Is(encodedData)) { return(false); } // Get the pixel format and the codec and make sure we can decode using them pixelFormat = (GvrPixelFormat)encodedData[0x09]; pixelCodec = GvrPixelCodec.GetPixelCodec(pixelFormat); if (pixelCodec == null) { return(false); } // Get the number of colors contained in the palette paletteEntries = PTMethods.ToUInt16BE(encodedData, 0x0E); return(true); }
protected override void Initalize() { // Check to see if what we are dealing with is a GVR texture if (!Is(encodedData)) { throw new NotAValidTextureException("This is not a valid GVR texture."); } // Determine the offsets of the GBIX/GCIX (if present) and GCIX header chunks. if (PTMethods.Contains(encodedData, 0, Encoding.UTF8.GetBytes("GBIX")) || PTMethods.Contains(encodedData, 0, Encoding.UTF8.GetBytes("GCIX"))) { gbixOffset = 0x00; pvrtOffset = 0x10; } else { gbixOffset = -1; pvrtOffset = 0x00; } // Read the global index (if it is present). If it is not present, just set it to 0. if (gbixOffset != -1) { globalIndex = PTMethods.ToUInt32BE(encodedData, gbixOffset + 0x08); } else { globalIndex = 0; } // Read information about the texture textureWidth = PTMethods.ToUInt16BE(encodedData, pvrtOffset + 0x0C); textureHeight = PTMethods.ToUInt16BE(encodedData, pvrtOffset + 0x0E); pixelFormat = (GvrPixelFormat)(encodedData[pvrtOffset + 0x0A] >> 4); // Only the first 4 bits matter dataFlags = (GvrDataFlags)(encodedData[pvrtOffset + 0x0A] & 0x0F); // Only the last 4 bits matter dataFormat = (GvrDataFormat)encodedData[pvrtOffset + 0x0B]; // Get the codecs and make sure we can decode using them dataCodec = GvrDataCodec.GetDataCodec(dataFormat); // We need a pixel codec if this is a palettized texture if (dataCodec != null && dataCodec.PaletteEntries != 0) { pixelCodec = GvrPixelCodec.GetPixelCodec(pixelFormat); if (pixelCodec != null) { dataCodec.PixelCodec = pixelCodec; canDecode = true; } } else { pixelFormat = GvrPixelFormat.Unknown; if (dataCodec != null) { canDecode = true; } } // Set the palette and data offsets paletteEntries = dataCodec.PaletteEntries; if (!canDecode || paletteEntries == 0 || (paletteEntries != 0 && (dataFlags & GvrDataFlags.ExternalPalette) != 0)) { paletteOffset = -1; dataOffset = pvrtOffset + 0x10; } else { paletteOffset = pvrtOffset + 0x10; dataOffset = paletteOffset + (paletteEntries * (pixelCodec.Bpp >> 3)); } // If the texture contains mipmaps, gets the offsets of them if (canDecode && paletteEntries == 0 && (dataFlags & GvrDataFlags.Mipmaps) != 0) { mipmapOffsets = new int[(int)Math.Log(textureWidth, 2) + 1]; int mipmapOffset = 0; for (int i = 0, size = textureWidth; i < mipmapOffsets.Length; i++, size >>= 1) { mipmapOffsets[i] = mipmapOffset; mipmapOffset += Math.Max(size * size * (dataCodec.Bpp >> 3), 32); } } initalized = true; }
public override byte[] Decode(byte[] input, int offset, int width, int height, VrPixelCodec PixelCodec) { byte[] output = new byte[width * height * 4]; // Palette for each 4x4 block byte[][] palette = new byte[4][]; palette[0] = new byte[4]; palette[1] = new byte[4]; palette[2] = new byte[4]; palette[3] = new byte[4]; // The two colors that determine the palette ushort[] pixel = new ushort[2]; for (int y = 0; y < height; y += 8) { for (int x = 0; x < width; x += 8) { for (int y2 = 0; y2 < 8; y2 += 4) { for (int x2 = 0; x2 < 8; x2 += 4) { // Get the first two colors pixel[0] = PTMethods.ToUInt16BE(input, offset); pixel[1] = PTMethods.ToUInt16BE(input, offset + 2); palette[0][3] = 0xFF; palette[0][2] = (byte)(((pixel[0] >> 11) & 0x1F) * 0xFF / 0x1F); palette[0][1] = (byte)(((pixel[0] >> 5) & 0x3F) * 0xFF / 0x3F); palette[0][0] = (byte)(((pixel[0] >> 0) & 0x1F) * 0xFF / 0x1F); palette[1][3] = 0xFF; palette[1][2] = (byte)(((pixel[1] >> 11) & 0x1F) * 0xFF / 0x1F); palette[1][1] = (byte)(((pixel[1] >> 5) & 0x3F) * 0xFF / 0x3F); palette[1][0] = (byte)(((pixel[1] >> 0) & 0x1F) * 0xFF / 0x1F); // Determine the next two colors based on how the first two are stored if (pixel[0] > pixel[1]) { palette[2][3] = 0xFF; palette[2][2] = (byte)(((palette[0][2] * 2) + palette[1][2]) / 3); palette[2][1] = (byte)(((palette[0][1] * 2) + palette[1][1]) / 3); palette[2][0] = (byte)(((palette[0][0] * 2) + palette[1][0]) / 3); palette[3][3] = 0xFF; palette[3][2] = (byte)(((palette[1][2] * 2) + palette[0][2]) / 3); palette[3][1] = (byte)(((palette[1][1] * 2) + palette[0][1]) / 3); palette[3][0] = (byte)(((palette[1][0] * 2) + palette[0][0]) / 3); } else { palette[2][3] = 0xFF; palette[2][2] = (byte)((palette[0][2] + palette[1][2]) / 2); palette[2][1] = (byte)((palette[0][1] + palette[1][1]) / 2); palette[2][0] = (byte)((palette[0][0] + palette[1][0]) / 2); palette[3][3] = 0x00; palette[3][2] = 0x00; palette[3][1] = 0x00; palette[3][0] = 0x00; } offset += 4; for (int y3 = 0; y3 < 4; y3++) { for (int x3 = 0; x3 < 4; x3++) { output[((((y + y2 + y3) * width) + (x + x2 + x3)) * 4) + 3] = palette[((input[offset] >> (6 - (x3 * 2))) & 0x03)][3]; output[((((y + y2 + y3) * width) + (x + x2 + x3)) * 4) + 2] = palette[((input[offset] >> (6 - (x3 * 2))) & 0x03)][2]; output[((((y + y2 + y3) * width) + (x + x2 + x3)) * 4) + 1] = palette[((input[offset] >> (6 - (x3 * 2))) & 0x03)][1]; output[((((y + y2 + y3) * width) + (x + x2 + x3)) * 4) + 0] = palette[((input[offset] >> (6 - (x3 * 2))) & 0x03)][0]; } offset++; } } } } } return(output); }