Skip to content

Commit

Permalink
Add the actual files
Browse files Browse the repository at this point in the history
  • Loading branch information
boiled-sugar committed Jul 8, 2012
1 parent 17b5669 commit f4bc19d
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@
*.lai
*.la
*.a

#AviUtl Plugins
*.auf
*.aui
*.auo
4 changes: 0 additions & 4 deletions README.md

This file was deleted.

74 changes: 74 additions & 0 deletions animationgif.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//----------------------------------------------------------------------------------
// アニメーションGIF出力プラグイン
//----------------------------------------------------------------------------------
#include <windows.h>
#include <wand/MagickWand.h>

#include "output.h"


//---------------------------------------------------------------------
// 出力プラグイン構造体定義
//---------------------------------------------------------------------
OUTPUT_PLUGIN_TABLE output_plugin_table = {
0, // フラグ NULLだと警告
"アニメーションGIF出力", // プラグインの名前
"GIF File (*.gif)\0*.gif\0AllFile (*.*)\0*.*\0", // 出力ファイルのフィルタ
"アニメーションGIF出力プラグイン ver.0.0.1", // プラグインの情報
NULL, // DLL開始時に呼ばれる関数へのポインタ (NULLなら呼ばれません)
NULL, // DLL終了時に呼ばれる関数へのポインタ (NULLなら呼ばれません)
func_output, // 出力時に呼ばれる関数へのポインタ
NULL, // 出力設定のダイアログを要求された時に呼ばれる関数へのポインタ (NULLなら呼ばれません)
NULL, // 出力設定データを取得する時に呼ばれる関数へのポインタ (NULLなら呼ばれません)
NULL , // 出力設定データを設定する時に呼ばれる関数へのポインタ (NULLなら呼ばれません)
};


//---------------------------------------------------------------------
// 出力プラグイン構造体のポインタを渡す関数
//---------------------------------------------------------------------
EXTERN_C OUTPUT_PLUGIN_TABLE __declspec(dllexport) * __stdcall GetOutputPluginTable( void )
{
return &output_plugin_table;
}


//---------------------------------------------------------------------
// 出力プラグイン処理本体
//---------------------------------------------------------------------
BOOL func_output( OUTPUT_INFO *oip )
{
const int mabiki = 1; //2にすると2フレーム中1フレームの間引き

if( oip->n > 400 / mabiki )
if( MessageBox( NULL, (LPCSTR) "大量のフレームが選択されています。\n本当に続行しますか?", (LPCSTR) "アニメーションGIF出力プラグイン", MB_YESNO | MB_ICONQUESTION )
== IDNO )
return FALSE;

const int delay = mabiki * 100 * oip->scale / oip->rate; //間引き×100÷フレームレート
MagickWandGenesis();
MagickWand *dest = NewMagickWand();

for( int i = 0; i < oip->n; i = i + mabiki )
{
if( oip->func_is_abort() )
break;
oip->func_rest_time_disp( i, oip->n );
MagickWand *source = NewMagickWand();
if( !MagickConstituteImage( source, oip->w, oip->h, "BGR", CharPixel, oip->func_get_video_ex( i, 0 ) ) ) //NULLだと警告
MessageBox( NULL, (LPCSTR) "データ取得失敗", (LPCSTR) "アニメーションGIF出力プラグイン", MB_OK|MB_ICONSTOP );
MagickFlipImage( source ); //AviUtlからはボトムアップで渡されるが、MagickConstituteImageはトップダウン固定
MagickSetImageDelay( source, delay );
MagickAddImage( dest, source );
DestroyMagickWand( source );
oip->func_update_preview();
}
if( !MagickSetFormat( dest, "GIF" ) || !MagickSetImageType( dest, PaletteType ) )
MessageBox( NULL, (LPCSTR) "GIFセット失敗", (LPCSTR) "アニメーションGIF出力プラグイン", MB_OK|MB_ICONSTOP );
if( !MagickWriteImages( MagickCoalesceImages( dest ), oip->savefile, MagickTrue ) )
MessageBox( NULL, (LPCSTR) "出力失敗", (LPCSTR) "アニメーションGIF出力プラグイン", MB_OK|MB_ICONSTOP );

DestroyMagickWand( dest );
MagickWandTerminus();
return TRUE;
}
5 changes: 5 additions & 0 deletions animationgif.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
LIBRARY animationgif.auo

