Go to Google Groups Home    microsoft.public.win32.programmer.directx.sdk
Re: GraphEdit File Format

Alessandro Angeli [MVP::DigitalMedia] <nob...@nowhere.in.the.net>

[Sorry for the richtext, but I've used it to preserve the code formatting.]

cairn wrote:
> I am reading in a .grf file into a IStorage, and then
> getting the data with an IStream object. I am then using
> the IStream read to get the data in to an array of bytes.
> This is then compacted by getting every other byte and
> placing the result into a CString, but when I view the
> data I cannot see the 'CONNECTIONS' section of the file.
> I get the Filters section and then some binary. Please
> could someone explain a good way to extarct all the data,
> anothe way to get the data from the file so that we can
> do some processing on it.

Most likely you are parsing it wrong. Here is a full sample
parser:

--------- grfdump.cpp -------------------
#include <windows.h>
#include <errno.h>
#include <stdio.h>

#define TRACE(x) x
#define trace_open(x,y)
#define trace_close()
#ifdef UNICODE
# define trace wprintf
# define TRACEWSTR TEXT("s")
#else
# define trace printf
# define TRACEWSTR TEXT("S")
#endif
#define DWRESERVED 0
#define LPRESERVED NULL
#define TRACEHR_STR TEXT("0x%08lX")
#define TRACEHR_REF(hr) (hr)

#define LWS(c) ((c) == L'\n' || (c) == L'\r' || (c) == L'\t' || (c) == L' ')

LPWSTR token(LPWSTR p, LPWSTR* s1, LPWSTR* s2, WCHAR* q)
{
 for(; LWS(*p); p++);
 if(*q = *p == L'"' ? *p++ : L'\0') {
  for(*s1 = p; *p != *q; p++); *s2 = p++;
 } else {
  for(*s1 = p; !LWS(*p); p++); *s2 = p;
 }
 return p;

}

HRESULT skip(LPWSTR s1, LPWSTR* p)
{
 int n = wcstol(s1,NULL,10);
 if(n == 0 && errno == ERANGE) return E_FAIL;
 (*p)++; if(n > 0) *p = (LPWSTR)&((LPBYTE)(*p))[n];
 return S_OK;

}

int wmain(int argc, LPWSTR argv[])
{
 HRESULT  hr   = S_OK;
 IStorage* pGrfFile = NULL;
 IStream* pGrfData = NULL;
 STATSTG  rGrfStat;
 int   cb;
 LPWSTR  pb  = NULL;
 LPWSTR  s1, s2, p;
 WCHAR  q;

 TRACE(trace_open(NULL,zFalse));

 TRACE(trace(TEXT("*** StgOpenStorage(L\"%") TRACEWSTR TEXT("\")...\n"),argv[1]));
 if(S_OK != (hr = StgOpenStorage(argv[1],NULL,STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE,NUL L,DWRESERVED,&pGrfFile))) goto exit;

 TRACE(trace(TEXT("*** OpenStream(L\"ActiveMovieGraph\")...\n")));
 if(S_OK != (hr = pGrfFile->OpenStream(L"ActiveMovieGraph",LPRESERVED,STGM_DIRECT|STGM_READ|S TGM_SHARE_EXCLUSIVE,DWRESERVED,&pGrfData))) goto exit;

 TRACE(trace(TEXT("*** Stat()...\n")));
 if(S_OK != (hr = pGrfData->Stat(&rGrfStat,STATFLAG_NONAME))) goto exit;

 cb = (int)rGrfStat.cbSize.QuadPart;
 TRACE(trace(TEXT("*** new BYTE[%d]...\n"),cb));
 if(NULL == (pb = (LPWSTR)new BYTE[cb])) goto exit;

 TRACE(trace(TEXT("*** Read(%d)...\n"),cb));
 if(S_OK != (hr = pGrfData->Read(pb,(ULONG)cb,NULL))) goto exit;

 p = pb;

 p = token(p,&s1,&s2,&q);
 TRACE(trace(TEXT(">>> version = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));

 p = token(p,&s1,&s2,&q);
 if(0 == wcsnicmp(s1,L"FILTERS",s2-s1)) {
  TRACE(trace(TEXT(">>> FILTERS\n")));
  while(TRUE) {
   p = token(p,&s1,&s2,&q);
   if(0 == wcsnicmp(s1,L"CONNECTIONS",s2-s1)) break;
   TRACE(trace(TEXT(">>>   %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(">>>     name .... = L\"%.*") TRACEWSTR TEXT("\"\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(">>>     class_id  = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   if(0 == wcsnicmp(s1,L"SOURCE",s2-s1) || 0 == wcsnicmp(s1,L"SINK",s2-s1)) {
    TRACE(trace(TEXT(">>>     file .... = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
    p = token(p,&s1,&s2,&q);
    TRACE(trace(TEXT(">>>     file_name = L\"%.*") TRACEWSTR TEXT("\"\n"),s2-s1,s1));
    p = token(p,&s1,&s2,&q);
   }
   TRACE(trace(TEXT(">>>     length .. = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   if(S_OK != (hr = skip(s1,&p))) goto exit;
  }
 }
 if(0 == wcsnicmp(s1,L"CONNECTIONS",s2-s1)) {
  TRACE(trace(TEXT(">>> CONNECTIONS\n")));
  while(TRUE) {
   p = token(p,&s1,&s2,&q);
   if(0 == wcsnicmp(s1,L"CLOCK",s2-s1)) break;
   if(0 == wcsnicmp(s1,L"END",s2-s1)) break;

   TRACE(trace(TEXT(">>>   %.*") TRACEWSTR,s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(" [L\"%.*") TRACEWSTR TEXT("\"]"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(" -> %.*") TRACEWSTR,s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(" [L\"%.*") TRACEWSTR TEXT("\"]\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(">>>     sample_size ........ = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(">>>     major_type ......... = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(">>>     subtype ............ = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(">>>     fixed_sample_size .. = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(">>>     temporal_compression = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(">>>     length(?) .......... = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(">>>     format_type ........ = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   p = token(p,&s1,&s2,&q);
   TRACE(trace(TEXT(">>>     length ............. = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
   if(S_OK != (hr = skip(s1,&p))) goto exit;
   p++; /// where is this L'\0' terminator documented??
  }
 }
 if(0 == wcsnicmp(s1,L"CLOCK",s2-s1)) {
  TRACE(trace(TEXT(">>> CLOCK\n")));
  p = token(p,&s1,&s2,&q);
  TRACE(trace(TEXT(">>>   required = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
  p = token(p,&s1,&s2,&q);
  TRACE(trace(TEXT(">>>   clock_id = %.*") TRACEWSTR TEXT("\n"),s2-s1,s1));
 }
 if(0 == wcsnicmp(s1,L"END",s2-s1)) {
  TRACE(trace(TEXT(">>> END\n")));
 }

exit:
 TRACE(trace(TEXT("*** hr = ") TRACEHR_STR TEXT("\n"),TRACEHR_REF(hr)));
 if(pb) delete [] (LPBYTE)pb;
 if(pGrfData) pGrfData->Release();
 if(pGrfFile) pGrfFile->Release();
 TRACE(trace_close());
 return hr;

}

-----------------------------------------

--

// Alessandro Angeli
// MVP :: Digital Media
// a dot angeli at psynet dot net