void SharpSquish_BlockAdvance(SharpSquishBlockAdvanceEventArgs e) { e.Cancel = _cancel; progressBar1.Maximum = e.Blocks; if (e.Current <= e.Blocks) progressBar1.Value = e.Current; else progressBar1.Value = progressBar1.Maximum; if ((e.Current - _last) > 60) { Application.DoEvents(); _last = e.Current; } }
/// <summary> /// Compresses an image in memory. /// </summary> /// <param name="rgba">The pixels of the source.</param> /// <param name="width">The width of the source image.</param> /// <param name="height">The height of the source image.</param> /// <param name="blocks">Storage for the compressed output.</param> /// <param name="flags">Compression flags.</param> public static unsafe void CompressImage(byte* rgba, int width, int height, byte* blocks, SquishFlags flags) { bool b_cancel = false; // fix any bad flags flags = FixFlags(flags); // initialise the block output byte* targetBlock = blocks; int bytesPerBlock = BytesPerBlock(flags); int current = 0, blocksCount = GetBlocksCount(width, height); // loop over blocks for (int y = 0; y < height; y += 4) { for (int x = 0; x < width; x += 4) { // build the 4x4 block of pixels byte[] sourceRgba = new byte[16 * 4]; fixed (byte* fixSourceRgba = sourceRgba) { byte* targetPixel = fixSourceRgba; //byte* targetPixel = sourceRgba; int mask = 0; for (int py = 0; py < 4; ++py) { for (int px = 0; px < 4; ++px) { // get the source pixel in the image int sx = x + px; int sy = y + py; // enable if we're in the image if (sx < width && sy < height) { // copy the rgba value byte* sourcePixel = rgba + 4 * (width * sy + sx); for (int i = 0; i < 4; ++i) *targetPixel++ = *sourcePixel++; // enable this pixel mask |= (1 << (4 * py + px)); } else { // skip this pixel as its outside the image targetPixel += 4; } } } // compress it into the output CompressMasked(fixSourceRgba, mask, targetBlock, flags); } if (BlockAdvance != null) { SharpSquishBlockAdvanceEventArgs e = new SharpSquishBlockAdvanceEventArgs(); e.Current = current; e.Blocks = blocksCount; BlockAdvance(e); if (e.Cancel) { b_cancel = true; break; } } // advance targetBlock += bytesPerBlock; current++; } if (b_cancel) break; } }