EXPORTS
GetOutputPluginTable @1

20 changes: 20 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CC = gcc
CFLAG = -c -O3 -std=c99 -Wall -I/usr/local/include/ImageMagick
LINK = gcc
LFLAG = --shared -L/usr/local/lib -Wl,--enable-stdcall-fixup,--dll -s

TARGET = animationgif.auo
OBJ1 = animationgif.o
DEF = animationgif.def

all: $(TARGET)

$(TARGET): $(OBJ1) $(DEF)
$(LINK) $(LFLAG) -o $(TARGET) $(OBJ1) -lMagickWand -lMagickCore -lz -lgdi32 $(DEF)
#-lMagickCore -lbz2 -lz -lgdi32 -lm -lgomp -lpthread
$(OBJ1): animationgif.c
$(CC) $(CFLAG) animationgif.c

clean:
rm -f *.o
rm -f *.auo
99 changes: 99 additions & 0 deletions output.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//----------------------------------------------------------------------------------
// 出力プラグイン ヘッダーファイル for AviUtl version 0.99g4 以降
// By KENくん
//----------------------------------------------------------------------------------

// 出力情報構造体
typedef struct {
int flag; // フラグ
// OUTPUT_INFO_FLAG_VIDEO : 画像データあり
// OUTPUT_INFO_FLAG_AUDIO : 音声データあり
// OUTPUT_INFO_FLAG_BATCH : バッチ出力中
int w,h; // 縦横サイズ
int rate,scale; // フレームレート
int n; // フレーム数
int size; // 1フレームのバイト数
int audio_rate; // 音声サンプリングレート
int audio_ch; // 音声チャンネル数
int audio_n; // 音声サンプリング数
int audio_size; // 音声1サンプルのバイト数
LPSTR savefile; // セーブファイル名へのポインタ
void *(*func_get_video)( int frame );
// DIB形式(RGB24bit)の画像データへのポインタを取得します。
// frame : フレーム番号
// 戻り値 : データへのポインタ
// 画像データポインタの内容は次に外部関数を使うかメインに処理を戻すまで有効
void *(*func_get_audio)( int start,int length,int *readed );
// 16bitPCM形式の音声データへのポインタを取得します。
// start : 開始サンプル番号
// length : 読み込むサンプル数
// readed : 読み込まれたサンプル数
// 戻り値 : データへのポインタ
// 音声データポインタの内容は次に外部関数を使うかメインに処理を戻すまで有効
BOOL (*func_is_abort)( void );
// 中断するか調べます。
// 戻り値 : TRUEなら中断
BOOL (*func_rest_time_disp)( int now,int total );
// 残り時間を表示させます。
// now : 処理しているフレーム番号
// total : 処理する総フレーム数
// 戻り値 : TRUEなら成功
int (*func_get_flag)( int frame );
// フラグを取得します。
// frame : フレーム番号
// 戻り値 : フラグ
// OUTPUT_INFO_FRAME_FLAG_KEYFRAME : キーフレーム推奨
// OUTPUT_INFO_FRAME_FLAG_COPYFRAME : コピーフレーム推奨
BOOL (*func_update_preview)( void );
// プレビュー画面を更新します。
// 最後にfunc_get_videoで読み込まれたフレームが表示されます。
// 戻り値 : TRUEなら成功
void *(*func_get_video_ex)( int frame,DWORD format );
// DIB形式の画像データを取得します。
// frame : フレーム番号
// format : 画像フォーマット( NULL = RGB24bit / 'Y''U''Y''2' = YUY2 / 'Y''C''4''8' = PIXEL_YC )
// ※PIXEL_YC形式 は YUY2フィルタモードでは使用出来ません。
// 戻り値 : データへのポインタ
// 画像データポインタの内容は次に外部関数を使うかメインに処理を戻すまで有効
} OUTPUT_INFO;
#define OUTPUT_INFO_FLAG_VIDEO 1
#define OUTPUT_INFO_FLAG_AUDIO 2
#define OUTPUT_INFO_FLAG_BATCH 4
#define OUTPUT_INFO_FRAME_FLAG_KEYFRAME 1
#define OUTPUT_INFO_FRAME_FLAG_COPYFRAME 2

