fortran66のブログ

fortran について書きます。

【メモ帳】最小サイズ gif ファイル

最小 gif 画像

以下のサイトを基点に勉強させていただいているのですが、最小サイズの gif 画像というものが助けになりました。
最小サイズのgif画像とアニメーションgif – ソフトウェア開発日記

ところで、その中の LINK 先になっている
・Cover Sheet for the GIF89a Specification https://www.w3.org/Graphics/GIF/spec-gif89a.txt
を読んでいきますと、image block の先頭に辞書の初期化用の clear code を置けとありますが、昨日までの私のプログラムはこれを守っておりませんでした。また LZW コード末尾には end code を入れろともありました。こちらは守っていました。

また Global Color Table は無くてもいいと書いてありまして、これがない場合システムデフォルト値が使われるようです。11. About Color Tables で、デコーダー側に最初の二色が「黒」「白」となっているのが望ましいと要望されています。実際やってみると windows では、この通りになっています。Photoshop ではどちらも黒になってしまいます。

Global Color Table を省くと最小 gif サイズは合法的に更に小さくできますが、環境依存の色となります。

f:id:fortran66:20180426000818g:plain

1 データあたり最小値の 3bit 使うとすると、先頭と最後にそれぞれ clear_code (2^2=4) と end_code (2^2+1=5) を置かねばならないので 6bit となり、最低 2byte 必要となります。すると 16 - 6 = 10bit 自由に使えそうですが、 データ数が増えると辞書サイズが膨らんでデータ長が 4bit になるので、結局 2 個分 6bit しか使えません(たぶん計算違いでなければ、もう一個データを入れるとそこから 4bit になって end code も 4bit になることを考えると 1bit 足りなくなります)。結局データ列としては、
4 clear_code
1 色番号1(白) 1pixel
6 lzw 圧縮データ 色番号1(白) 2pixel
7 lzw 圧縮データ 色番号1(白) 3pixel
5 end code
の 5byte で合計 6 pixel のドットが描けます。

実行結果

f:id:fortran66:20180426002645p:plain

  • ファイルの中身
47 49 46 38 39 61 03 00   02 00 19 00 00 2C 00 00
00 00 03 00 02 00 00 02   02 8C 5F 00 3B

29 byte

ソースプログラム

以下では 6 ピクセルを3x2の横長長方形サイズにしてみました。

    program gif
      use, intrinsic :: iso_fortran_env 
      implicit none
      integer :: iw
      integer(int16) :: m
      integer(int16), parameter :: nx = 3, ny = 2
      type :: t_gif_header
        sequence  
        character(3) :: signature = 'GIF'
        character(3) :: version   = '89a' ! '87a'
        integer(int16) :: width  = nx
        integer(int16) :: height = ny
        integer(int8)  :: pck   = int(B'00011001', int8) 
        integer(int8)  :: background_color_index = 0
        integer(int8)  :: pixel_aspect_ratio     = 0
      end type  
      
      type :: t_image_block
        sequence
        integer(int8) :: image_separator = Z'2C'
        integer(int16) :: image_left_position = 00
        integer(int16) :: image_top_position  = 00
        integer(int16) :: image_width  = nx 
        integer(int16) :: image_height = ny
        integer(int8) :: pck = int(B'00000000', int8)
        ! local color table
        !integer(int8) :: LZW_minimum_code_size 
        !integer(int8) :: block_size  
        !integer(int8) :: image_data
        !integer(int8) :: block_terminator = Z'00'  
      end type t_image_block

      type (t_gif_header ) :: head
      type (t_image_block) :: img    
      integer :: nbits = 2
      open(newunit = iw, file = 'min.gif', access = 'stream')
! image data
!   4   1   6   7   5        5   7   6   1   4       5    F     8    C
! 100 001 110 111 101 -> 0 101 111 110 001 100 -> 0101 1111  1000 1100 -> 5F 8C 
!      
      write(iw) head      
      write(iw) img     
      write(iw) achar([nbits])       ! LZW_minimum_code_size = 2   (2+1=3bit)  
      write(iw) achar([2])           ! block_size = 2byte        
      write(iw) achar([Z'8C', Z'5F'])! image_data  
      write(iw) achar(00)            ! block_terminator
      write(iw) achar([Z'3B'])       ! end of gif file
    end program gif

Modern Fortran Explained (Numerical Mathematics and Scientific Computation)

Modern Fortran Explained (Numerical Mathematics and Scientific Computation)

  • 作者: Michael Metcalf,John Reid,Malcolm Cohen
  • 出版社/メーカー: Oxford University Press, U.S.A.
  • 発売日: 2011/05/08
  • メディア: ペーパーバック
  • この商品を含むブログを見る
Numerical Computing with Modern Fortran (Applied Mathematics)

Numerical Computing with Modern Fortran (Applied Mathematics)

Introduction to Programming with Fortran: With Coverage of Fortran 90, 95, 2003, 2008 and 77

Introduction to Programming with Fortran: With Coverage of Fortran 90, 95, 2003, 2008 and 77

FORTRAN FOR SCIENTISTS & ENGINEERS

FORTRAN FOR SCIENTISTS & ENGINEERS