とりあえずやってみよう、そんな毎日

気が向いたときにつらつらと更新していく、 フリーダムなスタイルでお送りするブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
  1. --/--/--(--) --:--:--|
  2. スポンサー広告

画像ファイルのバイナリ情報とパレットのハナシ

え?自作OSなのに画像ファイルって関係ないじゃん・・・・・・・・
と思われてみなさんも多いと思いますが、以外とそうでもないんですよ。

OSを作るうえで切っても切れない関係にあるのが、メモリやファイルの容量です。
先人の方々は少ないメモリやHDD容量の中、より表現豊かなOSになるように苦闘されてきた歴史があります。

CPUクロック数がウン?00MHzでメインメモリが?00MBだとか、今ではありえない話ですが、
こち亀の漫画を見てもらうと、今では鼻で笑うスペックが当時ではいかにすごかったか語られてます。
参考:両津「メモリー512Mのモンスターマシンだあああ」
メモリ512MBでモンスターマシンですからね・・・・・
今だとメモリ1Gでも「遅くて使いものにならない」というんですから、贅沢なものです。


・・・話が脱線してしまいましたorz

そんな感じでしたから、OSでもよく使う画像の容量の圧縮についても工夫がなされてきた、ということがあります。

まず、どうやって画像ファイルって扱っているの?というところから、
一番単純なbitmapファイルのバイナリのフォーマットについて説明をしましょう。
#興味をひかれた方は、下のリンクに詳しく書かれているので覗いてみてください。
BMPファイルのフォーマット


bitmapファイルというのは、下記のヘッダとピクセルごとの色データから構成されていて、
下記の要領でデータが保存されています。

■ファイルヘッダ (size:14byte)  
#ほかの記事ではbitmapFileHeaderと呼ばれているものです

2byte : ファイルのタイプ(BM固定)
4byte : ファイルサイズ
2byte : 予約領域(0固定)
2byte : 予約領域(0固定)
4byte : ファイル先頭から画像データまでのオフセット(byte)

■情報ヘッダ (size:40tyte)
#ほかの記事ではbitmapInfoHeaderと呼ばれているものです。

4byte : 情報ヘッダサイズ(40固定)
4byte : 画像の高さ(ピクセル)
4byte : 画像の高さ(ピクセル)
2byte : プレーン数(1固定)
2byte : 色ビット数(1,4,8,(16), 24, 32)
4byte : 圧縮形式(0,1,2,3)
4byte : 画像データサイズ(byte)
4byte : 水平解像度(dot/meter)
4byte : 垂直解像度(dot/meter)
4byte : 格納パレット数(使用色数)
4byte : 重要なパレットのインデックス


バイナリエディタで開くと下記のような感じです。
青い枠内のところにファイルヘッダ、
赤い枠内のところに情報ヘッダが記録されています。


赤枠以降のところは、パレットを使う/使わないで形式が変わってきます。


■使わない場合
下記の要領でピクセル情報が並びます。
1byte : 青色情報(0~255)
1byte : 緑色情報(0~255)
1byte : 赤色情報(0~255)
1byte : 予約領域(0固定)

ということは、1ピクセルにつき4byte容量を食うということです。

■使う場合
パレットの色数分、上記のピクセル情報が並んだあと色番号のインデックス情報が並びます。

※インデックス情報の容量について
256色 : 1ピクセルにつき1byte
16色 : 1ピクセルにつき4bit (2ピクセルで1byte)
8色 : 1ピクセルにつき3bit (2ピクセル+2bitで1byte)
4色 : 1ピクセルにつき2bit (4ピクセルで1byte)
1色 : 1ピクセルにつき4bit (8ピクセルで1byte)

ということは、パレット数×4byte+インデックス情報(※)×解像度分容量を食うということです。


さて、ここで少し考えてみましょう。
仮に壁紙情報やアイコンの情報などをパレットを使わずに持っていたら、どうなるでしょう。
壁紙を800×600、アイコンのサイズを32×32のサイズとしましょうか。
これでも、いまの時代ではありえないショボさのOSになるのですが・・・・・・