// 出力プラグイン構造体
typedef struct {
int flag; // フラグ
LPSTR name; // プラグインの名前
LPSTR filefilter; // ファイルのフィルタ
LPSTR information; // プラグインの情報
BOOL (*func_init)( void );
// DLL開始時に呼ばれる関数へのポインタ (NULLなら呼ばれません)
BOOL (*func_exit)( void );
// DLL終了時に呼ばれる関数へのポインタ (NULLなら呼ばれません)
BOOL (*func_output)( OUTPUT_INFO *oip );
// 出力時に呼ばれる関数へのポインタ
BOOL (*func_config)( HWND hwnd,HINSTANCE dll_hinst );
// 出力設定のダイアログを要求された時に呼ばれる関数へのポインタ (NULLなら呼ばれません)
int (*func_config_get)( void *data,int size );
// 出力設定データを取得する時に呼ばれる関数へのポインタ (NULLなら呼ばれません)
// data : 設定データを書き込むバッファへのポインタ (NULLなら設定データサイズを返すだけ)
// size : 設定データを書き込むバッファのサイズ
// 戻り値 : 設定データのサイズ
int (*func_config_set)( void *data,int size );
// 出力設定データを設定する時に呼ばれる関数へのポインタ (NULLなら呼ばれません)
// data : 設定データへのポインタ
// size : 設定データのサイズ
// 戻り値 : 使用した設定データのサイズ
int reserve[16]; // 拡張用に予約されてます
} OUTPUT_PLUGIN_TABLE;

BOOL func_init( void );
BOOL func_exit( void );
BOOL func_output( OUTPUT_INFO *oip );
BOOL func_config( HWND hwnd,HINSTANCE hinst );
int func_config_get( void *data,int size );
int func_config_set( void *data,int size );


55 changes: 55 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
-----------------------------------------------------------------------
アニメーションGIF出力プラグイン v0.01
-----------------------------------------------------------------------

Copyright (c) 2012 Hiroki Taniura (boiled.sugar at gmail dot com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


【これは何?】
AviUtlから直接アニメーションGIFを出力するプラグインがなかったので作ってみました。
画像処理はImageMagickを使用しています。
ランタイム等は特に必要無いはずです。

【使用方法】
出力範囲を選択し、プラグイン出力→アニメーションGIF出力
表示タイミングはAviUtlのフレームレートをそのまま使いますが、
1/100秒単位のため、多少の誤差が出ます。
例えば24fpsのアニメを出力すると、4/100秒で画像が切り替わることになるので、25fpsとなります。
AviUtlが応答なしになっても多分処理中なので強制終了しないでください。

【注意事項】
短い範囲を選択して使用することをお勧めします。
試しに640x360を2209フレーム出力してみたのですが、AviUtlが1.7GBほどメモリを消費し、
TEMPに大量のファイルが作成され、4GBのRAMDISKを埋め尽くしてエラーで止まりました。
40フレームだとメモリ消費量は300MBほどで、一時ファイルも作成されません。
色々試した結果、約1.7GBがメモリ消費量の上限でそれを超えると一時ファイルが作成されるようです。
400フレームだとメモリ消費量は1.3GB程で、500フレームだとメモリ消費量が上限に達し、
TEMPの消費は400MBほどでした。
そこで選択範囲が400フレームより多い場合に本当に続行するか尋ねるようにしましたが、
画像サイズも影響するので十分に注意してください。
一時ファイルができてしまった場合、削除は手動で行わなければならないようです。
手動で%TEMP%\magick*を削除してください。

【ライセンス】
MIT Licenseです。

【レポジトリ】
https://github.com/boiled-sugar/Animated-GIF-output-plugin/

0 comments on commit f4bc19d

Please sign in to comment.