Win時代はやろうやろうと思ってついにやらなかったのだけれど
unix系の場合は随分と使いやすい様だ。cだとwinでもあるみたいだけど
pipeより使いやすいpopenを使ってみた。
これはいわばperlでいうところのsystem命令か
「``」バックスラッシュでシェル命令を囲んでいるようなものだろう。
先行してperlでいろいろ作っていたのだがそれの互換として考えると
print `ls`
は
#define BUFSIZE 4096
FILE *r_pipe;
int readed_num;
char buffer[BUFSIZE + 1];
memset(buffer,'\0',sizeof(buffer));
をとりあえず事前に宣言してある前提で
in_pipe = popen("ls","r");
if(in_pipe != NULL){
while(1){
if(feof(in_pipe)) break;
readed_num = fread(buffer,sizeof(char),BUFSIZE,r_pipe);
printf("%s",buffer);
pclose(in_pipe);
}
}
となる。
popenはテキスト系のサンプルが多いが汎用性を考えてfeofをチェックして
その間ループで回している。
「printf」の部分をTprocみたいにしておけば関数化できそうだ。
popenを"w"で実行するとインプット側のパラメータを与えられるのだが
その場合はファイル出力が前提となっているコマンドに限られそうだ。
今回のpopenでとっさに思いついたのがdjpegとcjpegの存在で
jpegの読み込みだけならdjpegをpopenで開けば良いし
書き出しもpopenでcjpegを呼べばいいのだが
単にファイルサイズを落としたいだけなら
system("djpeg a.jpg|cjpeg -optimize -quality 80 -outfile tmp.jpg");
で充分。
現状いろいろ加工が必要なのはデジカメの状態が悪いからで
多分今後デジカメを更新したらこの処理でいいのだろう。
そうするとココログ対応でexifだけ残しておきたいとなると
sprintf(str,"djpeg %s|cjpeg -optimize -quality 80",name);
popen(str,"r");
として元ファイルのexifをまず書き込んでからcjpegの出力のjfifタグ以降を書き込めばいいということになるが
ここまでやるとcjpegの両端パイプを開きたい。
パイプの両端を開く方法はpopenではだめでpipeとforkとdup2を使うのだが
使うかどうか別としてそれはまた、
コマンド呼び出しの方法よりもライブラリーを使う方が一見すっきりしているが
使っていないときのリソースを考えると頻繁に呼び出さないならば使いきりのpopenの方が速い。
リサイズについてはdjpegの-scaleで整数倍ならば落とせる他
jpegtranを使うと8ドット単位だがロスレスでクリップできる。
libjpegを使うコード量とpipeを使うコード量のトレードオフを見たいところだ。
ところで
popen1.c:35: error: stray '\343' in program
なんてのがでて全然意味が分からなかったのだけど
全角スペースが紛れ込んでいたのが原因だった。
全角英語ってhtmlのスパム避けにはいいのだけれど
geditは日本語なんて深く追求しないだろうから
スペースとかフォントとかでどうにかしないといけないと思えた。