public static TinyResourcesEntry TryCreateTinyResourcesEntry( string name, byte[] value ) { TinyResourcesEntry entry = null; try { MemoryStream stream = new MemoryStream( value ); BinaryReader reader = new BinaryReader( stream ); uint magicNumber = reader.ReadUInt32(); stream.Position = 0; if(magicNumber == TinyResourceFile.Header.MAGIC_NUMBER) { TinyResourceFile file = new TinyResourceFile(); file.Deserialize( reader ); if(file.resources.Length == 1) { TinyResourceFile.Resource resource = file.resources[0]; entry = new TinyResourcesEntry( name, resource.data ); entry.resource = resource.header; } } } catch { } return entry; }
void IResourceWriter.Generate() { //PrepareToGenerate(); ProcessResourceFiles.EnsureResourcesIds( this.resources ); TinyResourceFile.Header header = new TinyResourceFile.Header( (uint)resources.Count ); TinyResourceFile file = new TinyResourceFile( header ); for(int iResource = 0; iResource < resources.Count; iResource++) { Entry entry = (Entry)resources[iResource]; byte[] data = entry.GenerateResourceData(); TinyResourceFile.ResourceHeader resource = new TinyResourceFile.ResourceHeader(entry.Id, entry.ResourceType, (uint)data.Length); file.AddResource( new TinyResourceFile.Resource(resource, data) ); } using(FileStream fileStream = File.Open( fileName, FileMode.OpenOrCreate )) { BinaryWriter writer = new BinaryWriter( fileStream ); file.Serialize( writer ); fileStream.Flush(); } }
private byte[] GetBitmapData( Bitmap bitmap, out TinyResourceFile.CLR_GFX_BitmapDescription bitmapDescription ) { byte[] data = null; if(bitmap.Width > 0xFFFF || bitmap.Height > 0xFFFF) { throw new ArgumentException( "bitmap dimensions out of range" ); } if(bitmap.RawFormat.Equals(ImageFormat.Jpeg)) { data = GetBitmapDataJpeg( bitmap, out bitmapDescription ); } else if(bitmap.RawFormat.Equals(ImageFormat.Gif)) { data = GetBitmapDataGif( bitmap, out bitmapDescription ); } else if(bitmap.RawFormat.Equals( ImageFormat.Bmp )) { data = GetBitmapDataBmp( bitmap, out bitmapDescription ); } else { throw new NotSupportedException( string.Format("Bitmap imageFormat not supported '{0}'", bitmap.RawFormat.Guid.ToString()) ); } return data; }
private byte[] GetBitmapDataGif( Bitmap bitmap, out TinyResourceFile.CLR_GFX_BitmapDescription bitmapDescription ) { return GetBitmapDataRaw( bitmap, out bitmapDescription, TinyResourceFile.CLR_GFX_BitmapDescription.c_TypeGif); }
private byte[] GetBitmapDataRaw( Bitmap bitmap, out TinyResourceFile.CLR_GFX_BitmapDescription bitmapDescription, byte type ) { bitmapDescription = new TinyResourceFile.CLR_GFX_BitmapDescription( (ushort)bitmap.Width, (ushort)bitmap.Height, 0, 1, type); MemoryStream stream = new MemoryStream(); bitmap.Save( stream, bitmap.RawFormat ); stream.Capacity = (int)stream.Length; return stream.GetBuffer(); }
private byte[] GetBitmapDataBmp( Bitmap bitmap, out TinyResourceFile.CLR_GFX_BitmapDescription bitmapDescription ) { //issue warning for formats that we lose information? //other formats that we need to support?? byte bitsPerPixel = 24; BitmapData bitmapData = null; Rectangle rect = new Rectangle( 0, 0, bitmap.Width, bitmap.Height ); PixelFormat formatDst = bitmap.PixelFormat; byte[] data = null; switch(bitmap.PixelFormat) { case PixelFormat.Format1bppIndexed: bitsPerPixel = 1; formatDst = PixelFormat.Format1bppIndexed; break; // Anything more than 16bpp will fall through to 16bpp case PixelFormat.Format8bppIndexed: case PixelFormat.Format24bppRgb: case PixelFormat.Format32bppRgb: case PixelFormat.Format48bppRgb: case PixelFormat.Format16bppRgb555: case PixelFormat.Format16bppRgb565: bitsPerPixel = 16; formatDst = PixelFormat.Format16bppRgb565; break; default: throw new NotSupportedException( string.Format( "PixelFormat of '{0}' resource not supported", this.Name ) ); } //turn bitmap data into a form we can use. if(formatDst != bitmap.PixelFormat) { bitmap = bitmap.Clone( rect, formatDst ); } try { bitmapData = bitmap.LockBits( rect, ImageLockMode.ReadOnly, formatDst ); IntPtr p = bitmapData.Scan0; data = new byte[bitmapData.Stride * bitmap.Height]; System.Runtime.InteropServices.Marshal.Copy( bitmapData.Scan0, data, 0, data.Length ); if(bitsPerPixel == 1) { //special case for 1pp with index 0 equals white???!!!??? if(bitmap.Palette.Entries[0].GetBrightness() < 0.5) { for(int i = 0; i < data.Length; i++) { data[i] = (byte)~data[i]; } } //special case for 1pp need to flip orientation?? //for some stupid reason, 1bpp is flipped compared to windows!! Adjust1bppOrientation( data ); } } finally { if(bitmapData != null) { bitmap.UnlockBits( bitmapData ); } } bitmapDescription = new TinyResourceFile.CLR_GFX_BitmapDescription( (ushort)bitmap.Width, (ushort)bitmap.Height, 0, bitsPerPixel, TinyResourceFile.CLR_GFX_BitmapDescription.c_TypeBitmap ); if(bitsPerPixel == 1) { //test compression; Compress1bpp( bitmapDescription, ref data ); } return data; }
private void Compress1bpp( TinyResourceFile.CLR_GFX_BitmapDescription bitmapDescription, ref byte[] buf ) { MemoryStream ms = new MemoryStream( buf.Length ); //adapted from CLR_GFX_Bitmap::Compress //CLR_RT_Buffer buffer; int count = 0; bool fSetSav = false; bool fSet = false; bool fFirst = true; bool fRun = true; byte data = 0; bool fEmit = false; int widthInWords = (int)((bitmapDescription.m_width + 31) / 32); int iByte; byte iPixelMask; iByte = 0; for(int y = 0; y < bitmapDescription.m_height; y++) { iPixelMask = 0x1; iByte = y * (widthInWords * 4); for(int x = 0; x < bitmapDescription.m_width; x++) { fSetSav = fSet; fSet = (buf[iByte] & iPixelMask) != 0; if(fFirst) { fFirst = false; } else { if(fRun) { fRun = (fSetSav == fSet); if((count == 0x3f + TinyResourceFile.CLR_GFX_BitmapDescription.c_CompressedRunOffset) || (!fRun && count >= TinyResourceFile.CLR_GFX_BitmapDescription.c_CompressedRunOffset)) { data = TinyResourceFile.CLR_GFX_BitmapDescription.c_CompressedRun; data |= (fSetSav ? TinyResourceFile.CLR_GFX_BitmapDescription.c_CompressedRunSet : (byte)0x0); data |= (byte)(count - TinyResourceFile.CLR_GFX_BitmapDescription.c_CompressedRunOffset); fEmit = true; } } if(!fRun && count == TinyResourceFile.CLR_GFX_BitmapDescription.c_UncompressedRunLength) { fEmit = true; } if(fEmit) { ms.WriteByte( data ); data = 0; count = 0; fEmit = false; fRun = true; } } data |= (byte)((0x1 << count) & (fSet ? 0xff : 0x0)); iPixelMask <<= 1; if(iPixelMask == 0) { iPixelMask = 0x1; iByte++; } count++; } } if(fRun && count >= TinyResourceFile.CLR_GFX_BitmapDescription.c_CompressedRunOffset) { data = TinyResourceFile.CLR_GFX_BitmapDescription.c_CompressedRun; data |= (fSetSav ? TinyResourceFile.CLR_GFX_BitmapDescription.c_CompressedRunSet : (byte)0x0); data |= (byte)(count - TinyResourceFile.CLR_GFX_BitmapDescription.c_CompressedRunOffset); } ms.WriteByte( data ); if(ms.Length < buf.Length) { ms.Capacity = (int)ms.Length; buf = ms.GetBuffer(); bitmapDescription.m_flags |= TinyResourceFile.CLR_GFX_BitmapDescription.c_Compressed; } }