rfxswf cleanup: replaced LP<type> by <type> *
authorboehme <boehme>
Sun, 28 Oct 2001 13:06:33 +0000 (13:06 +0000)
committerboehme <boehme>
Sun, 28 Oct 2001 13:06:33 +0000 (13:06 +0000)
used tool: sed 's/\<LP\([A-Z]*\)\>/\1 */g'

lib/modules/swfbits.c
lib/modules/swfbutton.c
lib/modules/swfcgi.c
lib/modules/swfdump.c
lib/modules/swfobject.c
lib/modules/swfshape.c
lib/modules/swftext.c
lib/modules/swftools.c
lib/rfxswf.c
lib/rfxswf.h

index 5106df5..2ecc39d 100644 (file)
@@ -16,7 +16,7 @@
 
 typedef struct _JPEGDESTMGR
 { struct jpeg_destination_mgr mgr;
-  LPTAG  t;
+  TAG *  t;
   JOCTET * buffer;
   struct jpeg_compress_struct cinfo;
   struct jpeg_error_mgr jerr;
@@ -25,14 +25,14 @@ typedef struct _JPEGDESTMGR
 // Destination manager callbacks
 
 void swf_init_destination(j_compress_ptr cinfo) 
-{ LPJPEGDESTMGR dmgr = (LPJPEGDESTMGR)cinfo->dest;
+{ JPEGDESTMGR * dmgr = (JPEGDESTMGR *)cinfo->dest;
   dmgr->buffer = (JOCTET*)malloc(OUTBUFFER_SIZE);
   dmgr->mgr.next_output_byte = dmgr->buffer;
   dmgr->mgr.free_in_buffer = OUTBUFFER_SIZE;
 }
 
 boolean swf_empty_output_buffer(j_compress_ptr cinfo)
-{ LPJPEGDESTMGR dmgr = (LPJPEGDESTMGR)cinfo->dest;
+{ JPEGDESTMGR * dmgr = (JPEGDESTMGR *)cinfo->dest;
   SetBlock(dmgr->t,(U8*)dmgr->buffer,OUTBUFFER_SIZE);
   dmgr->mgr.next_output_byte = dmgr->buffer;
   dmgr->mgr.free_in_buffer = OUTBUFFER_SIZE;
@@ -40,19 +40,19 @@ boolean swf_empty_output_buffer(j_compress_ptr cinfo)
 }
 
 void swf_term_destination(j_compress_ptr cinfo) 
-{ LPJPEGDESTMGR dmgr = (LPJPEGDESTMGR)cinfo->dest;
+{ JPEGDESTMGR * dmgr = (JPEGDESTMGR *)cinfo->dest;
   SetBlock(dmgr->t,(U8*)dmgr->buffer,OUTBUFFER_SIZE-dmgr->mgr.free_in_buffer);
   free(dmgr->buffer);
   dmgr->mgr.free_in_buffer = 0;
 }
 
-LPJPEGBITS SetJPEGBitsStart(LPTAG t,int width,int height,int quality)
+JPEGBITS * SetJPEGBitsStart(TAG * t,int width,int height,int quality)
 {
-  LPJPEGDESTMGR jpeg;
+  JPEGDESTMGR * jpeg;
         
   // redirect compression lib output to local SWF Tag structure
   
-  jpeg = (LPJPEGDESTMGR)malloc(sizeof(JPEGDESTMGR));
+  jpeg = (JPEGDESTMGR *)malloc(sizeof(JPEGDESTMGR));
   if (!jpeg) return NULL;
   
   memset(jpeg,0x00,sizeof(JPEGDESTMGR));
@@ -87,32 +87,32 @@ LPJPEGBITS SetJPEGBitsStart(LPTAG t,int width,int height,int quality)
   jpeg_suppress_tables(&jpeg->cinfo, TRUE);
   jpeg_start_compress(&jpeg->cinfo, FALSE);
 
-  return (LPJPEGBITS)jpeg;
+  return (JPEGBITS *)jpeg;
 }
 
-int SetJPEGBitsLines(LPJPEGBITS jpegbits,U8 ** data,int n)
-{ LPJPEGDESTMGR jpeg = (LPJPEGDESTMGR)jpegbits;
+int SetJPEGBitsLines(JPEGBITS * jpegbits,U8 ** data,int n)
+{ JPEGDESTMGR * jpeg = (JPEGDESTMGR *)jpegbits;
   if (!jpeg) return -1;
   jpeg_write_scanlines(&jpeg->cinfo,data,n);
   return 0;
 }
 
-int SetJPEGBitsLine(LPJPEGBITS jpegbits,U8 * data)
+int SetJPEGBitsLine(JPEGBITS * jpegbits,U8 * data)
 { return SetJPEGBitsLines(jpegbits,&data,1);
 }
 
-int SetJPEGBitsFinish(LPJPEGBITS jpegbits)
-{ LPJPEGDESTMGR jpeg = (LPJPEGDESTMGR)jpegbits;
+int SetJPEGBitsFinish(JPEGBITS * jpegbits)
+{ JPEGDESTMGR * jpeg = (JPEGDESTMGR *)jpegbits;
   if (!jpeg) return -1;
   jpeg_finish_compress(&jpeg->cinfo);
   free(jpeg);
   return 0;
 }
 
-int SetJPEGBits(LPTAG t,char * fname,int quality)
+int SetJPEGBits(TAG * t,char * fname,int quality)
 { struct jpeg_decompress_struct cinfo;
   struct jpeg_error_mgr jerr;
-  LPJPEGBITS out;
+  JPEGBITS * out;
   FILE * f;
   U8 * scanline;
   
index 23bd3c7..fc1d087 100644 (file)
@@ -1,92 +1,92 @@
-/* swfbutton.c\r
-\r
-   Button functions\r
-\r
-   Extension module for the rfxswf library.\r
-   Part of the swftools package.\r
-\r
-   Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
\r
-   This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-int ButtonSetRecord(LPTAG t,U8 state,U16 id,U16 layer,LPMATRIX m,LPCXFORM cx)\r
-\r
-{ SetU8(t,state);\r
-  SetU16(t,id);\r
-  SetU16(t,layer);\r
-  SetMatrix(t,m);\r
-//  SetCXForm(t,cx,0);\r
-  return 0;\r
-}\r
-\r
-int ButtonSetCondition(LPTAG t,U16 condition)\r
-{ SetU16(t,0); // dummy for Action Offset -> later set by ButtonPostProcess\r
-  SetU16(t,condition);\r
-  return 0;\r
-}\r
-\r
-int ButtonSetFlags(LPTAG t,U8 flags)\r
-{ if (GetTagID(t)==ST_DEFINEBUTTON2)\r
-  { SetU8(t,flags);\r
-    SetU16(t,0); // dummy for Action Offset -> later set by ButtonPostProcess\r
-  }\r
-  return 0;\r
-}\r
-\r
-void SetButtonOffset(LPTAG t,U32 offsetpos)\r
-{ U32 now = GetTagPos(t);\r
-  U16 diff = now-offsetpos;\r
-  SetTagPos(t,offsetpos);\r
-  t->data[t->pos++] = (U8)(diff&0xff);\r
-  t->data[t->pos++] = (U8)(diff>>8);\r
-  SetTagPos(t,now);\r
-}\r
-\r
-int ButtonPostProcess(LPTAG t,int anz_action)\r
-{ if (GetTagID(t)==ST_DEFINEBUTTON2)\r
-  { U32 oldTagPos;\r
-    U32 offsetpos;\r
-\r
-    oldTagPos = GetTagPos(t);\r
-\r
-    // scan DefineButton2 Record\r
-    \r
-    GetU16(t);          // Character ID\r
-    GetU8(t);           // Flags;\r
-\r
-    offsetpos = GetTagPos(t);  // first offset\r
-    GetU16(t);\r
-\r
-    while (GetU8(t))      // state  -> parse ButtonRecord\r
-    { GetU16(t);          // id\r
-      GetU16(t);          // layer\r
-      GetMatrix(t,NULL);  // matrix\r
-      // evtl.: CXForm\r
-    }\r
-\r
-    SetButtonOffset(t,offsetpos);\r
-\r
-    while(anz_action)\r
-    { U8 a;\r
-        \r
-      offsetpos = GetTagPos(t); // offset\r
-      GetU16(t);\r
-\r
-      GetU16(t);                // condition\r
-      \r
-      while (a=GetU8(t))        // skip action records\r
-      { if (a&0x80)\r
-        { U16 l = GetU16(t);\r
-          GetBlock(t,NULL,l);\r
-        }\r
-      }\r
-      \r
-      if (--anz_action) SetButtonOffset(t,offsetpos);\r
-    }\r
-    \r
-    SetTagPos(t,oldTagPos);\r
-  }\r
-  return 0;\r
-}\r
+/* swfbutton.c
+
+   Button functions
+
+   Extension module for the rfxswf library.
+   Part of the swftools package.
+
+   Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+   This file is distributed under the GPL, see file COPYING for details 
+
+*/
+
+int ButtonSetRecord(TAG * t,U8 state,U16 id,U16 layer,MATRIX * m,CXFORM * cx)
+
+{ SetU8(t,state);
+  SetU16(t,id);
+  SetU16(t,layer);
+  SetMatrix(t,m);
+//  SetCXForm(t,cx,0);
+  return 0;
+}
+
+int ButtonSetCondition(TAG * t,U16 condition)
+{ SetU16(t,0); // dummy for Action Offset -> later set by ButtonPostProcess
+  SetU16(t,condition);
+  return 0;
+}
+
+int ButtonSetFlags(TAG * t,U8 flags)
+{ if (GetTagID(t)==ST_DEFINEBUTTON2)
+  { SetU8(t,flags);
+    SetU16(t,0); // dummy for Action Offset -> later set by ButtonPostProcess
+  }
+  return 0;
+}
+
+void SetButtonOffset(TAG * t,U32 offsetpos)
+{ U32 now = GetTagPos(t);
+  U16 diff = now-offsetpos;
+  SetTagPos(t,offsetpos);
+  t->data[t->pos++] = (U8)(diff&0xff);
+  t->data[t->pos++] = (U8)(diff>>8);
+  SetTagPos(t,now);
+}
+
+int ButtonPostProcess(TAG * t,int anz_action)
+{ if (GetTagID(t)==ST_DEFINEBUTTON2)
+  { U32 oldTagPos;
+    U32 offsetpos;
+
+    oldTagPos = GetTagPos(t);
+
+    // scan DefineButton2 Record
+    
+    GetU16(t);          // Character ID
+    GetU8(t);           // Flags;
+
+    offsetpos = GetTagPos(t);  // first offset
+    GetU16(t);
+
+    while (GetU8(t))      // state  -> parse ButtonRecord
+    { GetU16(t);          // id
+      GetU16(t);          // layer
+      GetMatrix(t,NULL);  // matrix
+      // evtl.: CXForm
+    }
+
+    SetButtonOffset(t,offsetpos);
+
+    while(anz_action)
+    { U8 a;
+        
+      offsetpos = GetTagPos(t); // offset
+      GetU16(t);
+
+      GetU16(t);                // condition
+      
+      while (a=GetU8(t))        // skip action records
+      { if (a&0x80)
+        { U16 l = GetU16(t);
+          GetBlock(t,NULL,l);
+        }
+      }
+      
+      if (--anz_action) SetButtonOffset(t,offsetpos);
+    }
+    
+    SetTagPos(t,oldTagPos);
+  }
+  return 0;
+}
index 98e5f03..67f6881 100644 (file)
-/* swfcgi.c\r
-\r
-   Parse CGI parameters\r
-   \r
-   Partly adopted from Steven Grimm's uncgi tool and library.\r
-\r
-   Extension module for the rfxswf library.\r
-   Part of the swftools package.\r
-\r
-   Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
\r
-   This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-\r
-#define ishex(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))\r
-\r
-#define PREFIX "WWW_"\r
-\r
-static int htoi(unsigned char * s)\r
-{ int     value;\r
-  char    c;\r
-\r
-  c = s[0];\r
-  if (isupper(c)) c = tolower(c);\r
-  value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;\r
-\r
-  c = s[1];\r
-  if (isupper(c)) c = tolower(c);\r
-  value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;\r
-\r
-  return (value);\r
-}\r
-\r
-static void url_unescape(unsigned char * s)\r
-{ unsigned char  *dest = s;\r
-\r
-  while (s[0])\r
-  { if (s[0] == '+') dest[0] = ' ';\r
-    else\r
-    { if (s[0] == '%' && ishex(s[1]) && ishex(s[2]))\r
-      { dest[0] = (unsigned char) htoi(s + 1);\r
-        s += 2;\r
-      }\r
-      else dest[0] = s[0];\r
-    }\r
-    s++;dest++;\r
-  }\r
-  dest[0] = 0;\r
-}\r
-\r
-static void cgienv(unsigned char * var)\r
-{ unsigned char *buf, *c, *s, *t, *oldval = NULL, *newval;\r
-  int despace = 0, got_cr = 0;\r
-\r
-  // fprintf(stderr,"%s\n",var);\r
-  url_unescape(var);\r
-  // fprintf(stderr,"%s\n",var);\r
-\r
-  \r
-  buf = (unsigned char*)malloc(strlen(var) + sizeof(PREFIX) + 2);\r
-  if (!buf) return;\r
-\r
-  strcpy(buf, PREFIX);\r
-  if (var[0] == '_')\r
-  { strcpy(&buf[sizeof(PREFIX)-1], &var[1]);\r
-    despace = 1;\r
-  }\r
-  else strcpy(&buf[sizeof(PREFIX)-1], var);\r
-\r
-  for (c = buf; c[0] ; c++)\r
-  { if (c[0] == '.') c[0] = '_';\r
-    if (c[0] == '=') break;\r
-  }\r
-  if (!c[0]) c[1] = 0;\r
-  c[0] = 0;\r
-\r
-  if (despace && c[1])\r
-  { for (s = c+1; s[0] && isspace(s[0]); s++);\r
-    t = c + 1;\r
-    while (s[0])\r
-    { if (s[0] == '\r')\r
-      { got_cr = 1;\r
-        s++;\r
-        continue;\r
-      }\r
-      if (got_cr)\r
-      { if (s[0] != '\n')\r
-        *t++ = '\n';\r
-        got_cr = 0;\r
-      }\r
-      *t++ = *s++;\r
-    }\r
-    while (t > c && isspace(*--t));\r
-    t[1] = 0;\r
-  }\r
-\r
-  if ((oldval = getenv(buf)))\r
-  { newval = (unsigned char*)malloc(strlen(oldval) + strlen(buf) + strlen(&c[1]) + 3);\r
-    if (!newval) return;\r
-\r
-    c[0] = '=';\r
-    sprintf(newval, "%s#%s", buf, oldval);\r
-    c[0] = 0;\r
-\r
-    oldval -= strlen(buf) + 1; // skip past VAR= \r
-  }\r
-  else \r
-  { c[0] = '=';\r
-    newval = buf;\r
-  }\r
-  \r
-  putenv(newval);\r
-        \r
-  if (oldval)\r
-  { free(oldval);\r
-    free(buf);\r
-  }\r
-}\r
-\r
-static void scanquery(char * q)\r
-{ char *next = q;\r
-  if (!q) return;\r
-\r
-  while (next)\r
-  { next = strchr(q, '&');\r
-    if (next) next[0] = 0;\r
-    cgienv(q);\r
-    if (next)\r
-    { next[0] = '&';\r
-      q = next+1;\r
-    }\r
-  } \r
-}\r
-\r
-char * postread()\r
-{ char * buf = NULL;\r
-  int size = 0, sofar = 0, got;\r
-\r
-  buf = getenv("CONTENT_TYPE");\r
-  if ((!buf) || strcmp(buf, "application/x-www-form-urlencoded")) return NULL;\r
-\r
-  buf = getenv("CONTENT_LENGTH");\r
-  if (!buf) return NULL;\r
-        \r
-  size = atoi(buf);\r
-  buf = (unsigned char*)malloc(size + 1);\r
-  if (buf)\r
-  { do\r
-    { got = fread(buf + sofar, 1, size - sofar, stdin);\r
-      sofar += got;\r
-    } while (got && sofar < size);\r
-    buf[sofar] = 0;\r
-  }\r
-\r
-  return buf;\r
-}\r
-\r
-void uncgi()\r
-{ char *query, *dupquery, *method;\r
-\r
-  query = getenv("QUERY_STRING");\r
-  if ((query) && strlen(query))\r
-  { dupquery = strdup(query);\r
-    scanquery(dupquery);\r
-    free(dupquery);\r
-  }\r
-\r
-  method = getenv("REQUEST_METHOD");\r
-  if ((method) && ! strcmp(method, "POST"))\r
-  { query = postread();\r
-    if ((query)&&(query[0]!=0)) scanquery(query);\r
-    free(query);\r
-  }\r
-  \r
-}\r
-      \r
-#undef ishex\r
+/* swfcgi.c
+
+   Parse CGI parameters
+   
+   Partly adopted from Steven Grimm's uncgi tool and library.
+
+   Extension module for the rfxswf library.
+   Part of the swftools package.
+
+   Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+   This file is distributed under the GPL, see file COPYING for details 
+
+*/
+
+
+#define ishex(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
+
+#define PREFIX "WWW_"
+
+static int htoi(unsigned char * s)
+{ int     value;
+  char    c;
+
+  c = s[0];
+  if (isupper(c)) c = tolower(c);
+  value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
+
+  c = s[1];
+  if (isupper(c)) c = tolower(c);
+  value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
+
+  return (value);
+}
+
+static void url_unescape(unsigned char * s)
+{ unsigned char  *dest = s;
+
+  while (s[0])
+  { if (s[0] == '+') dest[0] = ' ';
+    else
+    { if (s[0] == '%' && ishex(s[1]) && ishex(s[2]))
+      { dest[0] = (unsigned char) htoi(s + 1);
+        s += 2;
+      }
+      else dest[0] = s[0];
+    }
+    s++;dest++;
+  }
+  dest[0] = 0;
+}
+
+static void cgienv(unsigned char * var)
+{ unsigned char *buf, *c, *s, *t, *oldval = NULL, *newval;
+  int despace = 0, got_cr = 0;
+
+  // fprintf(stderr,"%s\n",var);
+  url_unescape(var);
+  // fprintf(stderr,"%s\n",var);
+
+  
+  buf = (unsigned char*)malloc(strlen(var) + sizeof(PREFIX) + 2);
+  if (!buf) return;
+
+  strcpy(buf, PREFIX);
+  if (var[0] == '_')
+  { strcpy(&buf[sizeof(PREFIX)-1], &var[1]);
+    despace = 1;
+  }
+  else strcpy(&buf[sizeof(PREFIX)-1], var);
+
+  for (c = buf; c[0] ; c++)
+  { if (c[0] == '.') c[0] = '_';
+    if (c[0] == '=') break;
+  }
+  if (!c[0]) c[1] = 0;
+  c[0] = 0;
+
+  if (despace && c[1])
+  { for (s = c+1; s[0] && isspace(s[0]); s++);
+    t = c + 1;
+    while (s[0])
+    { if (s[0] == '\r')
+      { got_cr = 1;
+        s++;
+        continue;
+      }
+      if (got_cr)
+      { if (s[0] != '\n')
+        *t++ = '\n';
+        got_cr = 0;
+      }
+      *t++ = *s++;
+    }
+    while (t > c && isspace(*--t));
+    t[1] = 0;
+  }
+
+  if ((oldval = getenv(buf)))
+  { newval = (unsigned char*)malloc(strlen(oldval) + strlen(buf) + strlen(&c[1]) + 3);
+    if (!newval) return;
+
+    c[0] = '=';
+    sprintf(newval, "%s#%s", buf, oldval);
+    c[0] = 0;
+
+    oldval -= strlen(buf) + 1; // skip past VAR= 
+  }
+  else 
+  { c[0] = '=';
+    newval = buf;
+  }
+  
+  putenv(newval);
+        
+  if (oldval)
+  { free(oldval);
+    free(buf);
+  }
+}
+
+static void scanquery(char * q)
+{ char *next = q;
+  if (!q) return;
+
+  while (next)
+  { next = strchr(q, '&');
+    if (next) next[0] = 0;
+    cgienv(q);
+    if (next)
+    { next[0] = '&';
+      q = next+1;
+    }
+  } 
+}
+
+char * postread()
+{ char * buf = NULL;
+  int size = 0, sofar = 0, got;
+
+  buf = getenv("CONTENT_TYPE");
+  if ((!buf) || strcmp(buf, "application/x-www-form-urlencoded")) return NULL;
+
+  buf = getenv("CONTENT_LENGTH");
+  if (!buf) return NULL;
+        
+  size = atoi(buf);
+  buf = (unsigned char*)malloc(size + 1);
+  if (buf)
+  { do
+    { got = fread(buf + sofar, 1, size - sofar, stdin);
+      sofar += got;
+    } while (got && sofar < size);
+    buf[sofar] = 0;
+  }
+
+  return buf;
+}
+
+void uncgi()
+{ char *query, *dupquery, *method;
+
+  query = getenv("QUERY_STRING");
+  if ((query) && strlen(query))
+  { dupquery = strdup(query);
+    scanquery(dupquery);
+    free(dupquery);
+  }
+
+  method = getenv("REQUEST_METHOD");
+  if ((method) && ! strcmp(method, "POST"))
+  { query = postread();
+    if ((query)&&(query[0]!=0)) scanquery(query);
+    free(query);
+  }
+  
+}
+      
+#undef ishex
index 12b3fdf..f30202d 100644 (file)
-/* swfdump.c\r
-\r
-   Dump / debug functions\r
-   \r
-   Extension module for the rfxswf library.\r
-   Part of the swftools package.\r
-\r
-   Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
\r
-   This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-void DumpHeader(FILE * f,LPSWF swf)\r
-{ if (!f) f = stderr;\r
-  fprintf(f,"File size\t%u\n",swf->FileSize);\r
-  fprintf(f,"Movie width\t%u\n",(swf->MovieSize.xmax - swf->MovieSize.xmin)/20);\r
-  fprintf(f,"Movie height\t%u\n",(swf->MovieSize.ymax - swf->MovieSize.ymin)/20);\r
-  fprintf(f,"Frame rate\t%u.%u\n",swf->FrameRate>>8,swf->FrameRate&0xff);\r
-  fprintf(f,"Frame count\t%u\n",swf->FrameCount);\r
-}\r
-\r
-void DumpMatrix(FILE * f,LPMATRIX m)\r
-{ if (!f) f = stderr;\r
-  fprintf(f,"[%08x][%08x]\n",m->sx,m->r1);\r
-  fprintf(f,"[%08x][%08x]\n",m->r0,m->sy);\r
-  fprintf(f," %08x, %08x\n",m->tx,m->ty);\r
-}\r
-\r
-void DumpTag(FILE * f,LPTAG t)\r
-{ int i;\r
-  if (!f) f = stderr;\r
-  for (i=0;i<t->len;i++)\r
-  { if (!(i&15)) fprintf(f,"\n");\r
-    fprintf(f,"%02x ",t->data[i]);\r
-  }\r
-  fprintf(f,"\n");\r
-}\r
-\r
-char* getTagName(TAG*tag)\r
-{\r
-    switch(tag->id)\r
-    {\r
-       case ST_END:\r
-           return "END";\r
-       case ST_SHOWFRAME:\r
-           return "SHOWFRAME";\r
-       case ST_DEFINESHAPE:\r
-           return "DEFINESHAPE";\r
-       case ST_FREECHARACTER:\r
-           return "FREECHARACTER";\r
-       case ST_PLACEOBJECT:\r
-           return "PLACEOBJECT";\r
-       case ST_REMOVEOBJECT:\r
-           return "REMOVEOBJECT";\r
-       case ST_DEFINEBITS:\r
-           return "DEFINEBITS";\r
-       case ST_DEFINEBUTTON:\r
-           return "DEFINEBUTTON";\r
-       case ST_JPEGTABLES:\r
-           return "JPEGTABLES";\r
-       case ST_SETBACKGROUNDCOLOR:\r
-           return "SETBACKGROUNDCOLOR";\r
-       case ST_DEFINEFONT:\r
-           return "DEFINEFONT";\r
-       case ST_DEFINETEXT:\r
-           return "DEFINETEXT";\r
-       case ST_DOACTION:\r
-           return "DOACTION";\r
-       case ST_DEFINEFONTINFO:\r
-           return "DEFINEFONTINFO";\r
-       case ST_DEFINESOUND:\r
-           return "DEFINESOUND";\r
-       case ST_STARTSOUND:\r
-           return "STARTSOUND";\r
-       case ST_DEFINEBUTTONSOUND:\r
-           return "DEFINEBUTTONSOUND";\r
-       case ST_SOUNDSTREAMHEAD:\r
-           return "SOUNDSTREAMHEAD";\r
-       case ST_SOUNDSTREAMBLOCK:\r
-           return "SOUNDSTREAMBLOCK";\r
-       case ST_DEFINEBITSLOSSLESS:\r
-           return "DEFINEBITSLOSSLESS";\r
-       case ST_DEFINEBITSJPEG2:\r
-           return "DEFINEBITSJPEG2";\r
-       case ST_DEFINESHAPE2:\r
-           return "DEFINESHAPE2";\r
-       case ST_DEFINEBUTTONCXFORM:\r
-           return "DEFINEBUTTONCXFORM";\r
-       case ST_PROTECT:\r
-           return "PROTECT";\r
-       case ST_PLACEOBJECT2:\r
-           return "PLACEOBJECT2";\r
-       case ST_REMOVEOBJECT2:\r
-           return "REMOVEOBJECT2";\r
-       case ST_DEFINESHAPE3:\r
-           return "DEFINESHAPE3";\r
-       case ST_DEFINETEXT2:\r
-           return "DEFINETEXT2";\r
-       case ST_DEFINEBUTTON2:\r
-           return "DEFINEBUTTON2";\r
-       case ST_DEFINEBITSJPEG3:\r
-           return "DEFINEBITSJPEG3";\r
-       case ST_DEFINEBITSLOSSLESS2:\r
-           return "DEFINEBITSLOSSLESS2";\r
-       case ST_DEFINESPRITE:\r
-           return "DEFINESPRITE";\r
-       case ST_NAMECHARACTER:\r
-           return "NAMECHARACTER";\r
-       case ST_SERIALNUMBER:\r
-           return "SERIALNUMBER";\r
-       case ST_GENERATORTEXT:\r
-           return "GENERATORTEXT";\r
-       case ST_FRAMELABEL:\r
-           return "FRAMELABEL";\r
-       case ST_SOUNDSTREAMHEAD2:\r
-           return "SOUNDSTREAMHEAD2";\r
-       case ST_DEFINEMORPHSHAPE:\r
-           return "DEFINEMORPHSHAPE";\r
-       case ST_DEFINEFONT2:\r
-           return "DEFINEFONT2";\r
-       case ST_TEMPLATECOMMAND:\r
-           return "TEMPLATECOMMAND";\r
-       case ST_GENERATOR3:\r
-           return "GENERATOR3";\r
-       case ST_EXTERNALFONT:\r
-           return "EXTERNALFONT";\r
-       case ST_REFLEX:\r
-           return "REFLEX";\r
-    }\r
-}\r
+/* swfdump.c
+
+   Dump / debug functions
+   
+   Extension module for the rfxswf library.
+   Part of the swftools package.
+
+   Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+   This file is distributed under the GPL, see file COPYING for details 
+
+*/
+
+void DumpHeader(FILE * f,SWF * swf)
+{ if (!f) f = stderr;
+  fprintf(f,"File size\t%u\n",swf->FileSize);
+  fprintf(f,"Movie width\t%u\n",(swf->MovieSize.xmax - swf->MovieSize.xmin)/20);
+  fprintf(f,"Movie height\t%u\n",(swf->MovieSize.ymax - swf->MovieSize.ymin)/20);
+  fprintf(f,"Frame rate\t%u.%u\n",swf->FrameRate>>8,swf->FrameRate&0xff);
+  fprintf(f,"Frame count\t%u\n",swf->FrameCount);
+}
+
+void DumpMatrix(FILE * f,MATRIX * m)
+{ if (!f) f = stderr;
+  fprintf(f,"[%08x][%08x]\n",m->sx,m->r1);
+  fprintf(f,"[%08x][%08x]\n",m->r0,m->sy);
+  fprintf(f," %08x, %08x\n",m->tx,m->ty);
+}
+
+void DumpTag(FILE * f,TAG * t)
+{ int i;
+  if (!f) f = stderr;
+  for (i=0;i<t->len;i++)
+  { if (!(i&15)) fprintf(f,"\n");
+    fprintf(f,"%02x ",t->data[i]);
+  }
+  fprintf(f,"\n");
+}
+
+char* getTagName(TAG*tag)
+{
+    switch(tag->id)
+    {
+       case ST_END:
+           return "END";
+       case ST_SHOWFRAME:
+           return "SHOWFRAME";
+       case ST_DEFINESHAPE:
+           return "DEFINESHAPE";
+       case ST_FREECHARACTER:
+           return "FREECHARACTER";
+       case ST_PLACEOBJECT:
+           return "PLACEOBJECT";
+       case ST_REMOVEOBJECT:
+           return "REMOVEOBJECT";
+       case ST_DEFINEBITS:
+           return "DEFINEBITS";
+       case ST_DEFINEBUTTON:
+           return "DEFINEBUTTON";
+       case ST_JPEGTABLES:
+           return "JPEGTABLES";
+       case ST_SETBACKGROUNDCOLOR:
+           return "SETBACKGROUNDCOLOR";
+       case ST_DEFINEFONT:
+           return "DEFINEFONT";
+       case ST_DEFINETEXT:
+           return "DEFINETEXT";
+       case ST_DOACTION:
+           return "DOACTION";
+       case ST_DEFINEFONTINFO:
+           return "DEFINEFONTINFO";
+       case ST_DEFINESOUND:
+           return "DEFINESOUND";
+       case ST_STARTSOUND:
+           return "STARTSOUND";
+       case ST_DEFINEBUTTONSOUND:
+           return "DEFINEBUTTONSOUND";
+       case ST_SOUNDSTREAMHEAD:
+           return "SOUNDSTREAMHEAD";
+       case ST_SOUNDSTREAMBLOCK:
+           return "SOUNDSTREAMBLOCK";
+       case ST_DEFINEBITSLOSSLESS:
+           return "DEFINEBITSLOSSLESS";
+       case ST_DEFINEBITSJPEG2:
+           return "DEFINEBITSJPEG2";
+       case ST_DEFINESHAPE2:
+           return "DEFINESHAPE2";
+       case ST_DEFINEBUTTONCXFORM:
+           return "DEFINEBUTTONCXFORM";
+       case ST_PROTECT:
+           return "PROTECT";
+       case ST_PLACEOBJECT2:
+           return "PLACEOBJECT2";
+       case ST_REMOVEOBJECT2:
+           return "REMOVEOBJECT2";
+       case ST_DEFINESHAPE3:
+           return "DEFINESHAPE3";
+       case ST_DEFINETEXT2:
+           return "DEFINETEXT2";
+       case ST_DEFINEBUTTON2:
+           return "DEFINEBUTTON2";
+       case ST_DEFINEBITSJPEG3:
+           return "DEFINEBITSJPEG3";
+       case ST_DEFINEBITSLOSSLESS2:
+           return "DEFINEBITSLOSSLESS2";
+       case ST_DEFINESPRITE:
+           return "DEFINESPRITE";
+       case ST_NAMECHARACTER:
+           return "NAMECHARACTER";
+       case ST_SERIALNUMBER:
+           return "SERIALNUMBER";
+       case ST_GENERATORTEXT:
+           return "GENERATORTEXT";
+       case ST_FRAMELABEL:
+           return "FRAMELABEL";
+       case ST_SOUNDSTREAMHEAD2:
+           return "SOUNDSTREAMHEAD2";
+       case ST_DEFINEMORPHSHAPE:
+           return "DEFINEMORPHSHAPE";
+       case ST_DEFINEFONT2:
+           return "DEFINEFONT2";
+       case ST_TEMPLATECOMMAND:
+           return "TEMPLATECOMMAND";
+       case ST_GENERATOR3:
+           return "GENERATOR3";
+       case ST_EXTERNALFONT:
+           return "EXTERNALFONT";
+       case ST_REFLEX:
+           return "REFLEX";
+    }
+}
index 132f116..fe32e77 100644 (file)
@@ -1,59 +1,59 @@
-/* swfobject.c\r
-\r
-   Object place and move routines\r
-      \r
-   Extension module for the rfxswf library.\r
-   Part of the swftools package.\r
-\r
-   Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
\r
-   This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-#define PF_MOVE         0x01\r
-#define PF_CHAR         0x02\r
-#define PF_MATRIX       0x04\r
-#define PF_CXFORM       0x08\r
-#define PF_RATIO        0x10\r
-#define PF_NAME         0x20\r
-#define PF_CLIPACTION   0x40\r
-\r
-int ObjectPlace(LPTAG t,U16 id,U16 depth,LPMATRIX m,LPCXFORM cx,U8 * name)\r
-{ U8 flags;\r
-  if (!t) return -1;\r
-\r
-  flags = (id?PF_CHAR:0)|(m?PF_MATRIX:0)|(cx?PF_CXFORM:0)|(name?PF_NAME:0)|((m||cx)&&(!id)?PF_MOVE:0);\r
-\r
-  SetU8(t,flags);\r
-  SetU16(t,depth);\r
-  if (flags&PF_CHAR) SetU16(t,id);\r
-  if (flags&PF_MATRIX) SetMatrix(t,m);\r
-  if (flags&PF_CXFORM) SetCXForm(t,cx,(cx->a0!=256)||(cx->a1));\r
-  if (flags&PF_RATIO) SetU16(t,0);\r
-  if (flags&PF_NAME) SetString(t,name);\r
-  \r
-  return 0; \r
-}\r
-\r
-int PlaceObject(LPTAG t,U16 id,U16 depth,LPMATRIX m,LPCXFORM cx,U8 * name, U16 clipaction)\r
-{ U8 flags;\r
-  if (!t) return -1;\r
-\r
-  flags = (id?PF_CHAR:0)|(m?PF_MATRIX:0)|(cx?PF_CXFORM:0)|(name?PF_NAME:0)|\r
-          ((m||cx)&&(!id)?PF_MOVE:0)|(clipaction?PF_CLIPACTION:0);\r
-\r
-  SetU8(t,flags);\r
-  SetU16(t,depth);\r
-  if (flags&PF_CHAR) SetU16(t,id);\r
-  if (flags&PF_MATRIX) SetMatrix(t,m);\r
-  if (flags&PF_CXFORM) SetCXForm(t,cx,(cx->a0!=256)||(cx->a1));\r
-  if (flags&PF_RATIO) SetU16(t,0);\r
-  if (flags&PF_NAME) SetString(t,name);\r
-  if (flags&PF_CLIPACTION) SetU16(t, clipaction);\r
-  return 0; \r
-}\r
-\r
-int ObjectMove(LPTAG t,U16 depth,LPMATRIX m,LPCXFORM cx)\r
-{ return ObjectPlace(t,0,depth,m,cx,NULL);\r
-}\r
+/* swfobject.c
+
+   Object place and move routines
+      
+   Extension module for the rfxswf library.
+   Part of the swftools package.
+
+   Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+   This file is distributed under the GPL, see file COPYING for details 
+
+*/
+
+#define PF_MOVE         0x01
+#define PF_CHAR         0x02
+#define PF_MATRIX       0x04
+#define PF_CXFORM       0x08
+#define PF_RATIO        0x10
+#define PF_NAME         0x20
+#define PF_CLIPACTION   0x40
+
+int ObjectPlace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,U8 * name)
+{ U8 flags;
+  if (!t) return -1;
+
+  flags = (id?PF_CHAR:0)|(m?PF_MATRIX:0)|(cx?PF_CXFORM:0)|(name?PF_NAME:0)|((m||cx)&&(!id)?PF_MOVE:0);
+
+  SetU8(t,flags);
+  SetU16(t,depth);
+  if (flags&PF_CHAR) SetU16(t,id);
+  if (flags&PF_MATRIX) SetMatrix(t,m);
+  if (flags&PF_CXFORM) SetCXForm(t,cx,(cx->a0!=256)||(cx->a1));
+  if (flags&PF_RATIO) SetU16(t,0);
+  if (flags&PF_NAME) SetString(t,name);
+  
+  return 0; 
+}
+
+int PlaceObject(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,U8 * name, U16 clipaction)
+{ U8 flags;
+  if (!t) return -1;
+
+  flags = (id?PF_CHAR:0)|(m?PF_MATRIX:0)|(cx?PF_CXFORM:0)|(name?PF_NAME:0)|
+          ((m||cx)&&(!id)?PF_MOVE:0)|(clipaction?PF_CLIPACTION:0);
+
+  SetU8(t,flags);
+  SetU16(t,depth);
+  if (flags&PF_CHAR) SetU16(t,id);
+  if (flags&PF_MATRIX) SetMatrix(t,m);
+  if (flags&PF_CXFORM) SetCXForm(t,cx,(cx->a0!=256)||(cx->a1));
+  if (flags&PF_RATIO) SetU16(t,0);
+  if (flags&PF_NAME) SetString(t,name);
+  if (flags&PF_CLIPACTION) SetU16(t, clipaction);
+  return 0; 
+}
+
+int ObjectMove(TAG * t,U16 depth,MATRIX * m,CXFORM * cx)
+{ return ObjectPlace(t,0,depth,m,cx,NULL);
+}
index dbd6c56..a8ff956 100644 (file)
-/* swfshape.c\r
-\r
-   shape functions\r
-      \r
-   Extension module for the rfxswf library.\r
-   Part of the swftools package.\r
-\r
-   Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
\r
-   This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-#define SF_MOVETO       0x01\r
-#define SF_FILL0        0x02\r
-#define SF_FILL1        0x04\r
-#define SF_LINE         0x08\r
-#define SF_NEWSTYLE     0x10\r
-\r
-#define FILL_SOLID      0x00\r
-#define FILL_LINEAR     0x10  // Gradient\r
-#define FILL_RADIAL     0x12\r
-#define FILL_TILED      0x40  // Bitmap\r
-#define FILL_CLIPPED    0x41\r
-\r
-void ShapeFree(LPSHAPE s)\r
-{ if (s)\r
-  { if (s->linestyle.data) free(s->linestyle.data);\r
-    s->linestyle.data = NULL;\r
-    s->linestyle.n    = 0;\r
-    if (s->fillstyle.data) free(s->fillstyle.data);\r
-    s->fillstyle.data = NULL;\r
-    s->fillstyle.n    = 0;\r
-    if (s->data) free(s->data);\r
-    s->data = NULL;\r
-  }\r
-  free(s);\r
-}\r
-\r
-int NewShape(LPSHAPE * s)\r
-{ LPSHAPE sh;\r
-  if (!s) return -1;\r
-  sh = (LPSHAPE)malloc(sizeof(SHAPE)); s[0] = sh;\r
-  if (sh) memset(sh,0x00,sizeof(SHAPE));\r
-  return sh?0:-1;\r
-}\r
-\r
-int GetSimpleShape(LPTAG t,LPSHAPE * s) // without Linestyle/Fillstyle Record\r
-{ LPSHAPE sh;\r
-  int bitl, len;\r
-  int end;\r
-  U32 pos;\r
-  \r
-  if (FAILED(NewShape(s))) return -1;\r
-  sh = s[0];\r
-\r
-  ResetBitmask(t); \r
-  sh->bits.fill = (U16)GetBits(t,4);\r
-  sh->bits.line = (U16)GetBits(t,4);\r
-  bitl = 0; end = 0; pos = GetTagPos(t);\r
-\r
-  while (!end)\r
-  { int edge = GetBits(t,1); bitl+=1;\r
-    if (edge)\r
-    { bitl+=1;\r
-      if (GetBits(t,1))                 // Line\r
-      { U16 nbits = GetBits(t,4)+2;\r
-        bitl+=5;\r
-\r
-        if (GetBits(t,1))               // x/y Line\r
-        { GetBits(t,nbits);\r
-          GetBits(t,nbits);\r
-          bitl+=nbits*2;\r
-        }\r
-        else                            // hline/vline\r
-        { GetBits(t,nbits+1);\r
-          bitl+=nbits+1;\r
-        }\r
-      }\r
-      else                              // Curve\r
-      { U16 nbits = GetBits(t,4)+2;\r
-        bitl+=4;\r
-\r
-        GetBits(t,nbits);\r
-        GetBits(t,nbits);\r
-        GetBits(t,nbits);\r
-        GetBits(t,nbits);\r
-\r
-        bitl+=4*nbits;\r
-      }\r
-    }\r
-    else\r
-    { U16 flags = GetBits(t,5); bitl+=5;\r
-      if (flags)\r
-      {\r
-        if (flags&SF_MOVETO)\r
-        { U16 nbits = GetBits(t,5); bitl+=5;\r
-          GetBits(t,nbits);\r
-          GetBits(t,nbits);\r
-          bitl+=2*nbits;\r
-        }\r
-        \r
-        if (flags&SF_FILL0)\r
-        { GetBits(t,sh->bits.fill);\r
-          bitl+=sh->bits.fill;\r
-        }\r
-        \r
-        if (flags&SF_FILL1)\r
-        { GetBits(t,sh->bits.fill);\r
-          bitl+=sh->bits.fill;\r
-        }\r
-\r
-        if (flags&SF_LINE)\r
-        { GetBits(t,sh->bits.line);\r
-          bitl+=sh->bits.line;\r
-        }\r
-\r
-        if (flags&SF_NEWSTYLE)\r
-        { fprintf(stderr,"Can't process extended styles in shape.\n");\r
-        }\r
-      }\r
-      else end = 1;\r
-    }\r
-  }\r
-  SetTagPos(t,pos);\r
-  len = (bitl+7)/8;\r
-  \r
-  if (sh->data) free(sh->data);\r
-  sh->data = (U8*)malloc(len);\r
-  \r
-  if (sh->data)\r
-  { sh->bitlen = bitl;\r
-    GetBlock(t,sh->data,len);\r
-  }\r
-  else return -1;\r
-  \r
-  return len;\r
-}\r
-\r
-int SetSimpleShape(LPTAG t,LPSHAPE s) // without Linestyle/Fillstyle Record\r
-{ int l;\r
-\r
-  if (!s) return -1;\r
-  l = (s->bitlen+7)/8;\r
-\r
-  if (t)\r
-  { ResetBitcount(t);\r
-\r
-    SetBits(t,s->bits.fill,4);\r
-    SetBits(t,s->bits.line,4);\r
-    SetBlock(t,s->data,l);\r
-\r
-    ResetBitcount(t);\r
-  }\r
-  return l+1;\r
-}\r
-\r
-int SetFillStyle(LPTAG t,LPFILLSTYLE f)\r
-{ if ((!t)||(!f)) return -1;\r
-  SetU8(t,f->type);\r
-  \r
-  // no gradients yet!\r
-  \r
-  switch (f->type)\r
-  { case FILL_SOLID:\r
-      if (GetTagID(t)!=ST_DEFINESHAPE3) SetRGB(t,&f->color);\r
-      else SetRGBA(t,&f->color);\r
-      break;\r
-\r
-    case FILL_TILED:\r
-    case FILL_CLIPPED:\r
-      SetU16(t,f->id_bitmap);\r
-      SetMatrix(t,&f->m);\r
-      break;\r
-  }\r
-  \r
-  return 0;\r
-}\r
-\r
-int SetLineStyle(LPTAG t,LPLINESTYLE l)\r
-{ if ((!l)||(!t)) return -1;\r
-  SetU16(t,l->width);\r
-\r
-  if (GetTagID(t)!=ST_DEFINESHAPE3) SetRGB(t,&l->color);\r
-  else SetRGBA(t,&l->color);\r
-  \r
-  return 0;\r
-}\r
-\r
-int SetShapeStyleCount(LPTAG t,U16 n)\r
-{ if (n>254)\r
-  { SetU8(t,0xff);\r
-    SetU16(t,n);\r
-    return 3;\r
-  }\r
-  else\r
-  { SetU8(t,n);\r
-    return 1;\r
-  }\r
-}\r
-\r
-int SetShapeStyles(LPTAG t,LPSHAPE s)\r
-{ int i,l;\r
-  if (!s) return -1;\r
-\r
-  l = 0;\r
-  l += SetShapeStyleCount(t,s->fillstyle.n);\r
-\r
-  for (i=0;i<s->fillstyle.n;i++)\r
-    l+=SetFillStyle(t,&s->fillstyle.data[i]);\r
-\r
-  l += SetShapeStyleCount(t,s->linestyle.n);\r
-\r
-  for (i=0;i<s->linestyle.n;i++)\r
-    l+=SetLineStyle(t,&s->linestyle.data[i]);\r
-\r
-  return l;\r
-}\r
-\r
-int ShapeCountBits(LPSHAPE s,U8 * fbits,U8 * lbits)\r
-{ if (!s) return -1;\r
-    \r
-  s->bits.fill = CountBits(s->fillstyle.n,0);\r
-  s->bits.line = CountBits(s->linestyle.n,0);\r
-\r
-  if (fbits) fbits[0] = s->bits.fill;\r
-  if (lbits) lbits[0] = s->bits.line;\r
-  \r
-  return 0;    \r
-}\r
-\r
-int SetShapeBits(LPTAG t,LPSHAPE s)\r
-{ if ((!t)||(!s)) return -1;\r
-  ResetBitcount(t);\r
-  SetBits(t,s->bits.fill,4);\r
-  SetBits(t,s->bits.line,4);\r
-  return 0;\r
-}\r
-\r
-int SetShapeHeader(LPTAG t,LPSHAPE s)\r
-{ int res;\r
-  res = SetShapeStyles(t,s);\r
-  if (res>=0) res = ShapeCountBits(s,NULL,NULL);\r
-  if (res>=0) res = SetShapeBits(t,s);\r
-  return res;\r
-}\r
-\r
-int ShapeExport(int handle,LPSHAPE s)  // without Linestyle/Fillstyle Record\r
-{ int l;\r
-  if (!s) return 0;\r
-\r
-  l = sizeof(SHAPE);\r
-\r
-  if (handle>=0)\r
-    if (write(handle,s,sizeof(SHAPE))!=sizeof(SHAPE)) return -1;\r
-\r
-  // Fillstyle, Linestyle ...\r
-\r
-  if (s->data)\r
-  { int ll = (s->bitlen+7)/8;\r
-    l+=ll;\r
-    if (handle>=0)\r
-      if (write(handle,s->data,ll)!=ll) return -1;\r
-  }\r
-\r
-  return l;\r
-}\r
-\r
-int ShapeImport(int handle,LPSHAPE * shape)\r
-{ LPSHAPE s;\r
-\r
-  if (handle<0) return -1;\r
-\r
-  s = (LPSHAPE)malloc(sizeof(SHAPE)); shape[0] = s;\r
-  if (!s) return -1;\r
-\r
-  if (read(handle,s,sizeof(SHAPE))!=sizeof(SHAPE))\r
-  { shape[0] = NULL;\r
-    free(s);\r
-    return -1;\r
-  }\r
-\r
-  if (s->data)\r
-  { int ll = (s->bitlen+7)/8;\r
-    s->data = (U8*)malloc(ll);\r
-    if (!s->data)\r
-    { shape[0] = NULL;\r
-      free(s);\r
-      return -1;\r
-    }\r
-    if (read(handle,s->data,ll)!=ll)\r
-    { free(s->data);\r
-      free(s);\r
-      shape[0] = NULL;\r
-      return -1;\r
-    }\r
-  }\r
-\r
-  return 0;\r
-}\r
-\r
-int ShapeAddFillStyle(LPSHAPE s,U8 type,LPMATRIX m,LPRGBA color,U16 id_bitmap)\r
-{ RGBA def_c;\r
-  MATRIX def_m;    \r
-\r
-  // handle defaults\r
-  \r
-  if (!s) return -1;\r
-  if (!color)\r
-  { color = &def_c;\r
-    def_c.a = 0xff;\r
-    def_c.r = def_c.g = def_c.b = 0;\r
-  }\r
-  if (!m)\r
-  { m = &def_m;\r
-    GetMatrix(NULL,m);\r
-  }\r
-\r
-  // handle memory\r
-  \r
-  if (s->fillstyle.data)\r
-  { LPFILLSTYLE new = (LPFILLSTYLE)realloc(s->fillstyle.data,(s->fillstyle.n+1)*sizeof(FILLSTYLE));\r
-    if (!new) return -1;\r
-    s->fillstyle.data = new;\r
-  }\r
-  else\r
-  { s->fillstyle.data = (LPFILLSTYLE)malloc(sizeof(FILLSTYLE));\r
-    s->fillstyle.n = 0;\r
-    if (!s->fillstyle.data) return -1;\r
-  }\r
-\r
-  // set fillstyle  (no gradients yet!)\r
-  \r
-  s->fillstyle.data[s->fillstyle.n].type = type; \r
-  s->fillstyle.data[s->fillstyle.n].id_bitmap = id_bitmap;\r
-  memcpy(&s->fillstyle.data[s->fillstyle.n].m,m,sizeof(MATRIX));\r
-  memcpy(&s->fillstyle.data[s->fillstyle.n].color,color,sizeof(RGBA));\r
-          \r
-  return (++s->fillstyle.n);\r
-}\r
-\r
-int ShapeAddSolidFillStyle(LPSHAPE s,LPRGBA color)\r
-{ return ShapeAddFillStyle(s,FILL_SOLID,NULL,color,0);\r
-}\r
-\r
-int ShapeAddBitmapFillStyle(LPSHAPE s,LPMATRIX m,U16 id_bitmap,int clip)\r
-{ return ShapeAddFillStyle(s,clip?FILL_CLIPPED:FILL_TILED,m,NULL,id_bitmap);\r
-}\r
-\r
-int ShapeAddLineStyle(LPSHAPE s,U16 width,LPRGBA color)\r
-{ RGBA def;\r
-  if (!s) return -1;\r
-  if (!color)\r
-  { color = &def;\r
-    def.a = 0xff;\r
-    def.r = def.g = def.b = 0; \r
-  }\r
-  if (s->linestyle.data)\r
-  { LPLINESTYLE new = (LPLINESTYLE)realloc(s->linestyle.data,(s->linestyle.n+1)*sizeof(LINESTYLE));\r
-    if (!new) return -1;\r
-    s->linestyle.data = new;\r
-  }\r
-  else\r
-  { s->linestyle.data = (LPLINESTYLE)malloc(sizeof(LINESTYLE));\r
-    s->linestyle.n = 0;\r
-    if (!s->linestyle.data) return -1;\r
-  }\r
-  \r
-  s->linestyle.data[s->linestyle.n].width = width;\r
-  memcpy(&s->linestyle.data[s->linestyle.n].color,color,sizeof(RGBA));\r
-\r
-  return (++s->linestyle.n);\r
-}\r
-\r
-int ShapeSetMove(LPTAG t,LPSHAPE s,S32 x,S32 y)\r
-{ U8 b;\r
-  if (!t) return -1;\r
-  SetBits(t,0,1);\r
-  SetBits(t,SF_MOVETO,5);\r
-  \r
-  b = CountBits(x,0);\r
-  b = CountBits(y,b);\r
-  \r
-  SetBits(t,b,5);\r
-  SetBits(t,x,b);\r
-  SetBits(t,y,b);\r
-\r
-  if (s)\r
-  { s->px = x;\r
-    s->py = y;\r
-  }\r
-  return 0;\r
-}\r
-\r
-int ShapeSetStyle(LPTAG t,LPSHAPE s,U16 line,U16 fill0,U16 fill1)\r
-{ if ((!t)||(!s)) return -1;\r
-    \r
-  SetBits(t,0,1);\r
-  SetBits(t,(line?SF_LINE:0)|(fill0?SF_FILL0:0)|(fill1?SF_FILL1:0),5);\r
-\r
-  if (fill0) SetBits(t,fill0,s->bits.fill);\r
-  if (fill1) SetBits(t,fill1,s->bits.fill);\r
-  if (line)  SetBits(t,line ,s->bits.line);\r
-  \r
-  return 0;\r
-}\r
-\r
-/* TODO: sometimes we want to set fillstyle 0, as that's the empty fill\r
-   used for line drawings. At the moment, we can't, as 0 fill be considered\r
-   nonexistent and therefore not set.\r
-   these defines are a workaround (they also reduce the maximal number of\r
-   fill styles to 32768)\r
- */\r
-#define FILL_RESET 0x8000\r
-#define LINE_RESET 0x8000\r
-int ShapeSetAll(LPTAG t,LPSHAPE s,S32 x,S32 y,U16 line,U16 fill0,U16 fill1)\r
-{ U8 b;\r
-  if ((!t)||(!s)) return -1;\r
-\r
-  SetBits(t,0,1);\r
-  SetBits(t,SF_MOVETO|(line?SF_LINE:0)|(fill0?SF_FILL0:0)|(fill1?SF_FILL1:0),5);\r
-\r
-  b = CountBits(x,0);\r
-  b = CountBits(y,b);\r
-  SetBits(t,b,5);\r
-  SetBits(t,x,b);\r
-  SetBits(t,y,b);\r
-  s->px = x;\r
-  s->py = y;\r
-\r
-  if (fill0) SetBits(t,fill0,s->bits.fill);\r
-  if (fill1) SetBits(t,fill1,s->bits.fill);\r
-  if (line)  SetBits(t,line ,s->bits.line);\r
-  \r
-  return 0;\r
-}\r
-\r
-int ShapeSetEnd(LPTAG t)\r
-{ if (!t) return -1;\r
-  SetBits(t,0,6);\r
-  ResetBitcount(t);\r
-  return 0;\r
-}\r
-\r
-int ShapeSetLine(LPTAG t,LPSHAPE s,S32 x,S32 y)\r
-{ U8 b;\r
-  if (!t) return -1;\r
-  SetBits(t,3,2); // Straight Edge\r
-\r
-  if ((!s)||((x!=0)&&(y!=0)))\r
-  { b = CountBits(x,2);\r
-    b = CountBits(y,b);\r
-    if(b<2) \r
-       b=2;\r
-    SetBits(t, b-2, 4);\r
-    SetBits(t,1,1);\r
-    SetBits(t,x,b);\r
-    SetBits(t,y,b);\r
-    if (s)\r
-    { s->px += x;\r
-      s->py += y;\r
-    }\r
-    return 0;\r
-  }\r
-\r
-  if (x==0)\r
-  { b = CountBits(y,2);\r
-    if(b<2) \r
-       b=2;\r
-    SetBits(t, b-2, 4);\r
-    SetBits(t,1,2);\r
-    SetBits(t,y,b);\r
-    s->py += y;\r
-  }\r
-  else\r
-  { b = CountBits(x,2);\r
-    if(b<2) \r
-       b=2;\r
-    SetBits(t, b-2, 4);\r
-    SetBits(t,0,2);\r
-    SetBits(t,x,b);\r
-    s->px += x;\r
-  }\r
-  return 0;\r
-}\r
-\r
-int ShapeSetCurve(LPTAG t,LPSHAPE s,S32 x,S32 y,S32 ax,S32 ay)\r
-{ U8 b;\r
-  if (!t) return -1;\r
-\r
-  SetBits(t,2,2);\r
-\r
-  b = CountBits(ax,2);\r
-  b = CountBits(ay,b);\r
-  b = CountBits(x,b);\r
-  b = CountBits(y,b);\r
-\r
-  SetBits(t,b-2,4);\r
-  SetBits(t,x,b);\r
-  SetBits(t,y,b);\r
-  SetBits(t,ax,b);\r
-  SetBits(t,ay,b);\r
-\r
-  if (s)\r
-  { s->px += x+ax;\r
-    s->py += y+ay;\r
-  }\r
-  return 0;\r
-}\r
-\r
-int ShapeSetCircle(LPTAG t,LPSHAPE s,S32 x,S32 y,S32 rx,S32 ry)\r
-{ double C1 = 0.2930;    \r
-  double C2 = 0.4140;   \r
-  double begin = 0.7070; \r
-\r
-  if (!t) return -1;\r
-  \r
-  ShapeSetMove(t,s,x+begin*rx,y+begin*ry);\r
-  ShapeSetCurve(t,s, -C1*rx,  C1*ry, -C2*rx,      0);\r
-  ShapeSetCurve(t,s, -C2*rx,      0, -C1*rx, -C1*ry);\r
-  ShapeSetCurve(t,s, -C1*rx, -C1*ry,      0, -C2*ry);\r
-  ShapeSetCurve(t,s,      0, -C2*ry,  C1*rx, -C1*ry);\r
-  ShapeSetCurve(t,s,  C1*rx, -C1*ry,  C2*rx,      0);\r
-  ShapeSetCurve(t,s,  C2*rx,      0,  C1*rx,  C1*ry);\r
-  ShapeSetCurve(t,s,  C1*rx,  C1*ry,      0,  C2*ry);\r
-  ShapeSetCurve(t,s,      0,  C2*ry, -C1*rx,  C1*ry);\r
-  \r
-  return 0;\r
-}\r
-\r
+/* swfshape.c
+
+   shape functions
+      
+   Extension module for the rfxswf library.
+   Part of the swftools package.
+
+   Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+   This file is distributed under the GPL, see file COPYING for details 
+
+*/
+
+#define SF_MOVETO       0x01
+#define SF_FILL0        0x02
+#define SF_FILL1        0x04
+#define SF_LINE         0x08
+#define SF_NEWSTYLE     0x10
+
+#define FILL_SOLID      0x00
+#define FILL_LINEAR     0x10  // Gradient
+#define FILL_RADIAL     0x12
+#define FILL_TILED      0x40  // Bitmap
+#define FILL_CLIPPED    0x41
+
+void ShapeFree(SHAPE * s)
+{ if (s)
+  { if (s->linestyle.data) free(s->linestyle.data);
+    s->linestyle.data = NULL;
+    s->linestyle.n    = 0;
+    if (s->fillstyle.data) free(s->fillstyle.data);
+    s->fillstyle.data = NULL;
+    s->fillstyle.n    = 0;
+    if (s->data) free(s->data);
+    s->data = NULL;
+  }
+  free(s);
+}
+
+int NewShape(SHAPE * * s)
+{ SHAPE * sh;
+  if (!s) return -1;
+  sh = (SHAPE *)malloc(sizeof(SHAPE)); s[0] = sh;
+  if (sh) memset(sh,0x00,sizeof(SHAPE));
+  return sh?0:-1;
+}
+
+int GetSimpleShape(TAG * t,SHAPE * * s) // without Linestyle/Fillstyle Record
+{ SHAPE * sh;
+  int bitl, len;
+  int end;
+  U32 pos;
+  
+  if (FAILED(NewShape(s))) return -1;
+  sh = s[0];
+
+  ResetBitmask(t); 
+  sh->bits.fill = (U16)GetBits(t,4);
+  sh->bits.line = (U16)GetBits(t,4);
+  bitl = 0; end = 0; pos = GetTagPos(t);
+
+  while (!end)
+  { int edge = GetBits(t,1); bitl+=1;
+    if (edge)
+    { bitl+=1;
+      if (GetBits(t,1))                 // Line
+      { U16 nbits = GetBits(t,4)+2;
+        bitl+=5;
+
+        if (GetBits(t,1))               // x/y Line
+        { GetBits(t,nbits);
+          GetBits(t,nbits);
+          bitl+=nbits*2;
+        }
+        else                            // hline/vline
+        { GetBits(t,nbits+1);
+          bitl+=nbits+1;
+        }
+      }
+      else                              // Curve
+      { U16 nbits = GetBits(t,4)+2;
+        bitl+=4;
+
+        GetBits(t,nbits);
+        GetBits(t,nbits);
+        GetBits(t,nbits);
+        GetBits(t,nbits);
+
+        bitl+=4*nbits;
+      }
+    }
+    else
+    { U16 flags = GetBits(t,5); bitl+=5;
+      if (flags)
+      {
+        if (flags&SF_MOVETO)
+        { U16 nbits = GetBits(t,5); bitl+=5;
+          GetBits(t,nbits);
+          GetBits(t,nbits);
+          bitl+=2*nbits;
+        }
+        
+        if (flags&SF_FILL0)
+        { GetBits(t,sh->bits.fill);
+          bitl+=sh->bits.fill;
+        }
+        
+        if (flags&SF_FILL1)
+        { GetBits(t,sh->bits.fill);
+          bitl+=sh->bits.fill;
+        }
+
+        if (flags&SF_LINE)
+        { GetBits(t,sh->bits.line);
+          bitl+=sh->bits.line;
+        }
+
+        if (flags&SF_NEWSTYLE)
+        { fprintf(stderr,"Can't process extended styles in shape.\n");
+        }
+      }
+      else end = 1;
+    }
+  }
+  SetTagPos(t,pos);
+  len = (bitl+7)/8;
+  
+  if (sh->data) free(sh->data);
+  sh->data = (U8*)malloc(len);
+  
+  if (sh->data)
+  { sh->bitlen = bitl;
+    GetBlock(t,sh->data,len);
+  }
+  else return -1;
+  
+  return len;
+}
+
+int SetSimpleShape(TAG * t,SHAPE * s) // without Linestyle/Fillstyle Record
+{ int l;
+
+  if (!s) return -1;
+  l = (s->bitlen+7)/8;
+
+  if (t)
+  { ResetBitcount(t);
+
+    SetBits(t,s->bits.fill,4);
+    SetBits(t,s->bits.line,4);
+    SetBlock(t,s->data,l);
+
+    ResetBitcount(t);
+  }
+  return l+1;
+}
+
+int SetFillStyle(TAG * t,FILLSTYLE * f)
+{ if ((!t)||(!f)) return -1;
+  SetU8(t,f->type);
+  
+  // no gradients yet!
+  
+  switch (f->type)
+  { case FILL_SOLID:
+      if (GetTagID(t)!=ST_DEFINESHAPE3) SetRGB(t,&f->color);
+      else SetRGBA(t,&f->color);
+      break;
+
+    case FILL_TILED:
+    case FILL_CLIPPED:
+      SetU16(t,f->id_bitmap);
+      SetMatrix(t,&f->m);
+      break;
+  }
+  
+  return 0;
+}
+
+int SetLineStyle(TAG * t,LINESTYLE * l)
+{ if ((!l)||(!t)) return -1;
+  SetU16(t,l->width);
+
+  if (GetTagID(t)!=ST_DEFINESHAPE3) SetRGB(t,&l->color);
+  else SetRGBA(t,&l->color);
+  
+  return 0;
+}
+
+int SetShapeStyleCount(TAG * t,U16 n)
+{ if (n>254)
+  { SetU8(t,0xff);
+    SetU16(t,n);
+    return 3;
+  }
+  else
+  { SetU8(t,n);
+    return 1;
+  }
+}
+
+int SetShapeStyles(TAG * t,SHAPE * s)
+{ int i,l;
+  if (!s) return -1;
+
+  l = 0;
+  l += SetShapeStyleCount(t,s->fillstyle.n);
+
+  for (i=0;i<s->fillstyle.n;i++)
+    l+=SetFillStyle(t,&s->fillstyle.data[i]);
+
+  l += SetShapeStyleCount(t,s->linestyle.n);
+
+  for (i=0;i<s->linestyle.n;i++)
+    l+=SetLineStyle(t,&s->linestyle.data[i]);
+
+  return l;
+}
+
+int ShapeCountBits(SHAPE * s,U8 * fbits,U8 * lbits)
+{ if (!s) return -1;
+    
+  s->bits.fill = CountBits(s->fillstyle.n,0);
+  s->bits.line = CountBits(s->linestyle.n,0);
+
+  if (fbits) fbits[0] = s->bits.fill;
+  if (lbits) lbits[0] = s->bits.line;
+  
+  return 0;    
+}
+
+int SetShapeBits(TAG * t,SHAPE * s)
+{ if ((!t)||(!s)) return -1;
+  ResetBitcount(t);
+  SetBits(t,s->bits.fill,4);
+  SetBits(t,s->bits.line,4);
+  return 0;
+}
+
+int SetShapeHeader(TAG * t,SHAPE * s)
+{ int res;
+  res = SetShapeStyles(t,s);
+  if (res>=0) res = ShapeCountBits(s,NULL,NULL);
+  if (res>=0) res = SetShapeBits(t,s);
+  return res;
+}
+
+int ShapeExport(int handle,SHAPE * s)  // without Linestyle/Fillstyle Record
+{ int l;
+  if (!s) return 0;
+
+  l = sizeof(SHAPE);
+
+  if (handle>=0)
+    if (write(handle,s,sizeof(SHAPE))!=sizeof(SHAPE)) return -1;
+
+  // Fillstyle, Linestyle ...
+
+  if (s->data)
+  { int ll = (s->bitlen+7)/8;
+    l+=ll;
+    if (handle>=0)
+      if (write(handle,s->data,ll)!=ll) return -1;
+  }
+
+  return l;
+}
+
+int ShapeImport(int handle,SHAPE * * shape)
+{ SHAPE * s;
+
+  if (handle<0) return -1;
+
+  s = (SHAPE *)malloc(sizeof(SHAPE)); shape[0] = s;
+  if (!s) return -1;
+
+  if (read(handle,s,sizeof(SHAPE))!=sizeof(SHAPE))
+  { shape[0] = NULL;
+    free(s);
+    return -1;
+  }
+
+  if (s->data)
+  { int ll = (s->bitlen+7)/8;
+    s->data = (U8*)malloc(ll);
+    if (!s->data)
+    { shape[0] = NULL;
+      free(s);
+      return -1;
+    }
+    if (read(handle,s->data,ll)!=ll)
+    { free(s->data);
+      free(s);
+      shape[0] = NULL;
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+int ShapeAddFillStyle(SHAPE * s,U8 type,MATRIX * m,RGBA * color,U16 id_bitmap)
+{ RGBA def_c;
+  MATRIX def_m;    
+
+  // handle defaults
+  
+  if (!s) return -1;
+  if (!color)
+  { color = &def_c;
+    def_c.a = 0xff;
+    def_c.r = def_c.g = def_c.b = 0;
+  }
+  if (!m)
+  { m = &def_m;
+    GetMatrix(NULL,m);
+  }
+
+  // handle memory
+  
+  if (s->fillstyle.data)
+  { FILLSTYLE * new = (FILLSTYLE *)realloc(s->fillstyle.data,(s->fillstyle.n+1)*sizeof(FILLSTYLE));
+    if (!new) return -1;
+    s->fillstyle.data = new;
+  }
+  else
+  { s->fillstyle.data = (FILLSTYLE *)malloc(sizeof(FILLSTYLE));
+    s->fillstyle.n = 0;
+    if (!s->fillstyle.data) return -1;
+  }
+
+  // set fillstyle  (no gradients yet!)
+  
+  s->fillstyle.data[s->fillstyle.n].type = type; 
+  s->fillstyle.data[s->fillstyle.n].id_bitmap = id_bitmap;
+  memcpy(&s->fillstyle.data[s->fillstyle.n].m,m,sizeof(MATRIX));
+  memcpy(&s->fillstyle.data[s->fillstyle.n].color,color,sizeof(RGBA));
+          
+  return (++s->fillstyle.n);
+}
+
+int ShapeAddSolidFillStyle(SHAPE * s,RGBA * color)
+{ return ShapeAddFillStyle(s,FILL_SOLID,NULL,color,0);
+}
+
+int ShapeAddBitmapFillStyle(SHAPE * s,MATRIX * m,U16 id_bitmap,int clip)
+{ return ShapeAddFillStyle(s,clip?FILL_CLIPPED:FILL_TILED,m,NULL,id_bitmap);
+}
+
+int ShapeAddLineStyle(SHAPE * s,U16 width,RGBA * color)
+{ RGBA def;
+  if (!s) return -1;
+  if (!color)
+  { color = &def;
+    def.a = 0xff;
+    def.r = def.g = def.b = 0; 
+  }
+  if (s->linestyle.data)
+  { LINESTYLE * new = (LINESTYLE *)realloc(s->linestyle.data,(s->linestyle.n+1)*sizeof(LINESTYLE));
+    if (!new) return -1;
+    s->linestyle.data = new;
+  }
+  else
+  { s->linestyle.data = (LINESTYLE *)malloc(sizeof(LINESTYLE));
+    s->linestyle.n = 0;
+    if (!s->linestyle.data) return -1;
+  }
+  
+  s->linestyle.data[s->linestyle.n].width = width;
+  memcpy(&s->linestyle.data[s->linestyle.n].color,color,sizeof(RGBA));
+
+  return (++s->linestyle.n);
+}
+
+int ShapeSetMove(TAG * t,SHAPE * s,S32 x,S32 y)
+{ U8 b;
+  if (!t) return -1;
+  SetBits(t,0,1);
+  SetBits(t,SF_MOVETO,5);
+  
+  b = CountBits(x,0);
+  b = CountBits(y,b);
+  
+  SetBits(t,b,5);
+  SetBits(t,x,b);
+  SetBits(t,y,b);
+
+  if (s)
+  { s->px = x;
+    s->py = y;
+  }
+  return 0;
+}
+
+int ShapeSetStyle(TAG * t,SHAPE * s,U16 line,U16 fill0,U16 fill1)
+{ if ((!t)||(!s)) return -1;
+    
+  SetBits(t,0,1);
+  SetBits(t,(line?SF_LINE:0)|(fill0?SF_FILL0:0)|(fill1?SF_FILL1:0),5);
+
+  if (fill0) SetBits(t,fill0,s->bits.fill);
+  if (fill1) SetBits(t,fill1,s->bits.fill);
+  if (line)  SetBits(t,line ,s->bits.line);
+  
+  return 0;
+}
+
+/* TODO: sometimes we want to set fillstyle 0, as that's the empty fill
+   used for line drawings. At the moment, we can't, as 0 fill be considered
+   nonexistent and therefore not set.
+   these defines are a workaround (they also reduce the maximal number of
+   fill styles to 32768)
+ */
+#define FILL_RESET 0x8000
+#define LINE_RESET 0x8000
+int ShapeSetAll(TAG * t,SHAPE * s,S32 x,S32 y,U16 line,U16 fill0,U16 fill1)
+{ U8 b;
+  if ((!t)||(!s)) return -1;
+
+  SetBits(t,0,1);
+  SetBits(t,SF_MOVETO|(line?SF_LINE:0)|(fill0?SF_FILL0:0)|(fill1?SF_FILL1:0),5);
+
+  b = CountBits(x,0);
+  b = CountBits(y,b);
+  SetBits(t,b,5);
+  SetBits(t,x,b);
+  SetBits(t,y,b);
+  s->px = x;
+  s->py = y;
+
+  if (fill0) SetBits(t,fill0,s->bits.fill);
+  if (fill1) SetBits(t,fill1,s->bits.fill);
+  if (line)  SetBits(t,line ,s->bits.line);
+  
+  return 0;
+}
+
+int ShapeSetEnd(TAG * t)
+{ if (!t) return -1;
+  SetBits(t,0,6);
+  ResetBitcount(t);
+  return 0;
+}
+
+int ShapeSetLine(TAG * t,SHAPE * s,S32 x,S32 y)
+{ U8 b;
+  if (!t) return -1;
+  SetBits(t,3,2); // Straight Edge
+
+  if ((!s)||((x!=0)&&(y!=0)))
+  { b = CountBits(x,2);
+    b = CountBits(y,b);
+    if(b<2) 
+       b=2;
+    SetBits(t, b-2, 4);
+    SetBits(t,1,1);
+    SetBits(t,x,b);
+    SetBits(t,y,b);
+    if (s)
+    { s->px += x;
+      s->py += y;
+    }
+    return 0;
+  }
+
+  if (x==0)
+  { b = CountBits(y,2);
+    if(b<2) 
+       b=2;
+    SetBits(t, b-2, 4);
+    SetBits(t,1,2);
+    SetBits(t,y,b);
+    s->py += y;
+  }
+  else
+  { b = CountBits(x,2);
+    if(b<2) 
+       b=2;
+    SetBits(t, b-2, 4);
+    SetBits(t,0,2);
+    SetBits(t,x,b);
+    s->px += x;
+  }
+  return 0;
+}
+
+int ShapeSetCurve(TAG * t,SHAPE * s,S32 x,S32 y,S32 ax,S32 ay)
+{ U8 b;
+  if (!t) return -1;
+
+  SetBits(t,2,2);
+
+  b = CountBits(ax,2);
+  b = CountBits(ay,b);
+  b = CountBits(x,b);
+  b = CountBits(y,b);
+
+  SetBits(t,b-2,4);
+  SetBits(t,x,b);
+  SetBits(t,y,b);
+  SetBits(t,ax,b);
+  SetBits(t,ay,b);
+
+  if (s)
+  { s->px += x+ax;
+    s->py += y+ay;
+  }
+  return 0;
+}
+
+int ShapeSetCircle(TAG * t,SHAPE * s,S32 x,S32 y,S32 rx,S32 ry)
+{ double C1 = 0.2930;    
+  double C2 = 0.4140;   
+  double begin = 0.7070; 
+
+  if (!t) return -1;
+  
+  ShapeSetMove(t,s,x+begin*rx,y+begin*ry);
+  ShapeSetCurve(t,s, -C1*rx,  C1*ry, -C2*rx,      0);
+  ShapeSetCurve(t,s, -C2*rx,      0, -C1*rx, -C1*ry);
+  ShapeSetCurve(t,s, -C1*rx, -C1*ry,      0, -C2*ry);
+  ShapeSetCurve(t,s,      0, -C2*ry,  C1*rx, -C1*ry);
+  ShapeSetCurve(t,s,  C1*rx, -C1*ry,  C2*rx,      0);
+  ShapeSetCurve(t,s,  C2*rx,      0,  C1*rx,  C1*ry);
+  ShapeSetCurve(t,s,  C1*rx,  C1*ry,      0,  C2*ry);
+  ShapeSetCurve(t,s,      0,  C2*ry, -C1*rx,  C1*ry);
+  
+  return 0;
+}
+
index 3c9eb07..ef46afd 100644 (file)
-/* swftext.c\r
-\r
-   Text and font routines\r
-      \r
-   Extension module for the rfxswf library.\r
-   Part of the swftools package.\r
-\r
-   Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
\r
-   This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-#define TF_TEXTCONTROL  0x80\r
-#define TF_HASFONT      0x08\r
-#define TF_HASCOLOR     0x04\r
-#define TF_HASYOFFSET   0x02\r
-#define TF_HASXOFFSET   0x01\r
-\r
-#define FF_WIDECODES    0x01\r
-#define FF_BOLD         0x02\r
-#define FF_ITALIC       0x04\r
-#define FF_ANSI         0x08\r
-#define FF_SHIFTJIS     0x10\r
-#define FF_UNICODE      0x20\r
-\r
-int FontEnumerate(LPSWF swf,void (*FontCallback) (U16,U8*))\r
-{ int n;\r
-  LPTAG t;\r
-  if (!swf) return -1;\r
-  t = swf->FirstTag;\r
-  n = 0;\r
-\r
-  while (t)\r
-  { if (GetTagID(t)==ST_DEFINEFONTINFO)\r
-    { n++;\r
-      if (FontCallback)\r
-      { U16 id;\r
-        int l;\r
-        U8 s[257];\r
-        SaveTagPos(t);\r
-        SetTagPos(t,0);\r
-\r
-        id  = GetU16(t);\r
-        l   = GetU8(t);\r
-        GetBlock(t,s,l);\r
-        s[l] = 0;\r
-\r
-        (FontCallback)(id,s); \r
-      \r
-        RestoreTagPos(t);\r
-      }\r
-    }\r
-    t = NextTag(t);\r
-  }\r
-  return n;\r
-}\r
-\r
-int FontExtract_DefineFont(int id,LPSWFFONT f,LPTAG t,LPSHAPE * shapes)\r
-{ U16 fid;\r
-  SaveTagPos(t);\r
-  SetTagPos(t,0);\r
-\r
-  fid = GetU16(t);\r
-  if ((!id)||(id==fid))\r
-  { U16 ofs[MAX_CHAR_PER_FONT];\r
-    int n,i;\r
-      \r
-    id = fid;\r
-    f->id = fid;\r
-\r
-    ofs[0] = GetU16(t);\r
-    n = ofs[0]/2;\r
-\r
-    for (i=1;i<n;i++) if (i<MAX_CHAR_PER_FONT) ofs[i] = GetU16(t); else GetU16(t);\r
-    for (i=0;i<n;i++) if (i<MAX_CHAR_PER_FONT) GetSimpleShape(t,&shapes[i]);\r
-    \r
-  }\r
-\r
-  RestoreTagPos(t);\r
-  return id;\r
-}\r
-\r
-int FontExtract_DefineFontInfo(int id,LPSWFFONT f,LPTAG t,LPSHAPE * shapes)\r
-{ U16 fid;\r
-  SaveTagPos(t);\r
-  SetTagPos(t,0);\r
-\r
-  fid = GetU16(t);\r
-  if (fid==id)\r
-  { U8 l = GetU8(t);\r
-    int i;\r
-    \r
-    if (l)\r
-    { if (f->name) free(f->name);\r
-      f->name = (U8*)malloc(l+1);\r
-      if (f->name)\r
-      { GetBlock(t,f->name,l);\r
-        f->name[l] = 0;\r
-      }\r
-      else\r
-      { RestoreTagPos(t);\r
-        return -1;\r
-      }\r
-    }\r
-    f->flags = GetU8(t);\r
-\r
-    i = 0;\r
-    while (shapes[i])\r
-    { U16 code = ((f->flags&FF_WIDECODES)?GetU16(t):GetU8(t))%MAX_CHAR_PER_FONT;\r
-        \r
-      f->glyph[code].shape = shapes[i];\r
-      f->glyph[code].gid   = i;\r
-      if (i<MAX_CHAR_PER_FONT) f->codes[i] = code;\r
-\r
-      i++;\r
-    }\r
-  }\r
-\r
-  RestoreTagPos(t);\r
-  return id;\r
-}\r
-\r
-#define FEDTJ_PRINT  0x01\r
-#define FEDTJ_MODIFY 0x02\r
-\r
-int FontExtract_DefineText(int id,LPSWFFONT f,LPTAG t,int jobs)\r
-{ U16    cid;\r
-  SRECT  r;\r
-  MATRIX m;\r
-  U8     gbits, abits, flags;\r
-  int    fid;\r
-\r
-  fid = 0;\r
-\r
-  SaveTagPos(t);\r
-  SetTagPos(t,0);\r
-\r
-  cid = GetU16(t);\r
-  GetRect(t,&r);\r
-  GetMatrix(t,&m);\r
-  gbits = GetU8(t);\r
-  abits = GetU8(t);\r
-\r
-  flags = GetU8(t);\r
-  \r
-  while(flags)\r
-  { if (flags&TF_TEXTCONTROL)\r
-    { if (flags&TF_HASFONT) fid = GetU16(t);\r
-      if (flags&TF_HASCOLOR)\r
-      { GetU8(t); // rgb\r
-        GetU8(t);\r
-        GetU8(t);\r
-        if (GetTagID(t)==ST_DEFINETEXT2) GetU8(t);\r
-      }\r
-      if (flags&TF_HASXOFFSET) GetS16(t);\r
-      if (flags&TF_HASYOFFSET) GetS16(t);\r
-      if (flags&TF_HASFONT) GetU16(t);\r
-    }\r
-    else\r
-    { int i;\r
-      for (i=0;i<flags;i++)\r
-      { int glyph;\r
-        int adv;\r
-        glyph = GetBits(t,gbits);\r
-        adv = GetBits(t,abits);\r
-        if (id==fid)                    // mitlesen ?\r
-        { int code = f->codes[glyph];\r
-          if (jobs&FEDTJ_PRINT) printf("%c",code);\r
-          if (jobs&FEDTJ_MODIFY)\r
-            /*if (f->glyph[code].advance)*/ f->glyph[code].advance = adv;\r
-        }\r
-      }\r
-      if ((id==fid)&&(jobs&FEDTJ_PRINT)) printf("\n");\r
-    }\r
-    flags = GetU8(t);\r
-  }\r
-  \r
-  RestoreTagPos(t);\r
-  return id;\r
-}  \r
-\r
-int FontExtract(LPSWF swf,int id,LPSWFFONT * font)\r
-{ LPTAG t;\r
-  LPSWFFONT f;\r
-  LPSHAPE shapes[MAX_CHAR_PER_FONT];\r
-    \r
-  if ((!swf)||(!font)) return -1;\r
-\r
-  f = (LPSWFFONT)malloc(sizeof(SWFFONT)); font[0] = f;\r
-  if (!f) return -1;\r
-  \r
-  memset(shapes,0x00,sizeof(shapes));\r
-  memset(f,0x00,sizeof(SWFFONT));\r
-\r
-  t = swf->FirstTag;\r
-\r
-  while (t)\r
-  { int nid = 0;\r
-    switch (GetTagID(t))\r
-    { case ST_DEFINEFONT:\r
-        nid = FontExtract_DefineFont(id,f,t,shapes);\r
-        break;\r
-        \r
-      case ST_DEFINEFONTINFO:\r
-        nid = FontExtract_DefineFontInfo(id,f,t,shapes);\r
-        break;\r
-        \r
-      case ST_DEFINETEXT:\r
-      case ST_DEFINETEXT2:\r
-        nid = FontExtract_DefineText(id,f,t,FEDTJ_MODIFY);\r
-        break;\r
-    }\r
-    if (nid>0) id = nid;\r
-    t = NextTag(t);\r
-  }\r
-  return 0;\r
-}\r
-\r
-int FontIsItalic(LPSWFFONT f) { return f->flags&FF_ITALIC; }\r
-int FontIsBold(LPSWFFONT f)   { return f->flags&FF_BOLD; }\r
-\r
-int FontSetID(LPSWFFONT f,U16 id) { if (!f) return -1; f->id = id; return 0; }\r
-\r
-int FontReduce(LPSWFFONT f,LPFONTUSAGE use)\r
-{ int i,j;\r
-  if ((!f)||(!use)) return -1;\r
-\r
-  memset(&f->codes,0x00,sizeof(f->codes));\r
-\r
-  j = 0;\r
-  for (i=0;i<MAX_CHAR_PER_FONT;i++)\r
-    if (f->glyph[i].shape)\r
-    { if (use->code[i])\r
-      { f->glyph[i].gid = j;\r
-        f->codes[j] = i;\r
-        j++;\r
-      }\r
-      else\r
-      { ShapeFree(f->glyph[i].shape);\r
-        f->glyph[i].shape   = 0;\r
-        f->glyph[i].gid     = 0;\r
-        f->glyph[i].advance = 0;\r
-      }\r
-    } else f->glyph[i].gid = 0;\r
-    \r
-  return j;\r
-}\r
-\r
-int FontInitUsage(LPFONTUSAGE use)\r
-{ if (!use) return -1;\r
-  memset(&use->code,0x00,sizeof(use->code));\r
-  return 0;\r
-}\r
-\r
-int FontUse(LPFONTUSAGE use,U8 * s)\r
-{ if ((!use)||(!s)) return -1;\r
-  while (s[0])\r
-  { use->code[s[0]] = 1;\r
-    s++;\r
-  }\r
-  return 0;  \r
-}\r
-\r
-int FontSetDefine(LPTAG t,LPSWFFONT f)\r
-{ U16 ofs[MAX_CHAR_PER_FONT];\r
-  int p,i,j;\r
-    \r
-  if ((!t)||(!f)) return -1;\r
-  ResetBitcount(t);\r
-  SetU16(t,f->id);\r
-\r
-  p = 0; j = 0;\r
-  for (i=0;i<MAX_CHAR_PER_FONT;i++)\r
-    if (f->glyph[i].shape)\r
-    { ofs[j++] = p;\r
-      p+=SetSimpleShape(NULL,f->glyph[i].shape);\r
-    }\r
-\r
-  for (i=0;i<j;i++) SetU16(t,ofs[i]+j*2);\r
-  \r
-  for (i=0;i<MAX_CHAR_PER_FONT;i++)\r
-    if (f->glyph[i].shape)\r
-      SetSimpleShape(t,f->glyph[i].shape);\r
-  \r
-  ResetBitcount(t);\r
-  return 0;\r
-}\r
-\r
-int FontSetInfo(LPTAG t,LPSWFFONT f)\r
-{ int l,i;\r
-  if ((!t)||(!f)) return -1;\r
-  ResetBitcount(t);\r
-  SetU16(t,f->id);\r
-  l = strlen(f->name); if (l>255) l = 255;\r
-  SetU8(t,l);\r
-  SetBlock(t,f->name,l);\r
-  SetU8(t,f->flags&0xfe); // no Wide-Codes\r
-\r
-  for (i=0;i<MAX_CHAR_PER_FONT;i++)\r
-    if (f->glyph[i].shape)\r
-      SetU8(t,i);\r
-  \r
-  return 0;\r
-}\r
-\r
-int FontExport(int handle,LPSWFFONT f)\r
-{ int l;\r
-  int i;\r
-  if (!f) return 0;\r
-\r
-  l = sizeof(SWFFONT);\r
-  if (handle>=0)\r
-    if (write(handle,f,sizeof(SWFFONT))!=sizeof(SWFFONT)) return -1;\r
-\r
-  if (f->name)\r
-  { U16 ln = strlen(f->name);\r
-    l+=2+ln;\r
-    if (handle>=0)\r
-    { if (write(handle,&ln,2)!=2) return -1;\r
-      if (write(handle,f->name,ln)!=ln) return -1;\r
-    }\r
-  }\r
-\r
-  if (f->layout)\r
-  { l+=sizeof(SWFLAYOUT);\r
-    if (handle>=0)\r
-      if (write(handle,f->layout,sizeof(SWFLAYOUT))!=sizeof(SWFLAYOUT)) return -1;\r
-    if (f->layout->kerning.data)\r
-    { l+=f->layout->kerning.count*4;\r
-      if (handle>=0)\r
-        if (write(handle,f->layout->kerning.data,f->layout->kerning.count*4)!=f->layout->kerning.count*4) return -1;\r
-    }\r
-  }\r
-\r
-  for (i=0;i<MAX_CHAR_PER_FONT;i++)\r
-  { if (f->glyph[i].shape)\r
-    { int ll = ShapeExport(handle,f->glyph[i].shape);\r
-      if (ll<0) return -1;\r
-      l+=ll;\r
-    }  \r
-  }\r
-\r
-  return l;\r
-}\r
-\r
-int FontImport(int handle,LPSWFFONT * font)\r
-{ LPSWFFONT f;\r
-  int layout;\r
-  int i = 0;\r
-\r
-  if ((!font)||(handle<0)) return -1;\r
-\r
-  f = (LPSWFFONT)malloc(sizeof(SWFFONT)); font[0] = f;\r
-  if (!f) return -1;\r
-\r
-  memset(f,0x00,sizeof(SWFFONT));\r
-  \r
-  if (read(handle,f,sizeof(SWFFONT))!=sizeof(SWFFONT)) goto fehler;\r
-\r
-  layout = (f->layout)?1:0;             // avoid illegal free()\r
-  f->layout = NULL;\r
-\r
-  if (f->name)\r
-  { U16 ln;\r
-    f->name = NULL;\r
-    if (read(handle,&ln,2)!=2) goto fehler;\r
-    f->name = (U8*)malloc(ln+1);\r
-    if (!f->name) goto fehler;\r
-    if (read(handle,f->name,ln)!=ln) goto fehler;\r
-    f->name[ln] = 0;\r
-  }\r
-\r
-  if (f->layout)\r
-  { f->layout = (LPSWFLAYOUT)malloc(sizeof(SWFLAYOUT));\r
-    if (!f->layout) goto fehler;\r
-    if (read(handle,f->layout,sizeof(SWFLAYOUT))!=sizeof(SWFLAYOUT)) goto fehler;\r
-    if (f->layout->kerning.data)\r
-    { int l = f->layout->kerning.count*4;\r
-      f->layout->kerning.data = (U8*)malloc(l);\r
-      if (!f->layout->kerning.data) goto fehler;\r
-      if (read(handle,f->layout->kerning.data,l)!=l) goto fehler;\r
-    }\r
-  }\r
-\r
-  for (i=0;i<MAX_CHAR_PER_FONT;i++)\r
-  { if (f->glyph[i].shape)\r
-    { if (ShapeImport(handle,&f->glyph[i].shape)<0) goto fehler;\r
-    }\r
-  }\r
-\r
-  f->id = 0;\r
-  \r
-  return 0;\r
-  \r
-fehler:\r
-  if (f) for (;i<MAX_CHAR_PER_FONT;i++) f->glyph[i].shape = NULL;\r
-  FontFree(f);\r
-  font[0] = NULL;\r
-  return -1;\r
-}\r
-\r
-int TextPrintDefineText(LPTAG t,LPSWFFONT f)\r
-{ int id = GetTagID(t);\r
-  if ((id==ST_DEFINETEXT)||(id==ST_DEFINETEXT2)) FontExtract_DefineText(f->id,f,t,FEDTJ_PRINT);\r
-    else return -1;\r
-  return 0;\r
-}\r
-\r
-void LayoutFree(LPSWFLAYOUT l)\r
-{ if (l)\r
-  { if (l->kerning.data) free(l->kerning.data);\r
-    l->kerning.data = NULL;\r
-  }\r
-  free(l);\r
-}\r
-\r
-void FontFree(LPSWFFONT f)\r
-{ if (f)\r
-  { int i;\r
-      \r
-    if (f->name) free(f->name);\r
-    if (f->layout) LayoutFree(f->layout);\r
-\r
-    f->name = NULL;\r
-    f->layout = NULL;\r
-\r
-    for (i=0;i<MAX_CHAR_PER_FONT;i++)\r
-      if (f->glyph[i].shape)\r
-      { ShapeFree(f->glyph[i].shape);\r
-        f->glyph[i].shape = NULL;\r
-      }\r
-  }\r
-  free(f);\r
-}\r
-\r
-int TextSetInfoRecord(LPTAG t,LPSWFFONT font,U16 size,LPRGBA color,S16 dx,S16 dy)\r
-{ U8 flags;\r
-  if (!t) return -1;\r
-\r
-  flags = TF_TEXTCONTROL|(font?TF_HASFONT:0)|(color?TF_HASCOLOR:0)|(dx?TF_HASXOFFSET:0)|(dy?TF_HASYOFFSET:0);\r
-\r
-  SetU8(t,flags);\r
-  if (font) SetU16(t,font->id);\r
-  if (color)\r
-  { if (GetTagID(t)==ST_DEFINETEXT2) SetRGBA(t,color);\r
-    else SetRGB(t,color);\r
-  }\r
-  if (dx) SetS16(t,dx);\r
-  if (dy) SetS16(t,dy);\r
-  if (font) SetU16(t,size);\r
-  \r
-  return 0;\r
-}\r
-\r
-int TextCountBits(LPSWFFONT font,U8 * s,int scale,U8 * gbits,U8 * abits)\r
-{ U16 g,a;\r
-  if ((!s)||(!font)||((!gbits)&&(!abits))) return -1;\r
-  g = a = 0;\r
-\r
-  while(s[0])\r
-  { g = CountBits(font->glyph[s[0]].gid,g);\r
-    a = CountBits((((U32)font->glyph[s[0]].advance)*scale)/100,a);\r
-    s++;\r
-  }\r
-\r
-  if (gbits) gbits[0] = (U8)g;\r
-  if (abits) abits[0] = (U8)a;\r
-\r
-  return 0;\r
-}\r
-\r
-int TextSetCharRecord(LPTAG t,LPSWFFONT font,U8 * s,int scale,U8 gbits,U8 abits)\r
-{ int l,i;\r
-    \r
-  if ((!t)||(!font)||(!s)) return -1;\r
-\r
-  l = strlen(s);\r
-  if (l>0x7f) l = 0x7f;\r
-  SetU8(t,l);\r
-\r
-  for (i=0;i<l;i++)\r
-  { SetBits(t,font->glyph[s[i]].gid,gbits);\r
-    SetBits(t,(((U32)font->glyph[s[i]].advance)*scale)/100,abits);\r
-  }\r
-\r
-  ResetBitcount(t);\r
-  return 0;\r
-}\r
-\r
-U32 TextGetWidth(LPSWFFONT font,U8 * s,int scale)\r
-{ U32 res = 0;\r
-\r
-  if (font&&s)\r
-  { while (s[0])\r
-    { res += font->glyph[s[0]].advance;\r
-      s++;\r
-    }\r
-    if (scale) res = (res*scale)/100;\r
-  }\r
-  \r
-  return res;\r
-}\r
+/* swftext.c
+
+   Text and font routines
+      
+   Extension module for the rfxswf library.
+   Part of the swftools package.
+
+   Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+   This file is distributed under the GPL, see file COPYING for details 
+
+*/
+
+#define TF_TEXTCONTROL  0x80
+#define TF_HASFONT      0x08
+#define TF_HASCOLOR     0x04
+#define TF_HASYOFFSET   0x02
+#define TF_HASXOFFSET   0x01
+
+#define FF_WIDECODES    0x01
+#define FF_BOLD         0x02
+#define FF_ITALIC       0x04
+#define FF_ANSI         0x08
+#define FF_SHIFTJIS     0x10
+#define FF_UNICODE      0x20
+
+int FontEnumerate(SWF * swf,void (*FontCallback) (U16,U8*))
+{ int n;
+  TAG * t;
+  if (!swf) return -1;
+  t = swf->FirstTag;
+  n = 0;
+
+  while (t)
+  { if (GetTagID(t)==ST_DEFINEFONTINFO)
+    { n++;
+      if (FontCallback)
+      { U16 id;
+        int l;
+        U8 s[257];
+        SaveTagPos(t);
+        SetTagPos(t,0);
+
+        id  = GetU16(t);
+        l   = GetU8(t);
+        GetBlock(t,s,l);
+        s[l] = 0;
+
+        (FontCallback)(id,s); 
+      
+        RestoreTagPos(t);
+      }
+    }
+    t = NextTag(t);
+  }
+  return n;
+}
+
+int FontExtract_DefineFont(int id,SWFFONT * f,TAG * t,SHAPE * * shapes)
+{ U16 fid;
+  SaveTagPos(t);
+  SetTagPos(t,0);
+
+  fid = GetU16(t);
+  if ((!id)||(id==fid))
+  { U16 ofs[MAX_CHAR_PER_FONT];
+    int n,i;
+      
+    id = fid;
+    f->id = fid;
+
+    ofs[0] = GetU16(t);
+    n = ofs[0]/2;
+
+    for (i=1;i<n;i++) if (i<MAX_CHAR_PER_FONT) ofs[i] = GetU16(t); else GetU16(t);
+    for (i=0;i<n;i++) if (i<MAX_CHAR_PER_FONT) GetSimpleShape(t,&shapes[i]);
+    
+  }
+
+  RestoreTagPos(t);
+  return id;
+}
+
+int FontExtract_DefineFontInfo(int id,SWFFONT * f,TAG * t,SHAPE * * shapes)
+{ U16 fid;
+  SaveTagPos(t);
+  SetTagPos(t,0);
+
+  fid = GetU16(t);
+  if (fid==id)
+  { U8 l = GetU8(t);
+    int i;
+    
+    if (l)
+    { if (f->name) free(f->name);
+      f->name = (U8*)malloc(l+1);
+      if (f->name)
+      { GetBlock(t,f->name,l);
+        f->name[l] = 0;
+      }
+      else
+      { RestoreTagPos(t);
+        return -1;
+      }
+    }
+    f->flags = GetU8(t);
+
+    i = 0;
+    while (shapes[i])
+    { U16 code = ((f->flags&FF_WIDECODES)?GetU16(t):GetU8(t))%MAX_CHAR_PER_FONT;
+        
+      f->glyph[code].shape = shapes[i];
+      f->glyph[code].gid   = i;
+      if (i<MAX_CHAR_PER_FONT) f->codes[i] = code;
+
+      i++;
+    }
+  }
+
+  RestoreTagPos(t);
+  return id;
+}
+
+#define FEDTJ_PRINT  0x01
+#define FEDTJ_MODIFY 0x02
+
+int FontExtract_DefineText(int id,SWFFONT * f,TAG * t,int jobs)
+{ U16    cid;
+  SRECT  r;
+  MATRIX m;
+  U8     gbits, abits, flags;
+  int    fid;
+
+  fid = 0;
+
+  SaveTagPos(t);
+  SetTagPos(t,0);
+
+  cid = GetU16(t);
+  GetRect(t,&r);
+  GetMatrix(t,&m);
+  gbits = GetU8(t);
+  abits = GetU8(t);
+
+  flags = GetU8(t);
+  
+  while(flags)
+  { if (flags&TF_TEXTCONTROL)
+    { if (flags&TF_HASFONT) fid = GetU16(t);
+      if (flags&TF_HASCOLOR)
+      { GetU8(t); // rgb
+        GetU8(t);
+        GetU8(t);
+        if (GetTagID(t)==ST_DEFINETEXT2) GetU8(t);
+      }
+      if (flags&TF_HASXOFFSET) GetS16(t);
+      if (flags&TF_HASYOFFSET) GetS16(t);
+      if (flags&TF_HASFONT) GetU16(t);
+    }
+    else
+    { int i;
+      for (i=0;i<flags;i++)
+      { int glyph;
+        int adv;
+        glyph = GetBits(t,gbits);
+        adv = GetBits(t,abits);
+        if (id==fid)                    // mitlesen ?
+        { int code = f->codes[glyph];
+          if (jobs&FEDTJ_PRINT) printf("%c",code);
+          if (jobs&FEDTJ_MODIFY)
+            /*if (f->glyph[code].advance)*/ f->glyph[code].advance = adv;
+        }
+      }
+      if ((id==fid)&&(jobs&FEDTJ_PRINT)) printf("\n");
+    }
+    flags = GetU8(t);
+  }
+  
+  RestoreTagPos(t);
+  return id;
+}  
+
+int FontExtract(SWF * swf,int id,SWFFONT * * font)
+{ TAG * t;
+  SWFFONT * f;
+  SHAPE * shapes[MAX_CHAR_PER_FONT];
+    
+  if ((!swf)||(!font)) return -1;
+
+  f = (SWFFONT *)malloc(sizeof(SWFFONT)); font[0] = f;
+  if (!f) return -1;
+  
+  memset(shapes,0x00,sizeof(shapes));
+  memset(f,0x00,sizeof(SWFFONT));
+
+  t = swf->FirstTag;
+
+  while (t)
+  { int nid = 0;
+    switch (GetTagID(t))
+    { case ST_DEFINEFONT:
+        nid = FontExtract_DefineFont(id,f,t,shapes);
+        break;
+        
+      case ST_DEFINEFONTINFO:
+        nid = FontExtract_DefineFontInfo(id,f,t,shapes);
+        break;
+        
+      case ST_DEFINETEXT:
+      case ST_DEFINETEXT2:
+        nid = FontExtract_DefineText(id,f,t,FEDTJ_MODIFY);
+        break;
+    }
+    if (nid>0) id = nid;
+    t = NextTag(t);
+  }
+  return 0;
+}
+
+int FontIsItalic(SWFFONT * f) { return f->flags&FF_ITALIC; }
+int FontIsBold(SWFFONT * f)   { return f->flags&FF_BOLD; }
+
+int FontSetID(SWFFONT * f,U16 id) { if (!f) return -1; f->id = id; return 0; }
+
+int FontReduce(SWFFONT * f,FONTUSAGE * use)
+{ int i,j;
+  if ((!f)||(!use)) return -1;
+
+  memset(&f->codes,0x00,sizeof(f->codes));
+
+  j = 0;
+  for (i=0;i<MAX_CHAR_PER_FONT;i++)
+    if (f->glyph[i].shape)
+    { if (use->code[i])
+      { f->glyph[i].gid = j;
+        f->codes[j] = i;
+        j++;
+      }
+      else
+      { ShapeFree(f->glyph[i].shape);
+        f->glyph[i].shape   = 0;
+        f->glyph[i].gid     = 0;
+        f->glyph[i].advance = 0;
+      }
+    } else f->glyph[i].gid = 0;
+    
+  return j;
+}
+
+int FontInitUsage(FONTUSAGE * use)
+{ if (!use) return -1;
+  memset(&use->code,0x00,sizeof(use->code));
+  return 0;
+}
+
+int FontUse(FONTUSAGE * use,U8 * s)
+{ if ((!use)||(!s)) return -1;
+  while (s[0])
+  { use->code[s[0]] = 1;
+    s++;
+  }
+  return 0;  
+}
+
+int FontSetDefine(TAG * t,SWFFONT * f)
+{ U16 ofs[MAX_CHAR_PER_FONT];
+  int p,i,j;
+    
+  if ((!t)||(!f)) return -1;
+  ResetBitcount(t);
+  SetU16(t,f->id);
+
+  p = 0; j = 0;
+  for (i=0;i<MAX_CHAR_PER_FONT;i++)
+    if (f->glyph[i].shape)
+    { ofs[j++] = p;
+      p+=SetSimpleShape(NULL,f->glyph[i].shape);
+    }
+
+  for (i=0;i<j;i++) SetU16(t,ofs[i]+j*2);
+  
+  for (i=0;i<MAX_CHAR_PER_FONT;i++)
+    if (f->glyph[i].shape)
+      SetSimpleShape(t,f->glyph[i].shape);
+  
+  ResetBitcount(t);
+  return 0;
+}
+
+int FontSetInfo(TAG * t,SWFFONT * f)
+{ int l,i;
+  if ((!t)||(!f)) return -1;
+  ResetBitcount(t);
+  SetU16(t,f->id);
+  l = strlen(f->name); if (l>255) l = 255;
+  SetU8(t,l);
+  SetBlock(t,f->name,l);
+  SetU8(t,f->flags&0xfe); // no Wide-Codes
+
+  for (i=0;i<MAX_CHAR_PER_FONT;i++)
+    if (f->glyph[i].shape)
+      SetU8(t,i);
+  
+  return 0;
+}
+
+int FontExport(int handle,SWFFONT * f)
+{ int l;
+  int i;
+  if (!f) return 0;
+
+  l = sizeof(SWFFONT);
+  if (handle>=0)
+    if (write(handle,f,sizeof(SWFFONT))!=sizeof(SWFFONT)) return -1;
+
+  if (f->name)
+  { U16 ln = strlen(f->name);
+    l+=2+ln;
+    if (handle>=0)
+    { if (write(handle,&ln,2)!=2) return -1;
+      if (write(handle,f->name,ln)!=ln) return -1;
+    }
+  }
+
+  if (f->layout)
+  { l+=sizeof(SWFLAYOUT);
+    if (handle>=0)
+      if (write(handle,f->layout,sizeof(SWFLAYOUT))!=sizeof(SWFLAYOUT)) return -1;
+    if (f->layout->kerning.data)
+    { l+=f->layout->kerning.count*4;
+      if (handle>=0)
+        if (write(handle,f->layout->kerning.data,f->layout->kerning.count*4)!=f->layout->kerning.count*4) return -1;
+    }
+  }
+
+  for (i=0;i<MAX_CHAR_PER_FONT;i++)
+  { if (f->glyph[i].shape)
+    { int ll = ShapeExport(handle,f->glyph[i].shape);
+      if (ll<0) return -1;
+      l+=ll;
+    }  
+  }
+
+  return l;
+}
+
+int FontImport(int handle,SWFFONT * * font)
+{ SWFFONT * f;
+  int layout;
+  int i = 0;
+
+  if ((!font)||(handle<0)) return -1;
+
+  f = (SWFFONT *)malloc(sizeof(SWFFONT)); font[0] = f;
+  if (!f) return -1;
+
+  memset(f,0x00,sizeof(SWFFONT));
+  
+  if (read(handle,f,sizeof(SWFFONT))!=sizeof(SWFFONT)) goto fehler;
+
+  layout = (f->layout)?1:0;             // avoid illegal free()
+  f->layout = NULL;
+
+  if (f->name)
+  { U16 ln;
+    f->name = NULL;
+    if (read(handle,&ln,2)!=2) goto fehler;
+    f->name = (U8*)malloc(ln+1);
+    if (!f->name) goto fehler;
+    if (read(handle,f->name,ln)!=ln) goto fehler;
+    f->name[ln] = 0;
+  }
+
+  if (f->layout)
+  { f->layout = (SWFLAYOUT *)malloc(sizeof(SWFLAYOUT));
+    if (!f->layout) goto fehler;
+    if (read(handle,f->layout,sizeof(SWFLAYOUT))!=sizeof(SWFLAYOUT)) goto fehler;
+    if (f->layout->kerning.data)
+    { int l = f->layout->kerning.count*4;
+      f->layout->kerning.data = (U8*)malloc(l);
+      if (!f->layout->kerning.data) goto fehler;
+      if (read(handle,f->layout->kerning.data,l)!=l) goto fehler;
+    }
+  }
+
+  for (i=0;i<MAX_CHAR_PER_FONT;i++)
+  { if (f->glyph[i].shape)
+    { if (ShapeImport(handle,&f->glyph[i].shape)<0) goto fehler;
+    }
+  }
+
+  f->id = 0;
+  
+  return 0;
+  
+fehler:
+  if (f) for (;i<MAX_CHAR_PER_FONT;i++) f->glyph[i].shape = NULL;
+  FontFree(f);
+  font[0] = NULL;
+  return -1;
+}
+
+int TextPrintDefineText(TAG * t,SWFFONT * f)
+{ int id = GetTagID(t);
+  if ((id==ST_DEFINETEXT)||(id==ST_DEFINETEXT2)) FontExtract_DefineText(f->id,f,t,FEDTJ_PRINT);
+    else return -1;
+  return 0;
+}
+
+void LayoutFree(SWFLAYOUT * l)
+{ if (l)
+  { if (l->kerning.data) free(l->kerning.data);
+    l->kerning.data = NULL;
+  }
+  free(l);
+}
+
+void FontFree(SWFFONT * f)
+{ if (f)
+  { int i;
+      
+    if (f->name) free(f->name);
+    if (f->layout) LayoutFree(f->layout);
+
+    f->name = NULL;
+    f->layout = NULL;
+
+    for (i=0;i<MAX_CHAR_PER_FONT;i++)
+      if (f->glyph[i].shape)
+      { ShapeFree(f->glyph[i].shape);
+        f->glyph[i].shape = NULL;
+      }
+  }
+  free(f);
+}
+
+int TextSetInfoRecord(TAG * t,SWFFONT * font,U16 size,RGBA * color,S16 dx,S16 dy)
+{ U8 flags;
+  if (!t) return -1;
+
+  flags = TF_TEXTCONTROL|(font?TF_HASFONT:0)|(color?TF_HASCOLOR:0)|(dx?TF_HASXOFFSET:0)|(dy?TF_HASYOFFSET:0);
+
+  SetU8(t,flags);
+  if (font) SetU16(t,font->id);
+  if (color)
+  { if (GetTagID(t)==ST_DEFINETEXT2) SetRGBA(t,color);
+    else SetRGB(t,color);
+  }
+  if (dx) SetS16(t,dx);
+  if (dy) SetS16(t,dy);
+  if (font) SetU16(t,size);
+  
+  return 0;
+}
+
+int TextCountBits(SWFFONT * font,U8 * s,int scale,U8 * gbits,U8 * abits)
+{ U16 g,a;
+  if ((!s)||(!font)||((!gbits)&&(!abits))) return -1;
+  g = a = 0;
+
+  while(s[0])
+  { g = CountBits(font->glyph[s[0]].gid,g);
+    a = CountBits((((U32)font->glyph[s[0]].advance)*scale)/100,a);
+    s++;
+  }
+
+  if (gbits) gbits[0] = (U8)g;
+  if (abits) abits[0] = (U8)a;
+
+  return 0;
+}
+
+int TextSetCharRecord(TAG * t,SWFFONT * font,U8 * s,int scale,U8 gbits,U8 abits)
+{ int l,i;
+    
+  if ((!t)||(!font)||(!s)) return -1;
+
+  l = strlen(s);
+  if (l>0x7f) l = 0x7f;
+  SetU8(t,l);
+
+  for (i=0;i<l;i++)
+  { SetBits(t,font->glyph[s[i]].gid,gbits);
+    SetBits(t,(((U32)font->glyph[s[i]].advance)*scale)/100,abits);
+  }
+
+  ResetBitcount(t);
+  return 0;
+}
+
+U32 TextGetWidth(SWFFONT * font,U8 * s,int scale)
+{ U32 res = 0;
+
+  if (font&&s)
+  { while (s[0])
+    { res += font->glyph[s[0]].advance;
+      s++;
+    }
+    if (scale) res = (res*scale)/100;
+  }
+  
+  return res;
+}
index 1b10385..b926346 100644 (file)
-/* swftools.c\r
-\r
-   Math and matrix functions, misc tools\r
-\r
-   Extension module for the rfxswf library.\r
-   Part of the swftools package.\r
-\r
-   Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
\r
-   This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-// Matrix & Math tools for SWF files\r
-\r
-#define S64 long long\r
-SFIXED SP(SFIXED a1,SFIXED a2,SFIXED b1,SFIXED b2)\r
-{ S64 a;\r
-  a = (S64)a1*(S64)b1+(S64)a2*(S64)b2;\r
-  return (SFIXED)(a>>16);\r
-}\r
-SFIXED QFIX(int zaehler,int nenner) // bildet Quotient von zwei INTs in SFIXED\r
-{ S64 z = zaehler<<16;\r
-  S64 a = z/(S64)nenner;\r
-  return (SFIXED)a;\r
-}\r
-#undef S64\r
-\r
-LPMATRIX MatrixJoin(LPMATRIX d,LPMATRIX s1,LPMATRIX s2)\r
-{        \r
-  if (!d) return NULL;\r
-  if (!s1) return (s2)?(LPMATRIX)memcpy(d,s2,sizeof(MATRIX)):NULL;\r
-  if (!s2) return (LPMATRIX)memcpy(d,s1,sizeof(MATRIX));\r
-  \r
-  d->tx = s1->tx + s2->tx;\r
-  d->ty = s1->ty + s2->ty;\r
-  \r
-  d->sx = SP(s1->sx,s1->r1,s2->sx,s2->r0);\r
-  d->sy = SP(s1->r0,s1->sy,s2->r1,s2->sy);\r
-  d->r0 = SP(s1->r0,s1->sy,s2->sx,s2->r0);\r
-  d->r1 = SP(s1->sx,s1->r1,s2->r1,s2->sy);\r
-\r
-  //DumpMatrix(NULL,d);\r
-  \r
-  return d;\r
-}\r
-\r
-LPMATRIX MatrixMapTriangle(LPMATRIX m,int dx,int dy,int x0,int y0,\r
-                               int x1,int y1,int x2,int y2)\r
-{ int dx1 = x1 - x0;\r
-  int dy1 = y1 - y0;\r
-  int dx2 = x2 - x0;\r
-  int dy2 = y2 - y0;\r
-  \r
-  if (!m) return NULL;\r
-  if ((!dx)||(!dy)) return NULL; // check DIV by zero\r
-\r
-  m->tx = x0;\r
-  m->ty = y0;\r
-  m->sx = QFIX(dx1,dx);\r
-  m->sy = QFIX(dy2,dy);\r
-  m->r0 = QFIX(dy1,dx);\r
-  m->r1 = QFIX(dx2,dy);\r
-  \r
-  return m;\r
-}\r
-\r
-U16 GetDefineID(LPTAG t)\r
-// up to SWF 4.0\r
-{ U32 oldTagPos;\r
-  U16 id = 0;\r
-\r
-  oldTagPos = GetTagPos(t);\r
-  SetTagPos(t,0);\r
-\r
-  switch (GetTagID(t))\r
-  { case ST_DEFINESHAPE:\r
-    case ST_DEFINESHAPE2:\r
-    case ST_DEFINESHAPE3:\r
-    case ST_DEFINEMORPHSHAPE:\r
-    case ST_DEFINEBITS:\r
-    case ST_DEFINEBITSJPEG2:\r
-    case ST_DEFINEBITSJPEG3:\r
-    case ST_DEFINEBITSLOSSLESS:\r
-    case ST_DEFINEBITSLOSSLESS2:\r
-    case ST_DEFINEBUTTON:\r
-    case ST_DEFINEBUTTON2:\r
-    case ST_DEFINEBUTTONCXFORM:\r
-    case ST_DEFINEBUTTONSOUND:\r
-    case ST_DEFINEFONT:\r
-    case ST_DEFINEFONT2:\r
-    case ST_DEFINEFONTINFO:\r
-    case ST_DEFINETEXT:\r
-    case ST_DEFINETEXT2:\r
-    case ST_DEFINESOUND:\r
-    case ST_DEFINESPRITE:\r
-      id = GetU16(t);\r
-      break;\r
-  }\r
-\r
-  SetTagPos(t,oldTagPos);\r
-\r
-  return id;\r
-}\r
-\r
-U16 GetPlaceID(LPTAG t)\r
-// up to SWF 4.0\r
-{ U32 oldTagPos;\r
-  U16 id = 0;\r
-\r
-  oldTagPos = GetTagPos(t);\r
-  SetTagPos(t,0);\r
-\r
-  switch (GetTagID(t))\r
-  { case ST_PLACEOBJECT:\r
-    case ST_REMOVEOBJECT:\r
-    case ST_STARTSOUND:\r
-      id = GetU16(t);\r
-      break;\r
-\r
-    case ST_PLACEOBJECT2:\r
-    { U8 flags = GetU8(t);\r
-      U16 d = GetU16(t);\r
-      id = (flags&PF_CHAR)?GetU16(t):id;\r
-    } break;\r
-\r
-  }\r
-\r
-  SetTagPos(t,oldTagPos);\r
-\r
-  return id;\r
-}\r
-\r
-int definingtagids[] =\r
-{ST_DEFINESHAPE,\r
- ST_DEFINESHAPE2,\r
- ST_DEFINESHAPE3,\r
- ST_DEFINEMORPHSHAPE,\r
- ST_DEFINEFONT,\r
- ST_DEFINEFONT2,\r
- ST_DEFINETEXT,\r
- ST_DEFINETEXT2,\r
- ST_DEFINEEDITTEXT,\r
- ST_DEFINEBITS,\r
- ST_DEFINEBITSJPEG2,\r
- ST_DEFINEBITSJPEG3,\r
- ST_DEFINEBITSLOSSLESS,\r
- ST_DEFINEBITSLOSSLESS2,\r
- ST_DEFINEMOVIE,\r
- ST_DEFINESPRITE,\r
- ST_DEFINEBUTTON,\r
- ST_DEFINEBUTTON2,\r
- ST_DEFINESOUND,\r
- -1\r
-};\r
-\r
-// tags which may be used inside a sprite definition\r
-int spritetagids[] =\r
-{ST_SHOWFRAME,\r
- ST_PLACEOBJECT,\r
- ST_PLACEOBJECT2,\r
- ST_REMOVEOBJECT,\r
- ST_REMOVEOBJECT2, //?\r
- ST_DOACTION,\r
- ST_STARTSOUND,\r
- ST_FRAMELABEL,\r
- ST_SOUNDSTREAMHEAD,\r
- ST_SOUNDSTREAMHEAD2,\r
- ST_SOUNDSTREAMBLOCK,\r
- ST_END,\r
- -1\r
-};\r
-\r
-char isAllowedSpriteTag (TAG*tag)\r
-{\r
-    int id = tag->id;\r
-    int t=0;\r
-    while(spritetagids[t]>=0)\r
-    {\r
-       if(spritetagids[t] == id) \r
-           return 1;\r
-       t++;\r
-    }\r
-    return 0; \r
-}\r
-\r
-char isDefiningTag (TAG*tag)\r
-{\r
-    int id = tag->id;\r
-    int t=0;\r
-    while(definingtagids[t]>=0)\r
-    {\r
-       if(definingtagids[t] == id) \r
-           return 1;\r
-       t++;\r
-    }\r
-    return 0; \r
-}\r
-\r
-U16 GetDepth(LPTAG t)\r
-// up to SWF 4.0\r
-{ \r
-  U16 depth = 0;\r
-  U32 oldTagPos;\r
-  oldTagPos = GetTagPos(t);\r
-  SetTagPos(t,0);\r
-\r
-  switch (GetTagID(t))\r
-  { case ST_PLACEOBJECT:\r
-    case ST_REMOVEOBJECT:\r
-      GetU16(t); //id\r
-      depth = GetU16(t);\r
-      break;\r
-    case ST_REMOVEOBJECT2:\r
-      depth = GetU16(t);\r
-      break;\r
-    case ST_PLACEOBJECT2:\r
-    { U8 flags = GetU8(t);\r
-      depth = GetU16(t);\r
-    } break;\r
-  }\r
-  SetTagPos(t,oldTagPos);\r
-  return depth;\r
-}\r
-\r
-char* GetName(LPTAG t)\r
-{\r
-    char* name = 0;\r
-    U32 oldTagPos;\r
-    MATRIX m;\r
-    CXFORM c;\r
-    oldTagPos = GetTagPos(t);\r
-    SetTagPos(t,0);\r
-    switch(GetTagID(t))\r
-    {\r
-        case ST_FRAMELABEL:\r
-           name = &t->data[GetTagPos(t)];\r
-        break;\r
-        case ST_PLACEOBJECT2: {   \r
-            U8 flags = GetU8(t);\r
-            GetU16(t); //depth;\r
-           if(flags&PF_CHAR) \r
-             GetU16(t); //id\r
-           if(flags&PF_MATRIX)\r
-             GetMatrix(t, &m);\r
-           if(flags&PF_CXFORM)\r
-             GetCXForm(t, &c, 1);\r
-           if(flags&PF_RATIO)\r
-             GetU16(t);\r
-           if(flags&PF_NAME) {\r
-             ResetBitmask(t);\r
-             name = &t->data[GetTagPos(t)];\r
-           }\r
-        }\r
-        break;\r
-    }\r
-    SetTagPos(t,oldTagPos);\r
-    return name;\r
-}\r
-\r
+/* swftools.c
+
+   Math and matrix functions, misc tools
+
+   Extension module for the rfxswf library.
+   Part of the swftools package.
+
+   Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+   This file is distributed under the GPL, see file COPYING for details 
+
+*/
+
+// Matrix & Math tools for SWF files
+
+#define S64 long long
+SFIXED SP(SFIXED a1,SFIXED a2,SFIXED b1,SFIXED b2)
+{ S64 a;
+  a = (S64)a1*(S64)b1+(S64)a2*(S64)b2;
+  return (SFIXED)(a>>16);
+}
+SFIXED QFIX(int zaehler,int nenner) // bildet Quotient von zwei INTs in SFIXED
+{ S64 z = zaehler<<16;
+  S64 a = z/(S64)nenner;
+  return (SFIXED)a;
+}
+#undef S64
+
+MATRIX * MatrixJoin(MATRIX * d,MATRIX * s1,MATRIX * s2)
+{        
+  if (!d) return NULL;
+  if (!s1) return (s2)?(MATRIX *)memcpy(d,s2,sizeof(MATRIX)):NULL;
+  if (!s2) return (MATRIX *)memcpy(d,s1,sizeof(MATRIX));
+  
+  d->tx = s1->tx + s2->tx;
+  d->ty = s1->ty + s2->ty;
+  
+  d->sx = SP(s1->sx,s1->r1,s2->sx,s2->r0);
+  d->sy = SP(s1->r0,s1->sy,s2->r1,s2->sy);
+  d->r0 = SP(s1->r0,s1->sy,s2->sx,s2->r0);
+  d->r1 = SP(s1->sx,s1->r1,s2->r1,s2->sy);
+
+  //DumpMatrix(NULL,d);
+  
+  return d;
+}
+
+MATRIX * MatrixMapTriangle(MATRIX * m,int dx,int dy,int x0,int y0,
+                               int x1,int y1,int x2,int y2)
+{ int dx1 = x1 - x0;
+  int dy1 = y1 - y0;
+  int dx2 = x2 - x0;
+  int dy2 = y2 - y0;
+  
+  if (!m) return NULL;
+  if ((!dx)||(!dy)) return NULL; // check DIV by zero
+
+  m->tx = x0;
+  m->ty = y0;
+  m->sx = QFIX(dx1,dx);
+  m->sy = QFIX(dy2,dy);
+  m->r0 = QFIX(dy1,dx);
+  m->r1 = QFIX(dx2,dy);
+  
+  return m;
+}
+
+U16 GetDefineID(TAG * t)
+// up to SWF 4.0
+{ U32 oldTagPos;
+  U16 id = 0;
+
+  oldTagPos = GetTagPos(t);
+  SetTagPos(t,0);
+
+  switch (GetTagID(t))
+  { case ST_DEFINESHAPE:
+    case ST_DEFINESHAPE2:
+    case ST_DEFINESHAPE3:
+    case ST_DEFINEMORPHSHAPE:
+    case ST_DEFINEBITS:
+    case ST_DEFINEBITSJPEG2:
+    case ST_DEFINEBITSJPEG3:
+    case ST_DEFINEBITSLOSSLESS:
+    case ST_DEFINEBITSLOSSLESS2:
+    case ST_DEFINEBUTTON:
+    case ST_DEFINEBUTTON2:
+    case ST_DEFINEBUTTONCXFORM:
+    case ST_DEFINEBUTTONSOUND:
+    case ST_DEFINEFONT:
+    case ST_DEFINEFONT2:
+    case ST_DEFINEFONTINFO:
+    case ST_DEFINETEXT:
+    case ST_DEFINETEXT2:
+    case ST_DEFINESOUND:
+    case ST_DEFINESPRITE:
+      id = GetU16(t);
+      break;
+  }
+
+  SetTagPos(t,oldTagPos);
+
+  return id;
+}
+
+U16 GetPlaceID(TAG * t)
+// up to SWF 4.0
+{ U32 oldTagPos;
+  U16 id = 0;
+
+  oldTagPos = GetTagPos(t);
+  SetTagPos(t,0);
+
+  switch (GetTagID(t))
+  { case ST_PLACEOBJECT:
+    case ST_REMOVEOBJECT:
+    case ST_STARTSOUND:
+      id = GetU16(t);
+      break;
+
+    case ST_PLACEOBJECT2:
+    { U8 flags = GetU8(t);
+      U16 d = GetU16(t);
+      id = (flags&PF_CHAR)?GetU16(t):id;
+    } break;
+
+  }
+
+  SetTagPos(t,oldTagPos);
+
+  return id;
+}
+
+int definingtagids[] =
+{ST_DEFINESHAPE,
+ ST_DEFINESHAPE2,
+ ST_DEFINESHAPE3,
+ ST_DEFINEMORPHSHAPE,
+ ST_DEFINEFONT,
+ ST_DEFINEFONT2,
+ ST_DEFINETEXT,
+ ST_DEFINETEXT2,
+ ST_DEFINEEDITTEXT,
+ ST_DEFINEBITS,
+ ST_DEFINEBITSJPEG2,
+ ST_DEFINEBITSJPEG3,
+ ST_DEFINEBITSLOSSLESS,
+ ST_DEFINEBITSLOSSLESS2,
+ ST_DEFINEMOVIE,
+ ST_DEFINESPRITE,
+ ST_DEFINEBUTTON,
+ ST_DEFINEBUTTON2,
+ ST_DEFINESOUND,
+ -1
+};
+
+// tags which may be used inside a sprite definition
+int spritetagids[] =
+{ST_SHOWFRAME,
+ ST_PLACEOBJECT,
+ ST_PLACEOBJECT2,
+ ST_REMOVEOBJECT,
+ ST_REMOVEOBJECT2, //?
+ ST_DOACTION,
+ ST_STARTSOUND,
+ ST_FRAMELABEL,
+ ST_SOUNDSTREAMHEAD,
+ ST_SOUNDSTREAMHEAD2,
+ ST_SOUNDSTREAMBLOCK,
+ ST_END,
+ -1
+};
+
+char isAllowedSpriteTag (TAG*tag)
+{
+    int id = tag->id;
+    int t=0;
+    while(spritetagids[t]>=0)
+    {
+       if(spritetagids[t] == id) 
+           return 1;
+       t++;
+    }
+    return 0; 
+}
+
+char isDefiningTag (TAG*tag)
+{
+    int id = tag->id;
+    int t=0;
+    while(definingtagids[t]>=0)
+    {
+       if(definingtagids[t] == id) 
+           return 1;
+       t++;
+    }
+    return 0; 
+}
+
+U16 GetDepth(TAG * t)
+// up to SWF 4.0
+{ 
+  U16 depth = 0;
+  U32 oldTagPos;
+  oldTagPos = GetTagPos(t);
+  SetTagPos(t,0);
+
+  switch (GetTagID(t))
+  { case ST_PLACEOBJECT:
+    case ST_REMOVEOBJECT:
+      GetU16(t); //id
+      depth = GetU16(t);
+      break;
+    case ST_REMOVEOBJECT2:
+      depth = GetU16(t);
+      break;
+    case ST_PLACEOBJECT2:
+    { U8 flags = GetU8(t);
+      depth = GetU16(t);
+    } break;
+  }
+  SetTagPos(t,oldTagPos);
+  return depth;
+}
+
+char* GetName(TAG * t)
+{
+    char* name = 0;
+    U32 oldTagPos;
+    MATRIX m;
+    CXFORM c;
+    oldTagPos = GetTagPos(t);
+    SetTagPos(t,0);
+    switch(GetTagID(t))
+    {
+        case ST_FRAMELABEL:
+           name = &t->data[GetTagPos(t)];
+        break;
+        case ST_PLACEOBJECT2: {   
+            U8 flags = GetU8(t);
+            GetU16(t); //depth;
+           if(flags&PF_CHAR) 
+             GetU16(t); //id
+           if(flags&PF_MATRIX)
+             GetMatrix(t, &m);
+           if(flags&PF_CXFORM)
+             GetCXForm(t, &c, 1);
+           if(flags&PF_RATIO)
+             GetU16(t);
+           if(flags&PF_NAME) {
+             ResetBitmask(t);
+             name = &t->data[GetTagPos(t)];
+           }
+        }
+        break;
+    }
+    SetTagPos(t,oldTagPos);
+    return name;
+}
+
index 8fe46bd..1c9bd66 100644 (file)
-/* rfxswf.c\r
-\r
-   Library for creating and reading SWF files or parts of it.\r
-   There's a module directory which provides some extended functionality.\r
-   Most modules are included at the bottom of this file.\r
-\r
-   Part of the swftools package.\r
-\r
-   Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
\r
-   This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-#include "rfxswf.h"\r
-\r
-#ifdef HAVE_LIBJPEG\r
-#ifdef HAVE_JPEGLIB_H\r
-#include <jpeglib.h>\r
-#define _JPEGLIB_INCLUDED_\r
-#endif //HAVE_JPEGLIB_H\r
-#endif //HAVE_LIBJPEG\r
-\r
-// Win32 support may be broken since it was only tested in an older version for Watcom C\r
-#ifdef __NT__\r
-#  include <io.h>\r
-#  include <malloc.h>\r
-#  include <string.h>\r
-#  ifdef DEBUG_RFXSWF\r
-#    include <stdio.h>\r
-#  endif\r
-#else\r
-#endif\r
-\r
-// internal constants\r
-\r
-#define MALLOC_SIZE     128\r
-#define INSERT_RFX_TAG\r
-\r
-#define MEMSIZE(l) (((l/MALLOC_SIZE)+1)*MALLOC_SIZE)\r
-\r
-// inline wrapper functions\r
-\r
-LPTAG NextTag(LPTAG t) { return t->next; }\r
-LPTAG PrevTag(LPTAG t) { return t->prev; }\r
-int   GetFrameNo(LPTAG t)  { return t->frame; }\r
-U16   GetTagID(LPTAG t)    { return t->id; }\r
-U32   GetDataSize(LPTAG t) { return t->len; }\r
-U8*   GetDataSizePtr(LPTAG t) { return &(t->data[t->len]); }\r
-U32   GetTagPos(LPTAG t)   { return t->pos; }\r
-\r
-// Basic Data Access Functions\r
-\r
-#define ResetBitmask(tag)   if (tag->bitmask)  { tag->pos++; tag->bitmask = 0; }\r
-#define ResetBitcount(tag)  if (tag->bitcount) { tag->bitcount = 0; }\r
-\r
-// for future purpose: avoid high level lib functions to change tagpos/bitcount\r
-\r
-#define SaveTagPos(tag)\r
-#define RestoreTagPos(tag)\r
-\r
-void SetTagPos(LPTAG t,U32 pos)\r
-{ ResetBitmask(t);\r
-  if (pos<=t->len) t->pos = pos;\r
-  #ifdef DEBUG_RFXSWF\r
-  else fprintf(stderr,"SetTagPos() out of bounds: TagID = %i\n",t->id);\r
-  #endif\r
-}\r
-\r
-U8 GetU8(LPTAG t)\r
-{ ResetBitmask(t);\r
-  #ifdef DEBUG_RFXSWF\r
-    if (t->pos>=t->len) \r
-    { fprintf(stderr,"GetU8() out of bounds: TagID = %i\n",t->id);\r
-      return 0;\r
-    }\r
-  #endif\r
-  return t->data[t->pos++];\r
-}\r
-\r
-U16 GetU16(LPTAG t)\r
-{ U16 res;\r
-  ResetBitmask(t);\r
-  #ifdef DEBUG_RFXSWF\r
-    if (t->pos>(t->len-2)) \r
-    { fprintf(stderr,"GetU16() out of bounds: TagID = %i\n",t->id);\r
-      return 0;\r
-    }\r
-  #endif\r
-  res = t->data[t->pos] | (t->data[t->pos+1]<<8);\r
-  t->pos+=2;\r
-  return res;\r
-}\r
-\r
-U32 GetU32(LPTAG t)\r
-{ U32 res;\r
-  ResetBitmask(t);\r
-  #ifdef DEBUG_RFXSWF\r
-    if (t->pos>(t->len-4)) \r
-    { fprintf(stderr,"GetU32() out of bounds: TagID = %i\n",t->id);\r
-      return 0;\r
-    }\r
-  #endif\r
-  res = t->data[t->pos]        | (t->data[t->pos+1]<<8) | \r
-       (t->data[t->pos+2]<<16) | (t->data[t->pos+3]<<24);\r
-  t->pos+=4;\r
-  return res;\r
-}\r
-\r
-int GetBlock(LPTAG t,U8 * b,int l)\r
-// returns number of bytes written (<=l)\r
-// b = NULL -> skip data\r
-{ ResetBitmask(t);\r
-  if ((t->len-t->pos)<l) l=t->len-t->pos;\r
-  if (b && l) memcpy(b,&t->data[t->pos],l);\r
-  t->pos+=l;\r
-  return l;\r
-}\r
-\r
-int SetBlock(LPTAG t,U8 * b,int l)\r
-// Appends Block to the end of Tagdata, returns size\r
-{ U32 newlen = t->len + l;\r
-  ResetBitcount(t);\r
-  if (newlen>t->memsize)\r
-  { U32  newmem  = MEMSIZE(newlen);  \r
-    U8 * newdata = (U8*)((t->data)?realloc(t->data,newmem):malloc(newmem));\r
-    if (!newdata)\r
-    {\r
-      #ifdef DEBUG_RFXSWF\r
-        fprintf(stderr,"Fatal Error: malloc()/realloc() failed.\n");\r
-      #endif\r
-      return 0;\r
-    }\r
-    t->memsize = newmem;\r
-    t->data    = newdata;\r
-  }\r
-  if (b) memcpy(&t->data[t->len],b,l);\r
-  else memset(&t->data[t->len],0x00,l);\r
-  t->len+=l;\r
-  return l;\r
-}\r
-\r
-int SetU8(LPTAG t,U8 v)\r
-{ ResetBitcount(t);\r
-  if ((t->len+1)>t->memsize) return (SetBlock(t,&v,1)==1)?0:-1;\r
-  t->data[t->len++] = v;\r
-  return 0;\r
-}\r
-\r
-int SetU16(LPTAG t,U16 v)\r
-{ U8 a[2];\r
-  a[0] = v&0xff;\r
-  a[1] = v>>8;\r
-  \r
-  ResetBitcount(t);\r
-  if ((t->len+2)>t->memsize) return (SetBlock(t,a,2)==2)?0:-1;\r
-  t->data[t->len++] = a[0];\r
-  t->data[t->len++] = a[1];\r
-  return 0;\r
-}\r
-\r
-int SetU32(LPTAG t,U32 v)\r
-{ U8 a[4];\r
-  a[0] = v&0xff;        // to ensure correct handling of non-intel byteorder\r
-  a[1] = (v>>8)&0xff;\r
-  a[2] = (v>>16)&0xff;\r
-  a[3] = (v>>24)&0xff;\r
-  \r
-  ResetBitcount(t);\r
-  if ((t->len+4)>t->memsize) return (SetBlock(t,a,4)==4)?0:-1;\r
-  t->data[t->len++] = a[0];\r
-  t->data[t->len++] = a[1];\r
-  t->data[t->len++] = a[2];\r
-  t->data[t->len++] = a[3];\r
-  return 0;\r
-}\r
-\r
-U32 GetBits(LPTAG t,int nbits)\r
-{ U32 res = 0;\r
-  if (!nbits) return 0;\r
-  if (!t->bitmask) t->bitmask = 0x80;\r
-  while (nbits)\r
-  { res<<=1;\r
-    if (t->data[t->pos]&t->bitmask) res|=1;\r
-    t->bitmask>>=1;\r
-    nbits--;\r
-    if (!t->bitmask)\r
-    { if (nbits) t->bitmask = 0x80;\r
-      #ifdef DEBUG_RFXSWF\r
-      if (t->pos>=t->len) \r
-      { fprintf(stderr,"GetBits() out of bounds: TagID = %i\n",t->id);\r
-        return res;\r
-      }\r
-      #endif\r
-      t->pos++;\r
-    }\r
-  }\r
-  return res;\r
-}\r
-\r
-S32 GetSBits(LPTAG t,int nbits)\r
-{ U32 res = GetBits(t,nbits);\r
-  if (res&(1<<(nbits-1))) res|=(0xffffffff<<nbits);  \r
-  return (S32)res;\r
-}\r
-\r
-int SetBits(LPTAG t,U32 v,int nbits)\r
-{ U32 bm = 1<<(nbits-1);\r
-\r
-  while (nbits)\r
-  { if (!t->bitcount)\r
-    { if (FAILED(SetU8(t,0))) return -1;\r
-      t->bitcount = 0x80;\r
-    }\r
-    if (v&bm) t->data[t->len-1] |= t->bitcount;\r
-    bm>>=1;\r
-    t->bitcount>>=1;\r
-    nbits--;\r
-  }\r
-  return 0;\r
-}\r
-\r
-// Advanced Data Access Functions\r
-\r
-int SetRGB(LPTAG t,LPRGBA col)\r
-{ if (!t) return -1;\r
-  if (col)\r
-  { SetU8(t,col->r);\r
-    SetU8(t,col->g);\r
-    SetU8(t,col->b);\r
-  } else SetBlock(t,NULL,3);\r
-  return 0;\r
-}\r
-\r
-int SetRGBA(LPTAG t,LPRGBA col)\r
-{ if (!t) return -1;\r
-  if (col)\r
-  { SetU8(t,col->r);\r
-    SetU8(t,col->g);\r
-    SetU8(t,col->b);\r
-    SetU8(t,col->a);\r
-  } else SetBlock(t,NULL,4);\r
-  return 0;\r
-}\r
-\r
-int CountBits(U32 v,int nbits)\r
-{ int n = 33;\r
-  U32 m = 0x80000000;\r
-  if (!v) n = 0; else\r
-  if (v&m)\r
-  { while (v&m)\r
-    { n--;\r
-      m>>=1;\r
-      if (!m) break;\r
-    } \r
-  }\r
-  else\r
-  { while (!(v&m))\r
-    { n--;\r
-      m>>=1;\r
-      if (!m) break;\r
-    } \r
-  }\r
-  return (n>nbits)?n:nbits;\r
-}\r
-\r
-int GetRect(LPTAG t,LPSRECT r)\r
-{ int nbits;\r
-  SRECT dummy;\r
-  if (!r) r = &dummy;\r
-  nbits = (int) GetBits(t,5);\r
-  r->xmin = GetSBits(t,nbits);\r
-  r->xmax = GetSBits(t,nbits);\r
-  r->ymin = GetSBits(t,nbits);\r
-  r->ymax = GetSBits(t,nbits);\r
-  return 0;\r
-}\r
-\r
-int SetRect(LPTAG t,LPSRECT r)\r
-{ int nbits;\r
-    \r
-  nbits = CountBits(r->xmin,0);\r
-  nbits = CountBits(r->xmax,nbits);\r
-  nbits = CountBits(r->ymin,nbits);\r
-  nbits = CountBits(r->ymax,nbits);\r
-\r
-  SetBits(t,nbits,5);\r
-  SetBits(t,r->xmin,nbits);\r
-  SetBits(t,r->xmax,nbits);\r
-  SetBits(t,r->ymin,nbits);\r
-  SetBits(t,r->ymax,nbits);\r
-\r
-  return 0;\r
-}\r
-\r
-int GetMatrix(LPTAG t,LPMATRIX m)\r
-{ MATRIX dummy;\r
-  int nbits;\r
-    \r
-  if (!m) m = &dummy;\r
-  \r
-  if (!t)\r
-  { m->sx = m->sy = 0x10000;\r
-    m->r0 = m->r1 = 0;\r
-    m->tx = m->ty = 0;\r
-    return -1;\r
-  }\r
-\r
-  ResetBitmask(t);\r
-  \r
-  if (GetBits(t,1))\r
-  { nbits = GetBits(t,5);\r
-    m->sx = GetSBits(t,nbits);\r
-    m->sy = GetSBits(t,nbits);\r
-  }\r
-  else m->sx = m->sy = 0x10000;\r
-  \r
-  if (GetBits(t,1))\r
-  { nbits = GetBits(t,5);\r
-    m->r0 = GetSBits(t,nbits);\r
-    m->r1 = GetSBits(t,nbits);\r
-  }\r
-  else m->r0 = m->r1 = 0x0;\r
-\r
-  nbits = GetBits(t,5);\r
-  m->tx = GetSBits(t,nbits);\r
-  m->ty = GetSBits(t,nbits);\r
-  \r
-  return 0;\r
-}\r
-\r
-int SetMatrix(LPTAG t,LPMATRIX m)\r
-{ int nbits;\r
-  MATRIX ma;\r
-\r
-  if (!m)\r
-  { m = &ma;\r
-    ma.sx = ma.sy = 0x10000;\r
-    ma.r0 = ma.r1 = 0;\r
-    ma.tx = ma.ty = 0;\r
-  }\r
-\r
-  ResetBitcount(t);\r
-\r
-  if ((m->sx==0x10000)&&(m->sy==0x10000)) SetBits(t,0,1);\r
-  else\r
-  { SetBits(t,1,1);\r
-    nbits = CountBits(m->sx,0);\r
-    nbits = CountBits(m->sy,nbits);\r
-    SetBits(t,nbits,5);\r
-    SetBits(t,m->sx,nbits);\r
-    SetBits(t,m->sy,nbits);\r
-  }\r
-\r
-  if ((!m->r0)&&(!m->r1)) SetBits(t,0,1);\r
-  else\r
-  { SetBits(t,1,1);\r
-    nbits = CountBits(m->r0,0);\r
-    nbits = CountBits(m->r1,nbits);\r
-    SetBits(t,nbits,5);\r
-    SetBits(t,m->r0,nbits);\r
-    SetBits(t,m->r1,nbits);\r
-  }\r
-\r
-  nbits = CountBits(m->tx,0);\r
-  nbits = CountBits(m->ty,nbits);\r
-  SetBits(t,nbits,5);\r
-  SetBits(t,m->tx,nbits);\r
-  SetBits(t,m->ty,nbits);\r
-\r
-  return 0;\r
-}\r
-\r
-int GetCXForm(LPTAG t,LPCXFORM cx,U8 alpha) //FIXME: alpha should be type bool\r
-{ CXFORM cxf;\r
-  int hasadd;\r
-  int hasmul;\r
-  int nbits;\r
-    \r
-  if (!cx) cx = &cxf;\r
-  \r
-  cx->a0 = cx->r0 = cx->g0 = cx->b0 = 256;\r
-  cx->a1 = cx->r1 = cx->g1 = cx->b1 = 0;\r
-\r
-  if (!t) return 0;\r
-  \r
-  ResetBitmask(t);\r
-  hasadd = GetBits(t,1);\r
-  hasmul = GetBits(t,1);\r
-  nbits  = GetBits(t,4);\r
-\r
-  if (hasmul)\r
-  { cx->r0 = (S16)GetSBits(t,nbits);\r
-    cx->g0 = (S16)GetSBits(t,nbits);\r
-    cx->b0 = (S16)GetSBits(t,nbits);\r
-    if (alpha)\r
-      cx->a0 = (S16)GetSBits(t,nbits);\r
-  }\r
-\r
-  if (hasadd)\r
-  { cx->r1 = (S16)GetSBits(t,nbits);\r
-    cx->g1 = (S16)GetSBits(t,nbits);\r
-    cx->b1 = (S16)GetSBits(t,nbits);\r
-    if (alpha)\r
-      cx->a1 = (S16)GetSBits(t,nbits);\r
-  }\r
-  \r
-  return 0;\r
-}\r
-\r
-int SetCXForm(LPTAG t,LPCXFORM cx,U8 alpha)\r
-{ CXFORM cxf;\r
-  int hasadd;\r
-  int hasmul;\r
-  int nbits;\r
-    \r
-  if (!cx)\r
-  { cx = &cxf;\r
-    cx->a0 = cx->r0 = cx->g0 = cx->b0 = 256;\r
-    cx->a1 = cx->r1 = cx->g1 = cx->b1 = 0;\r
-  }\r
-\r
-  if (!alpha)\r
-  { cx->a0 = 256;\r
-    cx->a1 = 0;\r
-  }\r
-\r
-  nbits = 0;\r
-\r
-  hasmul = (cx->a0!=256)||(cx->r0!=256)||(cx->g0!=256)||(cx->b0!=256);\r
-  hasadd = cx->a1|cx->r1|cx->g1|cx->b1;\r
-\r
-  if (hasmul)\r
-  { if (alpha) nbits = CountBits((S32)cx->a0,nbits);\r
-    nbits = CountBits((S32)cx->r0,nbits);\r
-    nbits = CountBits((S32)cx->g0,nbits);\r
-    nbits = CountBits((S32)cx->b0,nbits);\r
-  }\r
-\r
-  if (hasadd)\r
-  { if (alpha) nbits = CountBits((S32)cx->a1,nbits);\r
-    nbits = CountBits((S32)cx->r1,nbits);\r
-    nbits = CountBits((S32)cx->g1,nbits);\r
-    nbits = CountBits((S32)cx->b1,nbits);\r
-  }\r
-  \r
-  ResetBitcount(t);\r
-  SetBits(t,hasadd?1:0,1);\r
-  SetBits(t,hasmul?1:0,1);\r
-  SetBits(t,nbits,4);\r
-\r
-  if (hasmul)\r
-  { SetBits(t,cx->r0,nbits);\r
-    SetBits(t,cx->g0,nbits);\r
-    SetBits(t,cx->b0,nbits);\r
-    if (alpha) SetBits(t,cx->a0,nbits);\r
-  }\r
-\r
-  if (hasadd)\r
-  { SetBits(t,cx->r1,nbits);\r
-    SetBits(t,cx->g1,nbits);\r
-    SetBits(t,cx->b1,nbits);\r
-    if (alpha) SetBits(t,cx->a1,nbits);\r
-  }\r
-  \r
-  return 0;\r
-}\r
-\r
-int GetPoint(LPTAG t,LPSPOINT p) { return 0; }\r
-int SetPoint(LPTAG t,LPSPOINT p) { return 0; }\r
-\r
-// Tag List Manipulating Functions\r
-\r
-int RFXSWF_UpdateFrame(LPTAG t,S8 delta)\r
-// returns number of frames\r
-{ int res = -1;\r
-  while (t)\r
-  { t->frame+=delta;\r
-    res = t->frame;\r
-    t = t->next;\r
-  }\r
-  return res;\r
-}\r
-\r
-#define UpdateFrame(a,b) RFXSWF_UpdateFrame(a,b)\r
-\r
-LPTAG InsertTag(LPTAG after,U16 id)     // updates frames, if nescessary\r
-{ LPTAG t;\r
-\r
-  t = (LPTAG)malloc(sizeof(TAG));\r
-  if (t)\r
-  { memset(t,0x00,sizeof(TAG));\r
-    t->id = id;\r
-    t->bitcount = 0x80;\r
-    \r
-    if (after)\r
-    { t->frame = after->frame;\r
-      t->prev  = after;\r
-      t->next  = after->next;\r
-      after->next = t;\r
-      if (t->next) t->next->prev = t;\r
-      \r
-      if (id==ST_SHOWFRAME) UpdateFrame(t->next,+1);\r
-    }\r
-  }\r
-  return t;\r
-}\r
-\r
-int DeleteTag(LPTAG t)\r
-{ if (!t) return -1;\r
-\r
-  if (t->id==ST_SHOWFRAME) UpdateFrame(t->next,-1);\r
-    \r
-  if (t->prev) t->prev->next = t->next;\r
-  if (t->next) t->next->prev = t->prev;\r
-\r
-  if (t->data) free(t->data);\r
-  free(t);\r
-  return 0;\r
-}\r
-\r
-LPTAG RFXSWF_ReadTag(int handle,LPTAG prev)\r
-{ LPTAG t;\r
-  U16 raw;\r
-  U32 len;\r
-  int id;\r
-\r
-  if (read(handle,&raw,2)!=2) return NULL;\r
-\r
-  len = raw&0x3f;\r
-  id  = raw>>6;\r
-\r
-  if (len==0x3f)\r
-  { if (read(handle,&len,4)!=4) return NULL;\r
-  }\r
-\r
-  if (id==ST_DEFINESPRITE) len = 2*sizeof(U16);\r
-  // Sprite handling fix: Flaten sprite tree\r
-\r
-  t = (LPTAG)malloc(sizeof(TAG));\r
-  \r
-  if (!t)\r
-  {\r
-    #ifdef DEBUG_RFXSWF\r
-      fprintf(stderr,"Fatal Error: malloc()/realloc() failed.\n");\r
-    #endif\r
-    return NULL;\r
-  }\r
-\r
-  memset(t,0x00,sizeof(TAG));\r
-  \r
-  t->len = len;\r
-  t->id  = id;\r
-\r
-  if (t->len)\r
-  { t->data = (U8*)malloc(t->len);\r
-    if (!t->data)\r
-    {\r
-      #ifdef DEBUG_RFXSWF\r
-        fprintf(stderr,"Fatal Error: malloc()/realloc() failed.\n");\r
-      #endif\r
-      return NULL;\r
-    }\r
-    t->memsize = t->len;\r
-    if (read(handle,t->data,t->len)!=t->len) return NULL;\r
-  }\r
-\r
-  if (prev)\r
-  { t->frame = prev->frame+((prev->id==ST_SHOWFRAME)?1:0);\r
-    t->prev  = prev;\r
-    prev->next = t;\r
-  }\r
-\r
-  return t;\r
-}\r
-\r
-int DefineSprite_GetRealSize(LPTAG t);\r
-\r
-int RFXSWF_WriteTag(int handle,LPTAG t)\r
-// returns tag length in bytes (incl. Header), -1 = Error\r
-// handle = -1 -> no output\r
-{ U16 raw[3];\r
-  U32 len;\r
-  int short_tag;\r
-\r
-  if (!t) return -1;\r
-\r
-  len = (t->id==ST_DEFINESPRITE)?DefineSprite_GetRealSize(t):t->len;\r
-\r
-  short_tag = len<0x3f;\r
-\r
-  if (handle>=0)\r
-  { if (short_tag)\r
-    { raw[0] = len|((t->id&0x3ff)<<6);\r
-      if (write(handle,raw,2)!=2)\r
-      {\r
-        #ifdef DEBUG_RFXSWF\r
-          fprintf(stderr,"WriteTag() failed: Short Header.\n");\r
-        #endif\r
-        return -1;\r
-      }\r
-    }\r
-    else\r
-    { raw[0] = (t->id<<6)|0x3f;\r
-      raw[1] = (U16)(len&0xffff);\r
-      raw[2] = (U16)(len>>16);\r
-      if (write(handle,raw,6)!=6)\r
-      {\r
-        #ifdef DEBUG_RFXSWF\r
-          fprintf(stderr,"WriteTag() failed: Long Header.\n");\r
-        #endif\r
-        return -1;\r
-      }\r
-    }\r
-    \r
-    if (t->data)\r
-    { if (write(handle,t->data,t->len)!=t->len)\r
-      {\r
-        #ifdef DEBUG_RFXSWF\r
-          fprintf(stderr,"WriteTag() failed: Data.\n");\r
-        #endif\r
-        return -1;\r
-      }\r
-    }\r
-    #ifdef DEBUG_RFXSWF\r
-      else if (t->len) fprintf(stderr,"WriteTag(): Tag Data Error, id=%i\n",t->id);\r
-    #endif\r
-  }\r
-\r
-  return t->len+(short_tag?2:6);\r
-}\r
-\r
-int DefineSprite_GetRealSize(LPTAG t)\r
-// Sprite Handling: Helper function to pack DefineSprite-Tag\r
-{ U32 len = t->len;\r
-  do\r
-  { t = NextTag(t);\r
-    if (t->id!=ST_DEFINESPRITE) len += RFXSWF_WriteTag(-1,t);\r
-    else t = NULL;\r
-  } while (t&&(t->id!=ST_END));\r
-  return len;\r
-}\r
-\r
-#define ReadTag(a,b)  RFXSWF_ReadTag(a,b)\r
-#define WriteTag(a,b) RFXSWF_WriteTag(a,b)\r
-\r
-// Movie Functions\r
-\r
-int ReadSWF(int handle,LPSWF swf)       // Reads SWF to memory (malloc'ed), returns length or <0 if fails\r
-{     \r
-  if (!swf) return -1;\r
-  memset(swf,0x00,sizeof(SWF));\r
-\r
-  { char b[32];                         // Header lesen\r
-    TAG t1;\r
-    LPTAG t;\r
-    \r
-    memset(&t1,0x00,sizeof(TAG));\r
-    \r
-    if ((t1.len=read(handle,b,32))<21) return -1;\r
-    t1.data = (U8*)b;\r
-\r
-    if (GetU8(&t1)!=(U8)'F') return -1;\r
-    if (GetU8(&t1)!=(U8)'W') return -1;\r
-    if (GetU8(&t1)!=(U8)'S') return -1;\r
-\r
-    swf->FileVersion = GetU8(&t1);\r
-    swf->FileSize    = GetU32(&t1);\r
-    GetRect(&t1,&swf->MovieSize);\r
-    swf->FrameRate   = GetU16(&t1);\r
-    swf->FrameCount  = GetU16(&t1);\r
-\r
-    GetU8(&t1);\r
-    lseek(handle,GetTagPos(&t1)-1,SEEK_SET);\r
-  \r
-                                        // Tags lesen und verketten\r
-    t = &t1;\r
-    while (t) t = ReadTag(handle,t);\r
-    swf->FirstTag = t1.next;\r
-    t1.next->prev = NULL;\r
-  }\r
-  \r
-  return 0;\r
-}\r
-int  WriteSWF(int handle,LPSWF swf)     // Writes SWF to file, returns length or <0 if fails\r
-{ U32 len;\r
-  LPTAG t;\r
-    \r
-  if (!swf) return -1;\r
-\r
-  // Insert REFLEX Tag\r
-\r
-#ifdef INSERT_RFX_TAG\r
-\r
-  if (NextTag(swf->FirstTag))\r
-    if (GetTagID(NextTag(swf->FirstTag))!=ST_REFLEX)\r
-      SetBlock(InsertTag(swf->FirstTag,ST_REFLEX),"rfx",3);\r
-\r
-#endif // INSERT_RFX_TAG\r
-\r
-  // Count Frames + File Size\r
-\r
-  len = 0;\r
-  t = swf->FirstTag;\r
-  swf->FrameCount = 0;\r
-\r
-  while(t)\r
-  { len += WriteTag(-1,t);\r
-    if (t->id==ST_SHOWFRAME) swf->FrameCount++;\r
-    t = NextTag(t);\r
-  }\r
-  \r
-  { TAG t1;\r
-    char b[64];\r
-    U32 l;\r
-\r
-    memset(&t1,0x00,sizeof(TAG));\r
-    t1.data    = (U8*)b;\r
-    t1.memsize = 64;\r
-    \r
-    SetU8(&t1,'F');      \r
-    SetU8(&t1,'W');      \r
-    SetU8(&t1,'S');\r
-    SetU8(&t1,swf->FileVersion);\r
-    \r
-    SetU32(&t1,0);                      // Keep space for filesize\r
-    SetRect(&t1,&swf->MovieSize);\r
-    SetU16(&t1,swf->FrameRate);\r
-    SetU16(&t1,swf->FrameCount);\r
-\r
-    l = GetDataSize(&t1);\r
-    swf->FileSize = l+len;\r
-    t1.len = 4;                         // bad & ugly trick !\r
-    SetU32(&t1,swf->FileSize);\r
-\r
-    if (handle>=0)\r
-    { \r
-      int ret = write(handle,b,l);\r
-      if (ret!=l)\r
-      {\r
-        #ifdef DEBUG_RFXSWF\r
-         printf("ret:%d (fd:%d)\n",ret, handle);\r
-         perror("write:");\r
-          fprintf(stderr,"WriteSWF() failed: Header.\n");\r
-        #endif\r
-        return -1;\r
-      }\r
-\r
-      t = swf->FirstTag;\r
-      while (t)\r
-      { if (WriteTag(handle,t)<0) return -1;\r
-        t = NextTag(t);\r
-      }\r
-    }\r
-  }\r
-  return (int)swf->FileSize;\r
-}\r
-\r
-int WriteCGI(LPSWF swf)\r
-{ int len;\r
-  char s[1024];\r
-    \r
-  len = WriteSWF(-1,swf);\r
-\r
-  if (len<0) return -1;\r
-\r
-  sprintf(s,"Content-type: application/x-shockwave-flash\n"\r
-            "Accept-Ranges: bytes\n"\r
-            "Content-Length: %lu\n"\r
-            "Expires: Thu, 13 Apr 2000 23:59:59 GMT\n"\r
-            "\n",len);\r
-            \r
-  write(fileno(stdout),s,strlen(s));\r
-  return WriteSWF(fileno(stdout),swf);\r
-}\r
-\r
-void FreeTags(LPSWF swf)                 // Frees all malloc'ed memory for tags\r
-{ LPTAG t = swf->FirstTag;\r
-\r
-  while (t)\r
-  { LPTAG tnew = t->next;\r
-    if (t->data) free(t->data);\r
-    free(t);\r
-    t = tnew;\r
-  }\r
-}\r
-\r
-// include advanced functions\r
-\r
-#ifdef __NT__\r
-\r
-#include "modules\swfdump.c"\r
-#include "modules\swfshape.c"\r
-#include "modules\swftext.c"\r
-#include "modules\swfobject.c"\r
-#include "modules\swfbutton.c"\r
-#include "modules\swftools.c"\r
-#include "modules\swfcgi.c"\r
-#include "modules\swfbits.c"\r
-\r
-#else\r
-\r
-#include "modules/swfdump.c"\r
-#include "modules/swfshape.c"\r
-#include "modules/swftext.c"\r
-#include "modules/swfobject.c"\r
-#include "modules/swfbutton.c"\r
-#include "modules/swftools.c"\r
-#include "modules/swfcgi.c"\r
-#include "modules/swfbits.c"\r
-\r
-#endif\r
-\r
-\r
+/* rfxswf.c
+
+   Library for creating and reading SWF files or parts of it.
+   There's a module directory which provides some extended functionality.
+   Most modules are included at the bottom of this file.
+
+   Part of the swftools package.
+
+   Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+   This file is distributed under the GPL, see file COPYING for details 
+
+*/
+
+#include "rfxswf.h"
+
+#ifdef HAVE_LIBJPEG
+#ifdef HAVE_JPEGLIB_H
+#include <jpeglib.h>
+#define _JPEGLIB_INCLUDED_
+#endif //HAVE_JPEGLIB_H
+#endif //HAVE_LIBJPEG
+
+// Win32 support may be broken since it was only tested in an older version for Watcom C
+#ifdef __NT__
+#  include <io.h>
+#  include <malloc.h>
+#  include <string.h>
+#  ifdef DEBUG_RFXSWF
+#    include <stdio.h>
+#  endif
+#else
+#endif
+
+// internal constants
+
+#define MALLOC_SIZE     128
+#define INSERT_RFX_TAG
+
+#define MEMSIZE(l) (((l/MALLOC_SIZE)+1)*MALLOC_SIZE)
+
+// inline wrapper functions
+
+TAG * NextTag(TAG * t) { return t->next; }
+TAG * PrevTag(TAG * t) { return t->prev; }
+int   GetFrameNo(TAG * t)  { return t->frame; }
+U16   GetTagID(TAG * t)    { return t->id; }
+U32   GetDataSize(TAG * t) { return t->len; }
+U8*   GetDataSizePtr(TAG * t) { return &(t->data[t->len]); }
+U32   GetTagPos(TAG * t)   { return t->pos; }
+
+// Basic Data Access Functions
+
+#define ResetBitmask(tag)   if (tag->bitmask)  { tag->pos++; tag->bitmask = 0; }
+#define ResetBitcount(tag)  if (tag->bitcount) { tag->bitcount = 0; }
+
+// for future purpose: avoid high level lib functions to change tagpos/bitcount
+
+#define SaveTagPos(tag)
+#define RestoreTagPos(tag)
+
+void SetTagPos(TAG * t,U32 pos)
+{ ResetBitmask(t);
+  if (pos<=t->len) t->pos = pos;
+  #ifdef DEBUG_RFXSWF
+  else fprintf(stderr,"SetTagPos() out of bounds: TagID = %i\n",t->id);
+  #endif
+}
+
+U8 GetU8(TAG * t)
+{ ResetBitmask(t);
+  #ifdef DEBUG_RFXSWF
+    if (t->pos>=t->len) 
+    { fprintf(stderr,"GetU8() out of bounds: TagID = %i\n",t->id);
+      return 0;
+    }
+  #endif
+  return t->data[t->pos++];
+}
+
+U16 GetU16(TAG * t)
+{ U16 res;
+  ResetBitmask(t);
+  #ifdef DEBUG_RFXSWF
+    if (t->pos>(t->len-2)) 
+    { fprintf(stderr,"GetU16() out of bounds: TagID = %i\n",t->id);
+      return 0;
+    }
+  #endif
+  res = t->data[t->pos] | (t->data[t->pos+1]<<8);
+  t->pos+=2;
+  return res;
+}
+
+U32 GetU32(TAG * t)
+{ U32 res;
+  ResetBitmask(t);
+  #ifdef DEBUG_RFXSWF
+    if (t->pos>(t->len-4)) 
+    { fprintf(stderr,"GetU32() out of bounds: TagID = %i\n",t->id);
+      return 0;
+    }
+  #endif
+  res = t->data[t->pos]        | (t->data[t->pos+1]<<8) | 
+       (t->data[t->pos+2]<<16) | (t->data[t->pos+3]<<24);
+  t->pos+=4;
+  return res;
+}
+
+int GetBlock(TAG * t,U8 * b,int l)
+// returns number of bytes written (<=l)
+// b = NULL -> skip data
+{ ResetBitmask(t);
+  if ((t->len-t->pos)<l) l=t->len-t->pos;
+  if (b && l) memcpy(b,&t->data[t->pos],l);
+  t->pos+=l;
+  return l;
+}
+
+int SetBlock(TAG * t,U8 * b,int l)
+// Appends Block to the end of Tagdata, returns size
+{ U32 newlen = t->len + l;
+  ResetBitcount(t);
+  if (newlen>t->memsize)
+  { U32  newmem  = MEMSIZE(newlen);  
+    U8 * newdata = (U8*)((t->data)?realloc(t->data,newmem):malloc(newmem));
+    if (!newdata)
+    {
+      #ifdef DEBUG_RFXSWF
+        fprintf(stderr,"Fatal Error: malloc()/realloc() failed.\n");
+      #endif
+      return 0;
+    }
+    t->memsize = newmem;
+    t->data    = newdata;
+  }
+  if (b) memcpy(&t->data[t->len],b,l);
+  else memset(&t->data[t->len],0x00,l);
+  t->len+=l;
+  return l;
+}
+
+int SetU8(TAG * t,U8 v)
+{ ResetBitcount(t);
+  if ((t->len+1)>t->memsize) return (SetBlock(t,&v,1)==1)?0:-1;
+  t->data[t->len++] = v;
+  return 0;
+}
+
+int SetU16(TAG * t,U16 v)
+{ U8 a[2];
+  a[0] = v&0xff;
+  a[1] = v>>8;
+  
+  ResetBitcount(t);
+  if ((t->len+2)>t->memsize) return (SetBlock(t,a,2)==2)?0:-1;
+  t->data[t->len++] = a[0];
+  t->data[t->len++] = a[1];
+  return 0;
+}
+
+int SetU32(TAG * t,U32 v)
+{ U8 a[4];
+  a[0] = v&0xff;        // to ensure correct handling of non-intel byteorder
+  a[1] = (v>>8)&0xff;
+  a[2] = (v>>16)&0xff;
+  a[3] = (v>>24)&0xff;
+  
+  ResetBitcount(t);
+  if ((t->len+4)>t->memsize) return (SetBlock(t,a,4)==4)?0:-1;
+  t->data[t->len++] = a[0];
+  t->data[t->len++] = a[1];
+  t->data[t->len++] = a[2];
+  t->data[t->len++] = a[3];
+  return 0;
+}
+
+U32 GetBits(TAG * t,int nbits)
+{ U32 res = 0;
+  if (!nbits) return 0;
+  if (!t->bitmask) t->bitmask = 0x80;
+  while (nbits)
+  { res<<=1;
+    if (t->data[t->pos]&t->bitmask) res|=1;
+    t->bitmask>>=1;
+    nbits--;
+    if (!t->bitmask)
+    { if (nbits) t->bitmask = 0x80;
+      #ifdef DEBUG_RFXSWF
+      if (t->pos>=t->len) 
+      { fprintf(stderr,"GetBits() out of bounds: TagID = %i\n",t->id);
+        return res;
+      }
+      #endif
+      t->pos++;
+    }
+  }
+  return res;
+}
+
+S32 GetSBits(TAG * t,int nbits)
+{ U32 res = GetBits(t,nbits);
+  if (res&(1<<(nbits-1))) res|=(0xffffffff<<nbits);  
+  return (S32)res;
+}
+
+int SetBits(TAG * t,U32 v,int nbits)
+{ U32 bm = 1<<(nbits-1);
+
+  while (nbits)
+  { if (!t->bitcount)
+    { if (FAILED(SetU8(t,0))) return -1;
+      t->bitcount = 0x80;
+    }
+    if (v&bm) t->data[t->len-1] |= t->bitcount;
+    bm>>=1;
+    t->bitcount>>=1;
+    nbits--;
+  }
+  return 0;
+}
+
+// Advanced Data Access Functions
+
+int SetRGB(TAG * t,RGBA * col)
+{ if (!t) return -1;
+  if (col)
+  { SetU8(t,col->r);
+    SetU8(t,col->g);
+    SetU8(t,col->b);
+  } else SetBlock(t,NULL,3);
+  return 0;
+}
+
+int SetRGBA(TAG * t,RGBA * col)
+{ if (!t) return -1;
+  if (col)
+  { SetU8(t,col->r);
+    SetU8(t,col->g);
+    SetU8(t,col->b);
+    SetU8(t,col->a);
+  } else SetBlock(t,NULL,4);
+  return 0;
+}
+
+int CountBits(U32 v,int nbits)
+{ int n = 33;
+  U32 m = 0x80000000;
+  if (!v) n = 0; else
+  if (v&m)
+  { while (v&m)
+    { n--;
+      m>>=1;
+      if (!m) break;
+    } 
+  }
+  else
+  { while (!(v&m))
+    { n--;
+      m>>=1;
+      if (!m) break;
+    } 
+  }
+  return (n>nbits)?n:nbits;
+}
+
+int GetRect(TAG * t,SRECT * r)
+{ int nbits;
+  SRECT dummy;
+  if (!r) r = &dummy;
+  nbits = (int) GetBits(t,5);
+  r->xmin = GetSBits(t,nbits);
+  r->xmax = GetSBits(t,nbits);
+  r->ymin = GetSBits(t,nbits);
+  r->ymax = GetSBits(t,nbits);
+  return 0;
+}
+
+int SetRect(TAG * t,SRECT * r)
+{ int nbits;
+    
+  nbits = CountBits(r->xmin,0);
+  nbits = CountBits(r->xmax,nbits);
+  nbits = CountBits(r->ymin,nbits);
+  nbits = CountBits(r->ymax,nbits);
+
+  SetBits(t,nbits,5);
+  SetBits(t,r->xmin,nbits);
+  SetBits(t,r->xmax,nbits);
+  SetBits(t,r->ymin,nbits);
+  SetBits(t,r->ymax,nbits);
+
+  return 0;
+}
+
+int GetMatrix(TAG * t,MATRIX * m)
+{ MATRIX dummy;
+  int nbits;
+    
+  if (!m) m = &dummy;
+  
+  if (!t)
+  { m->sx = m->sy = 0x10000;
+    m->r0 = m->r1 = 0;
+    m->tx = m->ty = 0;
+    return -1;
+  }
+
+  ResetBitmask(t);
+  
+  if (GetBits(t,1))
+  { nbits = GetBits(t,5);
+    m->sx = GetSBits(t,nbits);
+    m->sy = GetSBits(t,nbits);
+  }
+  else m->sx = m->sy = 0x10000;
+  
+  if (GetBits(t,1))
+  { nbits = GetBits(t,5);
+    m->r0 = GetSBits(t,nbits);
+    m->r1 = GetSBits(t,nbits);
+  }
+  else m->r0 = m->r1 = 0x0;
+
+  nbits = GetBits(t,5);
+  m->tx = GetSBits(t,nbits);
+  m->ty = GetSBits(t,nbits);
+  
+  return 0;
+}
+
+int SetMatrix(TAG * t,MATRIX * m)
+{ int nbits;
+  MATRIX ma;
+
+  if (!m)
+  { m = &ma;
+    ma.sx = ma.sy = 0x10000;
+    ma.r0 = ma.r1 = 0;
+    ma.tx = ma.ty = 0;
+  }
+
+  ResetBitcount(t);
+
+  if ((m->sx==0x10000)&&(m->sy==0x10000)) SetBits(t,0,1);
+  else
+  { SetBits(t,1,1);
+    nbits = CountBits(m->sx,0);
+    nbits = CountBits(m->sy,nbits);
+    SetBits(t,nbits,5);
+    SetBits(t,m->sx,nbits);
+    SetBits(t,m->sy,nbits);
+  }
+
+  if ((!m->r0)&&(!m->r1)) SetBits(t,0,1);
+  else
+  { SetBits(t,1,1);
+    nbits = CountBits(m->r0,0);
+    nbits = CountBits(m->r1,nbits);
+    SetBits(t,nbits,5);
+    SetBits(t,m->r0,nbits);
+    SetBits(t,m->r1,nbits);
+  }
+
+  nbits = CountBits(m->tx,0);
+  nbits = CountBits(m->ty,nbits);
+  SetBits(t,nbits,5);
+  SetBits(t,m->tx,nbits);
+  SetBits(t,m->ty,nbits);
+
+  return 0;
+}
+
+int GetCXForm(TAG * t,CXFORM * cx,U8 alpha) //FIXME: alpha should be type bool
+{ CXFORM cxf;
+  int hasadd;
+  int hasmul;
+  int nbits;
+    
+  if (!cx) cx = &cxf;
+  
+  cx->a0 = cx->r0 = cx->g0 = cx->b0 = 256;
+  cx->a1 = cx->r1 = cx->g1 = cx->b1 = 0;
+
+  if (!t) return 0;
+  
+  ResetBitmask(t);
+  hasadd = GetBits(t,1);
+  hasmul = GetBits(t,1);
+  nbits  = GetBits(t,4);
+
+  if (hasmul)
+  { cx->r0 = (S16)GetSBits(t,nbits);
+    cx->g0 = (S16)GetSBits(t,nbits);
+    cx->b0 = (S16)GetSBits(t,nbits);
+    if (alpha)
+      cx->a0 = (S16)GetSBits(t,nbits);
+  }
+
+  if (hasadd)
+  { cx->r1 = (S16)GetSBits(t,nbits);
+    cx->g1 = (S16)GetSBits(t,nbits);
+    cx->b1 = (S16)GetSBits(t,nbits);
+    if (alpha)
+      cx->a1 = (S16)GetSBits(t,nbits);
+  }
+  
+  return 0;
+}
+
+int SetCXForm(TAG * t,CXFORM * cx,U8 alpha)
+{ CXFORM cxf;
+  int hasadd;
+  int hasmul;
+  int nbits;
+    
+  if (!cx)
+  { cx = &cxf;
+    cx->a0 = cx->r0 = cx->g0 = cx->b0 = 256;
+    cx->a1 = cx->r1 = cx->g1 = cx->b1 = 0;
+  }
+
+  if (!alpha)
+  { cx->a0 = 256;
+    cx->a1 = 0;
+  }
+
+  nbits = 0;
+
+  hasmul = (cx->a0!=256)||(cx->r0!=256)||(cx->g0!=256)||(cx->b0!=256);
+  hasadd = cx->a1|cx->r1|cx->g1|cx->b1;
+
+  if (hasmul)
+  { if (alpha) nbits = CountBits((S32)cx->a0,nbits);
+    nbits = CountBits((S32)cx->r0,nbits);
+    nbits = CountBits((S32)cx->g0,nbits);
+    nbits = CountBits((S32)cx->b0,nbits);
+  }
+
+  if (hasadd)
+  { if (alpha) nbits = CountBits((S32)cx->a1,nbits);
+    nbits = CountBits((S32)cx->r1,nbits);
+    nbits = CountBits((S32)cx->g1,nbits);
+    nbits = CountBits((S32)cx->b1,nbits);
+  }
+  
+  ResetBitcount(t);
+  SetBits(t,hasadd?1:0,1);
+  SetBits(t,hasmul?1:0,1);
+  SetBits(t,nbits,4);
+
+  if (hasmul)
+  { SetBits(t,cx->r0,nbits);
+    SetBits(t,cx->g0,nbits);
+    SetBits(t,cx->b0,nbits);
+    if (alpha) SetBits(t,cx->a0,nbits);
+  }
+
+  if (hasadd)
+  { SetBits(t,cx->r1,nbits);
+    SetBits(t,cx->g1,nbits);
+    SetBits(t,cx->b1,nbits);
+    if (alpha) SetBits(t,cx->a1,nbits);
+  }
+  
+  return 0;
+}
+
+int GetPoint(TAG * t,SPOINT * p) { return 0; }
+int SetPoint(TAG * t,SPOINT * p) { return 0; }
+
+// Tag List Manipulating Functions
+
+int RFXSWF_UpdateFrame(TAG * t,S8 delta)
+// returns number of frames
+{ int res = -1;
+  while (t)
+  { t->frame+=delta;
+    res = t->frame;
+    t = t->next;
+  }
+  return res;
+}
+
+#define UpdateFrame(a,b) RFXSWF_UpdateFrame(a,b)
+
+TAG * InsertTag(TAG * after,U16 id)     // updates frames, if nescessary
+{ TAG * t;
+
+  t = (TAG *)malloc(sizeof(TAG));
+  if (t)
+  { memset(t,0x00,sizeof(TAG));
+    t->id = id;
+    t->bitcount = 0x80;
+    
+    if (after)
+    { t->frame = after->frame;
+      t->prev  = after;
+      t->next  = after->next;
+      after->next = t;
+      if (t->next) t->next->prev = t;
+      
+      if (id==ST_SHOWFRAME) UpdateFrame(t->next,+1);
+    }
+  }
+  return t;
+}
+
+int DeleteTag(TAG * t)
+{ if (!t) return -1;
+
+  if (t->id==ST_SHOWFRAME) UpdateFrame(t->next,-1);
+    
+  if (t->prev) t->prev->next = t->next;
+  if (t->next) t->next->prev = t->prev;
+
+  if (t->data) free(t->data);
+  free(t);
+  return 0;
+}
+
+TAG * RFXSWF_ReadTag(int handle,TAG * prev)
+{ TAG * t;
+  U16 raw;
+  U32 len;
+  int id;
+
+  if (read(handle,&raw,2)!=2) return NULL;
+
+  len = raw&0x3f;
+  id  = raw>>6;
+
+  if (len==0x3f)
+  { if (read(handle,&len,4)!=4) return NULL;
+  }
+
+  if (id==ST_DEFINESPRITE) len = 2*sizeof(U16);
+  // Sprite handling fix: Flaten sprite tree
+
+  t = (TAG *)malloc(sizeof(TAG));
+  
+  if (!t)
+  {
+    #ifdef DEBUG_RFXSWF
+      fprintf(stderr,"Fatal Error: malloc()/realloc() failed.\n");
+    #endif
+    return NULL;
+  }
+
+  memset(t,0x00,sizeof(TAG));
+  
+  t->len = len;
+  t->id  = id;
+
+  if (t->len)
+  { t->data = (U8*)malloc(t->len);
+    if (!t->data)
+    {
+      #ifdef DEBUG_RFXSWF
+        fprintf(stderr,"Fatal Error: malloc()/realloc() failed.\n");
+      #endif
+      return NULL;
+    }
+    t->memsize = t->len;
+    if (read(handle,t->data,t->len)!=t->len) return NULL;
+  }
+
+  if (prev)
+  { t->frame = prev->frame+((prev->id==ST_SHOWFRAME)?1:0);
+    t->prev  = prev;
+    prev->next = t;
+  }
+
+  return t;
+}
+
+int DefineSprite_GetRealSize(TAG * t);
+
+int RFXSWF_WriteTag(int handle,TAG * t)
+// returns tag length in bytes (incl. Header), -1 = Error
+// handle = -1 -> no output
+{ U16 raw[3];
+  U32 len;
+  int short_tag;
+
+  if (!t) return -1;
+
+  len = (t->id==ST_DEFINESPRITE)?DefineSprite_GetRealSize(t):t->len;
+
+  short_tag = len<0x3f;
+
+  if (handle>=0)
+  { if (short_tag)
+    { raw[0] = len|((t->id&0x3ff)<<6);
+      if (write(handle,raw,2)!=2)
+      {
+        #ifdef DEBUG_RFXSWF
+          fprintf(stderr,"WriteTag() failed: Short Header.\n");
+        #endif
+        return -1;
+      }
+    }
+    else
+    { raw[0] = (t->id<<6)|0x3f;
+      raw[1] = (U16)(len&0xffff);
+      raw[2] = (U16)(len>>16);
+      if (write(handle,raw,6)!=6)
+      {
+        #ifdef DEBUG_RFXSWF
+          fprintf(stderr,"WriteTag() failed: Long Header.\n");
+        #endif
+        return -1;
+      }
+    }
+    
+    if (t->data)
+    { if (write(handle,t->data,t->len)!=t->len)
+      {
+        #ifdef DEBUG_RFXSWF
+          fprintf(stderr,"WriteTag() failed: Data.\n");
+        #endif
+        return -1;
+      }
+    }
+    #ifdef DEBUG_RFXSWF
+      else if (t->len) fprintf(stderr,"WriteTag(): Tag Data Error, id=%i\n",t->id);
+    #endif
+  }
+
+  return t->len+(short_tag?2:6);
+}
+
+int DefineSprite_GetRealSize(TAG * t)
+// Sprite Handling: Helper function to pack DefineSprite-Tag
+{ U32 len = t->len;
+  do
+  { t = NextTag(t);
+    if (t->id!=ST_DEFINESPRITE) len += RFXSWF_WriteTag(-1,t);
+    else t = NULL;
+  } while (t&&(t->id!=ST_END));
+  return len;
+}
+
+#define ReadTag(a,b)  RFXSWF_ReadTag(a,b)
+#define WriteTag(a,b) RFXSWF_WriteTag(a,b)
+
+// Movie Functions
+
+int ReadSWF(int handle,SWF * swf)       // Reads SWF to memory (malloc'ed), returns length or <0 if fails
+{     
+  if (!swf) return -1;
+  memset(swf,0x00,sizeof(SWF));
+
+  { char b[32];                         // Header lesen
+    TAG t1;
+    TAG * t;
+    
+    memset(&t1,0x00,sizeof(TAG));
+    
+    if ((t1.len=read(handle,b,32))<21) return -1;
+    t1.data = (U8*)b;
+
+    if (GetU8(&t1)!=(U8)'F') return -1;
+    if (GetU8(&t1)!=(U8)'W') return -1;
+    if (GetU8(&t1)!=(U8)'S') return -1;
+
+    swf->FileVersion = GetU8(&t1);
+    swf->FileSize    = GetU32(&t1);
+    GetRect(&t1,&swf->MovieSize);
+    swf->FrameRate   = GetU16(&t1);
+    swf->FrameCount  = GetU16(&t1);
+
+    GetU8(&t1);
+    lseek(handle,GetTagPos(&t1)-1,SEEK_SET);
+  
+                                        // Tags lesen und verketten
+    t = &t1;
+    while (t) t = ReadTag(handle,t);
+    swf->FirstTag = t1.next;
+    t1.next->prev = NULL;
+  }
+  
+  return 0;
+}
+int  WriteSWF(int handle,SWF * swf)     // Writes SWF to file, returns length or <0 if fails
+{ U32 len;
+  TAG * t;
+    
+  if (!swf) return -1;
+
+  // Insert REFLEX Tag
+
+#ifdef INSERT_RFX_TAG
+
+  if (NextTag(swf->FirstTag))
+    if (GetTagID(NextTag(swf->FirstTag))!=ST_REFLEX)
+      SetBlock(InsertTag(swf->FirstTag,ST_REFLEX),"rfx",3);
+
+#endif // INSERT_RFX_TAG
+
+  // Count Frames + File Size
+
+  len = 0;
+  t = swf->FirstTag;
+  swf->FrameCount = 0;
+
+  while(t)
+  { len += WriteTag(-1,t);
+    if (t->id==ST_SHOWFRAME) swf->FrameCount++;
+    t = NextTag(t);
+  }
+  
+  { TAG t1;
+    char b[64];
+    U32 l;
+
+    memset(&t1,0x00,sizeof(TAG));
+    t1.data    = (U8*)b;
+    t1.memsize = 64;
+    
+    SetU8(&t1,'F');      
+    SetU8(&t1,'W');      
+    SetU8(&t1,'S');
+    SetU8(&t1,swf->FileVersion);
+    
+    SetU32(&t1,0);                      // Keep space for filesize
+    SetRect(&t1,&swf->MovieSize);
+    SetU16(&t1,swf->FrameRate);
+    SetU16(&t1,swf->FrameCount);
+
+    l = GetDataSize(&t1);
+    swf->FileSize = l+len;
+    t1.len = 4;                         // bad & ugly trick !
+    SetU32(&t1,swf->FileSize);
+
+    if (handle>=0)
+    { 
+      int ret = write(handle,b,l);
+      if (ret!=l)
+      {
+        #ifdef DEBUG_RFXSWF
+         printf("ret:%d (fd:%d)\n",ret, handle);
+         perror("write:");
+          fprintf(stderr,"WriteSWF() failed: Header.\n");
+        #endif
+        return -1;
+      }
+
+      t = swf->FirstTag;
+      while (t)
+      { if (WriteTag(handle,t)<0) return -1;
+        t = NextTag(t);
+      }
+    }
+  }
+  return (int)swf->FileSize;
+}
+
+int WriteCGI(SWF * swf)
+{ int len;
+  char s[1024];
+    
+  len = WriteSWF(-1,swf);
+
+  if (len<0) return -1;
+
+  sprintf(s,"Content-type: application/x-shockwave-flash\n"
+            "Accept-Ranges: bytes\n"
+            "Content-Length: %lu\n"
+            "Expires: Thu, 13 Apr 2000 23:59:59 GMT\n"
+            "\n",len);
+            
+  write(fileno(stdout),s,strlen(s));
+  return WriteSWF(fileno(stdout),swf);
+}
+
+void FreeTags(SWF * swf)                 // Frees all malloc'ed memory for tags
+{ TAG * t = swf->FirstTag;
+
+  while (t)
+  { TAG * tnew = t->next;
+    if (t->data) free(t->data);
+    free(t);
+    t = tnew;
+  }
+}
+
+// include advanced functions
+
+#ifdef __NT__
+
+#include "modules\swfdump.c"
+#include "modules\swfshape.c"
+#include "modules\swftext.c"
+#include "modules\swfobject.c"
+#include "modules\swfbutton.c"
+#include "modules\swftools.c"
+#include "modules\swfcgi.c"
+#include "modules\swfbits.c"
+
+#else
+
+#include "modules/swfdump.c"
+#include "modules/swfshape.c"
+#include "modules/swftext.c"
+#include "modules/swfobject.c"
+#include "modules/swfbutton.c"
+#include "modules/swftools.c"
+#include "modules/swfcgi.c"
+#include "modules/swfbits.c"
+
+#endif
+
+
index 27d4a93..5efc48a 100644 (file)
-/* rfxswf.h\r
-\r
-   Headers for rfxswf.c and modules\r
-\r
-   Part of the swftools package.\r
-\r
-   Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
\r
-   This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-#ifndef __RFX_SWF_INCLUDED__\r
-#define __RFX_SWF_INCLUDED__\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include "../config.h"\r
-#include "old_rfxswf.h"\r
-\r
-#define DEBUG_RFXSWF\r
-\r
-// SWF Types\r
-\r
-typedef         unsigned long   U32;\r
-typedef         signed long     S32;\r
-typedef         unsigned short  U16;\r
-typedef         signed short    S16;\r
-typedef         unsigned char   U8;\r
-typedef         signed char     S8;\r
-typedef         signed long     SFIXED;\r
-typedef         signed long     SCOORD;\r
-\r
-// Basic Structures\r
-\r
-typedef struct _SPOINT\r
-{ SCOORD        x;\r
-  SCOORD        y;\r
-} SPOINT, * LPSPOINT;\r
-\r
-typedef struct _RGBA\r
-{ U8    r;\r
-  U8    g;\r
-  U8    b;\r
-  U8    a;\r
-} RGBA, * LPRGBA;\r
-\r
-typedef struct _SRECT\r
-{ SCOORD        xmin;\r
-  SCOORD        ymin;\r
-  SCOORD        xmax;\r
-  SCOORD        ymax;\r
-} SRECT, * LPSRECT;\r
-\r
-typedef struct _MATRIX\r
-{ SFIXED        sx;     // factor x\r
-  SFIXED        sy;\r
-  SFIXED        r0;     // rotation\r
-  SFIXED        r1;\r
-  SCOORD        tx;     // delta x\r
-  SCOORD        ty;\r
-} MATRIX, * LPMATRIX;\r
-\r
-typedef struct _CXFORM\r
-{ S16           a0, a1;\r
-  S16           r0, r1;\r
-  S16           g0, g1;\r
-  S16           b0, b1;\r
-} CXFORM, * LPCXFORM;\r
-\r
-typedef struct _TAG             // NEVER access a Tag-Struct directly !\r
-{ U16           id;\r
-  U32           len;\r
-  U8 *          data;\r
-\r
-  int           frame;\r
-\r
-  struct _TAG * next;\r
-  struct _TAG * prev;\r
-\r
-  U32           memsize;        // to minimize realloc() calls\r
-  U32           pos;            // for Get/Set-Access\r
-  U8            bitmask;        // for Bit-Manipulating Functions [read]\r
-  U8            bitcount;       // [write]\r
-} TAG, * LPTAG;\r
-\r
-typedef struct _SWF\r
-{ U8            FileVersion;\r
-  U32           FileSize;       // valid after load and save\r
-  SRECT         MovieSize;\r
-  U16           FrameRate;\r
-  U16           FrameCount;     // valid after load and save\r
-  LPTAG         FirstTag;\r
-} SWF, * LPSWF;\r
-\r
-// Basic Functions\r
-\r
-int  ReadSWF(int handle,LPSWF swf);     // Reads SWF to memory (malloc'ed), returns length or <0 if fails\r
-int  WriteSWF(int handle,LPSWF swf);    // Writes SWF to file, returns length or <0 if fails\r
-int  WriteCGI(LPSWF swf);               // Outputs SWF with valid CGI header to stdout\r
-void FreeTags(LPSWF swf);               // Frees all malloc'ed memory for swf\r
-    \r
-LPTAG InsertTag(LPTAG after,U16 id);    // updates frames, if necessary\r
-int   DeleteTag(LPTAG t);\r
-\r
-void  SetTagPos(LPTAG t,U32 pos);       // resets Bitcount\r
-U32   GetTagPos(LPTAG t);\r
-\r
-LPTAG NextTag(LPTAG t);\r
-LPTAG PrevTag(LPTAG t);\r
-\r
-int   GetFrameNo(LPTAG t);\r
-U16   GetTagID(LPTAG t);\r
-U32   GetDataSize(LPTAG t);\r
-U8*   GetDataSizePtr(LPTAG t);\r
-\r
-U32   GetBits(LPTAG t,int nbits);\r
-S32   GetSBits(LPTAG t,int nbits);\r
-int   SetBits(LPTAG t,U32 v,int nbits);\r
-\r
-int   GetBlock(LPTAG t,U8 * b,int l);   // resets Bitcount\r
-int   SetBlock(LPTAG t,U8 * b,int l);\r
-\r
-U8    GetU8(LPTAG t);                   // resets Bitcount\r
-U16   GetU16(LPTAG t);\r
-U32   GetU32(LPTAG t);\r
-\r
-int   SetU8(LPTAG t,U8 v);              // resets Bitcount\r
-int   SetU16(LPTAG t,U16 v);\r
-int   SetU32(LPTAG t,U32 v);\r
-\r
-int   GetPoint(LPTAG t,LPSPOINT p);     // resets Bitcount\r
-int   GetRect(LPTAG t,LPSRECT r);\r
-int   GetMatrix(LPTAG t,LPMATRIX m);\r
-int   GetCXForm(LPTAG t,LPCXFORM cx,U8 alpha);\r
-\r
-int   SetPoint(LPTAG t,LPSPOINT p);     // resets Bitcount\r
-int   SetRect(LPTAG t,LPSRECT r);\r
-int   SetMatrix(LPTAG t,LPMATRIX m);\r
-int   SetCXForm(LPTAG t,LPCXFORM cx,U8 alpha);\r
-int   SetRGB(LPTAG t,LPRGBA col);\r
-int   SetRGBA(LPTAG t,LPRGBA col);\r
-\r
-// Function Macros\r
-\r
-#define GetS8(tag)      ((S8)GetU8(tag))\r
-#define GetS16(tag)     ((S16)GetU16(tag))\r
-#define GetS32(tag)     ((S32)GetU32(tag))\r
-#define GetCoord(tag)   ((SCOORD)GetU32(tag))\r
-#define GetFixed(tag)   ((SFIXED)GetU32(tag))\r
-\r
-#define SetS8(tag,v)    SetU8(tag,(U8)v)\r
-#define SetS16(tag,v)   SetU16(tag,(U16)v)\r
-#define SetS32(tag,v)   SetU32(tag,(U32)v)\r
-#define SetCoord(tag,v) SetU32(tag,(U32)v)\r
-#define SetFixed(tag,v) SetU32(tag,(U32)v)\r
-#define SetString(t,s)  SetBlock(t,s,strlen(s)+1)\r
-\r
-#define FAILED(b)       ((b)<0)\r
-#define SUCCEDED(b)     ((b)>=0)\r
-\r
-// Tag IDs (adopted from J. C. Kessels' Form2Flash)\r
-\r
-#define ST_END                  0\r
-#define ST_SHOWFRAME            1\r
-#define ST_DEFINESHAPE          2\r
-#define ST_FREECHARACTER        3\r
-#define ST_PLACEOBJECT          4\r
-#define ST_REMOVEOBJECT         5\r
-#define ST_DEFINEBITS           6\r
-#define ST_DEFINEBUTTON         7\r
-#define ST_JPEGTABLES           8\r
-#define ST_SETBACKGROUNDCOLOR   9\r
-#define ST_DEFINEFONT           10\r
-#define ST_DEFINETEXT           11\r
-#define ST_DOACTION             12\r
-#define ST_DEFINEFONTINFO       13\r
-#define ST_DEFINESOUND          14 /* Event sound tags. */\r
-#define ST_STARTSOUND           15\r
-#define ST_DEFINEBUTTONSOUND    17\r
-#define ST_SOUNDSTREAMHEAD      18\r
-#define ST_SOUNDSTREAMBLOCK     19\r
-#define ST_DEFINEBITSLOSSLESS   20 /* A bitmap using lossless zlib compression. */\r
-#define ST_DEFINEBITSJPEG2      21 /* A bitmap using an internal JPEG compression table. */\r
-#define ST_DEFINESHAPE2         22\r
-#define ST_DEFINEBUTTONCXFORM   23\r
-#define ST_PROTECT              24 /* This file should not be importable for editing. */\r
-#define ST_PLACEOBJECT2         26 /* The new style place w/ alpha color transform and name. */\r
-#define ST_REMOVEOBJECT2        28 /* A more compact remove object that omits the character tag (just depth). */\r
-#define ST_DEFINESHAPE3         32 /* A shape V3 includes alpha values. */\r
-#define ST_DEFINETEXT2          33 /* A text V2 includes alpha values. */\r
-#define ST_DEFINEBUTTON2        34 /* A button V2 includes color transform, alpha and multiple actions */\r
-#define ST_DEFINEBITSJPEG3      35 /* A JPEG bitmap with alpha info. */\r
-#define ST_DEFINEBITSLOSSLESS2  36 /* A lossless bitmap with alpha info. */\r
-#define ST_DEFINEEDITTEXT       37\r
-#define ST_DEFINEMOVIE         38\r
-#define ST_DEFINESPRITE         39 /* Define a sequence of tags that describe the behavior of a sprite. */\r
-#define ST_NAMECHARACTER        40 /* Name a character definition, character id and a string, (used for buttons, bitmaps, sprites and sounds). */\r
-#define ST_SERIALNUMBER         41\r
-#define ST_GENERATORTEXT        42 /* contains an id */\r
-#define ST_FRAMELABEL           43 /* A string label for the current frame. */\r
-#define ST_SOUNDSTREAMHEAD2     45 /* For lossless streaming sound, should not have needed this... */\r
-#define ST_DEFINEMORPHSHAPE     46 /* A morph shape definition */\r
-#define ST_DEFINEFONT2          48\r
-#define ST_TEMPLATECOMMAND      49\r
-#define ST_GENERATOR3           51\r
-#define ST_EXTERNALFONT         52\r
-\r
-#define ST_REFLEX              777 /* to identify generator software */\r
-\r
-// Advanced Funtions\r
-\r
-// swfdump.c\r
-\r
-void DumpHeader(FILE * f,LPSWF swf);\r
-void DumpMatrix(FILE * f,LPMATRIX m);\r
-void DumpTag(FILE * f,LPTAG t); \r
-char* getTagName(TAG*tag);\r
-\r
-// swfshape.c\r
-\r
-typedef struct _LINESTYLE\r
-{ U16           width;\r
-  RGBA          color;\r
-} LINESTYLE, * LPLINESTYLE;\r
-\r
-typedef struct _FILLSTYLE\r
-{ U8     type;\r
-  RGBA   color;\r
-  MATRIX         m; \r
-  U16    id_bitmap;\r
-} FILLSTYLE, * LPFILLSTYLE;\r
-     \r
-typedef struct _SHAPE           // NEVER access a Shape-Struct directly !\r
-{                 \r
-  struct\r
-  { LPLINESTYLE data;\r
-    U16         n;\r
-  } linestyle;\r
-                  // note: changes of shape structure\r
-  struct                  // lead to incompatible .efont formats\r
-  { LPFILLSTYLE data;\r
-    U16         n;\r
-  } fillstyle;\r
-\r
-  S32           px;\r
-  S32           py;\r
-  \r
-  struct\r
-  { U16         fill;\r
-    U16         line;\r
-  } bits;\r
-  \r
-  U8 *          data;\r
-  U32           bitlen;         // length of data in bits\r
-} SHAPE, * LPSHAPE;\r
-\r
-// Shapes\r
-\r
-int   NewShape(LPSHAPE * s);\r
-void  ShapeFree(LPSHAPE s);\r
-\r
-int   GetSimpleShape(LPTAG t,LPSHAPE * s); // without Linestyle/Fillstyle Record\r
-int   SetSimpleShape(LPTAG t,LPSHAPE s);   // without Linestyle/Fillstyle Record\r
-\r
-int   ShapeAddLineStyle(LPSHAPE s,U16 width,LPRGBA color);\r
-int   ShapeAddSolidFillStyle(LPSHAPE s,LPRGBA color);\r
-int   ShapeAddBitmapFillStyle(LPSHAPE s,LPMATRIX m,U16 id_bitmap,int clip);\r
-\r
-int   SetShapeStyles(LPTAG t,LPSHAPE s);\r
-int   ShapeCountBits(LPSHAPE s,U8 * fbits,U8 * lbits);\r
-int   SetShapeBits(LPTAG t,LPSHAPE s);\r
-int   SetShapeHeader(LPTAG t,LPSHAPE s); // one call for upper three functions\r
-\r
-int   ShapeSetMove(LPTAG t,LPSHAPE s,S32 x,S32 y);\r
-int   ShapeSetStyle(LPTAG t,LPSHAPE s,U16 line,U16 fill0,U16 fill1);\r
-int   ShapeSetAll(LPTAG t,LPSHAPE s,S32 x,S32 y,U16 line,U16 fill0,U16 fill1);\r
-\r
-int   ShapeSetLine(LPTAG t,LPSHAPE s,S32 x,S32 y);\r
-int   ShapeSetCurve(LPTAG t,LPSHAPE s,S32 x,S32 y,S32 ax,S32 ay);\r
-int   ShapeSetCircle(LPTAG t,LPSHAPE s,S32 x,S32 y,S32 rx,S32 ry);\r
-int   ShapeSetEnd(LPTAG t);\r
-\r
-\r
-// swffont.c\r
-\r
-// does not support wide characters !\r
-\r
-#define MAX_CHAR_PER_FONT 256\r
-\r
-typedef struct _SWFLAYOUT\r
-{ S16         ascent;\r
-  S16         descent;\r
-  S16         leading;\r
-  SRECT       bounds[MAX_CHAR_PER_FONT];\r
-  struct\r
-  { U16       count;\r
-    U8 *      data;  // size = count*4 bytes\r
-  } kerning;\r
-} SWFLAYOUT, * LPSWFLAYOUT;\r
-\r
-typedef struct _SWFFONT\r
-{ U16           id;\r
-  U8 *          name;\r
-  LPSWFLAYOUT   layout;\r
-\r
-  U8            flags; // bold/italic/unicode/ansi ...\r
-\r
-  U16           codes[MAX_CHAR_PER_FONT];\r
-  \r
-  struct\r
-  { U16         advance;\r
-    U16         gid;            // Glyph-ID after DefineFont\r
-    LPSHAPE     shape;\r
-  }             glyph[MAX_CHAR_PER_FONT];\r
-} SWFFONT, * LPSWFFONT;\r
-\r
-typedef struct _FONTUSAGE\r
-{ U8 code[MAX_CHAR_PER_FONT];\r
-} FONTUSAGE, * LPFONTUSAGE;\r
-\r
-int FontEnumerate(LPSWF swf,void (*FontCallback) (U16,U8*));\r
-// -> void fontcallback(U16 id,U8 * name); returns number of defined fonts\r
-\r
-int FontExtract(LPSWF swf,int id,LPSWFFONT * f);\r
-// Fetches all available information from DefineFont, DefineFontInfo, DefineText, ...\r
-// id = FontID, id=0 -> Extract first Font\r
-\r
-int FontIsItalic(LPSWFFONT f);\r
-int FontIsBold(LPSWFFONT f);\r
-\r
-int FontSetID(LPSWFFONT f,U16 id);\r
-int FontReduce(LPSWFFONT f,LPFONTUSAGE use);\r
-\r
-int FontInitUsage(LPFONTUSAGE use);\r
-int FontUse(LPFONTUSAGE use,U8 * s);\r
-\r
-int FontSetDefine(LPTAG t,LPSWFFONT f);\r
-int FontSetInfo(LPTAG t,LPSWFFONT f);\r
-\r
-int FontExport(int handle,LPSWFFONT f);\r
-int FontImport(int handle,LPSWFFONT * f);\r
-\r
-void FontFree(LPSWFFONT f);\r
-\r
-U32 TextGetWidth(LPSWFFONT font,U8 * s,int scale);\r
-int TextCountBits(LPSWFFONT font,U8 * s,int scale,U8 * gbits,U8 * abits);\r
-\r
-int TextSetInfoRecord(LPTAG t,LPSWFFONT font,U16 size,LPRGBA color,S16 dx,S16 dy);\r
-int TextSetCharRecord(LPTAG t,LPSWFFONT font,U8 * s,int scale,U8 gbits,U8 abits);\r
-\r
-int TextPrintDefineText(LPTAG t,LPSWFFONT f);\r
-// Prints text defined in tag t with font f to stdout\r
-\r
-\r
-// swfobject.c\r
-\r
-// Always use ST_PLACEOBJECT2 !!!\r
-\r
-int ObjectPlace(LPTAG t,U16 id,U16 depth,LPMATRIX m,LPCXFORM cx,U8 * name);\r
-int PlaceObject(LPTAG t,U16 id,U16 depth,LPMATRIX m,LPCXFORM cx,U8 * name, U16 clipaction);\r
-int ObjectMove(LPTAG t,U16 depth,LPMATRIX m,LPCXFORM cx);\r
-\r
-// swfbutton.c\r
-\r
-// Button States\r
-\r
-#define BS_HIT          0x08\r
-#define BS_DOWN         0x04\r
-#define BS_OVER         0x02\r
-#define BS_UP           0x01\r
-\r
-// Button Conditions\r
-\r
-#define BC_OVERDOWN_IDLE        0x0100\r
-#define BC_IDLE_OVERDOWN        0x0080\r
-#define BC_OUTDOWN_IDLE         0x0040\r
-#define BC_OUTDOWN_OVERDOWN     0x0020\r
-#define BC_OVERDOWN_OUTDOWN     0x0010\r
-#define BC_OVERDOWN_OVERUP      0x0008\r
-#define BC_OVERUP_OVERDOWN      0x0004\r
-#define BC_OVERUP_IDLE          0x0002\r
-#define BC_IDLE_OVERUP          0x0001\r
-\r
-#define BC_KEY(c) (c<<9)\r
-\r
-#define BC_CURSORLEFT           0x0200\r
-#define BC_CURSORRIGHT          0x0400\r
-#define BC_POS1                 0x0600\r
-#define BC_END                  0x0800\r
-#define BC_INSERT               0x0a00\r
-#define BC_DELETE               0x0c00\r
-#define BC_BACKSPACE            0x1000\r
-#define BC_ENTER                0x1a00\r
-#define BC_CURSORUP             0x1c00\r
-#define BC_CURSORDOWN           0x1e00\r
-#define BC_PAGEUP               0x2000\r
-#define BC_PAGEDOWN             0x2200\r
-#define BC_TAB                  0x2400\r
-#define BC_SPACE                0x4000\r
-\r
-// Button Flag\r
-\r
-#define BF_TRACKMENU            0x01\r
-\r
-int ButtonSetRecord(LPTAG t,U8 state,U16 id,U16 layer,LPMATRIX m,LPCXFORM cx);\r
-int ButtonSetCondition(LPTAG t,U16 condition); // for DefineButton2\r
-int ButtonSetFlags(LPTAG t,U8 flags);  // necessary for DefineButton2\r
-int ButtonPostProcess(LPTAG t,int anz_action); // Set all offsets in DefineButton2-Tags (how many conditions to process)\r
-\r
-// swfbits.c\r
-\r
-typedef int * LPJPEGBITS; // cover libjpeg structures\r
-\r
-LPJPEGBITS SetJPEGBitsStart(LPTAG t,int width,int height,int quality);\r
-int SetJPEGBitsLines(LPJPEGBITS jpegbits,U8 ** data,int n);\r
-int SetJPEGBitsLine(LPJPEGBITS jpegbits,U8 * data);\r
-int SetJPEGBitsFinish(LPJPEGBITS jpegbits);\r
-\r
-int SetJPEGBits(LPTAG t,char * fname,int quality); // paste jpg file into swf stream\r
-\r
-// swftools.c\r
-\r
-char isDefiningTag(LPTAG t);\r
-char isAllowedSpriteTag(LPTAG t);\r
-U16 GetDefineID(LPTAG t);\r
-U16 GetPlaceID(LPTAG t); //PLACEOBJECT, PLACEOBJECT2 (sometimes), REMOVEOBJECT\r
-U16 GetDepth(LPTAG t); //PLACEOBJECT,PLACEOBJECT2,REMOVEOBJECT,REMOVEOBJECT2\r
-char* GetName(LPTAG t); //PLACEOBJECT2, FRAMELABEL\r
-LPMATRIX MatrixJoin(LPMATRIX d,LPMATRIX s1,LPMATRIX s2);\r
-LPMATRIX MatrixMapTriangle(LPMATRIX m,int dx,int dy,\r
-                    int x0,int y0,int x1,int y1,int x2,int y2);\r
-\r
-\r
-// swfcgi.c\r
-\r
-void uncgi();  // same behaviour as Steven Grimm's uncgi-library\r
-\r
-#endif\r
+/* rfxswf.h
+
+   Headers for rfxswf.c and modules
+
+   Part of the swftools package.
+
+   Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+   This file is distributed under the GPL, see file COPYING for details 
+
+*/
+
+#ifndef __RFX_SWF_INCLUDED__
+#define __RFX_SWF_INCLUDED__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../config.h"
+#include "old_rfxswf.h"
+
+#define DEBUG_RFXSWF
+
+// SWF Types
+
+typedef         unsigned long   U32;
+typedef         signed long     S32;
+typedef         unsigned short  U16;
+typedef         signed short    S16;
+typedef         unsigned char   U8;
+typedef         signed char     S8;
+typedef         signed long     SFIXED;
+typedef         signed long     SCOORD;
+
+// Basic Structures
+
+typedef struct _SPOINT
+{ SCOORD        x;
+  SCOORD        y;
+} SPOINT, * LPSPOINT;
+
+typedef struct _RGBA
+{ U8    r;
+  U8    g;
+  U8    b;
+  U8    a;
+} RGBA, * LPRGBA;
+
+typedef struct _SRECT
+{ SCOORD        xmin;
+  SCOORD        ymin;
+  SCOORD        xmax;
+  SCOORD        ymax;
+} SRECT, * LPSRECT;
+
+typedef struct _MATRIX
+{ SFIXED        sx;     // factor x
+  SFIXED        sy;
+  SFIXED        r0;     // rotation
+  SFIXED        r1;
+  SCOORD        tx;     // delta x
+  SCOORD        ty;
+} MATRIX, * LPMATRIX;
+
+typedef struct _CXFORM
+{ S16           a0, a1;
+  S16           r0, r1;
+  S16           g0, g1;
+  S16           b0, b1;
+} CXFORM, * LPCXFORM;
+
+typedef struct _TAG             // NEVER access a Tag-Struct directly !
+{ U16           id;
+  U32           len;
+  U8 *          data;
+
+  int           frame;
+
+  struct _TAG * next;
+  struct _TAG * prev;
+
+  U32           memsize;        // to minimize realloc() calls
+  U32           pos;            // for Get/Set-Access
+  U8            bitmask;        // for Bit-Manipulating Functions [read]
+  U8            bitcount;       // [write]
+} TAG, * LPTAG;
+
+typedef struct _SWF
+{ U8            FileVersion;
+  U32           FileSize;       // valid after load and save
+  SRECT         MovieSize;
+  U16           FrameRate;
+  U16           FrameCount;     // valid after load and save
+  TAG *         FirstTag;
+} SWF, * LPSWF;
+
+// Basic Functions
+
+int  ReadSWF(int handle,SWF * swf);     // Reads SWF to memory (malloc'ed), returns length or <0 if fails
+int  WriteSWF(int handle,SWF * swf);    // Writes SWF to file, returns length or <0 if fails
+int  WriteCGI(SWF * swf);               // Outputs SWF with valid CGI header to stdout
+void FreeTags(SWF * swf);               // Frees all malloc'ed memory for swf
+    
+TAG * InsertTag(TAG * after,U16 id);    // updates frames, if necessary
+int   DeleteTag(TAG * t);
+
+void  SetTagPos(TAG * t,U32 pos);       // resets Bitcount
+U32   GetTagPos(TAG * t);
+
+TAG * NextTag(TAG * t);
+TAG * PrevTag(TAG * t);
+
+int   GetFrameNo(TAG * t);              // should be renamed to TagGetFrame
+U16   GetTagID(TAG * t);                // ... TagGetID
+U32   GetDataSize(TAG * t);             // ... TagGetDataSize
+U8*   GetDataSizePtr(TAG * t);
+
+U32   GetBits(TAG * t,int nbits);
+S32   GetSBits(TAG * t,int nbits);
+int   SetBits(TAG * t,U32 v,int nbits);
+
+int   GetBlock(TAG * t,U8 * b,int l);   // resets Bitcount
+int   SetBlock(TAG * t,U8 * b,int l);
+
+U8    GetU8(TAG * t);                   // resets Bitcount
+U16   GetU16(TAG * t);
+U32   GetU32(TAG * t);
+
+int   SetU8(TAG * t,U8 v);              // resets Bitcount
+int   SetU16(TAG * t,U16 v);
+int   SetU32(TAG * t,U32 v);
+
+int   GetPoint(TAG * t,SPOINT * p);     // resets Bitcount
+int   GetRect(TAG * t,SRECT * r);
+int   GetMatrix(TAG * t,MATRIX * m);
+int   GetCXForm(TAG * t,CXFORM * cx,U8 alpha);
+
+int   SetPoint(TAG * t,SPOINT * p);     // resets Bitcount
+int   SetRect(TAG * t,SRECT * r);
+int   SetMatrix(TAG * t,MATRIX * m);
+int   SetCXForm(TAG * t,CXFORM * cx,U8 alpha);
+int   SetRGB(TAG * t,RGBA * col);
+int   SetRGBA(TAG * t,RGBA * col);
+
+// Function Macros
+
+#define GetS8(tag)      ((S8)GetU8(tag))
+#define GetS16(tag)     ((S16)GetU16(tag))
+#define GetS32(tag)     ((S32)GetU32(tag))
+#define GetCoord(tag)   ((SCOORD)GetU32(tag))
+#define GetFixed(tag)   ((SFIXED)GetU32(tag))
+
+#define SetS8(tag,v)    SetU8(tag,(U8)v)
+#define SetS16(tag,v)   SetU16(tag,(U16)v)
+#define SetS32(tag,v)   SetU32(tag,(U32)v)
+#define SetCoord(tag,v) SetU32(tag,(U32)v)
+#define SetFixed(tag,v) SetU32(tag,(U32)v)
+#define SetString(t,s)  SetBlock(t,s,strlen(s)+1)
+
+#define FAILED(b)       ((b)<0)
+#define SUCCEDED(b)     ((b)>=0)
+
+// Tag IDs (adopted from J. C. Kessels' Form2Flash)
+
+#define ST_END                  0
+#define ST_SHOWFRAME            1
+#define ST_DEFINESHAPE          2
+#define ST_FREECHARACTER        3
+#define ST_PLACEOBJECT          4
+#define ST_REMOVEOBJECT         5
+#define ST_DEFINEBITS           6
+#define ST_DEFINEBUTTON         7
+#define ST_JPEGTABLES           8
+#define ST_SETBACKGROUNDCOLOR   9
+#define ST_DEFINEFONT           10
+#define ST_DEFINETEXT           11
+#define ST_DOACTION             12
+#define ST_DEFINEFONTINFO       13
+#define ST_DEFINESOUND          14 /* Event sound tags. */
+#define ST_STARTSOUND           15
+#define ST_DEFINEBUTTONSOUND    17
+#define ST_SOUNDSTREAMHEAD      18
+#define ST_SOUNDSTREAMBLOCK     19
+#define ST_DEFINEBITSLOSSLESS   20 /* A bitmap using lossless zlib compression. */
+#define ST_DEFINEBITSJPEG2      21 /* A bitmap using an internal JPEG compression table. */
+#define ST_DEFINESHAPE2         22
+#define ST_DEFINEBUTTONCXFORM   23
+#define ST_PROTECT              24 /* This file should not be importable for editing. */
+#define ST_PLACEOBJECT2         26 /* The new style place w/ alpha color transform and name. */
+#define ST_REMOVEOBJECT2        28 /* A more compact remove object that omits the character tag (just depth). */
+#define ST_DEFINESHAPE3         32 /* A shape V3 includes alpha values. */
+#define ST_DEFINETEXT2          33 /* A text V2 includes alpha values. */
+#define ST_DEFINEBUTTON2        34 /* A button V2 includes color transform, alpha and multiple actions */
+#define ST_DEFINEBITSJPEG3      35 /* A JPEG bitmap with alpha info. */
+#define ST_DEFINEBITSLOSSLESS2  36 /* A lossless bitmap with alpha info. */
+#define ST_DEFINEEDITTEXT       37
+#define ST_DEFINEMOVIE          38
+#define ST_DEFINESPRITE         39 /* Define a sequence of tags that describe the behavior of a sprite. */
+#define ST_NAMECHARACTER        40 /* Name a character definition, character id and a string, (used for buttons, bitmaps, sprites and sounds). */
+#define ST_SERIALNUMBER         41
+#define ST_GENERATORTEXT        42 /* contains an id */
+#define ST_FRAMELABEL           43 /* A string label for the current frame. */
+#define ST_SOUNDSTREAMHEAD2     45 /* For lossless streaming sound, should not have needed this... */
+#define ST_DEFINEMORPHSHAPE     46 /* A morph shape definition */
+#define ST_DEFINEFONT2          48
+#define ST_TEMPLATECOMMAND      49
+#define ST_GENERATOR3           51
+#define ST_EXTERNALFONT         52
+
+#define ST_REFLEX              777 /* to identify generator software */
+
+// Advanced Funtions
+
+// swfdump.c
+
+void DumpHeader(FILE * f,SWF * swf);
+void DumpMatrix(FILE * f,MATRIX * m);
+void DumpTag(FILE * f,TAG * t); 
+char* getTagName(TAG*tag);
+
+// swfshape.c
+
+typedef struct _LINESTYLE
+{ U16           width;
+  RGBA          color;
+} LINESTYLE, * LPLINESTYLE;
+
+typedef struct _FILLSTYLE
+{ U8     type;
+  RGBA   color;
+  MATRIX         m; 
+  U16    id_bitmap;
+} FILLSTYLE, * LPFILLSTYLE;
+     
+typedef struct _SHAPE           // NEVER access a Shape-Struct directly !
+{                 
+  struct
+  { LINESTYLE * data;
+    U16         n;
+  } linestyle;
+                  // note: changes of shape structure
+  struct                  // lead to incompatible .efont formats
+  { FILLSTYLE * data;
+    U16         n;
+  } fillstyle;
+
+  S32           px;
+  S32           py;
+  
+  struct
+  { U16         fill;
+    U16         line;
+  } bits;
+  
+  U8 *          data;
+  U32           bitlen;         // length of data in bits
+} SHAPE, * LPSHAPE;
+
+// Shapes
+
+int   NewShape(SHAPE ** s);
+void  ShapeFree(SHAPE * s);
+
+int   GetSimpleShape(TAG * t,SHAPE ** s); // without Linestyle/Fillstyle Record
+int   SetSimpleShape(TAG * t,SHAPE * s);   // without Linestyle/Fillstyle Record
+
+int   ShapeAddLineStyle(SHAPE * s,U16 width,RGBA * color);
+int   ShapeAddSolidFillStyle(SHAPE * s,RGBA * color);
+int   ShapeAddBitmapFillStyle(SHAPE * s,MATRIX * m,U16 id_bitmap,int clip);
+
+int   SetShapeStyles(TAG * t,SHAPE * s);
+int   ShapeCountBits(SHAPE * s,U8 * fbits,U8 * lbits);
+int   SetShapeBits(TAG * t,SHAPE * s);
+int   SetShapeHeader(TAG * t,SHAPE * s); // one call for upper three functions
+
+int   ShapeSetMove(TAG * t,SHAPE * s,S32 x,S32 y);
+int   ShapeSetStyle(TAG * t,SHAPE * s,U16 line,U16 fill0,U16 fill1);
+int   ShapeSetAll(TAG * t,SHAPE * s,S32 x,S32 y,U16 line,U16 fill0,U16 fill1);
+
+int   ShapeSetLine(TAG * t,SHAPE * s,S32 x,S32 y);
+int   ShapeSetCurve(TAG * t,SHAPE * s,S32 x,S32 y,S32 ax,S32 ay);
+int   ShapeSetCircle(TAG * t,SHAPE * s,S32 x,S32 y,S32 rx,S32 ry);
+int   ShapeSetEnd(TAG * t);
+
+
+// swffont.c
+
+// does not support wide characters !
+
+#define MAX_CHAR_PER_FONT 256
+
+typedef struct _SWFLAYOUT
+{ S16         ascent;
+  S16         descent;
+  S16         leading;
+  SRECT       bounds[MAX_CHAR_PER_FONT];
+  struct
+  { U16       count;
+    U8 *      data;  // size = count*4 bytes
+  } kerning;
+} SWFLAYOUT, * LPSWFLAYOUT;
+
+typedef struct _SWFFONT
+{ U16           id;
+  U8 *          name;
+  SWFLAYOUT *   layout;
+
+  U8            flags; // bold/italic/unicode/ansi ...
+
+  U16           codes[MAX_CHAR_PER_FONT];
+  
+  struct
+  { U16         advance;
+    U16         gid;            // Glyph-ID after DefineFont
+    SHAPE *     shape;
+  }             glyph[MAX_CHAR_PER_FONT];
+} SWFFONT, * LPSWFFONT;
+
+typedef struct _FONTUSAGE
+{ U8 code[MAX_CHAR_PER_FONT];
+} FONTUSAGE, * LPFONTUSAGE;
+
+int FontEnumerate(SWF * swf,void (*FontCallback) (U16,U8*));
+// -> void fontcallback(U16 id,U8 * name); returns number of defined fonts
+
+int FontExtract(SWF * swf,int id,SWFFONT ** f);
+// Fetches all available information from DefineFont, DefineFontInfo, DefineText, ...
+// id = FontID, id=0 -> Extract first Font
+
+int FontIsItalic(SWFFONT * f);
+int FontIsBold(SWFFONT * f);
+
+int FontSetID(SWFFONT * f,U16 id);
+int FontReduce(SWFFONT * f,FONTUSAGE * use);
+
+int FontInitUsage(FONTUSAGE * use);
+int FontUse(FONTUSAGE * use,U8 * s);
+
+int FontSetDefine(TAG * t,SWFFONT * f);
+int FontSetInfo(TAG * t,SWFFONT * f);
+
+int FontExport(int handle,SWFFONT * f);
+int FontImport(int handle,SWFFONT * * f);
+
+void FontFree(SWFFONT * f);
+
+U32 TextGetWidth(SWFFONT * font,U8 * s,int scale);
+int TextCountBits(SWFFONT * font,U8 * s,int scale,U8 * gbits,U8 * abits);
+
+int TextSetInfoRecord(TAG * t,SWFFONT * font,U16 size,RGBA * color,S16 dx,S16 dy);
+int TextSetCharRecord(TAG * t,SWFFONT * font,U8 * s,int scale,U8 gbits,U8 abits);
+
+int TextPrintDefineText(TAG * t,SWFFONT * f);
+// Prints text defined in tag t with font f to stdout
+
+
+// swfobject.c
+
+// Always use ST_PLACEOBJECT2 !!!
+
+int ObjectPlace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,U8 * name);
+int PlaceObject(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,U8 * name, U16 clipaction);
+int ObjectMove(TAG * t,U16 depth,MATRIX * m,CXFORM * cx);
+
+// swfbutton.c
+
+// Button States
+
+#define BS_HIT          0x08
+#define BS_DOWN         0x04
+#define BS_OVER         0x02
+#define BS_UP           0x01
+
+// Button Conditions
+
+#define BC_OVERDOWN_IDLE        0x0100
+#define BC_IDLE_OVERDOWN        0x0080
+#define BC_OUTDOWN_IDLE         0x0040
+#define BC_OUTDOWN_OVERDOWN     0x0020
+#define BC_OVERDOWN_OUTDOWN     0x0010
+#define BC_OVERDOWN_OVERUP      0x0008
+#define BC_OVERUP_OVERDOWN      0x0004
+#define BC_OVERUP_IDLE          0x0002
+#define BC_IDLE_OVERUP          0x0001
+
+#define BC_KEY(c) (c<<9)
+
+#define BC_CURSORLEFT           0x0200
+#define BC_CURSORRIGHT          0x0400
+#define BC_POS1                 0x0600
+#define BC_END                  0x0800
+#define BC_INSERT               0x0a00
+#define BC_DELETE               0x0c00
+#define BC_BACKSPACE            0x1000
+#define BC_ENTER                0x1a00
+#define BC_CURSORUP             0x1c00
+#define BC_CURSORDOWN           0x1e00
+#define BC_PAGEUP               0x2000
+#define BC_PAGEDOWN             0x2200
+#define BC_TAB                  0x2400
+#define BC_SPACE                0x4000
+
+// Button Flag
+
+#define BF_TRACKMENU            0x01
+
+int ButtonSetRecord(TAG * t,U8 state,U16 id,U16 layer,MATRIX * m,CXFORM * cx);
+int ButtonSetCondition(TAG * t,U16 condition); // for DefineButton2
+int ButtonSetFlags(TAG * t,U8 flags);  // necessary for DefineButton2
+int ButtonPostProcess(TAG * t,int anz_action); // Set all offsets in DefineButton2-Tags (how many conditions to process)
+
+// swfbits.c
+
+typedef int JPEGBITS,* LPJPEGBITS; // cover libjpeg structures
+
+JPEGBITS * SetJPEGBitsStart(TAG * t,int width,int height,int quality);
+int SetJPEGBitsLines(JPEGBITS * jpegbits,U8 ** data,int n);
+int SetJPEGBitsLine(JPEGBITS * jpegbits,U8 * data);
+int SetJPEGBitsFinish(JPEGBITS * jpegbits);
+
+int SetJPEGBits(TAG * t,char * fname,int quality); // paste jpg file into swf stream
+
+// swftools.c
+
+char isDefiningTag(TAG * t);
+char isAllowedSpriteTag(TAG * t);
+U16 GetDefineID(TAG * t);
+U16 GetPlaceID(TAG * t); //PLACEOBJECT, PLACEOBJECT2 (sometimes), REMOVEOBJECT
+U16 GetDepth(TAG * t); //PLACEOBJECT,PLACEOBJECT2,REMOVEOBJECT,REMOVEOBJECT2
+char* GetName(TAG * t); //PLACEOBJECT2, FRAMELABEL
+MATRIX * MatrixJoin(MATRIX * d,MATRIX * s1,MATRIX * s2);
+MATRIX * MatrixMapTriangle(MATRIX * m,int dx,int dy,
+                    int x0,int y0,int x1,int y1,int x2,int y2);
+
+
+// swfcgi.c
+
+void uncgi();  // same behaviour as Steven Grimm's uncgi-library
+
+#endif