1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module zmbv_test
/*is aliced*/;
19 import core
.stdc
.stdlib
: malloc
, free
;
20 import core
.stdc
.string
: memset
, memcpy
, memcmp
;
32 ////////////////////////////////////////////////////////////////////////////////
33 // each KeyframeInterval frame will be key one
34 enum KeyframeInterval
= 300;
37 ////////////////////////////////////////////////////////////////////////////////
38 string inname
, outname
;
41 ubyte[256*3] curPal
= void;
42 ubyte[320*240] curScreen
= void;
47 Codec
.Compression cpr
= Codec
.Compression
.ZLib
;
51 ////////////////////////////////////////////////////////////////////////////////
54 flScreen
= File(inname
, "r");
55 flScreen
.rawRead((&scc
)[0..1]);
56 if (scc
== 0) throw new Exception("invalid screen cound!");
58 writefln("%s screens found", screenCount
);
64 if (flScreen
.isOpen
) flScreen
.close();
68 ////////////////////////////////////////////////////////////////////////////////
69 // 4 bytes: screen count
70 // 768+320*240: screen
72 if (frameNo
< screenCount
) {
73 flScreen
.rawRead(curPal
);
74 flScreen
.rawRead(curScreen
);
82 ////////////////////////////////////////////////////////////////////////////////
83 void encodeScreens (void delegate (const(void)[] buf
) writer
) {
84 auto zc
= new Encoder(320, 240, Codec
.bpp2format(8), complevel
, cpr
);
85 auto zd
= new Decoder(320, 240);
86 scope(exit
) { zc
.clear(); zd
.clear(); }
89 while (nextScreen()) {
90 thisIsKeyframe
= ((frameNo
-1)%KeyframeInterval
== 0);
91 zc
.prepareFrame((thisIsKeyframe ? zc
.PrepareFlags
.Keyframe
: zc
.PrepareFlags
.None
), curPal
);
92 foreach (/*auto*/ y
; 0..240) zc
.encodeLine(curScreen
[y
*320..(y
+1)*320]);
93 auto written
= zc
.finishFrame();
95 zd
.decodeFrame(written
);
96 ubyte fb
= (cast(ubyte[])written
)[0];
98 enforce(zd
.paletteChanged
);
100 enforce(((fb
&0x02) != 0) == zd
.paletteChanged
);
102 enforce(zd
.palette
== curPal
);
103 foreach (/*auto*/ y
; 0..240) {
104 auto line
= zd
.line(y
);
105 if (curScreen
[y
*320..(y
+1)*320] != line
[]) {
106 writeln("\nframe ", frameNo
, "; line ", y
);
107 foreach (/*auto*/ x
; 0..320) {
108 if (curScreen
[y
*320+x
] != line
[x
]) {
109 writefln(" x=%3s; orig=0x%02x; unp=0x%02x", x
, curScreen
[y
*320+x
], line
[x
]);
115 uint prc
= 100*frameNo
/screenCount
;
117 stdout
.writef("\r[%s/%s] %s%%", frameNo
, screenCount
, prc
);
122 stdout
.writefln("\r[%s/%s] %s%%", frameNo
, screenCount
, 100);
126 ////////////////////////////////////////////////////////////////////////////////
127 void encodeScreensToBin () {
128 auto fo
= File(outname
, "w");
130 void writer (const(void)[] buf
) {
131 if (thisIsKeyframe
) idxarray
~= cast(uint)fo
.tell
;
132 uint size
= cast(uint)buf
.length
;
133 fo
.rawWrite((&size
)[0..1]);
137 uint scc
= screenCount
;
139 fo
.rawWrite((&scc
)[0..1]);
142 fo
.rawWrite((&scc
)[0..1]);
144 fo
.rawWrite((&scc
)[0..1]);
145 encodeScreens(&writer
);
148 fo
.rawWrite(idxarray
);
151 scc
= cast(uint)idxarray
.length
;
152 fo
.rawWrite((&scc
)[0..1]);
153 scc
= cast(uint)ipos
;
154 fo
.rawWrite((&scc
)[0..1]);
158 ////////////////////////////////////////////////////////////////////////////////
159 void main (string
[] args
) {
161 std
.getopt
.config
.caseSensitive
,
162 std
.getopt
.config
.bundling
,
164 "Z", (string opt
) { cpr
= Codec
.Compression
.None
; },
166 if (complevel
> 9) throw new Exception("invalid compression level");
167 if (args
.length
< 2) throw new Exception("input file name missing");
168 if (args
.length
> 3) throw new Exception("too many file names");
170 if (args
.length
< 3) {
171 outname
= inname
.setExtension(".zmbv");
173 outname
= args
[2].defaultExtension(".zmbv");
175 writefln("using compression level %s", complevel
);
177 encodeScreensToBin();