新規記事投稿 フォロー記事投稿 記事のキャンセル
From: Hironobu <i14hnakagawa@ec.usp.ac.jp>
Subject: jpegのwidth/height
Date: 1997/11/11 01:26:36

Perlで、jpegファイルを読んでそのwidthとheightを返すプログラムが
必要なのですが、以下のスクリプトが上手く動きません。
UNIX System V (SPARCだと思う)のperl ver4.0だと動作しますが、
WinNT(Intel)のperl ver5.003_07 for Win32 Build306だと動きません。
エンディアンかとも思いましたが、うまく直せませんでした。
お助けください。

また、同様の動作をするスクリプト、またはDOSプログラムを知っていましたら
お教えください。


#行頭のprintはチェックの為に付けたもので、動作には関係ないです。

print &jpegsize('foo.jpg'),"\n";
exit;

sub jpegsize {
	local($file) = @_;
	local($done) = 0;
	local($size) = "";

	open(IN,$file)||die;

	read(IN, $c1, 1); read(IN, $c2, 1);
	if( !((ord($c1) == 0xFF) && (ord($c2) == 0xD8))){
		print "This is not a JPEG!";
		$done=1;
	}
	while (ord($ch) != 0xDA && !$done) {
		# Find next marker (JPEG markers begin with 0xFF)
		# This can hang the program!!
		while (ord($ch) != 0xFF) {
print '(A:'.ord($ch).')';
			read(IN, $ch, 1);
		}
		# JPEG markers can be padded with unlimited 0xFF's
		while (ord($ch) == 0xFF) {
print '{B:'.ord($ch).'}';
			read(IN, $ch, 1);
		}
		# Now, $ch contains the value of the marker.
		if ((ord($ch) >= 0xC0) && (ord($ch) <= 0xC3)) {
			read(IN, $junk, 3);
			read(IN, $s, 4);
			($a,$b,$c,$d)=unpack("CCCC",$s);
			$size=join("", 'HEIGHT=',$a<<8|$b,' WIDTH=',$c<<8|$d );
			$done=1;
		} else {
			# We **MUST** skip variables, since FF's within variable names are
			# NOT valid JPEG markers
			read(IN, $s, 2); 
			($c1, $c2) = unpack("CC",$s);
			$length = $c1<<8|$c2;
print "[L:$length]";
			if( ($length < 2) ){
				print "Erroneous JPEG marker length";
				$done=1;
			} else {
				read(IN, $junk, $length-2);
			}
		}
	}
	close(IN);
	return $size;
}