rpparser.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:79k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. // include
  36. #include "hxtypes.h"
  37. #include "hxwintyp.h"
  38. #include "hxcom.h"
  39. #include "hxresult.h"
  40. #include "hxcomm.h"
  41. #include "ihxpckts.h"
  42. #include "hxxml.h"
  43. #include "hxxres.h"
  44. #include "hxxrsmg.h"
  45. #include "hxerror.h"
  46. // hxmisc
  47. #include "baseobj.h"
  48. #include "unkimp.h"
  49. #include "hxxmlprs.h"
  50. #include "hxparse.h"
  51. // hxcont
  52. #include "hxbuffer.h"
  53. #include "hxslist.h"
  54. #include "hxmap.h"
  55. // coreres
  56. #include "pixres.h"
  57. // pxcomlib
  58. #include "pxrect.h"
  59. #include "pxcolor.h"
  60. #include "pxeffect.h"
  61. #include "gstring.h"
  62. #include "parseurl.h"
  63. #include "rpfile.h"
  64. #include "pxerror.h"
  65. #include "rpparser.h"
  66. // hxdebug
  67. #include "hxheap.h"
  68. #ifdef _DEBUG
  69. #undef HX_THIS_FILE
  70. static char HX_THIS_FILE[] = __FILE__;
  71. #endif
  72. #define BASE_VERSION      HX_ENCODE_PROD_VERSION(0, 0, 0, 0)
  73. #define U2_VERSION        HX_ENCODE_PROD_VERSION(1, 1, 0, 0)
  74. #define REDSTONE_VERSION  HX_ENCODE_PROD_VERSION(1, 1, 0, 0) // XXXMEH - for now, we keep it the same
  75. #define OPACITY_VERSION   HX_ENCODE_PROD_VERSION(1, 4, 0, 0)
  76. const UINT32 PXRealPixParser::m_ulHighestSupportedContentVersion = OPACITY_VERSION;
  77. const PXRealPixParser::PXStringTable PXRealPixParser::m_pTagTable[] = 
  78. {
  79.     { kTagRoot,             "imfl"             },
  80.     { kTagHead,             "head"             },
  81.     { kTagImage,            "image"            },
  82.     { kTagFill,             "fill"             },
  83.     { kTagFadein,           "fadein"           },
  84.     { kTagCrossfade,        "crossfade"        },
  85.     { kTagFadeout,          "fadeout"          },
  86.     { kTagWipe,             "wipe"             },
  87.     { kTagAnimate,          "animate"          },
  88.     { kTagViewchange,       "viewchange"       },
  89.     { kTagEffect,           "effect"           },
  90.     { kNumTags,             NULL               }
  91. };
  92. const PXRealPixParser::PXStringTable PXRealPixParser::m_pAttrTable[] =
  93. {
  94.     { kAttrWidth,             "width"            },
  95.     { kAttrHeight,            "height"           },
  96.     { kAttrBitrate,           "bitrate"          },
  97.     { kAttrTimeformat,        "timeformat"       },
  98.     { kAttrVersion,           "version"          },
  99.     { kAttrTitle,             "title"            },
  100.     { kAttrAuthor,            "author"           },
  101.     { kAttrCopyright,         "copyright"        },
  102.     { kAttrBackgroundcolor,   "background-color" },
  103.     { kAttrBackgroundOpacity, "backgroundOpacity"},
  104.     { kAttrStart,             "start"            },
  105.     { kAttrPreroll,           "preroll"          },
  106.     { kAttrAspect,            "aspect"           },
  107.     { kAttrUrl,               "url"              },
  108.     { kAttrMaxfps,            "maxfps"           },
  109.     { kAttrDuration,          "duration"         },
  110.     { kAttrHandle,            "handle"           },
  111.     { kAttrName,              "name"             },
  112.     { kAttrTarget,            "target"           },
  113.     { kAttrSrcx,              "srcx"             },
  114.     { kAttrSrcy,              "srcy"             },
  115.     { kAttrSrcw,              "srcw"             },
  116.     { kAttrSrch,              "srch"             },
  117.     { kAttrDstx,              "dstx"             },
  118.     { kAttrDsty,              "dsty"             },
  119.     { kAttrDstw,              "dstw"             },
  120.     { kAttrDsth,              "dsth"             },
  121.     { kAttrColor,             "color"            },
  122.     { kAttrDirection,         "direction"        },
  123.     { kAttrType,              "type"             },
  124.     { kAttrPackage,           "package"          },
  125.     { kAttrData,              "data"             },
  126.     { kAttrFile,              "file"             },
  127.     { kAttrStartsrcx,         "startsrcx"        },
  128.     { kAttrStartsrcy,         "startsrcy"        },
  129.     { kAttrStartsrcw,         "startsrcw"        },
  130.     { kAttrStartsrch,         "startsrch"        },
  131.     { kAttrStartdstx,         "startdstx"        },
  132.     { kAttrStartdsty,         "startdsty"        },
  133.     { kAttrStartdstw,         "startdstw"        },
  134.     { kAttrStartdsth,         "startdsth"        },
  135.     { kAttrCenter,            "center"           },
  136.     { kAttrSize,              "size"             },
  137.     { kAttrMime,              "mime"             },
  138.     { kNumAttr,               NULL               }
  139. };
  140. // This list will be used to initialize a data structure for
  141. // legal attribute lookup. The pattern is:
  142. //
  143. // tag-id1, id1-attr1, id1-attr2, ..., kNumAttr
  144. // tag-id2, id2-attr1, id2-attr2, ..., kNumAttr
  145. // ...
  146. // kNumTags
  147. // 
  148. //
  149. // kNumAttr is a marker for the end of the list of attribute ids.
  150. //
  151. const BYTE PXRealPixParser::m_pAttrList[] =
  152. {
  153.     kTagRoot,       kNumAttr,
  154.     kTagHead,       kAttrWidth, kAttrHeight, kAttrBitrate, kAttrTimeformat,
  155.                     kAttrVersion, kAttrTitle, kAttrAuthor, kAttrCopyright,
  156.                     kAttrBackgroundcolor, kAttrStart, kAttrPreroll, kAttrAspect,
  157.                     kAttrUrl, kAttrMaxfps, kAttrDuration, kAttrCenter, kNumAttr,
  158.     kTagImage,      kAttrHandle, kAttrName, kAttrSize, kAttrMime, kNumAttr,
  159.     kTagFill,       kAttrStart, kAttrDstx, kAttrDsty, kAttrDstw, kAttrDsth,
  160.                     kAttrUrl, kAttrMaxfps, kAttrColor, kNumAttr,
  161.     kTagFadein,     kAttrStart, kAttrDuration, kAttrTarget, kAttrSrcx,
  162.                     kAttrSrcy, kAttrSrcw, kAttrSrch, kAttrDstx, kAttrDsty,
  163.                     kAttrDstw, kAttrDsth, kAttrUrl, kAttrMaxfps,
  164.                     kAttrAspect, kAttrCenter, kAttrBackgroundcolor, kNumAttr,
  165.     kTagCrossfade,  kAttrStart, kAttrDuration, kAttrTarget, kAttrSrcx,
  166.                     kAttrSrcy, kAttrSrcw, kAttrSrch, kAttrDstx, kAttrDsty,
  167.                     kAttrDstw, kAttrDsth, kAttrUrl, kAttrMaxfps,
  168.                     kAttrAspect, kAttrCenter, kAttrBackgroundcolor, kNumAttr,
  169.     kTagFadeout,    kAttrStart, kAttrDuration, kAttrDstx, kAttrDsty,
  170.                     kAttrDstw, kAttrDsth, kAttrUrl, kAttrMaxfps,
  171.                     kAttrColor, kNumAttr,
  172.     kTagWipe,       kAttrStart, kAttrDuration, kAttrTarget, kAttrSrcx,
  173.                     kAttrSrcy, kAttrSrcw, kAttrSrch, kAttrDstx, kAttrDsty,
  174.                     kAttrDstw, kAttrDsth, kAttrUrl, kAttrMaxfps, kAttrAspect,
  175.                     kAttrDirection, kAttrType, kAttrCenter, kAttrBackgroundcolor,
  176.                     kNumAttr,
  177.     kTagAnimate,    kAttrStart, kAttrDuration, kAttrTarget, kAttrSrcx,
  178.                     kAttrSrcy, kAttrSrcw, kAttrSrch, kAttrDstx, kAttrDsty,
  179.                     kAttrDstw, kAttrDsth, kAttrUrl, kAttrMaxfps,
  180.                     kAttrAspect, kAttrCenter, kAttrBackgroundcolor, kNumAttr,
  181.     kTagViewchange, kAttrStart, kAttrDuration, kAttrSrcx, kAttrSrcy, kAttrSrcw,
  182.                     kAttrSrch, kAttrDstx, kAttrDsty, kAttrDstw, kAttrDsth,
  183.                     kAttrUrl, kAttrMaxfps, kAttrStartsrcx, kAttrStartsrcy,
  184.                     kAttrStartsrcw, kAttrStartsrch, kAttrStartdstx, kAttrStartdsty,
  185.                     kAttrStartdstw, kAttrStartdsth, kAttrTarget, kAttrAspect, kNumAttr,
  186.     kTagEffect,     kAttrStart, kAttrDuration, kAttrTarget, kAttrSrcx,
  187.                     kAttrSrcy, kAttrSrcw, kAttrSrch, kAttrDstx, kAttrDsty,
  188.                     kAttrDstw, kAttrDsth, kAttrUrl, kAttrMaxfps, kAttrAspect,
  189.                     kAttrPackage, kAttrName, kAttrData,
  190.                     kAttrFile, kNumAttr,
  191.     kNumTags
  192. };
  193. // This list will be used to initialize a data structure for
  194. // required attribute lookup. The pattern is:
  195. //
  196. // tag-id1, id1-attr1, id1-attr2, ..., kNumAttr
  197. // tag-id2, id2-attr1, id2-attr2, ..., kNumAttr
  198. // ...
  199. // kNumTags
  200. // 
  201. //
  202. // kNumAttr is a marker for the end of the list of attribute ids.
  203. //
  204. const BYTE PXRealPixParser::m_pRequiredAttrList[] =
  205. {
  206.     kTagRoot,       kNumAttr,
  207.     kTagHead,       kAttrWidth, kAttrHeight, kAttrBitrate, kNumAttr,
  208.     kTagImage,      kAttrHandle, kAttrName, kNumAttr,
  209.     kTagFill,       kAttrStart, kAttrColor, kNumAttr,
  210.     kTagFadein,     kAttrStart, kAttrDuration, kAttrTarget, kNumAttr,
  211.     kTagCrossfade,  kAttrStart, kAttrDuration, kAttrTarget, kNumAttr,
  212.     kTagFadeout,    kAttrStart, kAttrDuration, kNumAttr,
  213.     kTagWipe,       kAttrStart, kAttrDuration, kAttrTarget, kNumAttr,
  214.     kTagAnimate,    kAttrStart, kAttrDuration, kAttrTarget, kNumAttr,
  215.     kTagViewchange, kAttrStart, kAttrDuration, kNumAttr,
  216.     kTagEffect,     kAttrStart, kAttrDuration, kAttrTarget, kAttrPackage, kAttrName, kNumAttr,
  217.     kNumTags
  218. };
  219. BEGIN_INTERFACE_LIST(PXRealPixParser)
  220.     INTERFACE_LIST_ENTRY(IID_IHXXMLParserResponse, IHXXMLParserResponse)
  221. END_INTERFACE_LIST
  222. PXRealPixParser::PXRealPixParser()
  223. {
  224.     m_pContext            = NULL;
  225.     m_pCommonClassFactory = NULL;
  226.     m_pParser             = NULL;
  227.     m_pRealPixFile        = NULL;
  228.     m_pErrorText          = NULL;
  229.     m_pLegalAttrLUT       = NULL;
  230.     m_pTagToIDMap         = NULL;
  231.     m_pAttrToIDMap        = NULL;
  232.     m_bRealPixError       = FALSE;
  233.     m_pByteListCursor     = NULL;
  234.     m_ulState             = kStateConstructed;
  235.     m_pLastEffect         = NULL;
  236.     m_bVersionSpecified   = FALSE;
  237.     m_ulStrictnessLevel   = REALPIX_STRICTNESS_LOW;
  238. }
  239. PXRealPixParser::~PXRealPixParser()
  240. {
  241.     HX_RELEASE(m_pContext);
  242.     HX_RELEASE(m_pCommonClassFactory);
  243.     HX_RELEASE(m_pParser);
  244.     HX_RELEASE(m_pRealPixFile);
  245.     HX_RELEASE(m_pErrorText);
  246.     HX_RELEASE(m_pLegalAttrLUT);
  247.     HX_DELETE(m_pTagToIDMap);
  248.     HX_DELETE(m_pAttrToIDMap);
  249.     HX_RELEASE(m_pLastEffect);
  250. }
  251. STDMETHODIMP PXRealPixParser::Init(IUnknown*      pContext,
  252.                                    PXRealPixFile* pRealPixFile,
  253.                                    UINT32         ulStrictnessLevel)
  254. {
  255.     HX_RESULT retVal = HXR_OK;
  256.     if (pContext && pRealPixFile)
  257.     {
  258.         // Init members
  259.         HX_RELEASE(m_pContext);
  260.         m_pContext = pContext;
  261.         m_pContext->AddRef();
  262.         HX_RELEASE(m_pRealPixFile);
  263.         m_pRealPixFile = pRealPixFile;
  264.         m_pRealPixFile->AddRef();
  265.         if (ulStrictnessLevel == REALPIX_STRICTNESS_LOW    ||
  266.             ulStrictnessLevel == REALPIX_STRICTNESS_MEDIUM ||
  267.             ulStrictnessLevel == REALPIX_STRICTNESS_HIGH)
  268.         {
  269.             m_ulStrictnessLevel = ulStrictnessLevel;
  270.         }
  271.         else
  272.         {
  273.             m_ulStrictnessLevel = REALPIX_STRICTNESS_LOW;
  274.         }
  275.         // Get an IHXXMLParser interface
  276.         HX_RELEASE(m_pCommonClassFactory);
  277.         retVal = m_pContext->QueryInterface(IID_IHXCommonClassFactory,
  278.                                             (void**) &m_pCommonClassFactory);
  279.         if (SUCCEEDED(retVal))
  280.         {
  281.             BOOL bAllowBadComments = (m_ulStrictnessLevel >= REALPIX_STRICTNESS_MEDIUM ? FALSE : TRUE);
  282.             HXXMLParser* pParser = NULL;
  283.             pParser = new HXXMLParser(bAllowBadComments);
  284.             if (pParser)
  285.             {
  286.                 pParser->AddRef();
  287.                 HX_RELEASE(m_pParser);
  288.                 retVal = pParser->QueryInterface(IID_IHXXMLParser, (void**) &m_pParser);
  289.                 if (SUCCEEDED(retVal))
  290.                 {
  291.                     BOOL bXMLStrictness = (m_ulStrictnessLevel >= REALPIX_STRICTNESS_MEDIUM ? TRUE : FALSE);
  292.                     // Init the parser interface
  293.                     retVal = m_pParser->Init(this,  // this class holds the response interface
  294.                                              NULL,  // no special encoding
  295.                                              bXMLStrictness); // strict XML parsing or not
  296.                     if (SUCCEEDED(retVal))
  297.                     {
  298.                         retVal = SetupLegalAttrLUT();
  299.                         if (SUCCEEDED(retVal))
  300.                         {
  301.                             retVal = SetupIDMaps();
  302.                             if (SUCCEEDED(retVal))
  303.                             {
  304.                                 // Clear the RealPix error flag
  305.                                 m_bRealPixError = FALSE;
  306.                                 // Set the state
  307.                                 m_ulState       = kStateInitialized;
  308.                             }
  309.                         }
  310.                     }
  311.                 }
  312.             }
  313.             else
  314.             {
  315.                 retVal = HXR_OUTOFMEMORY;
  316.             }
  317.             HX_RELEASE(pParser);
  318.         }
  319.     }
  320.     else
  321.     {
  322.         retVal = HXR_INVALID_PARAMETER;
  323.     }
  324.     return retVal;
  325. }
  326. STDMETHODIMP PXRealPixParser::Parse(IHXBuffer* pFileBuffer, BOOL bIsFinal, REF(IHXBuffer*) rpErrorText)
  327. {
  328.     HX_RESULT retVal = HXR_OK;
  329.     if (pFileBuffer)
  330.     {
  331.         if (m_pParser && m_pTagToIDMap &&
  332.             m_pAttrToIDMap && m_pLegalAttrLUT)
  333.         {
  334.             // Parse the buffer
  335.             retVal = m_pParser->Parse(pFileBuffer, bIsFinal);
  336.             if (FAILED(retVal))
  337.             {
  338.                 // If the m_bRealPixError flag is set, then this error
  339.                 // was a RealPix error as opposed to an XML error. If
  340.                 // it was a RealPix error, then m_pErrorText should already
  341.                 // contain an error string. If it was an XML error, then we
  342.                 // need to get the error string from the XML parser.
  343.                 HX_RELEASE(rpErrorText);
  344.                 if (m_bRealPixError && m_pErrorText)
  345.                 {
  346.                     // We just need to assign m_pErrorText to the output buffer
  347.                     rpErrorText = m_pErrorText;
  348.                     rpErrorText->AddRef();
  349.                 }
  350.                 else
  351.                 {
  352.                     // This was an error detected by the XML parser,
  353.                     // so we need to get the error string from the parser
  354.                     m_pParser->GetCurrentErrorText(rpErrorText);
  355.                 }
  356.             }
  357.             else
  358.             {
  359.                 // Check to make sure we have some effects.
  360.                 if (m_pRealPixFile->GetNumEffects())
  361.                 {
  362.                     // We parsed ok, so now we need to do a lot of post-parse initialization.
  363.                     retVal = m_pRealPixFile->PostParseInit();
  364.                 }
  365.                 else
  366.                 {
  367.                     HX_RELEASE(rpErrorText);
  368.                     SetError(IDS_ERR_PIX_NOEFFECTS, 0, 0, NULL, NULL, rpErrorText);
  369.                     retVal = HXR_FAIL;
  370.                 }
  371.             }
  372. //            if (bIsFinal)
  373. //            {
  374. //                m_pParser->Close();
  375. //            }
  376.         }
  377.         else
  378.         {
  379.             retVal = HXR_UNEXPECTED;
  380.         }
  381.     }
  382.     else
  383.     {
  384.         retVal = HXR_INVALID_PARAMETER;
  385.     }
  386.     return retVal;
  387. }
  388. STDMETHODIMP PXRealPixParser::HandleStartElement(const char* pName,
  389.                                                  IHXValues* pAttributes,
  390.                                                  UINT32      ulLineNumber,
  391.                                                  UINT32      ulColumnNumber)
  392. {
  393.     HX_RESULT retVal = HXR_OK;
  394.     // Check the input
  395.     if (pName && pAttributes)
  396.     {
  397.         if (m_ulState >= kStateInitialized)
  398.         {
  399.             // First look up the tag ID
  400.             UINT32 ulTagID = 0;
  401.             retVal         = GetTagIDFromName(pName, ulTagID);
  402.             if (SUCCEEDED(retVal))
  403.             {
  404.                 // Loop through the attributes, checking to make sure each one
  405.                 // is a legal attribute of this tag
  406.                 const char* pszAttr = NULL;
  407.                 IHXBuffer* pValue  = NULL;
  408.                 HX_RESULT   rv      = pAttributes->GetFirstPropertyCString(pszAttr, pValue);
  409.                 while (SUCCEEDED(rv))
  410.                 {
  411.                     if (!IsLegalAttr(ulTagID, pszAttr))
  412.                     {
  413.                         if (m_ulStrictnessLevel == REALPIX_STRICTNESS_HIGH)
  414.                         {
  415.                             retVal = HXR_FAIL;
  416.                             break;
  417.                         }
  418.                         else if (m_ulStrictnessLevel == REALPIX_STRICTNESS_MEDIUM)
  419.                         {
  420.                             IHXBuffer* pErr = NULL;
  421.                             SetError(IDS_ERR_PIX_ILLEGALATTR, ulLineNumber, ulColumnNumber, pszAttr, pName, pErr);
  422.                             ReportError(HXLOG_WARNING, HXR_OK, pErr);
  423.                             HX_RELEASE(pErr);
  424.                         }
  425.                     }
  426.                     HX_RELEASE(pValue);
  427.                     rv = pAttributes->GetNextPropertyCString(pszAttr, pValue);
  428.                 }
  429.                 HX_RELEASE(pValue);
  430.                 if (SUCCEEDED(retVal))
  431.                 {
  432.                     // Now check to see if all the REQUIRED attributes for this
  433.                     // tag are present.
  434.                     const char* pszReqAttr = NULL;
  435.                     rv                     = GetFirstRequiredAttribute(ulTagID, pszReqAttr);
  436.                     while (SUCCEEDED(rv))
  437.                     {
  438.                         // Check if this attribute is present
  439.                         IHXBuffer* pTmp = NULL;
  440.                         retVal           = pAttributes->GetPropertyCString(pszReqAttr, pTmp);
  441.                         HX_RELEASE(pTmp);
  442.                         if (FAILED(retVal))
  443.                         {
  444.                             break;
  445.                         }
  446.                         // Get the next required attribute ID
  447.                         rv = GetNextRequiredAttribute(ulTagID, pszReqAttr);
  448.                     }
  449.                     if (SUCCEEDED(retVal))
  450.                     {
  451.                         // All of the attributes were legal, and all the required
  452.                         // attributes were present, so process the tag
  453.                         retVal = ParseTag(ulTagID, pAttributes, ulLineNumber, ulColumnNumber, m_pErrorText);
  454.                         if (FAILED(retVal))
  455.                         {
  456.                             m_bRealPixError = TRUE;
  457.                         }
  458.                     }
  459.                     else
  460.                     {
  461.                         // We are missing a required attribute
  462.                         m_bRealPixError = TRUE;
  463.                         HX_RELEASE(m_pErrorText);
  464.                         SetError(IDS_ERR_PIX_MISSREQATTR, ulLineNumber, ulColumnNumber,
  465.                                  pszReqAttr, pName, m_pErrorText);
  466.                     }
  467.                 }
  468.                 else
  469.                 {
  470.                     // One of the attributes of this tag wasn't legal
  471.                     m_bRealPixError = TRUE;
  472.                     HX_RELEASE(m_pErrorText);
  473.                     SetError(IDS_ERR_PIX_ILLEGALATTR, ulLineNumber, ulColumnNumber,
  474.                              pszAttr, pName, m_pErrorText);
  475.                 }
  476.             }
  477.             else
  478.             {
  479.                 // This is not a legal tag name
  480.                 m_bRealPixError = TRUE;
  481.                 HX_RELEASE(m_pErrorText);
  482.                 SetError(IDS_ERR_PIX_UNKNOWNTAG, ulLineNumber, ulColumnNumber,
  483.                          pName, NULL, m_pErrorText);
  484.             }
  485.         }
  486.         else
  487.         {
  488.             retVal = HXR_UNEXPECTED;
  489.         }
  490.     }
  491.     else
  492.     {
  493.         retVal = HXR_INVALID_PARAMETER;
  494.     }
  495.     return retVal;
  496. }
  497. STDMETHODIMP PXRealPixParser::HandleEndElement(const char* pName,
  498.                                                UINT32      ulLineNumber,
  499.                                                UINT32      ulColumnNumber)
  500. {
  501.     HX_RESULT retVal = HXR_OK;
  502.     if (pName)
  503.     {
  504.         // Get the tag ID
  505.         UINT32 ulTagID = 0;
  506.         retVal         = GetTagIDFromName(pName, ulTagID);
  507.         if (SUCCEEDED(retVal))
  508.         {
  509.             if (ulTagID == kTagRoot)
  510.             {
  511.                 if (m_ulState == kStateSawHead)
  512.                 {
  513.                     m_ulState = kStateSawRootEnd;
  514.                 }
  515.                 else
  516.                 {
  517.                     m_bRealPixError = TRUE;
  518.                     retVal          = HXR_FAIL;
  519.                     HX_RELEASE(m_pErrorText);
  520.                     SetError(IDS_ERR_PIX_INVALIDHEAD, ulLineNumber, ulColumnNumber, NULL, NULL, m_pErrorText);
  521.                 }
  522.             }
  523.         }
  524.         else
  525.         {
  526.             // This not a known tag
  527.             m_bRealPixError = TRUE;
  528.             HX_RELEASE(m_pErrorText);
  529.             SetError(IDS_ERR_PIX_UNKNOWNTAG, ulLineNumber, ulColumnNumber,
  530.                      pName, NULL, m_pErrorText);
  531.         }
  532.     }
  533.     else
  534.     {
  535.         retVal = HXR_INVALID_PARAMETER;
  536.     }
  537.     return retVal;
  538. }
  539. STDMETHODIMP PXRealPixParser::HandleCharacterData(IHXBuffer* pBuffer,
  540.                                                   UINT32      ulLineNumber,
  541.                                                   UINT32      ulColumnNumber)
  542. {
  543.     HX_RESULT retVal = HXR_OK;
  544.     return retVal;
  545. }
  546. STDMETHODIMP PXRealPixParser::HandleProcessingInstruction(const char* pTarget,
  547.                                                           IHXValues* pAttributes,
  548.                                                           UINT32      ulLineNumber,
  549.                                                           UINT32      ulColumnNumber)
  550. {
  551.     HX_RESULT retVal = HXR_OK;
  552.     return retVal;
  553. }
  554. STDMETHODIMP PXRealPixParser::HandleUnparsedEntityDecl(const char* pEntityName,
  555.                                                        const char* pSystemID,
  556.                                                        const char* pPublicID,
  557.                                                        const char* pNotationName,
  558.                                                        UINT32      ulLineNumber,
  559.                                                        UINT32      ulColumnNumber)
  560. {
  561.     HX_RESULT retVal = HXR_OK;
  562.     return retVal;
  563. }
  564. STDMETHODIMP PXRealPixParser::HandleNotationDecl(const char* pNotationName,
  565.                                                  const char* pSystemID,
  566.                                                  const char* pPublicID,
  567.                                                  UINT32      ulLineNumber,
  568.                                                  UINT32      ulColumNumber)
  569. {
  570.     HX_RESULT retVal = HXR_OK;
  571.     return retVal;
  572. }
  573. STDMETHODIMP PXRealPixParser::HandleComment(const char* pComment,
  574.                                             UINT32      ulLineNumber,
  575.                                             UINT32      ulColumnNumber)
  576. {
  577.     HX_RESULT retVal = HXR_OK;
  578.     return retVal;
  579. }
  580. STDMETHODIMP PXRealPixParser::HandleUnparsedDoctypeDecl(const char* pDoctype,
  581.                                                         const char* pSystemID,
  582.                                                         const char* pPublicID,
  583.                                                         UINT32      ulLineNumber,
  584.                                                         UINT32      ulColumnNumber)
  585. {
  586.     HX_RESULT retVal = HXR_OK;
  587.     return retVal;
  588. }
  589. STDMETHODIMP PXRealPixParser::HandleDefault(IHXBuffer* pBuffer,
  590.                                             UINT32      ulLineNumber,
  591.                                             UINT32      ulColumnNumber)
  592. {
  593.     HX_RESULT retVal = HXR_OK;
  594.     return retVal;
  595. }
  596. HX_RESULT PXRealPixParser::SetError(UINT32 ulErrorID, UINT32 ulLine, UINT32 ulCol,
  597.                                     const char* pszArg1, const char* pszArg2,
  598.                                     REF(IHXBuffer*) rpErrStr)
  599. {
  600.     HX_RESULT retVal = HXR_OK;
  601.     const char* pszFileName = NULL;
  602.     if (m_pRealPixFile)
  603.     {
  604.         pszFileName = m_pRealPixFile->GetFileName();
  605.     }
  606.     PXError cErr(m_pContext);
  607.     if (pszFileName)
  608.     {
  609.         retVal = cErr.SetError(pszFileName, ulErrorID, ulLine, ulCol, pszArg1, pszArg2, rpErrStr);
  610.     }
  611.     else
  612.     {
  613.         retVal = cErr.SetError(ulErrorID, ulLine, ulCol, pszArg1, pszArg2, rpErrStr);
  614.     }
  615.     return retVal;
  616. }
  617. HX_RESULT PXRealPixParser::ParseTag(UINT32 ulTagID, IHXValues* pAttr, UINT32 ulLine,
  618.                                     UINT32 ulCol, REF(IHXBuffer*) rpError)
  619. {
  620.     HX_RESULT retVal = HXR_OK;
  621.     // Clear out any present error string
  622.     HX_RELEASE(rpError);
  623.     switch(ulTagID)
  624.     {
  625.         case kTagRoot:
  626.             {
  627.                 if (m_ulState == kStateInitialized)
  628.                 {
  629.                     m_ulState = kStateSawRootStart;
  630.                 }
  631.                 else
  632.                 {
  633.                     SetError(IDS_ERR_PIX_ROOTNOTFIRST, ulLine, ulCol, NULL, NULL, rpError);
  634.                     retVal = HXR_FAIL;
  635.                 }
  636.             }
  637.             break;
  638.         case kTagHead:
  639.             {
  640.                 if (m_ulState == kStateInitialized)
  641.                 {
  642.                     SetError(IDS_ERR_PIX_ROOTNOTFIRST, ulLine, ulCol, NULL, NULL, rpError);
  643.                     retVal = HXR_FAIL;
  644.                 }
  645.                 else if (m_ulState == kStateSawRootStart)
  646.                 {
  647.                     // Process head here
  648.                     retVal = ParseHeadTag(pAttr, ulLine, ulCol, rpError);
  649.                     if (SUCCEEDED(retVal))
  650.                     {
  651.                         // Set the next state
  652.                         m_ulState = kStateSawHead;
  653.                     }
  654.                 }
  655.                 else
  656.                 {
  657.                     SetError(IDS_ERR_PIX_HEADNOTFIRST, ulLine, ulCol, NULL, NULL, rpError);
  658.                     retVal = HXR_FAIL;
  659.                 }
  660.             }
  661.             break;
  662.         case kTagImage:
  663.             {
  664.                 if (m_ulState == kStateInitialized)
  665.                 {
  666.                     SetError(IDS_ERR_PIX_ROOTNOTFIRST, ulLine, ulCol, NULL, NULL, rpError);
  667.                     retVal = HXR_FAIL;
  668.                 }
  669.                 else if (m_ulState == kStateSawRootStart)
  670.                 {
  671.                     SetError(IDS_ERR_PIX_HEADNOTFIRST, ulLine, ulCol, NULL, NULL, rpError);
  672.                     retVal = HXR_FAIL;
  673.                 }
  674.                 else if (m_ulState == kStateSawHead)
  675.                 {
  676.                     retVal = ParseImageTag(pAttr, ulLine, ulCol, rpError);
  677.                 }
  678.             }
  679.             break;
  680.         case kTagFill:
  681.         case kTagFadein:
  682.         case kTagCrossfade:
  683.         case kTagFadeout:
  684.         case kTagWipe:
  685.         case kTagAnimate:
  686.         case kTagViewchange:
  687.         case kTagEffect:
  688.             {
  689.                 if (m_ulState == kStateInitialized)
  690.                 {
  691.                     SetError(IDS_ERR_PIX_ROOTNOTFIRST, ulLine, ulCol, NULL, NULL, rpError);
  692.                     retVal = HXR_FAIL;
  693.                 }
  694.                 else if (m_ulState == kStateSawRootStart)
  695.                 {
  696.                     SetError(IDS_ERR_PIX_HEADNOTFIRST, ulLine, ulCol, NULL, NULL, rpError);
  697.                     retVal = HXR_FAIL;
  698.                 }
  699.                 else if (m_ulState == kStateSawHead)
  700.                 {
  701.                     retVal = ParseEffectTag(ulTagID, pAttr, ulLine, ulCol, rpError);
  702.                 }
  703.             }
  704.             break;
  705.     }
  706.     return retVal;
  707. }
  708. HX_RESULT PXRealPixParser::ParseHeadTag(IHXValues* pAttr, UINT32 ulLine, UINT32 ulCol,
  709.                                         REF(IHXBuffer*) rpError)
  710. {
  711.     HX_RESULT retVal = HXR_OK;
  712.     if (pAttr)
  713.     {
  714.         // First we check the content version attribute
  715.         const char* pszAttr = NULL;
  716.         IHXBuffer* pValue  = NULL;
  717.         GetAttributeNameFromID(kAttrVersion, pszAttr);
  718.         HX_RESULT rv        = pAttr->GetPropertyCString(pszAttr, pValue);
  719.         if (SUCCEEDED(rv))
  720.         {
  721.             UINT32 ulTmp = 0;
  722.             retVal       = ConvertVersionValue(pValue, ulTmp);
  723.             if (SUCCEEDED(retVal))
  724.             {
  725.                 if (ulTmp <= m_ulHighestSupportedContentVersion)
  726.                 {
  727.                     m_pRealPixFile->SetContentVersion(ulTmp);
  728.                     m_bVersionSpecified = TRUE;
  729.                 }
  730.                 else
  731.                 {
  732.                     SetError(IDS_ERR_PIX_FUTUREVERSION, ulLine, ulCol, (const char*) pValue->GetBuffer(), NULL, rpError);
  733.                     retVal = HXR_FAIL;
  734.                 }
  735.             }
  736.             else
  737.             {
  738.                 SetError(IDS_ERR_PIX_NULLVERSION, ulLine, ulCol, NULL, NULL, rpError);
  739.             }
  740.         }
  741.         else
  742.         {
  743.             // Set the default to 0.0.0.0
  744.             m_pRealPixFile->SetContentVersion(0);
  745.             m_bVersionSpecified = FALSE;
  746.         }
  747.         HX_RELEASE(pValue);
  748.         // Next we get the timeformat property in order to be able to
  749.         // correctly interpret time values
  750.         if (SUCCEEDED(retVal))
  751.         {
  752.             GetAttributeNameFromID(kAttrTimeformat, pszAttr);
  753.             rv = pAttr->GetPropertyCString(pszAttr, pValue);
  754.             if (SUCCEEDED(rv))
  755.             {
  756.                 if (!strcmp((const char*) pValue->GetBuffer(), "dd:hh:mm:ss.xyz"))
  757.                 {
  758.                     // Set timeformat to days/hours/minutes/seconds
  759.                     m_pRealPixFile->SetTimeFormat(PXRealPixFile::kTimeFormatDHMS);
  760.                 }
  761.                 else if (!strcmp((const char*) pValue->GetBuffer(), "milliseconds"))
  762.                 {
  763.                     // default is milliseconds
  764.                     m_pRealPixFile->SetTimeFormat(PXRealPixFile::kTimeFormatMilliseconds);
  765.                 }
  766.                 else
  767.                 {
  768.                     // Unknown time format
  769.                     SetError(IDS_ERR_PIX_BADTIMEFORMAT, ulLine, ulCol, (const char*) pValue->GetBuffer(), NULL, rpError);
  770.                     retVal = HXR_FAIL;
  771.                 }
  772.             }
  773.             else
  774.             {
  775.                 // No timeformat specified, so set to default of milliseconds
  776.                 m_pRealPixFile->SetTimeFormat(PXRealPixFile::kTimeFormatMilliseconds);
  777.             }
  778.             HX_RELEASE(pValue);
  779.             // Now loop through the attributes of the head tag
  780.             const char* pszName = NULL;
  781.             rv                  = pAttr->GetFirstPropertyCString(pszName, pValue);
  782.             while (SUCCEEDED(rv) && SUCCEEDED(retVal))
  783.             {
  784.                 // Get the attribute ID
  785.                 UINT32 ulAttrID = kNumAttr;
  786.                 GetAttributeIDFromName(pszName, ulAttrID);
  787.                 UINT32 ulMinVer = BASE_VERSION;
  788.                 switch (ulAttrID)
  789.                 {
  790.                     case kAttrTitle:
  791.                         {
  792.                             retVal = CheckStringContents(pValue);
  793.                             if (SUCCEEDED(retVal))
  794.                             {
  795.                                 retVal = m_pRealPixFile->SetTitle(pValue);
  796.                             }
  797.                             if (FAILED(retVal))
  798.                             {
  799.                                 SetError(IDS_ERR_PIX_NULLTITLE, ulLine, ulCol, NULL, NULL, rpError);
  800.                             }
  801.                         }
  802.                         break;
  803.                     case kAttrAuthor:
  804.                         {
  805.                             retVal = CheckStringContents(pValue);
  806.                             if (SUCCEEDED(retVal))
  807.                             {
  808.                                 retVal = m_pRealPixFile->SetAuthor(pValue);
  809.                             }
  810.                             if (FAILED(retVal))
  811.                             {
  812.                                 SetError(IDS_ERR_PIX_NULLAUTHOR, ulLine, ulCol, NULL, NULL, rpError);
  813.                             }
  814.                         }
  815.                         break;
  816.                     case kAttrCopyright:
  817.                         {
  818.                             retVal = CheckStringContents(pValue);
  819.                             if (SUCCEEDED(retVal))
  820.                             {
  821.                                 retVal = m_pRealPixFile->SetCopyright(pValue);
  822.                             }
  823.                             if (FAILED(retVal))
  824.                             {
  825.                                 SetError(IDS_ERR_PIX_NULLCOPYRIGHT, ulLine, ulCol, NULL, NULL, rpError);
  826.                             }
  827.                         }
  828.                         break;
  829.                     case kAttrStart:
  830.                         {
  831.                             UINT32 ulTmp = 0;
  832.                             retVal       = ConvertTimeValue(pValue, m_pRealPixFile->GetTimeFormat(), ulTmp);
  833.                             if (SUCCEEDED(retVal))
  834.                             {
  835.                                 m_pRealPixFile->SetStart(ulTmp);
  836.                             }
  837.                             else
  838.                             {
  839.                                 SetError(IDS_ERR_PIX_BADSTARTTIME, ulLine, ulCol, NULL, NULL, rpError);
  840.                             }
  841.                         }
  842.                         break;
  843.                     case kAttrDuration:
  844.                         {
  845.                             UINT32 ulTmp = 0;
  846.                             retVal       = ConvertTimeValue(pValue, m_pRealPixFile->GetTimeFormat(), ulTmp);
  847.                             if (SUCCEEDED(retVal))
  848.                             {
  849.                                 m_pRealPixFile->SetDuration(ulTmp);
  850.                             }
  851.                             else
  852.                             {
  853.                                 SetError(IDS_ERR_PIX_BADDURATION, ulLine, ulCol, NULL, NULL, rpError);
  854.                             }
  855.                         }
  856.                         break;
  857.                     case kAttrPreroll:
  858.                         {
  859.                             UINT32 ulTmp = 0;
  860.                             retVal       = ConvertTimeValue(pValue, m_pRealPixFile->GetTimeFormat(), ulTmp);
  861.                             if (SUCCEEDED(retVal))
  862.                             {
  863.                                 m_pRealPixFile->SetPreroll(ulTmp);
  864.                             }
  865.                             else
  866.                             {
  867.                                 SetError(IDS_ERR_PIX_BADPREROLL, ulLine, ulCol, NULL, NULL, rpError);
  868.                             }
  869.                         }
  870.                         break;
  871.                     case kAttrBitrate:
  872.                         {
  873.                             UINT32 ulTmp = strtoul((const char*) pValue->GetBuffer(), NULL, 10);
  874.                             m_pRealPixFile->SetBitrate(ulTmp);
  875.                         }
  876.                         break;
  877.                     case kAttrWidth:
  878.                         {
  879.                             UINT32 ulTmp = strtoul((const char*) pValue->GetBuffer(), NULL, 10);
  880.                             m_pRealPixFile->SetDisplayWidth(ulTmp);
  881.                         }
  882.                         break;
  883.                     case kAttrHeight:
  884.                         {
  885.                             UINT32 ulTmp = strtoul((const char*) pValue->GetBuffer(), NULL, 10);
  886.                             m_pRealPixFile->SetDisplayHeight(ulTmp);
  887.                         }
  888.                         break;
  889.                     case kAttrMaxfps:
  890.                         {
  891.                             UINT32 ulTmp = strtoul((const char*) pValue->GetBuffer(), NULL, 10);
  892.                             m_pRealPixFile->SetDefaultMaxFps(ulTmp);
  893.                         }
  894.                         break;
  895.                     case kAttrTimeformat:
  896.                         break;
  897.                     case kAttrAspect:
  898.                         {
  899.                             BOOL bTmp = FALSE;
  900.                             retVal    = ConvertBoolValue(pValue, bTmp);
  901.                             if (SUCCEEDED(retVal))
  902.                             {
  903.                                 m_pRealPixFile->SetDefaultAspectFlag(bTmp);
  904.                             }
  905.                             else
  906.                             {
  907.                                 SetError(IDS_ERR_PIX_BADASPECTFLAG, ulLine, ulCol, NULL, NULL, rpError);
  908.                             }
  909.                         }
  910.                         break;
  911.                     case kAttrCenter:
  912.                         {
  913.                             ulMinVer = REDSTONE_VERSION;
  914.                             BOOL bTmp = FALSE;
  915.                             retVal    = ConvertBoolValue(pValue, bTmp);
  916.                             if (SUCCEEDED(retVal))
  917.                             {
  918.                                 m_pRealPixFile->SetDefaultCenterFlag(bTmp);
  919.                             }
  920.                             else
  921.                             {
  922.                                 SetError(IDS_ERR_PIX_BADCENTERFLAG, ulLine, ulCol, NULL, NULL, rpError);
  923.                             }
  924.                         }
  925.                         break;
  926.                     case kAttrUrl:
  927.                         {
  928.                             retVal = CheckStringContents(pValue);
  929.                             if (SUCCEEDED(retVal))
  930.                             {
  931.                                 retVal = m_pRealPixFile->SetDefaultURL(pValue);
  932.                             }
  933.                             if (FAILED(retVal))
  934.                             {
  935.                                 SetError(IDS_ERR_PIX_NULLURL, ulLine, ulCol, NULL, NULL, rpError);
  936.                             }
  937.                         }
  938.                         break;
  939.                     case kAttrVersion:
  940.                         break;
  941.                     case kAttrBackgroundcolor:
  942.                         {
  943.                             ulMinVer     = U2_VERSION;
  944.                             BYTE ucRed   = 0;
  945.                             BYTE ucGreen = 0;
  946.                             BYTE ucBlue  = 0;
  947.                             retVal       = ConvertColorValue(pValue, ucRed, ucGreen, ucBlue);
  948.                             if (SUCCEEDED(retVal))
  949.                             {
  950.                                 m_pRealPixFile->SetBackgroundColor(ucRed, ucGreen, ucBlue);
  951.                             }
  952.                             else
  953.                             {
  954.                                 SetError(IDS_ERR_PIX_BADBGCOLOR, ulLine, ulCol, NULL, NULL, rpError);
  955.                             }
  956.                         }
  957.                         break;
  958.                     case kAttrBackgroundOpacity:
  959.                         {
  960.                             // Set the minimum version
  961.                             ulMinVer = OPACITY_VERSION;
  962.                             // Parse the opacity
  963.                             UINT32 ulOpacity = 255;
  964.                             HXParseOpacity((const char*) pValue->GetBuffer(), ulOpacity);
  965.                             m_pRealPixFile->SetBackgroundOpacity(ulOpacity);
  966.                         }
  967.                         break;
  968.                 }
  969.                 if (SUCCEEDED(retVal))
  970.                 {
  971.                     retVal = CheckVersion(ulMinVer);
  972.                     if (SUCCEEDED(retVal))
  973.                     {
  974.                         HX_RELEASE(pValue);
  975.                         rv = pAttr->GetNextPropertyCString(pszName, pValue);
  976.                     }
  977.                     else
  978.                     {
  979.                         SetError(IDS_ERR_PIX_INCOMPATVERSION, ulLine, ulCol, (const char*) pValue->GetBuffer(), NULL, rpError);
  980.                     }
  981.                 }
  982.             }
  983.             HX_RELEASE(pValue);
  984.         }
  985.         if (SUCCEEDED(retVal))
  986.         {
  987.             // Here we check for logical (parsed OK, but conflicting values)
  988.             // kind of errors
  989.         }
  990.     }
  991.     else
  992.     {
  993.         retVal = HXR_INVALID_PARAMETER;
  994.     }
  995.     return retVal;
  996. }
  997. HX_RESULT PXRealPixParser::ParseImageTag(IHXValues* pAttr, UINT32 ulLine, UINT32 ulCol,
  998.                                          REF(IHXBuffer*) rpError)
  999. {
  1000.     HX_RESULT retVal = HXR_OK;
  1001.     if (pAttr)
  1002.     {
  1003.         // Get the handle attribute
  1004.         const char* pszAttrStr = NULL;
  1005.         IHXBuffer* pValue     = NULL;
  1006.         GetAttributeNameFromID(kAttrHandle, pszAttrStr);
  1007.         retVal = pAttr->GetPropertyCString(pszAttrStr, pValue);
  1008.         if (SUCCEEDED(retVal))
  1009.         {
  1010.             UINT32 ulHandle = strtoul((const char*) pValue->GetBuffer(), NULL, 10);
  1011.             if (ulHandle)
  1012.             {
  1013.                 // Get the name attribute
  1014.                 GetAttributeNameFromID(kAttrName, pszAttrStr);
  1015.                 HX_RELEASE(pValue);
  1016.                 retVal = pAttr->GetPropertyCString(pszAttrStr, pValue);
  1017.                 if (SUCCEEDED(retVal))
  1018.                 {
  1019.                     retVal = CheckStringContents(pValue);
  1020.                     if (SUCCEEDED(retVal))
  1021.                     {
  1022.                         if (!m_pRealPixFile->IsImagePresent(ulHandle))
  1023.                         {
  1024.                             retVal = m_pRealPixFile->AddImage(ulHandle, pValue);
  1025.                             if (SUCCEEDED(retVal))
  1026.                             {
  1027.                                 // Get the size attribute string
  1028.                                 GetAttributeNameFromID(kAttrSize, pszAttrStr);
  1029.                                 // See if we have a size attribute
  1030.                                 HX_RELEASE(pValue);
  1031.                                 HX_RESULT rv = pAttr->GetPropertyCString(pszAttrStr, pValue);
  1032.                                 if (SUCCEEDED(rv))
  1033.                                 {
  1034.                                     retVal = CheckVersion(REDSTONE_VERSION);
  1035.                                     if (SUCCEEDED(retVal))
  1036.                                     {
  1037.                                         UINT32 ulSize = strtoul((const char*) pValue->GetBuffer(), NULL, 10);
  1038.                                         if (ulSize)
  1039.                                         {
  1040.                                             retVal = m_pRealPixFile->SetImageSize(ulHandle, ulSize);
  1041.                                         }
  1042.                                         else
  1043.                                         {
  1044.                                             retVal = HXR_FAIL;
  1045.                                             SetError(IDS_ERR_PIX_ZEROSIZE, ulLine, ulCol, NULL, NULL, rpError);
  1046.                                         }
  1047.                                     }
  1048.                                     else
  1049.                                     {
  1050.                                         SetError(IDS_ERR_PIX_INCOMPATVERSION, ulLine, ulCol,
  1051.                                                  (const char*) pValue->GetBuffer(), NULL, rpError);
  1052.                                     }
  1053.                                 }
  1054.                                 // Get the mime type attribute string
  1055.                                 GetAttributeNameFromID(kAttrMime, pszAttrStr);
  1056.                                 // See if we have a mime type attribute
  1057.                                 HX_RELEASE(pValue);
  1058.                                 rv = pAttr->GetPropertyCString(pszAttrStr, pValue);
  1059.                                 if (SUCCEEDED(rv))
  1060.                                 {
  1061.                                     retVal = CheckVersion(REDSTONE_VERSION);
  1062.                                     if (SUCCEEDED(retVal))
  1063.                                     {
  1064.                                         retVal = m_pRealPixFile->SetImageFileMimeType(ulHandle, pValue);
  1065.                                     }
  1066.                                     else
  1067.                                     {
  1068.                                         SetError(IDS_ERR_PIX_INCOMPATVERSION, ulLine, ulCol,
  1069.                                                  (const char*) pValue->GetBuffer(), NULL, rpError);
  1070.                                     }
  1071.                                 }
  1072.                             }
  1073.                         }
  1074.                         else
  1075.                         {
  1076.                             retVal = HXR_FAIL;
  1077.                             SetError(IDS_ERR_PIX_DUPHANDLE, ulLine, ulCol, NULL, NULL, rpError);
  1078.                         }
  1079.                     }
  1080.                     else
  1081.                     {
  1082.                         SetError(IDS_ERR_PIX_NULLNAME, ulLine, ulCol, NULL, NULL, rpError);
  1083.                     }
  1084.                 }
  1085.                 else
  1086.                 {
  1087.                     SetError(IDS_ERR_PIX_NONAME, ulLine, ulCol, NULL, NULL, rpError);
  1088.                 }
  1089.             }
  1090.             else
  1091.             {
  1092.                 SetError(IDS_ERR_PIX_BADHANDLE, ulLine, ulCol, NULL, NULL, rpError);
  1093.                 retVal = HXR_FAIL;
  1094.             }
  1095.         }
  1096.         else
  1097.         {
  1098.             SetError(IDS_ERR_PIX_NOHANDLE, ulLine, ulCol, NULL, NULL, rpError);
  1099.         }
  1100.         HX_RELEASE(pValue);
  1101.     }
  1102.     else
  1103.     {
  1104.         retVal = HXR_INVALID_PARAMETER;
  1105.     }
  1106.     return retVal;
  1107. }
  1108. HX_RESULT PXRealPixParser::ParseEffectTag(UINT32 ulTagID, IHXValues* pAttr, UINT32 ulLine,
  1109.                                           UINT32 ulCol, REF(IHXBuffer*) rpError)
  1110. {
  1111.     HX_RESULT retVal = HXR_OK;
  1112.     if (ulTagID < kNumTags && pAttr)
  1113.     {
  1114.         // Get the tag name
  1115.         const char* pszTagName = NULL;
  1116.         GetTagNameFromID(ulTagID, pszTagName);
  1117.         // Create a PXEffect object
  1118.         PXEffect* pEffect = NULL;
  1119.         retVal            = PXEffect::CreateObject(&pEffect);
  1120.         if (SUCCEEDED(retVal))
  1121.         {
  1122.             // AddRef the object
  1123.             pEffect->AddRef();
  1124.             // Set effect type
  1125.             BYTE ucEffectType = 0;
  1126.             switch (ulTagID)
  1127.             {
  1128.                 case kTagFill:
  1129.                     ucEffectType = PXEffect::kEffectTypeFill;
  1130.                     break;
  1131.                 case kTagFadein:
  1132.                     ucEffectType = PXEffect::kEffectTypeFadeIn;
  1133.                     break;
  1134.                 case kTagFadeout:
  1135.                     ucEffectType = PXEffect::kEffectTypeFadeOut;
  1136.                     break;
  1137.                 case kTagCrossfade:
  1138.                     ucEffectType = PXEffect::kEffectTypeCrossFade;
  1139.                     break;
  1140.                 case kTagWipe:
  1141.                     ucEffectType = PXEffect::kEffectTypeWipe;
  1142.                     break;
  1143.                 case kTagViewchange:
  1144.                     ucEffectType = PXEffect::kEffectTypeViewChange;
  1145.                     break;
  1146.                 case kTagEffect:
  1147.                     ucEffectType = PXEffect::kEffectTypeExternal;
  1148.                     break;
  1149.                 case kTagAnimate:
  1150.                     ucEffectType = PXEffect::kEffectTypeAnimate;
  1151.                     break;
  1152.             }
  1153.             pEffect->SetEffectType(ucEffectType);
  1154.             // Set defaults
  1155.             pEffect->SetAspectFlag(m_pRealPixFile->GetDefaultAspectFlag());
  1156.             pEffect->SetMaxFps(m_pRealPixFile->GetDefaultMaxFps());
  1157.             pEffect->SetCenterFlag(m_pRealPixFile->GetDefaultCenterFlag());
  1158.             // Loop through the attributes
  1159.             BOOL   bThrowError      = TRUE;
  1160.             BOOL   bNeedLastTarget  = TRUE;
  1161.             BOOL   bNeedLastRects   = TRUE;
  1162.             const char* pszAttrName = NULL;
  1163.             IHXBuffer* pAttrValue  = NULL;
  1164.             HX_RESULT   rv          = pAttr->GetFirstPropertyCString(pszAttrName, pAttrValue);
  1165.             while (SUCCEEDED(rv) && SUCCEEDED(retVal))
  1166.             {
  1167.                 // Get the attribute ID. Don't need to check return value
  1168.                 // since we have already check validity of each attribute
  1169.                 UINT32 ulAttrID = 0;
  1170.                 GetAttributeIDFromName(pszAttrName, ulAttrID);
  1171.                 // Choose different action based on attribute ID
  1172.                 UINT32 ulMinVer = BASE_VERSION;
  1173.                 switch (ulAttrID)
  1174.                 {
  1175.                     case kAttrStart:
  1176.                         {
  1177.                             UINT32 ulTmp = 0;
  1178.                             retVal       = ConvertTimeValue(pAttrValue, m_pRealPixFile->GetTimeFormat(), ulTmp);
  1179.                             if (SUCCEEDED(retVal))
  1180.                             {
  1181.                                 pEffect->SetStart(ulTmp);
  1182.                             }
  1183.                         }
  1184.                         break;
  1185.                     case kAttrDuration:
  1186.                         {
  1187.                             UINT32 ulTmp = 0;
  1188.                             retVal       = ConvertTimeValue(pAttrValue, m_pRealPixFile->GetTimeFormat(), ulTmp);
  1189.                             if (SUCCEEDED(retVal))
  1190.                             {
  1191.                                 pEffect->SetDuration(ulTmp);
  1192.                             }
  1193.                         }
  1194.                         break;
  1195.                     case kAttrTarget:
  1196.                         {
  1197.                             bNeedLastTarget = FALSE;
  1198.                             UINT32 ulTmp    = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1199.                             pEffect->SetTarget(ulTmp);
  1200.                         }
  1201.                         break;
  1202.                     case kAttrSrcx:
  1203.                         {
  1204.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1205.                             pEffect->SetSrcX(ulTmp);
  1206.                         }
  1207.                         break;
  1208.                     case kAttrSrcy:
  1209.                         {
  1210.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1211.                             pEffect->SetSrcY(ulTmp);
  1212.                         }
  1213.                         break;
  1214.                     case kAttrSrcw:
  1215.                         {
  1216.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1217.                             pEffect->SetSrcWidth(ulTmp);
  1218.                         }
  1219.                         break;
  1220.                     case kAttrSrch:
  1221.                         {
  1222.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1223.                             pEffect->SetSrcHeight(ulTmp);
  1224.                         }
  1225.                         break;
  1226.                     case kAttrStartsrcx:
  1227.                         {
  1228.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1229.                             pEffect->SetStartSrcX(ulTmp);
  1230.                             bNeedLastRects = FALSE;
  1231.                             ulMinVer       = REDSTONE_VERSION;
  1232.                         }
  1233.                         break;
  1234.                     case kAttrStartsrcy:
  1235.                         {
  1236.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1237.                             pEffect->SetStartSrcY(ulTmp);
  1238.                             bNeedLastRects = FALSE;
  1239.                             ulMinVer       = REDSTONE_VERSION;
  1240.                         }
  1241.                         break;
  1242.                     case kAttrStartsrcw:
  1243.                         {
  1244.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1245.                             pEffect->SetStartSrcWidth(ulTmp);
  1246.                             bNeedLastRects = FALSE;
  1247.                             ulMinVer       = REDSTONE_VERSION;
  1248.                         }
  1249.                         break;
  1250.                     case kAttrStartsrch:
  1251.                         {
  1252.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1253.                             pEffect->SetStartSrcHeight(ulTmp);
  1254.                             bNeedLastRects = FALSE;
  1255.                             ulMinVer       = REDSTONE_VERSION;
  1256.                         }
  1257.                         break;
  1258.                     case kAttrDstx:
  1259.                         {
  1260.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1261.                             pEffect->SetDstX(ulTmp);
  1262.                         }
  1263.                         break;
  1264.                     case kAttrDsty:
  1265.                         {
  1266.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1267.                             pEffect->SetDstY(ulTmp);
  1268.                         }
  1269.                         break;
  1270.                     case kAttrDstw:
  1271.                         {
  1272.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1273.                             pEffect->SetDstWidth(ulTmp);
  1274.                         }
  1275.                         break;
  1276.                     case kAttrDsth:
  1277.                         {
  1278.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1279.                             pEffect->SetDstHeight(ulTmp);
  1280.                         }
  1281.                         break;
  1282.                     case kAttrStartdstx:
  1283.                         {
  1284.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1285.                             pEffect->SetStartDstX(ulTmp);
  1286.                             bNeedLastRects = FALSE;
  1287.                             ulMinVer       = REDSTONE_VERSION;
  1288.                         }
  1289.                         break;
  1290.                     case kAttrStartdsty:
  1291.                         {
  1292.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1293.                             pEffect->SetStartDstY(ulTmp);
  1294.                             bNeedLastRects = FALSE;
  1295.                             ulMinVer       = REDSTONE_VERSION;
  1296.                         }
  1297.                         break;
  1298.                     case kAttrStartdstw:
  1299.                         {
  1300.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1301.                             pEffect->SetStartDstWidth(ulTmp);
  1302.                             bNeedLastRects = FALSE;
  1303.                             ulMinVer       = REDSTONE_VERSION;
  1304.                         }
  1305.                         break;
  1306.                     case kAttrStartdsth:
  1307.                         {
  1308.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1309.                             pEffect->SetDstHeight(ulTmp);
  1310.                             bNeedLastRects = FALSE;
  1311.                             ulMinVer       = REDSTONE_VERSION;
  1312.                         }
  1313.                         break;
  1314.                     case kAttrUrl:
  1315.                         {
  1316.                             retVal = CheckStringContents(pAttrValue);
  1317.                             if (SUCCEEDED(retVal))
  1318.                             {
  1319.                                 pEffect->SetURL((const char*) pAttrValue->GetBuffer());
  1320.                             }
  1321.                             else
  1322.                             {
  1323.                                 if (m_ulStrictnessLevel == REALPIX_STRICTNESS_LOW ||
  1324.                                     m_ulStrictnessLevel == REALPIX_STRICTNESS_MEDIUM)
  1325.                                 {
  1326.                                     bThrowError = FALSE;
  1327.                                 }
  1328.                             }
  1329.                         }
  1330.                         break;
  1331.                     case kAttrMaxfps:
  1332.                         {
  1333.                             UINT32 ulTmp = strtoul((const char*) pAttrValue->GetBuffer(), NULL, 10);
  1334.                             pEffect->SetMaxFps(ulTmp);
  1335.                         }
  1336.                         break;
  1337.                     case kAttrAspect:
  1338.                         {
  1339.                             BOOL bTmp = FALSE;
  1340.                             retVal    = ConvertBoolValue(pAttrValue, bTmp);
  1341.                             if (SUCCEEDED(retVal))
  1342.                             {
  1343.                                 pEffect->SetAspectFlag(bTmp);
  1344.                             }
  1345.                         }
  1346.                         break;
  1347.                     case kAttrCenter:
  1348.                         {
  1349.                             BOOL bTmp = FALSE;
  1350.                             retVal    = ConvertBoolValue(pAttrValue, bTmp);
  1351.                             if (SUCCEEDED(retVal))
  1352.                             {
  1353.                                 pEffect->SetCenterFlag(bTmp);
  1354.                                 ulMinVer = REDSTONE_VERSION;
  1355.                             }
  1356.                         }
  1357.                         break;
  1358.                     case kAttrBackgroundcolor:
  1359.                         ulMinVer = REDSTONE_VERSION;
  1360.                     case kAttrColor:
  1361.                         {
  1362.                             BYTE ucRed   = 0;
  1363.                             BYTE ucGreen = 0;
  1364.                             BYTE ucBlue  = 0;
  1365.                             retVal       = ConvertColorValue(pAttrValue, ucRed, ucGreen, ucBlue);
  1366.                             if (SUCCEEDED(retVal))
  1367.                             {
  1368.                                 pEffect->SetColor(ucRed, ucGreen, ucBlue);
  1369.                             }
  1370.                         }
  1371.                         break;
  1372.                     case kAttrDirection:
  1373.                         {
  1374.                             BYTE ucTmp = 0;
  1375.                             retVal     = ConvertWipeDirectionValue(pAttrValue, ucTmp);
  1376.                             if (SUCCEEDED(retVal))
  1377.                             {
  1378.                                 pEffect->SetWipeDirection(ucTmp);
  1379.                             }
  1380.                         }
  1381.                         break;
  1382.                     case kAttrType:
  1383.                         {
  1384.                             BYTE ucTmp = 0;
  1385.                             retVal     = ConvertWipeTypeValue(pAttrValue, ucTmp);
  1386.                             if (SUCCEEDED(retVal))
  1387.                             {
  1388.                                 pEffect->SetWipeType(ucTmp);
  1389.                             }
  1390.                         }
  1391.                         break;
  1392.                     case kAttrPackage:
  1393.                         {
  1394.                             retVal = CheckStringContents(pAttrValue);
  1395.                             if (SUCCEEDED(retVal))
  1396.                             {
  1397.                                 pEffect->SetExFxPackage((const char*) pAttrValue->GetBuffer());
  1398.                             }
  1399.                         }
  1400.                         break;
  1401.                     case kAttrName:
  1402.                         {
  1403.                             retVal = CheckStringContents(pAttrValue);
  1404.                             if (SUCCEEDED(retVal))
  1405.                             {
  1406.                                 pEffect->SetExFxName((const char*) pAttrValue->GetBuffer());
  1407.                             }
  1408.                         }
  1409.                         break;
  1410.                     case kAttrData:
  1411.                         {
  1412.                             retVal = CheckStringContents(pAttrValue);
  1413.                             if (SUCCEEDED(retVal))
  1414.                             {
  1415.                                 pEffect->SetExFxData((const char*) pAttrValue->GetBuffer());
  1416.                             }
  1417.                         }
  1418.                         break;
  1419.                     case kAttrFile:
  1420.                         {
  1421.                             retVal = CheckStringContents(pAttrValue);
  1422.                             if (SUCCEEDED(retVal))
  1423.                             {
  1424.                                 pEffect->SetExFxFile((const char*) pAttrValue->GetBuffer());
  1425.                             }
  1426.                         }
  1427.                         break;
  1428.                 }
  1429.                 if (SUCCEEDED(retVal) ||
  1430.                     (FAILED(retVal) && !bThrowError))
  1431.                 {
  1432.                     if (FAILED(retVal))
  1433.                     {
  1434.                         if (m_ulStrictnessLevel >= REALPIX_STRICTNESS_MEDIUM)
  1435.                         {
  1436.                             // We detected bad syntax but were told not to throw an error,
  1437.                             // so we will log a warning instead.
  1438.                             IHXBuffer* pErr = NULL;
  1439.                             SetError(IDS_ERR_PIX_BADATTRVALUE, ulLine, ulCol, pszAttrName, pszTagName, pErr);
  1440.                             ReportError(HXLOG_WARNING, HXR_OK, pErr);
  1441.                             HX_RELEASE(pErr);
  1442.                         }
  1443.                     }
  1444.                     retVal = CheckVersion(ulMinVer);
  1445.                     if (SUCCEEDED(retVal))
  1446.                     {
  1447.                         // Get the next attribute
  1448.                         HX_RELEASE(pAttrValue);
  1449.                         if (SUCCEEDED(retVal))
  1450.                         {
  1451.                             rv = pAttr->GetNextPropertyCString(pszAttrName, pAttrValue);
  1452.                         }
  1453.                     }
  1454.                     else
  1455.                     {
  1456.                         SetError(IDS_ERR_PIX_INCOMPATVERSION, ulLine, ulCol, (const char*) pAttrValue->GetBuffer(), NULL, rpError);
  1457.                     }
  1458.                 }
  1459.                 else
  1460.                 {
  1461.                     SetError(IDS_ERR_PIX_BADATTRVALUE, ulLine, ulCol, pszAttrName, pszTagName, rpError);
  1462.                 }
  1463.             }
  1464.             HX_RELEASE(pAttrValue);
  1465.             if (SUCCEEDED(retVal))
  1466.             {
  1467.                 // Here we do the hack to make sure that viewchange effects get the proper target
  1468.                 if (pEffect->GetEffectType() == PXEffect::kEffectTypeViewChange &&
  1469.                     pEffect->GetTarget()     == 0                               &&
  1470.                     m_pLastEffect                                               &&
  1471.                     bNeedLastTarget)
  1472.                 {
  1473.                     if (m_pLastEffect->HasTarget())
  1474.                     {
  1475.                         pEffect->SetTarget(m_pLastEffect->GetTarget());
  1476.                     }
  1477.                 }
  1478.                 // Here we do the hack to make sure that viewchange effects get the proper start rects
  1479.                 if (pEffect->GetEffectType() == PXEffect::kEffectTypeViewChange &&
  1480.                     m_pLastEffect                                               &&
  1481.                     bNeedLastRects)
  1482.                 {
  1483.                     if (m_pLastEffect->HasTarget())
  1484.                     {
  1485.                         pEffect->SetStartSrcRect(m_pLastEffect->GetSrcRect());
  1486.                     }
  1487.                     pEffect->SetStartDstRect(m_pLastEffect->GetDstRect());
  1488.                 }
  1489.                 // Part of the hack requires we save the last effect
  1490.                 HX_RELEASE(m_pLastEffect);
  1491.                 m_pLastEffect = pEffect;
  1492.                 m_pLastEffect->AddRef();
  1493.                 // Set the dst width and height if they defaulted to zero.
  1494.                 if (!pEffect->GetDstWidth())
  1495.                 {
  1496.                     pEffect->SetDstWidth(m_pRealPixFile->GetDisplayWidth());
  1497.                 }
  1498.                 if (!pEffect->GetDstHeight())
  1499.                 {
  1500.                     pEffect->SetDstHeight(m_pRealPixFile->GetDisplayHeight());
  1501.                 }
  1502.                 if (!pEffect->GetStartDstWidth())
  1503.                 {
  1504.                     pEffect->SetStartDstWidth(m_pRealPixFile->GetDisplayWidth());
  1505.                 }
  1506.                 if (!pEffect->GetStartDstHeight())
  1507.                 {
  1508.                     pEffect->SetStartDstHeight(m_pRealPixFile->GetDisplayHeight());
  1509.                 }
  1510.                 // Do some error checking on dst rect
  1511.                 if (pEffect->GetDstX()      + pEffect->GetDstWidth()       > m_pRealPixFile->GetDisplayWidth()  ||
  1512.                     pEffect->GetDstY()      + pEffect->GetDstHeight()      > m_pRealPixFile->GetDisplayHeight() ||
  1513.                     pEffect->GetStartDstX() + pEffect->GetStartDstWidth()  > m_pRealPixFile->GetDisplayWidth()  ||
  1514.                     pEffect->GetStartDstY() + pEffect->GetStartDstHeight() > m_pRealPixFile->GetDisplayHeight())
  1515.                 {
  1516.                     if (m_ulStrictnessLevel == REALPIX_STRICTNESS_HIGH)
  1517.                     {
  1518.                         SetError(IDS_ERR_PIX_BADDSTRECT, ulLine, ulCol, NULL, NULL, rpError);
  1519.                         retVal = HXR_FAIL;
  1520.                     }
  1521.                     else if (m_ulStrictnessLevel == REALPIX_STRICTNESS_MEDIUM)
  1522.                     {
  1523.                         IHXBuffer* pErr = NULL;
  1524.                         SetError(IDS_ERR_PIX_BADDSTRECT, ulLine, ulCol, NULL, NULL, pErr);
  1525.                         ReportError(HXLOG_WARNING, HXR_OK, pErr);
  1526.                         HX_RELEASE(pErr);
  1527.                     }
  1528.                 }
  1529.                 if (SUCCEEDED(retVal))
  1530.                 {
  1531.                     // Add the effect to the file
  1532.                     retVal = m_pRealPixFile->AddEffect(pEffect);
  1533.                 }
  1534.             }
  1535.         }
  1536.         HX_RELEASE(pEffect);
  1537.     }
  1538.     else
  1539.     {
  1540.         retVal = HXR_INVALID_PARAMETER;
  1541.     }
  1542.     return retVal;
  1543. }
  1544. HX_RESULT PXRealPixParser::SetupLegalAttrLUT()
  1545. {
  1546.     HX_RESULT retVal = HXR_OK;
  1547.     // Create the LUT IHXBuffer
  1548.     HX_RELEASE(m_pLegalAttrLUT);
  1549.     retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer,
  1550.                                                    (void**) &m_pLegalAttrLUT);
  1551.     if (SUCCEEDED(retVal))
  1552.     {
  1553.         // Set the size
  1554.         retVal = m_pLegalAttrLUT->SetSize(kNumTags * kNumAttr);
  1555.         if (SUCCEEDED(retVal))
  1556.         {
  1557.             // Zero it out
  1558.             BYTE* pLUT = m_pLegalAttrLUT->GetBuffer();
  1559.             memset(pLUT, 0, m_pLegalAttrLUT->GetSize());
  1560.             // Now fill it in - we advance through the list
  1561.             // until we see kNumTags, which marks the end
  1562.             BYTE* pAttrList = (BYTE*) m_pAttrList;
  1563.             while (*pAttrList < kNumTags)
  1564.             {
  1565.                 // Get the tag and advance to attribute list
  1566.                 UINT32 ulTag = *pAttrList++;
  1567.                 // Advance through the attribute list until
  1568.                 // we see a kNumAttr, which marks the end
  1569.                 // of the list
  1570.                 while (*pAttrList < kNumAttr)
  1571.                 {
  1572.                     // Get the attribute
  1573.                     UINT32 ulAttr = *pAttrList++;
  1574.                     // Set the value in the LUT to 1
  1575.                     pLUT[ulTag * kNumAttr + ulAttr] = 1;
  1576.                 }
  1577.                 // Advance to next tag
  1578.                 pAttrList++;
  1579.             }
  1580.         }
  1581.     }
  1582.     return retVal;
  1583. }
  1584. HX_RESULT PXRealPixParser::SetupIDMaps()
  1585. {
  1586.     HX_RESULT retVal = HXR_OK;
  1587.     // Create the tag map object
  1588.     HX_DELETE(m_pTagToIDMap);
  1589.     m_pTagToIDMap = new CHXMapStringToOb();
  1590.     if (m_pTagToIDMap)
  1591.     {
  1592.         // Go through the tag string list
  1593.         PXStringTable* pStr = (PXStringTable*) m_pTagTable;
  1594.         while (pStr->m_ulStringID < kNumTags)
  1595.         {
  1596.             m_pTagToIDMap->SetAt(pStr->m_pszString, (void*) pStr->m_ulStringID);
  1597.             pStr++;
  1598.         }
  1599.         // Create the attribute map object
  1600.         HX_DELETE(m_pAttrToIDMap);
  1601.         m_pAttrToIDMap = new CHXMapStringToOb();
  1602.         if (m_pAttrToIDMap)
  1603.         {
  1604.             // Go through the attribute string list
  1605.             pStr = (PXStringTable*) m_pAttrTable;
  1606.             while (pStr->m_ulStringID < kNumAttr)
  1607.             {
  1608.                 m_pAttrToIDMap->SetAt(pStr->m_pszString, (void*) pStr->m_ulStringID);
  1609.                 pStr++;
  1610.             }
  1611.         }
  1612.         else
  1613.         {
  1614.             retVal = HXR_OUTOFMEMORY;
  1615.         }
  1616.     }
  1617.     else
  1618.     {
  1619.         retVal = HXR_OUTOFMEMORY;
  1620.     }
  1621.     return retVal;
  1622. }
  1623. BOOL PXRealPixParser::IsLegalAttr(UINT32 ulTagID, const char* pszAttr)
  1624. {
  1625.     BOOL bLegal = FALSE;
  1626.     if (m_pAttrToIDMap && m_pLegalAttrLUT &&
  1627.         pszAttr && ulTagID < kNumTags)
  1628.     {
  1629.         // Lookup attribute ID from string map. If it's
  1630.         // not in the string map, then it can't be legal
  1631.         void* pVoid    = NULL;
  1632.         BOOL  bPresent = m_pAttrToIDMap->Lookup(pszAttr, pVoid);
  1633.         if (bPresent)
  1634.         {
  1635.             // Get the ID
  1636.             UINT32 ulAttrID = (UINT32) pVoid;
  1637.             // See if there's a non-zero value in the legal attr LUT
  1638.             BYTE *pLUT = m_pLegalAttrLUT->GetBuffer();
  1639.             if (pLUT[ulTagID * kNumAttr + ulAttrID])
  1640.             {
  1641.                 bLegal = TRUE;
  1642.             }
  1643.         }
  1644.     }
  1645.     return bLegal;
  1646. }
  1647. HX_RESULT PXRealPixParser::GetTagNameFromID(UINT32 ulTagID, REF(const char*) rpszTag)
  1648. {
  1649.     HX_RESULT retVal = HXR_OK;
  1650.     PXStringTable* pTable = (PXStringTable*) m_pTagTable;
  1651.     BOOL           bFound = FALSE;
  1652.     while (pTable->m_ulStringID < kNumTags)
  1653.     {
  1654.         if (pTable->m_ulStringID == ulTagID)
  1655.         {
  1656.             bFound = TRUE;
  1657.             break;
  1658.         }
  1659.         pTable++;
  1660.     }
  1661.     if (bFound)
  1662.     {
  1663.         rpszTag = pTable->m_pszString;
  1664.     }
  1665.     else
  1666.     {
  1667.         retVal = HXR_FAIL;
  1668.     }
  1669.     return retVal;
  1670. }
  1671. HX_RESULT PXRealPixParser::GetTagIDFromName(const char* pszTag, REF(UINT32) rulTagID)
  1672. {
  1673.     HX_RESULT retVal = HXR_FAIL;
  1674.     if (m_pTagToIDMap)
  1675.     {
  1676.         void* pVoid    = NULL;
  1677.         BOOL  bPresent = m_pTagToIDMap->Lookup(pszTag, pVoid);
  1678.         if (bPresent)
  1679.         {
  1680.             retVal   = HXR_OK;
  1681.             rulTagID = (UINT32) pVoid;
  1682.         }
  1683.     }
  1684.     return retVal;
  1685. }
  1686. HX_RESULT PXRealPixParser::GetAttributeNameFromID(UINT32 ulAttrID, REF(const char*) rpszAttr)
  1687. {
  1688.     HX_RESULT retVal = HXR_OK;
  1689.     PXStringTable* pTable = (PXStringTable*) m_pAttrTable;
  1690.     BOOL           bFound = FALSE;
  1691.     while (pTable->m_ulStringID < kNumAttr)
  1692.     {
  1693.         if (pTable->m_ulStringID == ulAttrID)
  1694.         {
  1695.             bFound = TRUE;
  1696.             break;
  1697.         }
  1698.         pTable++;
  1699.     }
  1700.     if (bFound)
  1701.     {
  1702.         rpszAttr = pTable->m_pszString;
  1703.     }
  1704.     else
  1705.     {
  1706.         retVal = HXR_FAIL;
  1707.     }
  1708.     return retVal;
  1709. }
  1710. HX_RESULT PXRealPixParser::GetAttributeIDFromName(const char* pszAttr, REF(UINT32) rulAttrID)
  1711. {
  1712.     HX_RESULT retVal = HXR_FAIL;
  1713.     if (m_pAttrToIDMap)
  1714.     {
  1715.         void* pVoid    = NULL;
  1716.         BOOL  bPresent = m_pAttrToIDMap->Lookup(pszAttr, pVoid);
  1717.         if (bPresent)
  1718.         {
  1719.             retVal    = HXR_OK;
  1720.             rulAttrID = (UINT32) pVoid;
  1721.         }
  1722.     }
  1723.     return retVal;
  1724. }
  1725. HX_RESULT PXRealPixParser::GetFirstRequiredAttribute(UINT32 ulTagID, REF(const char*) rpszAttr)
  1726. {
  1727.     HX_RESULT retVal = HXR_OK;
  1728.     // Make sure this is a valid ID
  1729.     if (ulTagID < kNumTags)
  1730.     {
  1731.         // First, find the tag ID in the list
  1732.         BYTE* pList = (BYTE*) m_pRequiredAttrList;
  1733.         while ((UINT32) *pList != ulTagID)
  1734.         {
  1735.             // Advance into the attribute list
  1736.             pList++;
  1737.             // Search for end of attribute list
  1738.             while (*pList < kNumAttr)
  1739.             {
  1740.                 pList++;
  1741.             }
  1742.             // Advance to next tag
  1743.             pList++;
  1744.         }
  1745.         // Advance to first required attribute
  1746.         pList++;
  1747.         // If we are already at the end of the attribute
  1748.         // list, then there are no required attributes for
  1749.         // this tag, so we fail.
  1750.         if (*pList < kNumAttr)
  1751.         {
  1752.             retVal = GetAttributeNameFromID((UINT32) *pList, rpszAttr);
  1753.             if (SUCCEEDED(retVal))
  1754.             {
  1755.                 // Set the state variable
  1756.                 m_pByteListCursor = pList;
  1757.             }
  1758.         }
  1759.         else
  1760.         {
  1761.             retVal = HXR_FAIL;
  1762.         }
  1763.     }
  1764.     else
  1765.     {
  1766.         retVal = HXR_FAIL;
  1767.     }
  1768.     return retVal;
  1769. }
  1770. HX_RESULT PXRealPixParser::GetNextRequiredAttribute(UINT32 ulTagID, REF(const char*) rpszAttr)
  1771. {
  1772.     HX_RESULT retVal = HXR_OK;
  1773.     if (ulTagID < kNumTags && m_pByteListCursor)
  1774.     {
  1775.         // Advance to the next required attribute
  1776.         m_pByteListCursor++;
  1777.         // Check to see if we're at the end of the list
  1778.         if (*m_pByteListCursor < kNumAttr)
  1779.         {
  1780.             retVal = GetAttributeNameFromID((UINT32) *m_pByteListCursor, rpszAttr);
  1781.         }
  1782.         else
  1783.         {
  1784.             m_pByteListCursor = NULL;
  1785.             retVal            = HXR_FAIL;
  1786.         }
  1787.     }
  1788.     else
  1789.     {
  1790.         retVal = HXR_FAIL;
  1791.     }
  1792.     return retVal;
  1793. }
  1794. HX_RESULT PXRealPixParser::CheckStringContents(IHXBuffer* pString)
  1795. {
  1796.     HX_RESULT retVal = HXR_FAIL;
  1797.     if (pString)
  1798.     {
  1799.         const char* pszStr = (const char*) pString->GetBuffer();
  1800.         if (pszStr)
  1801.         {
  1802.             UINT32 ulLen = (UINT32) strlen(pszStr);
  1803.             if (ulLen > 0 && strspn(pszStr, " rnt") < ulLen)
  1804.             {
  1805.                 retVal = HXR_OK;
  1806.             }
  1807.         }
  1808.     }
  1809.     return retVal;
  1810. }
  1811. HX_RESULT PXRealPixParser::ConvertTimeValue(IHXBuffer* pValue, UINT32 ulTimeFormat, REF(UINT32) ulTime)
  1812. {
  1813.     HX_RESULT retVal = HXR_OK;
  1814.     if (ulTimeFormat == PXRealPixFile::kTimeFormatDHMS)
  1815.     {
  1816.         BOOL bRet = ConvertTimeStringToULONG32((char*) pValue->GetBuffer(),
  1817.                                                strlen((const char*) pValue->GetBuffer()),
  1818.                                                ulTime);
  1819.         if (!bRet)
  1820.         {
  1821.             retVal = HXR_FAIL;
  1822.         }
  1823.     }
  1824.     else
  1825.     {
  1826.         ulTime = strtoul((const char*) pValue->GetBuffer(), NULL, 10);
  1827.     }
  1828.     return retVal;
  1829. }
  1830. HX_RESULT PXRealPixParser::ConvertBoolValue(IHXBuffer* pValue, REF(BOOL) rbValue)
  1831. {
  1832.     HX_RESULT retVal = HXR_FAIL;
  1833.     if (pValue)
  1834.     {
  1835.         const char* pszValue = (const char*) pValue->GetBuffer();
  1836.         if (!strcmp(pszValue, "true"))
  1837.         {
  1838.             rbValue = TRUE;
  1839.             retVal  = HXR_OK;
  1840.         }
  1841.         else if (!strcmp(pszValue, "false"))
  1842.         {
  1843.             rbValue = FALSE;
  1844.             retVal  = HXR_OK;
  1845.         }
  1846.     }
  1847.     return retVal;
  1848. }
  1849. HX_RESULT PXRealPixParser::ConvertVersionValue(IHXBuffer* pValue, REF(UINT32) rulVersion)
  1850. {
  1851.     HX_RESULT retVal = HXR_FAIL;
  1852.     if (pValue)
  1853.     {
  1854.         const char* pszStr = (const char*) pValue->GetBuffer();
  1855.         if (pszStr)
  1856.         {
  1857.             char*  pszToken = strtok((char *) pszStr, ".");
  1858.             UINT32 ulDotNum = 0;
  1859.             UINT32 ulVer[4] = {0, 0, 0, 0};
  1860.             while(pszToken && ulDotNum < 4)
  1861.             {
  1862.                 ulVer[ulDotNum++] = (UINT32) atol(pszToken);
  1863.                 pszToken          = strtok(NULL, ".");
  1864.             }
  1865.             rulVersion = HX_ENCODE_PROD_VERSION(ulVer[0], ulVer[1], ulVer[2], ulVer[3]);
  1866.             retVal     = HXR_OK;
  1867.         }
  1868.     }
  1869.     return retVal;
  1870. }
  1871. HX_RESULT PXRealPixParser::ConvertColorValue(IHXBuffer* pValue, REF(BYTE) rucRed,
  1872.                                              REF(BYTE) rucGreen, REF(BYTE) rucBlue)
  1873. {
  1874.     HX_RESULT retVal = HXR_OK;
  1875.     if (pValue)
  1876.     {
  1877.         PXColor cColor;
  1878.         retVal = cColor.InitFromString((const char*) pValue->GetBuffer());
  1879.         if (SUCCEEDED(retVal))
  1880.         {
  1881.             rucRed   = cColor.GetRed();
  1882.             rucGreen = cColor.GetGreen();
  1883.             rucBlue  = cColor.GetBlue();
  1884.         }
  1885.     }
  1886.     else
  1887.     {
  1888.         retVal = HXR_FAIL;
  1889.     }
  1890.     return retVal;
  1891. }
  1892. HX_RESULT PXRealPixParser::ConvertWipeDirectionValue(IHXBuffer* pValue, REF(BYTE) rucDir)
  1893. {
  1894.     HX_RESULT retVal = HXR_FAIL;
  1895.     if (pValue)
  1896.     {
  1897.         const char* pszValue = (const char*) pValue->GetBuffer();
  1898.         if (pszValue)
  1899.         {
  1900.             if (!strcmp(pszValue, "up"))
  1901.             {
  1902.                 rucDir = PXEffect::kWipeDirectionUp;
  1903.                 retVal = HXR_OK;
  1904.             }
  1905.             else if (!strcmp(pszValue, "down"))
  1906.             {
  1907.                 rucDir = PXEffect::kWipeDirectionDown;
  1908.                 retVal = HXR_OK;
  1909.             }
  1910.             else if (!strcmp(pszValue, "left"))
  1911.             {
  1912.                 rucDir = PXEffect::kWipeDirectionLeft;
  1913.                 retVal = HXR_OK;
  1914.             }
  1915.             else if (!strcmp(pszValue, "right"))
  1916.             {
  1917.                 rucDir = PXEffect::kWipeDirectionRight;
  1918.                 retVal = HXR_OK;
  1919.             }
  1920.         }
  1921.     }
  1922.     return retVal;
  1923. }
  1924. HX_RESULT PXRealPixParser::ConvertWipeTypeValue(IHXBuffer* pValue, REF(BYTE) rucType)
  1925. {
  1926.     HX_RESULT retVal = HXR_FAIL;
  1927.     if (pValue)
  1928.     {
  1929.         const char* pszValue = (const char*) pValue->GetBuffer();
  1930.         if (pszValue)
  1931.         {
  1932.             if (!strcmp(pszValue, "normal"))
  1933.             {
  1934.                 rucType = PXEffect::kWipeTypeNormal;
  1935.                 retVal  = HXR_OK;
  1936.             }
  1937.             else if (!strcmp(pszValue, "push"))
  1938.             {
  1939.                 rucType = PXEffect::kWipeTypePush;
  1940.                 retVal  = HXR_OK;
  1941.             }
  1942.         }
  1943.     }
  1944.     return retVal;
  1945. }
  1946. HX_RESULT PXRealPixParser::CheckVersion(UINT32 ulMinVersion)
  1947. {
  1948.     HX_RESULT retVal = HXR_OK;
  1949.     // Was the version specified in the <head>?
  1950.     if (m_bVersionSpecified)
  1951.     {
  1952.         // The version WAS specified in the <head> tag, so 
  1953.         // the <head> version must be at least as big as ulMinVersion.
  1954.         if (m_pRealPixFile->GetContentVersion() < ulMinVersion)
  1955.         {
  1956.             retVal = HXR_FAIL;
  1957.         }
  1958.     }
  1959.     else
  1960.     {
  1961.         // The version was NOT specified in the <head> tag, so we
  1962.         // need to set the content version to at LEAST ulMinVersion.
  1963.         m_pRealPixFile->SetContentVersionToAtLeast(ulMinVersion);
  1964.     }
  1965.     return retVal;
  1966. }
  1967. void PXRealPixParser::ReportError(const UINT8 ucSeverity,
  1968.                                   HX_RESULT   lHXCode,
  1969.                                   IHXBuffer* pErrorStr)
  1970. {
  1971.     if (pErrorStr)
  1972.     {
  1973.         if (m_pContext)
  1974.         {
  1975.             IHXErrorMessages* pErrorMessages = NULL;
  1976.             m_pContext->QueryInterface(IID_IHXErrorMessages, (void**) &pErrorMessages);
  1977.             if (pErrorMessages)
  1978.             {
  1979.                 pErrorMessages->Report(ucSeverity,                           // severity
  1980.                                        lHXCode,                             // RMA result (i.e. - HXR_FAIL, HXR_OUTOFMEMORY, etc.)
  1981.                                        0,                                    // user code (not used here)
  1982.                                        (const char*) pErrorStr->GetBuffer(), // string to be displayed
  1983.                                        NULL);                                // more info string (not used here)
  1984.             }
  1985.             HX_RELEASE(pErrorMessages);
  1986.         }
  1987.     }
  1988. }