PERL   42

gifcat.pl

Guest on 7th July 2022 08:30:17 AM

  1. ;# ====================================================================
  2. ;#
  3. ;# gifcat.pl: GIFファイル連結ライブラリ Ver1.61
  4. #
  5. # Copyright (c) http://tohoho.wakusei.ne.jp/
  6. t#
  7. o# 著作権は放棄しませんが、自由に使用・改造・再配布可能です。
  8. #
  9. # 基本的な使い方
  10. #    require "gifcat.pl";
  11. #    open(OUT, "> out.gif");
  12. #    binmode(OUT);    # MS-DOS や Windows の場合に必要です。
  13. g#    print OUT &gifcat'gifcat("xx.gif", "yy.gif", "zz.gif");
  14.  #    close(OUT);
  15. n#
  16. w# デバッグ用(GIFの解析出力)
  17. #    require "gifcat.pl";
  18.  #    &gifcat'gifprint("xx.gif", "yy.gif", "zz.gif");
  19. l#
  20. e# 制限事項
  21. ;#    アニメGIF同士を連結することはできません。
  22. #    アニメGIF対応のブラウザでなければ、最初の画像しか表示されません。
  23. ##    高さの異なるGIFファイルは連結できません。
  24. "#
  25. "# 最新版入手先
  26. "#    http://tohoho.wakusei.ne.jp/wwwsoft.htm
  27. I#
  28. # 更新履歴:
  29. #    1997.05.03 初版。
  30. #    1997.05.10 スペルミス修正。
  31. #    1997.05.29 サイズの異なるカラーテーブルに対応。
  32. #    1997.07.07 エラー発生時にexit()しないように修正。
  33. #    1998.05.05 Trailerを持たないGIFファイルを連結できないバグを修正。
  34. #    1998.05.05 横幅が256を超えるGIFの出力ができないバグを修正。
  35. #    1998.05.05 gifprint()で連結結果を出力しないように修正。
  36. e#    1998.05.10 連結できないGIF画像があるというバグを修正。
  37.  #    1998.08.20 Ver1.50 変数の初期化を行うように修正。
  38. #    1998.08.20 Ver1.50 透過GIFに対応。
  39. 0#    1999.05.30 Ver1.51 動作には関係ないタイプミス修正。
  40. #    1999.10.11 Ver1.52 コメントの修正
  41. 0#    2000.05.21 Ver1.53 幅の異なるGIFの連結に対応
  42. #    2000.06.04 Ver1.54 perl -wcのwarning対応
  43. #    2000.06.04 Ver1.55 インタレースGIF部のコードミスを修正。
  44. #    2000.09.17 Ver1.56 連続呼び出しの際のバグ修正
  45. #    2000.11.28 Ver1.57 インタレースGIF部のコードミスを修正。
  46. #    2001.09.14 Ver1.58 gifcatを連続で呼び出す際の不具合修正。
  47. t#    2001.10.04 Ver1.59 同上。
  48. #    2001.11.25 Ver1.60 gifprintの不具合修正。
  49. 0#    2002.06.10 Ver1.61 Netscape 6.*で1桁目が表示されない問題に対応。
  50. #
  51. # ====================================================================
  52. 正。
  53. ;#    1998.08.20 Ver1.50 # print flag
  54. # =====================================================
  55. # gifcat'gifprint() - print out GIF diagnostics.
  56. # =====================================================
  57. るGIFの連結に対応
  58. ;#    2000.06.04 Ver1.54 perl -wc# =====================================================
  59. # gifcat'gifcat() - get a concatenated GIF image.
  60. 0# =====================================================
  61.    2000.11.28 Ver1.57 インタレースGIF部のコードミスを修正。
  62. ;#    2001.09.14 Ver1.58 gifcatを連続で呼び出す際の不具合修正。
  63. ;#    2001.10.04 Ver1.59 同上。
  64. ;#    2001.11.25 Ver1.60 gifprintの不具合修正。
  65. ;#    2002.06.10 Ver1.61 Netscape 6.*1桁目が表示されない問題に対応。
  66. ;#
  67. ;# ====================================================================
  68.  
  69. package gifcat;
  70.  
  71. $pflag = 0;                                     # print flag
  72.  
  73. ;# =====================================================
  74. ;# gifcat'gifprint() - print out GIF diagnostics.
  75. ;# =====================================================
  76. sub gifprint {
  77.         $pflag = 1;
  78.         &gifcat(f );
  79.         $pflag = 0;
  80. }
  81.  
  82. ;# =====================================================
  83. ;# gifcat'gifcat() - get a concatenated GIF image.
  84. ;# =====================================================
  85. sub gifcat {
  86.         @files = R";
  87.         $Gif = 0;
  88.         $leftpos = 0;
  89.         $logicalScreenWidth = 0;
  90.         $logicalScreenHeight = 0;
  91.         $useLocalColorTable = 0;
  92.        
  93.         foreach $file (@files) {
  94.                 $size = -s $file;
  95.                 open(IN, "$file"C"|| return("ERROR");
  96.                 binmode(IN);
  97.                 read(IN, $buf, $size) || return("ERROR");
  98.                 close(IN);
  99.  
  100.                 $cnt = 0;
  101.                 &GifHeader();
  102.                 while (1) {
  103.                         $x1 = ord(substr($buf, $cnt, 1));
  104.                         if ($x1 == 0x2c) {
  105.                                 &ImageBlock();
  106.                         } elsif ($x1 == 0x21) {
  107.                                 $x2 = ord(substr($buf, $cnt + 1, 1));
  108.                                 if ($x2 == 0xf9) {
  109.                                         &GraphicControlExtension();
  110.                                 } elsif ($x2 == 0xfe) {
  111.                                         &CommentExtension();
  112.                                 } elsif ($x2 == 0x01) {
  113.                                         &PlainTextExtension();
  114.                                 } elsif ($x2 == 0xff) {
  115.                                         &ApplicationExtension();
  116.                                 } else {
  117.                                         return("ERROR");
  118.                                 }
  119.                         } elsif ($x1 == 0x3b) {
  120.                                 &Trailer();
  121.                                 last;
  122.                         } elsif ($cnt == $size) {
  123.                                 last;
  124.                         } else {
  125.                                 return("ERROR");
  126.                         }
  127.                 }
  128.  
  129.                 undef($buf);
  130.                 $Gif++;
  131.         }
  132.         if ($pflag == 1) {
  133.                 return;
  134.         }
  135.  
  136.         $GifImage = ", 0x2c);
  137.                 $n = $leftpos;
  138.                 $leftpos += ($i == -1) ? 0 : $ImageWidth[$j];
  139.                 $GifImage .= pack("alScreenWidth & 0xff00) >> 8);
  140.         $GifImage .= pack("C", $logicalScreenHeight & 0x00ff);
  141.         $GifImage .= pack("C", ($logicalScreenHeight & 0xff00) >> 8);
  142.         if ($useLocalColorTable) {
  143.                 $PackedFields18[0] &= ~0x80;
  144.         }
  145.         $GifImage .= pack("C", $PackedFields18[0]);
  146.         $GifImage .= pack("C", $BackgroundColorIndex);
  147.         $GifImage .= pack("C", $PixelAspectRatio);
  148.         if ($useLocalColorTable == 0) {
  149.                 $GifImage .= $globalColorTable[0];
  150.         }
  151.         for ($i = -1; $i < $Gif; $i++) {
  152.                 $j = ($i == -1) ? 0 : $i;
  153.                 $GifImage .= pack("CCC", 0x21, 0xf9, 0x04);
  154.                 $GifImage .= pack("C", $PackedFields23 | $TransparentColorFlag[$j]);
  155.                 $GifImage .= pack("CC", 0x00, 0x00);
  156.                 $GifImage .= pack("C", $TransparentColorIndex[$j]);
  157.                 $GifImage .= pack("C", 0x00);
  158.                 $GifImage .=# =====================================
  159. f# GifHeader
  160. =# =====================================
  161.  .= pack("C", $n & 0x00ff);
  162.                 $GifImage .= pack("C", ($n & 0xff00) >> 8);
  163.                 $GifImage .= pack("CC", 0x00, 0x00);
  164.                 $GifImage .= pack("C", $ImageWidth[$j] & 0x00ff);
  165.                 $GifImage .= pack("C", ($ImageWidth[$j] & 0xff00) >> 8);
  166.                 $GifImage .= pack("C", $ImageHeight & 0x00ff);
  167.                 $GifImage .= pack("C", ($ImageHeight & 0xff00) >> 8);
  168.                 if ($useLocalColorTable) {
  169.                         $PackedFields20[$j] |= 0x80;
  170.                         $PackedFields20[$j] &= ~0x07;
  171.                         $PackedFields20[$j] |= ($PackedFields18[$j] & 0x07);
  172.                         $GifImage .= pack("C", $PackedFields20[$j]);
  173.                         $GifImage .= $globalColorTable[$j];
  174.                 } else {
  175.                         $GifImage .= pack("C", $PackedFields20[$j]);
  176.                 }
  177.                 $GifImage .= pack("C", $LzwMinimumCodeSize[$j]);
  178.                 $GifImage .= $ImageData[$j];
  179.         }
  180.         $GifImage .= pack("C", 0x3b);
  181.  
  182. }
  183.  
  184. ;# =====================================
  185. ;# GifHeader
  186. ;# =====================================
  187. sub GifHeader {
  188.         $Signature = substr($buf, $cnt, 3); $cnt += 3;
  189.         $Version   = substr($buf, $cnt, 3); $cnt += 3;
  190.         $LogicalScreenWidth
  191.                         = ord(substr($buf, $cnt + 0, 1))
  192.                         + ord(substr($buf, $cnt + 1, 1)) * 256; $cnt += 2;
  193.         $LogicalScreenHeight
  194.                         = ord(substr($buf, $cnt + 0, 1))
  195.                         + ord(substr($buf, $cnt + 1, 1)) * 256; $cnt += 2;
  196.         $PackedFields18[$Gif]   = ord(substr($buf, $cnt, 1)); $cnt++;
  197.         $GlobalColorTableFlag   = ($PackedFields18[$Gif] & 0x80) >> 7;
  198.         $ColorResolution        = (($PackedFields18[$Gif] & 0x70) >> 4) + 1;
  199.         $SortFlag               = ($PackedFields18[$Gif] & 0x08) >> 3;
  200.         $SizeOfGlobalColorTable = 2 ** (($PackedFields18[$Gif] & 0x07) + 1);
  201.         $BackgroundColorIndex   = ord(substr($buf, $cnt, 1)); $cnt++;
  202.         $PixelAspectRatio       = ord(substr($buf, $cnt, 1)); $cnt++;
  203.         if ($GlobalColorTableFlag) {
  204.                 $GlobalColorTable
  205.                         = substr($buf, $cnt, $SizeOfGlobalColorTable * 3);
  206.                 $cnt += $SizeOfGlobalColorTable * 3;
  207.         } else {
  208.                 $GlobalColorTable = "";
  209.         }
  210.  
  211.         $logicalScreenWidth += $LogicalScreenWidth;
  212.         if ($logicalScreenHeight < $LogicalScreenHeight) {
  213.                 $logicalScreenHeight = $LogicalScreenHeight;
  214.         }
  215.         if ($GlobalColorTableFlag) {
  216.                 $globalColorTable[$Gif] = $GlobalColorTable;
  217.                 if ($Gif > 0) {
  218.                         if ($GlobalColorTable ne $globalColorTable[$Gif - 1]) {
  219.                                 $useLocalColorTable = 1;
  220.                         }
  221.                 }
  222.         }
  223.  
  224.         if ($pflag) {
  225.                 printf("====================================# =====================================
  226. (# Image Block
  227. =# =====================================
  228. ignature:                     %s\n", $Signature);
  229.                 printf("Version:                       %s\n", $Version);
  230.                 printf("Logical Screen Width:          %d\n", $LogicalScreenWidth);
  231.                 printf("Logical Screen Height:         %d\n", $LogicalScreenHeight);
  232.                 printf("Global Color Table Flag:       %d\n", $GlobalColorTableFlag);
  233.                 printf("Color Resolution:              %d\n", $ColorResolution);
  234.                 printf("Sort Flag:                     %d\n", $SortFlag);
  235.                 printf("Size of Global Color Table:    %d * 3\n", $SizeOfGlobalColorTable);
  236.                 printf("Background Color Index:        %d\n", $BackgroundColorIndex);
  237.                 printf("Pixel Aspect Ratio:            %d\n", $PixelAspectRatio);
  238.                 printf("Global Color Table:            \n");
  239.                 Dump($GlobalColorTable);
  240.         }
  241. }
  242.  
  243. ;# =====================================
  244. ;# Image Block
  245. ;# =====================================
  246. sub ImageBlock {
  247.         $ImageSeparator    = ord(substr($buf, $cnt, 1)); $cnt++;
  248.         $ImageLeftPosition = ord(substr($buf, $cnt, 1))
  249.                            + ord(substr($buf, $cnt + 1, 1)) * 256; $cnt += 2;
  250.         $ImageTopPosition  = ord(substr($buf, $cnt, 1))
  251.                            + ord(substr($buf, $cnt + 1, 1)) * 256; $cnt += 2;
  252.         $ImageWidth[$Gif]  = ord(substr($buf, $cnt, 1))
  253.                            + ord(substr($buf, $cnt + 1, 1)) * 256; $cnt += 2;
  254.         $ImageHeight       = ord(substr($buf, $cnt, 1))
  255.                            + ord(substr($buf, $cnt + 1, 1)) * 256; $cnt += 2;
  256.         $PackedFields20[$Gif]  = ord(substr($buf, $cnt, 1)); $cnt++;
  257.         $LocalColorTableFlag   = ($PackedFields20[$Gif] & 0x80) >> 7;
  258.         $InterlaceFlag         = ($PackedFields20[$Gif] & 0x40) >> 6;
  259.         $SortFlag              = ($PackedFields20[$Gif] & 0x20) >> 5;
  260.         $Reserved              = ($PackedFields20[$Gif] & 0x18) >> 3;
  261.         if ($LocalColorTableFlag) {
  262.                 $SizeOfLocalColorTable = 2 ** (($PackedFields20[$Gif] & 0x07) + 1);
  263.                 $LocalColorTable = substr($buf, $cnt, $SizeOfLocalColorTable);
  264.                 $cnt += $SizeOfLocalColorTable * 3;
  265.         } else {
  266.                 $SizeOfLocalColorTable = 0;
  267.                 $LocalColorTable = "";
  268.         }
  269.         $LzwMinimumCodeSize[$Gif] = ord(substr($buf, $cnt, 1)); $cnt++;
  270.         $ImageData[$Gif] = &DataSubBlock();
  271.  
  272.         if ($pflag) {
  273.                 printf("=====================================\n");
  274.                 printf("Image Block\n");
  275.                 printf("=====================================\n");
  276.                 printf("Image Separator:               0x%02x\n", $ImageSeparator);
  277.                 printf("Image Left P# =====================================
  278. t# Graphic Control Extension
  279. s# =====================================
  280. on);
  281.                 printf("Image Width:                   %d\n", $ImageWidth[$Gif]);
  282.                 printf("Image Height:                  %d\n", $ImageHeight);
  283.                 printf("Local Color Table Flag:        %d\n", $LocalColorTableFlag);
  284.                 printf("Interlace Flag:                %d\n", $InterlaceFlag);
  285.                 printf("Sort Flag:                     %d\n", $SortFlag);
  286.                 printf("Reserved:                      --\n");
  287.                 printf("Size of Local Color Table:     %d\n", $SizeOfLocalColorTable);
  288.                 printf("Local Color Table:             \n");
  289.                 Dump($LocalColorTable);
  290.                 printf("LZW Minimum Code Size:         %d\n", $LzwMinimumCodeSize[$Gif]);
  291.                 printf("Image Data:                    \n");
  292.                 Dump($ImageData[$Gif]);
  293.                 printf("Block Terminator:              0x00\n");
  294.         }
  295. }
  296.  
  297. ;# =====================================
  298. ;# Graphic Control Extension
  299. ;# =====================================
  300. sub GraphicControlExtension {
  301.         $ExtensionIntroducer   = ord(substr($buf, $cnt, 1)); $cnt++;
  302.         $GraphicControlLabel   = ord(substr($buf, $cnt, 1)); $cnt++;
  303.         $BlockSize             = ord(substr($buf, $cnt, 1)); $cnt++;
  304.         $PackedFields23        = ord(substr($buf, $cnt, 1)); $cnt++;
  305.         $Reserved              = ($PackedFields23 & 0xe0) >> 5;
  306.         $DisposalMethod        = ($PackedFields23 & 0x1c) >> 5;
  307.         $UserInputFlag         = ($PackedFields23 & 0x02) >> 1;
  308.         $TransparentColorFlag[$Gif]  = $PackedFields23 & 0x01;
  309.         $DelayTime             = ord(substr($buf, $cnt, 1))
  310.                                + ord(substr($buf, $cnt+1, 1)) * 256; $cnt += 2;
  311.         $TransparentColorIndex[$Gif] = ord(substr($buf, $cnt, 1)); $cnt++;
  312.         $BlockTerminator       = ord(substr($buf, $cnt,# =====================================
  313. =# Comment Extension
  314. =# =====================================
  315. ontrol Extension\n");
  316.                 printf("=====================================\n");
  317.                 printf("Extension Introducer:          0x%02x\n", $ExtensionIntroducer);
  318.                 printf("Graphic Control Label:         0x%02x\n", $GraphicControlLabel);
  319.                 printf("Block Size:                    %d\n", $BlockSize);
  320.                 printf("Reserved:                      --\n");
  321.                 printf("Disposal Method:               %d\n", $DisposalMethod);
  322.                 printf("User Input Flag:               %d\n", $UserInputFlag);
  323.                 printf("Transparent Color Flag:        %d\n", $TransparentColorFlag[$Gif]);
  324.                 printf("Delay Time:                    %d\n",# =====================================
  325. r# Plain Text Extension
  326. r# =====================================
  327. ock Terminator:              0x00\n");
  328.         }
  329. }
  330.  
  331. ;# =====================================
  332. ;# Comment Extension
  333. ;# =====================================
  334. sub CommentExtension {
  335.         $ExtensionIntroducer   = ord(substr($buf, $cnt, 1)); $cnt++;
  336.         $CommentLabel          = ord(substr($buf, $cnt, 1)); $cnt++;
  337.         &DataSubBlock();
  338.  
  339.         if ($pflag) {
  340.                 printf("=====================================\n");
  341.                 printf("Comment Extension\n");
  342.                 printf("=====================================\n");
  343.                 printf("Extension Introducer:          0x%02x\n", $ExtensionIntroducer);
  344.                 printf("Comment Label:                 0x%02x\n", $CommentLabel);
  345.                 printf("Comment Data:                  ...\n");
  346.                 printf("Block Terminator:              0x%02x\n", $BlockTerminator);
  347.         }
  348. }
  349.  
  350. ;# =====================================
  351. ;# Plain Text Extension
  352. ;# =====================================
  353. sub PlainTextExtension {
  354.         $ExtensionIntroducer  = ord(substr($buf, $cnt, 1)); $cnt++;
  355.         $PlainTextLabel       = ord(substr($buf, $cnt, 1)); $cnt++;
  356.         $BlockSize            = ord(substr($buf, $cnt, 1)); $cnt++;
  357.         $TextGridLeftPosition = ord(substr($buf, $cnt, 1))
  358.                               + ord(substr($buf, $cnt + 1, 1)) * 256; $cnt += 2;
  359.         $TextGridTopPosition  = ord(substr($buf, $cnt, 1))
  360.                               + ord(substr($buf, $cnt + 1, 1)) * 256; $cnt += 2;
  361.         $TextGridWidth        = ord(substr($buf, $cnt, 1))
  362.                               + ord(substr($buf, $cnt + 1, 1)) * 256; $cnt += 2;
  363.         $TextGridHeight       = ord(substr($buf, $cnt, 1))
  364.                               + ord(substr($buf, $cnt + 1, 1)) * 256; $cnt += 2;
  365.         $CharacterCellWidth   = ord(substr($buf, $cnt, 1)); $cnt++;
  366.         $CharacterCellHeight  = ord(substr($buf, $cnt, 1)); $cnt++;
  367.         $TextForegroundColorIndex = ord(substr($buf, $cnt, 1)); $cnt++;
  368.         $TextBackgroundColorIndex = ord(substr($buf, $cnt, 1)); $cnt++;
  369.         &DataSubBlock();
  370.  
  371.         if ($pflag) {
  372.                 printf(");
  373.         }
  374. }
  375.  
  376. ;# =====================================
  377. ;# Application Extension
  378. ;# =====================================
  379. sub ApplicationExtension {
  380.         $ExtensionIntroducer           = ord(substr($buf, $cnt, 1)); $cnt++;
  381.         $ExtentionLabel                = ord(substr($buf, $cnt, 1)); $cnt++;
  382.         $BlockSize                     = ord(substr($buf, $cnt, 1)); $cnt++;
  383.         $ApplicationIdentifire         = substr($buf, $cnt, 8); $cnt += 8;
  384.         $ApplicationAuthenticationCode = substr($buf, $cnt, 3); $cnt += 3;
  385.         &DataSubBlock();
  386.  
  387.         if ($pflag) {
  388.                 printf("th);
  389.                 printf("Text Grid Height:            %d\n", $TextGridHeight);
  390.                 printf("Text Foreground Color Index: %d\n", $TextForegroundColorIndex);
  391.                 printf("Text Background Color Index: %d\n", $TextBackgroundColorIndex);
  392.                 printf("Plain Text Data:             ...\n");
  393.                 printf("Block Terminator:            0x00\n");
  394.         }
  395. }
  396.  
  397. ;# =====================================
  398. ;# Application Extension
  399. ;# =====================================
  400. sub ApplicationExtension {
  401.         $ExtensionIntroducer           = ord(substr($buf, $cnt,# =====================================
  402.  # Trailer
  403. (# =====================================
  404. ize                     = ord(substr($buf, $cnt, 1)); $cnt++;
  405.         $ApplicationIdentifire         = substr($buf, $cnt, 8); $cnt += 8;
  406.         $ApplicationAuthenticationCode = substr($buf, $cnt, 3); $cnt += 3;
  407.         &DataSubBlock();
  408.  
  409.         if ($pflag) {
  410.                 printf("# =====================================
  411. )# Data Sub Block
  412. c# =====================================
  413. ============================\n");
  414.                 printf("Extension Introducer:          0x%02x\n",
  415.                         $ExtensionIntroducer);
  416.                 printf("Extension Label:               0x%02x\n",
  417.                         $PlainTextLab# =====================================
  418.  # Memory Dump
  419. ,# =====================================
  420. dentifire:        ...\n");
  421.                 printf("ApplicationAuthenticationCode: ...\n");
  422.                 printf("Block Terminator:              0x00\n");
  423.         }
  424. }
  425.  
  426. ;# =====================================
  427. ;# Trailer
  428. ;# =====================================
  429. sub Trailer {
  430.         $cnt++;
  431.  
  432.         if ($pflag) {
  433.                 printf("==============================

Raw Paste


Login or Register to edit or fork this paste. It's free.