added rfx_realloc().
[swftools.git] / lib / rfxswf.c
index 441e19d..3ee5c6e 100644 (file)
 #include "./bitio.h"
 #include "./MD5.h"
 
+// memory allocation
+
+void* rfx_alloc(int size)
+{
+  void*ptr;
+  if(size == 0) {
+    *(int*)0 = 0xdead;
+    fprintf(stderr, "Warning: Zero alloc\n");
+    return 0;
+  }
+
+  ptr = malloc(size);
+  if(!ptr) {
+    fprintf(stderr, "FATAL: Out of memory\n");
+    /* TODO: we should send a signal, so that the debugger kicks in */
+    exit(1);
+  }
+  return ptr;
+}
+void* rfx_realloc(void*data, int size)
+{
+  void*ptr;
+  if(size == 0) {
+    *(int*)0 = 0xdead;
+    fprintf(stderr, "Warning: Zero realloc\n");
+    rfx_free(data);
+    return 0;
+  }
+  if(!data) {
+    ptr = malloc(size);
+  } else {
+    ptr = realloc(data, size);
+  }
+
+  if(!ptr) {
+    fprintf(stderr, "FATAL: Out of memory\n");
+    /* TODO: we should send a signal, so that the debugger kicks in */
+    exit(1);
+  }
+  return ptr;
+}
+void* rfx_calloc(int size)
+{
+  void*ptr;
+  if(size == 0) {
+    *(int*)0 = 0xdead;
+    fprintf(stderr, "Warning: Zero alloc\n");
+    return 0;
+  }
+#ifdef HAVE_CALLOC
+  ptr = calloc(size);
+#else
+  ptr = malloc(size);
+#endif
+  if(!ptr) {
+    fprintf(stderr, "FATAL: Out of memory\n");
+    /* TODO: we should send a signal, so that the debugger kicks in */
+    exit(1);
+  }
+#ifndef HAVE_CALLOC
+  memset(ptr, 0, size);
+#endif
+  return ptr;
+}
+
+void rfx_free(void*ptr)
+{
+  if(!ptr)
+    return;
+  free(ptr);
+}
+
 // internal constants
 
 #define MALLOC_SIZE     128
 
 #define MEMSIZE(l) (((l/MALLOC_SIZE)+1)*MALLOC_SIZE)
 
-
 // inline wrapper functions
 
 TAG * swf_NextTag(TAG * t) { return t->next; }
@@ -65,11 +136,6 @@ U32   swf_GetTagLen(TAG * t) { return t->len; }
 U8*   swf_GetTagLenPtr(TAG * t) { return &(t->data[t->len]); }
 U32   swf_GetTagPos(TAG * t)   { return t->pos; }
 
-// Basic Data Access Functions
-
-#define swf_ResetReadBits(tag)   if (tag->readBit)  { tag->pos++; tag->readBit = 0; }
-#define swf_ResetWriteBits(tag)  if (tag->writeBit) { tag->writeBit = 0; }
-
 // for future purpose: avoid high level lib functions to change tagpos/bitpos
 
 #define swf_SaveTagPos(tag)
@@ -184,6 +250,13 @@ int swf_SetU16(TAG * t,U16 v)
   t->data[t->len++] = a[1];
   return 0;
 }
+void swf_SetS16(TAG * t,int v)
+{
+    if(v>32767 || v<-32768) {
+       fprintf(stderr, "Warning: S16 overflow: %d\n", v);
+    }
+    swf_SetU16(t, (S16)v);
+}
 
 int swf_SetU32(TAG * t,U32 v)
 { U8 a[4];
@@ -422,6 +495,14 @@ int swf_SetRect(TAG * t,SRECT * r)
 
 void swf_ExpandRect(SRECT*src, SPOINT add)
 {
+    if((src->xmin | src->ymin | src->xmax | src->ymax)==0) {
+       src->xmin = add.x;
+       src->ymin = add.y;
+       src->xmax = add.x;
+       src->ymax = add.y;
+       if((add.x|add.y) == 0) src->xmax++; //make sure the bbox is not NULL anymore
+       return;
+    }
     if(add.x < src->xmin)
        src->xmin = add.x;
     if(add.x > src->xmax)
@@ -446,6 +527,25 @@ void swf_ExpandRect2(SRECT*src, SRECT*add)
     if(add->ymax > src->ymax)
        src->ymax = add->ymax;
 }
+void swf_ExpandRect3(SRECT*src, SPOINT center, int radius)
+{
+    if((src->xmin | src->ymin | src->xmax | src->ymax)==0) {
+       src->xmin = center.x-radius;
+       src->ymin = center.y-radius;
+       src->xmax = center.x+radius;
+       src->ymax = center.y+radius;
+       if((center.x|center.y|radius) == 0) src->xmax++; //make sure the bbox is not NULL anymore
+       return;
+    }
+    if(center.x - radius < src->xmin)
+       src->xmin = center.x - radius;
+    if(center.x + radius > src->xmax)
+       src->xmax = center.x - radius;
+    if(center.y - radius < src->ymin)
+       src->ymin = center.y - radius;
+    if(center.y + radius > src->ymax)
+       src->ymax = center.y - radius;
+}
 SPOINT swf_TurnPoint(SPOINT p, MATRIX* m)
 {
     SPOINT r;
@@ -783,6 +883,13 @@ void swf_ResetTag(TAG*tag, U16 id)
     tag->id = id;
 }
 
+TAG* swf_CopyTag(TAG*tag, TAG*to_copy)
+{
+    tag = swf_InsertTag(tag, to_copy->id);
+    swf_SetBlock(tag, to_copy->data, to_copy->len);
+    return tag;
+}
+
 int swf_DeleteTag(TAG * t)
 { if (!t) return -1;
 
@@ -865,7 +972,7 @@ int swf_WriteTag2(struct writer_t*writer, TAG * t)
 
   len = (t->id==ST_DEFINESPRITE)?swf_DefineSprite_GetRealSize(t):t->len;
 
-  short_tag = len<0x3f;
+  short_tag = len<0x3f&&(t->id!=ST_DEFINEBITSLOSSLESS&&t->id!=ST_DEFINEBITSLOSSLESS2);
 
   if (writer)
   { if (short_tag)
@@ -1042,7 +1149,7 @@ void swf_FoldSprite(TAG * t)
 
   do
   { 
-    if(t->len<0x3f) {
+    if(t->len<0x3f&&t->id!=ST_DEFINEBITSLOSSLESS&&t->id!=ST_DEFINEBITSLOSSLESS2) {
        swf_SetU16(sprtag,t->len|(t->id<<6));
     } else {
        swf_SetU16(sprtag,0x3f|(t->id<<6));
@@ -1232,7 +1339,7 @@ int  swf_WriteSWF2(struct writer_t*writer, SWF * swf)     // Writes SWF to file,
 
   while(t) {
       len += swf_WriteTag(-1,t);
-      if(t->id == ST_DEFINESPRITE) inSprite++;
+      if(t->id == ST_DEFINESPRITE && !swf_IsFolded(t)) inSprite++;
       else if(t->id == ST_END && inSprite) inSprite--;
       else if(t->id == ST_SHOWFRAME && !inSprite) frameCount++;
       t = swf_NextTag(t);