/*--------------------------------------------------------------------------------* * Reads SWF to memory *--------------------------------------------------------------------------------*/ int swf_ReadSWF2(reader_t* reader, SWF* swf) { char b[32]; int len; int tc; /* tag counter */ TAG* t; TAG t1; reader_t zreader; if(NULL == swf) return -1; memset(swf, 0x00, sizeof(SWF)); len = reader->read(reader, b, 8); if(len < 8) return -1; if(b[0] != 'F' && b[0] != 'C') return -1; if(b[1] != 'W') return -1; if(b[2] != 'S') return -1; swf->fileVersion = b[3]; swf->compressed = (b[0]=='C') ? 1 : 0; swf->fileSize = GET32(&b[4]); if(swf->compressed) { /* at first, we do not care about SWC */ return -1; } swf->compressed = 0; reader_GetRect(reader, &swf->movieSize); reader->read(reader, &swf->frameRate, 2); swf->frameRate = LE_16_TO_NATIVE(swf->frameRate); reader->read(reader, &swf->frameCount, 2); swf->frameCount = LE_16_TO_NATIVE(swf->frameCount); /* read tags and connect to list */ t1.next = 0; t = &t1; tc = 0; while (t) { t = swf_ReadTag(reader, t); if(NULL == t) break; tc++; if(t->id == ST_FILEATTRIBUTES) { swf->fileAttributes = swf_GetU32(t); swf_ResetReadBits(t); } } /* printf("swf->frameCount:%d <--> tag count:%d\n", swf->frameCount, tc); */ swf->firstTag = t1.next; if(t1.next) t1.next->prev = NULL; return reader->pos; }
ActionTAG* action_WaitForFrame(ActionTAG*atag, U16 frame, U8 skip) { atag = swf_AddActionTAG(atag, ACTION_WAITFORFRAME, 0, 3); *(U16*)atag->tmp = LE_16_TO_NATIVE(frame); *(U8*)&atag->tmp[2] = skip; return atag; }
TAG* swf_ReadTag(reader_t* reader, TAG* prev) { TAG* t = NULL; U16 raw; U32 len; int id; if(reader->read(reader, &raw, 2) != 2) return NULL; raw = LE_16_TO_NATIVE(raw); len = raw & 0x3F; /*U16, 10 bits ~ tag type, 6 bits ~ tag len */ id = raw >> 6; if(0x3F == len) /* it is a long tag header behind */ { len = reader_readU32(reader); } if(ST_DEFINESPRITE == id) len = 2 * sizeof(U16); t = (TAG*)rfx_calloc(sizeof(TAG)); if(NULL == t) return NULL; t->len = len; t->id = id; if(t->len) { t->data = (U8*)rfx_calloc(t->len); if(NULL == t->data) { free(t); return NULL; } t->memsize = t->len; if(reader->read(reader, t->data, t->len) != t->len) { free(t->data); t->data = 0; free(t); return NULL; } } if(prev) { t->prev = prev; prev->next = t; } return t; }
void action_fixjump(ActionMarker m1, ActionMarker m2) { ActionTAG* a1 = m1.atag; ActionTAG* a2 = m2.atag; ActionTAG* a; int len = 0; int oplen = 0; a = a1; a = a->next; //first one is free while(a && a!=a2) { len += ActionTagSize(a); oplen ++; a = a->next; } if(!a) { len = 0; oplen = 0; a = a2; while(a && a!=a1) { len -= ActionTagSize(a); oplen --; a = a->next; } if(!a) { fprintf(stderr, "action_fixjump: couldn't find second tag\n"); return; } len -= ActionTagSize(a); oplen --; } if (a1->op == ACTION_IF || a1->op == ACTION_JUMP) { *(U16*)(a1->data) = LE_16_TO_NATIVE(len); } else if(a1->op == ACTION_WAITFORFRAME) { ((U8*)(a1->data))[2] = oplen; } else if(a1->op == ACTION_WAITFORFRAME2) { ((U8*)(a1->data))[0] = oplen; } }
ActionTAG* action_If(ActionTAG*atag, U16 branch) { atag = swf_AddActionTAG(atag, ACTION_IF, 0, 2); *(U16*)atag->tmp = LE_16_TO_NATIVE(branch); return atag; }
ActionTAG* action_GotoFrame(ActionTAG*atag, U16 frame) { atag = swf_AddActionTAG(atag, ACTION_GOTOFRAME, 0, 2); *(U16*)atag->tmp = LE_16_TO_NATIVE(frame); return atag; }