|
!十進 BASIC による プログレッシブ JPG の展開と画像化。
!を見ても、説明が解りにくく、実際の例が、必要です。あくまで、個人的理解の範囲ですが、
!
!具体的、可視的なプログラムで、実行し画像化しますので、詳細事項の追跡と御参考に。
!再生できるファイルは、1000x1000 までの JPG だけで、
! baseline , spectral selection , successive approximation の3種類( web 上の、ほぼ全種)
!
!1)successive approximation AC.subsequence(Y,Cb,Cr 別々、1bit づつの処理)
!
! 0 1 1 0 0 0 0 0 0 ?
! 0 0 0 0 0 1 0 0 0 ?
! 0 1 0 0 0 0 0 1 0 ?
! 0 1 1 0 0 1 0 1 0 ?
! 0 1 1 0 0 1 0 1 0 ?
! --------------------------------------------------------------------------
! ±1 b1 b2 0 0 b3 0 b4 ±1 ?
! 前の終り RRRR RRRR RRRR extend. 次の始め
!
! huffman.
! RRRRssss extend. b1 b2 b3 b4 …
! 3 1 (0 or 1) bit_stream=?何個になるかは、上図で、上位桁 =0 の係数が
! -1 +1 (0 or 1) RRRR 個 になるまでに通過した上位桁 <>0 の個数。
! 0 ±1
! 0 → 無変化。
! 1 → ±符号は上位桁に合せて加算。(絶対値が+1)
!
!2)successive approximation DC.subsequence(Y,Cb,Cr 別々、1bit づつの処理)
!
! ハフマン・コード RRRRssss 部は、存在せず、
! 頭からの bit_stream.で、1bit づつ、全てのblock の DC係数 に加える。
!
! AC と同様、0 → 無変化。1 → ±符号は上位桁に合せて加算。(絶対値が+1)
!
!※上記、successive approximation AC, DC とも、加える1は、
! 2^Al 倍の point transfer. としてから、加えます。
!
DEBUG ON
!------------------------
!JPG.decoder
! Baseline
! Progressive( spectral selection )( successive approximation )
!------------------------
OPTION ARITHMETIC NATIVE
OPTION BASE 0
OPTION CHARACTER byte
SET TEXT background "OPAQUE"
ASK BITMAP SIZE bmx,bmy
SET WINDOW 0,bmx, bmy,0
SET ECHO "OFF"
SET COLOR MODE "NATIVE"
!
DIM D8(1000,1000) !GDISP DSPYbr
DIM D2(1000,1000,2) !Y=D2(,,0) Cb=D2(,,1) Cr=D2(,,2)
DIM D1(1000,1000,2) !Y=D2(,,0) Cb=D2(,,1) Cr=D2(,,2)
DIM MH(2),MV(2) !R_BIN31 SOF0 MCU.Ybr.H()V()
DIM HDC(2),HAC(2) !R_BIN31 hT.table selection
DIM QS(2),CoID(255) !R_BIN31 qT.table selection
DIM M3(2)
!
DIM U(63),V(63) !zigzag
DIM DQ(7,7,3) !blk8x8 DQT
DIM DH(16,7),DV(255,7) !DHT
DIM B(255+1,7),L(255,7) !encorder & decorder's pre_table, length, ( MAKE_H2,MAKE_H0)
DIM A(2000,7) !decorder
DIM B2(2) !Ybr D.C.成分 starting & back_level for difference
DIM T(7,7),X(7),XO(7) !DDCT8X8, IDDCT8X8
!
LET BST=2 !huffman decorder's bit step 1=8.5s 2=6.5s 4=8.0s 8=50.0s
LET SHb=2^BST !huffman decorder *SHb(shl BST) /SHb(shr BST)
!LET YDC0=1024 !prediction 128( 50%) * {SQR(2/8)^2 * SQR(1/2)^2 * (8*8)}
!
!---zigzag table
FOR V_=0 TO 7
FOR U_=0 TO 7
READ i
LET U(i)=U_
LET V(i)=V_
NEXT U_
NEXT V_
DATA 0, 1, 5, 6,14,15,27,28
DATA 2, 4, 7,13,16,26,29,42
DATA 3, 8,12,17,25,30,41,43
DATA 9,11,18,24,31,40,44,53
DATA 10,19,23,32,39,45,52,54
DATA 20,22,33,38,46,51,55,60
DATA 21,34,37,47,50,56,59,61
DATA 35,36,48,49,57,58,62,63
!
DO
FILE GETNAME FL$, "jpg"
IF FL$="" THEN
PRINT "入力ファイル名が、ありません。"
STOP
END IF
PRINT "入力ファイル:"& FL$
!---
CLEAR
CALL IZZRL0 ! D2()<-- decord JPG
PRINT "次のファイル[ Any key ]"
beep
CHARACTER INPUT CLEAR: w$
LOOP UNTIL w$=CHR$(27) !ESC
!-------- IZZRL0 call here for display D2()
SUB MAIN65
PRINT "画像の準備中、";
CALL IDDCT8X8 ! D1()<-- iDCT<-- iDQT<-- D2()
!---
IF 1< MH(0) OR 1< MV(0) THEN ! Cb_Cr expand Blocks -->MCU scales
FOR V09=0 TO DV_-1 STEP 8*MV(0)
FOR U09=0 TO DU-1 STEP 8*MH(0)
!---MCU part.Cb.Cr
FOR V0=8*MV(0)-1 TO 0 STEP -1
FOR U0=8*MH(0)-1 TO 0 STEP -1
LET D1(U09+U0,V09+V0,1)=D1(U09+IP(U0/MH(0)),V09+IP(V0/MV(0)),1)
LET D1(U09+U0,V09+V0,2)=D1(U09+IP(U0/MH(0)),V09+IP(V0/MV(0)),2)
NEXT U0
NEXT V0
!---
NEXT U09
NEXT V09
END IF
! END SUB
!------ JPG 色空間 ----------------------------
! | Y | | 0.2990 +0.5870 +0.1140 | | R |
! |B-Y| = |-0.1687 -0.3313 +0.5000 | | G |
! |R-Y| | 0.5000 -0.4187 -0.0813 | | B |
!
! | R | | 1 0 +1.40200 | | Y |
! | G | = | 1 -0.34414 -0.71414 | |B-Y|
! | B | | 1 +1.77200 0 | |R-Y|
!----------------------------------------------
! SUB DSPYbr
FOR V0=0 TO DY-1
FOR U0=0 TO DX-1
LET w1=IP(D1(U0,V0,0) +1.40200*D1(U0,V0,2)) !R
LET w2=IP(D1(U0,V0,0) -0.34414*D1(U0,V0,1) -0.71414*D1(U0,V0,2)) !G
LET w3=IP(D1(U0,V0,0) +1.77200*D1(U0,V0,1)) !B
IF w1< 0 THEN
LET w1=0
ELSEIF 255< w1 THEN
LET w1=255
END IF
IF w2< 0 THEN
LET w2=0
ELSEIF 255< w2 THEN
LET w2=255
END IF
IF w3< 0 THEN
LET w3=0
ELSEIF 255< w3 THEN
LET w3=255
END IF
LET D8(U0,V0)=w3*65536+w2*256+w1 !(逆)BGR
NEXT U0
NEXT V0
LET w=TRUNCATE(MIN( (bmx-1)/DX,(bmy-1)/DY),1)
IF 1< w THEN LET w=IP(w)
IF 4< w THEN LET w=4
PRINT "描画の倍率=";w
MAT PLOT CELLS,IN 1,1; DX*w, DY*w :D8
END SUB
!========================
!inverse haffman Transform.
SUB IZZRL0
LET byt=0 !!!
CALL ROPEN ! FL$
!---
CALL R_BIN31(0) !A() B(i,J)L(i,J)<-- DH(), return at img.top
PRINT right$("000"& BSTR$(byt,16),4) !!!
PRINT "(";STR$(DX);"x";STR$(DY);
!---
MAT D8=ZER(DX-1,DY-1) !DSPYbr
LET i=8*MH(0) !MCU Y.Hsize
LET j=8*MV(0) !MCU Y.Vsize
LET DUM=CEIL(DX/i)*i !Uwidth=bound by MCU Y.Hsize
LET DVM=CEIL(DY/j)*j !Vwidth=bound by MCU Y.Vsize
MAT D1=ZER(DUM-1,DVM-1,2) !Y=D1(,,0) Cb=D1(,,1) Cr=D1(,,2)
MAT D2=ZER(DUM-1,DVM-1,2) !Y=D2(,,0) Cb=D2(,,1) Cr=D2(,,2)
LET MH_=MH(0)
LET MV_=MV(0)
LET DU =DUM !Uwidth=bound by MCU Y.Hsize
LET DV_=DVM !Vwidth=bound by MCU Y.Vsize
LET DU8=CEIL(DX/8)*8 !Uwidth=bound by block Y.Hsize
LET DV8=CEIL(DY/8)*8 !Vwidth=bound by block Y.Vsize
!---
PRINT "/ ";STR$(DU8);",";STR$(DV8);"/ ";STR$(DUM);",";STR$(DVM);")"
CALL frame
!---
CALL MAIN65
!---
IF 0< M THEN PRINT " (";STR$(DX);"x";STR$(DY);"/";STR$(U0);",";STR$(V0);") ";debug$;" abort by ";BSTR$(M,16) !!!
PRINT right$("000"& BSTR$(byt-2*SGN(M),16),4) !!!
CALL R_BIN31(M) ! return at img.top, or EOI
!---
DO WHILE M=BVAL("DA",16) !SOS
IF 0<=HAC(0) THEN
LET MV(0)=1
LET MH(0)=1
LET DU=DU8
LET DV_=DV8
END IF
CALL frame
LET MV(0)=MV_
LET MH(0)=MH_
LET DU=DUM
LET DV_=DVM
!---
IF Ss_<>Se_ AND M3(0)=M3(1) AND M3(1)=M3(2) THEN CALL MAIN65
!---
IF 0< M THEN PRINT " (";STR$(DX);"x";STR$(DY);"/";STR$(U0);",";STR$(V0);") ";debug$;" abort by ";BSTR$(M,16) !!!
PRINT right$("000"& BSTR$(byt-2*SGN(M),16),4) !!!
CALL R_BIN31(M) ! return at img.top
LOOP
CLOSE #1 ! FL$
END SUB
SUB reset0
LET B2(0)=0 !ROUND( YDC0/DQ(0,0,QS(0)) ) !prediction YDC.( 1st.reference level)
LET B2(1)=0 !prediction CbDC.
LET B2(2)=0 !prediction CrDC.
LET Hx=0 !bits stream input buffer 0~(7+8)bits, use fraction
LET BC=0 !stored bits in Hx
LET NA=0 !nest adr. in A()
LET EOB=0 !counter( end_of_band)
LET M=0
LET ext=0
END SUB
!Page-2 へ続く
|
|