/* * Public Domain 1995,1996 Timothy Butler * * THIS DOCUMENT IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * *//* Public Domain Additions 1998 Terence Kelly * Many more chunks and tags are now decoded than were * available in the original.  Anyone wishing to add additional * chunks or tags simply needs to write a callback function for that * chunk/tag and register it in the InitParser function.  My additions  * only print numerical values rather than the enumerated names.  Anyone wishing  * to add to or alter the current callback functions to include them can follow the  * examples Tim wrote in the NAMES.C library file. */ #include <assert.h>#include "niffio.h"extern void doindent(unsigned nLevel);static char separator[]={"////////////////////////////////////////////////////////////////////////////////"};/* this doline was altered by TK to save some time */doline(int indent){    int  dunsel;    char line_divider[81];    if ((--indent) < 0)        indent = 0;        dunsel=80-indent*4;    strncpy(line_divider,separator,dunsel);    line_divider[dunsel]=0;    printf("%s\n",line_divider);}/* This is Tim's original dolinedoline(int indent){    int i;    if ((--indent) < 0)        indent = 0;        for (i = indent * 4; i < 80; i++)        printf("/");    printf("\n");}*/int printSHORT(int nIndent, int nFieldWidth,            SHORT h, const char *strComment){    doindent(nIndent+1);    return printf("%*hd  // %s\n", nFieldWidth, h, strComment); }intprintSTROFFSET(int nIndent, int nFieldWidth,               STROFFSET offset, const char *strComment){    doindent(nIndent+1);    return printf("%*luL // %s\n", nFieldWidth, offset, strComment);}intprintRATIONAL(int nIndent, int nFieldWidth,              RATIONAL r, const char *strComment){    doindent(nIndent+1);    printf("%*hd  // %s numerator\n",            nFieldWidth, r.numerator, strComment);    doindent(nIndent+1);    return         printf("%*hd  // %s denominator\n",                nFieldWidth, r.denominator, strComment);}intprintBYTE(int nIndent, int nFieldWidth,          BYTE b, const char *strComment){    doindent(nIndent+1);    return printf("%*huC // %s\n", nFieldWidth, b, strComment);}printSIGNEDBYTE(int nIndent, int nFieldWidth,                SIGNEDBYTE sb, const char *strComment){    doindent(nIndent + 1);    return printf("%*hdC // %s\n", nFieldWidth, sb, strComment);}/* Print a Time-Slice type */printTS(int nIndent, int nFieldWidth,        BYTE ts, const char *strComment){    if (! NIFFIOSymbolTS(ts))        return printBYTE(nIndent, nFieldWidth, ts, strComment);    doindent(nIndent + 1);    return printf("%*s  // %s\n", nFieldWidth, NIFFIOSymbolTS(ts), strComment);}/* Print a Clef Shape */printCLEFSHAPE(int nIndent, int nFieldWidth,               BYTE cs, const char *strComment){    if (! NIFFIOSymbolCLEFSHAPE(cs))        return printBYTE(nIndent, nFieldWidth, cs, strComment);        doindent(nIndent + 1);    return printf("%*s  // %s\n",                   nFieldWidth, NIFFIOSymbolCLEFSHAPE(cs), strComment);    }printSymbol( const char * (decoder(BYTE)),             int nIndent, int nFieldWidth,             BYTE symbol, const char *strComment){    /* Do we know about this value */    if (! decoder(symbol))    {        printf("//\n");        printf("// WARNING: UNKNOWN VALUE for %s\n", strComment);        printf("//\n");        return printBYTE(nIndent, nFieldWidth, symbol, strComment);    }       doindent(nIndent + 1);    return printf("%*s  // %s\n",                   nFieldWidth, decoder(symbol), strComment);        }/* * cbListStart * =========== * Print the beginning of a list */RIFFIOSuccesscbListStart(NIFFIOChunkContext *pctxChunk){    char strId[RIFFIO_FOURCC_LIM];    char strType[RIFFIO_FOURCC_LIM];    assert (pctxChunk);    assert(pctxChunk->pnf);    assert(pctxChunk->pchunk);    RIFFIOFOURCCToString(pctxChunk->pchunk->fccId, strId);    RIFFIOFOURCCToString(pctxChunk->pchunk->fccType, strType);    doindent(pctxChunk->nLevel);    doline(pctxChunk->nLevel);    doindent(pctxChunk->nLevel);    printf("// %s\n", NIFFIONameListType(pctxChunk->pchunk->fccType));    doindent(pctxChunk->nLevel);    printf("'%s' ( '%s' // sizeData = %ul\n",           strId, strType, pctxChunk->pchunk->sizeData);    printf("\n");    return RIFFIO_OK;}RIFFIOSuccesscbListEnd(NIFFIOChunkContext *pctxChunk){    char strType[RIFFIO_FOURCC_LIM];    assert (pctxChunk);    assert(pctxChunk->pnf);    assert(pctxChunk->pchunk);    RIFFIOFOURCCToString(pctxChunk->pchunk->fccType, strType);    doindent(pctxChunk->nLevel);    printf(")\n");    doindent(pctxChunk->nLevel);    printf("// %s\n", NIFFIONameListType(pctxChunk->pchunk->fccType));    doindent(pctxChunk->nLevel);    doline(pctxChunk->nLevel);    printf("\n");    return RIFFIO_OK;}RIFFIOSuccesscbFormStart(NIFFIOChunkContext *pctxChunk){    char strId[RIFFIO_FOURCC_LIM];    char strType[RIFFIO_FOURCC_LIM];            assert(pctxChunk != 0);    assert(pctxChunk->pnf != 0);    assert(pctxChunk->pchunk != 0);    RIFFIOFOURCCToString(pctxChunk->pchunk->fccId, strId);    RIFFIOFOURCCToString(pctxChunk->pchunk->fccType, strType);    doline(0);    printf("// NIFF Form\n");    printf("'%s' ( '%s' // sizeData=%lu\n",           strId, strType, pctxChunk->pchunk->sizeData);    printf("\n");    return RIFFIO_OK;}RIFFIOSuccesscbFormEnd(NIFFIOChunkContext *pctxChunk){    assert (pctxChunk != 0);    assert (pctxChunk->pnf != 0);    assert (pctxChunk->pchunk != 0);    printf(")\n");    printf("// NIFF Form End\n");    doline(0);    return RIFFIO_OK;}/* * cbChunkStart * ========== * Print the chunk's name and size  */RIFFIOSuccesscbChunkStart(NIFFIOChunkContext *pctxChunk){    char strId[RIFFIO_FOURCC_LIM];            assert(pctxChunk != 0);    assert(pctxChunk->pnf != 0);    assert(pctxChunk->pchunk != 0);    RIFFIOFOURCCToString(pctxChunk->pchunk->fccId, strId);    doindent(pctxChunk->nLevel);    doline(pctxChunk->nLevel);    doindent(pctxChunk->nLevel);    printf("// %s\n", NIFFIONameChunkId(pctxChunk->pchunk->fccId));    doindent(pctxChunk->nLevel);    printf("'%s' ( // sizeData=%lu\n",           strId, pctxChunk->pchunk->sizeData);    printf("\n");    }/* * cbChunkEnd * ========== * Print the closing parenthesis of a chunk */RIFFIOSuccesscbChunkEnd(NIFFIOChunkContext *pctxChunk){    doindent(pctxChunk->nLevel);    printf(")\n\n");    return RIFFIO_OK;}/* * cbChunk * ======= * Default callback for any chunk  */RIFFIOSuccesscbChunk(NIFFIOChunkContext *pctxChunk){    cbChunkStart(pctxChunk);    doindent(pctxChunk->nLevel + 1);    printf("// Don't know how to decode this chunk (yet).\n");    printf("\n");    return cbChunkEnd(pctxChunk);}/* cbTag * ===== * Default callback for any tag */RIFFIOSuccesscbTagStart(NIFFIOTagContext *pctxTag){    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    doindent(pctxTag->nLevel);    doline(pctxTag->nLevel);        doindent(pctxTag->nLevel);    printf ("// %s\n",             NIFFIONameTagId(pctxTag->ptag->tagid));    doindent(pctxTag->nLevel);    printf("%uC ( // sizeData = %d\n",            pctxTag->ptag->tagid,           pctxTag->ptag->tagsizeData);    printf("\n");    return RIFFIO_OK;}cbTagEnd(NIFFIOTagContext *pctxTag){    doindent(pctxTag->nLevel);    printf(")\n\n");    return RIFFIO_OK;}RIFFIOSuccesscbTag(NIFFIOTagContext *pctxTag){    cbTagStart(pctxTag);    doindent(pctxTag->nLevel+1);    printf("Don't know how to decode tag (yet).\n");    return cbTagEnd(pctxTag);}RIFFIOSuccesscbSetupSectionStart(NIFFIOChunkContext *pctxChunk){    char strId[5];    char strType[5];    assert(pctxChunk != 0);    assert(pctxChunk->pnf != 0);    assert(pctxChunk->pchunk != 0);    RIFFIOFOURCCToString(pctxChunk->pchunk->fccId, strId);    RIFFIOFOURCCToString(pctxChunk->pchunk->fccType, strType);    doindent(pctxChunk->nLevel);    printf("'%s' ( '%s' // Setup Section, sizeData=%lu\n",           strId, strType, pctxChunk->pchunk->sizeData);    return RIFFIO_OK;        }RIFFIOSuccesscbSetupSectionEnd(NIFFIOChunkContext *pctxChunk){    assert(pctxChunk != 0);    assert(pctxChunk->pnf != 0);    assert(pctxChunk->pchunk != 0);    doindent(pctxChunk->nLevel);    printf(") // Setup Section\n");    return RIFFIO_OK;}RIFFIOSuccesscbInfoStart(NIFFIOChunkContext *pctxChunk, niffNiffInfo *ni){    cbChunkStart(pctxChunk);    doindent(pctxChunk->nLevel+1);    printf("\"%.8s\" // NIF Version\n", ni->NIFFVersion);    doindent(pctxChunk->nLevel+1);    printf("%10dC // Program Type\n", ni->programType);    doindent(pctxChunk->nLevel+1);    printf("%10dC // Standard Units\n", ni->standardUnits);    doindent(pctxChunk->nLevel+1);    printf("%10d  // Absolute Units\n", ni->absoluteUnits);    doindent(pctxChunk->nLevel+1);    printf("%10d  // Midi clocks per quarter\n", ni->midiClocksPerQuarter);    return RIFFIO_OK;}RIFFIOSuccesscbInfoEnd(NIFFIOChunkContext *pctxChunk,niffNiffInfo *ni){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbFontDescriptionStart(NIFFIOChunkContext *pctxChunk, niffFontDescription *np){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    printSTROFFSET( nLevel, 10, np->fontNamePtr,    "name");    printSHORT(     nLevel, 10, np->size,           "size");		printSHORT(     nLevel, 10, np->spaceHeight,    "space height");    printSHORT(     nLevel, 10, np->where,          "where (-1 is local)");    printBYTE(      nLevel, 10, np->style,          "style");    printf("\n");}RIFFIOSuccesscbFontDescriptionEnd(NIFFIOChunkContext *pctxChunk,niffFontDescription *ni){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbTextStart(NIFFIOChunkContext *pctxChunk, niffText *p){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);		printSTROFFSET( nLevel, 10, p->value,"string offset");}RIFFIOSuccesscbTextEnd(NIFFIOChunkContext *pctxChunk,niffText *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbPartStart(NIFFIOChunkContext *pctxChunk, niffPart *np){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);        printSHORT(     nLevel, 10, np->partID,         "Part ID");    printSTROFFSET( nLevel, 10, np->name,           "name");    printSTROFFSET( nLevel, 10, np->abbreviation,   "abbreviation");    printBYTE(      nLevel, 10, np->numberOfStaves, "number of staves");    printSIGNEDBYTE(nLevel, 10, np->midiChannel,    "MIDI channel");    printSIGNEDBYTE(nLevel, 10, np->midiCable,      "MIDI cable");    printSIGNEDBYTE(nLevel, 10, np->transpose,      "transpose");    printf("\n");}RIFFIOSuccesscbPartEnd(NIFFIOChunkContext *pctxChunk, niffPart *np){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbTimeSliceStart(NIFFIOChunkContext *pctxChunk, niffTimeSlice *p){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    printSymbol(NIFFIOSymbolTS, nLevel, 15,  p->type, "type");    printRATIONAL(nLevel, 15, p->startTime, "start time");    printf("\n");}RIFFIOSuccesscbTimeSliceEnd(NIFFIOChunkContext *pctxChunk, niffTimeSlice *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbBarlineStart(NIFFIOChunkContext *pctxChunk, niffBarline *p){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    printSymbol(NIFFIOSymbolBARTYPE,                 nLevel, 20, p->type, "type");    printSymbol(NIFFIOSymbolBAREXT,                 nLevel, 20, p->extendsTo, "extends to");    printSHORT(nLevel, 20, p->numberOfStaves, "number of staves");    printf("\n");}RIFFIOSuccesscbBarlineEnd(NIFFIOChunkContext *pctxChunk, niffBarline *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbClefStart(NIFFIOChunkContext *pctxChunk, niffClef *p){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    printSymbol(NIFFIOSymbolCLEFSHAPE,                 nLevel, 15, p->shape, "shape");    printSIGNEDBYTE(nLevel, 15, p->staffStep, "staffStep");    printSymbol(NIFFIOSymbolCLEFOCT,                 nLevel, 15, p->octaveNumber, "octaveNumber");    printf("\n");}RIFFIOSuccesscbClefEnd(NIFFIOChunkContext *pctxChunk, niffClef *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbKeySignatureStart(NIFFIOChunkContext *pctxChunk, niffKeySignature *p){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    printSIGNEDBYTE(nLevel, 15, p->standardCode, "standardCode");    printf("\n");}RIFFIOSuccesscbKeySignatureEnd(NIFFIOChunkContext *pctxChunk, niffKeySignature *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbTimeSignatureStart(NIFFIOChunkContext *pctxChunk, niffTimeSignature *p){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    printSIGNEDBYTE(nLevel, 15, p->topNumber,    "top number");    printBYTE      (nLevel, 15, p->bottomNumber, "bottom number");    printf("\n");}RIFFIOSuccesscbTimeSignatureEnd(NIFFIOChunkContext *pctxChunk, niffTimeSignature *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbNoteheadStart(NIFFIOChunkContext *pctxChunk, niffNotehead *p){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    printSymbol(NIFFIOSymbolNOTESHAPE,                 nLevel, 20, p->shape, "shape");    printSIGNEDBYTE(nLevel, 20, p->staffStep,    "staff step");    printRATIONAL  (nLevel, 20, p->duration, "duration");    printf("\n");}RIFFIOSuccesscbNoteheadEnd(NIFFIOChunkContext *pctxChunk, niffNotehead *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbBeamStart(NIFFIOChunkContext *pctxChunk, niffBeam *p){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    printBYTE(nLevel, 20, p->beamPartsToLeft,    "parts to left");    printBYTE(nLevel, 20, p->beamPartsToRight, "parts to right");    printf("\n");}RIFFIOSuccesscbBeamEnd(NIFFIOChunkContext *pctxChunk, niffBeam *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbOctaveSignStart(NIFFIOChunkContext *pctxChunk, niffOctaveSign *p){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    printBYTE(nLevel, 20, p->numberOfOctaves,    "parts to left");    printBYTE(nLevel, 20, p->aboveOrBelow, "1=Above, 2=Below");    printBYTE(nLevel, 20, p->type, "1=Transpose, 2=Double");    printSTROFFSET(nLevel,20,p->textString, "Text string");        printf("\n");}RIFFIOSuccesscbOctaveSignEnd(NIFFIOChunkContext *pctxChunk, niffOctaveSign *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbRestStart(NIFFIOChunkContext *pctxChunk, niffRest *p){    int nLevel;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    printSymbol(NIFFIOSymbolREST, nLevel, 15, p->shape, "shape");    printSIGNEDBYTE(nLevel, 15, p->staffStep,    "staff step");    printRATIONAL  (nLevel, 15, p->duration, "duration");    printf("\n");}RIFFIOSuccesscbRestEnd(NIFFIOChunkContext *pctxChunk, niffRest *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbAccidentalStart(NIFFIOChunkContext *pctxChunk, niffAccidental *p){    int nLevel;    char *str;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    switch(p->shape)    {    	case 1:    		str="double flat";    		break;    	case 2:    		str="flat";    		break;    	case 3:    		str="natural";    		break;    	case 4:    		str="sharp";    		break;	    	case 5:    		str="double sharp";    		break;    	case 6:    		str="quarter tone flat";    		break;    	case 7:    		str="three quarter tones flat";    		break;    	case 8:    		str="quarter tone sharp";    		break;    	case 9:    		str="three quarter tones sharp";    		break;    }        doindent(nLevel+1);    printf("%s\n",str);}RIFFIOSuccesscbAccidentalEnd(NIFFIOChunkContext *pctxChunk, niffAccidental *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbArticulationStart(NIFFIOChunkContext *pctxChunk, niffArticulation *p){    int nLevel;    char *str;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    switch(p->shape)    {    	case 1:    		str="strong accent (vertical wedge)";    		break;    	case 2:    		str="medium accent (>)";    		break;    	case 3:    		str="light accent (tenuto)";    		break;    	case 4:    		str="staccato";    		break;	    	case 5:    		str="down bow";    		break;    	case 6:    		str="up bow";    		break;    	case 7:    		str="harmonic (small circle)";    		break;    	case 8:    		str="fermata";    		break;    	case 9:    		str="arsis sign (unstressed)";    		break;    	case 10:    		str="thesis sign (stressed)";    		break;    	case 11:    		str="plus sign";    		break;    	case 12:    		str="vertical filled wedge (staccatissimo)";    		break;    	case 13:    		str="double tonguing (two dots)";    		break;    	case 14:    		str="triple tonguing (three dots)";    		break;    	case 15:    		str="snap, pizzicato";    		break;    }        doindent(nLevel+1);    printf("%s\n",str);}RIFFIOSuccesscbArticulationEnd(NIFFIOChunkContext *pctxChunk, niffArticulation *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbDynamicStart(NIFFIOChunkContext *pctxChunk, niffDynamic *p){    int nLevel;    char *str;        nLevel = pctxChunk->nLevel;    cbChunkStart(pctxChunk);    switch(p->code)    {    	case 1:    		str="pppp";    		break;    	case 2:    		str="ppp";    		break;    	case 3:    		str="pp";    		break;    	case 4:    		str="p";    		break;	    	case 5:    		str="mp";    		break;    	case 6:    		str="mf";    		break;    	case 7:    		str="f";    		break;    	case 8:    		str="ff";    		break;    	case 9:    		str="fff";    		break;    	case 10:    		str="ffff";    		break;    	case 11:    		str="sp";    		break;    	case 12:    		str="sf";    		break;    	case 13:    		str="sfz";    		break;    	case 14:    		str="fz";    		break;    	case 15:    		str="fp";    		break;    	case 16:    		str="cresc";    		break;    	case 17:    		str="crescendo";    		break;    	case 18:    		str="dim";    		break;    	case 19:    		str="diminuendo";    		break;    }        doindent(nLevel+1);    printf("%s\n",str);}RIFFIOSuccesscbDynamicEnd(NIFFIOChunkContext *pctxChunk, niffDynamic *p){    return cbChunkEnd(pctxChunk);}RIFFIOSuccesscbInvisible(NIFFIOTagContext *pctxTag){    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    doindent(pctxTag->nLevel);    printf("%uC <> // Invisible\n", pctxTag->ptag->tagid);    return RIFFIO_OK;}RIFFIOSuccesscbLogicalPlacement(NIFFIOTagContext *pctxTag, niffLogicalPlacement *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    printSymbol(NIFFIOSymbolLOGPLACEH,                 nLevel, 20, p->horizontal, "horizontal");    printSymbol(NIFFIOSymbolLOGPLACEV,                 nLevel, 20, p->vertical, "vertical");    printSymbol(NIFFIOSymbolLOGPLACEPROX,                 nLevel, 20, p->proximity, "proximity");    cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccesscbTupletDesc(NIFFIOTagContext *pctxTag, niffTupletDesc *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    printRATIONAL  (nLevel, 20, p->transformRatioAB, "transform AB");    printRATIONAL  (nLevel, 20, p->transformRatioCD, "transform CD");    printBYTE      (nLevel, 20, p->groupingSymbol, "grouping symbol");    cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccesscbAbsPlacement(NIFFIOTagContext *pctxTag, niffAbsPlacement *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    printSHORT(nLevel, 10, p->horizontal, "horizontal");    printSHORT(nLevel, 10, p->vertical, "vertical");    cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccesscbPartID(NIFFIOTagContext *pctxTag, niffPartID *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    printSHORT(nLevel, 10, *p, "Part ID Number");    cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccesscbWidth(NIFFIOTagContext *pctxTag, niffPartID *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    printSHORT(nLevel, 10, *p, "Width in Abs. Units");    cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccesscbHeight(NIFFIOTagContext *pctxTag, niffHeight *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    printSHORT(nLevel, 10, *p, "Height in Abs. Units");    cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccesscbNumberOfNodes(NIFFIOTagContext *pctxTag, niffNumberOfNodes *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    printSHORT(nLevel, 10, *p, "Nodes");    cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccesscbID(NIFFIOTagContext *pctxTag, niffID *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    printSHORT(nLevel, 10, *p, "Node ID");    cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccesscbNumberOfFlags(NIFFIOTagContext *pctxTag, niffNumberOfFlags *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    printBYTE(nLevel, 10, *p, "");    cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccesscbTieDirection(NIFFIOTagContext *pctxTag, niffTieDirection *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    if (*p==1)    {    	printBYTE(nLevel, 10, *p, "rounded above");		}		if (*p==2)		{    	printBYTE(nLevel, 10, *p, "rounded below");		}        cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccesscbFontID(NIFFIOTagContext *pctxTag, niffFontID *p){    int nLevel;    nLevel = pctxTag->nLevel;    assert(pctxTag != 0);    assert(pctxTag->pnf != 0);    assert(pctxTag->pchunkParent != 0);    cbTagStart(pctxTag);    printSHORT(nLevel, 10, *p, "Offset in font list");    cbTagEnd(pctxTag);    return RIFFIO_OK;}RIFFIOSuccess cbStringTable(NIFFIOChunkContext *pctxChunk){    char strFOURCC[RIFFIO_FOURCC_LIM]; /* Buffer for printing FOURCCs */    NIFFIOFile *pnf;    RIFFIOChunk *pchunk;    niffChklentabEntry entryCLT;    char buffer;    unsigned long offset;    int bytesRead;    pnf = pctxChunk->pnf;    pchunk = pctxChunk->pchunk;     cbChunkStart(pctxChunk);    offset = 0;    while (! NIFFIOChunkDataEnd(pnf, pchunk))    {        doindent(pctxChunk->nLevel+1);        printf("// offset == %lu\n", offset);        doindent(pctxChunk->nLevel+1);        printf("\"");                bytesRead = NIFFIORead(pnf, &buffer, 1);        offset += bytesRead;        while(buffer)        {            printf("%c", buffer);            bytesRead = NIFFIORead(pnf, &buffer, 1);            offset += bytesRead;        }        printf ("\"Z\n");        printf ("\n");    }    cbChunkEnd(pctxChunk);}RIFFIOSuccesscbChnkLenTable(NIFFIOChunkContext *pctxChunk){    char strFOURCC[RIFFIO_FOURCC_LIM]; /* Buffer for printing FOURCCs */    NIFFIOFile *pnf;    RIFFIOChunk *pchunk;    niffChklentabEntry entryCLT;        pnf = pctxChunk->pnf;    pchunk = pctxChunk->pchunk;    cbChunkStart(pctxChunk);    while (! NIFFIOChunkDataEnd(pnf, pchunk))    {        NIFFIOReadniffChklentabEntry(pnf, & entryCLT);        RIFFIOFOURCCToString(entryCLT.chunkName, strFOURCC);        doindent(pctxChunk->nLevel+1);        printf("'%s' %5ldL\n", strFOURCC, entryCLT.offsetOfFirstTag);    }        doindent(pctxChunk->nLevel);    printf("')'\n");    printf("\n");}NIFFIOParser *InitParser(void){    NIFFIOParser *pparserNew;            pparserNew = NIFFIOParserNew();    NIFFIORegisterForm(pparserNew, cbFormStart, cbFormEnd);    NIFFIORegisterDefaultList(pparserNew, cbListStart, cbListEnd);    NIFFIORegisterDefaultAtomicChunk(pparserNew, cbChunk);    NIFFIORegisterDefaultTaggedChunk(pparserNew, cbChunk, 0);    NIFFIORegisterDefaultTag(pparserNew, cbTag);    NIFFIORegisterChunkChnkLenTable(pparserNew, cbChnkLenTable);    NIFFIORegisterChunkStringTable(pparserNew, cbStringTable);    NIFFIORegisterChunkNiffInfo(pparserNew, cbInfoStart, cbInfoEnd);    NIFFIORegisterChunkFontDescription(pparserNew, cbFontDescriptionStart, cbFontDescriptionEnd);		NIFFIORegisterChunkText(pparserNew, cbTextStart, cbTextEnd);		NIFFIORegisterChunkPart(pparserNew, cbPartStart, cbPartEnd);    NIFFIORegisterChunkSystemHeader(pparserNew, cbChunkStart, cbChunkEnd);    NIFFIORegisterChunkStaffHeader(pparserNew, cbChunkStart, cbChunkEnd);    NIFFIORegisterChunkTimeSlice(pparserNew,                                  cbTimeSliceStart,                                 cbTimeSliceEnd);    NIFFIORegisterChunkBarline(pparserNew,                                cbBarlineStart,                               cbBarlineEnd);    NIFFIORegisterChunkClef(pparserNew,                             cbClefStart,                            cbClefEnd);    NIFFIORegisterChunkKeySignature(pparserNew,                                     cbKeySignatureStart,                                    cbKeySignatureEnd);    NIFFIORegisterChunkTimeSignature(pparserNew,                                      cbTimeSignatureStart,                                     cbTimeSignatureEnd);  	  	NIFFIORegisterChunkOctaveSign(pparserNew,                                      cbOctaveSignStart,                                     cbOctaveSignEnd);    NIFFIORegisterChunkNotehead(pparserNew, cbNoteheadStart, cbNoteheadEnd);    NIFFIORegisterChunkBeam(pparserNew, cbBeamStart, cbBeamEnd);    NIFFIORegisterChunkRest(pparserNew, cbRestStart, cbRestEnd);    NIFFIORegisterChunkAccidental(pparserNew, cbAccidentalStart, cbAccidentalEnd);    NIFFIORegisterChunkArticulation(pparserNew, cbArticulationStart, cbArticulationEnd);    NIFFIORegisterChunkDynamic(pparserNew, cbDynamicStart, cbDynamicEnd);    NIFFIORegisterChunkStem(pparserNew, cbChunkStart, cbChunkEnd);    NIFFIORegisterChunkAugDot(pparserNew, cbChunkStart, cbChunkEnd);    NIFFIORegisterChunkSlur(pparserNew, cbChunkStart, cbChunkEnd);            NIFFIORegisterTagInvisible(pparserNew, niffckidArticulation, cbInvisible);    NIFFIORegisterTagNumberOfFlags(pparserNew,                                    NIFFIO_FOURCC_WILDCARD,                                    cbNumberOfFlags);    NIFFIORegisterTagLogicalPlacement(pparserNew,                                       NIFFIO_FOURCC_WILDCARD,                                       cbLogicalPlacement);    NIFFIORegisterTagAbsPlacement(pparserNew,                                       NIFFIO_FOURCC_WILDCARD,                                       cbAbsPlacement);        NIFFIORegisterTagTupletDesc(pparserNew,                                       NIFFIO_FOURCC_WILDCARD,                                       cbTupletDesc);        NIFFIORegisterTagNumberOfNodes(pparserNew,                                       NIFFIO_FOURCC_WILDCARD,                                       cbNumberOfNodes);        NIFFIORegisterTagPartID(pparserNew,                                       NIFFIO_FOURCC_WILDCARD,                                       cbPartID);    NIFFIORegisterTagWidth(pparserNew,                                       NIFFIO_FOURCC_WILDCARD,                                       cbWidth);    NIFFIORegisterTagHeight(pparserNew,                                       NIFFIO_FOURCC_WILDCARD,                                       cbHeight);        NIFFIORegisterTagID(pparserNew,                                 NIFFIO_FOURCC_WILDCARD,                                 cbID);        NIFFIORegisterTagTieDirection(pparserNew,                                 NIFFIO_FOURCC_WILDCARD,                                 cbTieDirection);        NIFFIORegisterTagFontID(pparserNew,                                 NIFFIO_FOURCC_WILDCARD,                                 cbFontID);        return pparserNew;        }const char *NIFFIOSymbolCLEFSHAPE(BYTE cs)/***************************************************************************/{    switch(cs)    {      case clefshapeGclef: return "clefshapeGclef";      case clefshapeFclef: return "clefshapeFclef";      case clefshapeCclef: return "clefshapeCclef";      case clefshapePercussion: return "clefshapePercussion";      case clefshapeDoubleGclef: return "clefshapDoubleGclef";      case clefshapeGuitarTab: return "clefshapeGuitarTab";    }    return 0;}    