VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "clsFOTAAVIToBMP"
Attribute VB_GlobalNameSpace = True
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Option Explicit

Public Sub WriteOutBMP(sAVIFileName As String, sBMPFileNames As String)

    Dim nHR As Long         'result code
    Dim pAVIFile As Long    'pointer to AVI file interface (PAVIFILE handle)
    Dim pAVIStream As Long  'pointer to AVI stream interface (PAVISTREAM handle)
    Dim numFrames As Long   'number of frames in video stream
    Dim nFirstFrame As Long  'position of the first video frame
    Dim oStreamInfo As AVI_STREAM_INFO   'stream info struct
    Dim dib As cDib
    Dim pGetFrameObj As Long    'pointer to GetFrame interface
    Dim pDIB As Long            'pointer to packed DIB in memory
    Dim oFileInfo As AVI_FILE_INFO       'file info struct
    Dim oBitMapHeader As BITMAPINFOHEADER 'infoheader to pass to GetFrame functions
    Dim sError As String
    Dim i As Long
    sError = ""
     
    'Open the AVI File and get a file interface pointer (PAVIFILE)
    nHR = AVIFileOpen(pAVIFile, sAVIFileName, OF_SHARE_DENY_WRITE, 0&)
    If nHR <> AVIERR_OK Then
        sError = "Error opening AVI file <" & sAVIFileName & ">"
        GoTo ErrorOut
    End If
 
    'Get the first available video stream (PAVISTREAM)
    nHR = AVIFileGetStream(pAVIFile, pAVIStream, streamtypeVIDEO, 0)
    If nHR <> AVIERR_OK Then
        sError = "Error opening AVI stream"
        GoTo ErrorOut
    End If
    
    'get the starting position of the stream (some streams may not start simultaneously)
    nFirstFrame = AVIStreamStart(pAVIStream)
    If nFirstFrame = -1 Then
        sError = "Error finding the start of the AVI stream"
        GoTo ErrorOut 'this function returns -1 on error
    End If
    
    'get the length of video stream in frames
    numFrames = AVIStreamLength(pAVIStream)
    If numFrames = -1 Then
        sError = "Error getting the length of the AVI stream"
        GoTo ErrorOut ' this function returns -1 on error
    End If
    
    'get file info struct (UDT)
    nHR = AVIFileInfo(pAVIFile, oFileInfo, Len(oFileInfo))
    If nHR <> AVIERR_OK Then
        sError = "Error getting the AVI file statistics"
        GoTo ErrorOut
    End If
    
    'get stream info struct (UDT)
    nHR = AVIStreamInfo(pAVIStream, oStreamInfo, Len(oStreamInfo))
    If nHR <> AVIERR_OK Then
        sError = "Error getting AVI stream statistics"
        GoTo ErrorOut
    End If
    
    'set oBitMapHeader attributes which we want GetFrame functions to return
    oBitMapHeader.biBitCount = 24
    oBitMapHeader.biClrImportant = 0
    oBitMapHeader.biClrUsed = 0
    oBitMapHeader.biCompression = BI_RGB
    oBitMapHeader.biHeight = oStreamInfo.rcFrame.bottom - oStreamInfo.rcFrame.top
    oBitMapHeader.biPlanes = 1
    oBitMapHeader.biSize = 40
    oBitMapHeader.biWidth = oStreamInfo.rcFrame.right - oStreamInfo.rcFrame.left
    oBitMapHeader.biXPelsPerMeter = 0
    oBitMapHeader.biYPelsPerMeter = 0
    oBitMapHeader.biSizeImage = (((oBitMapHeader.biWidth * 3) + 3) And &HFFFC) * oBitMapHeader.biHeight 'calculate total size of RGBQUAD scanlines (DWORD aligned)
    
    'init AVISTreamGetFrame* functions and create GETFRAME object
    pGetFrameObj = AVIStreamGetFrameOpen(pAVIStream, oBitMapHeader) 'force function to return 24bit DIBS
    If pGetFrameObj = 0 Then
        'That didn't work?  Try this.
        'pGetFrameObj = AVIStreamGetFrameOpen(pAVIStream, ByVal AVIGETFRAMEF_BESTDISPLAYFMT) 'tell AVIStream API what format we expect and input stream
        If pGetFrameObj = 0 Then
            sError = "No suitable decompressor found for this video stream!"
            GoTo ErrorOut
        End If
    End If
    
    'create a DIB class to load the frames into
    Set dib = New cDib
    For i = nFirstFrame To (numFrames - 1) + nFirstFrame
        pDIB = AVIStreamGetFrame(pGetFrameObj, i)  'returns "packed DIB"
        If dib.CreateFromPackedDIBPointer(pDIB) Then
            Call dib.WriteToFile(sBMPFileNames & i & ".BMP")
        End If
    Next
    Set dib = Nothing

ErrorOut:
    If pGetFrameObj <> 0 Then
        Call AVIStreamGetFrameClose(pGetFrameObj) '//deallocates the GetFrame resources and interface
    End If
    If pAVIStream <> 0 Then
        Call AVIStreamRelease(pAVIStream) '//closes video stream
    End If
    If pAVIFile <> 0 Then
        Call AVIFileRelease(pAVIFile) '// closes the file
    End If
    
    If (nHR <> AVIERR_OK Or Len(sError) > 0) Then  'if there was an error then show feedback to user
        Call Err.Raise(-1, "clsFOTAVIToBMP.WriteOutBMP", "There was an error working with the file:" & vbCrLf & sAVIFileName & vbCrLf & sError)
    End If
End Sub

Private Sub Class_Initialize()
    Call AVIFileInit   '// opens AVIFile library
End Sub

Private Sub Class_Terminate()
    Call AVIFileExit   '// releases AVIFile library
End Sub
