2015年3月29日投稿 / 投稿者 : れい / タグ : 投稿プログラム ライブラリ
プチコン3号で利用することを前提に考えた画像フォーマットの仕様およびこれを利用するためのライブラリです。
プチコン3号はSDを利用している比較的大きなストレージを持ち、またGRPも1枚当たり500kByteと比較的大きいサイズになっています。 しかし公式サイトでのプログラムの配布は1プロジェクトあたりおおよそ4MByteに制限されており、 高画質、高音質、内容の多いコンテンツを作成する際に問題になる可能性があります。
PC用の圧縮・展開ルーチンはプチコン3号には負荷が高く、実用に耐える展開速度、コード量ではありません。
そこで、プチコン3号上でも十分高速に圧縮・展開でき、標準関数であるGLOAD/GSAVE等と相性の良い画像フォーマットを考案し、 それを用いる為のライブラリを作成しました。
プチコン3号の数値配列の1要素(4オクテット)の単位を1レコードとし、 配列の先頭から下記のようなレコード構造とします。
物理コード指定した際、GLOAD/GSAVEで得られる配列の各要素は16bitの範囲に収まっています。 この16bit配列をリトルエンディアンでバイトストリームとして解釈し、 バイト単位でLZSS圧縮を行ったものをデータストリームとします。 圧縮時の詳細は、ライブラリソースを仕様とします。
ライブラリの内容の説明です。
以下では、下記の単語を用います。
GLOAD配列をPZGファイルに保存する関数です。
GLOAD配列、その幅、高さを引数に取ります。 進捗を表示する場合はPROG%にTRUEを指定します。
PZGファイルからGLOAD配列を読み込む関数です。
ファイル名と出力配列を引数に取り、幅、高さを返します。 データは出力配列に追加される為、要素の無い配列を指定してください。 進捗を表示する場合はPROG%にTRUEを指定します。
GLOAD配列をPZG配列に圧縮する関数です。
GLOAD配列、出力配列、幅、高さを引数に取ります。 データは出力配列に追加される為、要素の無い配列を指定してください。 進捗を表示する場合はPROG%にTRUEを指定します。
PZG配列をGLOAD配列に展開する関数です。
PZG配列と出力配列を引数に取り、幅、高さを返します。 データは出力配列に追加される為、要素の無い配列を指定してください。 進捗を表示する場合はPROG%にTRUEを指定します。
任意の配列を圧縮する関数です。
入力配列、出力配列、ウィンドウサイズのビット数、一致長のビット数、最小一致量を引数にとります。 データに応じてウィンドウサイズは8〜12、一致長は3〜7、最小一致量は3〜5を用いてください。 展開時には同じウィンドウサイズ、一致長を指定する必要があります。 進捗を表示する場合はPROG%にTRUEを指定します。
LZで圧縮された配列を展開する関数です。
入力配列、開始オフセット、出力配列、ウィンドウサイズのビット数、一致長のビット数を引数にとります。 圧縮時に用いたものと同じウィンドウサイズ、一致長を指定する必要があります。 進捗を表示する場合はPROG%にTRUEを指定します。
公開数制限があるため、他のプログラムに同梱しています。
- ’−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
- ’ LZSS LIBRARY FOR PETITCOM
- ’ 2015/4/17 Ver.1.0.1
- ’ Rei Software
- ’
- ’FUNCTIONS
- ’
- ’SAVELZIMAGE − SAVE LZIMAGE FORMAT FILE
- ’ FILENAME$:FILENAME TO SAVE
- ’ IN%[]:GLOAD ARRAY
- ’ W%:IMAGE WIDTH
- ’ H%:IMAGE HEIGHT
- ’ PROG:DISPLAY PROGRESS
- ’
- ’LOADLZIMAGE − LOAD LZIMAGE FORMAT FILE
- ’ FILENAME$:FILENAME TO LOAD
- ’ OUT%[]:GLOAD ARRAY
- ’ PROG:DISPLAY PROGRESS
- ’ [OUT] W%:IMAGE WIDTH
- ’ [OUT] H%:IMAGE HEIGHT
- ’
- ’LZIMAGE − COMPRESS GLOAD ARRAY
- ’ IN%[]:SOURCE GLOAD ARRAY
- ’ OUT%[]:COMPRESSED ARRAY
- ’ W%:IMAGE WIDTH
- ’ H%:IMAGE HEIGHT
- ’ PROG:DISPLAY PROGRESS
- ’
- ’UNLZIMAGE − DECOMPRESS TO GLOAD ARRAY
- ’ IN%[]:SOURCE COMPRESSED ARRAY
- ’ OUT%[]:GLOAD ARRAY
- ’ PROG:DISPLAY PROGRESS
- ’ [OUT] W%:IMAGE WIDTH
- ’ [OUT] H%:IMAGE HEIGHT
- ’
- ’LZ − COMPRESS NUMBER ARRAY
- ’ IN%[]:SOURCE ARRAY
- ’ OUT%[]:COMPRESSED ARRAY
- ’ WLB%:WINDOWSIZE IN BIT (RECOMMEND 10)
- ’ MLB%:MAX REPETITION IN BIT (RECOMMEND 5)
- ’ LLB%:MIN REPETITION IN BYTE (RECOMMEND 3)
- ’ PROG:DISPLAY PROGRESS
- ’
- ’UNLZ − DECOMPRESS NUMBER ARRAY
- ’ IN%[]:SOURCE ARRAY
- ’ INOFS%:START INDEX OF SOURCE ARRAY
- ’ OUT%[]:DECOMPRESSED ARRAY
- ’ WLB%:WINDOWSIZE IN BIT
- ’ MLB%:MAX REPETITION IN BIT
- ’ PROG:DISPLAY PROGRESS
- ’
- DEF SAVELZIMAGE FILENAME$,IN%[],W%,H%,PROG%
- DIM P%[0],V%
- LZIMAGE IN%,P%,W%,H%,PROG%
- SAVE ”DAT:”+FILENAME$,P%
- WHILE LEN(P%)>0:V%=POP(P%):WEND
- END
- DEF LOADLZIMAGE FILENAME$,OUT%[],PROG% OUT W%,H%
- DIM P%[0],V%
- LOAD ”DAT:”+FILENAME$,P%,FALSE
- UNLZIMAGE P%,OUT%,PROG% OUT W%,H%
- WHILE LEN(P%)>0:V%=POP(P%):WEND
- END
- DEF LZIMAGE IN%[],OUT%[],W%,H%,PROG%
- VAR WLB%=10,MLB%=5,MM%=3
- DIM P%[0]
- VAR I%,V%,DD%
- FOR I%=0 TO LEN(IN%)−2 STEP 2
- PUSH P%,IN%[I%] OR (IN%[I%+1]<<16)
- NEXT
- IF I%==LEN(IN%)−1 THEN
- PUSH P%,IN%[I%]
- ENDIF
- WHILE LEN(OUT%)>0:DD%=POP(OUT%):WEND
- PUSH OUT%,&H505A473A’PZG:
- PUSH OUT%,1’VERSION1
- PUSH OUT%,(W%<<16) OR H%’WIDTH&HEIGHT
- PUSH OUT%,WLB% OR (MLB%<<8)’LZ PARAM
- LZ P%,OUT%,WLB%,MLB%,MM%,PROG%
- WHILE LEN(P%)>0:V%=POP(P%):WEND
- END
- DEF UNLZIMAGE IN%[],OUT%[],PROG% OUT W%,H%
- VAR WLB%,MLB%
- DIM P%[0]
- VAR V%,DD%
- IF IN%[0]!=&H505A473A THEN PRINT ”INVALID DATA”:STOP
- IF IN%[1]!=1 THEN PRINT ”UNSUPPORTED VERSION”:STOP
- W% =(IN%[2]>>16)AND &HFFFF
- H% = IN%[2] AND &HFFFF
- WLB%= IN%[3] AND &HFF
- MLB%=(IN%[3]>>8 )AND &HFF
- UNLZ IN%,4,P%,WLB%,MLB%,PROG%
- WHILE LEN(OUT%)>0:DD%=POP(OUT%):WEND
- WHILE LEN(P%)>0
- V%=SHIFT(P%)
- PUSH OUT%,V% AND &HFFFF
- PUSH OUT%,(V%>>16)AND &HFFFF
- WEND
- WHILE LEN(OUT%)>W%*H%
- DD%=POP(OUT%)
- WEND
- END
- DEF UNLZ IN%[],INOFS%,OUT%[],WLB%,MLB%,PROG%
- VAR JH%=INOFS%,JL%=0,C%,L%,D%,B%
- VAR OL%=0,O%=0,K%,I%
- VAR WL%=(1<<WLB%)−1
- VAR ML%=(1<<MLB%)−1
- VAR LEN_IN%=LEN(IN%)
- VAR CNT%=0,PRG1%
- DIM BB%[WL%+1]
-
- IF PROG% THEN
- PRG1%=JH%*40/LEN_IN%
- PRINT ”*”*PRG1%+”−”*(40−PRG1%)
- ENDIF
-
- WHILE JH%<LEN_IN%
- IF PROG% THEN
- INC CNT%
- IF CNT%>16 THEN
- CNT%=0
- PRG1%=JH%*40/LEN_IN%
- LOCATE 0,CSRY−1
- PRINT ”*”*PRG1%+”−”*(40−PRG1%)
- ENDIF
- ENDIF
- C%=((IN%[JH%]>>JL%)AND 1)
- INC JL%
- IF JL%>=32 THEN INC JH%:DEC JL%,32
- IF JH%>=LEN_IN% THEN BREAK
-
- IF C%==0 THEN
- B%=(IN%[JH%]>>JL%) AND 255
- INC JL%,8
- IF JL%>=32 THEN
- INC JH%:DEC JL%,32
- B%= B% AND ((1<<(8−JL%))−1)
- IF JH%<LEN_IN% THEN
- B%=(B% OR (IN%[JH%]<<(8−JL%))) AND 255
- ENDIF
- ENDIF
- O%=O% OR (B%<<OL%)
- PUSH BB%,B%:B%=SHIFT(BB%)
- INC OL%,8
- IF OL%>=32 THEN PUSH OUT%,O%:OL%=0:O%=0
- ELSE
- D%=(IN%[JH%]>>JL% AND WL%)
- INC JL%,WLB%
- IF JL%>=32 THEN
- INC JH%:DEC JL%,32
- D%= D% AND ((1<<(WLB%−JL%))−1)
- D%=(D% OR (IN%[JH%]<<(WLB%−JL%)))AND WL%
- ENDIF
- L%=(IN%[JH%]>>JL% AND ML%)
- INC JL%,MLB%
- IF JL%>=32 THEN
- INC JH%:DEC JL%,32
- L%= L% AND ((1<<(MLB%−JL%))−1)
- IF JH%<LEN_IN% THEN
- L%=(L% OR (IN%[JH%]<<(MLB%−JL%)))AND ML%
- ENDIF
- ENDIF
- L%=L%+1
- K%=WL%−D%
- FOR I%=1 TO L%
- B%=BB%[K%]
- O%=O% OR (B%<<OL%)
- PUSH BB%,B%:B%=SHIFT(BB%)
- INC OL%,8
- IF OL%>=32 THEN PUSH OUT%,O%:OL%=0:O%=0
- NEXT
- ENDIF
- WEND
- IF PROG% THEN LOCATE 0,CSRY−1:PRINT ”*”*40
- END
- DEF LZ IN%[],OUT%[],WLB%,MLB%,MM%,PROG%
- WLB%=MIN(MAX(WLB%,7),16)
- MLB%=MIN(MAX(MLB%,3),8)
- MM%=MIN(MAX(MM%,3),10)
-
- VAR WL%=(1<<WLB%)
- VAR ML%=(1<<MLB%)−1
- VAR PH%,PL%,P%,P2%,OL%,O%
- VAR MD%,MP%,MLL%,D%,L%,B%,I%,DD%
- VAR LEN_IN%=LEN(IN%)
- VAR LEN_IN_4P%=LEN(IN%)*4+ML%
- DIM BB%[WL%]
- DIM HS%[256],HL%[0]
- VAR H1%,H2%,HO%=0
-
- VAR CNT%=0,PRG1%
-
- FOR I%=0 TO 255:HS%[I%]=−1:NEXT
- PH%=0:PL%=0:P%=ML%
- FOR I%=0 TO ML%
- B%=(IN%[PH%]>>PL%) AND 255
- PUSH BB%,B%
- INC PL%,8:IF PL%>=32 THEN INC PH%:PL%=0
- NEXT
-
- IF PROG% THEN
- PRG1%=P%*40/LEN_IN_4P%
- PRINT ”*”*PRG1%+”−”*(40−PRG1%)
- ENDIF
-
- WHILE P%<LEN_IN_4P%
- IF PROG% THEN
- INC CNT%
- IF CNT%>16 THEN
- CNT%=0
- PRG1%=P%*40/LEN_IN_4P%
- LOCATE 0,CSRY−1
- PRINT ”*”*PRG1%+”−”*(40−PRG1%)
- ENDIF
- ENDIF
-
- H1%=BB%[WL%]XOR BB%[WL%+1]XOR BB%[WL%+2]
- MLL%=−1
- H2%=HS%[H1%]
- WHILE H2%>=0
- D%=(P%−ML%)−H2%
- IF D%>WL% THEN BREAK
- L%=1:P2%=WL%−D%
- WHILE P%+L%<LEN_IN_4P%
- IF BB%[P2%+L%]!=BB%[WL%+L%] THEN BREAK
- INC L%
- IF L%>ML% THEN MD%=D%:MLL%=L%:GOTO @LZ1
- WEND
- IF L%>MLL% THEN MD%=D%:MLL%=L%
- DEC H2%,HL%[H2%−HO%]
- WEND
-
- @LZ1
- IF MLL%<MM% THEN
- MLL%=1
- INC OL%
- IF OL%>=32 THEN
- PUSH OUT%,O%:O%=0:OL%=0
- ENDIF
- B%=BB%[WL%]
- O%=O% OR (B%<<OL%)
- INC OL%,8
- IF OL%>=32 THEN
- PUSH OUT%,O%:DEC OL%,32
- O%=B%>>(8−OL%)
- ENDIF
- ELSE
- O%=O% OR (1<<OL%)
- INC OL%
- IF OL%>=32 THEN
- PUSH OUT%,O%:O%=0:OL%=0
- ENDIF
- B%=MD%−1
- O%=O% OR (B%<<OL%)
- INC OL%,WLB%
- IF OL%>=32 THEN
- PUSH OUT%,O%:DEC OL%,32
- O%=B%>>(WLB%−OL%)
- ENDIF
- B%=MLL%−1
- O%=O% OR (B%<<OL%)
- INC OL%,MLB%
- IF OL%>=32 THEN
- PUSH OUT%,O%:DEC OL%,32
- O%=B%>>(MLB%−OL%)
- ENDIF
- ENDIF
-
- FOR I%=0 TO MLL%−1
- H1%=BB%[WL%]XOR BB%[WL%+1]XOR BB%[WL%+2]
- H2%=HS%[H1%]
- HS%[H1%]=P%−ML%
- PUSH HL%,LEN(HL%)+HO%−H2%
-
- IF PH%<LEN_IN% THEN
- B%=(IN%[PH%]>>PL%) AND 255
- ELSE
- B%=0
- ENDIF
- PUSH BB%,B%:B%=SHIFT(BB%)
-
- INC P%
- INC PL%,8:IF PL%>=32 THEN INC PH%:PL%=0
- NEXT
- WHILE LEN(HL%)>WL%
- DD%=SHIFT(HL%):INC HO%
- WEND
- WEND
- IF OL%>0 THEN PUSH OUT%,O%
- IF PROG% THEN LOCATE 0,CSRY−1:PRINT ”*”*40
- END
この作品に対するコメントがあれば一言どうぞ。(作品に直接関係ない質問や雑談は掲示板へ)
表示モード : [ スマホ・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