「行」と「列」が何を表すのかがややこしい。
論文の 1 章第 3 段落の 3 行目 → 横に並んでいる
原稿用紙の 3 行目 → 縦に並んでいる
運動会で 2 年 1 組の生徒が一列に並ぶ → 横向き? 縦向き? 斜め向き?
教室の前に一列に並ぶ → 横に並んでいる?
---- 広辞苑5: ぎょう【行】(ギヤウ)
ぎょう【行】(ギヤウ)
➀ゆくこと。すすむこと。「行幸・行列」
➁おこなうこと。おこない。ふるまい。「行政・行儀・悪行」
➂文字などの縦のならび。転じて、横のならびにも。くだり。「行間・改行・ア行」
(4)位が高く官が低いことを示す字。
→位署。
➄〔仏〕(梵語 sa̧mskāra)
(ア)(能動的意味で) 形成するもの。われわれの存在を成り立たせる潜在的形成力。また、さまざま
な心的活動。十二因縁の第2。五蘊の第4。
(イ)(受動的意味で) 形成されたもの。生滅変化する一切の現象世界の存在。
➅修行(しゆぎよう)。「無言の—」
➆行書の略。「真草行」
➇〔哲〕実践。行為。人間的な働き。↔知。
➈数学で、行列または行列式で横のならび。
→こう(行)
---- 広辞苑5: れつ【列】
れつ【列】
➀つらなること。ならんだもの。「—をくずす」「横の—」「行列・系列・列記・列代・列席」
➁順序。等級。「序列・同列・列次」
➂数の多いこと。「列国・列強」
(4)〔数〕行列または行列式で縦の並び。
日本語ではなく、 英語の row と column を理解するとよい。
---- Oxford Wordpower: row1 /rəʊ/ noun [countable]
row1 /rəʊ/ noun [countable]
1 a line of people or things
- a row of books
- The children were all standing in a row at the front of the class.
2 a line of seats in a theatre, cinema, etc.
- Our seats were in the back row.
- a front-row seat
[IDIOM]
_in a row_
one after another; without a break
- It rained solidly for four days in a row.
a line of people or houses → 横にしか並べない
---- Oxford Wordpower: column /ˈkɒləm/ noun [countable] stone
column /ˈkɒləm/ noun [countable] stone
1 a tall solid vertical post made of stone, supporting or decorating a building or standing alone
- Nelson's Column is a monument in London.
[PICT]shape
2 something that has the shape of a column
- a column of smoke (= smoke rising straight up)
on page
3 one of the vertical sections into which a printed page, especially in a newspaper, is divided
- a column of text
in newspaper
4 a piece of writing in a newspaper or magazine that is part of a regular series or always written
by the same writer
- the travel/gossip column
numbers
5 a series of numbers written one under the other
- to add up a column of figures
people/vehicles
6 a long line of people, vehicles, etc., one following behind another
- a column of troops
a tall solid vertical post → 縦になっているものが column
BMP file format
https://en.wikipedia.org/wiki/BMP_file_format
Microsoft が考案した画像のファイル形式。 中身はバイナリデータ。
課題のサンプル画像 in.bmp の冒頭をダンプしてみる。
$ xxd in.bmp | head -20
00000000: 424d 3608 0700 0000 0000 3600 0000 2800 BM6.......6...(.
00000010: 0000 e001 0000 4001 0000 0100 1800 0000 ......@.........
00000020: 0000 0008 0700 120b 0000 120b 0000 0000 ................
00000030: 0000 0000 0000 ffe6 dffd e6de fee7 dffd ................
00000040: e8e0 fde8 e0fc e7df fce7 dfff e9de ffea ................
00000050: dfff e9de fee8 ddfa e6db f5e2 daf1 e0d7 ................
00000060: eede d7ed ddd6 ead9 d6ec dbd8 eddd d7f0 ................
00000070: ddd8 f1de d9f2 dfda f3e0 dbf4 e1dc f4e1 ................
00000080: daf3 e0d9 f5df d9f7 e1db f8e2 dcfb e3dd ................
00000090: fce4 defd e5df fae5 ddf9 e4dc f5e2 daf3 ................
000000a0: e1da f0e0 d9ec dfd7 ebdd d7eb ddd7 ebdd ................
000000b0: d7ea dbd8 ebdc d9ed dedb efde dbf1 e0dd ................
000000c0: eddc d9ee ddda e7db dbe3 d6d8 e1d3 d5de ................
000000d0: cfd3 e0d1 d5e6 d8da e6d8 dae2 d5d7 ded3 ................
000000e0: d5d6 cfd4 cec7 d4be bad3 a4a4 c898 9aca ................
000000f0: 9094 ce84 8bca 7a85 c979 84ce 6675 be41 ......z..y..fu.A
00000100: 5193 1c2d 6000 123f 152c 5938 5883 5178 Q..-`..?.,Y8X.Qx
00000110: 9f62 8eb3 6994 bb5d 87b1 456f 993b 648b .b..i..]..Eo.;d.
00000120: 5377 9d69 89b2 6788 b65b 789f 3951 752f Sw.i..g..[x.9Qu/
00000130: 4071 3f4d 954f 60b6 526a c25b 76cc 617d @q?M.O`.Rj.[v.a}
先頭の 2 バイトが BM (0x42 0x4d) だから、 Windows 形式のビットマップファイルであることがわかる。
それ以降はバイナリデータなので、 ASCII ダンプを見てもよくわからない。
BMP ファイルヘッダの説明を見ると、 先頭の 14 バイトがヘッダであることがわかる。
Offset (bytes) Size (bytes) Description
0 2 The header field used to identify the BMP and DIB file is 0x42 0x4D in hexadecimal, same as BM in ASCII. The following entries are possible:
BM Windows 3.1x, 95, NT, ... etc.
BA OS/2 struct bitmap array
CI OS/2 struct color icon
CP OS/2 const color pointer
IC OS/2 struct icon
PT OS/2 pointer
2 4 The size of the BMP file in bytes
6 2 Reserved; actual value depends on the application that creates the image, if created manually can be 0
8 2 Reserved; actual value depends on the application that creates the image, if created manually can be 0
10 4 The offset, i.e. starting address, of the byte where the bitmap image data (pixel array) can be found.
2 バイト目からの 4 バイトがファイルの大きさで、 8 バイト目からの 4 バイトがオフセット。 バイナリデータの対応する箇所をマークする。
00000000: 424d 3608 0700 0000 0000 3600 0000 2800 BM6.......6...(.
========= size
========= offset
00000010: 0000 e001 0000 4001 0000 0100 1800 0000 ......@.........
00000020: 0000 0008 0700 120b 0000 120b 0000 0000 ................
00000030: 0000 0000 0000 ffe6 dffd e6de fee7 dffd ................
さらに、 14 バイト目からの 40 バイトが DIB (Devicee-Independent Bitmap) ヘッダである。 BMP ファイルでは他のパターンもあるが、 先頭が BM だったので 40 バイトの DIB ヘッダのパターンであることがわかる。
Offset (bytes) Size (bytes) Windows BITMAPINFOHEADER[2]
14 4 the size of this header, in bytes (40)
18 4 the bitmap width in pixels (signed integer)
22 4 the bitmap height in pixels (signed integer)
26 2 the number of color planes (must be 1)
28 2 the number of bits per pixel, which is the color depth of the image. Typical values are 1, 4, 8, 16, 24 and 32.
30 4 the compression method being used. See the next table for a list of possible values
34 4 the image size. This is the size of the raw bitmap data; a dummy 0 can be given for BI_RGB bitmaps.
38 4 the horizontal resolution of the image. (pixel per metre, signed integer)
42 4 the vertical resolution of the image. (pixel per metre, signed integer)
46 4 the number of colors in the color palette, or 0 to default to 2n
50 4 the number of important colors used, or 0 when every color is important; generally ignored
特に重要そうな箇所に注目すると、 18 バイト目からの 4 バイトが画像の幅、 22 バイト目からの 4 バイトが画像の高さ、 28 バイト目からの 2 バイトが 1 ピクセルのビット数がある。 バイナリデータの対応する箇所をマークする。
00000000: 424d 3608 0700 0000 0000 3600 0000 2800 BM6.......6...(.
========= size
========= offset
00000010: 0000 e001 0000 4001 0000 0100 1800 0000 ......@.........
========= width
========= height
==== nbits
00000020: 0000 0008 0700 120b 0000 120b 0000 0000 ................
00000030: 0000 0000 0000 ffe6 dffd e6de fee7 dffd ................
BMP ファイル形式はリトルエンディアンであることに注意すると、 幅が 0x0001e0 = 340、 高さが 0x00000140 = 320、 1 ピクセルのビット数が 0x0018 = 24 であることがわかる。
in.bmp の画像サイズを ImageMagick の identify コマンドで確認する。
$ identify in.bmp
in.bmp BMP3 480x320 480x320+0+0 8-bit sRGB 460854B 0.000u 0:00.001
当然ながら、 幅 480 ピクセル、 高さ 320 ピクセル、 8 ビットの RGB だから 24 ビットカラーと表示されている。
identify コマンドは、 BMP ファイルの上記の値を読み取って表示しているので、 値が一致するのは当然。
BMP ファイルの構造がわかれば、 BMP ファイルを扱うプログラムも簡単に書ける (今回の課題 B4 はその例にもなっている)。
BMP ファイルの画像の幅と高さを表示するプログラムを書いてみよう。
このくらい単純なものならスクラッチから書いてもよいが、 今回は AI (ChatGPT) で書いてみる。
コマンド行で指定された一つのファイルの、先頭から 2 バイトを文字列で、
先頭から 18 バイト目からの 4 バイトを image width (符号なし整数) として、
22 バイト目からの 4 バイトを image height (符号なし整数) として出力する、
できるだけ単純な Python プログラムを書いて。
実行結果は以下のようにして:
$ ./bmpinfo in.bmp
header: BMP
width: 320
height: 480
ChatGPT 4.1-nano の回答:
[gpt-4.1-nano]
以下に、指定された仕様に基づくPythonプログラム例を示します。このプログラムは、コマンドライン引数からファイル名を受け取り、ファイルの先頭から必要な情報を抽出して出力します。
### プログラムのポイント
- 先頭2バイトを文字列として取得
- 18バイト目から4バイトを符号なし整数(`unsigned int`)として解釈
- 22バイト目から4バイトも同様に解釈
- これらの値を出力
### 実装例
```python
import sys
import struct
def main():
if len(sys.argv) != 2:
print("Usage: {} <filename>".format(sys.argv[0]))
sys.exit(1)
filename = sys.argv[1]
with open(filename, 'rb') as f:
# 先頭2バイトを文字列として取得
header_bytes = f.read(2)
header_str = header_bytes.decode('ascii', errors='ignore')
# 18バイト目から4バイトを取得
f.seek(17) # 0-based indexなので、18バイト目は位置17
width_bytes = f.read(4)
width = struct.unpack('<I', width_bytes)[0] # リトルエンディアン
# 22バイト目から4バイトを取得
f.seek(21) # 22バイト目は位置21
height_bytes = f.read(4)
height = struct.unpack('<I', height_bytes)[0]
print("header: {}".format(header_str))
print("width: {}".format(width))
print("height: {}".format(height))
if __name__ == "__main__":
main()
```
---
### 補足と注意点
- **バイト位置の調整**:Pythonの`seek()`は0-basedなので、1バイト目は位置0です。したがって、18バイト目は位置17、22バイト目は位置21となります。
- **バイトの解釈**:`struct.unpack('<I', ...)`はリトルエンディアンの符号なし32ビット整数を解釈します。BMPファイルの仕様によってはエンディアンに注意が必要です。
- **エラーハンドリング**:簡潔さを優先し、ファイルの存在や読み取りエラーについては最低限のチェックに留めています。
### 実行例
```bash
$ ./bmpinfo in.bmp
header: BM
width: 320
height: 480
```
このプログラムは、指定されたバイト位置から必要な情報を抽出し、シンプルに出力することを目的としています。
あまり期待問通りの結果は得られなかった。 冗長なプログラムだし、 正常に動作しない。
ChatGPT 5 Instant に聞いてみる。
以下のようなシンプルな Python スクリプトで実現できます。
```python
#!/usr/bin/env python3
import sys
import struct
def main():
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <filename>")
sys.exit(1)
filename = sys.argv[1]
with open(filename, "rb") as f:
header = f.read(2).decode("ascii", errors="replace") # 先頭2バイト
f.seek(18)
width = struct.unpack("<I", f.read(4))[0] # little-endian 符号なし整数
height = struct.unpack("<I", f.read(4))[0]
print(f"header: {header}")
print(f"width: {width}")
print(f"height: {height}")
if __name__ == "__main__":
main()
```
---
### 使用例
```
$ ./bmpinfo in.bmp
header: BM
width: 320
height: 480
```
---
このスクリプトは BMP ファイルのヘッダ構造(`BITMAPFILEHEADER` と `BITMAPINFOHEADER`)に基づいています。
* 先頭 2 バイトは `"BM"` で始まることが多く、ファイル種別を示します。
* 18〜21 バイト目が幅 (`width`)、22〜25 バイト目が高さ (`height`) を表します。
このプログラムは正常に動作する。
ちなみに私が書くならこんな感じ:
#!/usr/bin/env python3
import sys
import struct
file = sys.argv[1]
with open(file, 'rb') as f:
buf = f.read(128)
signature = buf[0:2].decode()
width = struct.unpack('<I', buf[18:18 + 4])[0]
height = struct.unpack('<I', buf[22:22 + 4])[0]
print(f"""\
header: {signature}
width: {width}
height: {height}""")
ChatGPT 5 Instant が生成したプログラムとの違いは以下の通り。
- プログラムのロジックを単純にし、余計なオーバヘッドを減らすためにも、seek
や read を何度も呼び出さない。
- プログラムのロジックを単純にするため、複数行にまたがる出力は一行で書く。