예제 #1
0
        public static Image Fold(Func <Colord, Colord, Colord> function, Colord color, IEnumerable <Image> images)
        {
            var size = images.Aggregate(
                new Size3i(int.MaxValue, int.MaxValue, int.MaxValue),
                (s, i) =>
                Ibasa.Numerics.Geometry.Size.Min(s, i.Size));

            var result = new Image(size);

            for (int z = 0; z < result.Depth; ++z)
            {
                for (int y = 0; y < result.Height; ++y)
                {
                    for (int x = 0; x < result.Width; ++x)
                    {
                        var fold = color;
                        foreach (var image in images)
                        {
                            fold = function(fold, image[x, y, z]);
                        }
                        result[x, y, z] = fold;
                    }
                }
            }

            return(result);
        }
예제 #2
0
파일: BC4.cs 프로젝트: Frassle/Ibasa
 public override void GetBytes(
      Colord[] source, int index, int width, int height,
      System.IO.Stream destination, int rowPitch, int slicePitch,
      Boxi sourceBoxi, Point3i destinationPoint)
 {
     throw new NotImplementedException();
 }
예제 #3
0
파일: Sets.cs 프로젝트: bonomali/Ibasa
        public void Map(Colord[] colors, int colorIndex, int x, int y, int z, int width, int height)
        {
            //find width and height
            Width  = Functions.Min(4, width - x);
            Height = Functions.Min(4, height - y);

            //set points and weights to zero
            Array.Clear(Points, 0, Points.Length);
            Array.Clear(Weights, 0, Weights.Length);

            IsTransparent = false;

            int zindex = colorIndex + z * (height * width);

            for (int iy = 0; iy < Height; ++iy)
            {
                int xyindex = (x) + (y + iy) * width + zindex;

                for (int ix = 0; ix < Width; ++ix)
                {
                    Colord pixel = colors[xyindex++];

                    Points[ix, iy]  = new Vector3d(pixel.R, pixel.G, pixel.B);
                    Weights[ix, iy] = WeightColourByAlpha ? pixel.A : 1.0;

                    IsTransparent = pixel.A < 0.5 | IsTransparent;
                }
            }
        }
예제 #4
0
        public Colord[] GetPixels(int x, int y, int z, int width, int height, int depth)
        {
            Contract.Requires(x < Width && x >= 0, "x must be zero or greater, and less than the image width.");
            Contract.Requires(y < Height && y >= 0, "y must be zero or greater, and less than the image height.");
            Contract.Requires(z < Depth && z >= 0, "z must be zero or greater, and less than the image depth.");
            Contract.Requires(width > 0, "width must be greater than zero.");
            Contract.Requires(height > 0, "height must be greater than zero.");
            Contract.Requires(depth > 0, "depth must be greater than zero.");
            Contract.Requires(x + width < Width, "x plus width is greater than image width.");
            Contract.Requires(y + height < Height, "y plus height is greater than image height.");
            Contract.Requires(z + depth < Depth, "z plus depth is greater than image depth.");

            Colord[] pixels = new Colord[width * height * depth];

            for (int destZ = 0, srcZ = z; destZ < depth; ++destZ, ++srcZ)
            {
                int destZOffset = destZ * height;
                for (int destY = 0, srcY = y; destY < height; ++destY, ++srcY)
                {
                    int destYOffset = destY * width + destZOffset;
                    for (int destX = 0, srcX = x; destX < width; ++destX, ++srcX)
                    {
                        int destOffset = destX + destYOffset;
                        pixels[destOffset] = GetPixel(srcX, srcY, srcZ);
                    }
                }
            }

            return(pixels);
        }
예제 #5
0
        public void SetPixel(int index, Colord pixel)
        {
            Contract.Requires(index >= 0, "index is less than zero.");
            Contract.Requires(index < Pixels.Length, "index is out of image bounds.");

            Pixels[index] = pixel;
        }
예제 #6
0
파일: Sets.cs 프로젝트: Frassle/Ibasa
        public void Map(Colord[] colors, int colorIndex, int x, int y, int z, int width, int height)
        {
            //find width and height
            Width = Functions.Min(4, width - x);
            Height = Functions.Min(4, height - y);

            //set points and weights to zero
            Array.Clear(Points, 0, Points.Length);
            Array.Clear(Weights, 0, Weights.Length);

            IsTransparent = false;

            int zindex = colorIndex + z * (height * width);
            for (int iy = 0; iy < Height; ++iy)
            {
                int xyindex = (x) + (y + iy) * width + zindex;

                for (int ix = 0; ix < Width; ++ix)
                {
                    Colord pixel = colors[xyindex++];

                    Points[ix,iy] = new Vector3d(pixel.R, pixel.G, pixel.B);
                    Weights[ix,iy] = WeightColourByAlpha ? pixel.A : 1.0;

                    IsTransparent = pixel.A < 0.5 | IsTransparent;
                }
            }
		}
예제 #7
0
 public void Clear(Colord color)
 {
     for (int i = 0; i < Pixels.Length; ++i)
     {
         Pixels[i] = color;
     }
 }
예제 #8
0
        public void SetPixel(int x, int y, int z, Colord pixel)
        {
            Contract.Requires(x < Width && x >= 0, "x must be zero or greater, and less than the image width.");
            Contract.Requires(y < Height && y >= 0, "y must be zero or greater, and less than the image height.");
            Contract.Requires(z < Depth && z >= 0, "z must be zero or greater, and less than the image depth.");

            Pixels[x + y * Width + z * (Width * Height)] = pixel;
        }
예제 #9
0
        static void Scale2DCubic(Image source, Image scaled)
        {
            double scaleX = (double)source.Width / scaled.Width;
            double scaleY = (double)source.Height / scaled.Height;

            for (int y = 0; y < scaled.Height; ++y)
            {
                int y1 = (int)(y * scaleY);
                int y2 = Functions.Min(y1 + 1, source.Height - 1);
                int y0 = Functions.Max(y1 - 1, 0);
                int y3 = Functions.Min(y2 + 1, source.Height - 1);

                double fY  = (y * scaleY) - y1;
                double fY2 = fY * fY;
                double fY3 = fY2 * fY;

                for (int x = 0; x < scaled.Width; ++x)
                {
                    int x1 = (int)(x * scaleX);
                    int x2 = Functions.Min(x1 + 1, source.Width - 1);
                    int x0 = Functions.Max(x1 - 1, 0);
                    int x3 = Functions.Min(x2 + 1, source.Width - 1);

                    double fX  = (x * scaleX) - x1;
                    double fX2 = fX * fX;
                    double fX3 = fX2 * fX;

                    Colord p = Cerp(
                        Cerp(
                            source.GetPixel(x0, y0, 0),
                            source.GetPixel(x1, y0, 0),
                            source.GetPixel(x2, y0, 0),
                            source.GetPixel(x3, y0, 0),
                            fX, fX2, fX3),
                        Cerp(
                            source.GetPixel(x0, y1, 0),
                            source.GetPixel(x1, y1, 0),
                            source.GetPixel(x2, y1, 0),
                            source.GetPixel(x3, y1, 0),
                            fX, fX2, fX3),
                        Cerp(
                            source.GetPixel(x0, y2, 0),
                            source.GetPixel(x1, y2, 0),
                            source.GetPixel(x2, y2, 0),
                            source.GetPixel(x3, y2, 0),
                            fX, fX2, fX3),
                        Cerp(
                            source.GetPixel(x0, y3, 0),
                            source.GetPixel(x1, y3, 0),
                            source.GetPixel(x2, y3, 0),
                            source.GetPixel(x3, y3, 0),
                            fX, fX2, fX3),
                        fY, fY2, fY3);

                    scaled.SetPixel(x, 0, 0, p);
                }
            }
        }
예제 #10
0
        static Colord Cerp(Colord p0, Colord p1, Colord p2, Colord p3, double f, double f2, double f3)
        {
            Colord p = (p3 - p2) - (p0 - p1);
            Colord q = (p0 - p1) - p;
            Colord r = p2 - p0;
            Colord s = p1;

            return(p * f3 + q * f2 + r * f + s);
        }
예제 #11
0
        static Colord Cerp(Colord p0, Colord p1, Colord p2, Colord p3, double f, double f2, double f3)
		{
            Colord p = (p3 - p2) - (p0 - p1);
            Colord q = (p0 - p1) - p;
            Colord r = p2 - p0;
            Colord s = p1;

			return p*f3 + q*f2 + r*f + s;
		}
예제 #12
0
        public static Image Normalmap(Image depthmap, float depth)
        {
            //Create normalmap, only use the first slice if a 3D texture
            Image normalmap = new Image(new Size3i(depthmap.Width, depthmap.Height, 1));

            for (int y = 0; y < normalmap.Height; ++y)
            {
                for (int x = 0; x < normalmap.Width; ++x)
                {
                    double dx = 0.0;
                    double dy = 0.0;
                    double p;

                    p   = depthmap[x - 1, y - 1].R * depth;
                    dx -= p;
                    dy -= p;

                    p   = depthmap[x, y - 1].R * depth;
                    dy -= 2 * p;

                    p   = depthmap[x + 1, y - 1].R * depth;
                    dx += p;
                    dy -= p;

                    p   = depthmap[x - 1, y].R * depth;
                    dx -= 2 * p;

                    p   = depthmap[x + 1, y].R * depth;
                    dx += 2 * p;

                    p   = depthmap[x - 1, y + 1].R * depth;
                    dx -= p;
                    dy += p;

                    p   = depthmap[x, y + 1].R * depth;
                    dy += 2 * p;

                    p   = depthmap[x + 1, y + 1].R * depth;
                    dx += p;
                    dy += p;

                    Vector3d n = Vector.Normalize(new Vector3d(dx, dy, 0.0));

                    //[-1,1] -> [0,1]
                    n = (n * 0.5) + Vector3d.One;

                    normalmap[x, y] = new Colord(n.X, n.Y, n.Z);
                }
            }

            return(normalmap);
        }
