SWF

(20) DefineBitsLossless

フォーマットによってパレット形式とビットマップ形式がある。 どちらも独自形式

  • 共通部分
    +--------------------------------------------------------------------+---
    | tag & length |   length   |  image_id | format |  width  |  height | ...
    |  20 ,  0x3f  |            |           |        |         |         |
    +--------------------------------------------------------------------+---
    <-- 2 bytes --><- 4 bytes -><-2 bytes-><-1 byte-><-2 bytes-><-2 bytes->
                                  <------------------  length ---(最後まで)
    
  • format 3 (GIF のようなパレット形式)
    ----------------------------------------------+
     共通 |colormap_count|  (colormap & indices)  |
     部分 |              |     zlib compressed    |
    ----------------------------------------------+
           <-- 1 byte  -><-- contents 残り全部  -->
             RGBの順で並ぶ↓   ↑ zlib compress ↑
                        ------------------------------------------------+
                         |    colormap    |     indices                 |
                        ------------------------------------------------+
                          <-- colormap --><-((width + 3) & -4) * height->
                              count * 3
    
  • format 4 (実物にお目にかかった事がないけど…)
    ----------------------------------------------+
     共通 |colormap_count|  (colormap & indices)  |
     部分 |              |     zlib compressed    |
    ----------------------------------------------+
           <-- 2 bytes -><-- contents 残り全部  -->
                             ↑ zlib compress ↑
                        ------------------------------------------------+
                         |    colormap    |     indices                 |
                        ------------------------------------------------+
                          <-- colormap --><-((width + 3) & -4) * height->
                              count * 2
    colormap を 0RRRRRGGGGGBBBBB の 16bit (BigEndian)で表現する
    
  • format 5 (PNG のようなビットマップ形式)
    ----------------------------+
     共通 |    (bitmap)         |
     部分 |   zlib compressed   |
    ----------------------------+
          <- contents 残り全部 ->
             ↑ zlib compress ↑
       -----------------------------+
       ...|        bitmap           | ← XRGB の順で並ぶ (X は padding)
       -----------------------------+
           <-- width * height * 4 -->
    

(36) DefineBitsLossless2

DefineBitsLossless に透明度がついたもの。

  • 共通部分 (DefineBitsLossless と同じ)
    +--------------------------------------------------------------------+---
    | tag & length |   length   |  image_id | format |  width  |  height | ...
    |  36 ,  0x3f  |            |           |        |         |         |
    +--------------------------------------------------------------------+---
    <-- 2 bytes --><- 4 bytes -><-2 bytes-><-1 byte-><-2 bytes-><-2 bytes->
                                  <------------------  length ---(最後まで)
    
  • format 3 (GIF のようなパレット形式)
    ----------------------------------------------+
     共通 |colormap_count|  (colormap & indices)  |
     部分 |              |     zlib compressed    |
    ----------------------------------------------+
           <-- 1 byte  -><-- contents 残り全部  -->
          ARGBの順で並ぶ↓     ↑ zlib compress ↑
                        ------------------------------------------------+
                         |    colormap    |     indices                 |
                        ------------------------------------------------+
                          <-- colormap --><-((width + 3) & -4) * height->
                              count * 4
    
  • format 5 (PNG のようなビットマップ形式)
    ----------------------------+
     共通 |    (bitmap)         |
     部分 |   zlib compressed   |
    ----------------------------+
          <- contents 残り全部 ->
           ↑ zlib compress ↑
       -----------------------------+
       ...|        bitmap           | ← ARGB の順で並ぶ
        -----------------------------+
          <-- width * height * 4 -->
    

(メモ) colormap_number

colormap_number には実際に使われる色数から 1 を引いた値が入る。(つまり 0 数えのカウント)

1byte で 1色~256色 を表したいので。(そのままだと255色までしか届かない)

(メモ) RGB と A の絡み

A が 0 でも 255 でもない時は、RGB はズバリ入ってなくて、A に応じて補正されてます。

          BitmapPixelData ARGB[image data size]
Array of pixel colors.
Number of entries is BitmapWidth * BitmapHeight.
The RGB data must already be multiplied by the alpha channel value.
なので、PNG 画像を DefineBitsLossless2 に落とす場合は、 PNG の (R, G, B, A) を (R*A/255, G*A/255, B*A/255, A) に変換する必要があります。

実行時の透明pixelの重ね合わせは以下の計算式になる

output = alpha * foreground + (1-alpha) * background
なので、この (alpha * ) の処理を端折れるように、はじめから補正してあると。

(メモ) ((width + 3) & -4) * height って?

((width + 3) & -4) * height

って何じゃらほい。という感じだけど、witdh を4の倍数で合わせるという意味 ほら、-4 って 2 の補数だと二進数で 11(略)1100 じゃないですか。

witdh = 1 の場合 => ((1 + 3) & -4) = 4 & 11(略)1100 = 4
witdh = 2 の場合 => ((2 + 3) & -4) = 5 & 11(略)1100 = 4
witdh = 3 の場合 => ((3 + 3) & -4) = 6 & 11(略)1100 = 4
witdh = 4 の場合 => ((4 + 3) & -4) = 7 & 11(略)1100 = 4
witdh = 5 の場合 => ((5 + 3) & -4) = 8 & 11(略)1100 = 8
つまり、4の倍数への繰り上げ処理。Windows BMP もピクセルデータはこんな並びだし、普通。

% 4 とか mod 4 とか書いても良いけど、alexref にリスペクトして、あえてそのまま。(実コードに、この演算使うと処理速そうだし)

参考

関連

  • GIF | PNG