rpparser.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:80k
源码类别:

Symbian

开发平台:

Visual C++

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