private void Unpack(ref ColorEx dst, int x, int y, int z, PixelFormat format, BufferBase src, PixelBox srcbox, int elemsize) { var data = src + (elemsize * ((x) + (y) * srcbox.RowPitch + (z) * srcbox.SlicePitch)); dst = PixelConverter.UnpackColor(format, data); }
public static int GetMemorySize(int width, int height, int depth, PixelFormat format) { if (Compressed(format)) { switch (format) { // DXT formats work by dividing the image into 4x4 blocks, then encoding each // 4x4 block with a certain number of bytes. DXT can only be used on 2D images. case PixelFormat.DXT1: Debug.Assert(depth == 1); return(((width + 3) / 4) * ((height + 3) / 4) * 8); case PixelFormat.DXT2: case PixelFormat.DXT3: case PixelFormat.DXT4: case PixelFormat.DXT5: Debug.Assert(depth == 1); return(((width + 3) / 4) * ((height + 3) / 4) * 16); default: throw new Exception("Invalid compressed pixel format, in PixelBox.GetMemorySize"); } } else { return(width * height * depth * PixelConverter.GetNumElemBytes(format)); } }
private void _unpackDXTColor(PixelFormat pf, DXTColorBlock block, ColorEx[] pCol) { // Note - we assume all values have already been endian swapped // Colour lookup table var derivedColours = new ColorEx[4]; using (var src = BufferBase.Wrap(block.colour_0, 1)) { derivedColours[0] = PixelConverter.UnpackColor(PixelFormat.R5G6B5, src); } using (var src = BufferBase.Wrap(block.colour_1, 1)) { derivedColours[1] = PixelConverter.UnpackColor(PixelFormat.R5G6B5, src); } if (pf == PixelFormat.DXT1 && block.colour_0 <= block.colour_1) { // 1-bit alpha // one intermediate colour, half way between the other two derivedColours[2] = (derivedColours[0] + derivedColours[1]) / 2; // transparent colour derivedColours[3] = new ColorEx(0, 0, 0, 0); } else { // first interpolated colour, 1/3 of the way along derivedColours[2] = (derivedColours[0] * 2 + derivedColours[1]) / 3; // second interpolated colour, 2/3 of the way along derivedColours[3] = (derivedColours[0] + derivedColours[1] * 2) / 3; } // Process 4x4 block of texels for (var row = 0; row < 4; ++row) { for (var x = 0; x < 4; ++x) { // LSB come first var colIdx = (byte)block.indexRow[row] >> (x * 2) & 0x3; if (pf == PixelFormat.DXT1) { // Overwrite entire colour pCol[(row * 4) + x] = derivedColours[colIdx]; } else { // alpha has already been read (alpha precedes colour) var col = pCol[(row * 4) + x]; col.r = derivedColours[colIdx].r; col.g = derivedColours[colIdx].g; col.b = derivedColours[colIdx].b; } } } }
public static bool IsAccessible(PixelFormat format) { if (format == PixelFormat.Unknown) { return(false); } var flags = PixelConverter.GetDescriptionFor(format).flags; return(!((flags & PixelFormatFlags.Compressed) > 0 || (flags & PixelFormatFlags.Depth) > 0)); }
public static uint[] GetBitMasks(PixelFormat format) { var rgba = new uint[4]; var des = PixelConverter.GetDescriptionFor(format); rgba[0] = des.rmask; rgba[1] = des.gmask; rgba[2] = des.bmask; rgba[3] = des.amask; return(rgba); }
public static int[] GetBitDepths(PixelFormat format) { var rgba = new int[4]; var des = PixelConverter.GetDescriptionFor(format); rgba[0] = des.rbits; rgba[1] = des.gbits; rgba[2] = des.bbits; rgba[3] = des.abits; return(rgba); }
public static byte[] GetBitShifts(PixelFormat format) { var rgba = new byte[4]; var des = PixelConverter.GetDescriptionFor(format); rgba[0] = des.rshift; rgba[1] = des.gshift; rgba[2] = des.bshift; rgba[3] = des.ashift; return(rgba); }
///************************************************************************* /// Pixel packing/unpacking utilities ///************************************************************************* // ///<summary> // /// Pack a color value to memory // ///</summary> // ///<param name="color">The color</param> // ///<param name="format">Pixel format in which to write the color</param> // ///<param name="dest">Destination memory location</param> // public static void PackColor(System.Drawing.Color color, PixelFormat format, IntPtr dest) { // PackColor(color.r, color.g, color.b, color.a, format, dest); // } ///<summary> /// Pack a color value to memory ///</summary> ///<param name="r,g,b,a">The four color components, range 0x00 to 0xFF</param> ///<param name="format">Pixelformat in which to write the color</param> ///<param name="dest">Destination memory location</param> unsafe public void PackColor(uint r, uint g, uint b, uint a, PixelFormat format, byte *dest) { PixelFormatDescription des = PixelConverter.GetDescriptionFor(format); if ((des.flags & PixelFormatFlags.NativeEndian) != 0) { // Shortcut for integer formats packing uint value = (((Bitwise.FixedToFixed(r, 8, des.rbits) << des.rshift) & des.rmask) | ((Bitwise.FixedToFixed(g, 8, des.gbits) << des.gshift) & des.gmask) | ((Bitwise.FixedToFixed(b, 8, des.bbits) << des.bshift) & des.bmask) | ((Bitwise.FixedToFixed(a, 8, des.abits) << des.ashift) & des.amask)); // And write to memory Bitwise.IntWrite(dest, des.elemBytes, value); } else { // Convert to float PackColor((float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)a / 255.0f, format, dest); } }
// /** Unpack a color value from memory // @param color The color is returned here // @param pf Pixelformat in which to read the color // @param src Source memory location // */ // protected static void UnpackColor(ref System.Drawing.Color color, PixelFormat pf, IntPtr src) { // UnpackColor(color.r, color.g, color.b, color.a, pf, src); // } /** Unpack a color value from memory * @param r,g,b,a The color is returned here (as byte) * @param pf Pixelformat in which to read the color * @param src Source memory location * @remarks This function returns the color components in 8 bit precision, * this will lose precision when coming from A2R10G10B10 or floating * point formats. */ unsafe public static void UnpackColor(ref byte r, ref byte g, ref byte b, ref byte a, PixelFormat pf, byte *src) { PixelFormatDescription des = PixelConverter.GetDescriptionFor(pf); if ((des.flags & PixelFormatFlags.NativeEndian) != 0) { // Shortcut for integer formats unpacking uint value = Bitwise.IntRead(src, des.elemBytes); if ((des.flags & PixelFormatFlags.Luminance) != 0) { // Luminance format -- only rbits used r = g = b = (byte)Bitwise.FixedToFixed((value & des.rmask) >> des.rshift, des.rbits, 8); } else { r = (byte)Bitwise.FixedToFixed((value & des.rmask) >> des.rshift, des.rbits, 8); g = (byte)Bitwise.FixedToFixed((value & des.gmask) >> des.gshift, des.gbits, 8); b = (byte)Bitwise.FixedToFixed((value & des.bmask) >> des.bshift, des.bbits, 8); } if ((des.flags & PixelFormatFlags.HasAlpha) != 0) { a = (byte)Bitwise.FixedToFixed((value & des.amask) >> des.ashift, des.abits, 8); } else { a = 255; // No alpha, default a component to full } } else { // Do the operation with the more generic floating point float rr, gg, bb, aa; UnpackColor(out rr, out gg, out bb, out aa, pf, src); r = Bitwise.FloatToByteFixed(rr); g = Bitwise.FloatToByteFixed(gg); b = Bitwise.FloatToByteFixed(bb); a = Bitwise.FloatToByteFixed(aa); } }
///<summary> /// Pack a color value to memory ///</summary> ///<param name="r,g,b,a"> /// The four color components, range 0.0f to 1.0f /// (an exception to this case exists for floating point pixel /// formats, which don't clamp to 0.0f..1.0f) ///</param> ///<param name="format">Pixelformat in which to write the color</param> ///<param name="dest">Destination memory location</param> unsafe public static void PackColor(float r, float g, float b, float a, PixelFormat format, byte *dest) { // Catch-it-all here PixelFormatDescription des = PixelConverter.GetDescriptionFor(format); if ((des.flags & PixelFormatFlags.NativeEndian) != 0) { // Do the packing uint value = ((Bitwise.FloatToFixed(r, des.rbits) << des.rshift) & des.rmask) | ((Bitwise.FloatToFixed(g, des.gbits) << des.gshift) & des.gmask) | ((Bitwise.FloatToFixed(b, des.bbits) << des.bshift) & des.bmask) | ((Bitwise.FloatToFixed(a, des.abits) << des.ashift) & des.amask); // And write to memory Bitwise.IntWrite(dest, des.elemBytes, value); } else { switch (format) { case PixelFormat.FLOAT32_R: ((float *)dest)[0] = r; break; case PixelFormat.FLOAT32_RGB: ((float *)dest)[0] = r; ((float *)dest)[1] = g; ((float *)dest)[2] = b; break; case PixelFormat.FLOAT32_RGBA: ((float *)dest)[0] = r; ((float *)dest)[1] = g; ((float *)dest)[2] = b; ((float *)dest)[3] = a; break; case PixelFormat.FLOAT16_R: ((ushort *)dest)[0] = Bitwise.FloatToHalf(r); break; case PixelFormat.FLOAT16_RGB: ((ushort *)dest)[0] = Bitwise.FloatToHalf(r); ((ushort *)dest)[1] = Bitwise.FloatToHalf(g); ((ushort *)dest)[2] = Bitwise.FloatToHalf(b); break; case PixelFormat.FLOAT16_RGBA: ((ushort *)dest)[0] = Bitwise.FloatToHalf(r); ((ushort *)dest)[1] = Bitwise.FloatToHalf(g); ((ushort *)dest)[2] = Bitwise.FloatToHalf(b); ((ushort *)dest)[3] = Bitwise.FloatToHalf(a); break; // case PixelFormat.SHORT_RGBA: // ((ushort*)dest)[0] = Bitwise.FloatToFixed(r, 16); // ((ushort*)dest)[1] = Bitwise.FloatToFixed(g, 16); // ((ushort*)dest)[2] = Bitwise.FloatToFixed(b, 16); // ((ushort*)dest)[3] = Bitwise.FloatToFixed(a, 16); // break; // case PixelFormat.BYTE_LA: // ((byte*)dest)[0] = Bitwise.FloatToFixed(r, 8); // ((byte*)dest)[1] = Bitwise.FloatToFixed(a, 8); // break; default: // Not yet supported throw new Exception("Pack to " + format + " not implemented, in PixelUtil.PackColor"); } } }
public static string GetFormatName(PixelFormat format) { return(PixelConverter.GetDescriptionFor(format).name); }
public static bool HasAlpha(PixelFormat format) { return((PixelConverter.GetDescriptionFor(format).flags & PixelFormatFlags.HasAlpha) > 0); }
public static bool IsCompressed(PixelFormat format) { return((PixelConverter.GetDescriptionFor(format).flags & PixelFormatFlags.Compressed) > 0); }
/// <summary> /// Returns the size in bytes of an element of the given pixel format. /// </summary> /// <param name="format">Pixel format to test.</param> /// <returns>Size in bytes.</returns> public static int GetNumElemBytes(PixelFormat format) { return(PixelConverter.GetDescriptionFor(format).elemBytes); }
unsafe public static void UnpackColor(out float r, out float g, out float b, out float a, PixelFormat pf, byte *src) { PixelFormatDescription des = PixelConverter.GetDescriptionFor(pf); if ((des.flags & PixelFormatFlags.NativeEndian) != 0) { // Shortcut for integer formats unpacking uint value = Bitwise.IntRead(src, des.elemBytes); if ((des.flags & PixelFormatFlags.Luminance) != 0) { // Luminance format -- only rbits used r = g = b = Bitwise.FixedToFloat( (value & des.rmask) >> des.rshift, des.rbits); } else { r = Bitwise.FixedToFloat((value & des.rmask) >> des.rshift, des.rbits); g = Bitwise.FixedToFloat((value & des.gmask) >> des.gshift, des.gbits); b = Bitwise.FixedToFloat((value & des.bmask) >> des.bshift, des.bbits); } if ((des.flags & PixelFormatFlags.HasAlpha) != 0) { a = Bitwise.FixedToFloat((value & des.amask) >> des.ashift, des.abits); } else { a = 1.0f; // No alpha, default a component to full } } else { switch (pf) { case PixelFormat.FLOAT32_R: r = g = b = ((float *)src)[0]; a = 1.0f; break; case PixelFormat.FLOAT32_RGB: r = ((float *)src)[0]; g = ((float *)src)[1]; b = ((float *)src)[2]; a = 1.0f; break; case PixelFormat.FLOAT32_RGBA: r = ((float *)src)[0]; g = ((float *)src)[1]; b = ((float *)src)[2]; a = ((float *)src)[3]; break; case PixelFormat.FLOAT16_R: r = g = b = Bitwise.HalfToFloat(((ushort *)src)[0]); a = 1.0f; break; case PixelFormat.FLOAT16_RGB: r = Bitwise.HalfToFloat(((ushort *)src)[0]); g = Bitwise.HalfToFloat(((ushort *)src)[1]); b = Bitwise.HalfToFloat(((ushort *)src)[2]); a = 1.0f; break; case PixelFormat.FLOAT16_RGBA: r = Bitwise.HalfToFloat(((ushort *)src)[0]); g = Bitwise.HalfToFloat(((ushort *)src)[1]); b = Bitwise.HalfToFloat(((ushort *)src)[2]); a = Bitwise.HalfToFloat(((ushort *)src)[3]); break; // case PixelFormat.SHORT_RGBA: // r = Bitwise.FixedToFloat(((ushort*)src)[0], 16); // g = Bitwise.FixedToFloat(((ushort*)src)[1], 16); // b = Bitwise.FixedToFloat(((ushort*)src)[2], 16); // a = Bitwise.FixedToFloat(((ushort*)src)[3], 16); // break; // case PixelFormat.BYTE_LA: // r = g = b = Bitwise.FixedToFloat(((byte*)src)[0], 8); // a = Bitwise.FixedToFloat(((byte*)src)[1], 8); // break; default: // Not yet supported throw new Exception("Unpack from " + pf + " not implemented, in PixelUtil.UnpackColor"); } } }
public override Codec.DecodeResult Decode(Stream input) { using (var br = new BinaryReader(input)) { // Read 4 character code var fileType = br.ReadInt32(); using (var wrap = BufferBase.Wrap(fileType, 2)) { _flipEndian(wrap, sizeof(uint), 1); } if (FOURCC('D', 'D', 'S', ' ') != fileType) { throw new AxiomException("This is not a DDS file!"); } // Read header in full var header = DDSHeader.Read(br); // Endian flip if required, all 32-bit values using (var wrap = BufferBase.Wrap(header, Memory.SizeOf(typeof(DDSHeader)))) { _flipEndian(wrap, 4, Memory.SizeOf(typeof(DDSHeader)) / 4); } // Check some sizes if (header.size != DDS_HEADER_SIZE) { throw new AxiomException("DDS header size mismatch!"); } if (header.pixelFormat.size != DDS_PIXELFORMAT_SIZE) { throw new AxiomException("DDS header size mismatch!"); } var imgData = new ImageData(); imgData.depth = 1; // (deal with volume later) imgData.width = header.width; imgData.height = header.height; var numFaces = 1; // assume one face until we know otherwise if ((header.caps.caps1 & DDSCAPS_MIPMAP) != 0) { imgData.numMipMaps = header.mipMapCount - 1; } else { imgData.numMipMaps = 0; } imgData.flags = 0; var decompressDXT = false; // Figure out basic image type if ((header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0) { imgData.flags |= ImageFlags.CubeMap; numFaces = 6; } else if ((header.caps.caps2 & DDSCAPS2_VOLUME) != 0) { imgData.flags |= ImageFlags.Volume; imgData.depth = header.depth; } // Pixel format var sourceFormat = PixelFormat.Unknown; if ((header.pixelFormat.flags & DDPF_FOURCC) != 0) { sourceFormat = _convertFourCCFormat(header.pixelFormat.fourCC); } else { sourceFormat = _convertPixelFormat(header.pixelFormat.rgbBits, header.pixelFormat.redMask, header.pixelFormat.greenMask, header.pixelFormat.blueMask, (header.pixelFormat.flags & DDPF_ALPHAPIXELS) != 0 ? header.pixelFormat.alphaMask : 0); } if (PixelUtil.IsCompressed(sourceFormat)) { if (!Root.Instance.RenderSystem.Capabilities.HasCapability(Capabilities.TextureCompressionDXT)) { // We'll need to decompress decompressDXT = true; // Convert format switch (sourceFormat) { case PixelFormat.DXT1: // source can be either 565 or 5551 depending on whether alpha present // unfortunately you have to read a block to figure out which // Note that we upgrade to 32-bit pixel formats here, even // though the source is 16-bit; this is because the interpolated // values will benefit from the 32-bit results, and the source // from which the 16-bit samples are calculated may have been // 32-bit so can benefit from this. var block = DXTColorBlock.Read(br); using (var wrap = BufferBase.Wrap(block.colour_0, sizeof(ushort))) { _flipEndian(wrap, sizeof(ushort), 1); } using (var wrap = BufferBase.Wrap(block.colour_1, sizeof(ushort))) { _flipEndian(wrap, sizeof(ushort), 1); } // skip back since we'll need to read this again br.BaseStream.Seek(0 - (long)Memory.SizeOf(typeof(DXTColorBlock)), SeekOrigin.Current); // colour_0 <= colour_1 means transparency in DXT1 if (block.colour_0 <= block.colour_1) { imgData.format = PixelFormat.BYTE_RGBA; } else { imgData.format = PixelFormat.BYTE_RGB; } break; case PixelFormat.DXT2: case PixelFormat.DXT3: case PixelFormat.DXT4: case PixelFormat.DXT5: // full alpha present, formats vary only in encoding imgData.format = PixelFormat.BYTE_RGBA; break; default: // all other cases need no special format handling break; } } else { // Use original format imgData.format = sourceFormat; // Keep DXT data compressed imgData.flags |= ImageFlags.Compressed; } } else // not compressed { // Don't test against DDPF_RGB since greyscale DDS doesn't set this // just derive any other kind of format imgData.format = sourceFormat; } // Calculate total size from number of mipmaps, faces and size imgData.size = Image.CalculateSize(imgData.numMipMaps, numFaces, imgData.width, imgData.height, imgData.depth, imgData.format); // Now deal with the data var dest = new byte[imgData.size]; var destBuffer = BufferBase.Wrap(dest); // all mips for a face, then each face for (var i = 0; i < numFaces; ++i) { var width = imgData.width; var height = imgData.height; var depth = imgData.depth; for (var mip = 0; mip <= imgData.numMipMaps; ++mip) { var dstPitch = width * PixelUtil.GetNumElemBytes(imgData.format); if (PixelUtil.IsCompressed(sourceFormat)) { // Compressed data if (decompressDXT) { DXTColorBlock col; DXTInterpolatedAlphaBlock iAlpha; DXTExplicitAlphaBlock eAlpha; // 4x4 block of decompressed colour var tempColours = new ColorEx[16]; var destBpp = PixelUtil.GetNumElemBytes(imgData.format); var sx = Utility.Min(width, 4); var sy = Utility.Min(height, 4); var destPitchMinus4 = dstPitch - destBpp * sx; // slices are done individually for (var z = 0; z < depth; ++z) { // 4x4 blocks in x/y for (var y = 0; y < height; y += 4) { for (var x = 0; x < width; x += 4) { if (sourceFormat == PixelFormat.DXT2 || sourceFormat == PixelFormat.DXT3) { // explicit alpha eAlpha = DXTExplicitAlphaBlock.Read(br); using (var wrap = BufferBase.Wrap(eAlpha.alphaRow, eAlpha.alphaRow.Length * sizeof(ushort))) { _flipEndian(wrap, sizeof(ushort), 4); } _unpackDXTAlpha(eAlpha, tempColours); } else if (sourceFormat == PixelFormat.DXT4 || sourceFormat == PixelFormat.DXT5) { // interpolated alpha iAlpha = DXTInterpolatedAlphaBlock.Read(br); using (var wrap = BufferBase.Wrap(iAlpha.alpha_0, 1)) { _flipEndian(wrap, sizeof(ushort), 1); } using (var wrap = BufferBase.Wrap(iAlpha.alpha_1, 1)) { _flipEndian(wrap, sizeof(ushort), 1); } _unpackDXTAlpha(iAlpha, tempColours); } // always read colour col = DXTColorBlock.Read(br); using (var wrap = BufferBase.Wrap(col.colour_0, sizeof(ushort))) { _flipEndian(wrap, sizeof(ushort), 1); } using (var wrap = BufferBase.Wrap(col.colour_1, sizeof(ushort))) { _flipEndian(wrap, sizeof(ushort), 1); } _unpackDXTColor(sourceFormat, col, tempColours); // write 4x4 block to uncompressed version for (var by = 0; by < sy; ++by) { for (var bx = 0; bx < sx; ++bx) { PixelConverter.PackColor(tempColours[by * 4 + bx], imgData.format, destBuffer); destBuffer += destBpp; } // advance to next row destBuffer += destPitchMinus4; } // next block. Our dest pointer is 4 lines down // from where it started if (x + 4 >= width) { // Jump back to the start of the line destBuffer += -destPitchMinus4; } else { // Jump back up 4 rows and 4 pixels to the // right to be at the next block to the right destBuffer += -(dstPitch * sy + destBpp * sx); } } } } } else { // load directly // DDS format lies! sizeOrPitch is not always set for DXT!! var dxtSize = PixelUtil.GetMemorySize(width, height, depth, imgData.format); using (var src = BufferBase.Wrap(br.ReadBytes(dxtSize))) { Memory.Copy(src, destBuffer, dxtSize); } destBuffer += dxtSize; } } else { // Final data - trim incoming pitch int srcPitch; if ((header.flags & DDSD_PITCH) != 0) { srcPitch = header.sizeOrPitch / Utility.Max(1, mip * 2); } else { // assume same as final pitch srcPitch = dstPitch; } Contract.Requires(dstPitch <= srcPitch); var srcAdvance = (long)(srcPitch - dstPitch); for (var z = 0; z < imgData.depth; ++z) { for (var y = 0; y < imgData.height; ++y) { using (var src = BufferBase.Wrap(br.ReadBytes(dstPitch))) { Memory.Copy(src, destBuffer, dstPitch); } if (srcAdvance > 0) { br.BaseStream.Seek(srcAdvance, SeekOrigin.Current); } destBuffer += dstPitch; } } } // Next mip if (width != 1) { width /= 2; } if (height != 1) { height /= 2; } if (depth != 1) { depth /= 2; } } } destBuffer.Dispose(); return(new DecodeResult(new MemoryStream(dest), imgData)); } }
/// <summary> /// </summary> /// <param name="src"> </param> /// <param name="dst"> </param> public void Scale(PixelBox src, PixelBox dst) { var srcelemsize = PixelUtil.GetNumElemBytes(src.Format); var dstelemsize = PixelUtil.GetNumElemBytes(dst.Format); var dstOffset = 0; // sx_48,sy_48,sz_48 represent current position in source // using 16/48-bit fixed precision, incremented by steps var stepx = ((UInt64)src.Width << 48) / (UInt64)dst.Width; var stepy = ((UInt64)src.Height << 48) / (UInt64)dst.Height; var stepz = ((UInt64)src.Depth << 48) / (UInt64)dst.Depth; // temp is 16/16 bit fixed precision, used to adjust a source // coordinate (x, y, or z) backwards by half a pixel so that the // integer bits represent the first sample (eg, sx1) and the // fractional bits are the blend weight of the second sample uint temp; // note: ((stepz>>1) - 1) is an extra half-step increment to adjust // for the center of the destination pixel, not the top-left corner var sz_48 = (stepz >> 1) - 1; for (var z = dst.Front; z < dst.Back; z++, sz_48 += stepz) { temp = (uint)(sz_48 >> 32); temp = (temp > 0x8000) ? temp - 0x8000 : 0; var sz1 = (int)(temp >> 16); var sz2 = System.Math.Min(sz1 + 1, src.Depth - 1); var szf = (temp & 0xFFFF) / 65536f; var sy_48 = (stepy >> 1) - 1; for (var y = dst.Top; y < dst.Bottom; y++, sy_48 += stepy) { temp = (uint)(sy_48 >> 32); temp = (temp > 0x8000) ? temp - 0x8000 : 0; var sy1 = (int)(temp >> 16); // src x #1 var sy2 = System.Math.Min(sy1 + 1, src.Height - 1); // src x #2 var syf = (temp & 0xFFFF) / 65536f; // weight of #2 var sx_48 = (stepx >> 1) - 1; for (var x = dst.Left; x < dst.Right; x++, sx_48 += stepx) { temp = (uint)(sy_48 >> 32); temp = (temp > 0x8000) ? temp - 0x8000 : 0; var sx1 = (int)(temp >> 16); // src x #1 var sx2 = System.Math.Min(sx1 + 1, src.Width - 1); // src x #2 var sxf = (temp & 0xFFFF) / 65536f; // weight of #2 ColorEx x1y1z1 = ColorEx.White, x2y1z1 = ColorEx.White, x1y2z1 = ColorEx.White, x2y2z1 = ColorEx.White; ColorEx x1y1z2 = ColorEx.White, x2y1z2 = ColorEx.White, x1y2z2 = ColorEx.White, x2y2z2 = ColorEx.White; Unpack(ref x1y1z1, sx1, sy1, sz1, src.Format, src.Data, src, srcelemsize); Unpack(ref x2y1z1, sx2, sy1, sz1, src.Format, src.Data, src, srcelemsize); Unpack(ref x1y2z1, sx1, sy2, sz1, src.Format, src.Data, src, srcelemsize); Unpack(ref x2y2z1, sx2, sy2, sz1, src.Format, src.Data, src, srcelemsize); Unpack(ref x1y1z2, sx1, sy1, sz2, src.Format, src.Data, src, srcelemsize); Unpack(ref x2y1z2, sx2, sy1, sz2, src.Format, src.Data, src, srcelemsize); Unpack(ref x1y2z2, sx1, sy2, sz2, src.Format, src.Data, src, srcelemsize); Unpack(ref x2y2z2, sx2, sy2, sz2, src.Format, src.Data, src, srcelemsize); var accum = x1y1z1 * ((1.0f - sxf) * (1.0f - syf) * (1.0f - szf)) + x2y1z1 * (sxf * (1.0f - syf) * (1.0f - szf)) + x1y2z1 * ((1.0f - sxf) * syf * (1.0f - szf)) + x2y2z1 * (sxf * syf * (1.0f - szf)) + x1y1z2 * ((1.0f - sxf) * (1.0f - syf) * szf) + x2y1z2 * (sxf * (1.0f - syf) * szf) + x1y2z2 * ((1.0f - sxf) * syf * szf) + x2y2z2 * (sxf * syf * szf); PixelConverter.PackColor(accum, dst.Format, dst.Data + dstOffset); dstOffset += dstelemsize; } dstOffset += dstelemsize * dst.RowSkip; } dstOffset += dstelemsize * dst.SliceSkip; } }
public static PixelComponentType GetComponentType(PixelFormat format) { return(PixelConverter.GetDescriptionFor(format).componentType); }
public static bool IsNativeEndian(PixelFormat format) { return((PixelConverter.GetDescriptionFor(format).flags & PixelFormatFlags.NativeEndian) > 0); }
public static bool IsLuminance(PixelFormat format) { return((PixelConverter.GetDescriptionFor(format).flags & PixelFormatFlags.Luminance) > 0); }
public static bool IsFloatingPoint(PixelFormat format) { return((PixelConverter.GetDescriptionFor(format).flags & PixelFormatFlags.Float) > 0); }