LoginSignup
4
5

More than 5 years have passed since last update.

PNGのチャンクを読む

Last updated at Posted at 2015-12-16

PNGファイルは、最初の8バイトを除けば

チャンク

データ長 名称 データ CRC-32
4バイト 4バイト (データ長に示すバイト数) 4バイト

で構成されているので1

parse_png.sh
#!/bin/bash
set -eu
pngFile=$1
headPtr=0
if [ "89504E470D0A1A0A" != $(xxd -ps -u -s $headPtr -l 8 $pngFile) ]
then
  echo "pngファイルではありません"
  exit 1
fi
headPtr=$((headPtr+8))

chunkName=""
while [ "IEND" != "$chunkName" ] 
do
  chunkLength=$((0x$(xxd -ps -u -s $headPtr -l 4 $pngFile)))
  chunkName=$(dd if=$pngFile ibs=1 skip=$((headPtr+4)) count=4 2> /dev/null)
  checkSum=$(xxd -ps -u -s $((headPtr+4+4+chunkLength)) -l 4 $pngFile)
  printf "%04x: %s %04x\n" $headPtr $chunkName $chunkLength
  recount=$(printf "%08X" 0x$(dd if=$pngFile ibs=1 skip=$((headPtr+4)) count=$((4+chunkLength)) 2> /dev/null | cksum -o3 | cut -d " " -f 1 | xargs -I ZZ dc -e "16oAi ZZ p"))
  if [ "$recount" != "$checkSum" ]
  then
    echo "ファイルが壊れています"
    echo $recount is not equal to $checkSum
  fi
  headPtr=$((headPtr+4+4+chunkLength+4)) #to next chunk
done

https://gist.github.com/nyango/6cd8441edc16c060763a
などと書いてやれば(pngファイルは必ずIENDという名前のチャンクで終わる)、

$ bash parse_png.sh hoge.png
0008: IHDR 000d
0021: pHYs 0009
0036: vpAg 0009
004b: IDAT 8000
8057: IDAT 68e7
e94a: tEXt 0025
e97b: tEXt 0025
e9ac: IEND 0000

pngを構成するチャンクの名称(4文字の英字)とデータ長(バイト数)を確認できる。


4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5