-
Notifications
You must be signed in to change notification settings - Fork 0
/
jpeg13.bas
661 lines (605 loc) · 22.3 KB
/
jpeg13.bas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
DECLARE SUB QuitWithError (message$)
'JPEG Viewer by Dmitry Brant Version 1.2
'
'http://dmitrybrant.com
'me@dmitrybrant.com
'
'This program is freeware. Use freely, but give me credit where credit
'is due. Feel free to make improvements, additions, and optimizations.
'If you do, please tell me or show me what you have done.
'This program is also provided on an "as-is" basis.
'I can't be held responsible for the mischevious deeds you may perform
'with the aid of this program.
'
'NOTE: This specific edition of the viewer is designed to work with SCREEN 13.
'Because SCREEN 13 does not support packed-pixeling (HiColor), the JPG files
'can only be displayed in grayscale.
'The program will create a grayscale palette (0 to 255), and display only the
'Luminance (Y) attribute of the JPG file.
'This is the only SUB that has to be called to display the image.
DECLARE SUB PutJPG13 (file$, x0%, y0%)
'file$ = filename of the JPG image
'x0, y0 = coordinates where to start drawing the image
'These other functions are called from within the PutJPG sub.
'They are useless by themselves.
DECLARE FUNCTION Decode% (inArray() AS ANY, hnum%)
DECLARE FUNCTION ReceiveBits% (cat%)
DECLARE FUNCTION NextBit% ()
DECLARE SUB ToRGB (y0%, cb0%, cr0%, r0%, g0%, b0%)
DECLARE SUB GetBlock (vector%(), HuffDC() AS ANY, HuffDCNum%, HuffAC() AS ANY, HuffACNum%, Quant%(), QuantNum%, dcCoef%)
DECLARE FUNCTION GetHuffTables% ()
DECLARE FUNCTION GetQuantTables% (inArray() AS INTEGER)
DECLARE FUNCTION GetSOS% ()
DECLARE FUNCTION GetWord& ()
DECLARE FUNCTION GetByte% ()
DECLARE FUNCTION GetSOI% ()
DECLARE FUNCTION GetImageAttr% ()
DEFINT A-Z
TYPE JpegType 'some type definitions (for coherence)
rows AS INTEGER 'image height
cols AS INTEGER 'image width
SamplesY AS INTEGER 'sampling ratios
SamplesCbCr AS INTEGER
QuantTableY AS INTEGER 'quantization table numbers
QuantTableCbCr AS INTEGER
HuffDCTableY AS INTEGER 'huffman table numbers
HuffDCTableCbCr AS INTEGER
HuffACTableY AS INTEGER
HuffACTableCbCr AS INTEGER
NumComp AS INTEGER 'number of components
END TYPE
TYPE HuffmanEntry 'a type for huffman tables
Index AS LONG
Code AS INTEGER
Length AS INTEGER
END TYPE
'a few global variables
COMMON SHARED curByte, curBits, jfile, EOI, DCTables, ACTables, QTables
COMMON SHARED a$
DIM SHARED image AS JpegType
DIM SHARED HuffmanDC(0 TO 1, 0 TO 255) AS HuffmanEntry
DIM SHARED HuffmanAC(0 TO 1, 0 TO 255) AS HuffmanEntry
DIM SHARED dct(0 TO 7, 0 TO 7, 0 TO 7, 0 TO 7) AS INTEGER
'--------- A demonstration ----------
CLS
FILES "*.jpg": PRINT
INPUT "Enter a valid .JPG image file name> ", f$
SCREEN 13: COLOR 255
OUT &H3C8, 0 'create the grayscale palette
FOR i = 0 TO 255: OUT &H3C9, i \ 4: OUT &H3C9, i \ 4: OUT &H3C9, i \ 4: NEXT i
PutJPG13 f$, 0, 0 'draw the image at offset 0,0
BEEP
SYSTEM
'--------- End of Demo ----------
Zig2: 'Zigzag patterns for reordering quantization tables and vectors
DATA 0,0
ZigzagPositions:
DATA 0,1,1,0
DATA 2,0,1,1,0,2
DATA 0,3,1,2,2,1,3,0
DATA 4,0,3,1,2,2,1,3,0,4
DATA 0,5,1,4,2,3,3,2,4,1,5,0
DATA 6,0,5,1,4,2,3,3,2,4,1,5,0,6
DATA 0,7,1,6,2,5,3,4,4,3,5,2,6,1,7,0
DATA 7,1,6,2,5,3,4,4,3,5,2,6,1,7
DATA 2,7,3,6,4,5,5,4,6,3,7,2
DATA 7,3,6,4,5,5,4,6,3,7
DATA 4,7,5,6,6,5,7,4
DATA 7,5,6,6,5,7
DATA 6,7,7,6
DATA 7,7
FUNCTION Decode (inArray() AS HuffmanEntry, hnum)
IF GetByte = 255 THEN
n1 = GetByte
IF n1 >= &HD0 AND n1 <= &HD7 THEN
n2 = 2 ^ curBits - 1
SEEK #jfile, SEEK(jfile) - 2
IF curByte AND n2 = n2 THEN 'if the remaining bits are 1
EOI = 1
Decode = 0
EXIT FUNCTION
END IF
ELSE
SEEK #jfile, SEEK(jfile) - 2
END IF
ELSE
SEEK #jfile, SEEK(jfile) - 1
END IF
curVal& = 0
MatchFound = -1
FOR l = 1 TO 16 'cycle through 16 possible Huffman lengths
curVal& = curVal& * 2 + NextBit
IF EOI THEN EXIT FUNCTION
FOR i = 0 TO 255 'look for a match in the Huffman table
IF inArray(hnum, i).Length > l THEN EXIT FOR
IF inArray(hnum, i).Length = l THEN
IF inArray(hnum, i).Index = curVal& THEN MatchFound = i: EXIT FOR
END IF
NEXT i
IF MatchFound > -1 THEN EXIT FOR
NEXT l
IF MatchFound = -1 THEN BEEP: Decode = -1: EXIT FUNCTION
Decode = inArray(hnum, MatchFound).Code 'return the appropriate code
END FUNCTION
SUB GetBlock (vector(), HuffDC() AS HuffmanEntry, HuffDCNum, HuffAC() AS HuffmanEntry, HuffACNum, Quant(), QuantNum, dcCoef)
DIM array2(0 TO 7, 0 TO 7)
EOI = 0
temp0 = Decode(HuffDC(), HuffDCNum) 'Get the DC coefficient
IF EOI THEN d = 0
dcCoef = dcCoef + ReceiveBits(temp0)
vector(0, 0) = dcCoef * Quant(QuantNum, 0, 0)
xpos = 0: ypos = 0
RESTORE ZigzagPositions
ACcount = 1
DO
d = Decode(HuffAC(), HuffACNum)
IF EOI THEN d = 0
zeros = d \ 16
bits = d AND 15
bitVal = ReceiveBits(bits)
IF zeros = 0 AND bits = 0 THEN 'EOB Encountered
FOR j = ACcount TO 63
READ xpos, ypos
vector(xpos, ypos) = 0
NEXT j
EXIT DO
ELSEIF zeros = 15 AND bits = 0 THEN 'ZRL encountered
FOR j = ACcount TO ACcount + 15
READ xpos, ypos
vector(xpos, ypos) = 0
NEXT j
ACcount = ACcount + 16
ELSE
FOR j = 1 TO zeros
READ xpos, ypos
vector(xpos, ypos) = 0
ACcount = ACcount + 1
IF ACcount >= 64 THEN EXIT DO
NEXT j
READ xpos, ypos
vector(xpos, ypos) = bitVal * Quant(QuantNum, xpos, ypos)
ACcount = ACcount + 1
END IF
IF ACcount >= 64 THEN EXIT DO
LOOP
FOR x = 0 TO 7 'the IDCT routine (this SOB flies!)
FOR y = 0 TO 7
sum = 0
FOR v = 0 TO 7
FOR u = 0 TO 7
temp& = vector(u, v)
IF temp& THEN temp& = temp& * dct(x, y, u, v) / 512
sum = sum + temp&
NEXT u
NEXT v
array2(x, y) = sum
NEXT y
NEXT x
FOR u = 0 TO 7
FOR v = 0 TO 7
vector(u, v) = array2(u, v) + 128
NEXT v
NEXT u
END SUB
FUNCTION GetByte
GET #jfile, , a$
GetByte = ASC(a$)
END FUNCTION
FUNCTION GetHuffTables
DIM HuffAmount(1 TO 16)
l0 = GetWord
c0 = 2
DO
temp0 = GetByte: c0 = c0 + 1
t0 = (temp0 AND 16) \ 16
temp0 = temp0 AND 15
SELECT CASE t0
CASE 0 'DC Table
total = 0
FOR i = 1 TO 16
temp1 = GetByte: c0 = c0 + 1
total = total + temp1
HuffAmount(i) = temp1
NEXT i
FOR i = 0 TO total - 1
HuffmanDC(temp0, i).Code = GetByte: c0 = c0 + 1
NEXT i
curNum& = 0
curIndex = -1
FOR i = 1 TO 16
FOR j = 1 TO HuffAmount(i)
curIndex = curIndex + 1
HuffmanDC(temp0, curIndex).Index = curNum&
HuffmanDC(temp0, curIndex).Length = i
curNum& = curNum& + 1
NEXT j
curNum& = curNum& * 2
NEXT i
DCTables = DCTables + 1
CASE 1
total = 0
FOR i = 1 TO 16
temp1 = GetByte: c0 = c0 + 1
total = total + temp1
HuffAmount(i) = temp1
NEXT i
FOR i = 0 TO total - 1
HuffmanAC(temp0, i).Code = GetByte: c0 = c0 + 1
NEXT i
curNum& = 0
curIndex = -1
FOR i = 1 TO 16
FOR j = 1 TO HuffAmount(i)
curIndex = curIndex + 1
HuffmanAC(temp0, curIndex).Index = curNum&
HuffmanAC(temp0, curIndex).Length = i
curNum& = curNum& + 1
NEXT j
curNum& = curNum& * 2
NEXT i
ACTables = ACTables + 1
END SELECT
LOOP UNTIL c0 >= l0
GetHuffTables = 1
END FUNCTION
FUNCTION GetImageAttr
temp4& = GetWord 'Length of segment
temp0 = GetByte 'Data precision
IF temp0 <> 8 THEN GetImageAttr = 0: EXIT FUNCTION 'we do not support 12 or 16-bit samples
image.rows = GetWord 'Image Height
image.cols = GetWord 'Image Width
temp0 = GetByte 'Number of components
FOR i = 1 TO temp0
id = GetByte
SELECT CASE id
CASE 1
temp1 = GetByte
image.SamplesY = (temp1 AND 15) * (temp1 \ 16)
image.QuantTableY = GetByte
CASE 2, 3
temp1 = GetByte
image.SamplesCbCr = (temp1 AND 15) * (temp1 \ 16)
image.QuantTableCbCr = GetByte
END SELECT
NEXT i
GetImageAttr = 1
END FUNCTION
FUNCTION GetQuantTables (inArray() AS INTEGER)
l0 = GetWord
c0 = 2
DO
temp0 = GetByte: c0 = c0 + 1
IF temp0 AND &HF0 THEN
GetQuantTables = 0: EXIT FUNCTION 'we don't support 16-bit tables
END IF
temp0 = temp0 AND 15
RESTORE Zig2
xp = 0: yp = 0
FOR i = 0 TO 63
READ xp, yp
inArray(temp0, xp, yp) = GetByte: c0 = c0 + 1
NEXT i
QTables = QTables + 1
LOOP UNTIL c0 >= l0
GetQuantTables = 1: EXIT FUNCTION
END FUNCTION
FUNCTION GetSOI
a$ = " "
SEEK #jfile, 1
GET #jfile, , a$
IF a$ = CHR$(255) + CHR$(&HD8) THEN d = 1 ELSE d = 0
a$ = " "
GetSOI = d
END FUNCTION
FUNCTION GetSOS
temp4& = GetWord
temp0 = GetByte
IF temp0 <> 1 AND temp0 <> 3 THEN GetSOS = 0: EXIT FUNCTION
image.NumComp = temp0
FOR i = 1 TO temp0
temp1 = GetByte
SELECT CASE temp1
CASE 1
temp2 = GetByte
image.HuffACTableY = temp2 AND 15
image.HuffDCTableY = temp2 \ 16
CASE 2
temp2 = GetByte
image.HuffACTableCbCr = temp2 AND 15
image.HuffDCTableCbCr = temp2 \ 16
CASE 3
temp2 = GetByte
image.HuffACTableCbCr = temp2 AND 15
image.HuffDCTableCbCr = temp2 \ 16
CASE ELSE
GetSOS = 0: EXIT FUNCTION
END SELECT
NEXT i
a$ = " " '3 reserved bytes (?)
GET #1, , a$
a$ = " "
GetSOS = 1
END FUNCTION
FUNCTION GetWord&
GET #jfile, , a$
l0& = CLNG(ASC(a$)) * 256
GET #jfile, , a$
l0& = l0& + ASC(a$)
GetWord& = l0&
END FUNCTION
FUNCTION NextBit
t0 = 2 ^ curBits
v0 = -((curByte AND t0) <> 0)
curBits = curBits - 1
IF curBits < 0 THEN
curBits = 7: curByte = GetByte
IF curByte = 255 THEN
IF GetByte = &HD9 THEN EOI = 1: EXIT FUNCTION
END IF
END IF
NextBit = v0
END FUNCTION
SUB PutJPG13 (file$, x0, y0)
DIM YVector1(0 TO 7, 0 TO 7) '4 vectors for Y attribute
DIM YVector2(0 TO 7, 0 TO 7)
DIM YVector3(0 TO 7, 0 TO 7)
DIM YVector4(0 TO 7, 0 TO 7)
DIM CbVector(0 TO 7, 0 TO 7) '1 vector for Cb attribute
DIM CrVector(0 TO 7, 0 TO 7) '1 vector for Cr attribute
DIM QuantTable(0 TO 1, 0 TO 7, 0 TO 7) '2 quantization tables (Y, CbCr)
FOR x = 0 TO 7 'Initialize our cosine table
FOR y = 0 TO 7
FOR u = 0 TO 7
FOR v = 0 TO 7
t! = COS((2 * x + 1) * u * .1963495) * COS((2 * y + 1) * v * .1963495)
IF u = 0 THEN t! = t! * .707107
IF v = 0 THEN t! = t! * .707107
dct(x, y, u, v) = t! * 128
NEXT v
NEXT u
NEXT y
NEXT x
jfile = FREEFILE
a$ = " " 'The ideal byte
OPEN file$ FOR BINARY AS #jfile
IF LOF(jfile) = 0 THEN CLOSE #jfile: KILL file$: QuitWithError "File does not exist."
IF GetSOI = 0 THEN CLOSE #jfile: QuitWithError "Not a valid JPEG/JFIF file."
QTables = 0 'Initialize some checkpoint variables
ACTables = 0
DCTables = 0
Restart& = 0
DO 'Primary control loop for markers
IF GetByte = 255 THEN 'Marker Found
d = GetByte
SELECT CASE d 'which one is it?
CASE &HC0 'SOF0
IF GetImageAttr = 0 THEN QuitWithError "Error getting SOF0 Marker."
CASE &HC1 'SOF1
IF GetImageAttr = 0 THEN QuitWithError "Error getting SOF 1 Marker."
CASE &HC9 'SOF9
QuitWithError "Arithmetic Coding Not Supported."
CASE &HC4 'DHT
IF ACTables < 2 OR DCTables < 2 THEN
IF GetHuffTables = 0 THEN QuitWithError "Error getting Huffman tables."
END IF
CASE &HCC 'DAC
QuitWithError "Arithmetic Coding Not Supported."
CASE &HDA 'SOS
IF GetSOS = 0 THEN QuitWithError "Error getting SOS marker."
IF (DCTables = 2 AND ACTables = 2 AND QTables = 2) OR image.NumComp = 1 THEN
EOI = 0
EXIT DO 'Go on to secondary control loop
ELSE
QuitWithError "Unexpected file format."
END IF
CASE &HDB 'DQT
IF QTables < 2 THEN
IF GetQuantTables(QuantTable()) = 0 THEN QuitWithError "Error getting quantization tables."
END IF
CASE &HDD 'DRI
Restart& = GetWord
CASE &HE0 'APP0
temp1& = GetWord 'Length of segment
a$ = " "
GET #1, , a$ 'JFIF header
a$ = " "
temp0 = GetByte 'Major revision
temp0 = GetByte 'Minor revision
temp0 = GetByte 'Density definition
temp0 = GetByte 'X-Density
temp0 = GetByte 'Y-Density
temp0 = GetByte 'Thumbnail Width
temp1 = GetByte 'Thumbnail Height
CASE &HFE 'COM
a$ = SPACE$(GetWord - 2)
GET #1, , a$ 'Retrieve comment
a$ = " "
END SELECT
END IF
r$ = INKEY$
IF r$ = CHR$(27) THEN CLOSE #jfile: EXIT SUB
LOOP UNTIL EOF(1)
xpos = 0: ypos = 0
dcY = 0: dcCb = 0: dcCr = 0
xindex = 0: yindex = 0: mcu = 0
r = 0: g = 0: b = 0
curBits = 7: curByte = GetByte
DEF SEG = &HA000
SELECT CASE image.NumComp
CASE 3
SELECT CASE image.SamplesY
CASE 4
DO
GetBlock YVector1(), HuffmanDC(), image.HuffDCTableY, HuffmanAC(), image.HuffACTableY, QuantTable(), image.QuantTableY, dcY
GetBlock YVector2(), HuffmanDC(), image.HuffDCTableY, HuffmanAC(), image.HuffACTableY, QuantTable(), image.QuantTableY, dcY
GetBlock YVector3(), HuffmanDC(), image.HuffDCTableY, HuffmanAC(), image.HuffACTableY, QuantTable(), image.QuantTableY, dcY
GetBlock YVector4(), HuffmanDC(), image.HuffDCTableY, HuffmanAC(), image.HuffACTableY, QuantTable(), image.QuantTableY, dcY
GetBlock CbVector(), HuffmanDC(), image.HuffDCTableCbCr, HuffmanAC(), image.HuffACTableCbCr, QuantTable(), image.QuantTableCbCr, dcCb
GetBlock CrVector(), HuffmanDC(), image.HuffDCTableCbCr, HuffmanAC(), image.HuffACTableCbCr, QuantTable(), image.QuantTableCbCr, dcCr
FOR i = 0 TO 7
FOR j = 0 TO 7
y = YVector1(i, j)
IF y < 0 THEN y = 0
IF y > 255 THEN y = 255
xj = xindex + j: yi = yindex + i
o& = CLNG(yi + y0) * 320 + xj + x0
IF xj < image.cols AND yi < image.rows AND yi + y0 < 200 AND xj + x0 < 320 THEN POKE o&, y
NEXT j
NEXT i
FOR i = 0 TO 7
FOR j = 8 TO 15
y = YVector2(i, j - 8)
IF y < 0 THEN y = 0
IF y > 255 THEN y = 255
xj = xindex + j: yi = yindex + i
o& = CLNG(yi + y0) * 320 + xj + x0
IF xj < image.cols AND yi < image.rows AND yi + y0 < 200 AND xj + x0 < 320 THEN POKE o&, y
NEXT j
NEXT i
FOR i = 8 TO 15
FOR j = 0 TO 7
y = YVector3(i - 8, j)
IF y < 0 THEN y = 0
IF y > 255 THEN y = 255
xj = xindex + j: yi = yindex + i
o& = CLNG(yi + y0) * 320 + xj + x0
IF xj < image.cols AND yi < image.rows AND yi + y0 < 200 AND xj + x0 < 320 THEN POKE o&, y
NEXT j
NEXT i
FOR i = 8 TO 15
FOR j = 8 TO 15
y = YVector4(i - 8, j - 8)
IF y < 0 THEN y = 0
IF y > 255 THEN y = 255
xj = xindex + j: yi = yindex + i
o& = CLNG(yi + y0) * 320 + xj + x0
IF xj < image.cols AND yi < image.rows AND yi + y0 < 200 AND xj + x0 < 320 THEN POKE o&, y
NEXT j
NEXT i
xindex = xindex + 16
IF xindex >= image.cols THEN xindex = 0: yindex = yindex + 16: mcu = 1
IF mcu = 1 AND Restart& <> 0 THEN 'execute the restart interval
curByte = GetByte: curByte = GetByte: curByte = GetByte
curBits = 7
dcY = 0: dcCb = 0: dcCr = 0: mcu = 0
END IF
r$ = INKEY$
IF r$ = CHR$(27) THEN EXIT DO
LOOP UNTIL EOF(jfile) OR yindex >= image.rows OR yindex > 199
CASE 2
DO
GetBlock YVector1(), HuffmanDC(), image.HuffDCTableY, HuffmanAC(), image.HuffACTableY, QuantTable(), image.QuantTableY, dcY
GetBlock YVector2(), HuffmanDC(), image.HuffDCTableY, HuffmanAC(), image.HuffACTableY, QuantTable(), image.QuantTableY, dcY
GetBlock CbVector(), HuffmanDC(), image.HuffDCTableCbCr, HuffmanAC(), image.HuffACTableCbCr, QuantTable(), image.QuantTableCbCr, dcCb
GetBlock CrVector(), HuffmanDC(), image.HuffDCTableCbCr, HuffmanAC(), image.HuffACTableCbCr, QuantTable(), image.QuantTableCbCr, dcCr
FOR i = 0 TO 7
FOR j = 0 TO 7
y = YVector1(i, j)
IF y < 0 THEN y = 0
IF y > 255 THEN y = 255
xj = xindex + j: yi = yindex + i
o& = CLNG(yi + y0) * 320 + xj + x0
IF xj < image.cols AND yi < image.rows AND yi + y0 < 200 AND xj + x0 < 320 THEN POKE o&, y
NEXT j
NEXT i
FOR i = 0 TO 7
FOR j = 8 TO 15
y = YVector2(i, j - 8)
IF y < 0 THEN y = 0
IF y > 255 THEN y = 255
xj = xindex + j: yi = yindex + i
o& = CLNG(yi + y0) * 320 + xj + x0
IF xj < image.cols AND yi < image.rows AND yi + y0 < 200 AND xj + x0 < 320 THEN POKE o&, y
NEXT j
NEXT i
xindex = xindex + 16
IF xindex >= image.cols THEN xindex = 0: yindex = yindex + 8: mcu = 1
IF mcu = 1 AND Restart& <> 0 THEN 'execute the restart interval
curByte = GetByte: curByte = GetByte: curByte = GetByte
curBits = 7
dcY = 0: dcCb = 0: dcCr = 0: mcu = 0
END IF
r$ = INKEY$
IF r$ = CHR$(27) THEN EXIT DO
LOOP UNTIL EOF(jfile) OR yindex >= image.rows OR yindex > 199
CASE 1
DO
GetBlock YVector1(), HuffmanDC(), image.HuffDCTableY, HuffmanAC(), image.HuffACTableY, QuantTable(), image.QuantTableY, dcY
GetBlock CbVector(), HuffmanDC(), image.HuffDCTableCbCr, HuffmanAC(), image.HuffACTableCbCr, QuantTable(), image.QuantTableCbCr, dcCb
GetBlock CrVector(), HuffmanDC(), image.HuffDCTableCbCr, HuffmanAC(), image.HuffACTableCbCr, QuantTable(), image.QuantTableCbCr, dcCr
FOR i = 0 TO 7
FOR j = 0 TO 7
y = YVector1(i, j)
IF y < 0 THEN y = 0
IF y > 255 THEN y = 255
xj = xindex + j: yi = yindex + i
o& = CLNG(yi + y0) * 320 + xj + x0
IF xj < image.cols AND yi < image.rows AND yi + y0 < 200 AND xj + x0 < 320 THEN POKE o&, y
NEXT j
NEXT i
xindex = xindex + 8
IF xindex >= image.cols THEN xindex = 0: yindex = yindex + 8: mcu = 1
IF mcu = 1 AND Restart& <> 0 THEN 'execute the restart interval
curByte = GetByte: curByte = GetByte: curByte = GetByte
curBits = 7
dcY = 0: dcCb = 0: dcCr = 0: mcu = 0
END IF
r$ = INKEY$
IF r$ = CHR$(27) THEN EXIT DO
LOOP UNTIL EOF(jfile) OR yindex >= image.rows OR yindex > 199
END SELECT
CASE 1
DO
GetBlock YVector1(), HuffmanDC(), image.HuffDCTableY, HuffmanAC(), image.HuffACTableY, QuantTable(), image.QuantTableY, dcY
FOR i = 0 TO 7
FOR j = 0 TO 7
y = YVector1(i, j)
IF y < 0 THEN y = 0
IF y > 255 THEN y = 255
xj = xindex + j: yi = yindex + i
o& = CLNG(yi + y0) * 320 + xj + x0
IF xj < image.cols AND yi < image.rows AND yi + y0 < 200 AND xj + x0 < 320 THEN POKE o&, y
NEXT j
NEXT i
xindex = xindex + 8
IF xindex >= image.cols THEN xindex = 0: yindex = yindex + 8: mcu = 1
IF mcu = 1 AND Restart& <> 0 THEN 'execute the restart interval
curByte = GetByte: curByte = GetByte: curByte = GetByte
curBits = 7
dcY = 0: mcu = 0
END IF
r$ = INKEY$
IF r$ = CHR$(27) THEN EXIT DO
LOOP UNTIL EOF(jfile) OR yindex >= image.rows OR yindex > 199
END SELECT
DEF SEG
CLOSE #jfile
END SUB
SUB QuitWithError (message$)
SCREEN 0: WIDTH 80, 25
CLS : PRINT message$
CLOSE
SYSTEM
END SUB
FUNCTION ReceiveBits (cat)
temp0& = 0
FOR i = 1 TO cat
temp0& = temp0& * 2 + NextBit
NEXT i
IF temp0& >= 2 ^ (cat - 1) THEN
ReceiveBits = temp0&
ELSE
ReceiveBits = -(2 ^ cat - 1) + temp0&
END IF
END FUNCTION
SUB ToRGB (y0, cb0, cr0, r0, g0, b0)
r0 = y0 + 1.402 * (cr0 - 128)
g0 = y0 - .34414 * (cb0 - 128) - .71414 * (cr0 - 128)
b0 = y0 + 1.772 * (cb0 - 128)
IF r0 > 255 THEN r0 = 255
IF r0 < 0 THEN r0 = 0
IF g0 > 255 THEN g0 = 255
IF g0 < 0 THEN g0 = 0
IF b0 > 255 THEN b0 = 255
IF b0 < 0 THEN b0 = 0
END SUB