예제 #13
0
        public Image(Image source)
        {
            Contract.Requires(source != null);

            Size = source.Size;

            Pixels = new Colord[source.Pixels.Length];
            Array.Copy(source.Pixels, Pixels, Pixels.Length);

            AddressX = source.AddressX;
            AddressY = source.AddressY;
            AddressZ = source.AddressZ;
        }
예제 #14
0
        public Image(Size3i size)
        {
            Contract.Requires(size.Width > 0);
            Contract.Requires(size.Height > 0);
            Contract.Requires(size.Depth > 0);

            Size   = size;
            Pixels = new Colord[Width * Height * Depth];

            AddressX = AddressMode.Clamp;
            AddressY = AddressMode.Clamp;
            AddressZ = AddressMode.Clamp;
        }
예제 #15
0
        public Image(Colord[] pixels)
        {
            Contract.Requires(pixels != null);

            Size   = new Size3i(pixels.GetLength(0), 1, 1);
            Pixels = new Colord[Width];
            for (int x = 0; x < Width; ++x)
            {
                this[x] = pixels[x];
            }

            AddressX = AddressMode.Clamp;
            AddressY = AddressMode.Clamp;
            AddressZ = AddressMode.Clamp;
        }
예제 #16
0
파일: Sets.cs 프로젝트: Frassle/Ibasa
        public ChannelSet(Colord[] pixels, int mask, int channel)
		{
			Count = 0;
            Points = new double[16];
			
			// create the minimal set
			for( int i = 0; i < 16; ++i )
			{
				// check this pixel is enabled
				int bit = 1 << i;
				if( ( mask & (1 << i) ) == 0 )
				{
					remap[i] = -1;
					continue;
				}
				
				// loop over previous points for a match
				for( int j = 0;; ++j )
				{
					// allocate a new point
					if( j == i )
					{
						// add the point
						Points[Count] = pixels[i][channel];
						remap[i] = Count;

						// advance
						++Count;
						break;
					}

					// check for a match
					int oldbit = 1 << j;
					bool match = ( ( mask & oldbit ) != 0 )
						&& ( pixels[i][channel] == pixels[j][channel]);
					if( match )
					{
						// get the index of the match
						int index = remap[j];
						
						// map to this point
						remap[i] = index;
						break;
					}
				}
			}
		}
예제 #17
0
파일: R8G8B8A8.cs 프로젝트: bonomali/Ibasa
        public override void GetColords(
            System.IO.Stream source, int rowPitch, int slicePitch,
            Colord[] destination, int index, int width, int height,
            Boxi sourceBoxi, Point3i destinationPoint)
        {
            //seek to start
            source.Seek(
                sourceBoxi.X * 4 + sourceBoxi.Y * rowPitch + sourceBoxi.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                int zindex = index + (destinationPoint.Z + z) * (height * width);

                for (int y = 0; y < sourceBoxi.Height; ++y)
                {
                    int xyindex = destinationPoint.X + (destinationPoint.Y + y) * width + zindex;

                    //write scan line
                    for (int x = 0; x < sourceBoxi.Width; ++x)
                    {
                        int r = source.ReadByte();
                        int g = source.ReadByte();
                        int b = source.ReadByte();
                        int a = source.ReadByte();

                        if ((r | g | b | a) < 0)
                        {
                            throw new System.IO.EndOfStreamException();
                        }

                        destination[xyindex++] = new Colord(
                            (sbyte)(byte)r / sbyte.MaxValue,
                            (sbyte)(byte)g / sbyte.MaxValue,
                            (sbyte)(byte)b / sbyte.MaxValue,
                            (sbyte)(byte)a / sbyte.MaxValue);
                    }

                    //seek to next scan line
                    source.Seek(rowPitch - sourceBoxi.Width * 4, System.IO.SeekOrigin.Current);
                }

                //seek to next scan slice
                source.Seek(slicePitch - sourceBoxi.Height * rowPitch, System.IO.SeekOrigin.Current);
            }
        }
예제 #18
0
        public Image(Colord[,] pixels)
        {
            Contract.Requires(pixels != null);

            Size   = new Size3i(pixels.GetLength(0), pixels.GetLength(1), 1);
            Pixels = new Colord[Width * Height];
            for (int y = 0; y < Height; ++y)
            {
                for (int x = 0; x < Width; ++x)
                {
                    this[x, y] = pixels[x, y];
                }
            }

            AddressX = AddressMode.Clamp;
            AddressY = AddressMode.Clamp;
            AddressZ = AddressMode.Clamp;
        }
예제 #19
0
        public Image(Resource source, int mipSlice, int arraySlice)
        {
            Contract.Requires(source != null);
            Contract.Requires(0 < mipSlice);
            Contract.Requires(mipSlice < source.MipLevels);
            Contract.Requires(0 < arraySlice);
            Contract.Requires(arraySlice < source.ArraySize);

            Size = source.ComputeMipSliceSize(mipSlice);

            Pixels = new Colord[Width * Height * Depth];
            source.GetColords(
                mipSlice, arraySlice,
                Pixels, 0, Size.Width, Size.Height,
                new Boxi(Point3i.Zero, Size), Point3i.Zero);

            AddressX = AddressMode.Clamp;
            AddressY = AddressMode.Clamp;
            AddressZ = AddressMode.Clamp;
        }
예제 #20
0
        //public static Image Convolution(Image image, Matrix kernel)
        //{
        //    if (image == null)
        //        throw new ArgumentNullException("image");
        //    if (kernel == null)
        //        throw new ArgumentNullException("kernel");

        //    Image result = new Image(image.Size);

        //    for (int y = 0; y < image.Height; ++y)
        //    {
        //        for (int x = 0; x < image.Width; ++x)
        //        {
        //            Colord p = new Colord();
        //            for (int j = 0; j < kernel.Rows.Count; ++j)
        //            {
        //                for (int i = 0; i < kernel.Columns.Count; ++i)
        //                {
        //                    p += image[x - i, y - j] * kernel[i, j];
        //                }
        //            }
        //            result[x, y] = p;
        //        }
        //    }

        //    return result;
        //}
        #endregion

        #region Dither
        public static void Dither(Image image, Func <Colord, Colord> quantize)
        {
            for (int z = 0; z < image.Depth; ++z)
            {
                for (int y = 0; y < image.Height; ++y)
                {
                    for (int x = 0; x < image.Width; ++x)
                    {
                        Colord oldc = image[x, y, z];
                        Colord newc = quantize(oldc);
                        image[x, y, z] = newc;
                        Colord error = oldc - newc;

                        image[x + 1, y, z]     += (7.0 / 16.0 * error);
                        image[x - 1, y + 1, z] += (3.0 / 16.0 * error);
                        image[x, y + 1, z]     += (5.0 / 16.0 * error);
                        image[x + 1, y + 1, z] += (1.0 / 16.0 * error);
                    }
                }
            }
        }
예제 #21
0
        public override void GetColords(
            Stream source, int rowPitch, int slicePitch,
            Colord[] destination, int index, int width, int height,
            Boxi sourceBoxi, Point3i destinationPoint)
        {
            //seek to start
            source.Seek(
                sourceBoxi.X * 12 + sourceBoxi.Y * rowPitch + sourceBoxi.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            var buffer = new byte[12];

            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                int zindex = index + (destinationPoint.Z + z) * (height * width);

                for (int y = 0; y < sourceBoxi.Height; ++y)
                {
                    int xyindex = destinationPoint.X + (destinationPoint.Y + y) * width + zindex;

                    //write scan line
                    for (int x = 0; x < sourceBoxi.Width; ++x)
                    {
                        Ibasa.IO.StreamExtensions.ReadBytes(source, buffer, 0, 12);

                        float r = BitConverter.ToSingle(buffer, 0);
                        float g = BitConverter.ToSingle(buffer, 4);
                        float b = BitConverter.ToSingle(buffer, 8);

                        destination[xyindex++] = new Colord(r, g, b, 0);
                    }

                    //seek to next scan line
                    source.Seek(rowPitch - sourceBoxi.Width * 12, System.IO.SeekOrigin.Current);
                }

                //seek to next scan slice
                source.Seek(slicePitch - sourceBoxi.Height * rowPitch, System.IO.SeekOrigin.Current);
            }
        }
예제 #22
0
        static Colord Serp(Colord p0, Colord p1, Colord p2, Colord p3, double cint0, double cint1, double cint2, double cint3)
		{
			return p0 * cint0 + p1 * cint1 + p2 * cint2 + p3 * cint3;
		}
예제 #23
0
파일: Image.cs 프로젝트: Frassle/Ibasa
        public Image(Colord[,,] pixels)
        {
            Contract.Requires(pixels != null);

            Size = new Size3i(pixels.GetLength(0), pixels.GetLength(1), pixels.GetLength(2));
            Pixels = new Colord[Width * Height * Depth];
            for (int z = 0; z < Depth; ++z)
            {
                for (int y = 0; y < Height; ++y)
                {
                    for (int x = 0; x < Width; ++x)
                    {
                        this[x, y, z] = pixels[x, y, z];
                    }
                }
            }

            AddressX = AddressMode.Clamp;
            AddressY = AddressMode.Clamp;
            AddressZ = AddressMode.Clamp;
        }
예제 #24
0
        static Colord Lerp(Colord p0, Colord p1, double f)
		{
			return p0 + f * (p1 - p0);
		}
