1
1
// Copyright (c) Files Community
2
2
// Licensed under the MIT License.
3
3
4
+ using System . Drawing ;
4
5
using System . Collections . Concurrent ;
5
6
using System . Runtime . InteropServices ;
6
7
using Windows . Win32 ;
@@ -20,32 +21,6 @@ public static partial class WindowsStorableHelpers
20
21
private static ( Guid Format , Guid Encorder ) [ ] ? GdiEncoders ;
21
22
private static ConcurrentDictionary < ( string , int , int ) , byte [ ] > ? DllIconCache ;
22
23
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
-
49
24
// Methods
50
25
51
26
/// <inheritdoc cref="TryGetThumbnail"/>
@@ -84,48 +59,45 @@ public unsafe static HRESULT TryGetThumbnail(this IWindowsStorable storable, int
84
59
}
85
60
86
61
// 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 )
89
64
{
90
65
if ( ! hBitmap . IsNull ) PInvoke . DeleteObject ( hBitmap ) ;
91
66
return HRESULT . E_FAIL ;
92
67
}
93
68
94
69
// 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 ) ) ;
98
71
99
72
// Flip the image manually row by row
100
73
for ( int y = 0 ; y < bmp . bmHeight ; y ++ )
101
74
{
102
75
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 ,
105
78
bmp . bmWidthBytes ,
106
79
bmp . bmWidthBytes
107
80
) ;
108
81
}
109
82
110
83
// 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 )
113
86
{
114
- Marshal . FreeHGlobal ( flippedBits ) ;
87
+ if ( flippedBits is not null ) NativeMemory . Free ( flippedBits ) ;
115
88
if ( ! hBitmap . IsNull ) PInvoke . DeleteObject ( hBitmap ) ;
116
89
return HRESULT . E_FAIL ;
117
90
}
118
91
119
- Marshal . FreeHGlobal ( flippedBits ) ;
120
-
121
- GpBitmap * gpBitmap = ( GpBitmap * ) gpBitmapPtr ;
122
-
123
- if ( TryConvertGpBitmapToByteArray ( gpBitmap , out thumbnailData ) )
92
+ if ( ! TryConvertGpBitmapToByteArray ( gpBitmap , out thumbnailData ) )
124
93
{
125
94
if ( ! hBitmap . IsNull ) PInvoke . DeleteObject ( hBitmap ) ;
126
95
return HRESULT . E_FAIL ;
127
96
}
128
97
98
+ if ( flippedBits is not null ) NativeMemory . Free ( flippedBits ) ;
99
+ if ( ! hBitmap . IsNull ) PInvoke . DeleteObject ( hBitmap ) ;
100
+
129
101
return HRESULT . S_OK ;
130
102
}
131
103
0 commit comments