[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

(DTPtechNote:943) イラレのEPSから編集データ部分のみ取り出し



#!/usr/bin/perl -w

use File::Basename;

#Illustrator 9以降 (〜CS?) のEPSから、編集データ部分のみ取り出してみる.pl スクリプトです。
#最近のIllustrator EPSのデータ構造について知ることができます(?)。

#また、Illustrator CSと10が自身のEPSを開くとき、まれに出力データ部をスキップできない
#という問題(2004年10月23日現在)の緊急回避方法としても使えたりもするかも(^^;)。
#【参考 CLさんのblog】 http://cl.cocolog-nifty.com/dtp/2004/09/illustrator_cse.html

#※MacJPerl、Mac OS X、Win (ActivePerl) にて動作すると思います。
# WinにActivePerlをインストール。次に http://homepage3.nifty.com/yamakox/index.html
# のDrop on Scriptで「.pl」拡張子とperl.exeを関連づけして、ドロップレットにして確認。
#※当然のように無保証なので、実行・再配布等なにもかも自己責任でよろしくお願いします。

foreach $i (@ARGV) {
	($base, $dir, $ext) = fileparse($i, '\.[^\.]+$');
	$newpath = $dir . '@' . $base . $ext;
	open(IN, "$i") || die "can't open $i \n";
	binmode (IN);

	seek (IN,0,0); #TIFF preview
	if ((ord (getc IN) + ord (getc IN) * 0x100)==53445) {
		seek (IN,4,0); #PS start
		$psstrt = ord (getc IN) + ord (getc IN) * 0x100 + ord (getc IN) * 0x10000 + ord (getc IN) * 0x1000000;
		seek (IN,20,0); #preview start
		$prvst = ord (getc IN) + ord (getc IN) * 0x100 + ord (getc IN) * 0x10000 + ord (getc IN) * 0x1000000;
	} else {
		$psstrt = 0;
		seek (IN,0,2);
		$prvst = tell (IN);
	}

	$os = 0;
	seek (IN,$psstrt+23,0);
	$c = getc IN;
	if ($c eq chr(hex('0x0A'))) {
		$/ = pack("C", hex("A"));
		$os = 1; # unix LF
	} elsif ($c eq chr(hex('0x0D'))) {
		$/ = pack("C", hex("D"));
		$os = 2; # mac CR
		if (getc IN eq chr(hex('0x0A'))) {
			$/ = pack("C", hex("A"));
			$os = 3; # win CR+LF
		}
	}

	if ($os != 0) {
		seek (IN,$psstrt,0);
		$f = 0;
		while (<IN>) {
			if(/^%%Begin(?:Data|Binary):\s+(\d+)/) {
				seek IN, $1, 1;
			} # nomoto san arigaotou gozaimasu
			if (/^%AI9_PrivateDataBegin/) {
				$f = 1;
				last;
			}
		}

		if ($f == 1) {
			open(OUT, ">$newpath")|| die "can't open $newpath \n";
			binmode (OUT);
			$aisiz = $prvst -  tell (IN);
			for ($c = $aisiz; $c >= 0x10000; $c=$c-0x10000) {
				read (IN,$buf,0x10000);
				print (OUT $buf);
			}
			if (read (IN,$buf,$aisiz % 0x10000)) {
				print (OUT $buf);
			}
			close (OUT);
		}
	}
	close (IN);
}