예제 #25
0
        public static Image Normalmap(Image depthmap, float depth)
        {
            //Create normalmap, only use the first slice if a 3D texture
            Image normalmap = new Image(new Size3i(depthmap.Width, depthmap.Height, 1));

            for (int y = 0; y < normalmap.Height; ++y)
            {
                for (int x = 0; x < normalmap.Width; ++x)
                {
                    double dx = 0.0;
                    double dy = 0.0;
                    double p;

                    p = depthmap[x - 1, y - 1].R * depth;
                    dx -= p;
                    dy -= p;

                    p = depthmap[x, y - 1].R * depth;
                    dy -= 2 * p;

                    p = depthmap[x + 1, y - 1].R * depth;
                    dx += p;
                    dy -= p;

                    p = depthmap[x - 1, y].R * depth;
                    dx -= 2 * p;

                    p = depthmap[x + 1, y].R * depth;
                    dx += 2 * p;

                    p = depthmap[x - 1, y + 1].R * depth;
                    dx -= p;
                    dy += p;

                    p = depthmap[x, y + 1].R * depth;
                    dy += 2 * p;

                    p = depthmap[x + 1, y + 1].R * depth;
                    dx += p;
                    dy += p;

                    Vector3d n = Vector.Normalize(new Vector3d(dx, dy, 0.0));

                    //[-1,1] -> [0,1]
                    n = (n * 0.5) + Vector3d.One;

                    normalmap[x, y] = new Colord(n.X, n.Y, n.Z);
                }
            }

            return normalmap;
        }
예제 #26
0
파일: Image.cs 프로젝트: Frassle/Ibasa
 public void Clear(Colord color)
 {
     for (int i = 0; i < Pixels.Length; ++i)
     {
         Pixels[i] = color;
     }
 }
예제 #27
0
파일: Image.cs 프로젝트: Frassle/Ibasa
        public static Image Fold(Func<Colord, Colord, Colord> function, Colord color, IEnumerable<Image> images)
        {
            var size = images.Aggregate(
                new Size3i(int.MaxValue, int.MaxValue, int.MaxValue),
                (s, i) =>
                    Ibasa.Numerics.Geometry.Size.Min(s, i.Size));

            var result = new Image(size);

            for (int z = 0; z < result.Depth; ++z)
            {
                for (int y = 0; y < result.Height; ++y)
                {
                    for (int x = 0; x < result.Width; ++x)
                    {
                        var fold = color;
                        foreach (var image in images)
                        {
                            fold = function(fold, image[x,y,z]);
                        }
                        result[x, y, z] = fold;
                    }
                }
            }

            return result;
        }
예제 #28
0
파일: BC7.cs 프로젝트: Frassle/Ibasa
 private void DecodeMode7(byte[] block, Colord[] pixels)
 {
 }
예제 #29
0
파일: Image.cs 프로젝트: Frassle/Ibasa
        public Image(Resource source, int mipSlice, int arraySlice)
        {
            Contract.Requires(source != null);
            Contract.Requires(0 < mipSlice);
            Contract.Requires(mipSlice < source.MipLevels);
            Contract.Requires(0 < arraySlice);
            Contract.Requires(arraySlice < source.ArraySize);

            Size = source.ComputeMipSliceSize(mipSlice);

            Pixels = new Colord[Width * Height * Depth];
            source.GetColords(
                mipSlice, arraySlice,
                Pixels, 0, Size.Width, Size.Height,
                new Boxi(Point3i.Zero, Size), Point3i.Zero);

            AddressX = AddressMode.Clamp;
            AddressY = AddressMode.Clamp;
            AddressZ = AddressMode.Clamp;
        }
예제 #30
0
파일: Image.cs 프로젝트: Frassle/Ibasa
        public Image(Colord[] pixels)
        {
            Contract.Requires(pixels != null);

            Size = new Size3i(pixels.GetLength(0), 1, 1);
            Pixels = new Colord[Width];
            for (int x = 0; x < Width; ++x)
            {
                this[x] = pixels[x];
            }

            AddressX = AddressMode.Clamp;
            AddressY = AddressMode.Clamp;
            AddressZ = AddressMode.Clamp;
        }
예제 #31
0
파일: Image.cs 프로젝트: Frassle/Ibasa
        public void SetPixel(int index, Colord pixel)
        {
            Contract.Requires(index >= 0, "index is less than zero.");
            Contract.Requires(index < Pixels.Length, "index is out of image bounds.");

            Pixels[index] = pixel;
        }
예제 #32
0
파일: Image.cs 프로젝트: Frassle/Ibasa
        public void SetPixel(int x, int y, int z, Colord pixel)
        {
            Contract.Requires(x < Width && x >= 0, "x must be zero or greater, and less than the image width.");
            Contract.Requires(y < Height && y >= 0, "y must be zero or greater, and less than the image height.");
            Contract.Requires(z < Depth && z >= 0, "z must be zero or greater, and less than the image depth.");

            Pixels[x + y * Width + z * (Width * Height)] = pixel;
        }
예제 #33
0
파일: BC1.cs 프로젝트: Frassle/Ibasa
        public override void GetColords(
            System.IO.Stream source, int rowPitch, int slicePitch, 
            Colord[] destination, int index, int width, int height,
            Boxi sourceBoxi, Point3i destinationPoint)
        {
            if ((sourceBoxi.X & 0x3) != 0 || (sourceBoxi.Y & 0x3) != 0)
                throw new ArgumentException("sourceBoxi X and Y must be a multiple of 4.", "sourceBoxi");

            //seek to start
            source.Seek(
                (sourceBoxi.X / 4) * BlockSize + (sourceBoxi.Y / 4) * rowPitch + sourceBoxi.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            Colord[] codes = new Colord[4];
            byte[] block = new byte[BlockSize];

            // loop over blocks
            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                int zindex = index + (destinationPoint.Z + z) * (height * width);

                for (int y = 0; y < sourceBoxi.Height; y += 4)
                {
                    //read scan line
                    for (int x = 0; x < sourceBoxi.Width; x += 4)
                    {
                        //read block
                        int read = 0;
                        while (read < BlockSize)
                        {
                            int bytes = source.Read(block, read, BlockSize - read);
                            if (bytes == 0)
                                throw new System.IO.EndOfStreamException();
                            read += bytes;
                        }

                        // decompress the block
                        int color0 = BitConverter.ToUInt16(block, 0);
                        int color1 = BitConverter.ToUInt16(block, 2);
                        uint indices = BitConverter.ToUInt32(block, 4);

                        // unpack the endpoints
                        codes[0] = Color.Unquantized(5, 6, 5, Vector.Unpack(5, 6, 5, color0));
                        codes[1] = Color.Unquantized(5, 6, 5, Vector.Unpack(5, 6, 5, color1));

                        // generate the midpoints
                        if (color0 > color1)
                        {
                            codes[2] = Numerics.Color.Lerp(codes[0], codes[1], 1.0 / 3.0);
                            codes[3] = Numerics.Color.Lerp(codes[0], codes[1], 2.0 / 3.0);
                        }
                        else
                        {
                            codes[2] = Numerics.Color.Lerp(codes[0], codes[1], 1.0 / 2.0);
                            codes[3] = new Numerics.Colord(0.0, 0.0, 0.0, 0.0);
                        }


                        int bwidth = Functions.Min(4, width - (destinationPoint.X + x));
                        int bheight = Functions.Min(4, height - (destinationPoint.Y + y));

                        for (int y2 = 0; y2 < bheight; ++y2)
                        {
                            int xyindex = (destinationPoint.X + x) + (destinationPoint.Y + y + y2) * width + zindex;

                            for (int x2 = 0; x2 < bwidth; ++x2)
                            {
                                uint codeIndex = (indices >> ((x2 + (y2 * 4)) << 1) & 3);
                                destination[xyindex++] = codes[codeIndex];
                            }
                        }
                    }                
                    //seek to next scan line
                    source.Seek(rowPitch - (((sourceBoxi.Width + 3) / 4) * BlockSize), 
                        System.IO.SeekOrigin.Current);
                }
                //seek to next scan slice
                source.Seek(slicePitch - (((sourceBoxi.Height + 3) / 4) * ((sourceBoxi.Width + 3) / 4) * BlockSize), 
                    System.IO.SeekOrigin.Current);
            }
        }
예제 #34
0
파일: Image.cs 프로젝트: Frassle/Ibasa
        public void SetPixels(int x, int y, int z, int width, int height, int depth, Colord[] pixels)
        {
            Contract.Requires(width * height * depth == pixels.Length, 
                "pixels length does not match length given by width, height and depth.");
            Contract.Requires(x < Width && x >= 0, "x must be zero or greater, and less than the image width.");
            Contract.Requires(y < Height && y >= 0, "y must be zero or greater, and less than the image height.");
            Contract.Requires(z < Depth && z >= 0, "z must be zero or greater, and less than the image depth.");
            Contract.Requires(width > 0, "width must be greater than zero.");
            Contract.Requires(height > 0, "height must be greater than zero.");
            Contract.Requires(depth > 0, "depth must be greater than zero.");
            Contract.Requires(x + width < Width, "x plus width is greater than image width.");
            Contract.Requires(y + height < Height, "y plus height is greater than image height.");
            Contract.Requires(z + depth < Depth, "z plus depth is greater than image depth.");

            for (int destZ = z, srcZ = 0; srcZ < depth; ++destZ, ++srcZ)
            {
                int srcZOffset = srcZ * height;
                for (int destY = y, srcY = 0; srcY < height; ++destY, ++srcY)
                {
                    int srcYOffset = srcY * width + srcZOffset;
                    for (int destX = x, srcX = 0; srcX < width; ++destX, ++srcX)
                    {
                        int srcOffset = srcX + srcYOffset;
                        SetPixel(destX, destY, destZ, pixels[srcOffset]);
                    }
                }
            }
        }
