プチコン3号&BIGまとめWiki

投稿プログラム : 圧縮画像フォーマットPZG仕様とライブラリ

2015年3月29日投稿 / 投稿者 : れい / タグ : 投稿プログラム ライブラリ

概要

プチコン3号で利用することを前提に考えた画像フォーマットの仕様およびこれを利用するためのライブラリです。

目的

プチコン3号はSDを利用している比較的大きなストレージを持ち、またGRPも1枚当たり500kByteと比較的大きいサイズになっています。 しかし公式サイトでのプログラムの配布は1プロジェクトあたりおおよそ4MByteに制限されており、 高画質、高音質、内容の多いコンテンツを作成する際に問題になる可能性があります。

PC用の圧縮・展開ルーチンはプチコン3号には負荷が高く、実用に耐える展開速度、コード量ではありません。

そこで、プチコン3号上でも十分高速に圧縮・展開でき、標準関数であるGLOAD/GSAVE等と相性の良い画像フォーマットを考案し、 それを用いる為のライブラリを作成しました。

フォーマット

概要

プチコン3号の数値配列の1要素(4オクテット)の単位を1レコードとし、 配列の先頭から下記のようなレコード構造とします。

  • ヘッダー
    • 1 識別ID(&H505A473A「PZG:」)
    • 2 版(現在は1のみ)
    • 3 画像サイズ
      • 0-15bit: 高さ
      • 16-31bit: 幅
    • 4 LZSS圧縮パラメーター
      • 0-7bit: ウィンドウサイズのビット数
      • 8-15bit: 一致長のビット数
      • 16-31bit: 未使用
  • データ
    • 5- LZSSデータストリーム。リトルエンディアン。

LZSSデータストリーム

物理コード指定した際、GLOAD/GSAVEで得られる配列の各要素は16bitの範囲に収まっています。 この16bit配列をリトルエンディアンでバイトストリームとして解釈し、 バイト単位でLZSS圧縮を行ったものをデータストリームとします。 圧縮時の詳細は、ライブラリソースを仕様とします。

ライブラリ

ライブラリの内容の説明です。

以下では、下記の単語を用います。

  • GLOAD配列: 物理コード指定でGLOAD/GSAVEを呼ぶときに用いられる形式の配列と呼ぶ
  • PZG配列: GLOAD配列に画像サイズ情報を追加し圧縮した、この仕様で延べられるフォーマットに従った配列
  • PZGファイル: PZG配列をDATリソースとして記録したファイル

SAVELZIMAGE

GLOAD配列をPZGファイルに保存する関数です。

GLOAD配列、その幅、高さを引数に取ります。 進捗を表示する場合はPROG%にTRUEを指定します。

LOADLZIMAGE

PZGファイルからGLOAD配列を読み込む関数です。

ファイル名と出力配列を引数に取り、幅、高さを返します。 データは出力配列に追加される為、要素の無い配列を指定してください。 進捗を表示する場合はPROG%にTRUEを指定します。

LZIMAGE

GLOAD配列をPZG配列に圧縮する関数です。

GLOAD配列、出力配列、幅、高さを引数に取ります。 データは出力配列に追加される為、要素の無い配列を指定してください。 進捗を表示する場合はPROG%にTRUEを指定します。

UNLZIMAGE

PZG配列をGLOAD配列に展開する関数です。

PZG配列と出力配列を引数に取り、幅、高さを返します。 データは出力配列に追加される為、要素の無い配列を指定してください。 進捗を表示する場合はPROG%にTRUEを指定します。

LZ

任意の配列を圧縮する関数です。

入力配列、出力配列、ウィンドウサイズのビット数、一致長のビット数、最小一致量を引数にとります。 データに応じてウィンドウサイズは8〜12、一致長は3〜7、最小一致量は3〜5を用いてください。 展開時には同じウィンドウサイズ、一致長を指定する必要があります。 進捗を表示する場合はPROG%にTRUEを指定します。

UNLZ

LZで圧縮された配列を展開する関数です。

入力配列、開始オフセット、出力配列、ウィンドウサイズのビット数、一致長のビット数を引数にとります。 圧縮時に用いたものと同じウィンドウサイズ、一致長を指定する必要があります。 進捗を表示する場合はPROG%にTRUEを指定します。

スクリーンショット・動画

