private static unsafe MipGeneratorFn _Get(MipFormat format) { switch (format) { case MipFormat.RGBA: case MipFormat.pRGBA: return(_Color); // FIXME: Is this right? I think maybe it needs to be different case MipFormat.RGBA | MipFormat.sRGB: case MipFormat.pRGBA | MipFormat.sRGB: return(_sRGBColor); case MipFormat.Gray1: return(_Gray); case MipFormat.pGray4: return(_PAGray); case MipFormat.pGray4 | MipFormat.sRGB: return(_sRGBPAGray); default: return(null); } }
public unsafe MipGeneratorFn Get(MipFormat format) { switch (format) { case MipFormat.pGray4: return(PAGray); default: throw new ArgumentOutOfRangeException("format"); } }
public static unsafe MipGeneratorFn Get( MipFormat format, stbir_filter filter_horizontal = stbir_filter.DEFAULT, stbir_filter filter_vertical = stbir_filter.DEFAULT, stbir_edge edge_horizontal = stbir_edge.CLAMP, stbir_edge edge_vertical = stbir_edge.CLAMP ) { var masked = (format & ~MipFormat.sRGB); var datatype = (masked == MipFormat.Vector4) || (masked == MipFormat.pVector4) || (masked == MipFormat.Single) ? stbir_datatype.FLOAT : stbir_datatype.UINT8; var colorspace = (format & MipFormat.sRGB) == MipFormat.sRGB ? stbir_colorspace.SRGB : stbir_colorspace.LINEAR; var channels = masked == MipFormat.Gray1 ? 1 : 4; var flags = (masked == MipFormat.pRGBA) || (masked == MipFormat.pGray4) || (masked == MipFormat.pVector4) ? stbir_flags.ALPHA_PREMULTIPLIED : default; var alpha_channel = (masked == MipFormat.Gray1) ? -1 : 3; unsafe void Implementation( void *src, int srcWidth, int srcHeight, int srcStrideBytes, void *dest, int destWidth, int destHeight, int destStrideBytes ) { var result = API.stbir_resize( src, srcWidth, srcHeight, srcStrideBytes, dest, destWidth, destHeight, destStrideBytes, datatype, channels, alpha_channel, (int)flags, edge_horizontal, edge_vertical, filter_horizontal, filter_vertical, colorspace, null ); if (result != 1) { throw new Exception("An error occurred in stb_image_resize"); } } return(Implementation); } }
public static MipGeneratorFn Get(MipFormat format) { var index = (int)format; if ((index < 0) || (index >= Cache.Length)) { throw new ArgumentOutOfRangeException("format"); } var result = Cache[index]; if (result == null) { throw new ArgumentOutOfRangeException("format"); } return(result); }
public static void Set(MipFormat format, MipGeneratorFn implementation) { Cache[(int)format] = implementation; }
private unsafe void GenerateMips(bool sRGB) { void *pPreviousLevelData = null, pLevelData = Data; int levelWidth = Width, levelHeight = Height; int previousLevelWidth = Width, previousLevelHeight = Height; // FIXME MipChain = new byte[64][]; var pins = new List <GCHandle>(); MipFormat format = (MipFormat)(-1); if (IsFloatingPoint) { if (ChannelCount == 4) { format = IsPremultiplied ? MipFormat.pVector4 : MipFormat.Vector4; } else if (ChannelCount == 1) { format = MipFormat.Single; } } else if (!Is16Bit) { if (ChannelCount == 4) { format = IsPremultiplied ? MipFormat.pRGBA : MipFormat.RGBA; } else { format = MipFormat.Gray1; } } if (format == (MipFormat)(-1)) { throw new ArgumentOutOfRangeException("Mip generation is not supported for this image format"); } if (sRGB) { format |= MipFormat.sRGB; } var mipGenerator = STBMipGenerator.Get(format); for (uint level = 0; (levelWidth >= 1) && (levelHeight >= 1); level++) { if (IsDisposed) { throw new ObjectDisposedException("Image"); } if (level > 0) { var levelBuf = new byte[levelWidth * levelHeight * SizeofPixel]; MipChain[level - 1] = levelBuf; var pin = GCHandle.Alloc(levelBuf, GCHandleType.Pinned); pins.Add(pin); pLevelData = (void *)pin.AddrOfPinnedObject(); // FIXME: Do this one step at a time in a list of work items var previousStrideBytes = previousLevelWidth * SizeofPixel; var levelStrideBytes = levelWidth * SizeofPixel; mipGenerator( pPreviousLevelData, previousLevelWidth, previousLevelHeight, previousStrideBytes, pLevelData, levelWidth, levelHeight, levelStrideBytes ); } previousLevelWidth = levelWidth; previousLevelHeight = levelHeight; var newWidth = levelWidth / 2; var newHeight = levelHeight / 2; levelWidth = newWidth; levelHeight = newHeight; pPreviousLevelData = pLevelData; } foreach (var pin in pins) { pin.Free(); } }