예제 #35
0
        static void Scale2DSpline(Image source, Image scaled)
        {
            double scaleX = (double)source.Width / scaled.Width;
            double scaleY = (double)source.Height / scaled.Height;

            for (int y = 0; y < scaled.Height; ++y)
            {
                int y1 = (int)(y * scaleY);
                int y2 = Functions.Min(y1 + 1, source.Height - 1);
                int y0 = Functions.Max(y1 - 1, 0);
                int y3 = Functions.Min(y2 + 1, source.Height - 1);

                double fY = (y * scaleY) - y1;

                double cinty0 = (-fY * (fY - 1) * (fY - 2)) / 6;
                double cinty1 = (3 * (fY + 1) * (fY - 1) * (fY - 2)) / 6;
                double cinty2 = (-3 * (fY + 1) * fY * (fY - 2)) / 6;
                double cinty3 = ((fY + 1) * fY * (fY - 1)) / 6;

                for (int x = 0; x < scaled.Width; ++x)
                {
                    int x1 = (int)(x * scaleX);
                    int x2 = Functions.Min(x1 + 1, source.Width - 1);
                    int x0 = Functions.Max(x1 - 1, 0);
                    int x3 = Functions.Min(x2 + 1, source.Width - 1);

                    double fX = (x * scaleX) - x1;

                    double cintx0 = (-fX * (fX - 1) * (fX - 2)) / 6;
                    double cintx1 = (3 * (fX + 1) * (fX - 1) * (fX - 2)) / 6;
                    double cintx2 = (-3 * (fX + 1) * fX * (fX - 2)) / 6;
                    double cintx3 = ((fX + 1) * fX * (fX - 1)) / 6;

                    Colord p = Serp(
                        Serp(
                            source.GetPixel(x0, y0, 0),
                            source.GetPixel(x1, y0, 0),
                            source.GetPixel(x2, y0, 0),
                            source.GetPixel(x3, y0, 0),
                            cintx0, cintx1, cintx2, cintx3),
                        Serp(
                            source.GetPixel(x0, y1, 0),
                            source.GetPixel(x1, y1, 0),
                            source.GetPixel(x2, y1, 0),
                            source.GetPixel(x3, y1, 0),
                            cintx0, cintx1, cintx2, cintx3),
                        Serp(
                            source.GetPixel(x0, y2, 0),
                            source.GetPixel(x1, y2, 0),
                            source.GetPixel(x2, y2, 0),
                            source.GetPixel(x3, y2, 0),
                            cintx0, cintx1, cintx2, cintx3),
                        Serp(
                            source.GetPixel(x0, y3, 0),
                            source.GetPixel(x1, y3, 0),
                            source.GetPixel(x2, y3, 0),
                            source.GetPixel(x3, y3, 0),
                            cintx0, cintx1, cintx2, cintx3),
                        cinty0, cinty1, cinty2, cinty3);

                    scaled.SetPixel(x, y, 0, p);
                }
            }
        }