zlCfzTKwEgM1x1_YnP.jpg

公開キー

プチコン3号/BIG 公開キー
R584E83E

公開数制限があるため、他のプログラムに同梱しています。

プログラムリスト

  1. ’−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
  2. ’                 LZSS LIBRARY FOR PETITCOM
  3. ’                       2015/4/17 Ver.1.0.1
  4. ’                              Rei Software
  5. ’FUNCTIONS
  6. ’SAVELZIMAGE − SAVE LZIMAGE FORMAT FILE
  7. ’ FILENAME$:FILENAME TO SAVE
  8. ’ IN%[]:GLOAD ARRAY
  9. ’ W%:IMAGE WIDTH
  10. ’ H%:IMAGE HEIGHT
  11. ’ PROG:DISPLAY PROGRESS
  12. ’LOADLZIMAGE − LOAD LZIMAGE FORMAT FILE
  13. ’ FILENAME$:FILENAME TO LOAD
  14. ’ OUT%[]:GLOAD ARRAY
  15. ’ PROG:DISPLAY PROGRESS
  16. ’ [OUT] W%:IMAGE WIDTH
  17. ’ [OUT] H%:IMAGE HEIGHT
  18. ’LZIMAGE − COMPRESS GLOAD ARRAY
  19. ’ IN%[]:SOURCE GLOAD ARRAY
  20. ’ OUT%[]:COMPRESSED ARRAY
  21. ’ W%:IMAGE WIDTH
  22. ’ H%:IMAGE HEIGHT
  23. ’ PROG:DISPLAY PROGRESS
  24. ’UNLZIMAGE − DECOMPRESS TO GLOAD ARRAY
  25. ’ IN%[]:SOURCE COMPRESSED ARRAY
  26. ’ OUT%[]:GLOAD ARRAY
  27. ’ PROG:DISPLAY PROGRESS
  28. ’ [OUT] W%:IMAGE WIDTH
  29. ’ [OUT] H%:IMAGE HEIGHT
  30. ’LZ − COMPRESS NUMBER ARRAY
  31. ’ IN%[]:SOURCE ARRAY
  32. ’ OUT%[]:COMPRESSED ARRAY
  33. ’ WLB%:WINDOWSIZE IN BIT (RECOMMEND 10)
  34. ’ MLB%:MAX REPETITION IN BIT (RECOMMEND 5)
  35. ’ LLB%:MIN REPETITION IN BYTE (RECOMMEND 3)
  36. ’ PROG:DISPLAY PROGRESS
  37. ’UNLZ − DECOMPRESS NUMBER ARRAY
  38. ’ IN%[]:SOURCE ARRAY
  39. ’ INOFS%:START INDEX OF SOURCE ARRAY
  40. ’ OUT%[]:DECOMPRESSED ARRAY
  41. ’ WLB%:WINDOWSIZE IN BIT
  42. ’ MLB%:MAX REPETITION IN BIT
  43. ’ PROG:DISPLAY PROGRESS
  44. DEF SAVELZIMAGE FILENAME$,IN%[],W%,H%,PROG%
  45.  DIM P%[0],V%
  46.  LZIMAGE IN%,P%,W%,H%,PROG%
  47.  SAVE ”DAT:”+FILENAME$,P%
  48.  WHILE LEN(P%)>0:V%=POP(P%):WEND
  49. END
  50. DEF LOADLZIMAGE FILENAME$,OUT%[],PROG% OUT W%,H%
  51.  DIM P%[0],V%
  52.  LOAD ”DAT:”+FILENAME$,P%,FALSE
  53.  UNLZIMAGE P%,OUT%,PROG% OUT W%,H%
  54.  WHILE LEN(P%)>0:V%=POP(P%):WEND
  55. END
  56. DEF LZIMAGE IN%[],OUT%[],W%,H%,PROG%
  57.  VAR WLB%=10,MLB%=5,MM%=3
  58.  DIM P%[0]
  59.  VAR I%,V%,DD%
  60.  FOR I%=0 TO LEN(IN%)−2 STEP 2
  61.   PUSH P%,IN%[I%] OR (IN%[I%+1]<<16)
  62.  NEXT
  63.  IF I%==LEN(IN%)−1 THEN
  64.   PUSH P%,IN%[I%]
  65.  ENDIF
  66.  WHILE LEN(OUT%)>0:DD%=POP(OUT%):WEND
  67.  PUSH OUT%,&H505A473A’PZG:
  68.  PUSH OUT%,1’VERSION1
  69.  PUSH OUT%,(W%<<16) OR H%’WIDTH&HEIGHT
  70.  PUSH OUT%,WLB% OR (MLB%<<8)’LZ PARAM
  71.  LZ P%,OUT%,WLB%,MLB%,MM%,PROG%
  72.  WHILE LEN(P%)>0:V%=POP(P%):WEND
  73. END
  74. DEF UNLZIMAGE IN%[],OUT%[],PROG% OUT W%,H%
  75.  VAR WLB%,MLB%
  76.  DIM P%[0]
  77.  VAR V%,DD%
  78.  IF IN%[0]!=&H505A473A THEN PRINT ”INVALID DATA”:STOP
  79.  IF IN%[1]!=1 THEN PRINT ”UNSUPPORTED VERSION”:STOP
  80.  W%  =(IN%[2]>>16)AND &HFFFF
  81.  H%  = IN%[2]     AND &HFFFF
  82.  WLB%= IN%[3]     AND &HFF
  83.  MLB%=(IN%[3]>>8 )AND &HFF
  84.  UNLZ IN%,4,P%,WLB%,MLB%,PROG%
  85.  WHILE LEN(OUT%)>0:DD%=POP(OUT%):WEND
  86.  WHILE LEN(P%)>0
  87.   V%=SHIFT(P%)
  88.   PUSH OUT%,V%      AND &HFFFF
  89.   PUSH OUT%,(V%>>16)AND &HFFFF
  90.  WEND
  91.  WHILE LEN(OUT%)>W%*H%
  92.   DD%=POP(OUT%)
  93.  WEND
  94. END
  95. DEF UNLZ IN%[],INOFS%,OUT%[],WLB%,MLB%,PROG%
  96.  VAR JH%=INOFS%,JL%=0,C%,L%,D%,B%
  97.  VAR OL%=0,O%=0,K%,I%
  98.  VAR WL%=(1<<WLB%)−1
  99.  VAR ML%=(1<<MLB%)−1
  100.  VAR LEN_IN%=LEN(IN%)
  101.  VAR CNT%=0,PRG1%
  102.  DIM BB%[WL%+1]
  103.  
  104.  IF PROG% THEN
  105.   PRG1%=JH%*40/LEN_IN%
  106.   PRINT ”*”*PRG1%+”−”*(40−PRG1%)
  107.  ENDIF
  108.  
  109.  WHILE JH%<LEN_IN%
  110.   IF PROG% THEN
  111.    INC CNT%
  112.    IF CNT%>16 THEN
  113.     CNT%=0
  114.     PRG1%=JH%*40/LEN_IN%
  115.     LOCATE 0,CSRY−1
  116.     PRINT ”*”*PRG1%+”−”*(40−PRG1%)
  117.    ENDIF
  118.   ENDIF
  119.   C%=((IN%[JH%]>>JL%)AND 1)
  120.   INC JL%
  121.   IF JL%>=32 THEN INC JH%:DEC JL%,32
  122.   IF JH%>=LEN_IN% THEN BREAK
  123.   
  124.   IF C%==0 THEN
  125.    B%=(IN%[JH%]>>JL%) AND 255
  126.    INC JL%,8
  127.    IF JL%>=32 THEN
  128.     INC JH%:DEC JL%,32
  129.     B%= B% AND ((1<<(8−JL%))−1)
  130.     IF JH%<LEN_IN% THEN
  131.      B%=(B% OR  (IN%[JH%]<<(8−JL%))) AND 255
  132.     ENDIF
  133.    ENDIF
  134.    O%=O% OR (B%<<OL%)
  135.    PUSH BB%,B%:B%=SHIFT(BB%)
  136.    INC OL%,8
  137.    IF OL%>=32 THEN PUSH OUT%,O%:OL%=0:O%=0
  138.   ELSE
  139.    D%=(IN%[JH%]>>JL% AND WL%)
  140.    INC JL%,WLB%
  141.    IF JL%>=32 THEN
  142.     INC JH%:DEC JL%,32
  143.     D%= D% AND ((1<<(WLB%−JL%))−1)
  144.     D%=(D% OR (IN%[JH%]<<(WLB%−JL%)))AND WL%
  145.    ENDIF
  146.    L%=(IN%[JH%]>>JL% AND ML%)
  147.    INC JL%,MLB%
  148.    IF JL%>=32 THEN
  149.     INC JH%:DEC JL%,32
  150.     L%= L% AND ((1<<(MLB%−JL%))−1)
  151.     IF JH%<LEN_IN% THEN
  152.      L%=(L% OR (IN%[JH%]<<(MLB%−JL%)))AND ML%
  153.     ENDIF
  154.    ENDIF
  155.    L%=L%+1
  156.    K%=WL%−D%
  157.    FOR I%=1 TO L%
  158.     B%=BB%[K%]
  159.     O%=O% OR (B%<<OL%)
  160.     PUSH BB%,B%:B%=SHIFT(BB%)
  161.     INC OL%,8
  162.     IF OL%>=32 THEN PUSH OUT%,O%:OL%=0:O%=0
  163.    NEXT
  164.   ENDIF
  165.  WEND
  166.  IF PROG% THEN LOCATE 0,CSRY−1:PRINT ”*”*40
  167. END
  168. DEF LZ IN%[],OUT%[],WLB%,MLB%,MM%,PROG%
  169.  WLB%=MIN(MAX(WLB%,7),16)
  170.  MLB%=MIN(MAX(MLB%,3),8)
  171.  MM%=MIN(MAX(MM%,3),10)
  172.  
  173.  VAR WL%=(1<<WLB%)
  174.  VAR ML%=(1<<MLB%)−1
  175.  VAR PH%,PL%,P%,P2%,OL%,O%
  176.  VAR MD%,MP%,MLL%,D%,L%,B%,I%,DD%
  177.  VAR LEN_IN%=LEN(IN%)
  178.  VAR LEN_IN_4P%=LEN(IN%)*4+ML%
  179.  DIM BB%[WL%]
  180.  DIM HS%[256],HL%[0]
  181.  VAR H1%,H2%,HO%=0
  182.  
  183.  VAR CNT%=0,PRG1%
  184.  
  185.  FOR I%=0 TO 255:HS%[I%]=−1:NEXT
  186.  PH%=0:PL%=0:P%=ML%
  187.  FOR I%=0 TO ML%
  188.   B%=(IN%[PH%]>>PL%) AND 255
  189.   PUSH BB%,B%
  190.   INC PL%,8:IF PL%>=32 THEN INC PH%:PL%=0
  191.  NEXT
  192.  
  193.  IF PROG% THEN
  194.   PRG1%=P%*40/LEN_IN_4P%
  195.   PRINT ”*”*PRG1%+”−”*(40−PRG1%)
  196.  ENDIF
  197.  
  198.  WHILE P%<LEN_IN_4P%
  199.   IF PROG% THEN
  200.    INC CNT%
  201.    IF CNT%>16 THEN
  202.     CNT%=0
  203.     PRG1%=P%*40/LEN_IN_4P%
  204.     LOCATE 0,CSRY−1
  205.     PRINT ”*”*PRG1%+”−”*(40−PRG1%)
  206.    ENDIF
  207.   ENDIF
  208.   
  209.   H1%=BB%[WL%]XOR BB%[WL%+1]XOR BB%[WL%+2]
  210.   MLL%=−1
  211.   H2%=HS%[H1%]
  212.   WHILE H2%>=0
  213.    D%=(P%−ML%)−H2%
  214.    IF D%>WL% THEN BREAK
  215.    L%=1:P2%=WL%−D%
  216.    WHILE P%+L%<LEN_IN_4P%
  217.     IF BB%[P2%+L%]!=BB%[WL%+L%] THEN BREAK
  218.     INC L%
  219.     IF L%>ML% THEN MD%=D%:MLL%=L%:GOTO @LZ1
  220.    WEND
  221.    IF L%>MLL% THEN MD%=D%:MLL%=L%
  222.    DEC H2%,HL%[H2%−HO%]
  223.   WEND
  224.   
  225.   @LZ1
  226.   IF MLL%<MM% THEN
  227.    MLL%=1
  228.    INC OL%
  229.    IF OL%>=32 THEN
  230.     PUSH OUT%,O%:O%=0:OL%=0
  231.    ENDIF
  232.    B%=BB%[WL%]
  233.    O%=O% OR (B%<<OL%)
  234.    INC OL%,8
  235.    IF OL%>=32 THEN
  236.     PUSH OUT%,O%:DEC OL%,32
  237.     O%=B%>>(8−OL%)
  238.    ENDIF
  239.   ELSE
  240.    O%=O% OR (1<<OL%)
  241.    INC OL%
  242.    IF OL%>=32 THEN
  243.     PUSH OUT%,O%:O%=0:OL%=0
  244.    ENDIF
  245.    B%=MD%−1
  246.    O%=O% OR (B%<<OL%)
  247.    INC OL%,WLB%
  248.    IF OL%>=32 THEN
  249.     PUSH OUT%,O%:DEC OL%,32
  250.     O%=B%>>(WLB%−OL%)
  251.    ENDIF
  252.    B%=MLL%−1
  253.    O%=O% OR (B%<<OL%)
  254.    INC OL%,MLB%
  255.    IF OL%>=32 THEN
  256.     PUSH OUT%,O%:DEC OL%,32
  257.     O%=B%>>(MLB%−OL%)
  258.    ENDIF
  259.   ENDIF
  260.   
  261.   FOR I%=0 TO MLL%−1
  262.    H1%=BB%[WL%]XOR BB%[WL%+1]XOR BB%[WL%+2]
  263.    H2%=HS%[H1%]
  264.    HS%[H1%]=P%−ML%
  265.    PUSH HL%,LEN(HL%)+HO%−H2%
  266.    
  267.    IF PH%<LEN_IN% THEN
  268.     B%=(IN%[PH%]>>PL%) AND 255
  269.    ELSE
  270.     B%=0
  271.    ENDIF
  272.    PUSH BB%,B%:B%=SHIFT(BB%)
  273.     
  274.    INC P%
  275.    INC PL%,8:IF PL%>=32 THEN INC PH%:PL%=0
  276.   NEXT
  277.   WHILE LEN(HL%)>WL%
  278.    DD%=SHIFT(HL%):INC HO%
  279.   WEND
  280.  WEND
  281.  IF OL%>0 THEN PUSH OUT%,O%
  282.  IF PROG% THEN LOCATE 0,CSRY−1:PRINT ”*”*40
  283. END

