#include <fcntl.h>
#include "../lib/rfxswf.h"
#include "../lib/args.h"
-#include "reloc.h"
+#include "../lib/log.h"
#ifdef HAVE_ZLIB_H
#ifdef HAVE_LIBZ
#include "zlib.h"
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"},
{"i","id"},
{"j","jpegs"},
{"p","pngs"},
+ {"m","mp3"},
{"n","name"},
{"f","frame"},
{"V","version"},
{0,0}
};
+
int args_callback_option(char*name,char*val)
{
if(!strcmp(name, "V")) {
}
else if(!strcmp(name, "i")) {
extractids = val;
+ numextracts++;
if(extractname) {
fprintf(stderr, "You can only supply either name or id\n");
exit(1);
}
else if(!strcmp(name, "n")) {
extractname = val;
+ numextracts++;
if(extractids) {
fprintf(stderr, "You can only supply either name or id\n");
exit(1);
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;
}
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;
}
#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-w , --hollow\t\t\t hollow mode: don't remove empty frames\n");
+ printf("\t \t\t\t (use with -f)\n");
printf("\t-V , --version\t\t\t Print program version and exit\n");
}
int args_callback_command(char*name,char*val)
void idcallback(void*data)
{
- if(!(used[*(U16*)data]&1)) {
+ if(!(used[GET16(data)]&1)) {
changed = 1;
- used[*(U16*)data] |= 1;
+ used[GET16(data)] |= 1;
}
}
void enumerateIDs(TAG*tag, void(*callback)(void*))
{
- U8*data;
+/* U8*data;
int len = tag->len;
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);
+ */
+ int num = swf_GetNumUsedIDs(tag);
+ int *ptr = malloc(sizeof(int)*num);
+ int t;
+ swf_GetUsedIDs(tag, ptr);
+ for(t=0;t<num;t++)
+ callback(&tag->data[ptr[t]]);
}
void extractTag(SWF*swf, char*filename)
{
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
<ff d9 ff d8> bytes out, so that one stream remains */
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;
}
#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("<notice> Writing mp3 data to %s",filename);
+ }
+ else
+ logf("<error> Soundstream is not mp3");
+ break;
+ case ST_SOUNDSTREAMHEAD2:
+ if((tag->data[1]&0x30) == 0x20) {//mp3 compression
+ mp3file = fopen("mainstream.mp3", "wb");
+ logf("<notice> Writing mp3 data to %s",filename);
+ }
+ else
+ logf("<error> 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;
char listavailable = 0;
processargs(argc, argv);
- if(!extractframes && !extractids && ! extractname && !extractjpegids && !extractpngids)
+ if(!extractframes && !extractids && ! extractname && !extractjpegids && !extractpngids
+ && !extractmp3)
listavailable = 1;
if(!filename)
}
}
+ if(tag->id == ST_SOUNDSTREAMHEAD ||
+ tag->id == ST_SOUNDSTREAMHEAD2 ||
+ tag->id == ST_SOUNDSTREAMBLOCK) {
+ handlesoundstream(tag);
+ }
+
if(tag->id == ST_JPEGTABLES)
handlejpegtables(tag);
if (found)
extractTag(&swf, destfilename);
+ if(mp3file)
+ fclose(mp3file);
+
swf_FreeTags(&swf);
return 0;
}