• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

swfから画像を抽出するコマンドラインアプリケーション


Commit MetaInfo

Revisióne934d6bc8216331c532b2f8681f92bd2d0c24fc5 (tree)
Tiempo2016-09-20 20:55:23
Autormasakih <masakih@user...>
Commitermasakih

Log Message

複数のswfファイルを処理出来るようにした

Cambiar Resumen

Diferencia incremental

--- a/KanColleGraphicDivider/main.m
+++ b/KanColleGraphicDivider/main.m
@@ -304,12 +304,125 @@ void storeBitsLossless2(const unsigned char *p, UInt32 length) {
304304 saveImageAsPNG(imageRef, charactorID);
305305 }
306306
307+void extractImagesFromSWFFile(const char *filename) {
308+
309+ NSString *filePath = [NSString stringWithFormat:@"%s", filename];
310+ if(![filePath hasPrefix:@"/"]) {
311+ NSFileManager *fm = [NSFileManager defaultManager];
312+ filePath = [fm.currentDirectoryPath stringByAppendingPathComponent:filePath];
313+ }
314+
315+ NSURL *url = [NSURL fileURLWithPath:filePath];
316+ NSData *data = [NSData dataWithContentsOfURL:url];
317+ if(!data) {
318+ fprintf(stderr, "Can not open %s.\n", filename);
319+ return;
320+ }
321+
322+ sOriginalName = [filePath lastPathComponent];
323+ sOriginalName = [sOriginalName stringByDeletingPathExtension];
324+
325+ printHex(data.bytes);
326+
327+ // ヘッダの処理開始
328+ const HMSWFHeader *header = data.bytes;
329+ printLog("type\t%c%c%c\n", header->type[0], header->type[1], header->type[2]);
330+ printLog("version\t%d\n", header->version);
331+ printLog("file size\t0x%x (%d)\n", header->f.f, header->f.f);
332+ data = [data subdataWithRange:NSMakeRange(8, data.length - 8)];
333+ printHex(data.bytes);
334+
335+ // シグニチャがCの時はコンテントはzlibで圧縮されている
336+ if(header->type[0] == 'C') {
337+ data = [data inflate];
338+ printHex(data.bytes);
339+ }
340+
341+ const unsigned char *p = data.bytes;
342+
343+ // RECT: 上位5bitsが各要素のサイズを表す 要素は4つ
344+ UInt8 size = *(UInt8 *)p;
345+ size >>= 3;
346+ printLog("size -> %u (%x)\n", size, size);
347+ int offset = size * 4;
348+ offset += 5; // 上位5bit分
349+ // bit -> byte
350+ int div = offset / 8;
351+ int mod = offset % 8;
352+ offset = div + (mod == 0 ? 0 : 1); // アライメント
353+ printLog("offset -> %d\n", offset);
354+ p += offset;
355+
356+ // fps: 8.8 fixed number.
357+ printLog("fps -> %u.%u\n", *(UInt8 *)(p + 1), *(UInt8 *)p);
358+ p += 2;
359+
360+ // frame count
361+ printLog("frame count -> %u\n", *(UInt16 *)p);
362+ p += 2;
363+
364+ // タグの処理開始
365+ int tagCount = 0;
366+ while(1) {
367+ printHex(p);
368+
369+ HMSWFTag *tagP = (HMSWFTag *)p;
370+ p += 2;
371+ printLog("tag and length -> 0x%04x\n", tagP->tagAndLength);
372+ UInt32 tag = tagP->tagAndLength >> 6;
373+ UInt32 length = tagP->tagAndLength & 0x3F;
374+ if(length == 0x3F) {
375+ length = tagP->extraLength;
376+ p += 4;
377+ }
378+ printLog("tag -> %u\nlength -> %u\n", tag, length);
379+
380+ // tag == 0 終了タグ
381+ if(tag == 0) break;
382+
383+ // 画像の時の処理
384+ switch(tag) {
385+ case tagBits:
386+ @autoreleasepool {
387+ storeImage(p + 2, length - 2, *(UInt16 *)p);
388+ }
389+ break;
390+ case tagBitsJPEG3:
391+ @autoreleasepool {
392+ storeBitsJPEG3(p, length);
393+ }
394+ break;
395+ case tagBitsLossless2:
396+ @autoreleasepool {
397+ storeBitsLossless2(p, length);
398+ }
399+ break;
400+ case tagBitsJPEG2:
401+ case tagBitsLossless:
402+ case tagBitsJPEG4:
403+ case tagJPEGTables:
404+ if(length > 0) {
405+ fprintf(stderr, "Not supported type. (tag=%d)\n", tag);
406+ }
407+ break;
408+ }
409+
410+ p += length;
411+ tagCount++;
412+
413+ if(tagCount > 200) {
414+ return;
415+ }
416+ }
417+
418+ printLog("tag Count -> %d\n", tagCount);
419+}
420+
307421 int main(int argc, char * const *argv) {
308422 @autoreleasepool {
309423
310424 // 引数の処理
311425 int opt;
312- char *filename = NULL;
313426 char *oFilename = NULL;
314427 char *charactorid = NULL;
315428
@@ -344,9 +457,7 @@ int main(int argc, char * const *argv) {
344457 }
345458 }
346459
347- if(optind < argc) {
348- filename = argv[optind];
349- } else {
460+ if(optind >= argc) {
350461 usage(EXIT_FAILURE, stderr);
351462 }
352463
@@ -374,118 +485,11 @@ int main(int argc, char * const *argv) {
374485 }
375486 }
376487
377- NSString *filePath = [NSString stringWithFormat:@"%s", filename];
378- if(![filePath hasPrefix:@"/"]) {
379- NSFileManager *fm = [NSFileManager defaultManager];
380- filePath = [fm.currentDirectoryPath stringByAppendingPathComponent:filePath];
381- }
382-
383- NSURL *url = [NSURL fileURLWithPath:filePath];
384- NSData *data = [NSData dataWithContentsOfURL:url];
385- if(!data) {
386- fprintf(stderr, "Can not open %s.\n", filename);
387- exit(EXIT_FAILURE);
388- }
389-
390- sOriginalName = [filePath lastPathComponent];
391- sOriginalName = [sOriginalName stringByDeletingPathExtension];
392-
393-
394- printHex(data.bytes);
395-
396- // ヘッダの処理開始
397- const HMSWFHeader *header = data.bytes;
398- printLog("type\t%c%c%c\n", header->type[0], header->type[1], header->type[2]);
399- printLog("version\t%d\n", header->version);
400- printLog("file size\t0x%x (%d)\n", header->f.f, header->f.f);
401- data = [data subdataWithRange:NSMakeRange(8, data.length - 8)];
402- printHex(data.bytes);
403-
404- // シグニチャがCの時はコンテントはzlibで圧縮されている
405- if(header->type[0] == 'C') {
406- data = [data inflate];
407- printHex(data.bytes);
408- }
409-
410- const unsigned char *p = data.bytes;
411-
412- // RECT: 上位5bitsが各要素のサイズを表す 要素は4つ
413- UInt8 size = *(UInt8 *)p;
414- size >>= 3;
415- printLog("size -> %u (%x)\n", size, size);
416- int offset = size * 4;
417- offset += 5; // 上位5bit分
418- // bit -> byte
419- int div = offset / 8;
420- int mod = offset % 8;
421- offset = div + (mod == 0 ? 0 : 1); // アライメント
422- printLog("offset -> %d\n", offset);
423- p += offset;
424-
425- // fps: 8.8 fixed number.
426- printLog("fps -> %u.%u\n", *(UInt8 *)(p + 1), *(UInt8 *)p);
427- p += 2;
428-
429- // frame count
430- printLog("frame count -> %u\n", *(UInt16 *)p);
431- p += 2;
432-
433- // タグの処理開始
434- int tagCount = 0;
435- while(1) {
436- printHex(p);
437-
438- HMSWFTag *tagP = (HMSWFTag *)p;
439- p += 2;
440- printLog("tag and length -> 0x%04x\n", tagP->tagAndLength);
441- UInt32 tag = tagP->tagAndLength >> 6;
442- UInt32 length = tagP->tagAndLength & 0x3F;
443- if(length == 0x3F) {
444- length = tagP->extraLength;
445- p += 4;
446- }
447- printLog("tag -> %u\nlength -> %u\n", tag, length);
448-
449- // tag == 0 終了タグ
450- if(tag == 0) break;
451-
452- // 画像の時の処理
453- switch(tag) {
454- case tagBits:
455- @autoreleasepool {
456- storeImage(p + 2, length - 2, *(UInt16 *)p);
457- }
458- break;
459- case tagBitsJPEG3:
460- @autoreleasepool {
461- storeBitsJPEG3(p, length);
462- }
463- break;
464- case tagBitsLossless2:
465- @autoreleasepool {
466- storeBitsLossless2(p, length);
467- }
468- break;
469- case tagBitsJPEG2:
470- case tagBitsLossless:
471- case tagBitsJPEG4:
472- case tagJPEGTables:
473- if(length > 0) {
474- fprintf(stderr, "Not supported type. (tag=%d)\n", tag);
475- }
476- break;
477- }
478-
479- p += length;
480- tagCount++;
488+ for(int filePos = optind; filePos < argc; filePos++) {
489+ const char *filename = argv[filePos];
481490
482- if(tagCount > 200) {
483- exit(-1);
484- }
491+ extractImagesFromSWFFile(filename);
485492 }
486-
487- printLog("tag Count -> %d\n", tagCount);
488-
489493 }
490494 return 0;
491495 }