前回のラブライブ!
【調査中】JPEG画像を無劣化(ロスレス)で切り貼りしたい【ハフマン符号】 #画像処理 - Qiita
- JPEG画像を無劣化でトリミングしたり、左右に連結したりできるとするソフトウェアを紹介した
- JPEG画像内のハフマン符号の観察を行い、deflate と似た技術で符号が記述されていると予想した
別の表現をされた同じ(だろう)データの用意
圧縮をかけると、圧縮のしかたによって得られる画像に違いが出る可能性がある。
とはいえ、品質を 100 にして圧縮を避けることで、同じ画像が得られるかもしれないと考えた。
そこで、まず「8×8の緑背景で左上だけ黒いブロックを3個横に並べたPNG画像」を用意し、これを以下のソフトウェアでJPEGに変換した。
- ImageMagick 7.1.1-12
- JTrim Version 1.53c
- GIMP 2.10.38
GIMP における品質以外の保存設定は、以下のようにした。
- 各種「保存」(Exif データなど):オフ
- コメント:空
- Use arithmetic coding:オフ
- プログレッシブ:オフ
- スムージング:0.00
- リスタートマーカー:オフ
- サブサンプリング:4:4:4 (最高品質)
- DCT 変換方法:整数
以下が、元の画像と各ソフトウェアで変換した画像ファイルの hexdump である。
元の画像 (PNG)
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 00 18 00 00 00 08 08 06 00 00 00 e3 a1 3f |...............?|
00000020 63 00 00 00 01 73 52 47 42 00 ae ce 1c e9 00 00 |c....sRGB.......|
00000030 00 04 67 41 4d 41 00 00 b1 8f 0b fc 61 05 00 00 |..gAMA......a...|
00000040 00 09 70 48 59 73 00 00 0e c3 00 00 0e c3 01 c7 |..pHYs..........|
00000050 6f a8 64 00 00 00 2b 49 44 41 54 38 4f ad c9 b1 |o.d...+IDAT8O...|
00000060 0d 00 30 0c 80 30 fe 7f 3a dd 83 94 a5 c8 1b 00 |..0..0..:.......|
00000070 cc e9 fb ef 50 53 a8 29 d4 14 6a 0a 35 85 9a 42 |....PS.)..j.5..B|
00000080 ec 01 75 e0 7b 93 47 3f c0 92 00 00 00 00 49 45 |..u.{.G?......IE|
00000090 4e 44 ae 42 60 82 |ND.B`.|
ImageMagick で変換した画像
00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 02 00 25 |......JFIF.....%|
00000010 00 25 00 00 ff db 00 43 00 01 01 01 01 01 01 01 |.%.....C........|
00000020 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000030 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000040 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000050 01 01 01 01 01 01 01 01 01 ff db 00 43 01 01 01 |............C...|
00000060 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000070 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000080 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000090 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ff c0 |................|
000000a0 00 11 08 00 08 00 18 03 01 11 00 02 11 01 03 11 |................|
000000b0 01 ff c4 00 15 00 01 01 00 00 00 00 00 00 00 00 |................|
000000c0 00 00 00 00 00 00 00 08 ff c4 00 19 10 01 01 01 |................|
000000d0 01 01 01 00 00 00 00 00 00 00 00 00 00 05 04 03 |................|
000000e0 06 02 01 ff c4 00 15 01 01 01 00 00 00 00 00 00 |................|
000000f0 00 00 00 00 00 00 00 00 00 0a ff c4 00 18 11 01 |................|
00000100 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 04 |................|
00000110 03 05 02 01 ff da 00 0c 03 01 00 02 11 03 11 00 |................|
00000120 3f 00 a7 45 14 6e 6c 62 79 de 74 93 00 e7 c0 32 |?..E.nlby.t....2|
00000130 01 42 08 58 25 2c 61 46 2e 5c a1 30 92 4c 87 2c |.B.X%,aF.\.0.L.,|
00000140 22 38 c3 a2 c3 08 e0 82 3c 31 96 39 71 ca 79 f2 |"8......<1.9q.y.|
00000150 cf 1c fc 78 f9 2d 2f 7b b5 1c cd 3d 36 2f 47 4b |...x.-/{...=6/GK|
00000160 45 68 7e 86 83 d1 66 39 ee 65 bb 42 d8 c5 a3 ba |Eh~...f9.e.B....|
00000170 5d 4b 55 e9 4b a1 17 a7 76 bd bb ee b5 ef ae fa |]KU.K...v.......|
00000180 eb af 62 d3 4f 4f 4b 6b 4b 43 63 63 41 ba da fa |..b.OOKkKCccA...|
00000190 cd 5e 9e ae ae 9a ee fd 2d 3d 27 de 8a 76 86 83 |.^......-='..v..|
000001a0 95 4a a9 8d 62 ab 54 ad 69 ad 2e 8b d2 96 b5 3b |.J..b.T.i......;|
000001b0 a7 7d 75 e8 51 46 e6 c6 27 9d e7 49 30 0e 7c 03 |.}u.QF..'..I0.|.|
000001c0 20 14 20 85 82 52 c6 14 62 e5 ca 13 09 24 c8 72 | . ..R..b....$.r|
000001d0 c2 23 8c 3a 2c 30 8e 08 23 c3 19 63 97 1c a7 9f |.#.:,0..#..c....|
000001e0 2c f1 cf c7 8f 87 bd da 8e 66 9e 9b 17 a3 a5 a2 |,........f......|
000001f0 b4 3f 43 41 e8 b3 1c f7 32 dd a1 6c 62 d1 dd 2e |.?CA....2..lb...|
00000200 a5 aa f4 a5 d0 8b d3 bb 5e dd f7 5a f7 d7 7d 75 |........^..Z..}u|
00000210 d7 ad 3d 3d 2d ad 2d 0d 8d 8d 06 eb 6b eb 35 7a |..==-.-.....k.5z|
00000220 7a ba ba 6b bb f4 b4 f4 9f 7a 29 da 1a 0e 55 2a |z..k.....z)...U*|
00000230 a6 35 8a ad 52 b5 a6 b4 ba 2f 4a 5a d4 ee 9d f5 |.5..R..../JZ....|
00000240 d7 a1 45 1b 9b 18 9e 77 9d 24 c0 39 f0 0c 80 50 |..E....w.$.9...P|
00000250 82 16 09 4b 18 51 8b 97 28 4c 24 93 21 cb 08 8e |...K.Q..(L$.!...|
00000260 30 e8 b0 c2 38 20 8f 0c 65 8e 5c 72 9e 7c b3 c7 |0...8 ..e.\r.|..|
00000270 3f 1e 3e 1e f7 6a 39 9a 7a 6c 5e 8e 96 8a d0 fd |?.>..j9.zl^.....|
00000280 0d 07 a2 cc 73 dc cb 76 85 b1 8b 47 74 ba 96 ab |....s..v...Gt...|
00000290 d2 97 42 2f 4e ed 7b 77 dd 6b df 5d f5 d7 5e b4 |..B/N.{w.k.]..^.|
000002a0 f4 f4 b6 b4 b4 36 36 34 1b ad af ac d5 e9 ea ea |.....664........|
000002b0 e9 ae ef d2 d3 d2 7d e8 a7 68 68 39 54 aa 98 d6 |......}..hh9T...|
000002c0 2a b5 4a d6 9a d2 e8 bd 29 6b 53 ba 77 d7 5e ff |*.J.....)kS.w.^.|
000002d0 00 ff d9 |...|
JTrim で変換した画像
00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 |......JFIF......|
00000010 00 01 00 00 ff db 00 43 00 01 01 01 01 01 01 01 |.......C........|
00000020 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000030 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000040 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000050 01 01 01 01 01 01 01 01 01 ff db 00 43 01 01 01 |............C...|
00000060 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000070 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000080 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000090 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ff c0 |................|
000000a0 00 11 08 00 08 00 18 03 01 22 00 02 11 01 03 11 |........."......|
000000b0 01 ff c4 00 1f 00 00 01 05 01 01 01 01 01 01 00 |................|
000000c0 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 |................|
000000d0 0a 0b ff c4 00 b5 10 00 02 01 03 03 02 04 03 05 |................|
000000e0 05 04 04 00 00 01 7d 01 02 03 00 04 11 05 12 21 |......}........!|
000000f0 31 41 06 13 51 61 07 22 71 14 32 81 91 a1 08 23 |1A..Qa."q.2....#|
00000100 42 b1 c1 15 52 d1 f0 24 33 62 72 82 09 0a 16 17 |B...R..$3br.....|
00000110 18 19 1a 25 26 27 28 29 2a 34 35 36 37 38 39 3a |...%&'()*456789:|
00000120 43 44 45 46 47 48 49 4a 53 54 55 56 57 58 59 5a |CDEFGHIJSTUVWXYZ|
00000130 63 64 65 66 67 68 69 6a 73 74 75 76 77 78 79 7a |cdefghijstuvwxyz|
00000140 83 84 85 86 87 88 89 8a 92 93 94 95 96 97 98 99 |................|
00000150 9a a2 a3 a4 a5 a6 a7 a8 a9 aa b2 b3 b4 b5 b6 b7 |................|
00000160 b8 b9 ba c2 c3 c4 c5 c6 c7 c8 c9 ca d2 d3 d4 d5 |................|
00000170 d6 d7 d8 d9 da e1 e2 e3 e4 e5 e6 e7 e8 e9 ea f1 |................|
00000180 f2 f3 f4 f5 f6 f7 f8 f9 fa ff c4 00 1f 01 00 03 |................|
00000190 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 |................|
000001a0 02 03 04 05 06 07 08 09 0a 0b ff c4 00 b5 11 00 |................|
000001b0 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00 |..............w.|
000001c0 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 |......!1..AQ.aq.|
000001d0 22 32 81 08 14 42 91 a1 b1 c1 09 23 33 52 f0 15 |"2...B.....#3R..|
000001e0 62 72 d1 0a 16 24 34 e1 25 f1 17 18 19 1a 26 27 |br...$4.%.....&'|
000001f0 28 29 2a 35 36 37 38 39 3a 43 44 45 46 47 48 49 |()*56789:CDEFGHI|
00000200 4a 53 54 55 56 57 58 59 5a 63 64 65 66 67 68 69 |JSTUVWXYZcdefghi|
00000210 6a 73 74 75 76 77 78 79 7a 82 83 84 85 86 87 88 |jstuvwxyz.......|
00000220 89 8a 92 93 94 95 96 97 98 99 9a a2 a3 a4 a5 a6 |................|
00000230 a7 a8 a9 aa b2 b3 b4 b5 b6 b7 b8 b9 ba c2 c3 c4 |................|
00000240 c5 c6 c7 c8 c9 ca d2 d3 d4 d5 d6 d7 d8 d9 da e2 |................|
00000250 e3 e4 e5 e6 e7 e8 e9 ea f2 f3 f4 f5 f6 f7 f8 f9 |................|
00000260 fa ff da 00 0c 03 01 00 02 11 03 11 00 3f 00 fa |.............?..|
00000270 77 45 d1 74 6f 0d e8 da 4f 87 7c 3b a4 e9 9a 07 |wE.to...O.|;....|
00000280 87 f4 0d 32 c3 45 d0 b4 2d 16 c2 d7 4b d1 b4 5d |...2.E..-...K..]|
00000290 1b 4b b5 8a c7 4c d2 74 9d 32 c6 28 2c b4 ed 33 |.K...L.t.2.(,..3|
000002a0 4e b2 82 0b 3b 0b 0b 38 21 b5 b3 b5 86 2b 7b 78 |N...;..8!....+{x|
000002b0 a3 86 34 40 68 ba 2e 8d e1 bd 1b 49 f0 ef 87 74 |..4@h......I...t|
000002c0 9d 33 40 f0 fe 81 a6 58 68 ba 16 85 a2 d8 5a e9 |.3@....Xh.....Z.|
000002d0 7a 36 8b a3 69 76 b1 58 e9 9a 4e 93 a6 58 c5 05 |z6..iv.X..N..X..|
000002e0 96 9d a6 69 d6 50 41 67 61 61 67 04 36 b6 76 b0 |...i.PAgaag.6.v.|
000002f0 c5 6f 6f 14 70 c6 88 0a 2b fe 59 27 5e bd 4f 6b |.oo.p...+.Y'^.Ok|
00000300 ed 2b 55 9f b7 aa ab d7 e7 a9 39 7b 6a eb da 5a |.+U.......9{j..Z|
00000310 b5 5e 69 3f 69 55 7b 6a d6 a9 3b cd 7b 5a 96 97 |.^i?iU{j..;.{Z..|
00000320 ef 25 7f f8 ae a9 89 c4 d5 f6 fe d7 11 5e a7 d6 |.%...........^..|
00000330 6b ac 4e 27 da 55 a9 3f ac 62 63 ed b9 71 15 f9 |k.N'.U.?.bc..q..|
00000340 a4 fd ad 78 fd 62 bd aa d4 e6 a8 bd bd 6b 4b f7 |...x.b.......kK.|
00000350 93 e6 34 5d 17 46 f0 de 8d a4 f8 77 c3 ba 4e 99 |..4].F.....w..N.|
00000360 a0 78 7f 40 d3 2c 34 5d 0b 42 d1 6c 2d 74 bd 1b |.x.@.,4].B.l-t..|
00000370 45 d1 b4 bb 58 ac 74 cd 27 49 d3 2c 62 82 cb 4e |E...X.t.'I.,b..N|
00000380 d3 34 eb 28 20 b3 b0 b0 b3 82 1b 5b 3b 58 62 b7 |.4.( ......[;Xb.|
00000390 b7 8a 38 63 44 05 14 54 d4 a9 3a b5 27 56 ac e7 |..8cD..T..:.'V..|
000003a0 52 ad 49 ca a5 4a 95 24 e7 52 a4 e6 dc a7 39 ce |R.I..J.$.R....9.|
000003b0 4d ca 53 94 9b 94 a5 26 dc 9b 6d b6 d9 9d 5a b5 |M.S....&..m...Z.|
000003c0 2b d4 a9 5a b5 49 d6 ad 5a 73 ab 56 ad 59 ca a5 |+..Z.I..Zs.V.Y..|
000003d0 4a b5 2a 49 ce a5 4a 95 26 dc a7 39 c9 b9 4e 72 |J.*I..J.&..9..Nr|
000003e0 6e 52 93 6d b6 db 67 ff d9 |nR.m..g..|
GIMP で変換した画像 (最適化オン)
00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 02 00 25 |......JFIF.....%|
00000010 00 25 00 00 ff db 00 43 00 01 01 01 01 01 01 01 |.%.....C........|
00000020 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000030 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000040 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000050 01 01 01 01 01 01 01 01 01 ff db 00 43 01 01 01 |............C...|
00000060 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000070 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000080 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000090 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ff c0 |................|
000000a0 00 11 08 00 08 00 18 03 01 11 00 02 11 01 03 11 |................|
000000b0 01 ff c4 00 15 00 01 01 00 00 00 00 00 00 00 00 |................|
000000c0 00 00 00 00 00 00 00 08 ff c4 00 19 10 01 01 01 |................|
000000d0 01 01 01 00 00 00 00 00 00 00 00 00 00 05 04 03 |................|
000000e0 06 02 01 ff c4 00 15 01 01 01 00 00 00 00 00 00 |................|
000000f0 00 00 00 00 00 00 00 00 00 0a ff c4 00 18 11 01 |................|
00000100 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 04 |................|
00000110 03 05 02 01 ff da 00 0c 03 01 00 02 11 03 11 00 |................|
00000120 3f 00 a7 45 14 6e 6c 62 79 de 74 93 00 e7 c0 32 |?..E.nlby.t....2|
00000130 01 42 08 58 25 2c 61 46 2e 5c a1 30 92 4c 87 2c |.B.X%,aF.\.0.L.,|
00000140 22 38 c3 a2 c3 08 e0 82 3c 31 96 39 71 ca 79 f2 |"8......<1.9q.y.|
00000150 cf 1c fc 78 f9 2d 2f 7b b5 1c cd 3d 36 2f 47 4b |...x.-/{...=6/GK|
00000160 45 68 7e 86 83 d1 66 39 ee 65 bb 42 d8 c5 a3 ba |Eh~...f9.e.B....|
00000170 5d 4b 55 e9 4b a1 17 a7 76 bd bb ee b5 ef ae fa |]KU.K...v.......|
00000180 eb af 62 d3 4f 4f 4b 6b 4b 43 63 63 41 ba da fa |..b.OOKkKCccA...|
00000190 cd 5e 9e ae ae 9a ee fd 2d 3d 27 de 8a 76 86 83 |.^......-='..v..|
000001a0 95 4a a9 8d 62 ab 54 ad 69 ad 2e 8b d2 96 b5 3b |.J..b.T.i......;|
000001b0 a7 7d 75 e8 51 46 e6 c6 27 9d e7 49 30 0e 7c 03 |.}u.QF..'..I0.|.|
000001c0 20 14 20 85 82 52 c6 14 62 e5 ca 13 09 24 c8 72 | . ..R..b....$.r|
000001d0 c2 23 8c 3a 2c 30 8e 08 23 c3 19 63 97 1c a7 9f |.#.:,0..#..c....|
000001e0 2c f1 cf c7 8f 87 bd da 8e 66 9e 9b 17 a3 a5 a2 |,........f......|
000001f0 b4 3f 43 41 e8 b3 1c f7 32 dd a1 6c 62 d1 dd 2e |.?CA....2..lb...|
00000200 a5 aa f4 a5 d0 8b d3 bb 5e dd f7 5a f7 d7 7d 75 |........^..Z..}u|
00000210 d7 ad 3d 3d 2d ad 2d 0d 8d 8d 06 eb 6b eb 35 7a |..==-.-.....k.5z|
00000220 7a ba ba 6b bb f4 b4 f4 9f 7a 29 da 1a 0e 55 2a |z..k.....z)...U*|
00000230 a6 35 8a ad 52 b5 a6 b4 ba 2f 4a 5a d4 ee 9d f5 |.5..R..../JZ....|
00000240 d7 a1 45 1b 9b 18 9e 77 9d 24 c0 39 f0 0c 80 50 |..E....w.$.9...P|
00000250 82 16 09 4b 18 51 8b 97 28 4c 24 93 21 cb 08 8e |...K.Q..(L$.!...|
00000260 30 e8 b0 c2 38 20 8f 0c 65 8e 5c 72 9e 7c b3 c7 |0...8 ..e.\r.|..|
00000270 3f 1e 3e 1e f7 6a 39 9a 7a 6c 5e 8e 96 8a d0 fd |?.>..j9.zl^.....|
00000280 0d 07 a2 cc 73 dc cb 76 85 b1 8b 47 74 ba 96 ab |....s..v...Gt...|
00000290 d2 97 42 2f 4e ed 7b 77 dd 6b df 5d f5 d7 5e b4 |..B/N.{w.k.]..^.|
000002a0 f4 f4 b6 b4 b4 36 36 34 1b ad af ac d5 e9 ea ea |.....664........|
000002b0 e9 ae ef d2 d3 d2 7d e8 a7 68 68 39 54 aa 98 d6 |......}..hh9T...|
000002c0 2a b5 4a d6 9a d2 e8 bd 29 6b 53 ba 77 d7 5e ff |*.J.....)kS.w.^.|
000002d0 00 ff d9 |...|
GIMP で変換した画像 (最適化オフ)
00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 02 00 25 |......JFIF.....%|
00000010 00 25 00 00 ff db 00 43 00 01 01 01 01 01 01 01 |.%.....C........|
00000020 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000030 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000040 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000050 01 01 01 01 01 01 01 01 01 ff db 00 43 01 01 01 |............C...|
00000060 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000070 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000080 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000090 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ff c0 |................|
000000a0 00 11 08 00 08 00 18 03 01 11 00 02 11 01 03 11 |................|
000000b0 01 ff c4 00 1f 00 00 01 05 01 01 01 01 01 01 00 |................|
000000c0 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 |................|
000000d0 0a 0b ff c4 00 b5 10 00 02 01 03 03 02 04 03 05 |................|
000000e0 05 04 04 00 00 01 7d 01 02 03 00 04 11 05 12 21 |......}........!|
000000f0 31 41 06 13 51 61 07 22 71 14 32 81 91 a1 08 23 |1A..Qa."q.2....#|
00000100 42 b1 c1 15 52 d1 f0 24 33 62 72 82 09 0a 16 17 |B...R..$3br.....|
00000110 18 19 1a 25 26 27 28 29 2a 34 35 36 37 38 39 3a |...%&'()*456789:|
00000120 43 44 45 46 47 48 49 4a 53 54 55 56 57 58 59 5a |CDEFGHIJSTUVWXYZ|
00000130 63 64 65 66 67 68 69 6a 73 74 75 76 77 78 79 7a |cdefghijstuvwxyz|
00000140 83 84 85 86 87 88 89 8a 92 93 94 95 96 97 98 99 |................|
00000150 9a a2 a3 a4 a5 a6 a7 a8 a9 aa b2 b3 b4 b5 b6 b7 |................|
00000160 b8 b9 ba c2 c3 c4 c5 c6 c7 c8 c9 ca d2 d3 d4 d5 |................|
00000170 d6 d7 d8 d9 da e1 e2 e3 e4 e5 e6 e7 e8 e9 ea f1 |................|
00000180 f2 f3 f4 f5 f6 f7 f8 f9 fa ff c4 00 1f 01 00 03 |................|
00000190 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 |................|
000001a0 02 03 04 05 06 07 08 09 0a 0b ff c4 00 b5 11 00 |................|
000001b0 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00 |..............w.|
000001c0 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 |......!1..AQ.aq.|
000001d0 22 32 81 08 14 42 91 a1 b1 c1 09 23 33 52 f0 15 |"2...B.....#3R..|
000001e0 62 72 d1 0a 16 24 34 e1 25 f1 17 18 19 1a 26 27 |br...$4.%.....&'|
000001f0 28 29 2a 35 36 37 38 39 3a 43 44 45 46 47 48 49 |()*56789:CDEFGHI|
00000200 4a 53 54 55 56 57 58 59 5a 63 64 65 66 67 68 69 |JSTUVWXYZcdefghi|
00000210 6a 73 74 75 76 77 78 79 7a 82 83 84 85 86 87 88 |jstuvwxyz.......|
00000220 89 8a 92 93 94 95 96 97 98 99 9a a2 a3 a4 a5 a6 |................|
00000230 a7 a8 a9 aa b2 b3 b4 b5 b6 b7 b8 b9 ba c2 c3 c4 |................|
00000240 c5 c6 c7 c8 c9 ca d2 d3 d4 d5 d6 d7 d8 d9 da e2 |................|
00000250 e3 e4 e5 e6 e7 e8 e9 ea f2 f3 f4 f5 f6 f7 f8 f9 |................|
00000260 fa ff da 00 0c 03 01 00 02 11 03 11 00 3f 00 fa |.............?..|
00000270 77 45 d1 74 6f 0d e8 da 4f 87 7c 3b a4 e9 9a 07 |wE.to...O.|;....|
00000280 87 f4 0d 32 c3 45 d0 b4 2d 16 c2 d7 4b d1 b4 5d |...2.E..-...K..]|
00000290 1b 4b b5 8a c7 4c d2 74 9d 32 c6 28 2c b4 ed 33 |.K...L.t.2.(,..3|
000002a0 4e b2 82 0b 3b 0b 0b 38 21 b5 b3 b5 86 2b 7b 78 |N...;..8!....+{x|
000002b0 a3 86 34 41 ff 00 2d 38 fc 7e 3b 34 c7 63 33 3c |..4A..-8.~;4.c3<|
000002c0 cf 19 8b cc 73 2c c7 17 88 c7 e6 19 86 3f 11 5b |....s,.......?.[|
000002d0 19 8e c7 e3 b1 95 a7 88 c5 e3 31 98 bc 44 ea 57 |..........1..D.W|
000002e0 c5 62 f1 55 ea 54 af 88 c4 57 a9 3a d5 eb 4e 75 |.b.U.T...W.:..Nu|
000002f0 6a ce 53 94 a4 ff 00 e2 d3 33 cc f3 2c eb 32 cc |j.S......3..,.2.|
00000300 33 8c e3 30 c6 e6 d9 be 6d 8d c5 e6 79 ae 6b 99 |3..0....m...y.k.|
00000310 e2 eb e3 f3 2c cf 32 c7 d7 a9 8a c7 66 19 86 3b |....,.2.....f..;|
00000320 15 52 ae 2b 19 8d c6 62 aa d5 c4 e2 f1 78 9a b5 |.R.+...b.....x..|
00000330 2b e2 2b d4 a9 5a b5 49 d4 9c a4 cd 17 45 d1 bc |+.+..Z.I.....E..|
00000340 37 a3 69 3e 1d f0 ee 93 a6 68 1e 1f d0 34 cb 0d |7.i>.....h...4..|
00000350 17 42 d0 b4 5b 0b 5d 2f 46 d1 74 6d 2e d6 2b 1d |.B..[.]/F.tm..+.|
00000360 33 49 d2 74 cb 18 a0 b2 d3 b4 cd 3a ca 08 2c ec |3I.t.......:..,.|
00000370 2c 2c e0 86 d6 ce d6 18 ad ed e2 8e 18 d1 01 8f |,,..............|
00000380 c7 e3 b3 4c 76 33 33 cc f1 98 bc c7 32 cc 71 78 |...Lv33.....2.qx|
00000390 8c 7e 61 98 63 f1 15 b1 98 ec 7e 3b 19 5a 78 8c |.~a.c.....~;.Zx.|
000003a0 5e 33 19 8b c4 4e a5 7c 56 2f 15 5e a5 4a f8 8c |^3...N.|V/.^.J..|
000003b0 45 7a 93 ad 5e b4 e7 56 ac e5 39 4a 4c cc f3 3c |Ez..^..V..9JL..<|
000003c0 cb 3a cc b3 0c e3 38 cc 31 b9 b6 6f 9b 63 71 79 |.:....8.1..o.cqy|
000003d0 9e 6b 9a e6 78 ba f8 fc cb 33 cc b1 f5 ea 62 b1 |.k..x....3....b.|
000003e0 d9 86 61 8e c5 54 ab 8a c6 63 71 98 aa b5 71 38 |..a..T...cq...q8|
000003f0 bc 5e 26 ad 4a f8 8a f5 2a 56 ad 52 75 27 29 33 |.^&.J...*V.Ru')3|
00000400 45 d1 74 6f 0d e8 da 4f 87 7c 3b a4 e9 9a 07 87 |E.to...O.|;.....|
00000410 f4 0d 32 c3 45 d0 b4 2d 16 c2 d7 4b d1 b4 5d 1b |..2.E..-...K..].|
00000420 4b b5 8a c7 4c d2 74 9d 32 c6 28 2c b4 ed 33 4e |K...L.t.2.(,..3N|
00000430 b2 82 0b 3b 0b 0b 38 21 b5 b3 b5 86 2b 7b 78 a3 |...;..8!....+{x.|
00000440 86 34 40 63 f1 f8 ec d3 1d 8c cc f3 3c 66 2f 31 |.4@c........<f/1|
00000450 cc b3 1c 5e 23 1f 98 66 18 fc 45 6c 66 3b 1f 8e |...^#..f..Elf;..|
00000460 c6 56 9e 23 17 8c c6 62 f1 13 a9 5f 15 8b c5 57 |.V.#...b..._...W|
00000470 a9 52 be 23 11 5e a4 eb 57 ad 39 d5 ab 39 4e 52 |.R.#.^..W.9..9NR|
00000480 93 33 3c cf 32 ce b3 2c c3 38 ce 33 0c 6e 6d 9b |.3<.2..,.8.3.nm.|
00000490 e6 d8 dc 5e 67 9a e6 b9 9e 2e be 3f 32 cc f3 2c |...^g......?2..,|
000004a0 7d 7a 98 ac 76 61 98 63 b1 55 2a e2 b1 98 dc 66 |}z..va.c.U*....f|
000004b0 2a ad 5c 4e 2f 17 89 ab 52 be 22 bd 4a 95 ab 54 |*.\N/...R.".J..T|
000004c0 9d 49 ca 4f ff d9 |.I.O..|
すると、以下のことがわかった。
- ImageMagick で変換した画像と GIMP で変換した画像 (最適化オン) は、全く同じ (SHA-1 ハッシュ値が同じ) である
- ImageMagick の
compare
で比較した結果、GIMP で変換した2種類の画像は同じ内容であり、これらは JTrim で変換した画像とは異なる内容である
確実ではないものの、画像の内容が同じということは、記録されている内容も同じ可能性が高いと考えられる。
そこで、TSXBIN を用いて、GIMP で変換した2種類の画像のハフマン符号テーブル情報を見てみた。
結果は以下である。
0B1 ★DHT[0] FF C4
0B3 SizeOfThis[0] 00 15
0B5 Th 00
0B6 DCHaffman[0] 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0C6 DCHaffman[16] 00 08
0C8 ★DHT[0] FF C4
0CA SizeOfThis[0] 00 19
0CC Th 10
0CD ACHaffman[0] 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00
0DD ACHaffman[16] 05 04 03 06 02 01
0E3 ★DHT[0] FF C4
0E5 SizeOfThis[0] 00 15
0E7 Th 01
0E8 DCHaffman[0] 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0F8 DCHaffman[16] 00 0A
0FA ★DHT[0] FF C4
0FC SizeOfThis[0] 00 18
0FE Th 11
0FF ACHaffman[0] 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00
10F ACHaffman[16] 04 03 05 02 01
0B1 ★DHT[0] FF C4
0B3 SizeOfThis[0] 00 1F
0B5 Th 00
0B6 DCHaffman[0] 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00
0C6 DCHaffman[16] 00 01 02 03 04 05 06 07 08 09 0A 0B
0D2 ★DHT[0] FF C4
0D4 SizeOfThis[0] 00 B5
0D6 Th 10
0D7 ACHaffman[0] 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7D
0E7 ACHaffman[16] 01 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07
0F7 ACHaffman[32] 22 71 14 32 81 91 A1 08 23 42 B1 C1 15 52 D1 F0
107 ACHaffman[48] 24 33 62 72 82 09 0A 16 17 18 19 1A 25 26 27 28
117 ACHaffman[64] 29 2A 34 35 36 37 38 39 3A 43 44 45 46 47 48 49
127 ACHaffman[80] 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69
137 ACHaffman[96] 6A 73 74 75 76 77 78 79 7A 83 84 85 86 87 88 89
147 ACHaffman[112] 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7
157 ACHaffman[128] A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5
167 ACHaffman[144] C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2
177 ACHaffman[160] E3 E4 E5 E6 E7 E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8
187 ACHaffman[176] F9 FA
189 ★DHT[0] FF C4
18B SizeOfThis[0] 00 1F
18D Th 01
18E DCHaffman[0] 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00
19E DCHaffman[16] 00 01 02 03 04 05 06 07 08 09 0A 0B
1AA ★DHT[0] FF C4
1AC SizeOfThis[0] 00 B5
1AE Th 11
1AF ACHaffman[0] 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77
1BF ACHaffman[16] 00 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71
1CF ACHaffman[32] 13 22 32 81 08 14 42 91 A1 B1 C1 09 23 33 52 F0
1DF ACHaffman[48] 15 62 72 D1 0A 16 24 34 E1 25 F1 17 18 19 1A 26
1EF ACHaffman[64] 27 28 29 2A 35 36 37 38 39 3A 43 44 45 46 47 48
1FF ACHaffman[80] 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68
20F ACHaffman[96] 69 6A 73 74 75 76 77 78 79 7A 82 83 84 85 86 87
21F ACHaffman[112] 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5
22F ACHaffman[128] A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3
23F ACHaffman[144] C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA
24F ACHaffman[160] E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8
25F ACHaffman[176] F9 FA
最適化オンのときは、画像データで用いる最低限のデータをハフマン符号テーブルに載せていそうである。
一方、最適化オフのときは、画像データで用いないデータも含む?多くのデータがハフマン符号テーブルに載り、比較的複雑な符号になりそうである。
また、品質を 90 にした場合でも、GIMP の最適化オンとオフで今回変換した画像の内容は変わらなかった。
各符号長の符号が1個ずつしか無いデータの観察
より小さいデータで観察するため、白背景の8x8で左上だけ黒いPNG画像を用意し、GIMP で JPEG に変換した。
なお、普通に変換すると3個のコンポーネントがみられたので、画像を読み込んだあとメニューの「画像 → モード」で「グレースケール」を選択し、変換を行った。
元画像 (PNG)
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 00 08 00 00 00 08 08 06 00 00 00 c4 0f be |................|
00000020 8b 00 00 00 01 73 52 47 42 00 ae ce 1c e9 00 00 |.....sRGB.......|
00000030 00 04 67 41 4d 41 00 00 b1 8f 0b fc 61 05 00 00 |..gAMA......a...|
00000040 00 09 70 48 59 73 00 00 0e c3 00 00 0e c3 01 c7 |..pHYs..........|
00000050 6f a8 64 00 00 00 13 49 44 41 54 28 53 63 60 60 |o.d....IDAT(Sc``|
00000060 60 f8 8f 0f e0 97 1d 36 0a 00 75 9a fc 04 ca 40 |`......6..u....@|
00000070 e7 f3 00 00 00 00 49 45 4e 44 ae 42 60 82 |......IEND.B`.|
GIMP で変換した画像 (最適化オン)
00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 02 00 25 |......JFIF.....%|
00000010 00 25 00 00 ff db 00 43 00 01 01 01 01 01 01 01 |.%.....C........|
00000020 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000030 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000040 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000050 01 01 01 01 01 01 01 01 01 ff c0 00 0b 08 00 08 |................|
00000060 00 08 01 01 11 00 ff c4 00 14 00 01 00 00 00 00 |................|
00000070 00 00 00 00 00 00 00 00 00 00 00 0a ff c4 00 18 |................|
00000080 10 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 |................|
00000090 00 06 05 04 03 02 ff da 00 08 01 01 00 00 3f 00 |..............?.|
000000a0 7b 04 c9 95 04 54 c8 50 a6 4f 8b 12 2c fc 62 63 |{....T.P.O..,.bc|
000000b0 87 13 8d 38 e1 52 65 4e 4e cd 1c f1 93 27 a3 e6 |...8.ReNN....'..|
000000c0 c7 22 09 f8 52 31 e3 97 1a 34 bc 79 67 4b 9d 97 |."..R1...4.ygK..|
000000d0 36 1c 39 b8 66 e1 cb 97 9f ff d9 |6.9.f......|
GIMP で変換した画像 (最適化オフ)
00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 02 00 25 |......JFIF.....%|
00000010 00 25 00 00 ff db 00 43 00 01 01 01 01 01 01 01 |.%.....C........|
00000020 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000030 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000040 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000050 01 01 01 01 01 01 01 01 01 ff c0 00 0b 08 00 08 |................|
00000060 00 08 01 01 11 00 ff c4 00 1f 00 00 01 05 01 01 |................|
00000070 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 |................|
00000080 05 06 07 08 09 0a 0b ff c4 00 b5 10 00 02 01 03 |................|
00000090 03 02 04 03 05 05 04 04 00 00 01 7d 01 02 03 00 |...........}....|
000000a0 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 |....!1A..Qa."q.2|
000000b0 81 91 a1 08 23 42 b1 c1 15 52 d1 f0 24 33 62 72 |....#B...R..$3br|
000000c0 82 09 0a 16 17 18 19 1a 25 26 27 28 29 2a 34 35 |........%&'()*45|
000000d0 36 37 38 39 3a 43 44 45 46 47 48 49 4a 53 54 55 |6789:CDEFGHIJSTU|
000000e0 56 57 58 59 5a 63 64 65 66 67 68 69 6a 73 74 75 |VWXYZcdefghijstu|
000000f0 76 77 78 79 7a 83 84 85 86 87 88 89 8a 92 93 94 |vwxyz...........|
00000100 95 96 97 98 99 9a a2 a3 a4 a5 a6 a7 a8 a9 aa b2 |................|
00000110 b3 b4 b5 b6 b7 b8 b9 ba c2 c3 c4 c5 c6 c7 c8 c9 |................|
00000120 ca d2 d3 d4 d5 d6 d7 d8 d9 da e1 e2 e3 e4 e5 e6 |................|
00000130 e7 e8 e9 ea f1 f2 f3 f4 f5 f6 f7 f8 f9 fa ff da |................|
00000140 00 08 01 01 00 00 3f 00 fe f6 3c 27 e1 3f 0a f8 |......?...<'.?..|
00000150 0b c2 be 19 f0 2f 81 7c 33 e1 ff 00 05 f8 27 c1 |...../.|3.....'.|
00000160 7e 1f d1 bc 27 e0 ef 07 78 4f 46 d3 bc 39 e1 5f |~...'...xOF..9._|
00000170 09 f8 57 c3 9a 75 b6 8f e1 ef 0c f8 67 c3 da 3d |..W..u......g..=|
00000180 b5 9e 91 a0 f8 7f 42 d2 2c ec f4 bd 1b 46 d2 ec |......B.,....F..|
00000190 ed 74 ed 2f 4e b5 b6 b1 b1 b6 82 da 08 a2 5f ff |.t./N........._.|
000001a0 d9 |.|
最適化オンのハフマン符号情報と圧縮データ (一部) は、以下のようになっていた。
66 ★DHT[0] FF C4
68 SizeOfThis[0] 00 14
6A Th 00
6B DCHaffman[0] 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
7B DCHaffman[16] 0A
7C ★DHT[0] FF C4
7E SizeOfThis[0] 00 18
80 Th 10
81 ACHaffman[0] 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00
91 ACHaffman[16] 06 05 04 03 02
A0 圧縮データ(57B)[0] 7B 04 C9 95 04 54 C8 50 A6 4F 8B 12 2C FC 62 63
最適化オフでは、以下のようになっていた。
066 ★DHT[0] FF C4
068 SizeOfThis[0] 00 1F
06A Th 00
06B DCHaffman[0] 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00
07B DCHaffman[16] 00 01 02 03 04 05 06 07 08 09 0A 0B
087 ★DHT[0] FF C4
089 SizeOfThis[0] 00 B5
08B Th 10
08C ACHaffman[0] 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7D
09C ACHaffman[16] 01 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07
0AC ACHaffman[32] 22 71 14 32 81 91 A1 08 23 42 B1 C1 15 52 D1 F0
0BC ACHaffman[48] 24 33 62 72 82 09 0A 16 17 18 19 1A 25 26 27 28
0CC ACHaffman[64] 29 2A 34 35 36 37 38 39 3A 43 44 45 46 47 48 49
0DC ACHaffman[80] 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69
0EC ACHaffman[96] 6A 73 74 75 76 77 78 79 7A 83 84 85 86 87 88 89
0FC ACHaffman[112] 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7
10C ACHaffman[128] A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5
11C ACHaffman[144] C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2
12C ACHaffman[160] E3 E4 E5 E6 E7 E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8
13C ACHaffman[176] F9 FA
148 圧縮データ(87B)[0] FE F6 3C 27 E1 3F 0A F8 0B C2 BE 19 F0 2F 81 7C
最適化オンのデータにおいて、各長さの符号の数が全て 0 または 1 となっている。
deflate と同様のハフマン符号が用いられていると仮定すれば、このとき、符号は 0
、10
、110
、… のように、全て「1
が何個か続き、最後に1個 0
」のパターンになるはずである。
そのため、解析しやすそうである。
deflate と同様のハフマン符号が用いられていると仮定すれば、それぞれの画像におけるデータと符号の関係は、以下のようになる。
テーブル | データ | 最適化オン | 最適化オフ |
---|---|---|---|
DC | 0A |
0 |
11111110 |
AC | 02 |
11110 |
01 |
AC | 03 |
1110 |
100 |
AC | 04 |
110 |
1011 |
AC | 05 |
10 |
11010 |
AC | 06 |
0 |
1111000 |
さらに、CyberChef を用いて、圧縮データを 0/1 で表したものを 0 で区切ってみた。
Find / Replace, 3 more - CyberChef
この Recipe では、圧縮データ FF
を FF 00
で表すことは考慮していない。
今回は、手動でこの 00
を削除する対応をとった。
結果の冒頭は、以下のようになった。
最適化オン | 最適化オフ |
---|---|
0 11110 110 0 0 0 0 10 0 110 |
11111110 11110 110 0 0 11110 0 0 0 10 |
1行目は、最適化オンが 0
、最適化オフが 11111110
で、これはそれぞれのデータ 0A
に対応する DC 用ハフマン符号のようである。
しかし、その後のデータはよくわからなかった。
更に、今回の最適化オンの画像におけるハフマン符号は5ビットまでのはずであるにもかかわらず、1111110
(上記圧縮データの冒頭の FC
の部分に相当する) など6ビット以上の符号のようなものもみられた。
単純なハフマン符号ではないかもしれない……?
ググレカス
自分の頭だけで考えていても、らちがあかなそうなので、「jpeg ハフマン符号」でググってみた。
すると、以下のページが見つかった。
- JPEGのハフマン符号 (1) DC成分 - Tech と Culture
- JPEGのハフマン符号 (2) AC成分 - Tech と Culture
- JPEGのハフマン符号 (3) ハフマンテーブルの記述 - Tech と Culture
- JPEGのハフマン符号 (4) デコード用 ハフマン符号テーブルの生成 - Tech と Culture
これらのページを読むことで、以下のことがわかった。
- DC 成分は、「符号の後に何ビット追加するか」を符号で表す
- AC 成分は、「その符号が表すデータの前に
0
のデータがいくつあるか」と「符号の後に何ビット追加するか」の組を符号で表す - それぞれ、符号の後に実際に追加するビット数分のビットを置く
- AC 成分のデータは、全部で 63 個になるようにする
- ただし、「これ以降のデータは全部
0
」(EOB) を表す符号を用いることもある
- ただし、「これ以降のデータは全部
- ハフマン符号情報 (符号長ごとの符号数) からハフマン符号を構築する方法は、予想通り deflate で行う方法に近い
たとえば、先ほどの例においては、1行目で「追加データ10ビット」を表し、2~5行目の
11110
110
0
0
の部分がその追加データであると考えられそうである。
ハフマン符号の構築方法だけでなく、ハフマン符号に続けて追加のビット列を置く、という構造も、deflate に似ている。
最適化オフの画像における AC ハフマン符号のテーブルでは、多くのバイトが網羅されていそうであるにもかかわらず、なぜ FF
ではなく FA
までなのかが疑問だった。
しかし、この情報をもとに、
- 上位ニブル (4ビット) が、データの前に置く
0
の数を表す - 下位ニブルが、符号の後に追加するビット数を表す
と仮定すれば、辻褄が合いそうである。
「ハフマン符号の後に追加のデータが配置される」ことがわかれば、圧縮データ内に符号としてはおかしいデータがあったこともうなづける。
とはいえ、これだけでは DC 用ハフマン符号と AC 用ハフマン符号をどう使い分けるかがわからない。
詳細な情報を可視化してくれるソフトウェア
上記サイトで言及されていた「jpegsnoop」は、以下のソフトウェアを表すと思われる。
GitHub - ImpulseAdventure/JPEGsnoop: JPEGsnoop: JPEG decoder and detailed analysis
メニューの「Options → Scan Segment → Detailed Decode...」からダイアログを開き、「Enable detailed Scan Decode?」をオンにした状態で解析を行うことで、圧縮データをハフマン符号と追加データに分解して出力してくれる。
設定を変更したら、メニューの「File → Reprocess File」を押すことで、開いているファイルを新しい設定で再解析してくれる。
以下の結果が得られた。
圧縮データの分解結果 (最適化オン)
Lum (Tbl #0), MCU=[0,0]
[0x000000A0.0]: ZRL=[ 0] Val=[ 984] Coef=[00= DC] Data=[0x 7B 04 C9 95 = 0b (01111011 000----- -------- --------)]
[0x000000A1.3]: ZRL=[ 0] Val=[ -44] Coef=[01..01] Data=[0x 04 C9 95 04 = 0b (---00100 11------ -------- --------)]
[0x000000A2.2]: ZRL=[ 0] Val=[ -44] Coef=[02..02] Data=[0x C9 95 04 54 = 0b (--001001 1------- -------- --------)]
[0x000000A3.1]: ZRL=[ 0] Val=[ -42] Coef=[03..03] Data=[0x 95 04 54 C8 = 0b (-0010101 -------- -------- --------)]
[0x000000A4.0]: ZRL=[ 0] Val=[ -61] Coef=[04..04] Data=[0x 04 54 C8 50 = 0b (0000010- -------- -------- --------)]
[0x000000A4.7]: ZRL=[ 0] Val=[ -42] Coef=[05..05] Data=[0x 04 54 C8 50 = 0b (-------0 010101-- -------- --------)]
[0x000000A5.6]: ZRL=[ 0] Val=[ -38] Coef=[06..06] Data=[0x 54 C8 50 A6 = 0b (------00 11001--- -------- --------)]
[0x000000A6.5]: ZRL=[ 0] Val=[ -58] Coef=[07..07] Data=[0x C8 50 A6 4F = 0b (-----000 0101---- -------- --------)]
[0x000000A7.4]: ZRL=[ 0] Val=[ -58] Coef=[08..08] Data=[0x 50 A6 4F 8B = 0b (----0000 101----- -------- --------)]
[0x000000A8.3]: ZRL=[ 0] Val=[ -38] Coef=[09..09] Data=[0x A6 4F 8B 12 = 0b (---00110 01------ -------- --------)]
[0x000000A9.2]: ZRL=[ 0] Val=[ -32] Coef=[10..10] Data=[0x 4F 8B 12 2C = 0b (--001111 1------- -------- --------)]
[0x000000AA.1]: ZRL=[ 0] Val=[ -52] Coef=[11..11] Data=[0x 8B 12 2C FC = 0b (-0001011 -------- -------- --------)]
[0x000000AB.0]: ZRL=[ 0] Val=[ -54] Coef=[12..12] Data=[0x 12 2C FC 62 = 0b (0001001- -------- -------- --------)]
[0x000000AB.7]: ZRL=[ 0] Val=[ -52] Coef=[13..13] Data=[0x 12 2C FC 62 = 0b (-------0 001011-- -------- --------)]
[0x000000AC.6]: ZRL=[ 0] Val=[ -32] Coef=[14..14] Data=[0x 2C FC 62 63 = 0b (------00 11111--- -------- --------)]
[0x000000AD.5]: ZRL=[ 0] Val=[ -25] Coef=[15..15] Data=[0x FC 62 63 87 = 0b (-----100 0110---- -------- --------)]
[0x000000AE.4]: ZRL=[ 0] Val=[ -44] Coef=[16..16] Data=[0x 62 63 87 13 = 0b (----0010 011----- -------- --------)]
[0x000000AF.3]: ZRL=[ 0] Val=[ -49] Coef=[17..17] Data=[0x 63 87 13 8D = 0b (---00011 10------ -------- --------)]
[0x000000B0.2]: ZRL=[ 0] Val=[ -49] Coef=[18..18] Data=[0x 87 13 8D 38 = 0b (--000111 0------- -------- --------)]
[0x000000B1.1]: ZRL=[ 0] Val=[ -44] Coef=[19..19] Data=[0x 13 8D 38 E1 = 0b (-0010011 -------- -------- --------)]
[0x000000B2.0]: ZRL=[ 0] Val=[ -25] Coef=[20..20] Data=[0x 8D 38 E1 52 = 0b (1000110- -------- -------- --------)]
[0x000000B2.7]: ZRL=[ 0] Val=[ -17] Coef=[21..21] Data=[0x 8D 38 E1 52 = 0b (-------1 001110-- -------- --------)]
[0x000000B3.6]: ZRL=[ 0] Val=[ -35] Coef=[22..22] Data=[0x 38 E1 52 65 = 0b (------00 11100--- -------- --------)]
[0x000000B4.5]: ZRL=[ 0] Val=[ -42] Coef=[23..23] Data=[0x E1 52 65 4E = 0b (-----001 0101---- -------- --------)]
[0x000000B5.4]: ZRL=[ 0] Val=[ -44] Coef=[24..24] Data=[0x 52 65 4E 4E = 0b (----0010 011----- -------- --------)]
[0x000000B6.3]: ZRL=[ 0] Val=[ -42] Coef=[25..25] Data=[0x 65 4E 4E CD = 0b (---00101 01------ -------- --------)]
[0x000000B7.2]: ZRL=[ 0] Val=[ -35] Coef=[26..26] Data=[0x 4E 4E CD 1C = 0b (--001110 0------- -------- --------)]
[0x000000B8.1]: ZRL=[ 0] Val=[ -17] Coef=[27..27] Data=[0x 4E CD 1C F1 = 0b (-1001110 -------- -------- --------)]
[0x000000B9.0]: ZRL=[ 0] Val=[ -9] Coef=[28..28] Data=[0x CD 1C F1 93 = 0b (1100110- -------- -------- --------)]
[0x000000B9.7]: ZRL=[ 0] Val=[ -24] Coef=[29..29] Data=[0x CD 1C F1 93 = 0b (-------1 000111-- -------- --------)]
[0x000000BA.6]: ZRL=[ 0] Val=[ -33] Coef=[30..30] Data=[0x 1C F1 93 27 = 0b (------00 11110--- -------- --------)]
[0x000000BB.5]: ZRL=[ 0] Val=[ -38] Coef=[31..31] Data=[0x F1 93 27 A3 = 0b (-----001 1001---- -------- --------)]
[0x000000BC.4]: ZRL=[ 0] Val=[ -38] Coef=[32..32] Data=[0x 93 27 A3 E6 = 0b (----0011 001----- -------- --------)]
[0x000000BD.3]: ZRL=[ 0] Val=[ -33] Coef=[33..33] Data=[0x 27 A3 E6 C7 = 0b (---00111 10------ -------- --------)]
[0x000000BE.2]: ZRL=[ 0] Val=[ -24] Coef=[34..34] Data=[0x A3 E6 C7 22 = 0b (--100011 1------- -------- --------)]
[0x000000BF.1]: ZRL=[ 0] Val=[ -9] Coef=[35..35] Data=[0x E6 C7 22 09 = 0b (-1100110 -------- -------- --------)]
[0x000000C0.0]: ZRL=[ 0] Val=[ -12] Coef=[36..36] Data=[0x C7 22 09 F8 = 0b (1100011- -------- -------- --------)]
[0x000000C0.7]: ZRL=[ 0] Val=[ -23] Coef=[37..37] Data=[0x C7 22 09 F8 = 0b (-------1 001000-- -------- --------)]
[0x000000C1.6]: ZRL=[ 0] Val=[ -30] Coef=[38..38] Data=[0x 22 09 F8 52 = 0b (------10 00001--- -------- --------)]
[0x000000C2.5]: ZRL=[ 0] Val=[ -32] Coef=[39..39] Data=[0x 09 F8 52 31 = 0b (-----001 1111---- -------- --------)]
[0x000000C3.4]: ZRL=[ 0] Val=[ -29] Coef=[40..40] Data=[0x F8 52 31 E3 = 0b (----1000 010----- -------- --------)]
[0x000000C4.3]: ZRL=[ 0] Val=[ -23] Coef=[41..41] Data=[0x 52 31 E3 97 = 0b (---10010 00------ -------- --------)]
[0x000000C5.2]: ZRL=[ 0] Val=[ -12] Coef=[42..42] Data=[0x 31 E3 97 1A = 0b (--110001 1------- -------- --------)]
[0x000000C6.1]: ZRL=[ 0] Val=[ -12] Coef=[43..43] Data=[0x E3 97 1A 34 = 0b (-1100011 -------- -------- --------)]
[0x000000C7.0]: ZRL=[ 0] Val=[ -20] Coef=[44..44] Data=[0x 97 1A 34 BC = 0b (1001011- -------- -------- --------)]
[0x000000C7.7]: ZRL=[ 0] Val=[ -25] Coef=[45..45] Data=[0x 97 1A 34 BC = 0b (-------1 000110-- -------- --------)]
[0x000000C8.6]: ZRL=[ 0] Val=[ -25] Coef=[46..46] Data=[0x 1A 34 BC 79 = 0b (------10 00110--- -------- --------)]
[0x000000C9.5]: ZRL=[ 0] Val=[ -20] Coef=[47..47] Data=[0x 34 BC 79 67 = 0b (-----100 1011---- -------- --------)]
[0x000000CA.4]: ZRL=[ 0] Val=[ -12] Coef=[48..48] Data=[0x BC 79 67 4B = 0b (----1100 011----- -------- --------)]
[0x000000CB.3]: ZRL=[ 0] Val=[ -10] Coef=[49..49] Data=[0x 79 67 4B 9D = 0b (---11001 01------ -------- --------)]
[0x000000CC.2]: ZRL=[ 0] Val=[ -17] Coef=[50..50] Data=[0x 67 4B 9D 97 = 0b (--100111 0------- -------- --------)]
[0x000000CD.1]: ZRL=[ 0] Val=[ -20] Coef=[51..51] Data=[0x 4B 9D 97 36 = 0b (-1001011 -------- -------- --------)]
[0x000000CE.0]: ZRL=[ 0] Val=[ -17] Coef=[52..52] Data=[0x 9D 97 36 1C = 0b (1001110- -------- -------- --------)]
[0x000000CE.7]: ZRL=[ 0] Val=[ -10] Coef=[53..53] Data=[0x 9D 97 36 1C = 0b (-------1 100101-- -------- --------)]
[0x000000CF.6]: ZRL=[ 0] Val=[ -9] Coef=[54..54] Data=[0x 97 36 1C 39 = 0b (------11 00110--- -------- --------)]
[0x000000D0.5]: ZRL=[ 0] Val=[ -14] Coef=[55..55] Data=[0x 36 1C 39 B8 = 0b (-----110 0001---- -------- --------)]
[0x000000D1.4]: ZRL=[ 0] Val=[ -14] Coef=[56..56] Data=[0x 1C 39 B8 66 = 0b (----1100 001----- -------- --------)]
[0x000000D2.3]: ZRL=[ 0] Val=[ -9] Coef=[57..57] Data=[0x 39 B8 66 E1 = 0b (---11001 10------ -------- --------)]
[0x000000D3.2]: ZRL=[ 0] Val=[ -7] Coef=[58..58] Data=[0x B8 66 E1 CB = 0b (--111000 0------- -------- --------)]
[0x000000D4.1]: ZRL=[ 0] Val=[ -9] Coef=[59..59] Data=[0x 66 E1 CB 97 = 0b (-1100110 -------- -------- --------)]
[0x000000D5.0]: ZRL=[ 0] Val=[ -7] Coef=[60..60] Data=[0x E1 CB 97 9F = 0b (1110000- -------- -------- --------)]
Scan Data encountered marker 0xFFD9 @ 0x000000D9.0
[0x000000D5.7]: ZRL=[ 0] Val=[ -5] Coef=[61..61] Data=[0x E1 CB 97 9F = 0b (-------1 110010-- -------- --------)]
[0x000000D6.6]: ZRL=[ 0] Val=[ -5] Coef=[62..62] Data=[0x CB 97 9F FF = 0b (------11 10010--- -------- --------)]
[0x000000D7.5]: ZRL=[ 0] Val=[ -2] Coef=[63..63] Data=[0x 97 9F FF D9 = 0b (-----111 1001---- -------- --------)] EOB64
DCT Matrix=[ 984 -44 -42 -38 -32 -25 -17 -9]
[ -44 -61 -58 -52 -44 -35 -24 -12]
[ -42 -58 -54 -49 -42 -33 -23 -12]
[ -38 -52 -49 -44 -38 -29 -20 -10]
[ -32 -44 -42 -38 -32 -25 -17 -9]
[ -25 -35 -33 -30 -25 -20 -14 -7]
[ -17 -24 -23 -20 -17 -14 -9 -5]
[ -9 -12 -12 -10 -9 -7 -5 -2]
圧縮データの分解結果 (最適化オフ)
Lum (Tbl #0), MCU=[0,0]
[0x00000148.0]: ZRL=[ 0] Val=[ 984] Coef=[00= DC] Data=[0x FE F6 3C 27 = 0b (11111110 11110110 00------ --------)]
[0x0000014A.2]: ZRL=[ 0] Val=[ -44] Coef=[01..01] Data=[0x 3C 27 E1 3F = 0b (--111100 0010011- -------- --------)]
[0x0000014B.7]: ZRL=[ 0] Val=[ -44] Coef=[02..02] Data=[0x 27 E1 3F 0A = 0b (-------1 11100001 0011---- --------)]
[0x0000014D.4]: ZRL=[ 0] Val=[ -42] Coef=[03..03] Data=[0x 3F 0A F8 0B = 0b (----1111 00001010 1------- --------)]
[0x0000014F.1]: ZRL=[ 0] Val=[ -61] Coef=[04..04] Data=[0x F8 0B C2 BE = 0b (-1111000 000010-- -------- --------)]
[0x00000150.6]: ZRL=[ 0] Val=[ -42] Coef=[05..05] Data=[0x 0B C2 BE 19 = 0b (------11 11000010 101----- --------)]
[0x00000152.3]: ZRL=[ 0] Val=[ -38] Coef=[06..06] Data=[0x BE 19 F0 2F = 0b (---11110 00011001 -------- --------)]
[0x00000154.0]: ZRL=[ 0] Val=[ -58] Coef=[07..07] Data=[0x F0 2F 81 7C = 0b (11110000 00101--- -------- --------)]
[0x00000155.5]: ZRL=[ 0] Val=[ -58] Coef=[08..08] Data=[0x 2F 81 7C 33 = 0b (-----111 10000001 01------ --------)]
[0x00000157.2]: ZRL=[ 0] Val=[ -38] Coef=[09..09] Data=[0x 7C 33 E1 FF = 0b (--111100 0011001- -------- --------)]
[0x00000158.7]: ZRL=[ 0] Val=[ -32] Coef=[10..10] Data=[0x 33 E1 FF 05 = 0b (-------1 11100001 1111---- --------)]
[0x0000015A.4]: ZRL=[ 0] Val=[ -52] Coef=[11..11] Data=[0x FF 05 F8 27 = 0b (----1111 00000101 1------- --------)]
[0x0000015D.1]: ZRL=[ 0] Val=[ -54] Coef=[12..12] Data=[0x F8 27 C1 7E = 0b (-1111000 001001-- -------- --------)]
[0x0000015E.6]: ZRL=[ 0] Val=[ -52] Coef=[13..13] Data=[0x 27 C1 7E 1F = 0b (------11 11000001 011----- --------)]
[0x00000160.3]: ZRL=[ 0] Val=[ -32] Coef=[14..14] Data=[0x 7E 1F D1 BC = 0b (---11110 00011111 -------- --------)]
[0x00000162.0]: ZRL=[ 0] Val=[ -25] Coef=[15..15] Data=[0x D1 BC 27 E0 = 0b (11010001 10------ -------- --------)]
[0x00000163.2]: ZRL=[ 0] Val=[ -44] Coef=[16..16] Data=[0x BC 27 E0 EF = 0b (--111100 0010011- -------- --------)]
[0x00000164.7]: ZRL=[ 0] Val=[ -49] Coef=[17..17] Data=[0x 27 E0 EF 07 = 0b (-------1 11100000 1110---- --------)]
[0x00000166.4]: ZRL=[ 0] Val=[ -49] Coef=[18..18] Data=[0x EF 07 78 4F = 0b (----1111 00000111 0------- --------)]
[0x00000168.1]: ZRL=[ 0] Val=[ -44] Coef=[19..19] Data=[0x 78 4F 46 D3 = 0b (-1111000 010011-- -------- --------)]
[0x00000169.6]: ZRL=[ 0] Val=[ -25] Coef=[20..20] Data=[0x 4F 46 D3 BC = 0b (------11 01000110 -------- --------)]
[0x0000016B.0]: ZRL=[ 0] Val=[ -17] Coef=[21..21] Data=[0x D3 BC 39 E1 = 0b (11010011 10------ -------- --------)]
[0x0000016C.2]: ZRL=[ 0] Val=[ -35] Coef=[22..22] Data=[0x BC 39 E1 5F = 0b (--111100 0011100- -------- --------)]
[0x0000016D.7]: ZRL=[ 0] Val=[ -42] Coef=[23..23] Data=[0x 39 E1 5F 09 = 0b (-------1 11100001 0101---- --------)]
[0x0000016F.4]: ZRL=[ 0] Val=[ -44] Coef=[24..24] Data=[0x 5F 09 F8 57 = 0b (----1111 00001001 1------- --------)]
[0x00000171.1]: ZRL=[ 0] Val=[ -42] Coef=[25..25] Data=[0x F8 57 C3 9A = 0b (-1111000 010101-- -------- --------)]
[0x00000172.6]: ZRL=[ 0] Val=[ -35] Coef=[26..26] Data=[0x 57 C3 9A 75 = 0b (------11 11000011 100----- --------)]
[0x00000174.3]: ZRL=[ 0] Val=[ -17] Coef=[27..27] Data=[0x 9A 75 B6 8F = 0b (---11010 01110--- -------- --------)]
[0x00000175.5]: ZRL=[ 0] Val=[ -9] Coef=[28..28] Data=[0x 75 B6 8F E1 = 0b (-----101 10110--- -------- --------)]
[0x00000176.5]: ZRL=[ 0] Val=[ -24] Coef=[29..29] Data=[0x B6 8F E1 EF = 0b (-----110 1000111- -------- --------)]
[0x00000177.7]: ZRL=[ 0] Val=[ -33] Coef=[30..30] Data=[0x 8F E1 EF 0C = 0b (-------1 11100001 1110---- --------)]
[0x00000179.4]: ZRL=[ 0] Val=[ -38] Coef=[31..31] Data=[0x EF 0C F8 67 = 0b (----1111 00001100 1------- --------)]
[0x0000017B.1]: ZRL=[ 0] Val=[ -38] Coef=[32..32] Data=[0x F8 67 C3 DA = 0b (-1111000 011001-- -------- --------)]
[0x0000017C.6]: ZRL=[ 0] Val=[ -33] Coef=[33..33] Data=[0x 67 C3 DA 3D = 0b (------11 11000011 110----- --------)]
[0x0000017E.3]: ZRL=[ 0] Val=[ -24] Coef=[34..34] Data=[0x DA 3D B5 9E = 0b (---11010 00111--- -------- --------)]
[0x0000017F.5]: ZRL=[ 0] Val=[ -9] Coef=[35..35] Data=[0x 3D B5 9E 91 = 0b (-----101 10110--- -------- --------)]
[0x00000180.5]: ZRL=[ 0] Val=[ -12] Coef=[36..36] Data=[0x B5 9E 91 A0 = 0b (-----101 10011--- -------- --------)]
[0x00000181.5]: ZRL=[ 0] Val=[ -23] Coef=[37..37] Data=[0x 9E 91 A0 F8 = 0b (-----110 1001000- -------- --------)]
[0x00000182.7]: ZRL=[ 0] Val=[ -30] Coef=[38..38] Data=[0x 91 A0 F8 7F = 0b (-------1 10100000 1------- --------)]
[0x00000184.1]: ZRL=[ 0] Val=[ -32] Coef=[39..39] Data=[0x F8 7F 42 D2 = 0b (-1111000 011111-- -------- --------)]
[0x00000185.6]: ZRL=[ 0] Val=[ -29] Coef=[40..40] Data=[0x 7F 42 D2 2C = 0b (------11 01000010 -------- --------)]
[0x00000187.0]: ZRL=[ 0] Val=[ -23] Coef=[41..41] Data=[0x D2 2C EC F4 = 0b (11010010 00------ -------- --------)]
[0x00000188.2]: ZRL=[ 0] Val=[ -12] Coef=[42..42] Data=[0x 2C EC F4 BD = 0b (--101100 11------ -------- --------)]
[0x00000189.2]: ZRL=[ 0] Val=[ -12] Coef=[43..43] Data=[0x EC F4 BD 1B = 0b (--101100 11------ -------- --------)]
[0x0000018A.2]: ZRL=[ 0] Val=[ -20] Coef=[44..44] Data=[0x F4 BD 1B 46 = 0b (--110100 1011---- -------- --------)]
[0x0000018B.4]: ZRL=[ 0] Val=[ -25] Coef=[45..45] Data=[0x BD 1B 46 D2 = 0b (----1101 000110-- -------- --------)]
[0x0000018C.6]: ZRL=[ 0] Val=[ -25] Coef=[46..46] Data=[0x 1B 46 D2 EC = 0b (------11 01000110 -------- --------)]
[0x0000018E.0]: ZRL=[ 0] Val=[ -20] Coef=[47..47] Data=[0x D2 EC ED 74 = 0b (11010010 11------ -------- --------)]
[0x0000018F.2]: ZRL=[ 0] Val=[ -12] Coef=[48..48] Data=[0x EC ED 74 ED = 0b (--101100 11------ -------- --------)]
[0x00000190.2]: ZRL=[ 0] Val=[ -10] Coef=[49..49] Data=[0x ED 74 ED 2F = 0b (--101101 01------ -------- --------)]
[0x00000191.2]: ZRL=[ 0] Val=[ -17] Coef=[50..50] Data=[0x 74 ED 2F 4E = 0b (--110100 1110---- -------- --------)]
[0x00000192.4]: ZRL=[ 0] Val=[ -20] Coef=[51..51] Data=[0x ED 2F 4E B5 = 0b (----1101 001011-- -------- --------)]
[0x00000193.6]: ZRL=[ 0] Val=[ -17] Coef=[52..52] Data=[0x 2F 4E B5 B6 = 0b (------11 01001110 -------- --------)]
[0x00000195.0]: ZRL=[ 0] Val=[ -10] Coef=[53..53] Data=[0x B5 B6 B1 B1 = 0b (10110101 -------- -------- --------)]
[0x00000196.0]: ZRL=[ 0] Val=[ -9] Coef=[54..54] Data=[0x B6 B1 B1 B6 = 0b (10110110 -------- -------- --------)]
[0x00000197.0]: ZRL=[ 0] Val=[ -14] Coef=[55..55] Data=[0x B1 B1 B6 82 = 0b (10110001 -------- -------- --------)]
[0x00000198.0]: ZRL=[ 0] Val=[ -14] Coef=[56..56] Data=[0x B1 B6 82 DA = 0b (10110001 -------- -------- --------)]
[0x00000199.0]: ZRL=[ 0] Val=[ -9] Coef=[57..57] Data=[0x B6 82 DA 08 = 0b (10110110 -------- -------- --------)]
[0x0000019A.0]: ZRL=[ 0] Val=[ -7] Coef=[58..58] Data=[0x 82 DA 08 A2 = 0b (100000-- -------- -------- --------)]
[0x0000019A.6]: ZRL=[ 0] Val=[ -9] Coef=[59..59] Data=[0x 82 DA 08 A2 = 0b (------10 110110-- -------- --------)]
Scan Data encountered marker 0xFFD9 @ 0x0000019F.0
[0x0000019B.6]: ZRL=[ 0] Val=[ -7] Coef=[60..60] Data=[0x DA 08 A2 5F = 0b (------10 0000---- -------- --------)]
[0x0000019C.4]: ZRL=[ 0] Val=[ -5] Coef=[61..61] Data=[0x 08 A2 5F FF = 0b (----1000 10------ -------- --------)]
[0x0000019D.2]: ZRL=[ 0] Val=[ -5] Coef=[62..62] Data=[0x A2 5F FF D9 = 0b (--100010 -------- -------- --------)]
[0x0000019E.0]: ZRL=[ 0] Val=[ -2] Coef=[63..63] Data=[0x 5F FF D9 00 = 0b (0101---- -------- -------- --------)] EOB64
DCT Matrix=[ 984 -44 -42 -38 -32 -25 -17 -9]
[ -44 -61 -58 -52 -44 -35 -24 -12]
[ -42 -58 -54 -49 -42 -33 -23 -12]
[ -38 -52 -49 -44 -38 -29 -20 -10]
[ -32 -44 -42 -38 -32 -25 -17 -9]
[ -25 -35 -33 -30 -25 -20 -14 -7]
[ -17 -24 -23 -20 -17 -14 -9 -5]
[ -9 -12 -12 -10 -9 -7 -5 -2]
これから、以下のことが読み取れる。
- ブロック内の最初のデータのみ DC で、残りは AC である
- 最適化オンと最適化オフで、(少なくとも今回のデータでは) 異なるエンコードで同じ DCT Matrix が表されている
- 圧縮データにハフマン符号と追加データ以外のヘッダやフッタなどは含まれていなそうである
さらに、24×8の緑一色の画像も解析してみた。
24×8の緑一色の画像
00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 60 |......JFIF.....`|
00000010 00 60 00 00 ff e1 00 22 45 78 69 66 00 00 4d 4d |.`....."Exif..MM|
00000020 00 2a 00 00 00 08 00 01 01 12 00 03 00 00 00 01 |.*..............|
00000030 00 01 00 00 00 00 00 00 ff db 00 43 00 02 01 01 |...........C....|
00000040 02 01 01 02 02 02 02 02 02 02 02 03 05 03 03 03 |................|
00000050 03 03 06 04 04 03 05 07 06 07 07 07 06 07 07 08 |................|
00000060 09 0b 09 08 08 0a 08 07 07 0a 0d 0a 0a 0b 0c 0c |................|
00000070 0c 0c 07 09 0e 0f 0d 0c 0e 0b 0c 0c 0c ff db 00 |................|
00000080 43 01 02 02 02 03 03 03 06 03 03 06 0c 08 07 08 |C...............|
00000090 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c |................|
000000a0 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c |................|
000000b0 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c |................|
000000c0 0c 0c ff c0 00 11 08 00 08 00 18 03 01 22 00 02 |............."..|
000000d0 11 01 03 11 01 ff c4 00 15 00 01 01 00 00 00 00 |................|
000000e0 00 00 00 00 00 00 00 00 00 00 00 07 ff c4 00 14 |................|
000000f0 10 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000100 00 00 ff c4 00 15 01 01 01 00 00 00 00 00 00 00 |................|
00000110 00 00 00 00 00 00 00 00 09 ff c4 00 14 11 01 00 |................|
00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff |................|
00000130 da 00 0c 03 01 00 02 11 03 11 00 3f 00 ac 00 95 |...........?....|
00000140 e8 a6 00 0f ff d9 |......|
この画像のハフマン符号情報と圧縮データは、以下である。
0D5 ★DHT[0] FF C4
0D7 SizeOfThis[0] 00 15
0D9 Th 00
0DA DCHaffman[0] 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0EA DCHaffman[16] 00 07
0EC ★DHT[0] FF C4
0EE SizeOfThis[0] 00 14
0F0 Th 10
0F1 ACHaffman[0] 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
101 ACHaffman[16] 00
102 ★DHT[0] FF C4
104 SizeOfThis[0] 00 15
106 Th 01
107 DCHaffman[0] 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
117 DCHaffman[16] 00 09
119 ★DHT[0] FF C4
11B SizeOfThis[0] 00 14
11D Th 11
11E ACHaffman[0] 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
12E ACHaffman[16] 00
13D 圧縮データ(7B)[0] AC 00 95 E8 A6 00 0F
24×8の緑一色の画像の圧縮データの分解結果
Lum (Tbl #0), MCU=[0,0]
[0x0000013D.0]: ZRL=[ 0] Val=[ 88] Coef=[00= DC] Data=[0x AC 00 95 E8 = 0b (10101100 0------- -------- --------)]
[0x0000013E.1]: ZRL=[ 0] Val=[ 0] Coef=[01..01] Data=[0x 00 95 E8 A6 = 0b (-0------ -------- -------- --------)] EOB
DCT Matrix=[ 176 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
Lum (Tbl #0), MCU=[0,0]
[0x0000013E.2]: ZRL=[ 0] Val=[ 0] Coef=[00= DC] Data=[0x 00 95 E8 A6 = 0b (--0----- -------- -------- --------)] EOB
[0x0000013E.3]: ZRL=[ 0] Val=[ 0] Coef=[01..01] Data=[0x 00 95 E8 A6 = 0b (---0---- -------- -------- --------)] EOB
DCT Matrix=[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
Lum (Tbl #0), MCU=[0,0]
[0x0000013E.4]: ZRL=[ 0] Val=[ 0] Coef=[00= DC] Data=[0x 00 95 E8 A6 = 0b (----0--- -------- -------- --------)] EOB
[0x0000013E.5]: ZRL=[ 0] Val=[ 0] Coef=[01..01] Data=[0x 00 95 E8 A6 = 0b (-----0-- -------- -------- --------)] EOB
DCT Matrix=[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
Lum (Tbl #0), MCU=[0,0]
[0x0000013E.6]: ZRL=[ 0] Val=[ 0] Coef=[00= DC] Data=[0x 00 95 E8 A6 = 0b (------0- -------- -------- --------)] EOB
[0x0000013E.7]: ZRL=[ 0] Val=[ 0] Coef=[01..01] Data=[0x 00 95 E8 A6 = 0b (-------0 -------- -------- --------)] EOB
DCT Matrix=[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
Chr(0) (Tbl #1), MCU=[0,0]
[0x0000013F.0]: ZRL=[ 0] Val=[ -336] Coef=[00= DC] Data=[0x 95 E8 A6 00 = 0b (10010101 111----- -------- --------)]
[0x00000140.3]: ZRL=[ 0] Val=[ 0] Coef=[01..01] Data=[0x E8 A6 00 0F = 0b (---0---- -------- -------- --------)] EOB
DCT Matrix=[ -672 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
Chr(0) (Tbl #1), MCU=[0,0]
[0x00000140.4]: ZRL=[ 0] Val=[ -428] Coef=[00= DC] Data=[0x E8 A6 00 0F = 0b (----1000 1010011- -------- --------)]
Scan Data encountered marker 0xFFD9 @ 0x00000144.0
[0x00000141.7]: ZRL=[ 0] Val=[ 0] Coef=[01..01] Data=[0x A6 00 0F FF = 0b (-------0 -------- -------- --------)] EOB
DCT Matrix=[ -856 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
分解結果は、Lum のブロックが4個、Chr のブロックが2個、計6個のブロックに分かれているようである。
圧縮データの最後の余ったビットは 1
で埋め、これがハフマン符号のデータに対応しないノードに相当すると予想したが、実際には 0
であるにもかかわらず使われないビットもあるようである。
まとめ
今回わかったこと
- GIMP で JPEG 画像を保存する際の「最適化」の有無で、エンコードは変わるが、エンコードされるデータは変わらなそうである
- deflate でも用いられるアルゴリズムで、符号長ごとの符号数からハフマン符号を構築する
- ハフマン符号からは追加データのビット数を読み取り、圧縮データではハフマン符号の後にそのビット数のデータが続く
- AC 成分では、データの上位ニブルに「その要素の前に何要素の
0
を追加するか」を格納する - 圧縮データの各ブロックは、最初に1個の DC 成分を表すハフマン符号+追加データを置き、続いて63個分の AC 成分を表すハフマン符号+追加データを置く
- 圧縮データにはヘッダは無く、最初のブロックの DC 成分の情報から開始する
今後の課題
- ハフマン符号を読んでデータブロックを切り出すプログラムを書いてみる
- 圧縮データ内でデータブロックがどのように並んでいるかを調査する
- 各コンポーネントの並び順は?
- 画像内の位置との関係は?
- サンプリングファクター?
- プログレッシブ?
- 実は8×8ではなく16×16がひとかたまり?