A primitive describing a volume (3D), image (2D) or line (1D) of pixels in memory. In case of a rectangle, depth must be 1. Pixels are stored as a succession of "depth" slices, each containing "height" rows of "width" pixels.
Inheritance: BasicBox
Exemple #1
0
        /// <summary>
        ///   Return a subvolume of this PixelBox.
        /// </summary>
        /// <param name="def"> Defines the bounds of the subregion to return </param>
        /// <returns> A pixel box describing the region and the data in it </returns>
        /// <remarks>
        ///   This function does not copy any data, it just returns a PixelBox object with a data pointer pointing somewhere inside the data of object. Throws an Exception if def is not fully contained.
        /// </remarks>
        public PixelBox GetSubVolume(BasicBox def)
        {
            if (Compressed(this.format))
            {
                if (def.Left == left && def.Top == top && def.Front == front && def.Right == right && def.Bottom == bottom &&
                    def.Back == back)
                {
                    // Entire buffer is being queried
                    return(this);
                }
                throw new Exception("Cannot return subvolume of compressed PixelBuffer, in PixelBox.GetSubVolume");
            }
            if (!Contains(def))
            {
                throw new Exception("Bounds out of range, in PixelBox.GetSubVolume");
            }

            var elemSize = PixelUtil.GetNumElemBytes(this.format);
            // Calculate new data origin
            var rval = new PixelBox(def, this.format, this.data);

            rval.offset = (((def.Left - left) * elemSize) + ((def.Top - top) * this.rowPitch * elemSize) +
                           ((def.Front - front) * this.slicePitch * elemSize));
            rval.rowPitch   = this.rowPitch;
            rval.slicePitch = this.slicePitch;
            rval.format     = this.format;
            return(rval);
        }
        unsafe private static void B8G8R8toR8G8B8(PixelBox src, PixelBox dst)
        {
            Col3b *srcptr       = (Col3b *)(src.Data.ToPointer());
            Col3b *dstptr       = (Col3b *)(dst.Data.ToPointer());
            int    srcSliceSkip = src.SliceSkip;
            int    dstSliceSkip = dst.SliceSkip;
            int    k            = src.Right - src.Left;

            for (int z = src.Front; z < src.Back; z++)
            {
                for (int y = src.Top; y < src.Bottom; y++)
                {
                    for (int x = 0; x < k; x++)
                    {
                        Col3b inp = srcptr[x];
                        dstptr[x].x = inp.z;
                        dstptr[x].y = inp.y;
                        dstptr[x].z = inp.x;
                    }
                    srcptr += src.RowPitch;
                    dstptr += dst.RowPitch;
                }
                srcptr += srcSliceSkip;
                dstptr += dstSliceSkip;
            }
        }
            public static void Convert(PixelBox src, PixelBox dst, IPixelConverter pixelConverter)
            {
                {
                    var srcptr       = (BufferBase)src.Data.Clone();
                    var dstptr       = (BufferBase)dst.Data.Clone();
                    var srcSliceSkip = src.SliceSkip;
                    var dstSliceSkip = dst.SliceSkip;
                    var k            = src.Right - src.Left;

                    for (var z = src.Front; z < src.Back; z++)
                    {
                        for (var y = src.Top; y < src.Bottom; y++)
                        {
                            for (var x = 0; x < k; x++)
                            {
                                pixelConverter.Convert(srcptr, dstptr, x);
                            }
                            srcptr.Ptr += src.RowPitch * PixelUtil.GetNumElemBytes(src.Format);
                            dstptr.Ptr += dst.RowPitch * PixelUtil.GetNumElemBytes(dst.Format);
                        }
                        srcptr.Ptr += srcSliceSkip;
                        dstptr.Ptr += dstSliceSkip;
                    }
                }
            }
        unsafe private static void R8G8B8toB8G8R8A8(PixelBox src, PixelBox dst)
        {
            Col3b *srcptr       = (Col3b *)(src.Data.ToPointer());
            uint * dstptr       = (uint *)(dst.Data.ToPointer());
            int    xshift       = 8;
            int    yshift       = 16;
            int    zshift       = 24;
            int    ashift       = 0;
            int    srcSliceSkip = src.SliceSkip;
            int    dstSliceSkip = dst.SliceSkip;
            int    k            = src.Right - src.Left;

            for (int z = src.Front; z < src.Back; z++)
            {
                for (int y = src.Top; y < src.Bottom; y++)
                {
                    for (int x = 0; x < k; x++)
                    {
                        Col3b inp = srcptr[x];
#if BIG_ENDIAN
                        dstptr[x] = ((uint)(0xFF << ashift)) | (((uint)inp.x) << xshift) | (((uint)inp.y) << yshift) | (((uint)inp.z) << zshift);
#else
                        dstptr[x] = ((uint)(0xFF << ashift)) | (((uint)inp.x) << zshift) | (((uint)inp.y) << yshift) | (((uint)inp.z) << xshift);
#endif
                    }
                    srcptr += src.RowPitch;
                    dstptr += dst.RowPitch;
                }
                srcptr += srcSliceSkip;
                dstptr += dstSliceSkip;
            }
        }
        unsafe private static void A8R8G8B8toB8G8R8(PixelBox src, PixelBox dst)
        {
            uint * srcptr       = (uint *)(src.Data.ToPointer());
            Col3b *dstptr       = (Col3b *)(dst.Data.ToPointer());
            int    srcSliceSkip = src.SliceSkip;
            int    dstSliceSkip = dst.SliceSkip;
            int    k            = src.Right - src.Left;

            for (int z = src.Front; z < src.Back; z++)
            {
                for (int y = src.Top; y < src.Bottom; y++)
                {
                    for (int x = 0; x < k; x++)
                    {
                        uint inp = srcptr[x];
                        dstptr[x].x = (byte)((inp >> 0) & 0xFF);
                        dstptr[x].y = (byte)((inp >> 8) & 0xFF);
                        dstptr[x].z = (byte)((inp >> 16) & 0xFF);
                    }
                    srcptr += src.RowPitch;
                    dstptr += dst.RowPitch;
                }
                srcptr += srcSliceSkip;
                dstptr += dstSliceSkip;
            }
        }
Exemple #6
0
		public override void CopyContentsToMemory( PixelBox dst, RenderTarget.FrameBuffer buffer )
		{
			if ( buffer == FrameBuffer.Auto )
				buffer = FrameBuffer.Front;
			if ( buffer != FrameBuffer.Front )
			{
				throw new Exception( "Invalid buffer." );
			}

			pixelBuffer.BlitToMemory( dst );
		}
        public static bool DoOptimizedConversion(PixelBox src, PixelBox dst)
        {
            var conversion = ((int)src.Format << 8) | (int)dst.Format;

            if (_supportedConversions.ContainsKey(conversion))
            {
                PixelBoxConverter.Convert(src, dst, _supportedConversions[conversion]);
                return(true);
            }
            return(false);
        }
        ///<summary>
        ///    Convert consecutive pixels from one format to another. No dithering or filtering is being done.
        ///    Converting from RGB to luminance takes the R channel.  In case the source and destination format match,
        ///    just a copy is done.
        ///</summary>
        ///<param name="srcBytes">Pointer to source region</param>
        ///<param name="srcFormat">Pixel format of source region</param>
        ///<param name="dstBytes">Pointer to destination region</param>
        ///<param name="dstFormat">Pixel format of destination region</param>
        public static void BulkPixelConversion(IntPtr srcBytes, int srcOffset, PixelFormat srcFormat,
                                               IntPtr dstBytes, int dstOffset, PixelFormat dstFormat,
                                               int count)
        {
            PixelBox src = new PixelBox(count, 1, 1, srcFormat, srcBytes);

            src.Offset = srcOffset;
            PixelBox dst = new PixelBox(count, 1, 1, dstFormat, dstBytes);

            dst.Offset = dstOffset;
            BulkPixelConversion(src, dst);
        }
