Axiom.Plugins.DevILCodecs.ILUtil.ConvertFromIL C# (CSharp) Method

ConvertFromIL() static public method

static public ConvertFromIL ( PixelBox dst ) : void
dst Axiom.Media.PixelBox
return void
		static public void ConvertFromIL( PixelBox dst )
		{
			if ( !dst.IsConsecutive )
				throw new Exception( "Destination must currently be consecutive" );

			if ( dst.Width != Il.ilGetInteger( Il.IL_IMAGE_WIDTH ) ||
				dst.Height != Il.ilGetInteger( Il.IL_IMAGE_HEIGHT ) ||
				dst.Depth != Il.ilGetInteger( Il.IL_IMAGE_DEPTH ) )
				throw new Exception( "Destination dimensions must equal IL dimension" );

			int ilfmt = Il.ilGetInteger( Il.IL_IMAGE_FORMAT );
			int iltp = Il.ilGetInteger( Il.IL_IMAGE_TYPE );

			// Check if in-memory format just matches
			// If yes, we can just copy it and save conversion
			ILFormat ifmt = Convert( dst.Format );
			if ( ifmt.Format == ilfmt && ILabs( ifmt.Type ) == ILabs( iltp ) )
			{
				Memory.Copy( Il.ilGetData(), dst.Data, Il.ilGetInteger( Il.IL_IMAGE_SIZE_OF_DATA ) );
				return;
			}

			// Try if buffer is in a known Axiom format so we can use its conversion routines
			PixelFormat bufFmt = Convert( (int)ilfmt, (int)iltp );
			ifmt = Convert( bufFmt );

			if ( ifmt.Format == ilfmt && ILabs( ifmt.Type ) == ILabs( iltp ) )
			{
				// IL format matches another Axiom format
				PixelBox src = new PixelBox( dst.Width, dst.Height, dst.Depth, bufFmt, Il.ilGetData() );
				PixelConverter.BulkPixelConversion( src, dst );
				return;
			}

			// Thee extremely slow method
			if ( iltp == Il.IL_UNSIGNED_BYTE || iltp == Il.IL_BYTE )
			{
				throw new NotImplementedException( "Cannot convert this DevIL type." );
				//ilToOgreInternal( static_cast<uint8*>( dst.data ), dst.format, (uint8)0x00, (uint8)0x00, (uint8)0x00, (uint8)0xFF );
			}
			else if ( iltp == Il.IL_FLOAT )
			{
				throw new NotImplementedException( "Cannot convert this DevIL type." );
				//ilToOgreInternal( static_cast<uint8*>( dst.data ), dst.format, 0.0f, 0.0f, 0.0f, 1.0f );
			}
			else if ( iltp == Il.IL_SHORT || iltp == Il.IL_UNSIGNED_SHORT )
			{
				throw new NotImplementedException( "Cannot convert this DevIL type." );
				//ilToOgreInternal( static_cast<uint8*>( dst.data ), dst.format, (uint16)0x0000, (uint16)0x0000, (uint16)0x0000, (uint16)0xFFFF );
			}
			else
			{
				throw new Exception( "Cannot convert this DevIL type." );
			}
		}

Usage Example

