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); }
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; } }
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; } } } }
private static void *stbi__malloc(int size) { return(CRuntime.malloc((ulong)size)); }
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]))); }
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); }