|
From: <Gene_Gaunt@ReviewWorks.com>
> Does anyone have an MI example of CCITT group 4 decompression?
>
Yes, I wrote one for Harry Williams.
This will be a forthcoming chapter of my book.
Below is the guts of it.
It uses three tables that are generated automatically from
a list of the code words.
contact me privately for more.
Leif
/* DECOMPRESS TIFF T6 ENCODING */
/* LEIF SVALGAARD, 2002/02/05 */
DCL SPCPTR .PARM1 PARM;
DCL DD CONTROL CHAR(64) BAS(.PARM1);
DCL DD ROW-BITS BIN(2) DEF(CONTROL) POS( 1);
DCL DD NBR-OF-ROWS BIN(2) DEF(CONTROL) POS( 3);
DCL DD FIRST-TIME CHAR(1) DEF(CONTROL) POS( 5);
DCL SPCPTR .PARM2 PARM;
DCL DD SOURCE CHAR(512000) BAS(.PARM2);
DCL SPCPTR .PARM3 PARM;
DCL DD ROW CHAR(1000) BAS(.PARM3);
DCL OL PARMS(.PARM1, .PARM2, .PARM3) EXT PARM MIN(3);
DCL DD SHIFTX CHAR(4);
DCL DD SHIFT BIN(2) UNSGND DEF(SHIFTX) POS(3);
DCL DD BYTE-POS BIN(4) UNSGND;
DCL DD BIT-POS BIN(4) UNSGND;
DCL DD BIT-POSX CHAR(4) DEF(BIT-POS) POS(1);
DCL DD BITS CHAR(4);
DCL DD TABLE-INDEX BIN(2) UNSGND DEF(BITS) POS(1);
DCL DD ITEM-AREA CHAR(6) INIT(X'0000');
DCL DD ITEM-LENGTHX CHAR(4) DEF(ITEM-AREA) POS(1);
DCL DD ITEM CHAR(4) DEF(ITEM-AREA) POS(3);
DCL DD ITEM-LENGTH BIN(2) UNSGND DEF(ITEM) POS(1);
DCL DD ITEM-VALUE BIN(2) UNSGND DEF(ITEM) POS(3);
DCL DD A0 BIN(2) UNSGND;
DCL DD A1 BIN(2) UNSGND;
DCL DD A2 BIN(2) UNSGND;
DCL DD DIFF BIN(2);
/* RUNS ARE KEPT TRACK OF BY STORING THE PIXEL NUMBER */
/* OF THEIR 'TOP' PIXEL, I.E. THE NEXT PIXEL AFTER THE */
/* RUN. THEIR COLOR ALTERNATE: THE FIRST AND GENERALLY */
/* THE ODD-NUMBERED RUNS ARE WHITE. */
DCL DD CUR-RUN-NBR BIN(4) BDRY(4);
DCL DD CUR-RUNS CHAR(2000);
DCL DD CUR-RUN (1000) BIN(2) UNSGND DEF(CUR-RUNS) POS(1);
DCL DD REF-RUN-NBR BIN(4) BDRY(4);
DCL DD REF-RUN-NBRX CHAR(4) DEF(REF-RUN-NBR) POS(1);
DCL DD REF-RUNS CHAR(2000);
DCL DD REF-RUN (1000) BIN(2) UNSGND DEF(REF-RUNS) POS(1);
DCL DD MOVE BIN(4);
DCL DD ROW-CHARS BIN(2);
DCL DD BITS-TO-OUTPUT BIN(2);
DCL DD BIT-OUT-IDX BIN(2);
DCL DD THE-MODE BIN(2);
DCL DD THE-LENGTH BIN(2);
DCL DD THE-COLOR BIN(2);
DCL DD THE-ODDITY BIN(2);
ENTRY * (PARMS) EXT;
OVRPGATR 1, 2; /* NO ARRAY CHECKING */
OVRPGATR 2, 2; /* NO STRING CHECKING */
OVRPGATR 3, 1; /* NO BINARY SIZE CHECKING */
CMPBLA(B) FIRST-TIME, "Y"/NEQ(RESET-RUNS);
CPYBLA FIRST-TIME, "N";
CPYNV BIT-POS, 8; /* START AT CHAR POS 1 */
INIT-REFERENCE-LINE:
ADDN REF-RUN(1), ROW-BITS, 1;
MULTIPLE-OF-16-BYTES:
ADDN ROW-CHARS, ROW-BITS, 127;
CPYBTRLS ROW-CHARS, ROW-CHARS, 7;
CPYBTLLS ROW-CHARS, ROW-CHARS, 4;
RESET-RUNS:
CPYNV A0, 1;
CPYNV THE-COLOR, 0;
CPYNV CUR-RUN-NBR, 0;
CPYNV REF-RUN-NBR, 0;
CPYNV BIT-OUT-IDX, 0;
CPYBLAP ROW(1:ROW-CHARS), X'00', X'00';
GET-MODE:
AND SHIFTX, BIT-POS, X'00000007';
CPYBTL BYTE-POS, BIT-POS, 0, 29;
CPYBTLLS BITS, SOURCE(BYTE-POS:4), SHIFT;
CPYBTL TABLE-INDEX, BITS, 0, 7; /* 128 */
CPYBLA ITEM, MODES(TABLE-INDEX);
ADDLC(S) BIT-POSX, ITEM-LENGTHX;
CMPNV(B) ITEM-VALUE, 7/HI(NOT-VERTICAL);
GOT-VERTICAL: /* 1 THRU 7 */
SUBN DIFF, ITEM-VALUE, 4; /*V-3 ..V0 ..V+3 */
CMPNV(B) REF-RUN-NBR, 1/NHI(VERTICAL-START);
SUBN(S) REF-RUN-NBR, 2;
FIND-B1-VERT:
ADDN(S) REF-RUN-NBR, 1; FB1V:
CMPNV(B) REF-RUN(REF-RUN-NBR), A0/NHI(FIND-B1-VERT);
AND THE-ODDITY, REF-RUN-NBRX(3:2), X'0001';
CMPNV(B) THE-ODDITY, THE-COLOR / EQ(FIND-B1-VERT);
ADDN BITS-TO-OUTPUT, REF-RUN(REF-RUN-NBR), DIFF;
SUBN(S) BITS-TO-OUTPUT, A0;
CALLI OUTPUT-BITS, *, .RETURN;
ADDN(S) A0, BITS-TO-OUTPUT;
XOR(S) THE-COLOR, X'0001';
UPDATE-CUR-RUNS:
ADDN(S) CUR-RUN-NBR, 1;
CPYNV CUR-RUN (CUR-RUN-NBR), A0;
SEE-IF-END-OF-ROW:
CMPNV(B) A0, ROW-BITS/NHI(GET-MODE);
AT-END-OF-ROW:
SUBN(SB) NBR-OF-ROWS, 1/NPOS(DONE);
UPDATE-REF-RUNS:
ADDN(B) MOVE, CUR-RUN-NBR, CUR-RUN-NBR/ZER(=+2);
CPYBLA REF-RUNS(1:MOVE), CUR-RUNS(1:MOVE);:
SANITY-CHECK:
SUBN(S) A0, 1; /* A0 MUST NOW = ROW-BITS + 1 */
CMPNV(B) A0, ROW-BITS/EQ(RETURN);
DONE:
CPYBLA FIRST-TIME, "E"; /* END */
RETURN:
RTX *;
VERTICAL-START:
CPYNV REF-RUN-NBR, 1;
B FB1V;
NOT-VERTICAL:
CMPNV(B) ITEM-VALUE, 8/HI(HORIZONTAL-RUNS);
GOT-PASS-CODE: /* 9 */
CMPNV(B) REF-RUN-NBR, 1/NHI(PASS-START);
SUBN(S) REF-RUN-NBR, 2;
FIND-B1-PASS:
ADDN(S) REF-RUN-NBR, 1; FB1P:
CMPNV(B) REF-RUN(REF-RUN-NBR), A0/NHI(FIND-B1-PASS);
AND THE-ODDITY, REF-RUN-NBRX(3:2), X'0001';
CMPNV(B) THE-ODDITY, THE-COLOR / EQ(FIND-B1-PASS);
ADDN(S) REF-RUN-NBR, 1;
SUBN BITS-TO-OUTPUT, REF-RUN(REF-RUN-NBR), A0;
CALLI OUTPUT-BITS, *, .RETURN;
ADDN(S) A0, BITS-TO-OUTPUT;
B SEE-IF-END-OF-ROW;
PASS-START:
CPYNV REF-RUN-NBR, 1;
B FB1P;
HORIZONTAL-RUNS: /* 8 */
GET-A0A1:
CALLI GET-RUN-LENGTH, *, .RETURN;
CPYNV BITS-TO-OUTPUT, THE-LENGTH;
CALLI OUTPUT-BITS, *, .RETURN;
XOR(S) THE-COLOR, X'0001';
ADDN A1, A0, THE-LENGTH;
ADDN(S) CUR-RUN-NBR, 1;
CPYNV CUR-RUN (CUR-RUN-NBR), A1;
GET-A1A2:
CALLI GET-RUN-LENGTH, *, .RETURN;
CPYNV BITS-TO-OUTPUT, THE-LENGTH;
CALLI OUTPUT-BITS, *, .RETURN;
XOR(S) THE-COLOR, X'0001';
ADDN A0, A1, THE-LENGTH;
B UPDATE-CUR-RUNS;
DCL INSPTR .RETURN;
ENTRY GET-RUN-LENGTH INT;
CMPNV(B) THE-COLOR, 0/NEQ(=+2);
SETSPP .THE-TABLE, WHITE;:
CMPNV(B) THE-COLOR, 1/NEQ(=+2);
SETSPP .THE-TABLE, BLACK;:
CPYNV THE-LENGTH, 0;
ADD-UP-THE-LENGTHS:
AND SHIFTX, BIT-POS, X'00000007';
CPYBTL BYTE-POS, BIT-POS, 0, 29;
CPYBTLLS BITS, SOURCE(BYTE-POS:4), SHIFT;
CPYBTL TABLE-INDEX, BITS, 0, 13; /* 8192 */
CPYBLA ITEM, THE-TABLE(TABLE-INDEX);
ADDN(S) THE-LENGTH, ITEM-VALUE;
ADDLC(S) BIT-POSX, ITEM-LENGTHX;
CMPNV(B) ITEM-VALUE, 63/HI(ADD-UP-THE-LENGTHS);
B .RETURN;
DCL DD PARTIAL-BYTE BIN(2);
DCL DD ALREADY-SET BIN(2);
DCL DD NBR-OF-BITS BIN(2);
DCL DD BYTE-NBR BIN(2);
DCL DD BYTES-TO-OUTPUT BIN(2);
DCL DD BITS-TO-SET(0:7) CHAR(8) BDRY(8)
INIT(X'80C0E0F0F8FCFEFF', /* 0: 1 11 111 ...*/
X'406070787C7E7F' , /* 1: X1 X11 X111 ...*/
X'2030383C3E3F' , /* 2: XX1 XX11 XX111 ...*/
X'10181C1E1F' , /* 3: XXX1 XXX11 XXX111 ..*/
X'080C0E0F' , /* 4: XXXX1 XXXX11 XXXX111 .*/
X'040607' , /* 5: XXXXX1 XXXXX11 XXXXX111 */
X'0203' , /* 6: XXXXXX1 XXXXXX11 */
X'01' );/* 7: XXXXXXX1 */
/* 1 BIT 2 BITS 3 BITS ..*/
DCL DD CUR-PATTERN CHAR(8) BDRY(8);
DCL DD BIT-PATTERN(8) CHAR(1) DEF(CUR-PATTERN) POS(1);
DCL DD FIRST-BITS (8) CHAR(1) DEF(BITS-TO-SET) POS(1);
ENTRY OUTPUT-BITS INT;
CMPNV(B) THE-COLOR, 0/EQ(UPDATE-BIT-OUT-INDEX);
OUTPUT-BLACK-BITS:
AND ALREADY-SET, BIT-OUT-IDX, X'0007';
CPYBLA CUR-PATTERN, BITS-TO-SET(ALREADY-SET);
SUBN PARTIAL-BYTE, 8, ALREADY-SET;
CPYBTRLS BYTE-NBR, BIT-OUT-IDX, 3;
ADDN(S) BYTE-NBR, 1;
CMPNV(B) BITS-TO-OUTPUT, PARTIAL-BYTE/HI(OUTPUT-PART);
OUTPUT-FEW:
OR(S) ROW(BYTE-NBR:1), BIT-PATTERN(BITS-TO-OUTPUT);
B UPDATE-BIT-OUT-INDEX;
OUTPUT-PART:
OR(S) ROW(BYTE-NBR:1), BIT-PATTERN(PARTIAL-BYTE);
ADDN(S) BYTE-NBR, 1;
SUBN NBR-OF-BITS, BITS-TO-OUTPUT, PARTIAL-BYTE;
CPYBTRLS BYTES-TO-OUTPUT, NBR-OF-BITS, 3;
CMPNV(B) BYTES-TO-OUTPUT, 0/EQ(OUTPUT-REMAINING);
OUTPUT-FULL-BYTES:
CPYBLAP ROW(BYTE-NBR:BYTES-TO-OUTPUT), X'FF', X'FF';
ADDN(S) BYTE-NBR, BYTES-TO-OUTPUT;
OUTPUT-REMAINING:
AND(B) PARTIAL-BYTE, NBR-OF-BITS, X'0007'/ZER(=+2);
CPYBLA ROW(BYTE-NBR:1), FIRST-BITS(PARTIAL-BYTE);:
UPDATE-BIT-OUT-INDEX:
ADDN(S) BIT-OUT-IDX, BITS-TO-OUTPUT;
B .RETURN;
DCL DD THE-TABLE(0:8191) CHAR(4) BAS(.THE-TABLE);
DCL SPCPTR .THE-TABLE;
%INCLUDE T6MODES MODES 128 ENTRIES
%INCLUDE T6WHITE WHITE 8192 ENTRIES
%INCLUDE T6BLACK BLACK 8192 ENTRIES
-----
T6MODES:
DCL DD MODES(0:0127) CHAR(4) INIT(
/*'0007000A' @ 0: 0000000 -> 10 */
/*'00070001' @ 2: 0000010 -> 1 */
/*'00070007' @ 3: 0000011 -> 7 */
X'0007000A',X'0007000A',X'00070001',X'00070007',
/*'00060002' @ 4: 000010 -> 2 */
/*'00060006' @ 6: 000011 -> 6 */
X'00060002',X'00060002',X'00060006',X'00060006',
/*'00040008' @ 8: 0001 -> 8 */
X'00040008',X'00040008',X'00040008',X'00040008',
X'00040008',X'00040008',X'00040008',X'00040008',
/*'00030009' @ 16: 001 -> 9 */
X'00030009',X'00030009',X'00030009',X'00030009',
X'00030009',X'00030009',X'00030009',X'00030009',
X'00030009',X'00030009',X'00030009',X'00030009',
X'00030009',X'00030009',X'00030009',X'00030009',
/*'00030003' @ 32: 010 -> 3 */
X'00030003',X'00030003',X'00030003',X'00030003',
X'00030003',X'00030003',X'00030003',X'00030003',
X'00030003',X'00030003',X'00030003',X'00030003',
X'00030003',X'00030003',X'00030003',X'00030003',
/*'00030005' @ 48: 011 -> 5 */
X'00030005',X'00030005',X'00030005',X'00030005',
X'00030005',X'00030005',X'00030005',X'00030005',
X'00030005',X'00030005',X'00030005',X'00030005',
X'00030005',X'00030005',X'00030005',X'00030005',
/*'00010004' @ 64: 1 -> 4 */
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004',
X'00010004',X'00010004',X'00010004',X'00010004');
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.