Axiom.Media.PixelConverter.PackColor C# (CSharp) Method

PackColor() public static method

Pack a color value to memory
public static PackColor ( ColorEx color, PixelFormat format, IntPtr dest ) : void
color Axiom.Core.ColorEx The color
format PixelFormat Pixel format in which to write the color
dest System.IntPtr Destination memory location
return void
        public static void PackColor(ColorEx color, PixelFormat format, IntPtr dest)
        {
            PixelConverter.PackColor(color.r, color.g, color.b, color.a, format, dest);
        }

Same methods

PixelConverter::PackColor ( float r, float g, float b, float a, PixelFormat format, IntPtr dest ) : void
PixelConverter::PackColor ( uint r, uint g, uint b, uint a, PixelFormat format, IntPtr dest ) : void

Usage Example

Beispiel #1
0
        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));
            }
        }
All Usage Examples Of Axiom.Media.PixelConverter::PackColor