Exemple #9
0
        //-----------------------------------------------------------------------
        public void ILUtil.FromAxiom(PixelBox src)
        {
            // ilTexImage http://openil.sourceforge.net/docs/il/f00059.htm
            ILFormat ifmt = OgreFormat2ilFormat(src.format);

            if (src.isConsecutive() && ifmt.isValid())
            {
                // The easy case, the buffer is laid out in memory just like
                // we want it to be and is in a format DevIL can understand directly
                // We could even save the copy if DevIL would let us
                Il.ilTexImage(src.Width, src.Height, src.Depth, ifmt.numberOfChannels,
                              ifmt.format, ifmt.type, src.data);
            }
            else if (ifmt.isValid())
            {
                // The format can be understood directly by DevIL. The only
                // problem is that ilTexImage expects our image data consecutively
                // so we cannot use that directly.

                // Let DevIL allocate the memory for us, and copy the data consecutively
                // to its memory
                ilTexImage(static_cast <ILuint>(src.getWidth()),
                           static_cast <ILuint>(src.getHeight()),
                           static_cast <ILuint>(src.getDepth()), ifmt.numberOfChannels,
                           ifmt.format, ifmt.type, 0);
                PixelBox dst(src.getWidth(), src.getHeight(), src.getDepth(), src.format, ilGetData());

                PixelUtil::bulkPixelConversion(src, dst);
            }
            else
            {
                // Here it gets ugly. We're stuck with a pixel format that DevIL
                // can't do anything with. We will do a bulk pixel conversion and
                // then feed it to DevIL anyway. The problem is finding the best
                // format to convert to.

                // most general format supported by OGRE and DevIL
                PixelFormat fmt = PixelUtil::hasAlpha(src.format)?PF_FLOAT32_RGBA:PF_FLOAT32_RGB;

                // Make up a pixel format
                // We don't have to consider luminance formats as they have
                // straight conversions to DevIL, just weird permutations of RGBA an LA
                int depths[4];
Exemple #10
0
        /// <summary>
        /// </summary>
        public static void Scale(PixelBox src, PixelBox dst, int elementSize)
        {
            // assert(src.format == dst.format);
            // srcdata stays at beginning, pdst is a moving pointer
            //byte* srcdata = (byte*)src.Data;
            //byte* pdst = (byte*)dst.Data;
            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 = ((ulong)src.Width << 48) / (ulong)dst.Width;
            var stepy = ((ulong)src.Height << 48) / (ulong)dst.Height;
            var stepz = ((ulong)src.Depth << 48) / (ulong)dst.Depth;

            // 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 = (uint)dst.Front; z < dst.Back; z++, sz_48 += stepz)
            {
                var srczoff = (uint)(sz_48 >> 48) * (uint)src.SlicePitch;

                var sy_48 = (stepy >> 1) - 1;
                for (var y = (uint)dst.Top; y < dst.Bottom; y++, sy_48 += stepy)
                {
                    var srcyoff = (uint)(sy_48 >> 48) * (uint)src.RowPitch;

                    var sx_48 = (stepx >> 1) - 1;
                    for (var x = (uint)dst.Left; x < dst.Right; x++, sx_48 += stepx)
                    {
                        Memory.Copy(src.Data, dst.Data, (int)(elementSize * ((uint)(sx_48 >> 48) + srcyoff + srczoff)), dstOffset,
                                    elementSize);
                        dstOffset += elementSize;
                    }
                    dstOffset += elementSize * dst.RowSkip;
                }
                dstOffset += elementSize * dst.SliceSkip;
            }
        }
		/// <summary>
		/// </summary>
		public static void Scale( PixelBox src, PixelBox dst, int elementSize )
		{
			// assert(src.format == dst.format);
			// srcdata stays at beginning, pdst is a moving pointer
			//byte* srcdata = (byte*)src.Data;
			//byte* pdst = (byte*)dst.Data;
			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 = ( (ulong)src.Width << 48 )/(ulong)dst.Width;
			var stepy = ( (ulong)src.Height << 48 )/(ulong)dst.Height;
			var stepz = ( (ulong)src.Depth << 48 )/(ulong)dst.Depth;

			// 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 = (uint)dst.Front; z < dst.Back; z++, sz_48 += stepz )
			{
				var srczoff = (uint)( sz_48 >> 48 )*(uint)src.SlicePitch;

				var sy_48 = ( stepy >> 1 ) - 1;
				for ( var y = (uint)dst.Top; y < dst.Bottom; y++, sy_48 += stepy )
				{
					var srcyoff = (uint)( sy_48 >> 48 )*(uint)src.RowPitch;

					var sx_48 = ( stepx >> 1 ) - 1;
					for ( var x = (uint)dst.Left; x < dst.Right; x++, sx_48 += stepx )
					{
						Memory.Copy( src.Data, dst.Data, (int)( elementSize*( (uint)( sx_48 >> 48 ) + srcyoff + srczoff ) ), dstOffset,
						             elementSize );
						dstOffset += elementSize;
					}
					dstOffset += elementSize*dst.RowSkip;
				}
				dstOffset += elementSize*dst.SliceSkip;
			}
		}
        unsafe private static void L16toL8(PixelBox src, PixelBox dst)
        {
            ushort *srcptr       = (ushort *)(src.Data.ToPointer());
            byte *  dstptr       = (byte *)(dst.Data.ToPointer());
            int     srcSliceSkip = src.SliceSkip;
            int     dstSliceSkip = dst.SliceSkip;
            int     k            = src.Right - src.Left;

            for (int z = src.Front; z < src.Back; z++)
            {
                for (int y = src.Top; y < src.Bottom; y++)
                {
                    for (int x = 0; x < k; x++)
                    {
                        ushort inp = srcptr[x];
                        dstptr[x] = (byte)(inp >> 8);
                    }
                    srcptr += src.RowPitch;
                    dstptr += dst.RowPitch;
                }
                srcptr += srcSliceSkip;
                dstptr += dstSliceSkip;
            }
        }
        unsafe private static void X8B8G8R8toR8G8B8A8(PixelBox src, PixelBox dst)
        {
            uint *srcptr       = (uint *)(src.Data.ToPointer());
            uint *dstptr       = (uint *)(dst.Data.ToPointer());
            int   srcSliceSkip = src.SliceSkip;
            int   dstSliceSkip = dst.SliceSkip;
            int   k            = src.Right - src.Left;

            for (int z = src.Front; z < src.Back; z++)
            {
                for (int y = src.Top; y < src.Bottom; y++)
                {
                    for (int x = 0; x < k; x++)
                    {
                        uint inp = srcptr[x];
                        dstptr[x] = ((inp & 0x0000FF) << 24) | ((inp & 0xFF0000) >> 8) | ((inp & 0x00FF00) << 8) | 0x000000FF;
                    }
                    srcptr += src.RowPitch;
                    dstptr += dst.RowPitch;
                }
                srcptr += srcSliceSkip;
                dstptr += dstSliceSkip;
            }
        }
        unsafe private static void L8toB8G8R8A8(PixelBox src, PixelBox dst)
        {
            byte *srcptr       = (byte *)(src.Data.ToPointer());
            uint *dstptr       = (uint *)(dst.Data.ToPointer());
            int   srcSliceSkip = src.SliceSkip;
            int   dstSliceSkip = dst.SliceSkip;
            int   k            = src.Right - src.Left;

            for (int z = src.Front; z < src.Back; z++)
            {
                for (int y = src.Top; y < src.Bottom; y++)
                {
                    for (int x = 0; x < k; x++)
                    {
                        byte inp = srcptr[x];
                        dstptr[x] = 0x000000FF | (((uint)inp) << 8) | (((uint)inp) << 16) | (((uint)inp) << 24);
                    }
                    srcptr += src.RowPitch;
                    dstptr += dst.RowPitch;
                }
                srcptr += srcSliceSkip;
                dstptr += dstSliceSkip;
            }
        }
		protected static System.Drawing.Rectangle ToD3DRectangleExtent( PixelBox lockBox )
		{
			Debug.Assert( lockBox.Depth == 1 );
			var r = new System.Drawing.Rectangle();
			r.X = 0;
			r.Width = lockBox.Width;
			r.X = 0;
			r.Height = lockBox.Height;
			return r;
		}
		public void Bind( D3D9.Device dev, D3D9.Volume volume, D3D9.BaseTexture mipTex )
		{
			//Entering critical section
			LockDeviceAccess();

			var bufferResources = GetBufferResources( dev );
			var isNewBuffer = false;

			if ( bufferResources == null )
			{
				bufferResources = new BufferResources();
				this.mapDeviceToBufferResources.Add( dev, bufferResources );
				isNewBuffer = true;
			}

			bufferResources.MipTex = mipTex;
			bufferResources.Volume = volume;

			var desc = volume.Description;
			width = desc.Width;
			height = desc.Height;
			depth = desc.Depth;
			format = D3D9Helper.ConvertEnum( desc.Format );
			// Default
			rowPitch = Width;
			slicePitch = Height*Width;
			sizeInBytes = PixelUtil.GetMemorySize( Width, Height, Depth, Format );

			if ( isNewBuffer && this.ownerTexture.IsManuallyLoaded )
			{
				foreach ( var it in this.mapDeviceToBufferResources )
				{
					if ( it.Value != bufferResources && it.Value.Volume != null && it.Key.TestCooperativeLevel().Success &&
					     dev.TestCooperativeLevel().Success )
					{
						var fullBufferBox = new BasicBox( 0, 0, 0, Width, Height, Depth );
						var dstBox = new PixelBox( fullBufferBox, Format );

						var data = new byte[sizeInBytes];
						using ( var d = BufferBase.Wrap( data ) )
						{
							dstBox.Data = d;
							BlitToMemory( fullBufferBox, dstBox, it.Value, it.Key );
							BlitFromMemory( dstBox, fullBufferBox, bufferResources );
							Array.Clear( data, 0, sizeInBytes );
						}
						break;
					}
				}
			}

			//Leaving critical section
			UnlockDeviceAccess();
		}
		public GLESHardwarePixelBuffer( int width, int height, int depth, PixelFormat format, BufferUsage usage )
			: base( width, height, depth, format, usage, false, false )
		{
			_buffer = new PixelBox( width, height, depth, format );
			_glInternalFormat = 0;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="src"></param>
		/// <param name="dstBox"></param>
		public override void BlitFromMemory( PixelBox src, Media.BasicBox dstBox )
		{
			if ( !_buffer.Contains( dstBox ) )
			{
				throw new ArgumentOutOfRangeException( "Destination box out of range, GLESHardwarePixelBuffer.BlitToMemory" );
			}

			PixelBox scaled;

			if ( src.Width != dstBox.Width ||
				 src.Height != dstBox.Height ||
				 src.Depth != dstBox.Depth )
			{
				LogManager.Instance.Write( "[GLESHardwarePixelBuffer] Scale to destination size." );
				// Scale to destination size. Use DevIL and not iluScale because ILU screws up for 
				// floating point textures and cannot cope with 3D images.
				// This also does pixel format conversion if needed
				AllocateBuffer();
				scaled = _buffer.GetSubVolume( dstBox );
				Image.Scale( src, scaled, ImageFilter.Bilinear );
			}
			else if ( ( src.Format != Format ) ||
					( ( GLESPixelUtil.GetGLOriginFormat( src.Format ) == 0 ) && ( src.Format != PixelFormat.R8G8B8 ) ) )
			{
				LogManager.Instance.Write( "[GLESHardwarePixelBuffer] Extents match, but format is not accepted as valid source format for GL." );
				LogManager.Instance.Write( "[GLESHardwarePixelBuffer] Source.Format = {0}, Format = {1}, GLOriginFormat = {2}", src.Format, Format, GLESPixelUtil.GetGLOriginFormat( src.Format ) );
				// Extents match, but format is not accepted as valid source format for GL
				// do conversion in temporary buffer
				AllocateBuffer();
				scaled = _buffer.GetSubVolume( dstBox );

				PixelConverter.BulkPixelConversion( src, scaled );
			}
			else
			{
				LogManager.Instance.Write( "[GLESHardwarePixelBuffer] No scaling or conversion needed." );
				scaled = src;
				if ( src.Format == PixelFormat.R8G8B8 )
				{
					scaled.Format = PixelFormat.R8G8B8;
					PixelConverter.BulkPixelConversion( src, scaled );
				}
				// No scaling or conversion needed
				// Set extents for upload
				scaled.Left = dstBox.Left;
				scaled.Right = dstBox.Right;
				scaled.Top = dstBox.Top;
				scaled.Bottom = dstBox.Bottom;
				scaled.Front = dstBox.Front;
				scaled.Back = dstBox.Back;
			}

			Upload( scaled, dstBox );
			FreeBuffer();
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="data"></param>
		protected virtual void Download( PixelBox data )
		{
			throw new AxiomException( "Download not possible for this pixelbuffer type" );
		}
Exemple #20
0
 public abstract void CopyContentsToMemory(PixelBox pb, FrameBuffer buffer);
        public static bool DoOptimizedConversion(PixelBox src, PixelBox dst)
        {
            switch (((int)src.Format << 8) + (int)dst.Format)
            {
            case ((int)PixelFormat.A8R8G8B8 << 8) + (int)PixelFormat.A8B8G8R8:
                A8R8G8B8toA8B8G8R8(src, dst);
                break;

            case ((int)PixelFormat.A8R8G8B8 << 8) + (int)PixelFormat.B8G8R8A8:
                A8R8G8B8toB8G8R8A8(src, dst);
                break;

            case ((int)PixelFormat.A8R8G8B8 << 8) + (int)PixelFormat.R8G8B8A8:
                A8R8G8B8toR8G8B8A8(src, dst);
                break;

            case ((int)PixelFormat.A8B8G8R8 << 8) + (int)PixelFormat.A8R8G8B8:
                A8B8G8R8toA8R8G8B8(src, dst);
                break;

            case ((int)PixelFormat.A8B8G8R8 << 8) + (int)PixelFormat.B8G8R8A8:
                A8B8G8R8toB8G8R8A8(src, dst);
                break;

            case ((int)PixelFormat.A8B8G8R8 << 8) + (int)PixelFormat.R8G8B8A8:
                A8B8G8R8toR8G8B8A8(src, dst);
                break;

            case ((int)PixelFormat.B8G8R8A8 << 8) + (int)PixelFormat.A8R8G8B8:
                B8G8R8A8toA8R8G8B8(src, dst);
                break;

            case ((int)PixelFormat.B8G8R8A8 << 8) + (int)PixelFormat.A8B8G8R8:
                B8G8R8A8toA8B8G8R8(src, dst);
                break;

            case ((int)PixelFormat.B8G8R8A8 << 8) + (int)PixelFormat.R8G8B8A8:
                B8G8R8A8toR8G8B8A8(src, dst);
                break;

            //case ((int)PixelFormat.R8G8B8A8 << 8) + (int)PixelFormat.A8R8G8B8:
            //    R8G8B8A8toA8R8G8B8(src, dst);
            //    break;
            case ((int)PixelFormat.R8G8B8A8 << 8) + (int)PixelFormat.A8B8G8R8:
                R8G8B8A8toA8B8G8R8(src, dst);
                break;

            case ((int)PixelFormat.R8G8B8A8 << 8) + (int)PixelFormat.B8G8R8A8:
                R8G8B8A8toB8G8R8A8(src, dst);
                break;

            case ((int)PixelFormat.A8B8G8R8 << 8) + (int)PixelFormat.L8:
                A8B8G8R8toL8(src, dst);
                break;

            case ((int)PixelFormat.L8 << 8) + (int)PixelFormat.A8B8G8R8:
                L8toA8B8G8R8(src, dst);
                break;

            case ((int)PixelFormat.A8R8G8B8 << 8) + (int)PixelFormat.L8:
                A8R8G8B8toL8(src, dst);
                break;

            case ((int)PixelFormat.L8 << 8) + (int)PixelFormat.A8R8G8B8:
                L8toA8R8G8B8(src, dst);
                break;

            case ((int)PixelFormat.B8G8R8A8 << 8) + (int)PixelFormat.L8:
                B8G8R8A8toL8(src, dst);
                break;

            case ((int)PixelFormat.L8 << 8) + (int)PixelFormat.B8G8R8A8:
                L8toB8G8R8A8(src, dst);
                break;

            case ((int)PixelFormat.L8 << 8) + (int)PixelFormat.L16:
                L8toL16(src, dst);
                break;

            case ((int)PixelFormat.L16 << 8) + (int)PixelFormat.L8:
                L16toL8(src, dst);
                break;

            case ((int)PixelFormat.B8G8R8 << 8) + (int)PixelFormat.R8G8B8:
                B8G8R8toR8G8B8(src, dst);
                break;

            case ((int)PixelFormat.R8G8B8 << 8) + (int)PixelFormat.B8G8R8:
                R8G8B8toB8G8R8(src, dst);
                break;

            case ((int)PixelFormat.R8G8B8 << 8) + (int)PixelFormat.A8R8G8B8:
                R8G8B8toA8R8G8B8(src, dst);
                break;

            case ((int)PixelFormat.B8G8R8 << 8) + (int)PixelFormat.A8R8G8B8:
                B8G8R8toA8R8G8B8(src, dst);
                break;

            case ((int)PixelFormat.R8G8B8 << 8) + (int)PixelFormat.A8B8G8R8:
                R8G8B8toA8B8G8R8(src, dst);
                break;

            case ((int)PixelFormat.B8G8R8 << 8) + (int)PixelFormat.A8B8G8R8:
                B8G8R8toA8B8G8R8(src, dst);
                break;

            case ((int)PixelFormat.R8G8B8 << 8) + (int)PixelFormat.B8G8R8A8:
                R8G8B8toB8G8R8A8(src, dst);
                break;

            case ((int)PixelFormat.B8G8R8 << 8) + (int)PixelFormat.B8G8R8A8:
                B8G8R8toB8G8R8A8(src, dst);
                break;

            case ((int)PixelFormat.A8R8G8B8 << 8) + (int)PixelFormat.R8G8B8:
                A8R8G8B8toR8G8B8(src, dst);
                break;

            case ((int)PixelFormat.A8R8G8B8 << 8) + (int)PixelFormat.B8G8R8:
                A8R8G8B8toB8G8R8(src, dst);
                break;

            case ((int)PixelFormat.X8R8G8B8 << 8) + (int)PixelFormat.A8R8G8B8:
                X8R8G8B8toA8R8G8B8(src, dst);
                break;

            case ((int)PixelFormat.X8R8G8B8 << 8) + (int)PixelFormat.A8B8G8R8:
                X8R8G8B8toA8B8G8R8(src, dst);
                break;

            case ((int)PixelFormat.X8R8G8B8 << 8) + (int)PixelFormat.B8G8R8A8:
                X8R8G8B8toB8G8R8A8(src, dst);
                break;

            case ((int)PixelFormat.X8R8G8B8 << 8) + (int)PixelFormat.R8G8B8A8:
                X8R8G8B8toR8G8B8A8(src, dst);
                break;

            case ((int)PixelFormat.X8B8G8R8 << 8) + (int)PixelFormat.A8R8G8B8:
                X8B8G8R8toA8R8G8B8(src, dst);
                break;

            case ((int)PixelFormat.X8B8G8R8 << 8) + (int)PixelFormat.A8B8G8R8:
                X8B8G8R8toA8B8G8R8(src, dst);
                break;

            case ((int)PixelFormat.X8B8G8R8 << 8) + (int)PixelFormat.B8G8R8A8:
                X8B8G8R8toB8G8R8A8(src, dst);
                break;

            case ((int)PixelFormat.X8B8G8R8 << 8) + (int)PixelFormat.R8G8B8A8:
                X8B8G8R8toR8G8B8A8(src, dst);
                break;

            default:
                return(false);
            }
            return(true);
        }
Exemple #22
0
        //-----------------------------------------------------------------------
        public static void ToAxiom(PixelBox dst)
        {
            if (!dst.Consecutive)
            {
                throw new NotImplementedException("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 AxiomException("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 = ILUtil.ConvertToILFormat(dst.Format);

            if (ifmt.format == ilfmt && ILabs(ifmt.type) == ILabs(iltp))
            {
                int size = Il.ilGetInteger(Il.IL_IMAGE_SIZE_OF_DATA);
                // Copy from the IL structure to our buffer
                PixelUtil.CopyBytes(dst.Data, dst.Offset, Il.ilGetData(), 0, size);
                return;
            }
            // Try if buffer is in a known OGRE format so we can use OGRE its
            // conversion routines
            PixelFormat bufFmt = ILUtil.ConvertFromILFormat(ilfmt, iltp);

            ifmt = ILUtil.ConvertToILFormat(bufFmt);

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

#if NOT
            // The extremely slow method
            if (iltp == Il.IL_UNSIGNED_BYTE || iltp == Il.IL_BYTE)
            {
                ilToOgreInternal(static_cast <uint8 *>(dst.data), dst.format, (uint8)0x00, (uint8)0x00, (uint8)0x00, (uint8)0xFF);
            }
            else if (iltp == IL_FLOAT)
            {
                ilToOgreInternal(static_cast <uint8 *>(dst.data), dst.format, 0.0f, 0.0f, 0.0f, 1.0f);
            }
            else if (iltp == IL_SHORT || iltp == IL_UNSIGNED_SHORT)
            {
                ilToOgreInternal(static_cast <uint8 *>(dst.data), dst.format,
                                 (uint16)0x0000, (uint16)0x0000, (uint16)0x0000, (uint16)0xFFFF);
            }
            else
            {
                OGRE_EXCEPT(Exception::UNIMPLEMENTED_FEATURE,
                            "Cannot convert this DevIL type",
                            "ILUtil::ilToOgre");
            }
#else
            throw new NotImplementedException("Cannot convert this DevIL type");
#endif
        }
            public void Scale(PixelBox src, PixelBox dst)
            {
                // assert(src.format == dst.format);

                // only optimized for 2D
                if (src.Depth > 1 || dst.Depth > 1)
                {
                    (new LinearResampler()).Scale(src, dst);
                    return;
                }

#if !AXIOM_SAFE_ONLY
                unsafe
#endif
                {
                    // srcdata stays at beginning of slice, pdst is a moving pointer
                    var srcdata = src.Data.ToBytePointer();
                    var dstData = dst.Data.ToBytePointer();
                    var pdst    = 0;

                    // sx_48,sy_48 represent current position in source
                    // using 16/48-bit fixed precision, incremented by steps
                    var stepx = (UInt64)((src.Width << 48) / dst.Width);
                    var stepy = (UInt64)((src.Height << 48) / dst.Height);

                    // bottom 28 bits of temp are 16/12 bit fixed precision, used to
                    // adjust a source coordinate 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;

                    var sy_48 = (stepy >> 1) - 1;
                    for (var y = (uint)dst.Top; y < dst.Bottom; y++, sy_48 += stepy)
                    {
                        temp = (uint)(sy_48 >> 36);
                        temp = (temp > 0x800) ? temp - 0x800 : 0;
                        var syf    = temp & 0xFFF;
                        var sy1    = temp >> 12;
                        var sy2    = (uint)System.Math.Min(sy1 + 1, src.Bottom - src.Top - 1);
                        var syoff1 = (uint)(sy1 * src.RowPitch);
                        var syoff2 = (uint)(sy2 * src.RowPitch);

                        var sx_48 = (stepx >> 1) - 1;
                        for (var x = (uint)dst.Left; x < dst.Right; x++, sx_48 += stepx)
                        {
                            temp = (uint)(sx_48 >> 36);
                            temp = (temp > 0x800) ? temp - 0x800 : 0;
                            var sxf = temp & 0xFFF;
                            var sx1 = temp >> 12;
                            var sx2 = (uint)System.Math.Min(sx1 + 1, src.Right - src.Left - 1);

                            var sxfsyf = sxf * syf;
                            for (uint k = 0; k < this._channels; k++)
                            {
                                var accum =
                                    (uint)
                                    (srcdata[(int)((sx1 + syoff1) * this._channels + k)] *
                                     (char)(0x1000000 - (sxf << 12) - (syf << 12) + sxfsyf) +
                                     srcdata[(int)((sx2 + syoff1) * this._channels + k)] * (char)((sxf << 12) - sxfsyf) +
                                     srcdata[(int)((sx1 + syoff2) * this._channels + k)] * (char)((syf << 12) - sxfsyf) +
                                     srcdata[(int)((sx2 + syoff2) * this._channels + k)] * (char)sxfsyf);
                                // accum is computed using 8/24-bit fixed-point math
                                // (maximum is 0xFF000000; rounding will not cause overflow)
                                dstData[pdst++] = (byte)((accum + 0x800000) >> 24);
                            }
                        }
                        pdst += this._channels * dst.RowSkip;
                    }
                }
            }
Exemple #24
0
        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);
        }
		protected PixelBox LockBuffer( BufferResources bufferResources, BasicBox lockBox, D3D9.LockFlags flags )
		{
			// Set extents and format
			// Note that we do not carry over the left/top/front here, since the returned
			// PixelBox will be re-based from the locking point onwards
			var rval = new PixelBox( lockBox.Width, lockBox.Height, lockBox.Depth, Format );

			if ( bufferResources.Surface != null )
			{
				//Surface
				DX.DataRectangle lrect; // Filled in by D3D

				if ( lockBox.Left == 0 && lockBox.Top == 0 && lockBox.Right == Width && lockBox.Bottom == Height )
				{
					// Lock whole surface
					lrect = bufferResources.Surface.LockRectangle( flags );
				}
				else
				{
					var prect = ToD3DRectangle( lockBox );
					lrect = bufferResources.Surface.LockRectangle( prect, flags );
				}

				FromD3DLock( rval, lrect );
			}
			else if ( bufferResources.Volume != null )
			{
				// Volume
				var pbox = ToD3DBox( lockBox ); // specify range to lock
				var lbox = bufferResources.Volume.LockBox( pbox, flags );
				FromD3DLock( rval, lbox );
			}

			return rval;
		}
Exemple #26
0
 /// <summary>
 /// </summary>
 /// <param name="src"> </param>
 /// <param name="temp"> </param>
 public static void Scale(PixelBox src, PixelBox temp)
 {
     Scale(src, temp, PixelUtil.GetNumElemBytes(src.Format));
 }
		protected void BlitFromMemory( PixelBox src, BasicBox dstBox, BufferResources dstBufferResources )
		{
			// for scoped deletion of conversion buffer
			var converted = src;
			var bufSize = 0;

			// convert to pixelbuffer's native format if necessary
			if ( D3D9Helper.ConvertEnum( src.Format ) == D3D9.Format.Unknown )
			{
				bufSize = PixelUtil.GetMemorySize( src.Width, src.Height, src.Depth, Format );
				var newBuffer = new byte[bufSize];
				using ( var data = BufferBase.Wrap( newBuffer ) )
				{
					converted = new PixelBox( src.Width, src.Height, src.Depth, Format, data );
				}
				PixelConverter.BulkPixelConversion( src, converted );
			}

			int rowWidth = 0;
			if ( PixelUtil.IsCompressed( converted.Format ) )
			{
				rowWidth = converted.RowPitch/4;
				// D3D wants the width of one row of cells in bytes
				if ( converted.Format == PixelFormat.DXT1 )
				{
					// 64 bits (8 bytes) per 4x4 block
					rowWidth *= 8;
				}
				else
				{
					// 128 bits (16 bytes) per 4x4 block
					rowWidth *= 16;
				}
			}
			else
			{
				rowWidth = converted.RowPitch*PixelUtil.GetNumElemBytes( converted.Format );
			}

			if ( dstBufferResources.Surface != null )
			{
				var srcRect = ToD3DRectangle( converted );
				var destRect = ToD3DRectangle( dstBox );

				bufSize = PixelUtil.GetMemorySize( converted.Width, converted.Height, converted.Depth, converted.Format );
				var data = new byte[bufSize];
				using ( var dest = BufferBase.Wrap( data ) )
				{
					Memory.Copy( converted.Data, dest, bufSize );
				}

				try
				{
					D3D9.Surface.FromMemory( dstBufferResources.Surface, data, D3D9.Filter.Default, 0,
					                         D3D9Helper.ConvertEnum( converted.Format ), rowWidth, srcRect, destRect );
				}
				catch ( Exception e )
				{
					throw new AxiomException( "D3D9.Surface.FromMemory failed in D3D9HardwarePixelBuffer.BlitFromMemory", e );
				}
			}
			else if ( dstBufferResources.Volume != null )
			{
				var srcBox = ToD3DBox( converted );
				var destBox = ToD3DBox( dstBox );
				var sliceWidth = 0;
				if ( PixelUtil.IsCompressed( converted.Format ) )
				{
					sliceWidth = converted.SlicePitch/16;
					// D3D wants the width of one slice of cells in bytes
					if ( converted.Format == PixelFormat.DXT1 )
					{
						// 64 bits (8 bytes) per 4x4 block
						sliceWidth *= 8;
					}
					else
					{
						// 128 bits (16 bytes) per 4x4 block
						sliceWidth *= 16;
					}
				}
				else
				{
					sliceWidth = converted.SlicePitch*PixelUtil.GetNumElemBytes( converted.Format );
				}

				bufSize = PixelUtil.GetMemorySize( converted.Width, converted.Height, converted.Depth, converted.Format );
                var data = new byte[ bufSize ];
				using ( var dest = BufferBase.Wrap( data ) )
				{
					Memory.Copy( converted.Data, dest, bufSize );
				}

				try
				{
                    using ( var srcData = BufferBase.Wrap( data ) )
                    {
                        var srcMemoryPtr = new IntPtr( srcData.Ptr );
                        dstBufferResources.Volume.LoadFromMemory( null, destBox, srcMemoryPtr, D3D9Helper.ConvertEnum( converted.Format ),
                            rowWidth, slicePitch, null, srcBox, D3D9.Filter.Default, 0 );
                    }
				}
				catch ( Exception e )
				{
					throw new AxiomException( "D3D9.Volume.FromFileInMemory failed in D3D9HardwarePixelBuffer.BlitFromMemory", e );
				}
			}

			if ( this.doMipmapGen )
			{
				GenMipmaps( dstBufferResources.MipTex );
			}
		}
Exemple #28
0
		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." );
			}
		}
Exemple #29
0
 public void CopyContentsToMemory(PixelBox pb)
 {
     CopyContentsToMemory(pb, FrameBuffer.Auto);
 }
Exemple #30
0
		static public void ConvertToIL( PixelBox src )
		{
			// ilTexImage http://openil.sourceforge.net/docs/il/f00059.htm
			ILFormat ifmt = Convert( src.Format );
			if ( src.IsConsecutive && ifmt.IsValid )
			{
				// The easy case, the buffer is laid out in memory just like 
				// we want it to be and is in a format DevIL can understand directly
				// We could even save the copy if DevIL would let us
				Il.ilTexImage( src.Width, src.Height, src.Depth, (byte)ifmt.Channels, ifmt.Format, ifmt.Type, src.Data );
			}
			else if ( ifmt.IsValid )
			{
				// The format can be understood directly by DevIL. The only 
				// problem is that ilTexImage expects our image data consecutively 
				// so we cannot use that directly.

				// Let DevIL allocate the memory for us, and copy the data consecutively
				// to its memory
				Il.ilTexImage( src.Width, src.Height, src.Depth, (byte)ifmt.Channels, ifmt.Format, ifmt.Type, IntPtr.Zero );
				PixelBox dst = new PixelBox( src.Width, src.Height, src.Depth, src.Format, Il.ilGetData() );
				PixelConverter.BulkPixelConversion( src, dst );
			}
			else
			{
				// Here it gets ugly. We're stuck with a pixel format that DevIL
				// can't do anything with. We will do a bulk pixel conversion and
				// then feed it to DevIL anyway. The problem is finding the best
				// format to convert to.

				// most general format supported by Axiom and DevIL
				PixelFormat fmt = PixelUtil.HasAlpha( src.Format ) ? PixelFormat.FLOAT32_RGBA : PixelFormat.FLOAT32_RGB;

				// Make up a pixel format
				// We don't have to consider luminance formats as they have
				// straight conversions to DevIL, just weird permutations of RGBA an LA
				int[] depths = PixelUtil.GetBitDepths( src.Format );

				// Native endian format with all bit depths<8 can safely and quickly be 
				// converted to 24/32 bit
				if ( PixelUtil.IsNativeEndian( src.Format ) &&
					depths[ 0 ] <= 8 && depths[ 1 ] <= 8 && depths[ 2 ] <= 8 && depths[ 3 ] <= 8 )
				{
					if ( PixelUtil.HasAlpha( src.Format ) )
					{
						fmt = PixelFormat.A8R8G8B8;
					}
					else
					{
						fmt = PixelFormat.R8G8B8;
					}
				}

				// Let DevIL allocate the memory for us, then do the conversion ourselves
				ifmt = Convert( fmt );
				Il.ilTexImage( src.Width, src.Height, src.Depth, (byte)ifmt.Channels, ifmt.Format, ifmt.Type, IntPtr.Zero ); // TAO 2.0
				//Il.ilTexImage( src.Width, src.Height, src.Depth, (byte)ifmt.Channels, ifmt.Format, ifmt.Type, null );
				IntPtr data = Il.ilGetData();
				PixelBox dst = new PixelBox( src.Width, src.Height, src.Depth, fmt, data );
				PixelConverter.BulkPixelConversion( src, dst );
			}
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="data"></param>
		/// <param name="dest"></param>
		protected virtual void Upload( PixelBox data, BasicBox dest )
		{
			throw new AxiomException( "Upload not possible for this pixelbuffer type" );
		}
Exemple #32
0
		public void WriteContentsToFile( string fileName )
		{
			var pf = SuggestPixelFormat();

			var data = new byte[Width*Height*PixelUtil.GetNumElemBytes( pf )];
			var buf = BufferBase.Wrap( data );
			var pb = new PixelBox( Width, Height, 1, pf, buf );

			CopyContentsToMemory( pb );

			( new Image() ).FromDynamicImage( data, Width, Height, 1, pf, false, 1, 0 ).Save( fileName );
			buf.Dispose();
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="srcBox"></param>
		/// <param name="dst"></param>
		public override void BlitToMemory( BasicBox srcBox, PixelBox dst )
		{
			if ( !_buffer.Contains( srcBox ) )
			{
				throw new ArgumentOutOfRangeException( "source boux out of range" );
			}

			if ( srcBox.Left == 0 && srcBox.Right == Width &&
				srcBox.Top == 0 && srcBox.Bottom == Height &&
				srcBox.Front == 0 && srcBox.Back == Depth &&
				dst.Width == Width &&
				dst.Height == Height &&
				dst.Depth == Depth &&
				GLESPixelUtil.GetGLOriginFormat( dst.Format ) != 0 )
			{
				// The direct case: the user wants the entire texture in a format supported by GL
				// so we don't need an intermediate buffer
				Download( dst );
			}
			else
			{
				// Use buffer for intermediate copy
				AllocateBuffer();
				//download entire buffer
				Download( _buffer );
				if ( srcBox.Width != dst.Width ||
					srcBox.Height != dst.Height ||
					srcBox.Depth != dst.Depth )
				{
					// we need scaling
					Image.Scale( _buffer.GetSubVolume( srcBox ), dst, ImageFilter.Bilinear );
				}
				else
				{
					// Just copy the bit that we need
					PixelConverter.BulkPixelConversion( _buffer.GetSubVolume( srcBox ), dst );
				}
				FreeBuffer();
			}
		}
		protected void BlitToMemory( BasicBox srcBox, PixelBox dst, BufferResources srcBufferResources, D3D9.Device d3d9Device )
		{
			// Decide on pixel format of temp surface
			PixelFormat tmpFormat = Format;
			if ( D3D9Helper.ConvertEnum( dst.Format ) != D3D9.Format.Unknown )
			{
				tmpFormat = dst.Format;
			}

			if ( srcBufferResources.Surface != null )
			{
				Debug.Assert( srcBox.Depth == 1 && dst.Depth == 1 );
				var srcDesc = srcBufferResources.Surface.Description;
				var temppool = D3D9.Pool.Scratch;

				// if we're going to try to use GetRenderTargetData, need to use system mem pool
				var tryGetRenderTargetData = false;
				if ( ( ( srcDesc.Usage & D3D9.Usage.RenderTarget ) != 0 ) && ( srcBox.Width == dst.Width ) &&
				     ( srcBox.Height == dst.Height ) && ( srcBox.Width == Width ) && ( srcBox.Height == Height ) &&
				     ( Format == tmpFormat ) )
				{
					tryGetRenderTargetData = true;
					temppool = D3D9.Pool.SystemMemory;
				}

				// Create temp texture
				var tmp = new D3D9.Texture( d3d9Device, dst.Width, dst.Height, 1, // 1 mip level ie topmost, generate no mipmaps
				                            0, D3D9Helper.ConvertEnum( tmpFormat ), temppool );

				var surface = tmp.GetSurfaceLevel( 0 );

				// Copy texture to this temp surface
				var srcRect = ToD3DRectangle( srcBox );
				var destRect = ToD3DRectangle( dst );

				// Get the real temp surface format
				var dstDesc = surface.Description;
				tmpFormat = D3D9Helper.ConvertEnum( dstDesc.Format );

				// Use fast GetRenderTargetData if we are in its usage conditions
				var fastLoadSuccess = false;
				if ( tryGetRenderTargetData )
				{
					var result = d3d9Device.GetRenderTargetData( srcBufferResources.Surface, surface );
					fastLoadSuccess = result.Success;
				}
				if ( !fastLoadSuccess )
				{
					var res = D3D9.Surface.FromSurface( surface, srcBufferResources.Surface, D3D9.Filter.Default, 0, srcRect, destRect );
					if ( res.Failure )
					{
						surface.SafeDispose();
						tmp.SafeDispose();
						throw new AxiomException( "D3D9.Surface.FromSurface failed in D3D9HardwarePixelBuffer.BlitToMemory" );
					}
				}

				// Lock temp surface and copy it to memory
				var lrect = surface.LockRectangle( D3D9.LockFlags.ReadOnly );

				// Copy it
				var locked = new PixelBox( dst.Width, dst.Height, dst.Depth, tmpFormat );
				FromD3DLock( locked, lrect );
				PixelConverter.BulkPixelConversion( locked, dst );
				surface.UnlockRectangle();
				// Release temporary surface and texture
				surface.SafeDispose();
				tmp.SafeDispose();
			}
			else if ( srcBufferResources.Volume != null )
			{
				// Create temp texture
				var tmp = new D3D9.VolumeTexture( d3d9Device, dst.Width, dst.Height, dst.Depth, 0, 0,
				                                  D3D9Helper.ConvertEnum( tmpFormat ), D3D9.Pool.Scratch );

				var surface = tmp.GetVolumeLevel( 0 );

				// Volume
				var ddestBox = ToD3DBoxExtent( dst );
				var dsrcBox = ToD3DBox( srcBox );

				var res = D3D9.Volume.FromVolume( surface, srcBufferResources.Volume, D3D9.Filter.Default, 0, dsrcBox, ddestBox );
				if ( res.Failure )
				{
					surface.SafeDispose();
					tmp.SafeDispose();
					throw new AxiomException( "D3D9.Surface.FromVolume failed in D3D9HardwarePixelBuffer.BlitToMemory" );
				}

				// Lock temp surface and copy it to memory
				var lbox = surface.LockBox( D3D9.LockFlags.ReadOnly ); // Filled in by D3D

				// Copy it
				var locked = new PixelBox( dst.Width, dst.Height, dst.Depth, tmpFormat );
				FromD3DLock( locked, lbox );
				PixelConverter.BulkPixelConversion( locked, dst );
				surface.UnlockBox();
				// Release temporary surface and texture
				surface.SafeDispose();
				tmp.SafeDispose();
			}
		}
		/// <summary>
		///     Called to destroy this buffer.
		/// </summary>
		protected override void dispose( bool disposeManagedResources )
		{
			if ( !IsDisposed )
			{
				if ( disposeManagedResources )
				{
					if ( data != null )
					{
						Memory.UnpinObject( data );
						data = null;
						_buffer.Data = IntPtr.Zero;
						_buffer = null;
					}
				}
			}

			// If it is available, make the call to the
			// base class's Dispose(Boolean) method
			base.dispose( disposeManagedResources );
		}
Exemple #36
0
		public override void EncodeToFile( Stream input, string outFileName, Codec.CodecData codecData )
		{
			int imageID;

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

			var buffer = new byte[input.Length];
			input.Read( buffer, 0, buffer.Length );

			var imgData = (ImageData)codecData;

			PixelBox src;
			using ( var bufHandle = BufferBase.Wrap( buffer ) )
			{
				src = new PixelBox( imgData.width, imgData.height, imgData.depth, imgData.format, bufHandle );
			}

			try
			{
				// Convert image from Axiom to current IL image
				ILUtil.ConvertToIL( src );
			}
			catch ( Exception ex )
			{
				LogManager.Instance.Write( "IL Failed image conversion :", ex.Message );
			}

			// flip the image
			Ilu.iluFlipImage();

			// save the image to file
			Il.ilSaveImage( outFileName );

			var error = Il.ilGetError();

			if ( error != Il.IL_NO_ERROR )
			{
				LogManager.Instance.Write( "IL Error, could not save file: {0} : {1}", outFileName, Ilu.iluErrorString( error ) );
			}

			Il.ilDeleteImages( 1, ref imageID );
		}
        public override object Decode(Stream input, Stream output, params object[] args)
        {
            ImageData data = new ImageData();

            int imageID;
            int format, bytesPerPixel, imageType;

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

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

            // create a temp buffer and write the stream into it
            byte[] buffer = new byte[input.Length];
            input.Read(buffer, 0, buffer.Length);

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

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

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

            format = Il.ilGetInteger(Il.IL_IMAGE_FORMAT);
            imageType = Il.ilGetInteger(Il.IL_IMAGE_TYPE);
            //bytesPerPixel = Math.Max(Il.ilGetInteger(Il.IL_IMAGE_BPC),
            //                         Il.ilGetInteger(Il.IL_IMAGE_BYTES_PER_PIXEL));

            // 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(format, Il.IL_FLOAT);
                imageType = Il.IL_FLOAT;
            }
            // Converted paletted images
            if (format == Il.IL_COLOUR_INDEX) {
                Il.ilConvertImage(Il.IL_BGRA, Il.IL_UNSIGNED_BYTE);
                format = Il.IL_BGRA;
                imageType = Il.IL_UNSIGNED_BYTE;
            }

            bytesPerPixel = Il.ilGetInteger(Il.IL_IMAGE_BYTES_PER_PIXEL);

            // populate the image data
            data.format = ILUtil.ConvertFromILFormat(format, imageType);
            data.width = Il.ilGetInteger(Il.IL_IMAGE_WIDTH);
            data.height = Il.ilGetInteger(Il.IL_IMAGE_HEIGHT);
            data.depth = Il.ilGetInteger(Il.IL_IMAGE_DEPTH);
            data.numMipMaps = Il.ilGetInteger(Il.IL_NUM_MIPMAPS);
            data.flags = 0;

            if (data.format == PixelFormat.Unknown) {
                Il.ilDeleteImages(1, ref imageID);
                throw new AxiomException("Unsupported DevIL format: ImageFormat = {0:x} ImageType = {1:x}", format, imageType);
            }

            // Check for cubemap
            // int cubeflags = Il.ilGetInteger(Il.IL_IMAGE_CUBEFLAGS);
            int numFaces = Il.ilGetInteger(Il.IL_NUM_IMAGES) + 1;
            if (numFaces == 6)
                data.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)
            int dxtFormat = Il.ilGetInteger(Il.IL_DXTC_DATA_FORMAT);
            if (dxtFormat != Il.IL_DXT_NO_COMP &&
                Root.Instance.RenderSystem.Caps.CheckCap(Axiom.Graphics.Capabilities.TextureCompressionDXT))
            {
                data.format = ILUtil.ConvertFromILFormat(dxtFormat, imageType);
                data.flags |= ImageFlags.Compressed;

                // Validate that this devil version saves DXT mipmaps
                if (data.numMipMaps > 0)
                {
                    Il.ilBindImage(imageID);
                    Il.ilActiveMipmap(1);
                    if (Il.ilGetInteger(Il.IL_DXTC_DATA_FORMAT) != dxtFormat)
                    {
                        data.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
            data.size = Image.CalculateSize(data.numMipMaps, numFaces,
                                            data.width, data.height,
                                            data.depth, data.format);

            // set up buffer for the decoded data
            buffer = new byte[data.size];
            // Pin the buffer, so we can use our PixelBox methods on it
            GCHandle bufGCHandle = new GCHandle();
            bufGCHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            IntPtr bufPtr = bufGCHandle.AddrOfPinnedObject();

            int offset = 0;

            // Dimensions of current mipmap
            int width = data.width;
            int height = data.height;
            int depth = data.depth;

            // Transfer data
            for (int mip=0; mip <= data.numMipMaps; ++mip)
            {
                for (int i = 0; i < numFaces; ++i)
                {
                    Il.ilBindImage(imageID);
                    if (numFaces > 1)
                        Il.ilActiveImage(i);
                    if (data.numMipMaps > 0)
                        Il.ilActiveMipmap(mip);
                    /// Size of this face
                    int imageSize = PixelUtil.GetMemorySize(width, height, depth, data.format);
                    if ((data.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
                            byte[] tmpBuffer = new byte[imageSize];
                            Il.ilGetDXTCData(tmpBuffer, imageSize, dxtFormat);
                            // Copy the data into our output buffer
                            Array.Copy(tmpBuffer, 0, buffer, offset, tmpBuffer.Length);
                        } 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
                        PixelBox dst = new PixelBox(width, height, depth, data.format, bufPtr);
                        dst.Offset = offset;
                        ILUtil.ToAxiom(dst);
                    }
                    offset += imageSize;
                }

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

            // we won't be needing this anymore
            Il.ilDeleteImages(1, ref imageID);

            output.Write(buffer, 0, buffer.Length);

            // Free the buffer we allocated for the conversion.
            // I used bufPtr to store my data while I converted it.
            // I need to free it here.  This invalidates bufPtr.
            // My data has already been copied to output.
            if (bufGCHandle.IsAllocated)
                bufGCHandle.Free();

            return data;
        }
        public override object Decode(Stream input, Stream output, params object[] args)
        {
            ImageData data = new ImageData();

            int imageID;
            int format, bytesPerPixel, imageType;

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

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

            // create a temp buffer and write the stream into it
            byte[] buffer = new byte[input.Length];
            input.Read(buffer, 0, buffer.Length);

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

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

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

            format    = Il.ilGetInteger(Il.IL_IMAGE_FORMAT);
            imageType = Il.ilGetInteger(Il.IL_IMAGE_TYPE);
            //bytesPerPixel = Math.Max(Il.ilGetInteger(Il.IL_IMAGE_BPC),
            //                         Il.ilGetInteger(Il.IL_IMAGE_BYTES_PER_PIXEL));

            // 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(format, Il.IL_FLOAT);
                imageType = Il.IL_FLOAT;
            }
            // Converted paletted images
            if (format == Il.IL_COLOUR_INDEX)
            {
                Il.ilConvertImage(Il.IL_BGRA, Il.IL_UNSIGNED_BYTE);
                format    = Il.IL_BGRA;
                imageType = Il.IL_UNSIGNED_BYTE;
            }

            bytesPerPixel = Il.ilGetInteger(Il.IL_IMAGE_BYTES_PER_PIXEL);

            // populate the image data
            data.format     = ILUtil.ConvertFromILFormat(format, imageType);
            data.width      = Il.ilGetInteger(Il.IL_IMAGE_WIDTH);
            data.height     = Il.ilGetInteger(Il.IL_IMAGE_HEIGHT);
            data.depth      = Il.ilGetInteger(Il.IL_IMAGE_DEPTH);
            data.numMipMaps = Il.ilGetInteger(Il.IL_NUM_MIPMAPS);
            data.flags      = 0;

            if (data.format == PixelFormat.Unknown)
            {
                Il.ilDeleteImages(1, ref imageID);
                throw new AxiomException("Unsupported DevIL format: ImageFormat = {0:x} ImageType = {1:x}", format, imageType);
            }

            // Check for cubemap
            // int cubeflags = Il.ilGetInteger(Il.IL_IMAGE_CUBEFLAGS);
            int numFaces = Il.ilGetInteger(Il.IL_NUM_IMAGES) + 1;

            if (numFaces == 6)
            {
                data.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)
            int dxtFormat = Il.ilGetInteger(Il.IL_DXTC_DATA_FORMAT);

            if (dxtFormat != Il.IL_DXT_NO_COMP &&
                Root.Instance.RenderSystem.Caps.CheckCap(Axiom.Graphics.Capabilities.TextureCompressionDXT))
            {
                data.format = ILUtil.ConvertFromILFormat(dxtFormat, imageType);
                data.flags |= ImageFlags.Compressed;

                // Validate that this devil version saves DXT mipmaps
                if (data.numMipMaps > 0)
                {
                    Il.ilBindImage(imageID);
                    Il.ilActiveMipmap(1);
                    if (Il.ilGetInteger(Il.IL_DXTC_DATA_FORMAT) != dxtFormat)
                    {
                        data.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
            data.size = Image.CalculateSize(data.numMipMaps, numFaces,
                                            data.width, data.height,
                                            data.depth, data.format);

            // set up buffer for the decoded data
            buffer = new byte[data.size];
            // Pin the buffer, so we can use our PixelBox methods on it
            GCHandle bufGCHandle = new GCHandle();

            bufGCHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            IntPtr bufPtr = bufGCHandle.AddrOfPinnedObject();

            int offset = 0;

            // Dimensions of current mipmap
            int width  = data.width;
            int height = data.height;
            int depth  = data.depth;

            // Transfer data
            for (int mip = 0; mip <= data.numMipMaps; ++mip)
            {
                for (int i = 0; i < numFaces; ++i)
                {
                    Il.ilBindImage(imageID);
                    if (numFaces > 1)
                    {
                        Il.ilActiveImage(i);
                    }
                    if (data.numMipMaps > 0)
                    {
                        Il.ilActiveMipmap(mip);
                    }
                    /// Size of this face
                    int imageSize = PixelUtil.GetMemorySize(width, height, depth, data.format);
                    if ((data.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
                            byte[] tmpBuffer = new byte[imageSize];
                            Il.ilGetDXTCData(tmpBuffer, imageSize, dxtFormat);
                            // Copy the data into our output buffer
                            Array.Copy(tmpBuffer, 0, buffer, offset, tmpBuffer.Length);
                        }
                        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
                        PixelBox dst = new PixelBox(width, height, depth, data.format, bufPtr);
                        dst.Offset = offset;
                        ILUtil.ToAxiom(dst);
                    }
                    offset += imageSize;
                }

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

            // we won't be needing this anymore
            Il.ilDeleteImages(1, ref imageID);

            output.Write(buffer, 0, buffer.Length);


            // Free the buffer we allocated for the conversion.
            // I used bufPtr to store my data while I converted it.
            // I need to free it here.  This invalidates bufPtr.
            // My data has already been copied to output.
            if (bufGCHandle.IsAllocated)
            {
                bufGCHandle.Free();
            }

            return(data);
        }
		protected static void FromD3DLock( PixelBox rval, DX.DataBox lbox )
		{
			var bpp = PixelUtil.GetNumElemBytes( rval.Format );
			var size = 0;

			if ( bpp != 0 )
			{
				rval.RowPitch = lbox.RowPitch/bpp;
				rval.SlicePitch = lbox.SlicePitch/bpp;
				Debug.Assert( ( lbox.RowPitch%bpp ) == 0 );
				Debug.Assert( ( lbox.SlicePitch%bpp ) == 0 );
				size = lbox.RowPitch*rval.Height;
			}
			else if ( PixelUtil.IsCompressed( rval.Format ) )
			{
				rval.RowPitch = rval.Width;
				rval.SlicePitch = rval.Width*rval.Height;
				size = rval.Width*rval.Height;
			}
			else
			{
				throw new AxiomException( "Invalid pixel format" );
			}

			rval.Data = BufferBase.Wrap( lbox.DataPointer, size );
		}
Exemple #40
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="src"></param>
		/// <param name="dst"></param>
		public void Scale( PixelBox src, PixelBox dst )
		{
			int srcelemsize = PixelUtil.GetNumElemBytes( src.Format );
			int dstelemsize = PixelUtil.GetNumElemBytes( dst.Format );

			int dstOffset = 0;

			// sx_48,sy_48,sz_48 represent current position in source
			// using 16/48-bit fixed precision, incremented by steps
			UInt64 stepx = ( (UInt64)src.Width << 48 ) / (UInt64)dst.Width;
			UInt64 stepy = ( (UInt64)src.Height << 48 ) / (UInt64)dst.Height;
			UInt64 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
			UInt64 sz_48 = ( stepz >> 1 ) - 1;
			for ( int z = dst.Front; z < dst.Back; z++, sz_48 += stepz )
			{
				temp = (uint)( sz_48 >> 32 );
				temp = ( temp > 0x8000 ) ? temp - 0x8000 : 0;
				int sz1 = (int)( temp >> 16 );
				int sz2 = System.Math.Min( sz1 + 1, src.Depth - 1 );
				float szf = ( temp & 0xFFFF ) / 65536f;

				UInt64 sy_48 = ( stepy >> 1 ) - 1;
				for ( int y = dst.Top; y < dst.Bottom; y++, sy_48 += stepy )
				{
					temp = (uint)( sy_48 >> 32 );
					temp = ( temp > 0x8000 ) ? temp - 0x8000 : 0;
					int sy1 = (int)( temp >> 16 ); // src x #1
					int sy2 = System.Math.Min( sy1 + 1, src.Height - 1 ); // src x #2
					float syf = ( temp & 0xFFFF ) / 65536f; // weight of #2

					UInt64 sx_48 = ( stepx >> 1 ) - 1;
					for ( int x = dst.Left; x < dst.Right; x++, sx_48 += stepx )
					{
						temp = (uint)( sy_48 >> 32 );
						temp = ( temp > 0x8000 ) ? temp - 0x8000 : 0;
						int sx1 = (int)( temp >> 16 ); // src x #1
						int sx2 = System.Math.Min( sx1 + 1, src.Width - 1 ); // src x #2
						float 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 );

						ColorEx 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, new IntPtr( dst.Data.ToInt32() + dstOffset ) );
						dstOffset += dstelemsize;
					}
					dstOffset += dstelemsize * dst.RowSkip;
				}
				dstOffset += dstelemsize * dst.SliceSkip;
			}
		}
		protected static D3D9.Box ToD3DBoxExtent( PixelBox lockBox )
		{
			var pbox = new D3D9.Box();
			pbox.Left = 0;
			pbox.Right = lockBox.Width;
			pbox.Top = 0;
			pbox.Bottom = lockBox.Height;
			pbox.Front = 0;
			pbox.Back = lockBox.Depth;
			return pbox;
		}
Exemple #42
0
		/// <summary>
		/// </summary>
		/// <param name="pb"> </param>
		/// <param name="buffer"> </param>
		public override void CopyContentsToMemory( PixelBox pb, RenderTarget.FrameBuffer buffer )
		{
			throw new NotImplementedException();
		}
		public override void BlitFromMemory( PixelBox src, BasicBox dstBox )
		{
			//Entering critical section
			LockDeviceAccess();

			foreach ( var it in this.mapDeviceToBufferResources )
			{
				BlitFromMemory( src, dstBox, it.Value );
			}

			//Leaving critical section
			UnlockDeviceAccess();
		}
Exemple #44
0
        public void WriteContentsToFile(string fileName)
        {
            var pf = SuggestPixelFormat();

            var data = new byte[Width * Height * PixelUtil.GetNumElemBytes(pf)];
            var bufGcHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
            var pb = new PixelBox(Width, Height, 1, pf, bufGcHandle.AddrOfPinnedObject());

            CopyContentsToMemory(pb);

            (new Image()).FromDynamicImage(data, Width, Height, 1, pf, false, 1, 0).Save(fileName);

            if (bufGcHandle.IsAllocated)
                bufGcHandle.Free();
        }
		public override void BlitToMemory( BasicBox srcBox, PixelBox dst )
		{
			//Entering critical section
			LockDeviceAccess();

			var pair = this.mapDeviceToBufferResources.First();
			BlitToMemory( srcBox, dst, pair.Value, pair.Key );

			//Leaving critical section
			UnlockDeviceAccess();
		}
Exemple #46
0
        /// <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;
            }
        }
        /// <summary>
        ///   Save our texture to a stream
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="requestedFormat"></param>
        public override void Save(System.IO.Stream stream, PixelFormat requestedFormat)
        {
            // First try to see if we can use the fast method to save this image.
            // TODO: I should be able to make the common path closer to this in performance ([email protected])
            if (pixelBuffer.Format == PixelFormat.A8R8G8B8) {
                if (requestedFormat == PixelFormat.A8B8G8R8 || requestedFormat == PixelFormat.B8G8R8) {
                    SimpleSave(stream, requestedFormat);
                    return;
                }
            }
            int bufSize = PixelUtil.GetMemorySize(pixelBuffer.Width, pixelBuffer.Height, pixelBuffer.Depth, requestedFormat);
            byte[] buffer = new byte[bufSize];
            // Pin down the byte array
            GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            IntPtr address = handle.AddrOfPinnedObject();
            PixelBox box =
                new PixelBox(pixelBuffer.Width, pixelBuffer.Height, pixelBuffer.Depth, requestedFormat, address);
            pixelBuffer.BlitToMemory(box);
            handle.Free();

            // I need to flip this image, since it was upside down in the
            // internal buffers.  I could do this in the save pass, which
            // would make this more efficient, but I don't currently think
            // that efficiency is that important.
            Image image = Image.FromDynamicImage(buffer, pixelBuffer.Width, pixelBuffer.Height,
                                                 pixelBuffer.Depth, requestedFormat);
            image.FlipAroundX();
            // Ok, now the data in buffer has been flipped.
            // Go ahead and discard the image
            image.Dispose();

            // write the data to the stream provided
            stream.Write(buffer, 0, bufSize);
        }
        ///<summary>
        ///    Convert pixels from one format to another. No dithering or filtering is being done. Converting
        ///    from RGB to luminance takes the R channel.
        ///</summary>
        ///<param name="src">PixelBox containing the source pixels, pitches and format</param>
        ///<param name="dst">PixelBox containing the destination pixels, pitches and format</param>
        ///<remarks>
        ///    The source and destination boxes must have the same
        ///    dimensions. In case the source and destination format match, a plain copy is done.
        ///</remarks>
        public static void BulkPixelConversion(PixelBox src, PixelBox dst)
        {
            Debug.Assert(src.Width == dst.Width && src.Height == dst.Height && src.Depth == dst.Depth);

            // Check for compressed formats, we don't support decompression, compression or recoding
            if (PixelBox.Compressed(src.Format) || PixelBox.Compressed(dst.Format))
            {
                if (src.Format == dst.Format)
                {
                    CopyBytes(dst.Data, dst.Offset, src.Data, src.Offset, src.ConsecutiveSize);
                    return;
                }
                else
                {
                    throw new Exception("This method can not be used to compress or decompress images, in PixelBox.BulkPixelConversion");
                }
            }

            // The easy case
            if (src.Format == dst.Format)
            {
                // Everything consecutive?
                if (src.Consecutive && dst.Consecutive)
                {
                    CopyBytes(dst.Data, dst.Offset, src.Data, src.Offset, src.ConsecutiveSize);
                    return;
                }
                unsafe {
                    byte *srcBytes     = (byte *)src.Data.ToPointer();
                    byte *dstBytes     = (byte *)dst.Data.ToPointer();
                    byte *srcptr       = srcBytes + src.Offset;
                    byte *dstptr       = dstBytes + dst.Offset;
                    int   srcPixelSize = PixelUtil.GetNumElemBytes(src.Format);
                    int   dstPixelSize = PixelUtil.GetNumElemBytes(dst.Format);

                    // Calculate pitches+skips in bytes
                    int srcRowPitchBytes = src.RowPitch * srcPixelSize;
                    //int srcRowSkipBytes = src.RowSkip * srcPixelSize;
                    int srcSliceSkipBytes = src.SliceSkip * srcPixelSize;

                    int dstRowPitchBytes = dst.RowPitch * dstPixelSize;
                    //int dstRowSkipBytes = dst.RowSkip * dstPixelSize;
                    int dstSliceSkipBytes = dst.SliceSkip * dstPixelSize;

                    // Otherwise, copy per row
                    int rowSize = src.Width * srcPixelSize;
                    for (int z = src.Front; z < src.Back; z++)
                    {
                        for (int y = src.Top; y < src.Bottom; y++)
                        {
                            byte *s = srcptr;
                            byte *d = dstptr;
                            for (int i = 0; i < rowSize; i++)
                            {
                                *d++ = *s++;
                            }
                            srcptr += srcRowPitchBytes;
                            dstptr += dstRowPitchBytes;
                        }
                        srcptr += srcSliceSkipBytes;
                        dstptr += dstSliceSkipBytes;
                    }
                }
                return;
            }

            if (PixelConversionLoops.DoOptimizedConversion(src, dst))
            {
                // If so, good
                return;
            }

            unsafe {
                byte *srcBytes     = (byte *)src.Data.ToPointer();
                byte *dstBytes     = (byte *)dst.Data.ToPointer();
                byte *srcptr       = srcBytes + src.Offset;
                byte *dstptr       = dstBytes + dst.Offset;
                int   srcPixelSize = PixelUtil.GetNumElemBytes(src.Format);
                int   dstPixelSize = PixelUtil.GetNumElemBytes(dst.Format);

                // Calculate pitches+skips in bytes
                int srcRowSkipBytes   = src.RowSkip * srcPixelSize;
                int srcSliceSkipBytes = src.SliceSkip * srcPixelSize;
                int dstRowSkipBytes   = dst.RowSkip * dstPixelSize;
                int dstSliceSkipBytes = dst.SliceSkip * dstPixelSize;

                // The brute force fallback
                float r, g, b, a;
                for (int z = src.Front; z < src.Back; z++)
                {
                    for (int y = src.Top; y < src.Bottom; y++)
                    {
                        for (int x = src.Left; x < src.Right; x++)
                        {
                            UnpackColor(out r, out g, out b, out a, src.Format, srcptr);
                            PackColor(r, g, b, a, dst.Format, dstptr);
                            srcptr += srcPixelSize;
                            dstptr += dstPixelSize;
                        }
                        srcptr += srcRowSkipBytes;
                        dstptr += dstRowSkipBytes;
                    }
                    srcptr += srcSliceSkipBytes;
                    dstptr += dstSliceSkipBytes;
                }
            }
        }
Exemple #49
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 );
		}
Exemple #50
0
		void Unpack( ref ColorEx dst, int x, int y, int z, PixelFormat format, IntPtr src, PixelBox srcbox, int elemsize )
		{
			unsafe
			{
				byte* pSrc = (byte*)src;
				IntPtr data = (IntPtr)( pSrc + elemsize * ( ( x ) + ( y ) * srcbox.RowPitch + ( z ) * srcbox.SlicePitch ) );
				dst = PixelConverter.UnpackColor( format, data );
			}
		}