public static void EncodePixel(this PsuTexturePixelFormat format, byte[] sourcePixels, int sourceAddress, byte[] destinationPixels, int destinationAddress) { switch (format) { //These are direct copies. case PsuTexturePixelFormat.Palette8: case PsuTexturePixelFormat.Argb1555: case PsuTexturePixelFormat.Rgb555: case PsuTexturePixelFormat.Rgb565: case PsuTexturePixelFormat.Argb8888: Array.Copy(sourcePixels, sourceAddress * format.GetSourceBytesPerPixel(), destinationPixels, destinationAddress * format.GetDestinationBytesPerPixel(), format.GetSourceBytesPerPixel()); break; //Promote all 4 colors from 4 to 8 bits. case PsuTexturePixelFormat.Argb4444: byte a = sourcePixels[sourceAddress * 4 + 3]; byte r = sourcePixels[sourceAddress * 4 + 2]; byte g = sourcePixels[sourceAddress * 4 + 1]; byte b = sourcePixels[sourceAddress * 4]; byte ar = (byte)((a & 0xF0) | (r >> 4)); byte gb = (byte)((g & 0xF0) | (b >> 4)); destinationPixels[destinationAddress * 2] = gb; destinationPixels[destinationAddress * 2 + 1] = ar; break; //Copy 3 bytes, discard the next, copy the result into 3. case PsuTexturePixelFormat.Xrgb8888: destinationPixels[destinationAddress * 4] = sourcePixels[sourceAddress * 3 + 0]; // B destinationPixels[destinationAddress * 4 + 1] = sourcePixels[sourceAddress * 3 + 1]; // G destinationPixels[destinationAddress * 4 + 2] = sourcePixels[sourceAddress * 3 + 2]; // R break; //Promote first byte to upper byte of destination case PsuTexturePixelFormat.Ax88: destinationPixels[destinationAddress * 2] = sourcePixels[sourceAddress * 2 + 1]; break; //Promote all 3 colors to 8 bits case PsuTexturePixelFormat.Rgb655: b = sourcePixels[sourceAddress * 3]; g = sourcePixels[sourceAddress * 3 + 1]; r = sourcePixels[sourceAddress * 3 + 2]; byte lowerByte = (byte)((b >> 5) | ((g & 0x38) << 2)); byte upperByte = (byte)((r & 0xFC) | ((g & 0xC0) >> 6)); destinationPixels[destinationAddress * 2] = lowerByte; destinationPixels[destinationAddress * 2 + 1] = upperByte; break; //Copy values, add dummy third value case PsuTexturePixelFormat.Gb88: g = sourcePixels[sourceAddress * 3 + 1]; b = sourcePixels[sourceAddress * 3 + 0]; destinationPixels[destinationAddress * 2] = b; destinationPixels[destinationAddress * 2 + 1] = g; break; case PsuTexturePixelFormat.Rb88: r = sourcePixels[sourceAddress * 3 + 1]; b = sourcePixels[sourceAddress * 3 + 0]; destinationPixels[destinationAddress * 2] = b; destinationPixels[destinationAddress * 2 + 1] = r; break; //Reorder values case PsuTexturePixelFormat.Rgba8888: destinationPixels[destinationAddress * 4 + 1] = sourcePixels[sourceAddress * 4]; // B destinationPixels[destinationAddress * 4 + 2] = sourcePixels[sourceAddress * 4 + 1]; // G destinationPixels[destinationAddress * 4 + 3] = sourcePixels[sourceAddress * 4 + 2]; // R destinationPixels[destinationAddress * 4] = sourcePixels[sourceAddress * 4 + 3]; // A break; case PsuTexturePixelFormat.Abgr8888: destinationPixels[destinationAddress * 4 + 2] = sourcePixels[sourceAddress * 4]; // B destinationPixels[destinationAddress * 4 + 1] = sourcePixels[sourceAddress * 4 + 1]; // G destinationPixels[destinationAddress * 4 + 0] = sourcePixels[sourceAddress * 4 + 2]; // R destinationPixels[destinationAddress * 4 + 3] = sourcePixels[sourceAddress * 4 + 3]; // A break; //These values have no bitmasks, so nothing gets copied. case PsuTexturePixelFormat.Mystery16: case PsuTexturePixelFormat.Mystery32: default: break; } }
public static void DecodePixel(this PsuTexturePixelFormat format, byte[] sourcePixels, int sourceAddress, byte[] destinationPixels, int destinationAddress) { switch (format) { //These are direct copies. case PsuTexturePixelFormat.Palette8: case PsuTexturePixelFormat.Argb1555: case PsuTexturePixelFormat.Rgb555: case PsuTexturePixelFormat.Rgb565: case PsuTexturePixelFormat.Argb8888: Array.Copy(sourcePixels, sourceAddress * format.GetSourceBytesPerPixel(), destinationPixels, destinationAddress * format.GetDestinationBytesPerPixel(), format.GetSourceBytesPerPixel()); break; //Promote all 4 colors from 4 to 8 bits. case PsuTexturePixelFormat.Argb4444: byte gb = sourcePixels[sourceAddress * 2]; byte ar = sourcePixels[sourceAddress * 2 + 1]; byte a = (byte)(ar & 0xF0); byte r = (byte)((ar & 0xF) << 4); byte g = (byte)(gb & 0xF0); byte b = (byte)((gb & 0xF) << 4); destinationPixels[destinationAddress * 4] = b; destinationPixels[destinationAddress * 4 + 1] = g; destinationPixels[destinationAddress * 4 + 2] = r; destinationPixels[destinationAddress * 4 + 3] = a; break; //Copy 3 bytes, discard the next, copy the result into 3. case PsuTexturePixelFormat.Xrgb8888: destinationPixels[destinationAddress * 3] = sourcePixels[sourceAddress * 4 + 0]; // B destinationPixels[destinationAddress * 3 + 1] = sourcePixels[sourceAddress * 4 + 1]; // G destinationPixels[destinationAddress * 3 + 2] = sourcePixels[sourceAddress * 4 + 2]; // R break; //Promote first byte to upper byte of destination case PsuTexturePixelFormat.Ax88: destinationPixels[destinationAddress * 2 + 1] = sourcePixels[sourceAddress * 2]; break; //Promote all 3 colors to 8 bits case PsuTexturePixelFormat.Rgb655: ushort combinedColor = (ushort)((sourcePixels[sourceAddress * 2 + 1] << 8) | sourcePixels[sourceAddress * 2]); b = (byte)((combinedColor & 0x1F) << 3); g = (byte)((combinedColor & 0x3E0) >> 2); r = (byte)((combinedColor & 0xFC00) >> 8); destinationPixels[destinationAddress * 3] = b; // B destinationPixels[destinationAddress * 3 + 1] = g; // G destinationPixels[destinationAddress * 3 + 2] = r; // R break; //Copy values, add dummy third value case PsuTexturePixelFormat.Gb88: g = sourcePixels[sourceAddress * 2 + 1]; b = sourcePixels[sourceAddress * 2 + 0]; destinationPixels[destinationAddress * 3] = b; destinationPixels[destinationAddress * 3 + 1] = g; break; case PsuTexturePixelFormat.Rb88: r = sourcePixels[sourceAddress * 2 + 1]; b = sourcePixels[sourceAddress * 2 + 0]; destinationPixels[destinationAddress * 3] = b; destinationPixels[destinationAddress * 3 + 1] = r; break; //Reorder values case PsuTexturePixelFormat.Rgba8888: destinationPixels[destinationAddress * 4] = sourcePixels[sourceAddress * 4 + 1]; // B destinationPixels[destinationAddress * 4 + 1] = sourcePixels[sourceAddress * 4 + 2]; // G destinationPixels[destinationAddress * 4 + 2] = sourcePixels[sourceAddress * 4 + 3]; // R destinationPixels[destinationAddress * 4 + 3] = sourcePixels[sourceAddress * 4]; // A break; case PsuTexturePixelFormat.Abgr8888: destinationPixels[destinationAddress * 4] = sourcePixels[sourceAddress * 4 + 2]; // B destinationPixels[destinationAddress * 4 + 1] = sourcePixels[sourceAddress * 4 + 1]; // G destinationPixels[destinationAddress * 4 + 2] = sourcePixels[sourceAddress * 4 + 0]; // R destinationPixels[destinationAddress * 4 + 3] = sourcePixels[sourceAddress * 4 + 3]; // A break; //These values have no bitmasks, so nothing gets copied. case PsuTexturePixelFormat.Mystery16: case PsuTexturePixelFormat.Mystery32: default: break; } }