#!/usr/bin/perl # Last updated: <2006/03/01 15:38:08 +0900> # # imgjoin.pl # # 指定フォルダ内のgif画像を連結・1つのファイルにしてから、 # iモード端末の通信サイズに分割して出力する。 # # usage : perl imgjoin.pl DIR_NAME OUTPUT_FILENAME # # 出力ファイルの先頭には、ヘッダーが入る。 # # 2byte ファイル数 # 2byte 簡易checksum # 4byte 1ファイル目 : ファイル実データまでのオフセット # 4byte 1ファイル目 : ファイル実データのサイズ # 4byte 2ファイル目 : ファイル実データまでのオフセット # 4byte 2ファイル目 : ファイル実データのサイズ # ... # 4byte nファイル目 : ファイル実データまでのオフセット # 4byte nファイル目 : ファイル実データのサイズ # x byte gif画像データ # # OUTPUT_FILENAME は拡張子なしで指定。 # (スクリプト中で、.pak .txt 等を付け足してファイル名を決めてる) # # ActivePerl-5.8.7.815-MSWin32-x86-211909 で動作確認。 # # by mieki256 # 2006/02/20 0.01 とりあえず作成。 # 2006/02/25 0.02 iモード端末の通信サイズに分割するよう修正。 # 2006/02/26 0.03 ヘッダ先頭に簡易でchecksumを書くように修正。 use strict; my $ext ="gif"; # 処理する拡張子 my $outdir = "./bin"; # 出力先のディレクトリ名 (最後の '/' は不要) my $pakext = ".pak"; # パックしたデータファイルの拡張子 my $lstext = ".txt"; # データ順の定義部分を出力する際の拡張子 my $hedext = ".hed"; # 分割データリストファイルの拡張子 my $splitsize = 20480; #iモード端末の通信サイズ if ( $#ARGV != 1 ) { die "引数が異常です。 : $!"; } my $dir = $ARGV[0]; # 指定ディレクトリ名を得る my $outfname = $ARGV[1]; # 出力ファイル名を得る if ( -d $dir ) { print " ... Found Directory : $dir \n"; } else { die "Not Found $dir :"; } # ---------------------------------------- # ファイルリスト取得 my @list = (); opendir DH, $dir or die "$dir : $!"; while (my $file = readdir DH) { next if $file =~ /^\.{1,2}$/; # '.' '..' をスキップ if ( $file =~ /\.$ext$/i ) { push(@list,$file); } } closedir DH; if ( $#list < 0 ) { die "Not Found .$ext file. : $!"; } my @sortlist = sort {$a cmp $b} @list; my @sizelist = (); # ---------------------------------------- # ファイルサイズ取得 foreach my $f (@sortlist) { my $size = -s "$dir/$f"; print "found $f : size $size\n"; push(@sizelist, $size); } my $binsize = 0; foreach my $s (@sizelist) { $binsize += $s; } print " ... ", $#sortlist+1," files. : size = $binsize\n"; # ---------------------------------------- # 結合データ作成 # ファイルデータ結合 my $bodydata = ""; foreach my $f (@sortlist) { open(FH, "$dir/$f") || die $!; binmode FH; my $data; { local $/ = undef; $data = ; $bodydata .= $data; } close(FH); } # 簡易チェックサム算出 my $cksum = 0; foreach my $c (split //, $bodydata) { $cksum += ord $c; } $cksum = $cksum & 0x0FFFF; # ヘッダ作成 my $heddata = ""; $heddata .= pack("n", ($#sizelist + 1) ); # ファイル数 $heddata .= pack("n", $cksum); # checksum my $offset = 4 + (($#sizelist + 1) * 8); # 最初のファイルのオフセット foreach my $size (@sizelist) { $heddata .= pack( "N", $offset); # オフセット $heddata .= pack( "N", $size ); # ファイルサイズ $offset += $size; } my $wrdata = $heddata . $bodydata; # 結合したデータをファイルに出力 my $num = 0; while ( length($wrdata) > 0 ) { my $fn = "$outdir/$outfname$num$pakext"; my $wrd; if ( length($wrdata) > $splitsize ) { $wrd = substr($wrdata, 0, $splitsize); $wrdata = substr($wrdata, $splitsize); } else { $wrd = substr($wrdata, 0); $wrdata = ""; } open(OUT,"> $fn") || die $!; binmode OUT; print OUT $wrd; close OUT; print " ... write $fn : length = ", length($wrd), "\n"; $num++; } open(OUTH,"> $outdir/$outfname$hedext") || die $!; for ( my $i = 0; $i < $num; $i++ ) { print OUTH "$outfname$i$pakext\n"; } close(OUTH); # ついでに、.java 内で使う、定義部分のファイルを出力しておく # (出力ディレクトリがちと違うので注意。) open(OUTLST,"> $dir/$outfname$lstext") || die $!; my $c = 0; foreach my $f (@sortlist) { $f =~ tr/[a-z]/[A-Z]/; $f =~ tr/\./_/; $f =~ /(.*)_GIF/; my $p = $1; print OUTLST "\tprivate final int IMG_$p = $c;\t// ", $sizelist[$c],"\n"; $c++; } print OUTLST "\tprivate final int IMG_NUM_MAX = ", $c - 1, ";\n"; close(OUTLST); print "checksum = ",substr(sprintf("0000%X", $cksum), -4),"\n"; exit 0;