home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 6_2008-2009.ISO / data / zips / Planet_Pho2141741272009.psc / Ac32bppDIB.cls < prev   
Text File  |  2008-12-26  |  42KB  |  858 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "Ac32bppDIB"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. ' Credits/Acknowledgements - Thanx goes to:
  17. '   Paul Caton for his class on calling non VB-Friendly DLLs that use _cdecl calling convention
  18. '       Used when calling non VB-friendly zLIB dll versions
  19. '   Alfred Koppold for his PNG, VB-only, decompression routines.
  20. '       Used when zLib & GDI+ not available
  21. '   Carles P.V for his pvResize logic
  22. '       Used when manually scaling images with NearestNeighbor or BiLinear interpolation
  23. '   www.zlib.net for their free zLIB.dll, the standard DLL for compressing/decompressing PNGs
  24. '       Without it, we'd be limited to GDI+ for creating PNGs
  25. '   coders like you that provide constructive criticism to make this class better & more all-inclusive
  26. '       Without your comments, this project probably would have died several versions/updates ago
  27. ' For most current updates/enhancements visit the following:
  28. '   Visit http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=67466&lngWId=1
  29.  
  30. ' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  31. '                                    O V E R V I E W
  32. ' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  33. ' About 32bpp pre-multiplied RGB (pARGB) bitmaps, if you are not aware.
  34. '   - These are used specifically for the AlphaBlend API & are GDI+ compatible
  35. '   Advantages:
  36. '       - Images can be per-pixel alpha blended
  37. '       - Opacity can be simultaneously adjusted during rendering
  38. '       - AlphaBlend does both BitBlt & StretchBlt for pARGB images.
  39. '       - Speed: AlphaBlend & GDI+ are pretty quick APIs vs manual blending
  40. '   Disadvantages:
  41. '       - The original RGB values are permanently destroyed during pre-multiplying
  42. '           -- Premultiplied formula: preMultipliedRed=(OriginalRed * Alpha) \ 255
  43. '           -- There is no way to convert pARGB back to non-premultiplied RGB values
  44. '              The formula would be: reconstructedRed=(preMultipliedRed * 255) \ Alpha.
  45. '               but because of integer division when pre-multiplying, the result is only
  46. '               close and if this should be premultiplied again & converted again, the
  47. '               alphas can get more transparent with every iteration.
  48. '               Fully opaque pixels & fully transparent pixels are not affected.
  49. '           ** Note: When images are converted to PNG formats, removal of
  50. '              premultiplication is performed to meet PNG specs.
  51. '       - Displaying a pre-multiplied bitmap without AlphaBlend will not result in
  52. '           the image being displayed as expected.
  53. '       - Not ideal for saving due to its size: SizeOf= W x H x 4
  54. '           -- better to save source image instead or compress the DIB bytes using favorite compression utility
  55. '           -- with GDI+ or zLib, image can be converted to PNG for storage
  56. '       - AlphaBlend (msimg32.dll) is not included/compatible with Win95, NT4 and lower
  57. '       - AlphaBlend on Win9x systems can be buggy, especially when rendering to DIBs vs DDBs
  58. ' Note that GDI+ is standard on WinXP+, and can be used on Win98,ME,2K, & on NT4 if SP6 is installed
  59. ' Download GDI+ from:
  60. ' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/GDIPlus.asp
  61.  
  62. ' ----------------------------------------------
  63. ' About Win95, Win98, NT3.5, NT4 & WinME support
  64. ' ----------------------------------------------
  65. ' The routines will not honor AlphaBlend if it exists on those systems. Win98's version,
  66. ' for example, has several bugs that can crash the application when AlphaBlending to DIBs.
  67. ' NT4, NT3.5 & Win95 do not come with AlphaBlend and I do not have WinME to test with.
  68. ' Therefore, to support these systems, the Render routine will alphablend manually
  69. ' regardless if the AlhpaBlend API (msimg32.dll) exists on the system or not.
  70. ' However, this can be overridden by you. See isAlphaBlendFriendly routine
  71.  
  72.  
  73. ' Class Purpose:
  74. ' ----------------------------------------------
  75. ' This class holds the 32bpp image. It also marshals any new image thru
  76. ' the battery of parsers to determine best method for converting the image
  77. ' to a 32bpp alpha-compatible image. It handles rendering, rotating, scaling,
  78. ' mirroring of DIBs using manual processes, AlphaBlend, and/or GDI+.
  79.  
  80. ' The parser order is very important for fastest/best results...
  81. ' AcPNGparser :: will convert PNG, all bit depths; aborts quickly if not PNG
  82. ' AcGIFparser :: will convert non-transparent/transparent GIFs; aborts quickly
  83. ' cICOpraser :: will convert XP-Alpha, paletted, true color, & Vista PNG icons
  84. '               -- can also convert most non-animated cursors
  85. ' AcBMPparser :: will convert bitmaps, wmf/emf & jpgs
  86.  
  87. ' The parsers are efficient. Most image formats have a magic number that give
  88. '   a hint to what type of image the file/stream is. However, checks need to
  89. '   be employed because non-image files could feasibly have those same magic
  90. '   numbers. If the image is determined not to be one the parser is designed
  91. '   to handle, the parser rejects it and the next parser takes over.  The
  92. '   icon parser is slightly different because PNG files can be included into
  93. '   a Vista ico file. When this occurs, the icon parser will pass off the
  94. '   PNG format to the PNG parser automatically.
  95. ' And last but not least, the parsers have no advanced knowledge of the image
  96. ' format; as far as they are concerned, anything passed is just a byte array
  97.  
  98. ' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  99. '                                       CHANGE HISTORY
  100. ' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  101. ' Accompanying FAQ.rtf is updated with every change
  102. ' Last changed: 11 Apr 07. See change history within the FAQ file
  103. ' 26 Dec 06: First version
  104. ' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  105.  
  106. ' No APIs are declared public. This is to prevent possibly, differently
  107. ' declared APIs, or different versions of the same API, from conflciting
  108. ' with any APIs you declared in your project. Same rule for UDTs.
  109. ' Note: I did take liberties, changing parameter types, in several APIs throughout
  110.  
  111. ' Used to determine operating system
  112. Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As Any) As Long
  113. Private Type OSVERSIONINFOEX
  114.    dwOSVersionInfoSize As Long
  115.    dwMajorVersion As Long
  116.    dwMinorVersion As Long
  117.    dwBuildNumber As Long
  118.    dwPlatformId As Long
  119.    szCSDVersion As String * 128 ' up to here is OSVERSIONINFO vs EX
  120.    wServicePackMajor As Integer ' 8 bytes larger than OSVERSIONINFO
  121.    wServicePackMinor As Integer
  122.    wSuiteMask As Integer
  123.    wProductType As Byte
  124.    wReserved As Byte
  125. End Type
  126.  
  127. ' APIs used to manage the 32bpp DIB
  128. Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
  129. Private Declare Sub FillMemory Lib "kernel32.dll" Alias "RtlFillMemory" (ByRef Destination As Any, ByVal Length As Long, ByVal Fill As Byte)
  130. Private Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hDC As Long) As Long
  131. Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Long) As Long
  132. Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As Long, ByVal hDC As Long) As Long
  133. Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hDC As Long) As Long
  134. Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hDC As Long, ByVal hObject As Long) As Long
  135. Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
  136. Private Declare Function CreateDIBSection Lib "gdi32.dll" (ByVal hDC As Long, ByRef pBitmapInfo As Any, ByVal un As Long, ByRef Pointer As Long, ByVal Handle As Long, ByVal dw As Long) As Long
  137. Private Declare Function AlphaBlend Lib "MSIMG32.dll" (ByVal hdcDest As Long, ByVal nXOriginDest As Long, ByVal nYOriginDest As Long, ByVal nWidthDest As Long, ByVal nHeightDest As Long, ByVal hdcSrc As Long, ByVal nXOriginSrc As Long, ByVal nYOriginSrc As Long, ByVal nWidthSrc As Long, ByVal nHeightSrc As Long, ByVal lBlendFunction As Long) As Long
  138. Private Declare Function SetStretchBltMode Lib "gdi32.dll" (ByVal hDC As Long, ByVal nStretchMode As Long) As Long
  139. Private Declare Function GetObjectType Lib "gdi32.dll" (ByVal hgdiobj As Long) As Long
  140. Private Declare Function GetCurrentObject Lib "gdi32.dll" (ByVal hDC As Long, ByVal uObjectType As Long) As Long
  141. Private Declare Function GetIconInfo Lib "user32.dll" (ByVal hIcon As Long, ByRef piconinfo As ICONINFO) As Long
  142. Private Declare Function BitBlt Lib "gdi32.dll" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
  143. Private Declare Function SetDIBitsToDevice Lib "gdi32.dll" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long, ByVal dX As Long, ByVal dY As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, ByRef Bits As Any, ByRef BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
  144. Private Declare Function GetDIBits Lib "gdi32.dll" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, ByRef lpBits As Any, ByRef lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
  145. Private Declare Function OffsetRgn Lib "gdi32.dll" (ByVal hRgn As Long, ByVal X As Long, ByVal Y As Long) As Long
  146. Private Const STRETCH_HALFTONE As Long = &H4&
  147. Private Const OBJ_BITMAP As Long = &H7&
  148. Private Const OBJ_METAFILE As Long = &H9&
  149. Private Const OBJ_ENHMETAFILE As Long = &HD&
  150.  
  151. ' APIs used to create files
  152. Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
  153. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
  154. Private Declare Function GetFileSize Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpFileSizeHigh As Long) As Long
  155. Private Declare Function ReadFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, ByRef lpOverlapped As Any) As Long
  156. Private Declare Function SetFilePointer Lib "kernel32.dll" (ByVal hFile As Long, ByVal lDistanceToMove As Long, ByRef lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
  157. Private Const INVALID_HANDLE_VALUE = -1&
  158.  
  159. ' ////////////////////////////////////////////////////////////////
  160. ' Unicode-capable Drag and Drop of file names with wide characters
  161. ' ////////////////////////////////////////////////////////////////
  162. Private Declare Function DispCallFunc Lib "oleaut32" (ByVal pvInstance As Long, _
  163.     ByVal offsetinVft As Long, ByVal CallConv As Long, ByVal retTYP As VbVarType, _
  164.     ByVal paCNT As Long, ByRef paTypes As Integer, _
  165.     ByRef paValues As Long, ByRef retVAR As Variant) As Long
  166. Private Declare Function lstrlenW Lib "kernel32.dll" (lpString As Any) As Long
  167. Private Declare Function GlobalFree Lib "kernel32.dll" (ByVal hMem As Long) As Long
  168.  
  169. ' ////////////////////////////////////////////////////////////////
  170. ' Unicode-capable Pasting of file names with wide characters
  171. ' ////////////////////////////////////////////////////////////////
  172. Private Declare Function DragQueryFile Lib "shell32.dll" Alias "DragQueryFileA" (ByVal hDrop As Long, ByVal UINT As Long, ByVal lpStr As String, ByVal ch As Long) As Long
  173. Private Declare Function OpenClipboard Lib "user32.dll" (ByVal hwnd As Long) As Long
  174. Private Declare Function GetClipboardData Lib "user32.dll" (ByVal wFormat As Long) As Long
  175. Private Declare Function CloseClipboard Lib "user32.dll" () As Long
  176. ' ////////////////////////////////////////////////////////////////
  177. Private Type FORMATETC
  178.     cfFormat As Long
  179.     pDVTARGETDEVICE As Long
  180.     dwAspect As Long
  181.     lIndex As Long
  182.     TYMED As Long
  183. End Type
  184. Private Type DROPFILES
  185.     pFiles As Long
  186.     ptX As Long
  187.     ptY As Long
  188.     fNC As Long
  189.     fWide As Long
  190. End Type
  191. Private Type STGMEDIUM
  192.     TYMED As Long
  193.     Data As Long
  194.     pUnkForRelease As IUnknown
  195. End Type
  196.  
  197.  
  198. ' used to create the checkerboard pattern on demand
  199. Private Declare Function FillRect Lib "user32.dll" (ByVal hDC As Long, ByRef lpRect As RECT, ByVal hBrush As Long) As Long
  200. Private Declare Function CreateSolidBrush Lib "gdi32.dll" (ByVal crColor As Long) As Long
  201. Private Declare Function OffsetRect Lib "user32.dll" (ByRef lpRect As RECT, ByVal X As Long, ByVal Y As Long) As Long
  202. Private Type RECT
  203.     Left As Long
  204.     Top As Long
  205.     Right As Long
  206.     Bottom As Long
  207. End Type
  208.  
  209. ' used when saving an image or part of the image
  210. Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Ptr() As Any) As Long
  211. Private Type SafeArrayBound
  212.     cElements As Long
  213.     lLbound As Long
  214. End Type
  215. Private Type SafeArray
  216.     cDims As Integer
  217.     fFeatures As Integer
  218.     cbElements As Long
  219.     cLocks As Long
  220.     pvData As Long
  221.     rgSABound(0 To 1) As SafeArrayBound ' reusable UDT for 1 & 2 dim arrays
  222. End Type
  223.  
  224. Private Type ICONINFO
  225.     fIcon As Long
  226.     xHotspot As Long
  227.     yHotspot As Long
  228.     hbmMask As Long
  229.     hbmColor As Long
  230. End Type
  231. Private Type BITMAPINFOHEADER
  232.     biSize As Long
  233.     biWidth As Long
  234.     biHeight As Long
  235.     biPlanes As Integer
  236.     biBitCount As Integer
  237.     biCompression As Long
  238.     biSizeImage As Long
  239.     biXPelsPerMeter As Long
  240.     biYPelsPerMeter As Long
  241.     biClrUsed As Long
  242.     biClrImportant As Long
  243. End Type
  244. Private Type BITMAPINFO
  245.     bmiHeader As BITMAPINFOHEADER
  246.     bmiPalette As Long
  247. End Type
  248.  
  249. Private Const AC_SRC_OVER = &H0&
  250. Private Const AC_SRC_ALPHA = &H1&
  251.  
  252. Public Enum AeImageFormat    ' source image format
  253.     AimgError = -1  ' no DIB has been initialized
  254.     AimgNone = 0    ' no image loaded
  255.     AimgBitmap = 1  ' standard bitmap or jpg
  256.     AimgIcon = 3    ' standard icon
  257.     AimgWMF = 2     ' windows meta file
  258.     AimgEMF = 4     ' enhanced WMF
  259.     AimgCursor = 5  ' standard cursor
  260.     AimgBmpARGB = 6  ' 32bpp bitmap where RGB is not pre-multiplied
  261.     AimgBmpPARGB = 7 ' 32bpp bitmap where RGB is pre-multiplied
  262.     AimgIconARGB = 8 ' XP-type icon; 32bpp ARGB
  263.     AimgGIF = 9      ' gif; if class.Alpha=True, then transparent GIF
  264.     AimgPNG = 10     ' PNG image
  265.     AimgPNGicon = 11 ' PNG in icon file (Vista)
  266.     AimgCursorARGB = 12 ' alpha blended cursors? do they exist yet?
  267.     AimgCheckerBoard = 64 ' image is displaying own checkerboard pattern; no true image
  268. End Enum
  269.  
  270. Public Enum AePngProperties ' following are recognized "Captions" within a PNG file
  271.     AtxtTitle = 1           ' See AcPNGwriter.SetPngProperty for more information
  272.     AtxtAuthor = 2
  273.     AtxtDescription = 4
  274.     AtxtCopyright = 8
  275.     AtxtCreationTime = 16
  276.     AtxtSoftware = 32
  277.     AtxtDisclaimer = 64
  278.     AtxtWarning = 128
  279.     AtxtSource = 256
  280.     AtxtComment = 512
  281.     ' special properties
  282.     AtxtLargeBlockText = 1024 ' this is free-form text can be of any length & contain most any characters
  283.     AdateTimeModified = 2048  ' date/time of the last image modification (not the time of initial image creation)
  284.     AcolorDefaultBkg = 4096   ' default background color to use if PNG viewer does not do transparency
  285.     AfilterType = 8192        ' one of the AeFilterMethods values
  286.     ClearAllProperties = -1  ' resets all PNG properties
  287. End Enum
  288.  
  289. Public Enum AeTrimOptions    ' see TrimImage method
  290.     trimAll = 0             ' can be combined using OR
  291.     trimLeft = 1
  292.     trimTop = 2
  293.     trimRight = 4
  294.     trimBottom = 8
  295. End Enum
  296.  
  297. Public Enum eScaleOptions   ' See ScaleImage method
  298.     scaleToSize = 0         ' [Default] will always scale
  299.     scaleDownAsNeeded = 1   ' will only scale down if image won't fit
  300.     ScaleStretch = 2        ' wll always stretch/distort
  301. End Enum
  302.  
  303. Public Enum AeGrayScaleFormulas
  304.     AgsclNTSCPAL = 0     ' R=R*.299, G=G*.587, B=B*.114 - Default
  305.     AgsclCCIR709 = 1     ' R=R*.213, G=G*.715, B=B*.072
  306.     AgsclSimpleAvg = 2   ' R,G, and B = (R+G+B)/3
  307.     AgsclRedMask = 3     ' uses only the Red sample value: RGB = Red / 3
  308.     AgsclGreenMask = 4   ' uses only the Green sample value: RGB = Green / 3
  309.     AgsclBlueMask = 5    ' uses only the Blue sample value: RGB = Blue / 3
  310.     AgsclRedGreenMask = 6 ' uses Red & Green sample value: RGB = (Red+Green) / 2
  311.     AgsclBlueGreenMask = 7 ' uses Blue & Green sample value: RGB = (Blue+Green) / 2
  312.     AgsclNone = -1
  313. End Enum
  314.  
  315. Public Enum AeFilterMethods
  316.     AfilterDefault = 0     ' paletted PNGs will use AfilterNone while others will use AfilterPaeth
  317.     AfilterNone = 1        ' no byte preparation used; else preps bytes using one of the following
  318.     AfilterAdjLeft = 2     ' see AcPNGwriter.EncodeFilter_Sub
  319.     AfilterAdjTop = 3      ' see AcPNGwriter.EncodeFilter_Up
  320.     AfilterAdjAvg = 4      ' see AcPNGwriter.EncodeFilter_Avg
  321.     AfilterPaeth = 5       ' see AcPNGwriter.EncodeFilter_Paeth
  322.     AfilterAdaptive = 6    ' this is a best guess of the above 4 (can be different for each DIB scanline)
  323. End Enum
  324.  
  325. Public Enum AeRegionStyles     ' See CreateRegion
  326.     AregionBounds = 0
  327.     AregionEnclosed = 1
  328.     AregionShaped = 2
  329. End Enum
  330.  
  331. Public Enum AeConstants      ' See SourceIconSizes
  332.     ATRUE_COLOR = &HFF000000
  333.     AHIGH_COLOR = &HFFFF00
  334.     ATRUE_COLOR_ALPHA = &HFFFFFFFF
  335. End Enum
  336.  
  337. 'Private m_PNGprops As AcPNGwriter    ' used for more advanced PNG creation options
  338. Private m_StretchQuality As Boolean ' if true will use BiLinear or better interpolation
  339. Private m_Handle As Long        ' handle to 32bpp DIB
  340. Private m_Pointer As Long       ' pointer to DIB bits
  341. Private m_Height As Long        ' height of DIB
  342. Private m_Width As Long         ' width of DIB
  343. Private m_hDC As Long           ' DC if self-managing one
  344. Private m_prevObj As Long       ' object deselected from DC when needed
  345. Private m_osCAP As Long         ' See Class_Initialize
  346. Private m_Format As AeImageFormat ' type of source image
  347. Private m_ManageDC As Boolean   ' does class manage its own DC
  348. Private m_AlphaImage As Boolean ' does the DIB contain alpha/transparency
  349. Private m_GDItoken As Long
  350. Private m_ImageByteCache() As Byte  ' should you want the DIB class to cache original bytes
  351. ' ^^ N/A if image is loaded by handle, stdPicture, or resource
  352.  
  353. Public Function LoadPicture_File(ByVal FileName As String, Optional ByVal iconCx As Long, Optional ByVal iconCy As Long, Optional ByVal SaveFormat As Boolean, Optional ByVal iconBitDepth As Long = 32) As Boolean
  354.  
  355.     ' PURPOSE: Convert passed image file into a 32bpp image
  356.     
  357.     ' Parameters.
  358.     ' FileName :: full path of file. Validation occurs before we continue
  359.     ' iconCx :: desired width of icon if file is an icon file. Default is 32x32
  360.     ' iconCy :: desired height of icon if file is an icon file. Default is 32x32
  361.     ' SaveFormat :: if true, then the image will be cached as a byte array only
  362.     '   if the image was successfully loaded. Call GetOrginalFormat to retrieve them.
  363.     ' iconBitDepth :: the desired bit depth of an icon if the resource is an icon file
  364.     
  365.     ' Why would you want to save the bytes? If this is being used in a usercontrol,
  366.     ' saving the bytes will almost always be less size than saving the 32bit DIB.
  367.     ' Additionally, these classes have the ability to get different sizes from
  368.     ' the original source (i.e., WMF, icon, cursors) if available, but if the
  369.     ' 32bit DIB is saved, it is a constant size. The potential of different sizes
  370.     ' could allow better resizing of the image vs stretching the DIB.
  371.  
  372.     On Error Resume Next
  373.     Dim hFile As Long
  374.     
  375.     hFile = AiparseGetFileHandle(FileName, True, ((m_osCAP And 24) = 8))
  376.     If hFile = INVALID_HANDLE_VALUE Then Exit Function
  377.     
  378.     If GetFileSize(hFile, 0&) > 56 Then
  379.         
  380.         ' no image file/stream can be less than 57 bytes and still be an image
  381.         Dim aDIB() As Byte  ' dummy array
  382.         LoadPicture_File = LoadPictureEx(hFile, FileName, aDIB(), iconCx, iconCy, 0&, 0&, SaveFormat, iconBitDepth)
  383.     
  384.     End If
  385.     CloseHandle hFile
  386.     
  387. End Function
  388.  
  389. Friend Property Let Alpha(isAlpha As Boolean)
  390.     m_AlphaImage = isAlpha  ' determines the flags used for AlphaBlend API
  391.     ' this flag is set by the various image parsers; setting it yourself
  392.     ' can produce less than desirable effects.
  393.     ' Used in Me.Render & Me.TrimImage, AcPNGwriter.OptimizeTrueColor & AcPNGwriter.PalettizeImage
  394. End Property
  395. Public Property Get Alpha() As Boolean
  396.     Alpha = m_AlphaImage
  397. End Property
  398.  
  399. Public Property Let HighQualityInterpolation(Value As Boolean)
  400.     ' When possible GDI+ will be used for stretching & rotation.
  401.     ' If GDI+ is used,then high quality equates to BiCubic interpolation
  402.     ' If not used, then BiLinear (manual processing) will be used.
  403.     ' If High Quality is false, then Nearest Neighbor (very fast) interpolation used
  404.     m_StretchQuality = Value
  405. End Property
  406. Public Property Get HighQualityInterpolation() As Boolean
  407.     HighQualityInterpolation = m_StretchQuality
  408. End Property
  409.  
  410. Public Property Get ImageType() As AeImageFormat
  411.     ImageType = m_Format    ' returns image format of the source image
  412. End Property
  413. Friend Property Let ImageType(iType As AeImageFormat)
  414.     m_Format = iType    ' set by the various image parsers. This is not used
  415.     ' anywhere in these classes, you can do with it what you want -- for now.
  416. End Property
  417.  
  418. Public Property Get Width() As Long
  419.     Width = m_Width     ' width of image in pixels
  420. End Property
  421. Public Property Get Height() As Long
  422.     Height = m_Height   ' height of image in pixels
  423. End Property
  424. Public Property Get BitsPointer() As Long
  425.     BitsPointer = m_Pointer ' pointer to the bits of the image
  426. End Property
  427. Public Property Get scanWidth() As Long
  428.     scanWidth = m_Width * 4&    ' number of bytes per scan line
  429. End Property
  430. Public Property Get Handle() As Long
  431.     Handle = m_Handle   ' the picture handle of the image
  432. End Property
  433.  
  434. Public Function LoadDIBinDC(ByVal bLoad As Boolean) As Long
  435.  
  436.     ' Purpose: Select/Unselect the DIB into a DC.
  437.     ' Returns the DC handle when image is loaded
  438.     ' Called by image parser if it needs to paint the image into the DIB
  439.        
  440.     If bLoad = True Then
  441.         Dim tDC As Long
  442.         If Not m_Handle = 0& Then    ' do we have an image?
  443.             If m_hDC = 0& Then        ' do we have a DC?
  444.                 tDC = GetDC(0&)     ' if not create one
  445.                 m_hDC = CreateCompatibleDC(tDC)
  446.                 ReleaseDC 0&, tDC
  447.             End If
  448.             If m_prevObj = 0& Then
  449.                 m_prevObj = SelectObject(m_hDC, m_Handle)
  450.             End If
  451.             LoadDIBinDC = m_hDC
  452.         End If
  453.     Else
  454.         If Not m_prevObj = 0& Then
  455.             SelectObject m_hDC, m_prevObj
  456.             If m_ManageDC = False Then
  457.                 DeleteObject m_hDC
  458.                 m_hDC = 0&
  459.             End If
  460.             m_prevObj = 0&
  461.         End If
  462.     End If
  463. End Function
  464.  
  465. Public Property Let ManageOwnDC(bManage As Boolean)
  466.     ' Determines whether or not this class will manage its own DC
  467.     ' If false, then a DC is created each time the image needs to be Rendered
  468.     Dim tDC As Long
  469.     If bManage = False Then     ' removing management of DC
  470.         If Not m_hDC = 0& Then   ' DC does exist, destroy it
  471.             ' first remove the dib, if one exists
  472.             If Not m_Handle = 0& Then SelectObject m_hDC, m_prevObj
  473.             m_prevObj = 0&
  474.         End If
  475.         DeleteDC m_hDC
  476.         m_hDC = 0&
  477.     Else                        ' allowing creation of dc
  478.         If m_hDC = 0& Then        ' create DC only if we have a dib to put in it
  479.             If Not m_Handle = 0& Then
  480.                 tDC = GetDC(0&)
  481.                 m_hDC = CreateCompatibleDC(tDC)
  482.                 ReleaseDC 0&, tDC
  483.             End If
  484.         End If
  485.     End If
  486.     m_ManageDC = bManage
  487. End Property
  488. Public Property Get ManageOwnDC() As Boolean
  489.     ManageOwnDC = m_ManageDC
  490. End Property
  491.  
  492. Public Property Get isAlphaBlendFriendly() As Boolean
  493.     isAlphaBlendFriendly = ((m_osCAP And 1) = 1)
  494.     ' WinNT4 & below and Win95 are not shipped with msimg32.dll (AlphaBlend API)
  495.     ' Win98 has bugs & would believe that WinME is buggy too but don't know for sure
  496.     ' Therefore, the Rendering in this class will not use AlphaBlend on these
  497.     ' operating systems even if the DLL exists, but will use GDI+ if available
  498.     ' Can be overridden by setting this property to True
  499. End Property
  500. Public Property Let isAlphaBlendFriendly(Enabled As Boolean)
  501.     ' This has been provided to override safety of using AlphaBlend on Win9x systems.
  502.     ' Caution. Only set this when rendering to a known device dependent bitmap (DDB)
  503.     ' Alphablend can crash when rendering DIB to DIB vs DIB to DDB. Be warned.
  504.     If Enabled = True Then
  505.         ' Overriding in play: allow AlphaBlend if system is Win98 or better
  506.         ' By default this is already set for Win2K or better
  507.         If ((m_osCAP And 8) = 8) Then m_osCAP = m_osCAP Or 1
  508.     Else
  509.         m_osCAP = m_osCAP And Not 1 ' disallow AlphaBlend
  510.     End If
  511. End Property
  512. Public Property Get isGDIplusEnabled() As Boolean
  513.     ' identifies if GDI+ is usable on the system.
  514.     ' Before this property is set, GDI+ is tested to ensure it is usable
  515.     isGDIplusEnabled = ((m_osCAP And 2) = 2)
  516. End Property
  517. Public Property Let isGDIplusEnabled(Enabled As Boolean)
  518.     ' Sets the property. If set to False by you, GDI+ will not be used
  519.     ' for any rendering, but still may be used to create PNG files if needed
  520.     
  521.     If Not Enabled = Me.isGDIplusEnabled Then
  522.         m_osCAP = (m_osCAP And Not 2)
  523.         If Enabled Then
  524.             If (m_osCAP And 32) = 0 Then ' else Win95, NT4 SP5 or lower
  525.                 Dim cGDIp As New AcGDIPlus
  526.                 If cGDIp.isGDIplusOk() = True Then m_osCAP = m_osCAP Or 2
  527.             End If
  528.         End If
  529.     End If
  530. End Property
  531.  
  532.  
  533.  
  534. Public Function InitializeDIB(ByVal Width As Long, ByVal Height As Long) As Boolean
  535.  
  536.     ' Creates a blank (all black, all transparent) DIB of requested height & width
  537.     
  538.     Dim tBMPI As BITMAPINFO, tDC As Long
  539.     
  540.     DestroyDIB ' clear any pre-existing dib
  541.     
  542.     If Width < 0& Then Exit Function
  543.     If Height = 0& Then
  544.         Exit Function
  545.     ElseIf Height < 0& Then
  546.         Height = Abs(Height) ' no top-down dibs
  547.     End If
  548.     
  549.     On Error Resume Next
  550.     With tBMPI.bmiHeader
  551.         .biBitCount = 32
  552.         .biHeight = Height
  553.         .biWidth = Width
  554.         .biPlanes = 1
  555.         .biSize = 40&
  556.         .biSizeImage = .biHeight * .biWidth * 4&
  557.     End With
  558.     If Err Then
  559.         Err.Clear
  560.         ' only possible error would be that Width*Height*4& is absolutely huge
  561.         Exit Function
  562.     End If
  563.     
  564.     tDC = GetDC(0&) ' get screen DC
  565.     m_Handle = CreateDIBSection(tDC, tBMPI, 0&, m_Pointer, 0&, 0&)
  566.     If m_ManageDC = True Then
  567.         ' create a DC if class is managing its own & one isn't created yet
  568.         If m_hDC = 0& Then m_hDC = CreateCompatibleDC(tDC)
  569.     End If
  570.     ' release the screen DC if we captured it
  571.     ReleaseDC 0&, tDC
  572.     
  573.     If Not m_Handle = 0& Then    ' let's hope system resources allowed DIB creation
  574.         m_Width = Width
  575.         m_Height = Height
  576.         m_AlphaImage = True
  577.         m_Format = AimgNone
  578.         InitializeDIB = True
  579.     End If
  580.  
  581. End Function
  582.  
  583. Public Sub DestroyDIB()
  584.     
  585.     ' PURPOSE: Destroy any existing image
  586.     If Not m_hDC = 0& Then   ' do we have a DC?
  587.         ' do we have an image; if so get it out of the DC
  588.         If Not m_prevObj = 0& Then SelectObject m_hDC, m_prevObj
  589.         ' destroy our DC, no point in keeping it w/o image
  590.         DeleteObject m_hDC
  591.         m_hDC = 0&
  592.     End If
  593.     ' if we do have an image, destroy it now
  594.     If Not m_Handle = 0& Then
  595.         DeleteObject m_Handle
  596.         Erase m_ImageByteCache
  597.     End If
  598.     ' reset other image attributes
  599.     m_Width = 0&
  600.     m_Height = 0&
  601.     m_Handle = 0&
  602.     m_Pointer = 0&
  603.     m_prevObj = 0&
  604.     m_AlphaImage = False
  605.     m_Format = AimgError
  606. End Sub
  607.  
  608. Public Sub EraseDIB()
  609.     ' Function clears out an existing DIB, making it 100% transparent/black
  610.     If Not m_Handle = 0& Then
  611.         FillMemory ByVal m_Pointer, m_Width * m_Height * 4&, 0
  612.         m_Format = AimgNone
  613.         m_AlphaImage = True
  614.     End If
  615.     
  616. End Sub
  617.  
  618. Public Function Render(ByVal destinationDC As Long, Optional ByVal destX As Long, Optional ByVal destY As Long, Optional ByVal destWidth As Long, Optional ByVal destHeight As Long, Optional ByVal SrcX As Long, Optional ByVal SrcY As Long, Optional ByVal srcWidth As Long, Optional ByVal srcHeight As Long, Optional ByVal Opacity As Long = 100&, Optional ByVal Blend As Boolean = True, Optional ByVal SetHalfTone As Boolean = True, Optional ByRef destHostDIB As Ac32bppDIB, Optional ByVal grayScale As AeGrayScaleFormulas = AgsclNone) As Boolean
  619.  
  620.     ' PURPOSE: Render an existing 32bpp DIB to a target DC
  621.     
  622.     ' Parameters.
  623.     ' destinationDC :: target DC to draw to
  624.     ' destX, destY :: the top/left coordinates to draw to, default is 0,0
  625.     ' destWidth, destHeight :: the width and height to draw to, default is the image's width & height
  626.     ' srcX, srcY :: the left & top offset within the DIB
  627.     ' srcWidth, srcHeight :: the amount of DIB to be rendered
  628.     ' Opacity :: how opaque to draw the image, default is 100% opaque
  629.     ' Blend :: no longer used, reserved
  630.     ' SetHalfTone :: if True, then the destination DC's stretch mode will be modified to
  631.     '       produce better quality results. This option is not available on Win9x systems.
  632.     '       Tip: When AlphaBlending to another DIB set to False
  633.     '            When AlphaBlending to CompatibleBitmap (DDB) or visible DC set to True
  634.     ' destHostDIB :: When rendering from DIB class to DIB class, pass the destination
  635.     '       DIB class to ensure alpha blending occurs correctly on systems that do not
  636.     '       support GDI+ or AlphaBlend APIs
  637.     ' grayscale :: one of several formulas to grayscale while rendering (optional)
  638.  
  639.     Dim lBlendFunc As Long, tDC As Long, hOldImage As Long
  640.     Dim lStretchMode As Long
  641.     Dim aResizedBytes() As Byte, aMirrorBytes() As Byte
  642.     Dim bStretching As Boolean
  643.     Dim bMirroring As Boolean
  644.     Dim bCanUseAlphaBlend As Boolean
  645.     
  646.     ' validate a few things
  647.     If m_Handle = 0& Then
  648.         Exit Function
  649.     ElseIf destinationDC = 0& Then
  650.         Exit Function
  651.     ElseIf srcWidth < 0& Then   ' AlphaBlend is not compatible with negative width/height
  652.         Exit Function          ' negative values used in APIs like StretchBlt for mirroring
  653.     ElseIf srcHeight < 0& Then
  654.         Exit Function
  655.     End If
  656.     
  657.     If Opacity = 0& Then
  658.         Render = True
  659.         Exit Function   ' pointless if image is 100% transparent
  660.     Else
  661.         Opacity = Abs(Opacity) Mod 100
  662.         If Opacity = 0& Then Opacity = 100&
  663.     End If
  664.     
  665.     ' validate optional parameters for source image
  666.         If srcWidth = 0& Then srcWidth = m_Width
  667.         If srcHeight = 0& Then srcHeight = m_Height
  668.         If SrcX < 0& Then SrcX = 0&  ' source X,Y cannot be negative
  669.         If SrcY < 0& Then SrcY = 0&  ' but the dest X,Y can be
  670.     ' AlphaBlend requires that the source rectangle fit within the image
  671.         If SrcX + srcWidth > m_Width Then srcWidth = m_Width - SrcX
  672.         If SrcY + srcHeight > m_Height Then srcHeight = m_Height - SrcY
  673.     ' validate optional parameters for destination image
  674.         If destWidth = 0& Then
  675.             destWidth = m_Width
  676.         Else
  677.             If destWidth < 0& Then bMirroring = True   ' rules out AlphaBlend usage
  678.         End If
  679.         bStretching = Not (Abs(destWidth) = srcWidth) ' rules out AlphaBlend usage if Bilinear interpolation requested
  680.         If destHeight = 0& Then
  681.             destHeight = m_Height
  682.         Else
  683.             If destHeight < 0& Then bMirroring = True ' rules out AlphaBlend usage
  684.         End If
  685.         If Not bStretching Then bStretching = Not (Abs(destHeight) = srcHeight) ' rules out AlphaBlend usage if Bilinear interpolation requested
  686.         
  687.     If Me.isAlphaBlendFriendly Then ' Win98 or better with AlphaBlend enabled
  688.         If Not bMirroring Then  ' Not mirroring, can use AlphaBlend
  689.             If grayScale = AgsclNone Then
  690.                 If bStretching Then
  691.                     bCanUseAlphaBlend = Not m_StretchQuality ' no Bilinear interpolation, can use AlphaBlend
  692.                 Else
  693.                     bCanUseAlphaBlend = True
  694.                 End If
  695.             End If
  696.         End If
  697.     End If
  698.     
  699.     If Me.isGDIplusEnabled = True And bCanUseAlphaBlend = False Then
  700.         ' we will use GDI+ to render when higher quality interpolation is desired or system is not AlphaBlend friendly
  701.         Dim cGDIp As New AcGDIPlus
  702.         Dim Rg As Single, Gg As Single, Bg As Single
  703.         Render = cGDIp.RenderGDIplus(Me, destinationDC, 0&, Opacity, destX, destY, destWidth, destHeight, SrcX, SrcY, srcWidth, srcHeight, m_StretchQuality, grayScale, m_GDItoken)
  704.  
  705.     Else
  706.         
  707.         
  708.         If m_hDC = 0& Then  ' do we have a DC to select our image into?
  709.             tDC = GetDC(0&) ' if not create one, if ManageOwnDC=True, we will have one
  710.             m_hDC = CreateCompatibleDC(tDC)
  711.             ReleaseDC 0&, tDC
  712.             hOldImage = SelectObject(m_hDC, m_Handle)
  713.         Else
  714.             ' we have a DC, but is the image selected into it?
  715.             If m_prevObj = 0& Then hOldImage = SelectObject(m_hDC, m_Handle)
  716.         End If
  717.         
  718.         If bCanUseAlphaBlend = False Then
  719.             ' Ruled out use of AlphaBlend (preferred when GDI+ isn't available)
  720.             ' Win95/NT4 - can't use AlphaBlend
  721.             ' Mirroring or high quality interpolation stretching - can't use AlphaBlend
  722.             
  723.             ' doing it completely manually
  724.             If bMirroring Then MirrorDIB SrcX, SrcY, srcWidth, srcHeight, destWidth, destHeight, aMirrorBytes()
  725.             If bStretching Then
  726.                 If pvResize(destinationDC, aResizedBytes(), aMirrorBytes(), Nothing, SrcX, SrcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight) = False Then Exit Function
  727.             End If
  728.             ' use custom blending routine
  729.             Render = Win9xBlend(destinationDC, aResizedBytes(), SrcX, SrcY, destX, destY, destWidth, destHeight, (255& * Opacity) \ 100&, destHostDIB, grayScale)
  730.         
  731.         Else ' we can use AlphaBlend
  732.         
  733.             ' Stretch_Halftone not compatible with win9x
  734.             If SetHalfTone Then
  735.                 If Me.isAlphaBlendFriendly Then lStretchMode = SetStretchBltMode(destinationDC, STRETCH_HALFTONE)
  736.             End If
  737.             
  738.             ' calculate the opacity required & add it to the BlendFunction variable
  739.             lBlendFunc = AC_SRC_OVER Or (((255& * Opacity) \ 100&) * &H10000)
  740.             ' if the image has transparency, then we add the AC_SRC_ALPHA flag too
  741.             If m_AlphaImage = True And Blend = True Then lBlendFunc = lBlendFunc Or (AC_SRC_ALPHA * &H1000000)
  742.             Render = Not (AlphaBlend(destinationDC, destX, destY, destWidth, destHeight, m_hDC, SrcX, SrcY, srcWidth, srcHeight, lBlendFunc) = 0&)
  743.             
  744.             If SetHalfTone Then
  745.                 If Me.isAlphaBlendFriendly Then SetStretchBltMode destinationDC, lStretchMode
  746.             End If
  747.             
  748.         End If
  749.         
  750.         ' remove the image from the DC if necessary
  751.         If Not hOldImage = 0& Then SelectObject m_hDC, hOldImage
  752.         If Not tDC = 0& Then    ' if we created a DC, let's destroy it now
  753.             DeleteDC m_hDC
  754.             m_hDC = 0&
  755.         End If
  756.         
  757.     End If
  758.     
  759. End Function
  760.  
  761. Private Function LoadPictureEx(FileHandle As Long, FileName As String, aStream() As Byte, cx As Long, cy As Long, streamOffset As Long, streamLength As Long, SaveFormat As Boolean, bitDepth As Long) As Boolean
  762.     
  763.     ' PURPOSE: Marshal passed file/array to image classes for conversion to 32bpp image
  764.     ' For parameter information, see LoadPicture_File & LoadPicture_Stream
  765.     
  766.     Me.DestroyDIB
  767.     
  768.     ' various image parsers, in order of precedence
  769.     ' All 4 recognize transparency
  770.     Dim cPNG As AcPNGparser  ' very fast to abort if not a PNG file
  771.     
  772.     Dim bReturn As Boolean  ' function return value
  773.     Dim rtnRead As Long
  774.     
  775.     ' validate passed desired icon sizes
  776.     If cx < 0& Then cx = 0&
  777.     If cy < 0& Then cy = 0&
  778.     If bitDepth < 0& Then
  779.         bitDepth = 32
  780.     ElseIf bitDepth > 32 Then
  781.         bitDepth = 32
  782.     End If
  783.     
  784.     Set cPNG = New AcPNGparser   ' see if image is a PNG; aborts quickly if not
  785.     bReturn = cPNG.LoadFile(FileHandle, FileName, Me, m_GDItoken)
  786.         'If bReturn = True Then Close #fileNum         ' close the file
  787.     If Err Then MsgBox Err.Description
  788.     Set cPNG = Nothing
  789.     If Not bReturn Then
  790.         If Not FileHandle = 0& Then
  791.             streamOffset = 0&
  792.             streamLength = GetFileSize(FileHandle, 0&)
  793.             'streamLength = LOF(fileNum) ' cache length of file
  794.             ReDim aStream(streamOffset To streamLength - 1&)
  795.             'Get #fileNum, , aStream()   ' populate our stream with the file contents
  796.             'Close #fileNum
  797.             SetFilePointer FileHandle, 0&, 0&, 0&
  798.             ReadFile FileHandle, aStream(streamOffset), streamLength, rtnRead, ByVal 0&
  799.         End If
  800.         'Set cGIF = New AcGIFparser ' what about a GIF; aborts quickly if not
  801.         'bReturn = cGIF.LoadStream(aStream(), Me, streamOffset, streamLength)
  802.         'Set cGIF = Nothing
  803.         If Not bReturn Then
  804.             'Set cICO = New AcICOparser   ' will process Vista PNG icon if needed
  805.             'bReturn = cICO.LoadStream(aStream(), cx, cy, Me, streamOffset, streamLength, bitDepth, m_GDItoken)
  806.             'Set cICO = Nothing
  807.             If Not bReturn Then ' check for bmp, emf, wmf & jpg << last chance
  808.                 'Set cBMP = New AcBMPparser
  809.                 'bReturn = cBMP.LoadStream(aStream(), Me, streamOffset, streamLength)
  810.                 'Set cBMP = Nothing
  811.             End If
  812.         End If
  813.     End If
  814.     If Not m_Handle = 0 Then
  815.         If SaveFormat = True Then ' we will cache the original bytes
  816.             If AiparseIsArrayEmpty(VarPtrArray(aStream)) = 0& And Not FileHandle = 0& Then
  817.                 ' we loaded the image from the file and not a stream (PNG), need to get stream
  818.                 'fileNum = FreeFile()
  819.                 'Open FileName For Binary Access Read As #fileNum
  820.                 If streamLength = 0& Then streamLength = GetFileSize(FileHandle, 0&)
  821.                 ReDim m_ImageByteCache(0 To streamLength - 1)
  822.                 SetFilePointer FileHandle, 0&, 0&, 0&
  823.                 ReadFile FileHandle, m_ImageByteCache(0), streamLength, rtnRead, ByVal 0&
  824.                 'Get #fileNum, 1, m_ImageByteCache
  825.                 'Close #fileNum
  826.             Else
  827.                 m_ImageByteCache() = aStream()
  828.             End If
  829.         End If
  830.         LoadPictureEx = True
  831.     End If
  832.  
  833. End Function
  834.  
  835. Private Function pvResize(ByVal destDC As Long, rSizedBytes() As Byte, rMirror() As Byte, Optional tHost As Ac32bppDIB, Optional ByVal SrcX As Long, Optional ByVal scrY As Long, Optional ByVal srcWidth As Long, Optional ByVal srcHeight As Long, Optional ByVal destX As Long, Optional ByVal destY As Long, Optional destWidth As Long, Optional destHeight As Long) As Boolean
  836.                             
  837.     ' Function resizes an alpha image, maintaining premultiplied pixels & alpha values
  838.     ' Code originally by Carles P.V. but significantly modified for this project.
  839.     
  840.     ' Parameters:
  841.     ' destDC :: DC being rendered to, may be null
  842.     ' rSizedbytes() : array to hold resized alpha section; not used if tHost is not Nothing
  843.     ' tHost : when resizing to another DIB class, the destination DIB class
  844.     ' srcX,Y : the coordinates of the source image to start resizing from
  845.     ' srcWidth,srcHeight : the width/height of the source image to resize from
  846.     ' destX,Y : the coordinates of the destination image to resize to
  847.     ' destWidth,destHeight : the width/height of the destination image to resize to
  848.  
  849.     If srcWidth = 0& Then srcWidth = m_Width
  850.     If srcHeight = 0& Then srcHeight = m_Height
  851.  
  852.     Dim aNewBits() As Byte, dSA As SafeArray   ' new size, overlay of DIB pointer
  853.     Dim aOldBits() As Byte, tSA As SafeArray   ' old size, overlay of DIB pointer
  854.     
  855.     Dim xLUdbl() As Double                     ' look o resize to
  856.     ' destWidtto
  857.     'l   Dim xLUdbl()magbm xLUdbl()mcecttttb Varl destX As Lon)pLib "a DC is created each time X As Lon)pLibHe resiiiiiiii ' newcreatestX, g' new st, streamLengVarl'llPile isu, GDI+ w  
  858.     Des