2 * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <libxml/parser.h>
19 #include <libxml/tree.h>
21 #include "MsgMmsMessage.h"
22 #include "MsgInternalTypes.h"
24 #include "MsgUtilFunction.h"
27 #define INVALID_HOBJ -1
28 #define MSG_SMIL_MAX_DOC 1
29 #define MSG_SMIL_COLOR_SIZE 10
30 #define MSG_STDSTR_SHORT 0x7F
32 typedef int HMsgSmil; /* SmilDoc Handle */
34 typedef enum _SMIL_ELEMENT_T {
54 typedef enum _SMIL_ATTRIBUTE_T {
55 ATTRIBUTE_UNKNOWN = -1,
86 ATTRIBUTE_REPEAT_COUNT,
89 typedef struct _MsgSmilDoc {
91 xmlNodePtr pstRootNode;
94 /* static variables */
95 static char gszEmptyRawDoc[] = "<smil><head><layout></layout></head><body></body></smil>";
97 __thread MsgSmilDoc *__gpaMsgSmilDoc[MSG_SMIL_MAX_DOC]={NULL, };
98 __thread char gszColor[MSG_SMIL_COLOR_SIZE + 1] = {0, };
100 __thread bool gCmd[ELEMENT_MAX] = {false, };
101 __thread MMS_SMIL_ROOTLAYOUT gRootlayout = {};
102 __thread MMS_SMIL_REGION *gRegion = NULL;
103 __thread MMS_PAGE_S *gPage = NULL;
104 __thread MMS_MEDIA_S *gMedia = NULL;
105 __thread MMS_SMIL_TRANSITION *gTransition = NULL;
106 __thread MMS_SMIL_META *gMeta = NULL;
109 static int MsgSmilGetColorValue(xmlChar *content);
110 static int MsgSmilGetTime(char *pValue);
111 static int MsgSmilAtoIHexa(char *pInput);
112 static int MsgSmilGetElementID(char *pString);
113 static int MsgSmilGetAttrID(char *pString);
114 static int MsgSmilGetFontSizeValue(char *pString);
115 static bool MsgSmilGetFontAttrib(char *pString);
116 static MmsTextDirection MsgSmilGetFontDirection(char *pString);
117 static MmsSmilFontType MsgSmilGetFontTypeValue(char *pString);
119 static xmlNodePtr MsgSmilGetNodeByElementName(xmlNodePtr pstNode, char *pszName);
121 /* For Generate Smil */
122 static HMsgSmil MsgSmilCreateEmptySmilDoc(void);
123 static HMsgSmil MsgSmilCreateSmilDoc(char *pszRawData);
124 static bool MsgSmilDestroyDoc(HMsgSmil hSmilDoc);
125 static bool IsValidSmilDocNo(int nSmilDocNo);
126 static char *MsgSmilGetRawData(HMsgSmil hSmilDoc);
128 static const char *MsgSmilColorValueToString(int nValue);
130 static bool MsgSmilAddPage(HMsgSmil hSmilDoc, MMS_PAGE_S *pstSmilPage);
131 static bool MsgSmilAddRootLayout(HMsgSmil hSmilDoc, MMS_SMIL_ROOTLAYOUT *pstSmilRootLayout);
132 static bool MsgSmilAddRegion(HMsgSmil hSmilDoc, MMS_SMIL_REGION *pstSmilRegion);
133 static bool MsgSmilAddMedia(HMsgSmil hSmilDoc, int nPageNo, int nMediaIdx, MMS_MEDIA_S *pstSmilMedia, char *pszContentID);
134 static xmlNode *MsgSmilCreateTextNode(MMS_MEDIA_S *pstSmilMedia, char *pszContentID);
135 static xmlNode *MsgSmilCreateMMNode(MMS_MEDIA_S *pstSmilMedia, char *pszContentID);
136 static bool MsgSmilInsertFirstChild(xmlNode *pParent, xmlNode *pNode);
137 static bool MsgSmilInsertNode(xmlNode *pParent, xmlNode *pLeftSibling, xmlNode *pNode);
138 static void MsgSmilSetAttribute(xmlNode *pNode, char *szField, char *szValue);
141 int MsgSmilGetColorValue(xmlChar *content)
144 char color_inp[9] = {0, };
146 if (content[0] == '#') { /* RGB value */
147 snprintf(color_inp, sizeof(color_inp), "FF%s", (char *)&content[1]);
148 color = MsgSmilAtoIHexa(color_inp);
149 } else if (content[0] == '0' && (content[1] == 'x' || content[1] == 'X')) {
150 snprintf(color_inp, sizeof(color_inp), "%s", (char *)&content[2]);
151 color = MsgSmilAtoIHexa(color_inp);
153 MSG_DEBUG("Invalid Color Value");
161 const char *MsgSmilColorValueToString(int nValue)
163 unsigned char alpha = (nValue & 0xFF000000) >> 24;
164 unsigned char red = (nValue & 0xFF0000) >> 16;
165 unsigned char green = (nValue & 0x00FF00) >> 8;
166 unsigned char blue = nValue & 0x0000FF;
169 snprintf(gszColor, sizeof(gszColor), "#%02x%02x%02x", red, green, blue);
171 snprintf(gszColor, sizeof(gszColor), "0x%02x%02x%02x%02x", alpha, red, green, blue);
174 MSG_DEBUG("color value : [%s]", gszColor);
180 int MsgSmilAtoIHexa(char *pInput)
187 char *pOutput = NULL;
189 len = strlen(pInput);
190 pOutput = (char *)malloc(len + 1);
192 if (pOutput == NULL) {
193 MSG_DEBUG("Memory full");
197 memset(pOutput, 0, len + 1);
199 for (i = len - 1; i >= 0; i--) {
200 for (j = 0; j < (len - 1 - i); j++) {
276 res += (pOutput[i] * temp);
290 int MsgSmilGetTime(char *pValue)
297 if (pValue == NULL || pValue[0] == '\0')
300 /* Default time unit -> millisecond */
301 if (strstr(pValue, "msec"))
304 if (strstr(pValue, "ms"))
307 pTemp = (char *)calloc(1, strlen(pValue) + 1);
310 MSG_DEBUG("calloc for <time> attribute is failed");
314 while (isdigit(pValue[i])) {
315 pTemp[i] = pValue[i];
320 /* Detect 's' and 'ms' here */
321 retVal = atoi(pTemp);
334 int MsgSmilGetElementID(char *pString)
336 if (!strcmp(pString, "smil"))
338 else if (!strcmp(pString, "head"))
340 else if (!strcmp(pString, "layout"))
341 return ELEMENT_LAYOUT;
342 else if (!strcmp(pString, "root-layout"))
343 return ELEMENT_ROOTLAYOUT;
344 else if (!strcmp(pString, "region"))
345 return ELEMENT_REGION;
346 else if (!strcmp(pString, "body"))
348 else if (!strcmp(pString, "par"))
350 else if (!strcmp(pString, "param"))
351 return ELEMENT_PARAM;
352 else if (!strcmp(pString, "text"))
354 else if (!strcmp(pString, "img"))
356 else if (!strcmp(pString, "audio"))
357 return ELEMENT_AUDIO;
358 else if (!strcmp(pString, "video"))
359 return ELEMENT_VIDEO;
360 else if (!strcmp(pString, "ref"))
362 else if (!strcmp(pString, "animate"))
363 return ELEMENT_ANIMATE;
364 else if (!strcmp(pString, "transition"))
365 return ELEMENT_TRANSITION;
366 else if (!strcmp(pString, "meta"))
372 int MsgSmilGetAttrID(char *pString)
374 if (!strcmp(pString, "id"))
376 else if (!strcmp(pString, "top"))
377 return ATTRIBUTE_TOP;
378 else if (!strcmp(pString, "left"))
379 return ATTRIBUTE_LEFT;
380 else if (!strcmp(pString, "width"))
381 return ATTRIBUTE_WIDTH;
382 else if (!strcmp(pString, "height"))
383 return ATTRIBUTE_HEIGHT;
384 else if (!strcmp(pString, "fit"))
385 return ATTRIBUTE_FIT;
386 else if (!strcmp(pString, "backgroundColor") || !strcmp(pString, "background-color"))
387 return ATTRIBUTE_BGCOLOR;
388 else if (!strcmp(pString, "dur"))
389 return ATTRIBUTE_DUR;
390 else if (!strcmp(pString, "src"))
391 return ATTRIBUTE_SRC;
392 else if (!strcmp(pString, "color"))
393 return ATTRIBUTE_COLOR;
394 else if (!strcmp(pString, "bold"))
395 return ATTRIBUTE_BOLD;
396 else if (!strcmp(pString, "underline"))
397 return ATTRIBUTE_UNDERLINE;
398 else if (!strcmp(pString, "italic"))
399 return ATTRIBUTE_ITALIC;
400 else if (!strcmp(pString, "reverse"))
401 return ATTRIBUTE_REVERSE;
402 else if (!strcmp(pString, "direction"))
403 return ATTRIBUTE_DIRECTION;
404 else if (!strcmp(pString, "size"))
405 return ATTRIBUTE_SIZE;
406 else if (!strcmp(pString, "font"))
407 return ATTRIBUTE_FONT;
408 else if (!strcmp(pString, "region"))
409 return ATTRIBUTE_REGION;
410 else if (!strcmp(pString, "name"))
411 return ATTRIBUTE_NAME;
412 else if (!strcmp(pString, "value"))
413 return ATTRIBUTE_VALUE;
414 else if (!strcmp(pString, "alt"))
415 return ATTRIBUTE_ALT;
416 else if (!strcmp(pString, "type"))
417 return ATTRIBUTE_TYPE;
418 else if (!strcmp(pString, "subtype"))
419 return ATTRIBUTE_SUBTYPE;
420 else if (!strcmp(pString, "content"))
421 return ATTRIBUTE_CONTENT;
422 else if (!strcmp(pString, "transIn"))
423 return ATTRIBUTE_TRANSIN;
424 else if (!strcmp(pString, "transOut"))
425 return ATTRIBUTE_TRANSOUT;
426 else if (!strcmp(pString, "begin"))
427 return ATTRIBUTE_BEGIN;
428 else if (!strcmp(pString, "end"))
429 return ATTRIBUTE_END;
430 else if (!strcmp(pString, "repeatCount"))
431 return ATTRIBUTE_REPEAT_COUNT;
436 bool MsgSmilGetFontAttrib(char *pString)
438 if (!strcmp(pString, "true"))
444 MmsTextDirection MsgSmilGetFontDirection(char *pString)
446 MmsTextDirection direction = MMS_TEXT_DIRECTION_INVALID;
448 if (!strcmp(pString, "right"))
449 direction = MMS_TEXT_DIRECTION_RIGHT;
450 else if (!strcmp(pString, "down"))
451 direction = MMS_TEXT_DIRECTION_DOWN;
456 int MsgSmilGetFontSizeValue(char *pString)
458 if (!strcmp(pString, "small"))
459 return MMS_SMIL_FONT_SIZE_SMALL;
460 else if (!strcmp(pString, "normal"))
461 return MMS_SMIL_FONT_SIZE_NORMAL;
462 else if (!strcmp(pString, "large"))
463 return MMS_SMIL_FONT_SIZE_LARGE;
465 return atoi(pString);
468 MmsSmilFontType MsgSmilGetFontTypeValue(char *pString)
470 if (!strcmp(pString, "normal"))
471 return MMS_SMIL_FONT_TYPE_NORMAL;
472 else if (!strcmp(pString, "italic"))
473 return MMS_SMIL_FONT_TYPE_ITALIC;
474 else if (!strcmp(pString, "bold"))
475 return MMS_SMIL_FONT_TYPE_BOLD;
476 else if (!strcmp(pString, "underline"))
477 return MMS_SMIL_FONT_TYPE_UNDERLINE;
479 return MMS_SMIL_FONT_TYPE_NORMAL;
482 HMsgSmil MsgSmilCreateEmptySmilDoc(void)
488 hMmsSmil = MsgSmilCreateSmilDoc(gszEmptyRawDoc);
490 MSG_DEBUG("Create an empty smilDoc.(Handle = %d)", hMmsSmil);
497 HMsgSmil MsgSmilCreateSmilDoc(char *pszRawData)
500 xmlNodePtr stRootNode;
504 /* Destroy smil doc if present */
505 if (NULL != __gpaMsgSmilDoc[nSmilDocNo]) {
506 if (false == MsgSmilDestroyDoc(nSmilDocNo)) {
507 MSG_DEBUG("MsgSmilDestroyDoc: Failed!");
511 for (nSmilDocNo = 0; nSmilDocNo < MSG_SMIL_MAX_DOC; nSmilDocNo++) {
512 if (NULL == __gpaMsgSmilDoc[nSmilDocNo])
516 if (MSG_SMIL_MAX_DOC == nSmilDocNo) {
517 MSG_DEBUG("SmilDoc table is full. Can't create.");
520 __gpaMsgSmilDoc[nSmilDocNo] = (MsgSmilDoc*)malloc(sizeof(MsgSmilDoc));
521 if (NULL == __gpaMsgSmilDoc[nSmilDocNo]) {
522 MSG_DEBUG("Memory Allocation Failed.");
525 memset(__gpaMsgSmilDoc[nSmilDocNo], 0, sizeof(MsgSmilDoc));
527 __gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc = xmlParseMemory(pszRawData, strlen(pszRawData));
528 if (NULL == __gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc) {
529 if (false == MsgSmilDestroyDoc(nSmilDocNo)) {
530 MSG_DEBUG("MsgSmilDestroyDoc: Failed!");
535 stRootNode = xmlDocGetRootElement(__gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc);
536 if (NULL == stRootNode) {
537 MSG_DEBUG("Empty document");
538 if (false == MsgSmilDestroyDoc(nSmilDocNo)) {
539 MSG_DEBUG("MsgSmilDestroyDoc: Failed!");
544 if (xmlStrcmp(stRootNode->name, (const xmlChar *) "smil")) {
545 MSG_DEBUG("Document of the wrong type, root node != smil");
546 if (false == MsgSmilDestroyDoc(nSmilDocNo)) {
547 MSG_DEBUG("MsgSmilDestroyDoc: Failed!");
552 __gpaMsgSmilDoc[nSmilDocNo]->pstRootNode = stRootNode;
555 return ((HMsgSmil)nSmilDocNo);
558 bool MsgSmilDestroyDoc(HMsgSmil hSmilDoc)
560 int nSmilDocNo = (int)hSmilDoc;
564 if (0 <= nSmilDocNo &&
565 nSmilDocNo < MSG_SMIL_MAX_DOC &&
566 __gpaMsgSmilDoc[nSmilDocNo]) {
567 if (__gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc) {
568 xmlFreeDoc(__gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc);
571 if (__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode) {
574 free(__gpaMsgSmilDoc[nSmilDocNo]);
575 __gpaMsgSmilDoc[nSmilDocNo] = NULL;
577 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
585 bool IsValidSmilDocNo(int nSmilDocNo)
587 bool bIsValidSmil = false;
591 if (0 <= nSmilDocNo &&
592 nSmilDocNo < MSG_SMIL_MAX_DOC &&
593 __gpaMsgSmilDoc[nSmilDocNo] &&
594 __gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc) {
602 char *MsgSmilGetRawData(HMsgSmil hSmilDoc)
604 int nSmilDocNo = (int)hSmilDoc;
605 char *pszRawData = NULL;
609 if (IsValidSmilDocNo(nSmilDocNo)) {
610 /* xmlSaveFormatFileEnc("-", __gpaMmsSmilDoc[nSmilDocNo]->pSmilDoc, "UTF-8", 1); */
611 xmlDocDumpMemory(__gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc, (xmlChar **)(&pszRawData) , NULL);
612 if (NULL == pszRawData) {
613 MSG_DEBUG("Invalid pSmilDoc (now wellformed document)");
617 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
622 bool MsgSmilAddPage(HMsgSmil hSmilDoc, MMS_PAGE_S *pstSmilPage)
624 int nSmilDocNo = hSmilDoc;
630 if (IsValidSmilDocNo(nSmilDocNo)) {
631 xmlNodePtr pstParElement;
632 xmlNodePtr pstBodyElement;
633 xmlNodePtr pstParList;
634 char szBuf[MSG_STDSTR_SHORT] = {0, };
636 pstBodyElement = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"body");
638 if (NULL == pstBodyElement) {
639 MSG_DEBUG("There is no <body> node. Can't create <par> node.");
643 /* Create "par" node and insert it */
644 pstParElement = xmlNewNode(NULL, (xmlChar *)"par");
646 if (NULL == pstParElement) {
647 MSG_DEBUG("Can't create <par> node. (from XmlParser)");
651 MSG_SEC_DEBUG("Par Element Name = %s", (char *)pstParElement->name);
653 /* Add attributes to "par" */
654 if (pstSmilPage->nDur > 0) {
655 snprintf(szBuf, MSG_STDSTR_SHORT, "%dms", pstSmilPage->nDur);
656 xmlSetProp(pstParElement, (const xmlChar *)"dur", (const xmlChar *)szBuf);
657 MSG_DEBUG("[Set Attribute] : dur : [%s]", szBuf);
660 /* Find the insertion point : right sibling of the last <par> node or first child of <body> */
661 pstParList = xmlGetLastChild(pstBodyElement);
664 ret = MsgSmilInsertNode(pstBodyElement, pstParList, pstParElement);
666 xmlFreeNode(pstParElement);
668 ret = MsgSmilInsertFirstChild(pstBodyElement, pstParElement);
670 xmlFreeNode(pstParElement);
673 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
680 bool MsgSmilAddRootLayout(HMsgSmil hSmilDoc, MMS_SMIL_ROOTLAYOUT *pstSmilRootLayout)
682 int nSmilDocNo = hSmilDoc;
683 xmlNodePtr pstRootLayout = NULL;
684 xmlNodePtr pstLayoutList = NULL;
685 xmlNodePtr pstRootLayoutList = NULL;
686 char szBuf[MSG_STDSTR_SHORT] = {0, };
690 if (IsValidSmilDocNo(nSmilDocNo)) {
691 pstLayoutList = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"layout");
693 if (NULL == pstLayoutList) {
694 MSG_DEBUG("There is no <layout> node. Can't create <root-layout> node.");
697 MSG_SEC_DEBUG("Layout Element Name = %s ", (char *)pstLayoutList->name);
699 pstRootLayoutList = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"root-layout");
701 if (NULL != pstRootLayoutList) {
702 MSG_DEBUG("There is <root-layout> node already");
703 MSG_SEC_DEBUG("Root Layout Element Name = %s", (char *)pstRootLayoutList->name);
706 /* Create "root-layout" node and insert it */
707 pstRootLayout = xmlNewNode(NULL, (xmlChar *)"root-layout");
708 if (NULL == pstRootLayout) {
709 MSG_DEBUG("Can't create <root-layout> node. (from XmlParser)");
712 MSG_SEC_DEBUG("Root Layout Element Name = %s", (char *)pstRootLayout->name);
714 if (pstSmilRootLayout->bBgColor == true) { /* Replace value later */
715 if (((pstSmilRootLayout->bgColor & 0xFF000000) >> 24) > 0) { /* check alpha value */
716 xmlSetProp(pstRootLayout, (const xmlChar *)"backgroundColor", (const xmlChar *)MsgSmilColorValueToString(pstSmilRootLayout->bgColor));
721 if (true == pstSmilRootLayout->width.bUnitPercent) {
722 snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRootLayout->width.value);
723 xmlSetProp(pstRootLayout, (const xmlChar *)"width", (const xmlChar *)szBuf);
725 if (pstSmilRootLayout->width.value > 0) {
726 snprintf(szBuf, MSG_STDSTR_SHORT, "%d", pstSmilRootLayout->width.value);
727 xmlSetProp(pstRootLayout, (const xmlChar *)"width", (const xmlChar *)szBuf);
729 MSG_DEBUG("Set Width : default value [100%%]");
730 xmlSetProp(pstRootLayout, (const xmlChar *)"width", (const xmlChar *)"100%");
735 if (true == pstSmilRootLayout->height.bUnitPercent) {
736 snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRootLayout->height.value);
737 xmlSetProp(pstRootLayout, (const xmlChar *)"height", (const xmlChar *)szBuf);
739 if (pstSmilRootLayout->height.value > 0) {
740 snprintf(szBuf, MSG_STDSTR_SHORT, "%d", pstSmilRootLayout->height.value);
741 xmlSetProp(pstRootLayout, (const xmlChar *)"height", (const xmlChar *)szBuf);
743 xmlSetProp(pstRootLayout, (const xmlChar *)"height", (const xmlChar *)"100%");
747 xmlAddChild(pstLayoutList, pstRootLayout);
751 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
756 bool MsgSmilAddRegion(HMsgSmil hSmilDoc, MMS_SMIL_REGION *pstSmilRegion)
758 int nSmilDocNo = hSmilDoc;
762 if (IsValidSmilDocNo(nSmilDocNo)) {
765 xmlNodePtr pstRegion;
766 xmlNodePtr pstLayoutList;
767 xmlNodePtr pstRootLayoutList;
768 xmlAttrPtr pAttribute;
769 char szBuf[MSG_STDSTR_SHORT] = {0, };
771 pstLayoutList = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"layout");
772 if (NULL == pstLayoutList) {
773 MSG_DEBUG(" There is no <layout> node. Can't create <region> node");
777 /* Find the insertion point : right sibling of the last root-layout node or first child of pLayout */
778 pstRootLayoutList = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"root-layout");
780 if (NULL == pstRootLayoutList) {
781 MSG_DEBUG("There is no <root-layout> node. Can't create <root-layout> node.");
784 pAttribute = pstRootLayoutList->properties;
787 if (NULL == pAttribute) {
788 MSG_DEBUG("There is no Attribute in <root-layout> node.");
792 xmlAttrPtr pstAttr = pAttribute;
793 for ( ; pstAttr; pstAttr = pstAttr->next) {
795 MSG_SEC_DEBUG("AttributeType: (%s, %s) ", pstAttr->name, pstAttr->children->content);
796 switch (attrType = MsgSmilGetAttrID((char *)pstAttr->name)) {
797 case ATTRIBUTE_WIDTH: {
801 if (strchr((char *)pstAttr->children->content, '%'))
804 bUnitPercent = false;
806 nRootWidth = atoi((char *)pstAttr->children->content);
810 case ATTRIBUTE_HEIGHT: {
814 if (strchr((char *)pstAttr->children->content, '%'))
817 bUnitPercent = false;
819 nRootHeight = atoi((char *)pstAttr->children->content);
828 /* Create "region" node and insert it */
829 pstRegion = xmlNewNode(NULL, (xmlChar *)"region");
830 if (NULL == pstRegion) {
831 MSG_DEBUG("Can't create <region> node. (from XmlParser)");
835 MSG_SEC_DEBUG("Region Element Name = %s", (char *)pstRegion->name);
837 if (strlen(pstSmilRegion->szID) > 0) {
838 xmlSetProp(pstRegion, (const xmlChar *)"id", (const xmlChar *)pstSmilRegion->szID);
839 MSG_DEBUG("[Set Attribute] : Region Id : [%s]", pstSmilRegion->szID);
842 if (pstSmilRegion->bBgColor == true) {
843 MSG_DEBUG(" [Set Attribute] : BkGrd Color");
844 if (((pstSmilRegion->bgColor & 0xFF000000) >> 24) > 0) {
845 xmlSetProp(pstRegion, (const xmlChar *)"backgroundColor", (const xmlChar *)MsgSmilColorValueToString(pstSmilRegion->bgColor));
846 MSG_DEBUG("[Set Attribute] : backgroundColor [%s]", MsgSmilColorValueToString(pstSmilRegion->bgColor));
851 if (true == pstSmilRegion->width.bUnitPercent) {
852 if (pstSmilRegion->width.value > 0) {
853 snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRegion->width.value);
854 xmlSetProp(pstRegion, (const xmlChar *)"width", (const xmlChar *)szBuf);
855 MSG_DEBUG("[Set Attribute] : Width : [%s]", szBuf);
858 /* Note: nRootWidth should be in terms of value(pixel) not unitpercent(%) */
859 /* Validation should be done before this. */
860 if (pstSmilRegion->width.value >= 0 &&
861 pstSmilRegion->width.value <= nRootWidth &&
863 int iWidth = (pstSmilRegion->width.value * 100) / nRootWidth;
865 snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", iWidth);
866 xmlSetProp(pstRegion, (const xmlChar *)"width", (const xmlChar *)szBuf);
867 MSG_DEBUG("[Set Attribute] : Width : [%s]", szBuf);
871 if (true == pstSmilRegion->height.bUnitPercent) {
872 if (pstSmilRegion->height.value > 0) {
873 snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRegion->height.value);
874 xmlSetProp(pstRegion, (const xmlChar *)"height", (const xmlChar *)szBuf);
875 MSG_DEBUG("[Set Attribute] : Height : [%s]", szBuf);
878 /* Note: nRootHeight should be in terms of value(pixel) not unitpercent(%) */
879 /* Validation should be done before this. */
880 if (pstSmilRegion->height.value >= 0 &&
881 pstSmilRegion->height.value <= nRootHeight &&
883 int iHeight = (pstSmilRegion->height.value * 100) / nRootHeight;
885 snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", iHeight);
886 xmlSetProp(pstRegion, (const xmlChar *)"height", (const xmlChar *)szBuf);
888 MSG_DEBUG("[Set Attribute] : Height : [%s]", szBuf);
892 if (true == pstSmilRegion->nLeft.bUnitPercent) {
893 if (pstSmilRegion->nLeft.value > 0) {
894 snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRegion->nLeft.value);
895 xmlSetProp(pstRegion, (const xmlChar *)"left", (const xmlChar *)szBuf);
897 MSG_DEBUG("[Set Attribute] : Left : [%s]", szBuf);
900 /* Note: nRootWidth should be in terms of value(pixel) not unitpercent(%) */
901 /* Validation should be done before this. */
902 if (pstSmilRegion->nLeft.value >= 0 && nRootWidth != 0) {
903 int iLeft = (pstSmilRegion->nLeft.value * 100) / nRootWidth;
905 snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", iLeft);
906 xmlSetProp(pstRegion, (const xmlChar *)"left", (const xmlChar *)szBuf);
907 MSG_DEBUG("[Set Attribute] : Left : [%s]", szBuf);
911 if (true == pstSmilRegion->nTop.bUnitPercent) {
912 if (pstSmilRegion->nTop.value > 0 &&
914 snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRegion->nTop.value);
915 xmlSetProp(pstRegion, (const xmlChar *)"top", (const xmlChar *)szBuf);
916 MSG_DEBUG("[Set Attribute] : Top : [%s]", szBuf);
919 /* Note: nRootHeight should be in terms of value(pixel) not unitpercent(%) */
920 /* Validation should be done before this. */
921 if (pstSmilRegion->nTop.value >= 0 && nRootHeight != 0) {
922 int iTop = (pstSmilRegion->nTop.value * 100) / nRootHeight;
924 snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", iTop);
925 xmlSetProp(pstRegion, (const xmlChar *)"top", (const xmlChar *)szBuf);
926 MSG_DEBUG("[Set Attribute] : Top : [%s]", szBuf);
931 if (MMSUI_IMAGE_REGION_FIT_MEET == pstSmilRegion->fit) {
932 xmlSetProp(pstRegion, (const xmlChar *)"fit", (const xmlChar *)"meet");
933 MSG_DEBUG("[Set Attribute] : fit : [meet]");
934 } else if (MMSUI_IMAGE_REGION_FIT_HIDDEN == pstSmilRegion->fit) {
935 xmlSetProp(pstRegion, (const xmlChar *)"fit", (const xmlChar *)"hidden");
936 MSG_DEBUG("[Set Attribute] : fit : [hidden]");
939 MsgSmilInsertNode(pstLayoutList, pstRootLayoutList, pstRegion);
941 MSG_DEBUG("There is no attribute in <region> node");
947 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
952 bool MsgSmilAddMedia(HMsgSmil hSmilDoc, int nPageNo, int nMediaIdx, MMS_MEDIA_S *pstSmilMedia, char *pszContentID)
954 int nSmilDocNo = hSmilDoc;
958 if (NULL == pszContentID) {
959 MSG_DEBUG(" Content Id is NULL");
962 memset(pszContentID, 0, sizeof(pstSmilMedia->szContentID));
963 if (IsValidSmilDocNo(nSmilDocNo)) {
966 xmlNode *pstLastChild;
967 xmlNodePtr pstParList;
970 pstParList = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"par");
972 if (NULL == pstParList) {
973 MSG_DEBUG("There is no <par> node. Can't create <media> node.");
977 for (nIndex = 0; (pstParList && nIndex < nPageNo); nIndex++) {
978 pstParList = pstParList->next;
981 if (NULL == pstParList) {
982 MSG_DEBUG("There is no such page node. Can't insert <media> node.");
986 /* Find insertion point and make a contentID */
987 pstLastChild = xmlGetLastChild(pstParList);
989 pszExt = strrchr(pstSmilMedia->szFileName, '.');
990 if (pszExt && !strrchr(pszExt, '/'))
991 snprintf(pszContentID, MSG_MSG_ID_LEN+1, "%lu_%lu%s", (unsigned long)nPageNo, (unsigned long)nMediaIdx, pszExt);
993 snprintf(pszContentID, MSG_MSG_ID_LEN+1, "%lu_%lu", (unsigned long)nPageNo, (unsigned long)nMediaIdx);
995 /* remove space character in content location */
996 msg_replace_space_char(pstSmilMedia->szFileName);
998 memset(pstSmilMedia->szContentLocation, 0, sizeof(pstSmilMedia->szContentLocation));
999 gchar *tmpContentLoc = msg_replace_non_ascii_char(pstSmilMedia->szFileName, '_');
1000 if (tmpContentLoc) {
1001 MSG_SEC_DEBUG("tmpContentLoc = [%s]", tmpContentLoc);
1002 snprintf(pstSmilMedia->szContentLocation, sizeof(pstSmilMedia->szContentLocation), "%s", tmpContentLoc);
1003 g_free(tmpContentLoc);
1004 tmpContentLoc = NULL;
1006 MSG_WARN("tmpContentLoc is NULL.");
1007 snprintf(pstSmilMedia->szContentLocation, sizeof(pstSmilMedia->szContentLocation), "%s", pstSmilMedia->szFileName);
1010 /* Create <media> node and insert set attribute */
1011 switch (pstSmilMedia->mediatype) {
1012 case MMS_SMIL_MEDIA_TEXT:
1013 pstMedia = MsgSmilCreateTextNode(pstSmilMedia, pszContentID);
1015 case MMS_SMIL_MEDIA_AUDIO:
1016 case MMS_SMIL_MEDIA_VIDEO:
1017 case MMS_SMIL_MEDIA_IMG:
1018 pstMedia = MsgSmilCreateMMNode(pstSmilMedia, pszContentID);
1021 MSG_DEBUG("Invalid media type. Can't insert such-<media> node.");
1025 if (NULL == pstMedia) {
1026 MSG_DEBUG("Can't create <media> node. (from XmlParser) (media-type:%d)", pstSmilMedia->mediatype);
1030 /* Find the insertion point : the last child of <par> node */
1032 MsgSmilInsertNode(pstParList, pstLastChild, pstMedia);
1034 MsgSmilInsertFirstChild(pstParList, pstMedia);
1039 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
1044 xmlNode *MsgSmilCreateTextNode(MMS_MEDIA_S *pstSmilMedia, char *pszContentID)
1046 xmlNode *pstMedia = NULL;
1047 xmlNode *pstParam = NULL;
1048 char szBuf[MSG_STDSTR_SHORT] = {0, };
1049 char szSizeBuf[MSG_STDSTR_SHORT] = {0, };
1053 pstMedia = xmlNewNode(NULL, (xmlChar *)"text");
1054 if (NULL == pstMedia) {
1055 MSG_DEBUG("Can't create <Text> node.");
1059 /* Add attributes */
1061 if (strlen(pstSmilMedia->regionId) > 0) {
1062 xmlSetProp(pstMedia, (const xmlChar *)"region", (const xmlChar *)pstSmilMedia->regionId);
1063 MSG_DEBUG("[Set Attribute] Region Id : [%s]", pstSmilMedia->regionId);
1066 if (pstSmilMedia->sMedia.sText.nBegin > 0) {
1067 snprintf (szBuf, sizeof(szBuf), "%dms", pstSmilMedia->sMedia.sText.nBegin);
1068 xmlSetProp(pstMedia, (const xmlChar *)"begin", (const xmlChar *) szBuf);
1069 MSG_DEBUG("[Set Attribute] Begin : [%s]", szBuf);
1072 if (pstSmilMedia->sMedia.sText.nDurTime > 0) {
1073 snprintf (szBuf, sizeof(szBuf), "%dms", pstSmilMedia->sMedia.sText.nDurTime);
1074 xmlSetProp(pstMedia, (const xmlChar *)"dur", (const xmlChar *)szBuf);
1075 MSG_DEBUG("[Set Attribute] Duration : [%s]", szBuf);
1078 if (strlen(pstSmilMedia->szAlt) > 0) {
1079 int wrn = snprintf (szBuf, sizeof(szBuf), "%s", pstSmilMedia->szAlt);
1081 MSG_DEBUG("snprintf was failed\n");
1082 xmlSetProp(pstMedia, (const xmlChar *)"alt", (const xmlChar *)szBuf);
1083 MSG_DEBUG("[Set Attribute] Alternate : [%s]", szBuf);
1087 char szFilePathWithCid[MSG_MSG_ID_LEN + 5]; /* for "cid:" */
1089 snprintf (szFilePathWithCid, sizeof(szFilePathWithCid), "cid:%s", pszContentID);
1090 MsgSmilSetAttribute(pstMedia, (char *)"src", szFilePathWithCid);
1092 if (strlen(pstSmilMedia->szContentLocation) > 0) {
1093 MsgSmilSetAttribute(pstMedia, (char *)"src", pstSmilMedia->szContentLocation); /* using content Location in Smil */
1094 MSG_DEBUG("[Set Attribute] Src : [%s]", pstSmilMedia->szContentLocation);
1097 if (((pstSmilMedia->sMedia.sText.nColor & 0xFF000000) >> 24) > 0) {
1098 pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1100 if (NULL == pstParam) {
1101 MSG_DEBUG("Cannot create <param> node");
1105 xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"foreground-color");
1106 xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)MsgSmilColorValueToString(pstSmilMedia->sMedia.sText.nColor));
1108 MSG_DEBUG("[Set param] Font Foreground Color : [0x%08x]", pstSmilMedia->sMedia.sText.nColor);
1110 MsgSmilInsertFirstChild(pstMedia, pstParam);
1113 if (((pstSmilMedia->sMedia.sText.nBgColor & 0xFF000000) >> 24) > 0) {
1114 pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1116 if (NULL == pstParam) {
1117 MSG_DEBUG("Cannot create <param> node");
1121 xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"background-color");
1122 xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)MsgSmilColorValueToString(pstSmilMedia->sMedia.sText.nBgColor));
1124 MSG_DEBUG("[Set param] Font Background Color : [0x%08x]", pstSmilMedia->sMedia.sText.nBgColor);
1126 MsgSmilInsertFirstChild(pstMedia, pstParam);
1129 if (pstSmilMedia->sMedia.sText.nSize > 0) {
1130 pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1131 if (NULL == pstParam) {
1132 MSG_DEBUG(" __MmsCreateTextNode: cannot create <param> node");
1136 if (pstSmilMedia->sMedia.sText.nSize <= MMS_SMIL_FONT_SIZE_SMALL) {
1137 snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "small");
1138 } else if ((pstSmilMedia->sMedia.sText.nSize > MMS_SMIL_FONT_SIZE_SMALL) && (pstSmilMedia->sMedia.sText.nSize < MMS_SMIL_FONT_SIZE_LARGE)) {
1139 snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "normal");
1141 snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "large");
1144 xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"textsize");
1145 xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)szSizeBuf);
1147 MSG_DEBUG("[Set param] textsize : [%s]", szSizeBuf);
1149 MsgSmilInsertFirstChild(pstMedia, pstParam);
1152 if (pstSmilMedia->sMedia.sText.bBold == true) {
1153 pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1154 if (NULL == pstParam) {
1155 MSG_DEBUG(" __MmsCreateTextNode: cannot create <param> node");
1159 snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "bold");
1161 xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"textattribute");
1162 xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)szSizeBuf);
1164 MSG_DEBUG("[Set param] textattribute : [%s]", szSizeBuf);
1166 MsgSmilInsertFirstChild(pstMedia, pstParam);
1169 if (pstSmilMedia->sMedia.sText.bItalic == true) {
1170 pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1171 if (NULL == pstParam) {
1172 MSG_DEBUG(" __MmsCreateTextNode: cannot create <param> node");
1176 snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "italic");
1178 xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"textattribute");
1179 xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)szSizeBuf);
1181 MSG_DEBUG("[Set param] textattribute : [%s]", szSizeBuf);
1183 MsgSmilInsertFirstChild(pstMedia, pstParam);
1186 if (pstSmilMedia->sMedia.sText.bUnderLine == true) {
1187 pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1188 if (NULL == pstParam) {
1189 MSG_DEBUG(" __MmsCreateTextNode: cannot create <param> node");
1193 snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "underline");
1195 xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"textattribute");
1196 xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)szSizeBuf);
1198 MSG_DEBUG("[Set param] textattribute : [%s]", szSizeBuf);
1200 MsgSmilInsertFirstChild(pstMedia, pstParam);
1208 xmlNode *MsgSmilCreateMMNode(MMS_MEDIA_S *pstSmilMedia, char *pszContentID)
1210 xmlNode *pstMedia = NULL;
1211 char szBuf[MSG_STDSTR_SHORT] = {0, };
1218 switch (pstSmilMedia->mediatype) {
1219 case MMS_SMIL_MEDIA_AUDIO:
1220 pstMedia = xmlNewNode(NULL, (xmlChar *)"audio");
1223 case MMS_SMIL_MEDIA_VIDEO:
1224 pstMedia = xmlNewNode(NULL, (xmlChar *)"video");
1227 case MMS_SMIL_MEDIA_IMG:
1228 pstMedia = xmlNewNode(NULL, (xmlChar *)"img");
1231 MSG_DEBUG("Invalid media type. Can't insert such-<media> node.");
1236 if (strlen(pstSmilMedia->regionId) > 0) {
1237 xmlSetProp(pstMedia, (const xmlChar *)"region", (const xmlChar *)pstSmilMedia->regionId);
1238 MSG_DEBUG("[Set Attribute] Region Id : [%s]", pstSmilMedia->regionId);
1241 #if 0 /* set src attribute cid */
1242 char szFilePathWithCid[MSG_MSG_ID_LEN + 5]; /* for "cid:" */
1243 snprintf (szFilePathWithCid, sizeof(szFilePathWithCid), "cid:%s", pszContentID);
1244 MsgSmilSetAttribute(pstMedia, (char *)"src", szFilePathWithCid);
1246 if (strlen(pstSmilMedia->szContentLocation) > 0) {
1247 MsgSmilSetAttribute(pstMedia, (char *)"src", pstSmilMedia->szContentLocation); /* using content Location in Smil */
1248 MSG_SEC_DEBUG("[Set Attribute] src : [%s]", pstSmilMedia->szContentLocation);
1251 if (pstSmilMedia->sMedia.sAVI.nBegin > 0) {
1252 snprintf (szBuf, sizeof(szBuf), "%dms", pstSmilMedia->sMedia.sAVI.nBegin);
1253 xmlSetProp(pstMedia, (const xmlChar *)"begin", (const xmlChar *)szBuf);
1254 MSG_DEBUG("[Set Attribute] begin : [%s]", szBuf);
1257 if (pstSmilMedia->sMedia.sAVI.nDurTime > 0) {
1258 snprintf (szBuf, sizeof(szBuf), "%dms", pstSmilMedia->sMedia.sAVI.nDurTime);
1259 xmlSetProp(pstMedia, (const xmlChar *)"dur", (const xmlChar *)szBuf);
1260 MSG_DEBUG("[Set Attribute] dur : [%s]", szBuf);
1263 if (strlen(pstSmilMedia->szAlt) > 0) {
1264 int wrn = snprintf (szBuf, sizeof(szBuf), "%s", pstSmilMedia->szAlt);
1266 MSG_DEBUG("snprintf was failed\n");
1267 xmlSetProp(pstMedia, (const xmlChar *)"alt", (const xmlChar *)szBuf);
1268 MSG_DEBUG("[Set Attribute] alt : [%s]", szBuf);
1271 MSG_DEBUG("There is no attribute in such-<media> node");
1278 bool MsgSmilInsertFirstChild(xmlNode *pstParent, xmlNode *pstCurr)
1284 if (NULL == xmlAddChild(pstParent, pstCurr)) {
1285 MSG_SEC_DEBUG("%s Node not added", pstCurr->name);
1293 bool MsgSmilInsertNode(xmlNode *pstParent, xmlNode *pstLeftSibling, xmlNode *pstCurr)
1298 if (pstLeftSibling) {
1299 /* Parent Node is Unused */
1300 while (pstLeftSibling->next != NULL)
1301 pstLeftSibling = pstLeftSibling->next;
1303 if (NULL == xmlAddNextSibling(pstLeftSibling, pstCurr)) {
1304 MSG_SEC_DEBUG("%s Node not added", pstCurr->name);
1308 if (NULL == xmlAddChild(pstParent, pstCurr)) {
1309 MSG_SEC_DEBUG("%s Node not added", pstCurr->name);
1317 void MsgSmilSetAttribute(xmlNode *pNode, char *szField, char *szValue)
1321 if (pNode && szField && strlen(szField)) {
1322 if (szValue && strlen(szValue)) {
1323 xmlSetProp(pNode, (const xmlChar *)szField, (const xmlChar *)szValue);
1325 xmlSetProp(pNode, (const xmlChar *)szField, (const xmlChar *)"");
1332 xmlNodePtr MsgSmilGetNodeByElementName(xmlNodePtr pstNode, char *pszName)
1334 if ((NULL != pstNode) && (NULL != pszName)) {
1335 xmlNodePtr pstTempNode;
1336 xmlNodePtr pstReturnNode;
1338 pstTempNode = pstNode;
1340 for ( ; pstTempNode; pstTempNode = pstTempNode->next) {
1341 if (0 == strcasecmp((char *)pstTempNode->name, pszName)) {
1342 MSG_SEC_DEBUG("Find Node : name [%s][%p]", (char *)pstTempNode->name, pstTempNode);
1346 if (pstTempNode->children) {
1347 pstReturnNode = MsgSmilGetNodeByElementName(pstTempNode->children, pszName);
1348 if (NULL != pstReturnNode) {
1349 return pstReturnNode;
1357 void MsgSmilParseNode(MMS_MESSAGE_DATA_S *pMmsMsg, xmlNode *a_node, int depth)
1364 xmlNode *cur_node = NULL;
1366 if (depth == 0) { /* init */
1367 memset(gCmd, 0x00, ELEMENT_MAX);
1368 memset(&gRootlayout, 0x00, sizeof(MMS_SMIL_ROOTLAYOUT));
1376 for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
1377 MSG_SEC_DEBUG("## [%d] node type : [Element], name: [%s] ##", depth, cur_node->name);
1379 if (cur_node->type == XML_ELEMENT_NODE) {
1380 /* Get Smil Element */
1381 switch (elementType = MsgSmilGetElementID((char *)cur_node->name)) {
1382 case ELEMENT_ROOTLAYOUT:
1383 gCmd[ELEMENT_ROOTLAYOUT] = true;
1386 case ELEMENT_REGION:
1388 MSG_DEBUG("region exist");
1392 gRegion = (MMS_SMIL_REGION *)calloc(1, sizeof(MMS_SMIL_REGION));
1393 gCmd[ELEMENT_REGION] = true;
1396 case ELEMENT_TRANSITION:
1398 MSG_DEBUG("Transition exist");
1402 gTransition = (MMS_SMIL_TRANSITION *)calloc(1, sizeof(MMS_SMIL_TRANSITION));
1403 gCmd[ELEMENT_TRANSITION] = true;
1408 MSG_DEBUG("Meta exist");
1412 gMeta = (MMS_SMIL_META *)calloc(1, sizeof(MMS_SMIL_META));
1413 gCmd[ELEMENT_META] = true;
1418 MSG_DEBUG("Page exist");
1422 gPage = (MMS_PAGE_S *)calloc(1, sizeof(MMS_PAGE_S));
1423 gCmd[ELEMENT_PAR] = true;
1426 case ELEMENT_PARAM: /* Need to check the original element type */
1427 gCmd[ELEMENT_PARAM] = true;
1432 MSG_DEBUG("Media exist");
1436 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1438 MSG_DEBUG("calloc for gMedia is failed");
1441 gMedia->mediatype = MMS_SMIL_MEDIA_TEXT;
1442 gCmd[ELEMENT_TEXT] = true;
1447 MSG_DEBUG("Media exist");
1451 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1453 MSG_DEBUG("calloc for gMedia is failed");
1456 gMedia->mediatype = MMS_SMIL_MEDIA_IMG;
1457 gCmd[ELEMENT_IMG] = true;
1462 MSG_DEBUG("Media exist");
1466 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1468 MSG_DEBUG("calloc for gMedia is failed");
1471 gMedia->mediatype = MMS_SMIL_MEDIA_AUDIO;
1472 gCmd[ELEMENT_AUDIO] = true;
1477 MSG_DEBUG("Media exist");
1481 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1483 MSG_DEBUG("calloc for gMedia is failed");
1486 gMedia->mediatype = MMS_SMIL_MEDIA_VIDEO;
1487 gCmd[ELEMENT_VIDEO] = true;
1492 MSG_DEBUG("Media exist");
1496 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1498 MSG_DEBUG("calloc for gMedia is failed");
1501 gMedia->mediatype = MMS_SMIL_MEDIA_IMG_OR_VIDEO;
1502 gCmd[ELEMENT_REF] = true;
1505 case ELEMENT_ANIMATE:
1507 MSG_DEBUG("Media exist");
1511 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1513 MSG_DEBUG("calloc for gMedia is failed");
1516 gMedia->mediatype = MMS_SMIL_MEDIA_ANIMATE;
1517 gCmd[ELEMENT_ANIMATE] = true;
1521 MSG_DEBUG("Unsupported element type [%d]", elementType);
1525 /* Get Smil Attribute */
1526 xmlAttr *pAttr = cur_node->properties;
1528 SMIL_ATTRIBUTE_T paramType = ATTRIBUTE_UNKNOWN;
1530 for ( ; pAttr; pAttr = pAttr->next) {
1531 MSG_SEC_DEBUG("## attribute type : name [%s] value [%s] ##", pAttr->name, pAttr->children->content);
1533 switch (attrType = MsgSmilGetAttrID((char *)pAttr->name)) {
1534 case ATTRIBUTE_ID: {
1535 if (gCmd[ELEMENT_REGION] && gRegion) {
1536 strncpy(gRegion->szID, (char *)pAttr->children->content, MAX_SMIL_REGION_ID - 1);
1537 } else if (gCmd[ELEMENT_TRANSITION] && gTransition) {
1538 strncpy(gTransition->szID, (char *)pAttr->children->content, MAX_SMIL_TRANSITION_ID - 1);
1539 } else if (gCmd[ELEMENT_META] && gMeta) {
1540 strncpy(gMeta->szID, (char *)pAttr->children->content, MAX_SMIL_META_ID - 1);
1545 case ATTRIBUTE_TOP: {
1549 if (strchr((char *)pAttr->children->content, '%'))
1550 bUnitPercent = true;
1552 bUnitPercent = false;
1554 value = atoi((char *)pAttr->children->content);
1556 if (gCmd[ELEMENT_REGION] && gRegion) {
1557 gRegion->nTop.bUnitPercent = bUnitPercent;
1558 gRegion->nTop.value = value;
1563 case ATTRIBUTE_LEFT: {
1567 if (strchr((char *)pAttr->children->content, '%'))
1568 bUnitPercent = true;
1570 bUnitPercent = false;
1572 value = atoi((char *)pAttr->children->content);
1574 if (gCmd[ELEMENT_REGION] && gRegion) {
1575 gRegion->nLeft.bUnitPercent = bUnitPercent;
1576 gRegion->nLeft.value = value;
1582 case ATTRIBUTE_WIDTH: {
1586 if (strchr((char *)pAttr->children->content, '%'))
1587 bUnitPercent = true;
1589 bUnitPercent = false;
1591 value = atoi((char *)pAttr->children->content);
1593 if (gCmd[ELEMENT_ROOTLAYOUT]) {
1594 gRootlayout.width.bUnitPercent = bUnitPercent;
1595 gRootlayout.width.value = value;
1596 } else if (gCmd[ELEMENT_REGION] && gRegion) {
1597 gRegion->width.bUnitPercent = bUnitPercent;
1598 gRegion->width.value = value;
1603 case ATTRIBUTE_HEIGHT: {
1607 if (strchr((char *)pAttr->children->content, '%'))
1608 bUnitPercent = true;
1610 bUnitPercent = false;
1612 value = atoi((char *)pAttr->children->content);
1614 if (gCmd[ELEMENT_ROOTLAYOUT]) {
1615 gRootlayout.height.bUnitPercent = bUnitPercent;
1616 gRootlayout.height.value = value;
1617 } else if (gCmd[ELEMENT_REGION] && gRegion) {
1618 gRegion->height.bUnitPercent = bUnitPercent;
1619 gRegion->height.value = value;
1625 if (gCmd[ELEMENT_REGION] && gRegion) {
1626 if (!strcmp((char *)pAttr->children->content, "meet")) {
1627 gRegion->fit = MMSUI_IMAGE_REGION_FIT_MEET;
1629 gRegion->fit = MMSUI_IMAGE_REGION_FIT_HIDDEN;
1634 case ATTRIBUTE_BGCOLOR:
1635 if (gCmd[ELEMENT_ROOTLAYOUT]) {
1636 gRootlayout.bBgColor = true;
1637 gRootlayout.bgColor = MsgSmilGetColorValue(pAttr->children->content);
1638 } else if (gCmd[ELEMENT_REGION] && gRegion) {
1639 gRegion->bBgColor = true;
1640 gRegion->bgColor = MsgSmilGetColorValue(pAttr->children->content);
1641 } else if (gCmd[ELEMENT_TEXT] && gMedia) {
1642 gMedia->sMedia.sText.nBgColor = MsgSmilGetColorValue(pAttr->children->content);
1643 } else if (gMedia) {
1644 gMedia->sMedia.sAVI.nBgColor = MsgSmilGetColorValue(pAttr->children->content);
1650 if (gCmd[ELEMENT_PAR] && gPage) {
1651 if (elementType == ELEMENT_PAR)
1652 gPage->nDur = MsgSmilGetTime((char *)pAttr->children->content);
1653 } else if (gCmd[ELEMENT_TRANSITION] && gTransition) {
1654 gTransition->nDur = MsgSmilGetTime((char *)pAttr->children->content);
1655 } else if (gCmd[ELEMENT_TEXT] && gMedia) {
1656 gMedia->sMedia.sText.nDurTime = MsgSmilGetTime((char *)pAttr->children->content);
1657 } else if (gMedia) {
1658 gMedia->sMedia.sAVI.nDurTime = MsgSmilGetTime((char *)pAttr->children->content);
1662 case ATTRIBUTE_SRC: {
1664 char szContentID[MSG_MSG_ID_LEN + 1] = {0, };
1667 snprintf(szContentID, sizeof(szContentID), "%s", (char *)pAttr->children->content);
1669 cLen = strlen(szContentID);
1670 if (!strncasecmp(szContentID, "cid:", 4)) {
1671 strncpy(gMedia->szContentID, szContentID + 4, cLen - 4);
1672 gMedia->szContentID[cLen - 4] = '\0';
1674 strncpy(gMedia->szContentID, szContentID, cLen);
1675 gMedia->szContentID[cLen] = '\0';
1680 case ATTRIBUTE_COLOR:
1681 if (gCmd[ELEMENT_TEXT] && gMedia)
1682 gMedia->sMedia.sText.nColor = MsgSmilGetColorValue(pAttr->children->content);
1685 case ATTRIBUTE_SIZE:
1686 if (gCmd[ELEMENT_TEXT] && gMedia)
1687 gMedia->sMedia.sText.nSize = atoi((char *)pAttr->children->content);
1690 case ATTRIBUTE_BOLD:
1691 if (gCmd[ELEMENT_TEXT] && gMedia) {
1692 gMedia->sMedia.sText.bBold = MsgSmilGetFontAttrib((char *)pAttr->children->content);
1696 case ATTRIBUTE_UNDERLINE:
1697 if (gCmd[ELEMENT_TEXT] && gMedia)
1698 gMedia->sMedia.sText.bUnderLine = MsgSmilGetFontAttrib((char *)pAttr->children->content);
1701 case ATTRIBUTE_ITALIC:
1702 if (gCmd[ELEMENT_TEXT] && gMedia)
1703 gMedia->sMedia.sText.bItalic = MsgSmilGetFontAttrib((char *)pAttr->children->content);
1706 case ATTRIBUTE_REVERSE:
1707 if (gCmd[ELEMENT_TEXT] && gMedia)
1708 gMedia->sMedia.sText.bReverse = MsgSmilGetFontAttrib((char *)pAttr->children->content);
1711 case ATTRIBUTE_DIRECTION:
1712 if (gCmd[ELEMENT_TEXT] && gMedia)
1713 gMedia->sMedia.sText.nDirection = MsgSmilGetFontDirection((char *)pAttr->children->content);
1715 case ATTRIBUTE_REGION:
1717 strncpy(gMedia->regionId, (char *)pAttr->children->content, MAX_SMIL_REGION_ID - 1);
1721 case ATTRIBUTE_TRANSIN:
1723 if (gCmd[ELEMENT_TEXT] )
1724 strncpy(gMedia->sMedia.sText.szTransInId, (char *)pAttr->children->content, MAX_SMIL_TRANSIN_ID - 1);
1726 strncpy(gMedia->sMedia.sAVI.szTransInId, (char *)pAttr->children->content, MAX_SMIL_TRANSIN_ID - 1);
1730 case ATTRIBUTE_TRANSOUT:
1732 if (gCmd[ELEMENT_TEXT])
1733 strncpy(gMedia->sMedia.sText.szTransOutId, (char *)pAttr->children->content, MAX_SMIL_TRANSOUT_ID - 1);
1735 strncpy(gMedia->sMedia.sAVI.szTransOutId, (char *)pAttr->children->content, MAX_SMIL_TRANSOUT_ID - 1);
1739 case ATTRIBUTE_BEGIN:
1741 if (gCmd[ELEMENT_TEXT])
1742 gMedia->sMedia.sText.nBegin = MsgSmilGetTime((char *)pAttr->children->content);
1744 gMedia->sMedia.sAVI.nBegin = MsgSmilGetTime((char *)pAttr->children->content);
1750 if (gCmd[ELEMENT_TEXT])
1751 gMedia->sMedia.sText.nEnd = MsgSmilGetTime((char *)pAttr->children->content);
1753 gMedia->sMedia.sAVI.nEnd = MsgSmilGetTime((char *)pAttr->children->content);
1757 case ATTRIBUTE_REPEAT_COUNT:
1759 if (gCmd[ELEMENT_TEXT])
1760 gMedia->sMedia.sText.nRepeat = atoi((char *)pAttr->children->content);
1762 gMedia->sMedia.sAVI.nRepeat = atoi((char *)pAttr->children->content);
1766 case ATTRIBUTE_NAME:
1767 if (gCmd[ELEMENT_PARAM]) {
1768 if (!strcmp((char *)pAttr->children->content, "foreground-color") || !strcmp((char *)pAttr->children->content, "foregroundcolor"))
1769 paramType = ATTRIBUTE_FGCOLOR;
1770 else if (!strcmp((char *)pAttr->children->content, "background-color") || !strcmp((char *)pAttr->children->content, "backgroundcolor"))
1771 paramType = ATTRIBUTE_BGCOLOR;
1772 else if (!strcmp((char *)pAttr->children->content, "textsize"))
1773 paramType = ATTRIBUTE_SIZE;
1774 else if (!strcmp((char *)pAttr->children->content, "textattribute"))
1775 paramType = ATTRIBUTE_TEXTFORMAT;
1777 } else if (gCmd[ELEMENT_META] && gMeta) {
1778 strncpy(gMeta->szName, (char *)pAttr->children->content, MAX_SMIL_META_NAME - 1);
1782 case ATTRIBUTE_VALUE:
1784 if (paramType == ATTRIBUTE_SIZE && gCmd[ELEMENT_TEXT] && gMedia) {
1785 gMedia->sMedia.sText.nSize = MsgSmilGetFontSizeValue((char *)pAttr->children->content);
1786 } else if (paramType == ATTRIBUTE_FGCOLOR && gCmd[ELEMENT_TEXT] && gMedia) {
1787 gMedia->sMedia.sText.nColor = MsgSmilGetColorValue(pAttr->children->content);
1788 } else if (paramType == ATTRIBUTE_BGCOLOR && gCmd[ELEMENT_TEXT] && gMedia) {
1789 gMedia->sMedia.sText.nBgColor = MsgSmilGetColorValue(pAttr->children->content);
1790 } else if (paramType == ATTRIBUTE_TEXTFORMAT && gCmd[ELEMENT_TEXT] && gMedia) {
1791 MmsSmilFontType fontType;
1793 fontType = MsgSmilGetFontTypeValue((char *)pAttr->children->content);
1795 if (fontType == MMS_SMIL_FONT_TYPE_BOLD)
1796 gMedia->sMedia.sText.bBold = true;
1798 gMedia->sMedia.sText.bBold = false;
1800 if (fontType == MMS_SMIL_FONT_TYPE_ITALIC)
1801 gMedia->sMedia.sText.bItalic = true;
1803 gMedia->sMedia.sText.bItalic = false;
1805 if (fontType == MMS_SMIL_FONT_TYPE_UNDERLINE)
1806 gMedia->sMedia.sText.bUnderLine = true;
1808 gMedia->sMedia.sText.bUnderLine = false;
1810 paramType = ATTRIBUTE_UNKNOWN;
1815 strncpy(gMedia->szAlt, (char *)pAttr->children->content, MAX_SMIL_ALT_LEN - 1);
1819 case ATTRIBUTE_TYPE:
1821 gTransition->nType = (MmsSmilTransType)atoi((char *)pAttr->children->content);
1823 switch (gTransition->nType) {
1824 case MMS_SMIL_TRANS_SLIDEWIPE:
1825 gTransition->nSubType = MMS_SMIL_TRANS_SUB_FROM_LEFT;
1827 case MMS_SMIL_TRANS_BARWIPE:
1828 gTransition->nSubType = MMS_SMIL_TRANS_SUB_TOP_TO_BOTTOM;
1830 case MMS_SMIL_TRANS_BARNDOORWIPE:
1831 gTransition->nSubType = MMS_SMIL_TRANS_SUB_HORIZONTAL;
1834 gTransition->nSubType = MMS_SMIL_TRANS_SUB_NONE;
1840 case ATTRIBUTE_SUBTYPE:
1842 gTransition->nSubType = (MmsSmilTransSubType)atoi((char *)pAttr->children->content);
1845 case ATTRIBUTE_CONTENT:
1847 strncpy(gMeta->szContent, (char *)pAttr->children->content, MAX_SMIL_META_CONTENT - 1);
1851 MSG_DEBUG("Undefined Attribute was found!!!!!");
1856 if (cur_node->children) { /* child first */
1857 MsgSmilParseNode(pMmsMsg, cur_node->children, depth + 1);
1860 if (elementType == ELEMENT_REGION && gRegion) {
1861 _MsgMmsAddRegion(pMmsMsg, gRegion);
1863 } else if (elementType == ELEMENT_PAR && gPage) {
1864 _MsgMmsAddPage(pMmsMsg, gPage);
1866 } else if ((elementType == ELEMENT_TEXT || elementType == ELEMENT_IMG || elementType == ELEMENT_AUDIO || elementType == ELEMENT_VIDEO || elementType == ELEMENT_ANIMATE || elementType == ELEMENT_REF)
1867 && gCmd[ELEMENT_PAR] && gPage && gMedia) {
1868 _MsgMmsAddMedia(gPage, gMedia);
1870 } else if (elementType == ELEMENT_ROOTLAYOUT) {
1871 _MsgMmsSetRootLayout(pMmsMsg, &gRootlayout);
1872 } else if (elementType == ELEMENT_TRANSITION && gTransition) {
1873 _MsgMmsAddTransition(pMmsMsg, gTransition);
1875 } else if (elementType == ELEMENT_META && gMeta) {
1876 _MsgMmsAddMeta(pMmsMsg, gMeta);
1880 if (elementType >= ELEMENT_SMIL)
1881 gCmd[elementType] = false;
1883 paramType = ATTRIBUTE_UNKNOWN;
1890 bool MsgSmilParseSmilDoc(MMS_MESSAGE_DATA_S *pstMsgMmsBody, const char *pSmilDoc)
1897 if (pSmilDoc == NULL || strlen(pSmilDoc) == 0) {
1898 MSG_DEBUG("Invalid Parameter : pSmilDoc [%p]", pSmilDoc);
1902 MSG_SEC_INFO("Parse Smil : [%s]", pSmilDoc);
1904 doc = xmlParseMemory(pSmilDoc, strlen(pSmilDoc));
1906 MSG_DEBUG("Failed xmlParseMemory");
1910 cur = xmlDocGetRootElement(doc);
1912 MSG_DEBUG("Failed xmlDocGetRootElement");
1917 if (xmlStrcmp(cur->name, (const xmlChar *) "smil")) {
1918 MSG_DEBUG("document of the wrong type, root node != smil");
1923 MsgSmilParseNode(pstMsgMmsBody, cur, 0);
1930 bool MsgSmilGenerateSmilDoc(MMS_MESSAGE_DATA_S *pstMsgMmsBody, char **ppSmilDoc)
1934 HMsgSmil hSmilDoc = INVALID_HOBJ;
1940 MMS_PAGE_S *pstPage;
1941 MMS_MEDIA_S *pstMedia;
1942 MMS_SMIL_REGION *pstRegion;
1945 hSmilDoc = MsgSmilCreateEmptySmilDoc();
1946 if (INVALID_HOBJ == hSmilDoc) {
1947 MSG_DEBUG("Invalid SmilDoc[%d]", hSmilDoc);
1950 /* Add Root Layout to Smil Document */
1951 if (false == MsgSmilAddRootLayout(hSmilDoc, &(pstMsgMmsBody->rootlayout))) {
1952 MSG_DEBUG("MsgSmilAddRootLayout Failed");
1953 MsgSmilDestroyDoc(hSmilDoc);
1955 /* Add Region list to Smil Document */
1956 nRegionCount = pstMsgMmsBody->regionCnt;
1957 MSG_DEBUG("Region Count = [%d]", nRegionCount);
1958 for (nIndex = 0; nIndex < nRegionCount; nIndex++) {
1959 pstRegion = _MsgMmsGetSmilRegion(pstMsgMmsBody, nIndex);
1960 if (NULL == pstRegion) {
1961 MSG_DEBUG("pstRegion is NULL");
1962 MsgSmilDestroyDoc(hSmilDoc);
1966 if (false == MsgSmilAddRegion(hSmilDoc, pstRegion)) {
1967 MSG_DEBUG("Adding Region to smil doc failed");
1968 MsgSmilDestroyDoc(hSmilDoc);
1973 /* Add page list to Smil Document */
1974 nTotalPageNum = pstMsgMmsBody->pageCnt ;
1975 MSG_DEBUG("Page Count = [%d]", nTotalPageNum);
1976 for (nIndex = 0; nIndex < nTotalPageNum; nIndex++) {
1977 pstPage = _MsgMmsGetPage(pstMsgMmsBody, nIndex);
1978 if (NULL == pstPage) {
1979 MSG_DEBUG("pstPage is NULL");
1980 MsgSmilDestroyDoc(hSmilDoc);
1984 /* Add page to smil doc */
1985 if (false == MsgSmilAddPage(hSmilDoc, pstPage)) {
1986 MSG_DEBUG("Adding page to smil doc failed");
1987 MsgSmilDestroyDoc(hSmilDoc);
1991 nTotalMediaNum = pstPage->mediaCnt;
1992 MSG_DEBUG("Media Count = [%d]", nTotalMediaNum);
1993 for (nMediaIndex = 0; nMediaIndex < nTotalMediaNum; nMediaIndex++) {
1994 pstMedia = _MsgMmsGetMedia(pstPage, nMediaIndex);
1995 if (NULL == pstMedia) {
1996 MSG_DEBUG("pMedia is NULL");
1997 MsgSmilDestroyDoc(hSmilDoc);
2001 if (false == MsgSmilAddMedia(hSmilDoc, nIndex, nMediaIndex, pstMedia, pstMedia->szContentID)) {
2002 MSG_DEBUG("MsgSmilAddMedia failed");
2003 MsgSmilDestroyDoc(hSmilDoc);
2009 pszRawData = MsgSmilGetRawData(hSmilDoc);
2010 if (NULL == pszRawData) {
2011 MSG_DEBUG("MsgSmilGetRawData failed");
2012 MsgSmilDestroyDoc(hSmilDoc);
2017 *ppSmilDoc = pszRawData;
2018 MSG_SEC_INFO("Generated Smil : [%s]", pszRawData);
2021 MsgSmilDestroyDoc(hSmilDoc);