Пример #1
0
        public static short[] decode_vorbis_from_memory(byte[] input, out int sampleRate, out int chan)
        {
            short *result = null;
            int    length = 0;

            fixed(byte *b = input)
            {
                int c, s;

                length = stb_vorbis_decode_memory(b, input.Length, &c, &s, ref result);

                chan       = c;
                sampleRate = s;
            }

            var output = new short[length];

            Marshal.Copy(new IntPtr(result), output, 0, output.Length);
            CRuntime.free(result);

            return(output);
        }
Пример #2
0
        public Image Read(Stream stream, int req_comp = StbImage.STBI_default)
        {
            _stream = stream;

            try
            {
                int x, y, comp;
                var result = StbImage.stbi_load_from_callbacks(_callbacks, null, &x, &y, &comp, req_comp);

                var image = new Image
                {
                    Width      = x,
                    Height     = y,
                    SourceComp = comp,
                    Comp       = req_comp == StbImage.STBI_default ? comp : req_comp
                };

                if (result == null)
                {
                    throw new Exception(StbImage.LastError);
                }

                // Convert to array
                var data = new byte[x * y * image.Comp];
                Marshal.Copy(new IntPtr(result), data, 0, data.Length);
                CRuntime.free(result);

                image.Data = data;

                return(image);
            }
            finally
            {
                _stream = null;
            }
        }
Пример #3
0
        public static void stb__DitherBlock(byte *dest, byte *block)
        {
            int *err = stackalloc int[8];
            var  ep1 = err;
            var  ep2 = err + 4;
            int  ch;

            for (ch = 0; ch < 3; ++ch)
            {
                var bp         = block + ch;
                var dp         = dest + ch;
                var quantArray = ch == (1) ? stb__QuantGTab : stb__QuantRBTab;
                fixed(byte *quant = quantArray)
                {
                    CRuntime.memset(err, 0, (ulong)(8 * sizeof(int)));
                    int y;

                    for (y = 0; (y) < (4); ++y)
                    {
                        dp[0]  = quant[bp[0] + ((3 * ep2[1] + 5 * ep2[0]) >> 4)];
                        ep1[0] = bp[0] - dp[0];
                        dp[4]  = quant[bp[4] + ((7 * ep1[0] + 3 * ep2[2] + 5 * ep2[1] + ep2[0]) >> 4)];
                        ep1[1] = bp[4] - dp[4];
                        dp[8]  = quant[bp[8] + ((7 * ep1[1] + 3 * ep2[3] + 5 * ep2[2] + ep2[1]) >> 4)];
                        ep1[2] = bp[8] - dp[8];
                        dp[12] = quant[bp[12] + ((7 * ep1[2] + 5 * ep2[3] + ep2[2]) >> 4)];
                        ep1[3] = bp[12] - dp[12];
                        bp    += 16;
                        dp    += 16;
                        var et = ep1;
                        ep1 = ep2;
                        ep2 = et;
                    }
                }
            }
        }
Пример #4
0
 private static void *stbi__malloc(int size)
 {
     return(CRuntime.malloc((ulong)size));
 }
