X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fswfextract.c;h=fa612fc70fe864616264bb9495bd2b73032f6390;hb=0c3006e417a705dcacc7dad7083de0e4adb41971;hp=50a4f7525808d69cefc030d52a559fc960a496bf;hpb=f02782b303696f722003f59d5ec537b4aec77957;p=swftools.git diff --git a/src/swfextract.c b/src/swfextract.c index 50a4f75..fa612fc 100644 --- a/src/swfextract.c +++ b/src/swfextract.c @@ -22,17 +22,20 @@ char * filename = 0; char * destfilename = "output.swf"; -int verbose = 2; +int verbose = 3; char* extractids = 0; char* extractframes = 0; char* extractjpegids = 0; char* extractpngids = 0; +char extractmp3 = 0; char* extractname = 0; char hollow = 0; +int numextracts = 0; + struct options_t options[] = { {"o","output"}, @@ -47,6 +50,7 @@ struct options_t options[] = {0,0} }; + int args_callback_option(char*name,char*val) { if(!strcmp(name, "V")) { @@ -59,6 +63,7 @@ int args_callback_option(char*name,char*val) } else if(!strcmp(name, "i")) { extractids = val; + numextracts++; if(extractname) { fprintf(stderr, "You can only supply either name or id\n"); exit(1); @@ -67,6 +72,7 @@ int args_callback_option(char*name,char*val) } else if(!strcmp(name, "n")) { extractname = val; + numextracts++; if(extractids) { fprintf(stderr, "You can only supply either name or id\n"); exit(1); @@ -77,11 +83,17 @@ int args_callback_option(char*name,char*val) verbose ++; return 0; } + else if(!strcmp(name, "m")) { + extractmp3 = 1; + numextracts++; + return 0; + } else if(!strcmp(name, "j")) { if(extractjpegids) { fprintf(stderr, "Only one --jpegs argument is allowed. (Try to use a range, e.g. -j 1,2,3)\n"); exit(1); } + numextracts++; extractjpegids = val; return 1; } @@ -91,11 +103,13 @@ int args_callback_option(char*name,char*val) fprintf(stderr, "Only one --pngs argument is allowed. (Try to use a range, e.g. -p 1,2,3)\n"); exit(1); } + numextracts++; extractpngids = val; return 1; } #endif else if(!strcmp(name, "f")) { + numextracts++; extractframes = val; return 1; } @@ -125,6 +139,7 @@ void args_callback_usage(char*name) #ifdef _ZLIB_INCLUDED_ printf("\t-p , --pngs IDs\t\t\t IDs of the PNG pictures to extract\n"); #endif + printf("\t-m , --mp3\t\t\t Extract main mp3 stream\n"); printf("\t-f , --frame frames\t\t frame numbers to extract\n"); printf("\t-w , --hollow\t\t\t hollow mode: don't remove empty frames (use with -f)\n"); printf("\t-V , --version\t\t\t Print program version and exit\n"); @@ -152,9 +167,9 @@ char * tagused; void idcallback(void*data) { - if(!(used[*(U16*)data]&1)) { + if(!(used[GET16(data)]&1)) { changed = 1; - used[*(U16*)data] |= 1; + used[GET16(data)] |= 1; } } @@ -165,13 +180,16 @@ void enumerateIDs(TAG*tag, void(*callback)(void*)) if(tag->len>=64) { len += 6; data = (U8*)malloc(len); - *(U16*)data = (tag->id<<6)+63; - *(U32*)&data[2] = tag->len; + PUT16(data, (tag->id<<6)+63); + *(U8*)&data[2] = tag->len; + *(U8*)&data[3] = tag->len>>8; + *(U8*)&data[4] = tag->len>>16; + *(U8*)&data[5] = tag->len>>24; memcpy(&data[6], tag->data, tag->len); } else { len += 2; data = (U8*)malloc(len); - *(U16*)data = (tag->id<<6)+tag->len; + PUT16(data, (tag->id<<6)+tag->len); memcpy(&data[2], tag->data, tag->len); } map_ids_mem(data, len, callback); @@ -392,7 +410,7 @@ void handlejpeg(TAG*tag) { char name[80]; FILE*fi; - sprintf(name, "pic%d.jpeg", *(U16*)tag->data); + sprintf(name, "pic%d.jpeg", GET16(tag->data)); /* swf jpeg images have two streams, which both start with ff d8 and end with ff d9. The following code handles sorting the middle bytes out, so that one stream remains */ @@ -414,7 +432,7 @@ void handlejpeg(TAG*tag) fclose(fi); } if(tag->id == ST_DEFINEBITSJPEG3 && tag->len>6) { - U32 end = *(U32*)&tag->data[2]+6; + U32 end = GET32(&tag->data[2])+6; int pos = findjpegboundary(&tag->data[6], tag->len-6); if(pos<0) return; @@ -645,6 +663,39 @@ void handlelossless(TAG*tag) } #endif +FILE*mp3file; +void handlesoundstream(TAG*tag) +{ + char*filename = "output.mp3"; + if(numextracts==1) { + filename = destfilename; + if(!strcmp(filename,"output.swf")) + filename = "output.mp3"; + } + switch(tag->id) { + case ST_SOUNDSTREAMHEAD: + if((tag->data[1]&0x30) == 0x20) { //mp3 compression + mp3file = fopen(filename, "wb"); + logf(" Writing mp3 data to %s",filename); + } + else + logf(" Soundstream is not mp3"); + break; + case ST_SOUNDSTREAMHEAD2: + if((tag->data[1]&0x30) == 0x20) {//mp3 compression + mp3file = fopen("mainstream.mp3", "wb"); + logf(" Writing mp3 data to %s",filename); + } + else + logf(" Soundstream is not mp3 (2)"); + break; + case ST_SOUNDSTREAMBLOCK: + if(mp3file) + fwrite(&tag->data[4],tag->len-4,1,mp3file); + break; + } +} + int main (int argc,char ** argv) { TAG*tag; @@ -657,7 +708,8 @@ int main (int argc,char ** argv) char listavailable = 0; processargs(argc, argv); - if(!extractframes && !extractids && ! extractname && !extractjpegids && !extractpngids) + if(!extractframes && !extractids && ! extractname && !extractjpegids && !extractpngids + && !extractmp3) listavailable = 1; if(!filename) @@ -730,6 +782,12 @@ int main (int argc,char ** argv) } } + if(tag->id == ST_SOUNDSTREAMHEAD || + tag->id == ST_SOUNDSTREAMHEAD2 || + tag->id == ST_SOUNDSTREAMBLOCK) { + handlesoundstream(tag); + } + if(tag->id == ST_JPEGTABLES) handlejpegtables(tag); @@ -784,6 +842,9 @@ int main (int argc,char ** argv) if (found) extractTag(&swf, destfilename); + if(mp3file) + fclose(mp3file); + swf_FreeTags(&swf); return 0; }