Beispiel #1
0
        public override Codec.DecodeResult Decode(Stream input)
        {
            var imgData = new ImageData();
            var output  = new MemoryStream();

            int imageID;
            int imageFormat, bytesPerPixel;

            // create and bind a new image
            Il.ilGenImages(1, out imageID);
            Il.ilBindImage(imageID);

            // create a temp buffer and write the stream into it
            var buffer = new byte[input.Length];

            input.Read(buffer, 0, buffer.Length);

            // Put it right side up
            Il.ilEnable(Il.IL_ORIGIN_SET);
            Il.ilSetInteger(Il.IL_ORIGIN_MODE, Il.IL_ORIGIN_UPPER_LEFT);

            // Keep DXTC(compressed) data if present
            Il.ilSetInteger(Il.IL_KEEP_DXTC_DATA, Il.IL_TRUE);

            // load the data into DevIL
            Il.ilLoadL(this._ilType, buffer, buffer.Length);

            // check for an error
            var ilError = Il.ilGetError();

            if (ilError != Il.IL_NO_ERROR)
            {
                throw new AxiomException("Error while decoding image data: '{0}'", Ilu.iluErrorString(ilError));
            }

            imageFormat = Il.ilGetInteger(Il.IL_IMAGE_FORMAT);
            var imageType = Il.ilGetInteger(Il.IL_IMAGE_TYPE);

            // Convert image if imageType is incompatible with us (double or long)
            if (imageType != Il.IL_BYTE && imageType != Il.IL_UNSIGNED_BYTE && imageType != Il.IL_FLOAT &&
                imageType != Il.IL_UNSIGNED_SHORT && imageType != Il.IL_SHORT)
            {
                Il.ilConvertImage(imageFormat, Il.IL_FLOAT);
                imageType = Il.IL_FLOAT;
            }

            // Converted paletted images
            if (imageFormat == Il.IL_COLOR_INDEX)
            {
                Il.ilConvertImage(Il.IL_BGRA, Il.IL_UNSIGNED_BYTE);
                imageFormat = Il.IL_BGRA;
                imageType   = Il.IL_UNSIGNED_BYTE;
            }

            // populate the image data
            bytesPerPixel = Il.ilGetInteger(Il.IL_IMAGE_BYTES_PER_PIXEL);

            imgData.format     = ILUtil.Convert(imageFormat, imageType);
            imgData.width      = Il.ilGetInteger(Il.IL_IMAGE_WIDTH);
            imgData.height     = Il.ilGetInteger(Il.IL_IMAGE_HEIGHT);
            imgData.depth      = Il.ilGetInteger(Il.IL_IMAGE_DEPTH);
            imgData.numMipMaps = Il.ilGetInteger(Il.IL_NUM_MIPMAPS);

            if (imgData.format == PixelFormat.Unknown)
            {
                throw new AxiomException("Unsupported devil format ImageFormat={0} ImageType={1}", imageFormat, imageType);
            }

            // Check for cubemap
            var numFaces = Il.ilGetInteger(Il.IL_NUM_IMAGES) + 1;

            if (numFaces == 6)
            {
                imgData.flags |= ImageFlags.CubeMap;
            }
            else
            {
                numFaces = 1;                 // Support only 1 or 6 face images for now
            }

            // Keep DXT data (if present at all and the GPU supports it)
            var dxtFormat = Il.ilGetInteger(Il.IL_DXTC_DATA_FORMAT);

            if (dxtFormat != Il.IL_DXT_NO_COMP &&
                Root.Instance.RenderSystem.Capabilities.HasCapability(Axiom.Graphics.Capabilities.TextureCompressionDXT))
            {
                imgData.format = ILUtil.Convert(dxtFormat, imageType);
                imgData.flags |= ImageFlags.Compressed;

                // Validate that this devil version loads DXT mipmaps
                if (imgData.numMipMaps > 0)
                {
                    Il.ilBindImage(imageID);
                    Il.ilActiveMipmap(1);
                    if ((uint)Il.ilGetInteger(Il.IL_DXTC_DATA_FORMAT) != dxtFormat)
                    {
                        imgData.numMipMaps = 0;
                        LogManager.Instance.Write(
                            "Warning: Custom mipmaps for compressed image were ignored because they are not loaded by this DevIL version.");
                    }
                }
            }

            // 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);

            // get the decoded data
            BufferBase BufferHandle;

            // Dimensions of current mipmap
            var width  = imgData.width;
            var height = imgData.height;
            var depth  = imgData.depth;

            // Transfer data
            for (var mip = 0; mip <= imgData.numMipMaps; ++mip)
            {
                for (var i = 0; i < numFaces; ++i)
                {
                    Il.ilBindImage(imageID);
                    if (numFaces > 1)
                    {
                        Il.ilActiveImage(i);
                    }
                    if (imgData.numMipMaps > 0)
                    {
                        Il.ilActiveMipmap(mip);
                    }

                    // Size of this face
                    var imageSize = PixelUtil.GetMemorySize(width, height, depth, imgData.format);
                    buffer = new byte[imageSize];

                    if ((imgData.flags & ImageFlags.Compressed) != 0)
                    {
                        // Compare DXT size returned by DevIL with our idea of the compressed size
                        if (imageSize == Il.ilGetDXTCData(IntPtr.Zero, 0, dxtFormat))
                        {
                            // Retrieve data from DevIL
                            using (BufferHandle = BufferBase.Wrap(buffer))
                            {
                                Il.ilGetDXTCData(BufferHandle.Pin(), imageSize, dxtFormat);
                                BufferHandle.UnPin();
                            }
                        }
                        else
                        {
                            LogManager.Instance.Write("Warning: compressed image size mismatch, devilsize={0} oursize={1}",
                                                      Il.ilGetDXTCData(IntPtr.Zero, 0, dxtFormat), imageSize);
                        }
                    }
                    else
                    {
                        // Retrieve data from DevIL
                        using (BufferHandle = BufferBase.Wrap(buffer))
                        {
                            var dst = new PixelBox(width, height, depth, imgData.format, BufferHandle);
                            ILUtil.ConvertFromIL(dst);
                        }
                    }

                    // write the decoded data to the output stream
                    output.Write(buffer, 0, buffer.Length);
                }

                // Next mip
                if (width != 1)
                {
                    width /= 2;
                }

                if (height != 1)
                {
                    height /= 2;
                }

                if (depth != 1)
                {
                    depth /= 2;
                }
            }

            // Restore IL state
            Il.ilDisable(Il.IL_ORIGIN_SET);
            Il.ilDisable(Il.IL_FORMAT_SET);

            Il.ilDeleteImages(1, ref imageID);

            return(new DecodeResult(output, imgData));
        }