CHECKER FLAG (ひとことコメント)

この作品に対するコメントがあれば一言どうぞ。(作品に直接関係ない質問や雑談は掲示板へ)

  • れい : ごみごみ (2015/03/29 (日) 07:29:05)
  • 天郷思音 : やけに%ばっかりのプログラムだなぁと思ったら3号では変数の型が選べたんだった。というか全ての数値変数に%がついてる?それならOPTION DEFINTした方がすっきりするよ。 (2015/03/29 (日) 14:49:24)
  • れい : ライブラリなので組み込むこと前提にしてるんでOPTION使えんのよ (2015/03/29 (日) 23:56:54)
  • 3D梨 : 画質は問題ナシだが...このコードただのデブだぞ (2015/04/15 (水) 02:04:24)
  • 名無しさん : ただのデブ? (2015/04/15 (水) 17:07:02)
  • 名無しさん : 配列を文字列にして格納したい (2015/04/15 (水) 18:42:20)
  • 天郷思音 : なるほど (2015/04/15 (水) 18:55:19)
  • 名無しさん : 文字列にするとUTF8になって容量が増えそう (2015/04/15 (水) 21:27:56)
  • れい : 一部問題あったんで更新した。 (2015/04/17 (金) 04:46:09)

メニュー 【3号】

ヘルプ

リンク

最近の更新

最近の人気ページ

オンライン情報

  • 現在同時に 2 人がこのサイトを見ています
  • このページはこれまでに 1698 回、本日は 1 回、昨日は 2 回閲覧されました

ページの先頭に戻る

表示モード : [ スマホ・3DS対応表示 | クラシック表示 ]
PukiWiki 1.4.7 Copyright © 2001-2006 PukiWiki Developers Team. License is GPL. Based on "PukiWiki" 1.3 by yu-ji
ページの処理時間 : 0.086 秒 | このページの最終更新 : 2015/04/17 (金) 04:46:58 (2598d) | ログイン
Copyright(C) 2011-2014 プチコンまとめWiki ◆1sxkymI8ji30