AnatomyJPG.pl

#!/usr/local/bin/perl
# (c)copyleft 2017-6-19 : Coded by shun kinoshita / knuhs
# JPEG file の解剖プログラム( AnatomyJPG.pl )
use strict;
use vars qw/ %HashTBL %DataTBL /; # Global の扱いにする
use lib 'C:/Users/恂/Documents/MyDoc/tym33/apl3/lib';
                  # ライブラリに追加するモジュールを置く場所を指定する
use JPGvivisect;  # モジュール( JPGvivisect.pm )を指定する

my $directory = "C:/Users/恂/Documents/MyDoc/tym33/uploadDATA2";
my $jpgFile = "IMG_0772.JPG";  # 絶対パスとファイル名を適宜指定する
my $jpgSTR;

# Marker の Code一覧
my @Codelist = ('FFD8', 'FFE0', 'FFE1',  'FFDB',  'FFC0',
                'FFC4', 'FFDA', 'Data1', 'Data2', 'FFD9');
# Marker Code の意味
my %Code2Name = (
     'FFE0'  => 'APP0(JFIF)                    ',
     'FFE1'  => 'APP1(Exif)                    ',
     'FFDB'  => 'DQT(Define Quantization Table)',
     'FFDA'  => 'SOS(Start Of Scan)            ',
     'FFC4'  => 'DHT(Define Huffman Table)     ',
     'FFC0'  => 'SOF0(Start Of Frame 0)        ',
     'FFD8'  => 'SOI(Start of Image)           ',
     'Data1' => '(Top Of Binary-Data)          ',
     'Data2' => '(End Of Binary-Data)          ',
     'FFD9'  => 'EOI(End Of Image)             ' );

# ファイルの大きさを調べる
    stat("$directory/$jpgFile"); my  $size = -s _;

# ファイルを読み込む
    open(JPEG, "$directory/$jpgFile") || die "開けません: $!";
    sysread(JPEG, $jpgSTR, $size) || die "入力エラー\n";

# 解析作業へ
my  $SGMsize = JPGvivisect(\$jpgSTR, $size, $directory, $jpgFile);
    if ( $SGMsize<=0 )
    { print "解析できません。\n"; exit; }

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# 解析結果:既知のファイル情報を表示する
    print "\n * JPEGファイルの解析結果\n";
    print "-----------------------------------------------------------\n";
    print "      既知のファイル情報一覧:\n";
    print "-----------------------------------------------------------\n";

    foreach my $key ( sort keys %DataTBL )
    {   print " $key = $DataTBL{$key}";   }

# 使用された Marker Code一覧
my  @marks = reverse sort keys( %HashTBL );
    print " Used Markers = ".join(',', @marks)."\n\n";

    print "\n      Marker に関する情報:\n";
    print "-----------------------------------------------------------\n";
    print " Marker                        | Code\t| 先頭からの位置\n";
    print "-----------------------------------------------------------\n";

# Marker に関する情報一覧
    foreach my $mark (@Codelist)
    {   my $count = $HashTBL{$mark}[0];
        for( my $i=1; $i<=$count; $i++ )
        {  print " $Code2Name{$mark}| $mark\t| ";
           print show($HashTBL{$mark}[$i])."\n";
        }
    }
    print "-----------------------------------------------------------\n";
    close(JPEG);

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# 使用例(1)
# 画像の縦横の長さを求める
    print "\n使用例(1):画像の縦横の長さを求める\n";

my  $C0pos = $HashTBL{'FFC0'}[1];
my ( $H, $W ) = ( getByte($C0pos+5, 2), getByte($C0pos+7, 2) );

    $DataTBL{'横幅'} = insCom($W)." Pixel\n";
    $DataTBL{'高さ'} = insCom($H)." Pixel\n";
    print "\$W = $W\n\$H = $H\n";

# 使用例(2)
# Data Scan して 管理情報を含まないデータの実測値を求める
    print "\n使用例(2):管理情報を含まないデータの実測値を求める\n";

my  $DApos = $HashTBL{'FFDA'}[1];
    $DApos += getByte($DApos+2, 2);
my  $top = $DApos + 3;
    while(1)
    {    next if( getByte($DApos,1) != 0xFF );
         last if( getByte($DApos+1,1) == 0xD9 );
    }continue{ $DApos++; }
    $DApos -= --$top; # 画像データの実測値を求める

    print "データの実測値 = ".insCom($DApos)." Bytes\n";
    $DataTBL{'データ実測値'} = insCom($DApos)." Bytes\n";

# 最終結果を表示する
    print "\n      ファイルに関する情報の最終結果:\n";
    print "-----------------------------------------------------------\n";
    foreach my $key ( sort keys %DataTBL )
    {   print " $key = $DataTBL{$key}";  }
    print "-----------------------------------------------------------\n";
    exit;