/// <summary> /// constructs a 32bpp icon image from a stream, /// not accessible outside the dll /// </summary> internal IconImage32bpp(Stream str, Size sz) { #region read 32bpp data //create bitmap and lock it _bitmap = new Bitmap(sz.Width, sz.Height, PixelFormat.Format32bppArgb); BitmapData bd = _bitmap.LockBits( new Rectangle(Point.Empty, _bitmap.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); int *scan0 = (int *)bd.Scan0; //read pixels, note: bottom-up, left-right using (SimpleReader rdr = new SimpleReader(str)) { scan0 += bd.Width * bd.Height; for (int y = 0; y < bd.Height; y++) { scan0 -= bd.Width; for (int x = 0; x < bd.Width; x++) { scan0[x] = rdr.ReadInt32(); } } ANDMap.StampToBitmapData(rdr, bd); } _bitmap.UnlockBits(bd); #endregion _bitsperpixel = 32; }
/// <summary> /// constructs a indexed icon image from a stream, /// not accessible outside the dll /// </summary> internal IconImageIndexed(Stream str, Size sz, short bpp) { using (SimpleReader rdr = new SimpleReader(str)) { #region read palette int colorcount = Quantizer.LengthOfPalette(bpp); ColorBgra[] palette = new ColorBgra[colorcount]; for (int i = 0; i < palette.Length; i++) { palette[i].A = 255; palette[i].B = rdr.ReadByte(); palette[i].G = rdr.ReadByte(); palette[i].R = rdr.ReadByte(); rdr.ReadByte(); //reserved } _octree = Octree.FromColorArray(palette); #endregion #region read indexed data //create bitmap and lock it _bitmap = new Bitmap(sz.Width, sz.Height, PixelFormat.Format32bppArgb); BitmapData bd = _bitmap.LockBits( new Rectangle(Point.Empty, _bitmap.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); ColorBgra *scan0 = (ColorBgra *)bd.Scan0; //read pixels int indexmask = (1 << bpp) - 1; scan0 += bd.Width * bd.Height; for (int y = 0; y < bd.Height; y++) { scan0 -= bd.Width; int indexpos = 8 - bpp, data = rdr.ReadInt32(); for (int x = 0; x < bd.Width; x++) { if (indexpos >= 32) { data = rdr.ReadInt32(); indexpos -= 32; } scan0[x] = palette[indexmask & (data >> indexpos)]; if (indexpos % 8 == 0) { indexpos += 16 - bpp; } else { indexpos -= bpp; } } } ANDMap.StampToBitmapData(rdr, bd); _bitmap.UnlockBits(bd); #endregion } _bitsperpixel = bpp; }
/// <summary> /// writes the image to the specified stream /// </summary> public override void Write(Stream str) { if (str == null) { throw new ArgumentNullException("str"); } //write header BITMAPINFOHEADER header = new BITMAPINFOHEADER( _bitmap.Size, 24, this.SizeInBytes, 0); header.Write(str); #region write 24bpp data //write bitmap BitmapData bd = _bitmap.LockBits( new Rectangle(Point.Empty, _bitmap.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); ColorBgra *scan0 = (ColorBgra *)bd.Scan0; //calculate padding at end of stride int padbytescount = (_bitmap.Width * 3) % 4; byte[] padbytes = null; if (padbytescount != 0) { padbytes = new byte[padbytescount]; } //write pixels, note: bottom-up, left-right using (SimpleWriter wrt = new SimpleWriter(str)) { scan0 += bd.Width * bd.Height; for (int y = 0; y < bd.Height; y++) { scan0 -= bd.Width; for (int x = 0; x < bd.Width; x++) { wrt.Write(scan0[x].Blue); wrt.Write(scan0[x].Green); wrt.Write(scan0[x].Red); } //pad to 32bit if (padbytes != null) { wrt.Write(padbytes); } } ANDMap.WriteToStream(bd, wrt); } _bitmap.UnlockBits(bd); #endregion }
/// <summary> /// constructs a 24bpp icon image from a stream, /// not accessible outside the dll /// </summary> internal IconImage24bpp(Stream str, Size sz) { #region read 24bpp data //create bitmap and lock it _bitmap = new Bitmap(sz.Width, sz.Height, PixelFormat.Format32bppArgb); BitmapData bd = _bitmap.LockBits( new Rectangle(Point.Empty, _bitmap.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); ColorBgra *scan0 = (ColorBgra *)bd.Scan0; //calculate padding at end of stride int padbytescount = (_bitmap.Width * 3) % 4; //read pixels, note: bottom-up, left-right ColorBgra color = ColorBgra.Black; using (SimpleReader rdr = new SimpleReader(str)) { scan0 += bd.Width * bd.Height; for (int y = 0; y < bd.Height; y++) { scan0 -= bd.Width; for (int x = 0; x < bd.Width; x++) { color.Blue = rdr.ReadByte(); color.Green = rdr.ReadByte(); color.Red = rdr.ReadByte(); scan0[x] = color; } //pad to 32bit if (padbytescount != 0) { rdr.ReadBytes(padbytescount); } } ANDMap.StampToBitmapData(rdr, bd); } _bitmap.UnlockBits(bd); #endregion _bitsperpixel = 24; }
/// <summary> /// writes the image to the specified stream /// </summary> public override void Write(Stream str) { if (str == null) { throw new ArgumentNullException("str"); } //write header BITMAPINFOHEADER header = new BITMAPINFOHEADER( _bitmap.Size, 32, this.SizeInBytes, 0); header.Write(str); #region write 32bpp data //write bitmap BitmapData bd = _bitmap.LockBits( new Rectangle(Point.Empty, _bitmap.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); int *scan0 = (int *)bd.Scan0; //write pixels, note: bottom-up, left-right using (SimpleWriter wrt = new SimpleWriter(str)) { scan0 += bd.Width * bd.Height; for (int y = 0; y < bd.Height; y++) { scan0 -= bd.Width; for (int x = 0; x < bd.Width; x++) { wrt.Write(scan0[x]); } } ANDMap.WriteToStream(bd, wrt); } _bitmap.UnlockBits(bd); #endregion }
/// <summary> /// writes the image to the specified stream /// </summary> public override void Write(Stream str) { if (str == null) { throw new ArgumentNullException("str"); } //write header BITMAPINFOHEADER header = new BITMAPINFOHEADER( _bitmap.Size, _bitsperpixel, this.SizeInBytes, (1 << _bitsperpixel) & 0xFF); header.Write(str); using (SimpleWriter wrt = new SimpleWriter(str)) { #region write palette foreach (ColorBgra value in _octree.Table) { wrt.Write(value.B); wrt.Write(value.G); wrt.Write(value.R); wrt.Write((byte)0); //reserved } #endregion #region write indexed data //write bitmap BitmapData bd = _bitmap.LockBits( new Rectangle(Point.Empty, _bitmap.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); ColorBgra *scan0 = (ColorBgra *)bd.Scan0; //write indexed data int indexmask = (1 << _bitsperpixel) - 1, indexdata = 0; scan0 += bd.Width * bd.Height; for (int y = 0; y < bd.Height; y++) { scan0 -= bd.Width; int indexpos = 8 - _bitsperpixel; indexdata = 0; for (int x = 0; x < bd.Width; x++) { indexdata |= (_octree.GetOctreeIndex(scan0[x]) & indexmask) << indexpos; if (indexpos % 8 == 0) { indexpos += (16 - _bitsperpixel); } else { indexpos -= _bitsperpixel; } if (indexpos >= 32) { wrt.Write(indexdata); indexdata = 0; indexpos -= 32; } } if (indexpos != (8 - _bitsperpixel)) { wrt.Write(indexdata); } } ANDMap.WriteToStream(bd, wrt); #endregion _bitmap.UnlockBits(bd); } }