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

ヘルプ

リンク

最近の更新

最近の人気ページ

オンライン情報

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

ページの先頭に戻る

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