■壁紙
54byte+800×600×4byte=1,920,054byte≒1.92M byte
※54byteは各種ヘッダの合計サイズ

■アイコン
ヘッダサイズ54byte+32×32×4byte=4150byte=4.15K byte

おまけ:自作OS入門の筆者が作ったOSのプログラムのサイズ
80KB

昔よく使われていた8インチのフロッピ-ディスクで記録できる容量は1400KB(自作OS入門より引用)
↑決してGBの間違いではありませんから!
で、考えると、アイコンは1枚のフロッピーに300枚近く入れられるとしても、
壁紙一つ入フロッピーには入らんのです。


そこで、パレットと色番号情報で画像を管理する、という方法を使うのです。
上記と同じ条件を16色bitmapと256色bitmapで容量を試算してみると、下記の様になります。
※正確には、bitmapの横サイズが4バイト区切りになるように0埋めのパディングデータが入るため少し容量が増えます。

■壁紙
(16色)
 54byte+(16×4byte)+(800×600)×1/2byte=54+64+(480000/2)=2400118≒240K byte

(256色)
 54byte+(256×4byte)+(800×600)×1byte=54+1024+(480000)=481078≒480K byte
※16×4byte、256×4byteはパレットのサイズです。

■アイコン
(16色)
 54byte+(16×4byte)+(32×32)×1/2byte=54+64+(1024/2)=630 byte

(256色)
 54byte+(256×4byte)+(32×32)×1byte=54+1024+1024=2102≒2.1K byte
※16×4byte、256×4byteはパレットのサイズです。

おまけリターンズ:自作OS入門の筆者が作ったOSのプログラムのサイズ
80KB

すごく容量が小さくなりました。(自作OS筆者のOSサイズってどんだけ・・・・・・)
画面の情報だってピクセル情報をメモリに展開して使うでしょうから、小さいに越したことはありません。

pngだとかjpegだとかの圧縮形式をつかえばいいじゃないか、という話もあると思いますが、
結局はメモリに展開した時に容量を食うか、描画の度、解凍するためにCPUに負荷をかけるか、という話になるので、
現実的に考えるとパレットを使う方法に落ち着くのかと思います。
#パレットならメモリのアドレスを切り替えるだけで済みますからね

余談ですが、パレットの色情報を変更することで、画像の色味をガラリと帰ることができます。
#わかりやすい話で言うと、ファミコンのスーパーマリオのマリオとルイージの色分けなどです。

また、パレットの色替えを有効に使うと、Windowsでやっているようなデスクトップテーマみたいなことをできるわけです。
フォントや下のバー、背景などで使うパレット番号を決めておき、
対応するパレットの色を変更すれば実現できますよね。
そう考えると、パレットの考え方って、意外とOSにあってるのではないかな、とも思えてきます。


以上です。
文章が長い&取り留めのない記事になってしまいましたが、
最後までお読みいただきありがとうざいました。


おまけ:
下記に256色bitmap生成プログラムのサンプルを用意してみました。
参考にしてもらえると嬉しいです。
#ハードコーディング気味&気が利かないところ多くて難なのですが・・・・・・・

http://climbi.com/b/8796/0
(わからないところはナカタニへ連絡くださいな☆

※注意:
  アライメントの関係で、コンパイルしてもうまく生成されないというケースが起こることがあります。
  その際は、コンパイラのアライメント設定を2バイト単位に変更してコンパイルしてみてください。
スポンサーサイト
  1. 2016/12/23(金) 20:38:12|
  2. プログラミングとかとか
  3. | トラックバック:0
  4. | コメント:0
<<プログラマってこんなことやってます | ホーム | USBにosをインストールするツールをつかってみた>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://hiyashicurry.blog106.fc2.com/tb.php/16-f5f547b9
この記事にトラックバックする(FC2ブログユーザー)

最新記事

最新コメント

最新トラックバック

月別アーカイブ

カテゴリ

未分類 (9)
プロフィール (2)
会社で聞いたタメになるコト (2)
最近ふと思うこと (3)
プログラミングとかとか (23)
コンピュータの話 (17)
雑談 (11)

検索フォーム

RSSリンクの表示

リンク

このブログをリンクに追加する

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。