예제 #36
0
        public override void GetColords(
            System.IO.Stream source, int rowPitch, int slicePitch,
            Colord[] destination, int index, int width, int height,
            Boxi sourceBoxi, Point3i destinationPoint)
        {
            if ((sourceBoxi.X & 0x3) != 0 || (sourceBoxi.Y & 0x3) != 0)
            {
                throw new ArgumentException("sourceBoxi X and Y must be a multiple of 4.", "sourceBoxi");
            }

            //seek to start
            source.Seek(
                (sourceBoxi.X / 4) * BlockSize + (sourceBoxi.Y / 4) * rowPitch + sourceBoxi.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            Colord[] ccodes = new Colord[4];
            double[] acodes = new double[8];
            byte[]   block  = new byte[BlockSize];

            // loop over blocks
            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                int zindex = index + (destinationPoint.Z + z) * (height * width);

                for (int y = 0; y < sourceBoxi.Height; y += 4)
                {
                    //read scan line
                    for (int x = 0; x < sourceBoxi.Width; x += 4)
                    {
                        //read block
                        int read = 0;
                        while (read < BlockSize)
                        {
                            int bytes = source.Read(block, read, BlockSize - read);
                            if (bytes == 0)
                            {
                                throw new System.IO.EndOfStreamException();
                            }
                            read += bytes;
                        }

                        // decompress the block
                        int   alpha0   = block[0];
                        int   alpha1   = block[1];
                        ulong aindices =
                            BitConverter.ToUInt16(block, 2) |
                            ((ulong)BitConverter.ToUInt32(block, 4) << 16); //Only 6 bytes
                        int  color0   = BitConverter.ToUInt16(block, 8);
                        int  color1   = BitConverter.ToUInt16(block, 10);
                        uint cindices = BitConverter.ToUInt32(block, 12);

                        // unpack the endpoints
                        ccodes[0] = Color.Unquantized(5, 6, 5, Vector.Unpack(5, 6, 5, color0));
                        ccodes[1] = Color.Unquantized(5, 6, 5, Vector.Unpack(5, 6, 5, color1));

                        // generate the midpoints
                        ccodes[2] = Numerics.Color.Lerp(ccodes[0], ccodes[1], 1.0 / 3.0);
                        ccodes[3] = Numerics.Color.Lerp(ccodes[0], ccodes[1], 2.0 / 3.0);

                        //unpack alpha
                        acodes[0] = alpha0 / 255.0;
                        acodes[1] = alpha1 / 255.0;

                        //generate midpoints
                        if (alpha0 > alpha1)
                        {
                            acodes[2] = (6 * acodes[0] + 1 * acodes[1]) / 7.0; // bit code 010
                            acodes[3] = (5 * acodes[0] + 2 * acodes[1]) / 7.0; // bit code 011
                            acodes[4] = (4 * acodes[0] + 3 * acodes[1]) / 7.0; // bit code 100
                            acodes[5] = (3 * acodes[0] + 4 * acodes[1]) / 7.0; // bit code 101
                            acodes[6] = (2 * acodes[0] + 5 * acodes[1]) / 7.0; // bit code 110
                            acodes[7] = (1 * acodes[0] + 6 * acodes[1]) / 7.0; // bit code 111
                        }
                        else
                        {
                            acodes[2] = (4 * acodes[0] + 1 * acodes[1]) / 5.0; // bit code 010
                            acodes[3] = (3 * acodes[0] + 2 * acodes[1]) / 5.0; // bit code 011
                            acodes[4] = (2 * acodes[0] + 3 * acodes[1]) / 5.0; // bit code 100
                            acodes[5] = (1 * acodes[0] + 4 * acodes[1]) / 5.0; // bit code 101
                            acodes[6] = 0.0;                                   // bit code 110
                            acodes[7] = 1.0;                                   // bit code 111
                        }

                        int bwidth  = Functions.Min(4, width - (destinationPoint.X + x));
                        int bheight = Functions.Min(4, height - (destinationPoint.Y + y));

                        for (int y2 = 0; y2 < bheight; ++y2)
                        {
                            int xyindex = (destinationPoint.X + x) + (destinationPoint.Y + y + y2) * width + zindex;

                            for (int x2 = 0; x2 < bwidth; ++x2)
                            {
                                uint  codeIndex  = (cindices >> ((x2 + (y2 * 4)) << 1) & 3);
                                ulong alphaIndex = (aindices >> ((x2 + (y2 * 4)) << 2)) & 7;

                                destination[xyindex++] = new Numerics.Colord(
                                    ccodes[codeIndex].R,
                                    ccodes[codeIndex].G,
                                    ccodes[codeIndex].B,
                                    acodes[alphaIndex]);
                            }
                        }
                    }
                    //seek to next scan line
                    source.Seek(rowPitch - ((sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
                }
                //seek to next scan slice
                source.Seek(slicePitch - ((sourceBoxi.Height / 4) * (sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
            }
        }
예제 #37
0
파일: BC7.cs 프로젝트: Frassle/Ibasa
        public override void GetColords(
           System.IO.Stream source, int rowPitch, int slicePitch,
           Colord[] destination, int index, int width, int height,
           Boxi sourceBoxi, Point3i destinationPoint)
        {
            if ((sourceBoxi.X & 0x3) != 0 || (sourceBoxi.Y & 0x3) != 0)
                throw new ArgumentException("sourceBoxi X and Y must be a multiple of 4.", "sourceBoxi");

            //seek to start
            source.Seek(
                (sourceBoxi.X / 4) * BlockSize + (sourceBoxi.Y / 4) * rowPitch + sourceBoxi.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            byte[] block = new byte[BlockSize];
            Colord[] pixels = new Colord[16];

            // loop over blocks
            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                int zindex = index + (destinationPoint.Z + z) * (height * width);

                for (int y = 0; y < sourceBoxi.Height; y += 4)
                {
                    //read scan line
                    for (int x = 0; x < sourceBoxi.Width; x += 4)
                    {
                        //read block
                        int read = 0;
                        while (read < BlockSize)
                        {
                            int bytes = source.Read(block, read, BlockSize - read);
                            if (bytes == 0)
                                throw new System.IO.EndOfStreamException();
                            read += bytes;
                        }

                        int mode = (block[0] & (-block[0]));

                        switch (mode)
                        {
                            case 1:
                                DecodeMode0(block, pixels); break;
                            case 2:
                                DecodeMode1(block, pixels); break;
                            case 4:
                                DecodeMode2(block, pixels); break;
                            case 8:
                                DecodeMode3(block, pixels); break;
                            case 16:
                                DecodeMode4(block, pixels); break;
                            case 32:
                                DecodeMode5(block, pixels); break;
                            case 64:
                                DecodeMode6(block, pixels); break;
                            case 128:
                                DecodeMode7(block, pixels); break;
                        }

                        int bwidth = Functions.Min(4, width - (destinationPoint.X + x));
                        int bheight = Functions.Min(4, height - (destinationPoint.Y + y));

                        for (int y2 = 0; y2 < bheight; ++y2)
                        {
                            int xyindex = (destinationPoint.X + x) + (destinationPoint.Y + y + y2) * width + zindex;
                            int xy2index = y2 * 4;

                            for (int x2 = 0; x2 < bwidth; ++x2)
                            {
                                destination[xyindex++] = pixels[xy2index++];
                            }
                        }
                    }
                    //seek to next scan line
                    source.Seek(rowPitch - ((sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
                }
                //seek to next scan slice
                source.Seek(slicePitch - ((sourceBoxi.Height / 4) * (sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
            }
        }
예제 #38
0
        public static bool ThresholdBoundary(Colord value)
		{
            return (value.R >= 0.5);
		}
예제 #39
0
파일: BC7.cs 프로젝트: Frassle/Ibasa
        private unsafe void DecodeMode0(byte[] block, Colord[] pixels)
        {
            //Number of subsets in each partition: 3
            //Partition bits: 4
            //Rotation bits: 0
            //Index selection bits: 0
            //Colord bits: 4
            //Alpha bits: 0
            //Endpoint P-bits: 1
            //Shared P-bits: 0
            //Index bits per element: 3
            //Secondary index bits per element: 0

            // [76543210] counter
            // [rrrppppm] 0
            // [rrrrrrrr] 1
            // [rrrrrrrr] 2
            // [gggrrrrr] 3
            // [gggggggg] 4
            // [gggggggg] 5
            // [bbbggggg] 6
            // [bbbbbbbb] 7
            // [bbbbbbbb] 8
            // [pppbbbbb] 9
            // [xxxxxppp] A
            // [xxxxxxxx] B
            // [xxxxxxxx] C
            // [xxxxxxxx] D
            // [xxxxxxxx] E
            // [xxxxxxxx] F

            int partition = (block[0] >> 1) & 0x0F;

            int* codes = stackalloc int[18];

            codes[0] = ((block[0] >> 1) | (block[1] << 7)) & 0xF0 | ((block[9] >> 2) & 0x08);
            codes[1] = ((block[3] >> 1) | (block[4] << 7)) & 0xF0 | ((block[9] >> 2) & 0x08);
            codes[2] = ((block[6] >> 1) | (block[7] << 7)) & 0xF0 | ((block[9] >> 2) & 0x08);
            codes[3] = (block[1] << 3) & 0xF0 | ((block[9] >> 3) & 0x08);
            codes[4] = (block[4] << 3) & 0xF0 | ((block[9] >> 3) & 0x08);
            codes[5] = (block[7] << 3) & 0xF0 | ((block[9] >> 3) & 0x08);

            codes[6] = ((block[1] >> 1) | (block[2] << 7)) & 0xF0 | ((block[9] >> 4) & 0x08);
            codes[7] = ((block[4] >> 1) | (block[5] << 7)) & 0xF0 | ((block[9] >> 4) & 0x08);
            codes[8] = ((block[7] >> 1) | (block[8] << 7)) & 0xF0 | ((block[9] >> 4) & 0x08);
            codes[9] = (block[2] << 3) & 0xF0 | ((block[10] << 3) & 0x08);
            codes[10] = (block[5] << 3) & 0xF0 | ((block[10] << 3) & 0x08);
            codes[11] = (block[8] << 3) & 0xF0 | ((block[10] << 3) & 0x08);

            codes[12] = ((block[2] >> 1) | (block[3] << 7)) & 0xF0 | ((block[10] << 2) & 0x08);
            codes[13] = ((block[5] >> 1) | (block[6] << 7)) & 0xF0 | ((block[10] << 2) & 0x08);
            codes[14] = ((block[8] >> 1) | (block[9] << 7)) & 0xF0 | ((block[10] << 2) & 0x08);
            codes[15] = (block[3] << 3) & 0xF0 | ((block[10] << 1) & 0x08);
            codes[16] = (block[6] << 3) & 0xF0 | ((block[10] << 1) & 0x08);
            codes[17] = (block[9] << 3) & 0xF0 | ((block[10] << 1) & 0x08);

            codes[0] |= (codes[0] >> 5);
            codes[1] |= (codes[1] >> 5);
            codes[2] |= (codes[2] >> 5);
            codes[3] |= (codes[3] >> 5);
            codes[4] |= (codes[4] >> 5);
            codes[5] |= (codes[5] >> 5);
            codes[6] |= (codes[6] >> 5);
            codes[7] |= (codes[7] >> 5);
            codes[8] |= (codes[8] >> 5);
            codes[9] |= (codes[9] >> 5);
            codes[10] |= (codes[10] >> 5);
            codes[11] |= (codes[11] >> 5);
            codes[12] |= (codes[12] >> 5);
            codes[13] |= (codes[13] >> 5);
            codes[14] |= (codes[14] >> 5);
            codes[15] |= (codes[15] >> 5);
            codes[16] |= (codes[16] >> 5);
            codes[17] |= (codes[17] >> 5);

            for (int i = 0; i < 16; ++i)
            {
                int colorIndex = 0;

                //64 <= partition < 64 + 16
                //if (i == 0)
                //    colorIndex = (block.z >> 19) & 0x03;
                //else if (i < candidateFixUpIndex1DOrdered[partition][0])
                //{
                //    if (i < 4)
                //        colorIndex = (block.z >> (i * 3 + 18)) & 0x07;
                //    else if (i == 4)
                //        colorIndex = ((block.z >> (i * 3 + 18)) & 0x03) | ((block.w << 2) & 0x04);
                //    else
                //        colorIndex = (block.w >> (i * 3 - 14)) & 0x07;
                //}
                //else if (i == candidateFixUpIndex1DOrdered[partition][0])
                //{
                //    if (i <= 4)
                //        colorIndex = (block.z >> (i * 3 + 18)) & 0x03;
                //    else
                //        colorIndex = (block.w >> (i * 3 - 14)) & 0x03;
                //}
                //else if (i < candidateFixUpIndex1DOrdered[partition][1])
                //{
                //    if (i <= 4)
                //        colorIndex = (block.z >> (i * 3 + 17)) & 0x07;
                //    else
                //        colorIndex = (block.w >> (i * 3 - 15)) & 0x07;
                //}
                //else if (i == candidateFixUpIndex1DOrdered[partition][1]) //i >= 8
                //    colorIndex = (block.w >> (i * 3 - 15)) & 0x03;
                //else //i >= 9
                //    colorIndex = (block.w >> (i * 3 - 16)) & 0x07;

                //int subsetIndex = (candidateSectionCompressed[partition] >> (30 - i * 2)) & 0x03;
                int subsetIndex = 0;
                pixels[i] = InterpolateColord(Weights3[colorIndex], codes, subsetIndex);
            }
        }
예제 #40
0
		public static Image DistanceTransform(
			Image source, int width, int height, int depth,
            Func<Colord, bool> boundary, Metric metric)
		{
			Image dt = new Image(new Size3i(width, height, depth));
			
			double zScale = depth == 1 ? 0 : (double)(source.Depth-1)/(depth-1);
			double yScale = height == 1 ? 0 : (double)(source.Height-1)/(height-1);
			double xScale = width == 1 ? 0 : (double)(source.Width-1)/(width-1);

            int spread = (int)Functions.Max(source.Width, Functions.Max(source.Height, Functions.Max(source.Depth, 3)));
            if (spread % 2 == 0) //0 % 2 == 0
                spread += 1; //spread must be odd and at least 3
			
			for (int z = 0; z < dt.Depth; ++z)
            {
				int srcZ = (int)(z * zScale);
                for (int y = 0; y < dt.Height; ++y)
                {
					int srcY = (int)(y * yScale);
                    for (int x = 0; x < dt.Width; ++x)
                    {
						int srcX = (int)(x * xScale);
						int boxSize = 3;		
						
						double minDistance = double.MaxValue;
                        bool srcBoundary = boundary(source[srcX, srcY, srcZ]);

                        while (boxSize <= spread)
						{		
							int minZ = srcZ - (boxSize/2);
							int maxZ = srcZ + (boxSize/2);
							int minY = srcY - (boxSize/2);
							int maxY = srcY + (boxSize/2);
							int minX = srcX - (boxSize/2);
							int maxX = srcX + (boxSize/2);
							
							int zStart = Functions.Max(minZ, 0);
							int zEnd = Functions.Min(maxZ+1, source.Depth);
							int yStart = Functions.Max(minY, 0);
							int yEnd = Functions.Min(maxY+1, source.Height);
							int xStart = Functions.Max(minX, 0);
							int xEnd = Functions.Min(maxX+1, source.Width);

							for (int boxZ = zStart; boxZ < zEnd; ++boxZ)
							{
                                bool notOnZBorder = (boxZ != minZ && boxZ != maxZ);
								
								for (int boxY = yStart; boxY < yEnd; ++boxY)
								{
                                    bool notOnYBorder = (boxY != minY && boxY != maxY);
									
									for (int boxX = xStart; boxX < xEnd; ++boxX)
									{
										bool notOnXBorder = (boxX != minX && boxX != maxX);

                                        if (notOnZBorder && notOnYBorder && notOnXBorder)
											continue;

                                        bool boxBoundary = boundary(source[boxX, boxY, boxZ]);
                                        
                                        if (srcBoundary != boxBoundary)
											minDistance = Functions.Min(minDistance, metric(srcX,srcY,srcZ,boxX,boxY,boxZ));
									}
								}
							}
							
							//found closest opposite pixel
							if(minDistance != double.MaxValue)
								break;
							
							//not found any opposites yet, expand our search range
							boxSize += 2;
						}

                        if(srcBoundary)
                            dt[x, y, z] = new Colord(minDistance, 0, 0, 0);
                        else
                            dt[x, y, z] = new Colord(-minDistance, 0, 0, 0);
					}
				}
			}

            return dt;
		}
예제 #41
0
파일: Image.cs 프로젝트: Frassle/Ibasa
        public Image(Image source)
        {
            Contract.Requires(source != null);

            Size = source.Size;

            Pixels = new Colord[source.Pixels.Length];
            Array.Copy(source.Pixels, Pixels, Pixels.Length);

            AddressX = source.AddressX;
            AddressY = source.AddressY;
            AddressZ = source.AddressZ;
        }
예제 #42
0
파일: Format.cs 프로젝트: bonomali/Ibasa
 public Format(string name, Colord minColord, Colord maxColord, bool isNormalized, bool isCompressed)
     : base(name, minColord, maxColord, isNormalized, isCompressed)
 {
 }
예제 #43
0
파일: Image.cs 프로젝트: Frassle/Ibasa
        public Image(Size3i size)
        {
            Contract.Requires(size.Width > 0);
            Contract.Requires(size.Height > 0);
            Contract.Requires(size.Depth > 0);

            Size = size;
            Pixels = new Colord[Width * Height * Depth];

            AddressX = AddressMode.Clamp;
            AddressY = AddressMode.Clamp;
            AddressZ = AddressMode.Clamp;
        }
예제 #44
0
파일: Image.cs 프로젝트: Frassle/Ibasa
        public Colord[] GetPixels(int x, int y, int z, int width, int height, int depth)
        {
            Contract.Requires(x < Width && x >= 0, "x must be zero or greater, and less than the image width.");
            Contract.Requires(y < Height && y >= 0, "y must be zero or greater, and less than the image height.");
            Contract.Requires(z < Depth && z >= 0, "z must be zero or greater, and less than the image depth.");
            Contract.Requires(width > 0, "width must be greater than zero.");
            Contract.Requires(height > 0, "height must be greater than zero.");
            Contract.Requires(depth > 0, "depth must be greater than zero.");
            Contract.Requires(x + width < Width, "x plus width is greater than image width.");
            Contract.Requires(y + height < Height, "y plus height is greater than image height.");
            Contract.Requires(z + depth < Depth, "z plus depth is greater than image depth.");

            Colord[] pixels = new Colord[width * height * depth];

            for (int destZ = 0, srcZ = z; destZ < depth; ++destZ, ++srcZ)
            {        
                int destZOffset = destZ * height;
                for (int destY = 0, srcY = y; destY < height; ++destY, ++srcY)
                {
                    int destYOffset = destY * width + destZOffset;
                    for (int destX = 0, srcX = x; destX < width; ++destX, ++srcX)
                    {
                        int destOffset = destX + destYOffset;
                        pixels[destOffset] = GetPixel(srcX,srcY,srcZ);
                    }
                }
            }

            return pixels;
        }
예제 #45
0
 static Colord Serp(Colord p0, Colord p1, Colord p2, Colord p3, double cint0, double cint1, double cint2, double cint3)
 {
     return(p0 * cint0 + p1 * cint1 + p2 * cint2 + p3 * cint3);
 }
예제 #46
0
파일: BC7.cs 프로젝트: bonomali/Ibasa
        public override void GetColords(
            System.IO.Stream source, int rowPitch, int slicePitch,
            Colord[] destination, int index, int width, int height,
            Boxi sourceBoxi, Point3i destinationPoint)
        {
            if ((sourceBoxi.X & 0x3) != 0 || (sourceBoxi.Y & 0x3) != 0)
            {
                throw new ArgumentException("sourceBoxi X and Y must be a multiple of 4.", "sourceBoxi");
            }

            //seek to start
            source.Seek(
                (sourceBoxi.X / 4) * BlockSize + (sourceBoxi.Y / 4) * rowPitch + sourceBoxi.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            byte[]   block  = new byte[BlockSize];
            Colord[] pixels = new Colord[16];

            // loop over blocks
            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                int zindex = index + (destinationPoint.Z + z) * (height * width);

                for (int y = 0; y < sourceBoxi.Height; y += 4)
                {
                    //read scan line
                    for (int x = 0; x < sourceBoxi.Width; x += 4)
                    {
                        //read block
                        int read = 0;
                        while (read < BlockSize)
                        {
                            int bytes = source.Read(block, read, BlockSize - read);
                            if (bytes == 0)
                            {
                                throw new System.IO.EndOfStreamException();
                            }
                            read += bytes;
                        }

                        int mode = (block[0] & (-block[0]));

                        switch (mode)
                        {
                        case 1:
                            DecodeMode0(block, pixels); break;

                        case 2:
                            DecodeMode1(block, pixels); break;

                        case 4:
                            DecodeMode2(block, pixels); break;

                        case 8:
                            DecodeMode3(block, pixels); break;

                        case 16:
                            DecodeMode4(block, pixels); break;

                        case 32:
                            DecodeMode5(block, pixels); break;

                        case 64:
                            DecodeMode6(block, pixels); break;

                        case 128:
                            DecodeMode7(block, pixels); break;
                        }

                        int bwidth  = Functions.Min(4, width - (destinationPoint.X + x));
                        int bheight = Functions.Min(4, height - (destinationPoint.Y + y));

                        for (int y2 = 0; y2 < bheight; ++y2)
                        {
                            int xyindex  = (destinationPoint.X + x) + (destinationPoint.Y + y + y2) * width + zindex;
                            int xy2index = y2 * 4;

                            for (int x2 = 0; x2 < bwidth; ++x2)
                            {
                                destination[xyindex++] = pixels[xy2index++];
                            }
                        }
                    }
                    //seek to next scan line
                    source.Seek(rowPitch - ((sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
                }
                //seek to next scan slice
                source.Seek(slicePitch - ((sourceBoxi.Height / 4) * (sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
            }
        }
예제 #47
0
파일: BC3.cs 프로젝트: Frassle/Ibasa
        public override void GetColords(
            System.IO.Stream source, int rowPitch, int slicePitch,
            Colord[] destination, int index, int width, int height,
            Boxi sourceBoxi, Point3i destinationPoint)
        {
            if ((sourceBoxi.X & 0x3) != 0 || (sourceBoxi.Y & 0x3) != 0)
                throw new ArgumentException("sourceBoxi X and Y must be a multiple of 4.", "sourceBoxi");

            //seek to start
            source.Seek(
                (sourceBoxi.X / 4) * BlockSize + (sourceBoxi.Y / 4) * rowPitch + sourceBoxi.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            Colord[] ccodes = new Colord[4];
            double[] acodes = new double[8];
            byte[] block = new byte[BlockSize];

            // loop over blocks
            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                int zindex = index + (destinationPoint.Z + z) * (height * width);

                for (int y = 0; y < sourceBoxi.Height; y += 4)
                {
                    //read scan line
                    for (int x = 0; x < sourceBoxi.Width; x += 4)
                    {
                        //read block
                        int read = 0;
                        while (read < BlockSize)
                        {
                            int bytes = source.Read(block, read, BlockSize - read);
                            if (bytes == 0)
                                throw new System.IO.EndOfStreamException();
                            read += bytes;
                        }

                        // decompress the block
                        int alpha0 = block[0];
                        int alpha1 = block[1];
                        ulong aindices =
                            BitConverter.ToUInt16(block, 2) |
                            ((ulong)BitConverter.ToUInt32(block, 4) << 16); //Only 6 bytes
                        int color0 = BitConverter.ToUInt16(block, 8);
                        int color1 = BitConverter.ToUInt16(block, 10);
                        uint cindices = BitConverter.ToUInt32(block, 12);

                        // unpack the endpoints
                        ccodes[0] = Color.Unquantized(5, 6, 5, Vector.Unpack(5, 6, 5, color0));
                        ccodes[1] = Color.Unquantized(5, 6, 5, Vector.Unpack(5, 6, 5, color1));

                        // generate the midpoints
                        ccodes[2] = Numerics.Color.Lerp(ccodes[0], ccodes[1], 1.0 / 3.0);
                        ccodes[3] = Numerics.Color.Lerp(ccodes[0], ccodes[1], 2.0 / 3.0);

                        //unpack alpha
                        acodes[0] = alpha0 / 255.0;
                        acodes[1] = alpha1 / 255.0;

                        //generate midpoints
                        if (alpha0 > alpha1)
                        {
                            acodes[2] = (6 * acodes[0] + 1 * acodes[1]) / 7.0; // bit code 010
                            acodes[3] = (5 * acodes[0] + 2 * acodes[1]) / 7.0; // bit code 011
                            acodes[4] = (4 * acodes[0] + 3 * acodes[1]) / 7.0; // bit code 100
                            acodes[5] = (3 * acodes[0] + 4 * acodes[1]) / 7.0; // bit code 101
                            acodes[6] = (2 * acodes[0] + 5 * acodes[1]) / 7.0; // bit code 110
                            acodes[7] = (1 * acodes[0] + 6 * acodes[1]) / 7.0; // bit code 111
                        }
                        else
                        {
                            acodes[2] = (4 * acodes[0] + 1 * acodes[1]) / 5.0; // bit code 010
                            acodes[3] = (3 * acodes[0] + 2 * acodes[1]) / 5.0; // bit code 011
                            acodes[4] = (2 * acodes[0] + 3 * acodes[1]) / 5.0; // bit code 100
                            acodes[5] = (1 * acodes[0] + 4 * acodes[1]) / 5.0; // bit code 101
                            acodes[6] = 0.0;					 // bit code 110
                            acodes[7] = 1.0;					 // bit code 111
                        }

                        int bwidth = Functions.Min(4, width - (destinationPoint.X + x));
                        int bheight = Functions.Min(4, height - (destinationPoint.Y + y));

                        for (int y2 = 0; y2 < bheight; ++y2)
                        {
                            int xyindex = (destinationPoint.X + x) + (destinationPoint.Y + y + y2) * width + zindex;

                            for (int x2 = 0; x2 < bwidth; ++x2)
                            {
                                uint codeIndex = (cindices >> ((x2 + (y2 * 4)) << 1) & 3);
                                ulong alphaIndex = (aindices >> ((x2 + (y2 * 4)) << 2)) & 7;

                                destination[xyindex++] = new Numerics.Colord(
                                    ccodes[codeIndex].R,
                                    ccodes[codeIndex].G,
                                    ccodes[codeIndex].B,
                                    acodes[alphaIndex]);
                            }
                        }
                    }
                    //seek to next scan line
                    source.Seek(rowPitch - ((sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
                }
                //seek to next scan slice
                source.Seek(slicePitch - ((sourceBoxi.Height / 4) * (sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
            }
        }
예제 #48
0
 public static bool ThresholdBoundary(Colord value)
 {
     return(value.R >= 0.5);
 }
예제 #49
0
파일: BC1.cs 프로젝트: Frassle/Ibasa
        public override void GetBytes(
            Colord[] source, int index, int width, int height, 
            System.IO.Stream destination, int rowPitch, int slicePitch, 
            Boxi sourceBoxi, Point3i destinationPoint)
        {
            if ((destinationPoint.X & 0x3) != 0 || (destinationPoint.Y & 0x3) != 0)
                throw new ArgumentException("destinationPoint X and Y must be a multiple of 4.", "destinationPoint");

            //seek to start
            destination.Seek(
                (destinationPoint.X / 4) * BlockSize + (destinationPoint.Y / 4) * rowPitch + destinationPoint.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            // loop over blocks
            Internal.ColordSet colorSet = new Internal.ColordSet(Options.WeightColordByAlpha);
            Internal.ColordBlock colorBlock = new Internal.ColordBlock();

            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                for (int y = 0; y < sourceBoxi.Height; y+=4)
                {
                    //write scan line
                    for (int x = 0; x < sourceBoxi.Width; x+=4)
                    {
                        // compress the block
                        colorSet.Map(source, index, sourceBoxi.X + x, sourceBoxi.Y + y, sourceBoxi.Z + z, width, height);

                        //if (colorSet.Count != 1)
                        //    colorBlock = Internal.SingleColordFit.Fit(colorSet, Options);
                        //else
                        {
                            switch (Options.Quality)
                            {
                                case Quality.Fastest:
                                case Quality.Low:
                                case Quality.Normal:
                                case Quality.High:
                                case Quality.Best:
                                    Internal.BoxiFit.Fit(colorBlock, colorSet, Options, true); break;
                                //case Quality.Normal:
                                //    colorBlock = Internal.RangeFit.Fit(colorSet, Options, true); break;
                                //case quality.High:
                                //    colorBlock = Internal.ClusterFit.Fit(colorSet, options, true, false); break;
                                //case quality.Best:
                                //    colorBlock = Internal.ClusterFit.Fit(colorSet, options, true, true); break;

                                default:
                                    break;
                            }
                        }

                        // write the endpoints
                        destination.WriteByte((byte)colorBlock.Colord0);
                        destination.WriteByte((byte)(colorBlock.Colord0 >> 8));
                        destination.WriteByte((byte)colorBlock.Colord1);
                        destination.WriteByte((byte)(colorBlock.Colord1 >> 8));

                        int indices = 0;
                        for (int i = 0; i < 16; ++i)
                        {
                            indices |= (colorBlock.Indices[i] & 3) << (i << 1);
                        }

                        // write the indices
                        destination.WriteByte((byte)indices);
                        destination.WriteByte((byte)(indices >> 8));
                        destination.WriteByte((byte)(indices >> 16));
                        destination.WriteByte((byte)(indices >> 24));
                    }
                    //seek to next scan line
                    destination.Seek(rowPitch - (((sourceBoxi.Width + 3) / 4) * BlockSize), 
                        System.IO.SeekOrigin.Current);
                }
                //seek to next scan slice
                destination.Seek(slicePitch - (((sourceBoxi.Height + 3) / 4) * ((sourceBoxi.Width + 3) / 4) * BlockSize), 
                    System.IO.SeekOrigin.Current);
            }
        }
예제 #50
0
        public static Image DistanceTransform(
            Image source, int width, int height, int depth,
            Func <Colord, bool> boundary, Metric metric)
        {
            Image dt = new Image(new Size3i(width, height, depth));

            double zScale = depth == 1 ? 0 : (double)(source.Depth - 1) / (depth - 1);
            double yScale = height == 1 ? 0 : (double)(source.Height - 1) / (height - 1);
            double xScale = width == 1 ? 0 : (double)(source.Width - 1) / (width - 1);

            int spread = (int)Functions.Max(source.Width, Functions.Max(source.Height, Functions.Max(source.Depth, 3)));

            if (spread % 2 == 0) //0 % 2 == 0
            {
                spread += 1;     //spread must be odd and at least 3
            }
            for (int z = 0; z < dt.Depth; ++z)
            {
                int srcZ = (int)(z * zScale);
                for (int y = 0; y < dt.Height; ++y)
                {
                    int srcY = (int)(y * yScale);
                    for (int x = 0; x < dt.Width; ++x)
                    {
                        int srcX    = (int)(x * xScale);
                        int boxSize = 3;

                        double minDistance = double.MaxValue;
                        bool   srcBoundary = boundary(source[srcX, srcY, srcZ]);

                        while (boxSize <= spread)
                        {
                            int minZ = srcZ - (boxSize / 2);
                            int maxZ = srcZ + (boxSize / 2);
                            int minY = srcY - (boxSize / 2);
                            int maxY = srcY + (boxSize / 2);
                            int minX = srcX - (boxSize / 2);
                            int maxX = srcX + (boxSize / 2);

                            int zStart = Functions.Max(minZ, 0);
                            int zEnd   = Functions.Min(maxZ + 1, source.Depth);
                            int yStart = Functions.Max(minY, 0);
                            int yEnd   = Functions.Min(maxY + 1, source.Height);
                            int xStart = Functions.Max(minX, 0);
                            int xEnd   = Functions.Min(maxX + 1, source.Width);

                            for (int boxZ = zStart; boxZ < zEnd; ++boxZ)
                            {
                                bool notOnZBorder = (boxZ != minZ && boxZ != maxZ);

                                for (int boxY = yStart; boxY < yEnd; ++boxY)
                                {
                                    bool notOnYBorder = (boxY != minY && boxY != maxY);

                                    for (int boxX = xStart; boxX < xEnd; ++boxX)
                                    {
                                        bool notOnXBorder = (boxX != minX && boxX != maxX);

                                        if (notOnZBorder && notOnYBorder && notOnXBorder)
                                        {
                                            continue;
                                        }

                                        bool boxBoundary = boundary(source[boxX, boxY, boxZ]);

                                        if (srcBoundary != boxBoundary)
                                        {
                                            minDistance = Functions.Min(minDistance, metric(srcX, srcY, srcZ, boxX, boxY, boxZ));
                                        }
                                    }
                                }
                            }

                            //found closest opposite pixel
                            if (minDistance != double.MaxValue)
                            {
                                break;
                            }

                            //not found any opposites yet, expand our search range
                            boxSize += 2;
                        }

                        if (srcBoundary)
                        {
                            dt[x, y, z] = new Colord(minDistance, 0, 0, 0);
                        }
                        else
                        {
                            dt[x, y, z] = new Colord(-minDistance, 0, 0, 0);
                        }
                    }
                }
            }

            return(dt);
        }
예제 #51
0
        public override void GetColords(
            System.IO.Stream source, int rowPitch, int slicePitch,
            Colord[] destination, int index, int width, int height,
            Boxi sourceBoxi, Point3i destinationPoint)
        {
            if ((sourceBoxi.X & 0x3) != 0 || (sourceBoxi.Y & 0x3) != 0)
            {
                throw new ArgumentException("sourceBoxi X and Y must be a multiple of 4.", "sourceBoxi");
            }

            //seek to start
            source.Seek(
                (sourceBoxi.X / 4) * BlockSize + (sourceBoxi.Y / 4) * rowPitch + sourceBoxi.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            double[] rcodes = new double[16];
            double[] gcodes = new double[16];
            byte[]   block  = new byte[BlockSize];

            // loop over blocks
            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                int zindex = index + (destinationPoint.Z + z) * (height * width);

                for (int y = 0; y < sourceBoxi.Height; y += 4)
                {
                    //read scan line
                    for (int x = 0; x < sourceBoxi.Width; x += 4)
                    {
                        //read block
                        int read = 0;
                        while (read < BlockSize)
                        {
                            int bytes = source.Read(block, read, BlockSize - read);
                            if (bytes == 0)
                            {
                                throw new System.IO.EndOfStreamException();
                            }
                            read += bytes;
                        }

                        // decompress the block
                        int   red0     = block[0];
                        int   red1     = block[1];
                        ulong rindices =
                            BitConverter.ToUInt16(block, 2) |
                            ((ulong)BitConverter.ToUInt32(block, 4) << 16); //Only 6 bytes
                        int   green0   = block[8];
                        int   green1   = block[9];
                        ulong gindices =
                            BitConverter.ToUInt16(block, 10) |
                            ((ulong)BitConverter.ToUInt32(block, 12) << 16); //Only 6 bytes

                        // unpack the endpoints
                        rcodes[0] = red0 / 255.0;
                        rcodes[1] = red1 / 255.0;

                        gcodes[0] = green0 / 255.0;
                        gcodes[1] = green1 / 255.0;

                        //generate midpoints
                        if (red0 > red1)
                        {
                            rcodes[2] = (6 * rcodes[0] + 1 * rcodes[1]) / 7.0; // bit code 010
                            rcodes[3] = (5 * rcodes[0] + 2 * rcodes[1]) / 7.0; // bit code 011
                            rcodes[4] = (4 * rcodes[0] + 3 * rcodes[1]) / 7.0; // bit code 100
                            rcodes[5] = (3 * rcodes[0] + 4 * rcodes[1]) / 7.0; // bit code 101
                            rcodes[6] = (2 * rcodes[0] + 5 * rcodes[1]) / 7.0; // bit code 110
                            rcodes[7] = (1 * rcodes[0] + 6 * rcodes[1]) / 7.0; // bit code 111
                        }
                        else
                        {
                            rcodes[2] = (4 * rcodes[0] + 1 * rcodes[1]) / 5.0; // bit code 010
                            rcodes[3] = (3 * rcodes[0] + 2 * rcodes[1]) / 5.0; // bit code 011
                            rcodes[4] = (2 * rcodes[0] + 3 * rcodes[1]) / 5.0; // bit code 100
                            rcodes[5] = (1 * rcodes[0] + 4 * rcodes[1]) / 5.0; // bit code 101
                            rcodes[6] = 0.0;                                   // bit code 110
                            rcodes[7] = 1.0;                                   // bit code 111
                        }

                        if (green0 > green1)
                        {
                            gcodes[2] = (6 * gcodes[0] + 1 * gcodes[1]) / 7.0; // bit code 010
                            gcodes[3] = (5 * gcodes[0] + 2 * gcodes[1]) / 7.0; // bit code 011
                            gcodes[4] = (4 * gcodes[0] + 3 * gcodes[1]) / 7.0; // bit code 100
                            gcodes[5] = (3 * gcodes[0] + 4 * gcodes[1]) / 7.0; // bit code 101
                            gcodes[6] = (2 * gcodes[0] + 5 * gcodes[1]) / 7.0; // bit code 110
                            gcodes[7] = (1 * gcodes[0] + 6 * gcodes[1]) / 7.0; // bit code 111
                        }
                        else
                        {
                            gcodes[2] = (4 * gcodes[0] + 1 * gcodes[1]) / 5.0; // bit code 010
                            gcodes[3] = (3 * gcodes[0] + 2 * gcodes[1]) / 5.0; // bit code 011
                            gcodes[4] = (2 * gcodes[0] + 3 * gcodes[1]) / 5.0; // bit code 100
                            gcodes[5] = (1 * gcodes[0] + 4 * gcodes[1]) / 5.0; // bit code 101
                            gcodes[6] = 0.0;                                   // bit code 110
                            gcodes[7] = 1.0;                                   // bit code 111
                        }

                        int bwidth  = Functions.Min(4, width - (destinationPoint.X + x));
                        int bheight = Functions.Min(4, height - (destinationPoint.Y + y));

                        for (int y2 = 0; y2 < bheight; ++y2)
                        {
                            int xyindex = (destinationPoint.X + x) + (destinationPoint.Y + y + y2) * width + zindex;

                            for (int x2 = 0; x2 < bwidth; ++x2)
                            {
                                ulong rindex = (rindices >> ((x2 + (y2 * 4)) << 2)) & 7;
                                ulong gindex = (gindices >> ((x2 + (y2 * 4)) << 2)) & 7;
                                destination[xyindex++] = new Colord(
                                    rcodes[rindex],
                                    gcodes[gindex],
                                    0.0);
                            }
                        }
                    }
                    //seek to next scan line
                    source.Seek(rowPitch - ((sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
                }
                //seek to next scan slice
                source.Seek(slicePitch - ((sourceBoxi.Height / 4) * (sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
            }
        }
예제 #52
0
 static Colord Lerp(Colord p0, Colord p1, double f)
 {
     return(p0 + f * (p1 - p0));
 }
예제 #53
0
파일: BC4.cs 프로젝트: Frassle/Ibasa
        public override void GetColords(
            System.IO.Stream source, int rowPitch, int slicePitch,
            Colord[] destination, int index, int width, int height,
            Boxi sourceBoxi, Point3i destinationPoint)
        {
            if ((width & 0x3) != 0 || (height & 0x3) != 0)
                throw new ArgumentException("sourceSize Width and Height must be a multiple of 4.", "sourceSize");
            if ((sourceBoxi.X & 0x3) != 0 || (sourceBoxi.Y & 0x3) != 0)
                throw new ArgumentException("sourceBoxi X and Y must be a multiple of 4.", "sourceBoxi");

            //seek to start
            source.Seek(
                (sourceBoxi.X / 4) * BlockSize + (sourceBoxi.Y / 4) * rowPitch + sourceBoxi.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            double[] rcodes = new double[16];
            byte[] block = new byte[BlockSize];

            // loop over blocks
            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                int zindex = index + (destinationPoint.Z + z) * (height * width);

                for (int y = 0; y < sourceBoxi.Height; y += 4)
                {
                    //read scan line
                    for (int x = 0; x < sourceBoxi.Width; x += 4)
                    {
                        //read block
                        int read = 0;
                        while (read < BlockSize)
                        {
                            int bytes = source.Read(block, read, BlockSize - read);
                            if (bytes == 0)
                                throw new System.IO.EndOfStreamException();
                            read += bytes;
                        }

                        // decompress the block
                        int red0 = block[0];
                        int red1 = block[1];
                        ulong rindices =
                            BitConverter.ToUInt16(block, 2) |
                            ((ulong)BitConverter.ToUInt32(block, 4) << 16); //Only 6 bytes

                        // unpack the endpoints
                        rcodes[0] = red0 / 255.0;
                        rcodes[1] = red1 / 255.0;

                        //generate midpoints
                        if (red0 > red1)
                        {
                            rcodes[2] = (6 * rcodes[0] + 1 * rcodes[1]) / 7.0; // bit code 010
                            rcodes[3] = (5 * rcodes[0] + 2 * rcodes[1]) / 7.0; // bit code 011
                            rcodes[4] = (4 * rcodes[0] + 3 * rcodes[1]) / 7.0; // bit code 100
                            rcodes[5] = (3 * rcodes[0] + 4 * rcodes[1]) / 7.0; // bit code 101
                            rcodes[6] = (2 * rcodes[0] + 5 * rcodes[1]) / 7.0; // bit code 110
                            rcodes[7] = (1 * rcodes[0] + 6 * rcodes[1]) / 7.0; // bit code 111
                        }
                        else
                        {
                            rcodes[2] = (4 * rcodes[0] + 1 * rcodes[1]) / 5.0; // bit code 010
                            rcodes[3] = (3 * rcodes[0] + 2 * rcodes[1]) / 5.0; // bit code 011
                            rcodes[4] = (2 * rcodes[0] + 3 * rcodes[1]) / 5.0; // bit code 100
                            rcodes[5] = (1 * rcodes[0] + 4 * rcodes[1]) / 5.0; // bit code 101
                            rcodes[6] = 0.0;					 // bit code 110
                            rcodes[7] = 1.0;					 // bit code 111
                        }

                        int bwidth = Functions.Min(4, width - (destinationPoint.X + x));
                        int bheight = Functions.Min(4, height - (destinationPoint.Y + y));

                        for (int y2 = 0; y2 < bheight; ++y2)
                        {
                            int xyindex = (destinationPoint.X + x) + (destinationPoint.Y + y + y2) * width + zindex;

                            for (int x2 = 0; x2 < bwidth; ++x2)
                            {
                                ulong rindex = (rindices >> ((x2 + (y2 * 4)) << 2)) & 7;
                                destination[xyindex++] = new Colord(
                                    rcodes[rindex],
                                    0.0,
                                    0.0);
                            }
                        }
                    }
                    //seek to next scan line
                    source.Seek(rowPitch - ((sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
                }
                //seek to next scan slice
                source.Seek(slicePitch - ((sourceBoxi.Height / 4) * (sourceBoxi.Width / 4) * BlockSize), System.IO.SeekOrigin.Current);
            }
        }
예제 #54
0
파일: BC1.cs 프로젝트: bonomali/Ibasa
        public override void GetColords(
            System.IO.Stream source, int rowPitch, int slicePitch,
            Colord[] destination, int index, int width, int height,
            Boxi sourceBoxi, Point3i destinationPoint)
        {
            if ((sourceBoxi.X & 0x3) != 0 || (sourceBoxi.Y & 0x3) != 0)
            {
                throw new ArgumentException("sourceBoxi X and Y must be a multiple of 4.", "sourceBoxi");
            }

            //seek to start
            source.Seek(
                (sourceBoxi.X / 4) * BlockSize + (sourceBoxi.Y / 4) * rowPitch + sourceBoxi.Z * slicePitch,
                System.IO.SeekOrigin.Current);

            Colord[] codes = new Colord[4];
            byte[]   block = new byte[BlockSize];

            // loop over blocks
            for (int z = 0; z < sourceBoxi.Depth; ++z)
            {
                int zindex = index + (destinationPoint.Z + z) * (height * width);

                for (int y = 0; y < sourceBoxi.Height; y += 4)
                {
                    //read scan line
                    for (int x = 0; x < sourceBoxi.Width; x += 4)
                    {
                        //read block
                        int read = 0;
                        while (read < BlockSize)
                        {
                            int bytes = source.Read(block, read, BlockSize - read);
                            if (bytes == 0)
                            {
                                throw new System.IO.EndOfStreamException();
                            }
                            read += bytes;
                        }

                        // decompress the block
                        int  color0  = BitConverter.ToUInt16(block, 0);
                        int  color1  = BitConverter.ToUInt16(block, 2);
                        uint indices = BitConverter.ToUInt32(block, 4);

                        // unpack the endpoints
                        codes[0] = Color.Unquantized(5, 6, 5, Vector.Unpack(5, 6, 5, color0));
                        codes[1] = Color.Unquantized(5, 6, 5, Vector.Unpack(5, 6, 5, color1));

                        // generate the midpoints
                        if (color0 > color1)
                        {
                            codes[2] = Numerics.Color.Lerp(codes[0], codes[1], 1.0 / 3.0);
                            codes[3] = Numerics.Color.Lerp(codes[0], codes[1], 2.0 / 3.0);
                        }
                        else
                        {
                            codes[2] = Numerics.Color.Lerp(codes[0], codes[1], 1.0 / 2.0);
                            codes[3] = new Numerics.Colord(0.0, 0.0, 0.0, 0.0);
                        }


                        int bwidth  = Functions.Min(4, width - (destinationPoint.X + x));
                        int bheight = Functions.Min(4, height - (destinationPoint.Y + y));

                        for (int y2 = 0; y2 < bheight; ++y2)
                        {
                            int xyindex = (destinationPoint.X + x) + (destinationPoint.Y + y + y2) * width + zindex;

                            for (int x2 = 0; x2 < bwidth; ++x2)
                            {
                                uint codeIndex = (indices >> ((x2 + (y2 * 4)) << 1) & 3);
                                destination[xyindex++] = codes[codeIndex];
                            }
                        }
                    }
                    //seek to next scan line
                    source.Seek(rowPitch - (((sourceBoxi.Width + 3) / 4) * BlockSize),
                                System.IO.SeekOrigin.Current);
                }
                //seek to next scan slice
                source.Seek(slicePitch - (((sourceBoxi.Height + 3) / 4) * ((sourceBoxi.Width + 3) / 4) * BlockSize),
                            System.IO.SeekOrigin.Current);
            }
        }