× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



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 thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 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.