11// Copyright (c) Files Community
22// Licensed under the MIT License.
33
4+ using System . Drawing ;
45using System . Collections . Concurrent ;
56using System . Runtime . InteropServices ;
67using Windows . Win32 ;
@@ -20,32 +21,6 @@ public static partial class WindowsStorableHelpers
2021 private static ( Guid Format , Guid Encorder ) [ ] ? GdiEncoders ;
2122 private static ConcurrentDictionary < ( string , int , int ) , byte [ ] > ? DllIconCache ;
2223
23- private const int PixelFormat32bppARGB = 2498570 ; // Added constant for transparency
24-
25- [ StructLayout ( LayoutKind . Sequential ) ]
26- private struct BITMAP // Added BITMAP structure for bitmap operations
27- {
28- public int bmType ;
29- public int bmWidth ;
30- public int bmHeight ;
31- public int bmWidthBytes ;
32- public ushort bmPlanes ;
33- public ushort bmBitsPixel ;
34- public IntPtr bmBits ;
35- }
36-
37- [ DllImport ( "gdi32.dll" , SetLastError = true ) ] // Added P/Invoke for GetObject
38- private static extern int GetObject ( IntPtr hObject , int nCount , ref BITMAP lpObject ) ;
39-
40- [ DllImport ( "gdiplus.dll" , SetLastError = true ) ] // Added P/Invoke for GdipCreateBitmapFromScan0
41- private static extern int GdipCreateBitmapFromScan0 (
42- int width ,
43- int height ,
44- int stride ,
45- int pixelFormat ,
46- IntPtr scan0 ,
47- out IntPtr bitmap ) ;
48-
4924 // Methods
5025
5126 /// <inheritdoc cref="TryGetThumbnail"/>
@@ -84,48 +59,45 @@ public unsafe static HRESULT TryGetThumbnail(this IWindowsStorable storable, int
8459 }
8560
8661 // Retrieve BITMAP data
87- BITMAP bmp = new BITMAP ( ) ;
88- if ( GetObject ( ( nint ) hBitmap . Value , Marshal . SizeOf ( typeof ( BITMAP ) ) , ref bmp ) == 0 )
62+ BITMAP bmp = default ;
63+ if ( PInvoke . GetObject ( hBitmap , sizeof ( BITMAP ) , & bmp ) is 0 )
8964 {
9065 if ( ! hBitmap . IsNull ) PInvoke . DeleteObject ( hBitmap ) ;
9166 return HRESULT . E_FAIL ;
9267 }
9368
9469 // Allocate buffer for flipped pixel data
95- IntPtr flippedBits = Marshal . AllocHGlobal ( bmp . bmWidthBytes * bmp . bmHeight ) ;
96- byte * src = ( byte * ) bmp . bmBits ;
97- byte * dst = ( byte * ) flippedBits ;
70+ byte * flippedBits = ( byte * ) NativeMemory . AllocZeroed ( ( nuint ) ( bmp . bmWidthBytes * bmp . bmHeight ) ) ;
9871
9972 // Flip the image manually row by row
10073 for ( int y = 0 ; y < bmp . bmHeight ; y ++ )
10174 {
10275 Buffer . MemoryCopy (
103- src + y * bmp . bmWidthBytes ,
104- dst + ( bmp . bmHeight - y - 1 ) * bmp . bmWidthBytes ,
76+ ( byte * ) bmp . bmBits + y * bmp . bmWidthBytes ,
77+ flippedBits + ( bmp . bmHeight - y - 1 ) * bmp . bmWidthBytes ,
10578 bmp . bmWidthBytes ,
10679 bmp . bmWidthBytes
10780 ) ;
10881 }
10982
11083 // Create GpBitmap from the flipped pixel data
111- IntPtr gpBitmapPtr ;
112- if ( GdipCreateBitmapFromScan0 ( bmp . bmWidth , bmp . bmHeight , bmp . bmWidthBytes , PixelFormat32bppARGB , flippedBits , out gpBitmapPtr ) != 0 )
84+ GpBitmap * gpBitmap = default ;
85+ if ( PInvoke . GdipCreateBitmapFromScan0 ( bmp . bmWidth , bmp . bmHeight , bmp . bmWidthBytes , PInvoke . PixelFormat32bppARGB , flippedBits , & gpBitmap ) != Status . Ok )
11386 {
114- Marshal . FreeHGlobal ( flippedBits ) ;
87+ if ( flippedBits is not null ) NativeMemory . Free ( flippedBits ) ;
11588 if ( ! hBitmap . IsNull ) PInvoke . DeleteObject ( hBitmap ) ;
11689 return HRESULT . E_FAIL ;
11790 }
11891
119- Marshal . FreeHGlobal ( flippedBits ) ;
120-
121- GpBitmap * gpBitmap = ( GpBitmap * ) gpBitmapPtr ;
122-
123- if ( TryConvertGpBitmapToByteArray ( gpBitmap , out thumbnailData ) )
92+ if ( ! TryConvertGpBitmapToByteArray ( gpBitmap , out thumbnailData ) )
12493 {
12594 if ( ! hBitmap . IsNull ) PInvoke . DeleteObject ( hBitmap ) ;
12695 return HRESULT . E_FAIL ;
12796 }
12897
98+ if ( flippedBits is not null ) NativeMemory . Free ( flippedBits ) ;
99+ if ( ! hBitmap . IsNull ) PInvoke . DeleteObject ( hBitmap ) ;
100+
129101 return HRESULT . S_OK ;
130102 }
131103
0 commit comments