Пример #5
0
        public static void stb__OptimizeColorsBlock(byte *block, ushort *pmax16, ushort *pmin16)
        {
            int    mind = (int)(0x7fffffff);
            int    maxd = (int)(-0x7fffffff);
            byte * minp = null;
            byte * maxp = null;
            double magn;
            int    v_r;
            int    v_g;
            int    v_b;
            int    nIterPower = (int)(4);
            float *covf       = stackalloc float[6];
            float  vfr;
            float  vfg;
            float  vfb;
            int *  cov = stackalloc int[6];
            int *  mu  = stackalloc int[3];
            int *  min = stackalloc int[3];
            int *  max = stackalloc int[3];
            int    ch;
            int    i;
            int    iter;

            for (ch = (int)(0); (ch) < (3); ch++)
            {
                byte *bp = (block) + ch;
                int   muv;
                int   minv;
                int   maxv;
                muv = (int)(minv = (int)(maxv = (int)(bp[0])));
                for (i = (int)(4); (i) < (64); i += (int)(4))
                {
                    muv += (int)(bp[i]);
                    if ((bp[i]) < (minv))
                    {
                        minv = (int)(bp[i]);
                    }
                    else if ((bp[i]) > (maxv))
                    {
                        maxv = (int)(bp[i]);
                    }
                }
                mu[ch]  = (int)((muv + 8) >> 4);
                min[ch] = (int)(minv);
                max[ch] = (int)(maxv);
            }
            for (i = (int)(0); (i) < (6); i++)
            {
                cov[i] = (int)(0);
            }
            for (i = (int)(0); (i) < (16); i++)
            {
                int r = (int)(block[i * 4 + 0] - mu[0]);
                int g = (int)(block[i * 4 + 1] - mu[1]);
                int b = (int)(block[i * 4 + 2] - mu[2]);
                cov[0] += (int)(r * r);
                cov[1] += (int)(r * g);
                cov[2] += (int)(r * b);
                cov[3] += (int)(g * g);
                cov[4] += (int)(g * b);
                cov[5] += (int)(b * b);
            }
            for (i = (int)(0); (i) < (6); i++)
            {
                covf[i] = (float)(cov[i] / 255.0f);
            }
            vfr = ((float)(max[0] - min[0]));
            vfg = ((float)(max[1] - min[1]));
            vfb = ((float)(max[2] - min[2]));
            for (iter = (int)(0); (iter) < (nIterPower); iter++)
            {
                float r = (float)(vfr * covf[0] + vfg * covf[1] + vfb * covf[2]);
                float g = (float)(vfr * covf[1] + vfg * covf[3] + vfb * covf[4]);
                float b = (float)(vfr * covf[2] + vfg * covf[4] + vfb * covf[5]);
                vfr = (float)(r);
                vfg = (float)(g);
                vfb = (float)(b);
            }
            magn = (double)(CRuntime.fabs((double)(vfr)));
            if ((CRuntime.fabs((double)(vfg))) > (magn))
            {
                magn = (double)(CRuntime.fabs((double)(vfg)));
            }
            if ((CRuntime.fabs((double)(vfb))) > (magn))
            {
                magn = (double)(CRuntime.fabs((double)(vfb)));
            }
            if ((magn) < (4.0f))
            {
                v_r = (int)(299);
                v_g = (int)(587);
                v_b = (int)(114);
            }
            else
            {
                magn = (double)(512.0 / magn);
                v_r  = ((int)(vfr * magn));
                v_g  = ((int)(vfg * magn));
                v_b  = ((int)(vfb * magn));
            }

            for (i = (int)(0); (i) < (16); i++)
            {
                int dot = (int)(block[i * 4 + 0] * v_r + block[i * 4 + 1] * v_g + block[i * 4 + 2] * v_b);
                if ((dot) < (mind))
                {
                    mind = (int)(dot);
                    minp = block + i * 4;
                }
                if ((dot) > (maxd))
                {
                    maxd = (int)(dot);
                    maxp = block + i * 4;
                }
            }
            *pmax16 = (ushort)(stb__As16Bit((int)(maxp[0]), (int)(maxp[1]), (int)(maxp[2])));
            *pmin16 = (ushort)(stb__As16Bit((int)(minp[0]), (int)(minp[1]), (int)(minp[2])));
        }
Пример #6
0
        public static byte[] stb_compress_dxt(Image image, bool hasAlpha = true, int mode = 10)
        {
            if (image.Comp != 4)
            {
                throw new Exception("This method supports only rgba images");
            }

            var osize  = hasAlpha ? 16 : 8;
            var result = new byte[(image.Width + 3) * (image.Height + 3) / 16 * osize];

            fixed(byte *rgba = image.Data)
            {
                fixed(byte *resultPtr = result)
                {
                    var p = resultPtr;

                    byte *block = stackalloc byte[16 * 4];

                    for (var j = 0; j < image.Width; j += 4)
                    {
                        var x = 4;
                        for (var i = 0; i < image.Height; i += 4)
                        {
                            if (j + 3 >= image.Width)
                            {
                                x = image.Width - j;
                            }
                            int y;
                            for (y = 0; y < 4; ++y)
                            {
                                if (j + y >= image.Height)
                                {
                                    break;
                                }
                                CRuntime.memcpy(block + y * 16, rgba + image.Width * 4 * (j + y) + i * 4, x * 4);
                            }
                            int y2;
                            if (x < 4)
                            {
                                switch (x)
                                {
                                case 0:
                                    throw new Exception("Unknown error");

                                case 1:
                                    for (y2 = 0; y2 < y; ++y2)
                                    {
                                        CRuntime.memcpy(block + y2 * 16 + 1 * 4, block + y2 * 16 + 0 * 4, 4);
                                        CRuntime.memcpy(block + y2 * 16 + 2 * 4, block + y2 * 16 + 0 * 4, 8);
                                    }
                                    break;

                                case 2:
                                    for (y2 = 0; y2 < y; ++y2)
                                    {
                                        CRuntime.memcpy(block + y2 * 16 + 2 * 4, block + y2 * 16 + 0 * 4, 8);
                                    }
                                    break;

                                case 3:
                                    for (y2 = 0; y2 < y; ++y2)
                                    {
                                        CRuntime.memcpy(block + y2 * 16 + 3 * 4, block + y2 * 16 + 1 * 4, 4);
                                    }
                                    break;
                                }
                            }
                            y2 = 0;
                            for (; y < 4; ++y, ++y2)
                            {
                                CRuntime.memcpy(block + y * 16, block + y2 * 16, 4 * 4);
                            }
                            stb_compress_dxt_block(p, block, hasAlpha ? 1 : 0, mode);
                            p += hasAlpha ? 16 : 8;
                        }
                    }
                }
            }

            return(result);
        }