Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

バイナリ形式のPPM画像が読み込めない #11

Open
momeemt opened this issue Feb 1, 2021 · 6 comments
Open

バイナリ形式のPPM画像が読み込めない #11

momeemt opened this issue Feb 1, 2021 · 6 comments

Comments

@momeemt
Copy link
Contributor

momeemt commented Feb 1, 2021

概要

readPPMプロシージャを用いてバイナリ形式(P6)のPPM画像を読み込むと、次のようなエラーが発生する。

/Volumes/momeeSSD/Developer/pien/src/pien.nim(32) pien
/Volumes/momeeSSD/Developer/pien/src/pien.nim(26) rsv
/Users/momiyama/.nimble/pkgs/pnm-2.1.1/pnm.nim(853) readPPMFile
/Users/momiyama/.nimble/pkgs/pnm-2.1.1/pnm.nim(810) readPPM
/Users/momiyama/.nimble/pkgs/pnm-2.1.1/pnm.nim(603) parsePPM
/Users/momiyama/.choosenim/toolchains/nim-1.4.0/lib/pure/strutils.nim(1129) parseInt
Error: unhandled exception: invalid integer: # [ValueError]

原因

バイナリを正しく読み取ることができていないのではないかと思います。
調べたところ、wavファイルのバイナリを読み取りたいという質問に対して、streamを用いると良いと回答されていました。現在、これを使って正しく読み取ることができないか確かめています。

私はNimでファイルを扱うことに慣れていないので、もし何か思い当たる解決策がありましたら教えていただけると助かります。

読み取ろうとした画像(一部)

P6
# Created by IrfanView
1024 768
255
59R6:S04M15N8:S>@Y8:S46O46O,.G02K8:SBB\88R??W9;R;@VCI_PRiHJa6;O6;O;@V=BV7<P8=P:@P:@P;=L79H76H87I@?Q@?Q=8N:7L1.C97L31G:8NIJ_ABWA=T<:P<:RAAY@>VGE]GE]:8P<<V::T8:Q>@W=BX>CY?AX46M79P8:Q79NCEZ@EY?DX:?R49L<AW38N48Q:>W>D\7=U7=S7?T8@W*5K-8N8CY:@Z39S59R15N13LCE^JLeDF_CG`@E[;@V5:N55M<<TPNfJH`CC[??W:8P64LB@XEC[CC[@@X<<VAA[<<TBBZLIdHE`;;UGGaMJiEEa44P/1J=?X79R9;R>@W>>X44N$"::8P<8O73J51H=9P95L<8OF@ZJD^D@YA=VGE[KI_IG_LJbMNc>?TFD\IIaKLaBDY:<Q?AVABW=>S?@UIJ_DF[=?TDF[GI^DI]MRfUWlQShKNa?BU<=Q78L?=UKIaKIaLJbDBZNLdTRhPNdSSmPPj@BY13J9;

(長すぎるので省略)

@jiro4989
Copy link
Owner

jiro4989 commented Feb 1, 2021

多分2行目のコメント行消してみたら動いたりしないですかね

@jiro4989
Copy link
Owner

jiro4989 commented Feb 1, 2021

バイナリを読み取るのにstreamを使ったほうが扱いやすいのは確かにそうですが、
readFileとかでstring型のデータで読み取っても、byteシーケンスに変換してあげれば結局同じデータになります

@jiro4989
Copy link
Owner

jiro4989 commented Feb 1, 2021

軽くparsePPM(s: openArray[uint8])みてたらコメント行を処理するような実装にしてない気がしたんで、コメント行消したら動きそうな気がしました

@jiro4989
Copy link
Owner

jiro4989 commented Feb 1, 2021

waveモジュールとかの方はstreams使ってるんですが、
pnmは実装した時期が相当昔なんで、streamsの使い方わかってなくて実装がイケてないですね

https://github.com/jiro4989/wave/blob/master/src/wave/waveread.nim

@momeemt
Copy link
Contributor Author

momeemt commented Feb 1, 2021

テキストエディタからPPM画像のコメントを削除するとデータが破損してしまったものの、PNMモジュールの処理は正しく通るようになったのでコメント行によるものでした。
次のようにコメント行を除去する前処理を追加したのですが、バイナリに '#' が含まれる場合にデータが破損することがわかりました。とはいえ、先にuint8にキャストするとそこで落ちてしまうので、詰まっています。

proc readPPM*(f: File): PPM =
  let fileReadAll: string = f.readAll
  var lines: string
  for line in fileReadAll.replaceWhiteSpace.splitLines.mapIt(it.strip):
    if not line.startsWith "#":
      lines.add line & '\n'
  let data = lines.mapIt(it.uint8)
  f.setFilePos 0
  validatePPM(data)

  let fd = f.readLine
  f.setFilePos 0
  case fd
  of ppmFileDescriptorP3:
    result = f.readAll.parsePPM
  of ppmFileDescriptorP6:
    result = data.parsePPM
  else: discard

@momeemt
Copy link
Contributor Author

momeemt commented Feb 1, 2021

streamについては勉強になりました。ファイル読み書きの知識があまりないので勉強してみたいと思います🙇‍♂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants