home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume15 / g3g4 / part03 < prev    next >
Text File  |  1990-12-16  |  58KB  |  1,769 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: davidsen@crdos1.crd.ge.com
  3. subject: v15i088: G3 and G4 utilities - part 3/3
  4. from: davidsen@crdos1.crd.ge.com
  5. organization: GE Corporate R&D Center
  6. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  7.  
  8. Posting-number: Volume 15, Issue 88
  9. Submitted-by: davidsen@crdos1.crd.ge.com
  10. Archive-name: g3g4/part03
  11.  
  12. #!/bin/sh
  13. # this is part 3 of a multipart archive
  14. # do not concatenate these parts, unpack them in order with /bin/sh
  15. # file g4sdecod.c continued
  16. #
  17. CurArch=3
  18. if test ! -r s2_seq_.tmp
  19. then echo "Please unpack part 1 first!"
  20.      exit 1; fi
  21. ( read Scheck
  22.   if test "$Scheck" != $CurArch
  23.   then echo "Please unpack part $Scheck next!"
  24.        exit 1;
  25.   else exit 0; fi
  26. ) < s2_seq_.tmp || exit 1
  27. sed 's/^X//' << 'SHAR_EOF' >> g4sdecod.c
  28. X          else /* 011010010 */ return (832);
  29. X        }
  30. X        else /* 01101000 */ return (576);
  31. X          }
  32. X        }
  33. X      }
  34. X      else /* 01100... */
  35. X      {
  36. X        if (next_bit ()) /* 011001... */
  37. X        {
  38. X          if (next_bit ()) /* 0110011... */
  39. X          {
  40. X        if (next_bit ()) /* 01100111 */ return (640);
  41. X        else /* 01100110 */
  42. X        {
  43. X          if (next_bit ()) /* 011001101 */ return (768);
  44. X          else /* 011001100 */ return (704);
  45. X        }
  46. X          }
  47. X          else /* 0110010 */
  48. X          {
  49. X        if (next_bit ()) /* 01100101 */ return (512);
  50. X        else /* 01100100 */ return (448);
  51. X          }
  52. X        }
  53. X        else /* 011000 */ return (1664);
  54. X      }
  55. X    }
  56. X      }
  57. X      else /* 010... */
  58. X      {
  59. X    if (next_bit ()) /* 0101... */
  60. X    {
  61. X      if (next_bit ()) /* 01011... */
  62. X      {
  63. X        if (next_bit ()) /* 010111 */ return (192);
  64. X        else /* 010110... */
  65. X        {
  66. X          if (next_bit ()) /* 0101101... */
  67. X          {
  68. X        if (next_bit ()) /* 01011011 */ return (58);
  69. X        else /* 01011010 */ return (57);
  70. X          }
  71. X          else /* 0101100... */
  72. X          {
  73. X        if (next_bit ()) /* 01011001 */ return (56);
  74. X        else /* 01011000 */ return (55);
  75. X          }
  76. X        }
  77. X      }
  78. X      else /* 01010... */
  79. X      {
  80. X        if (next_bit ()) /* 010101... */
  81. X        {
  82. X          if (next_bit ()) /* 0101011 */ return (25);
  83. X          else /* 0101010... */
  84. X          {
  85. X        if (next_bit ()) /* 01010101 */ return (52);
  86. X        else /* 01010100 */ return (51);
  87. X          }
  88. X        }
  89. X        else /* 010100... */
  90. X        {
  91. X          if (next_bit ()) /* 0101001... */
  92. X          {
  93. X        if (next_bit ()) /* 01010011 */ return (50);
  94. X        else /* 01010010 */ return (49);
  95. X          }
  96. X          else /* 0101000 */ return (24);
  97. X        }
  98. X      }
  99. X    }
  100. X    else /* 0100... */
  101. X    {
  102. X      if (next_bit ()) /* 01001... */
  103. X      {
  104. X        if (next_bit ()) /* 010011... */
  105. X        {
  106. X          if (next_bit ()) /* 0100111 */ return (18);
  107. X          else /* 0100110... */
  108. X          {
  109. X        if (next_bit ()) /* 01001101... */
  110. X        {
  111. X          if (next_bit ()) /* 010011011 */ return (1728);
  112. X          else /* 010011010 */ return (1600);
  113. X        }
  114. X        else /* 01001100... */
  115. X        {
  116. X          if (next_bit ()) /* 010011001 */ return (1536);
  117. X          else /* 010011000 */ return (1472);
  118. X        }
  119. X          }
  120. X        }
  121. X        else /* 010010... */
  122. X        {
  123. X          if (next_bit ()) /* 0100101... */
  124. X          {
  125. X        if (next_bit ()) /* 01001011 */ return (60);
  126. X        else /* 01001010 */ return (59);
  127. X          }
  128. X          else /* 0100100 */ return (27);
  129. X        }
  130. X      }
  131. X      else /* 01000 */ return (11);
  132. X    }
  133. X      }
  134. X    }
  135. X    else /* 00... */
  136. X    {
  137. X      if (next_bit ()) /* 001... */
  138. X      {
  139. X    if (next_bit ()) /* 0011... */
  140. X    {
  141. X      if (next_bit ()) /* 00111 */ return (10);
  142. X      else /* 00110... */
  143. X      {
  144. X        if (next_bit ()) /* 001101... */
  145. X        {
  146. X          if (next_bit ()) /* 0011011... */
  147. X          {
  148. X        if (next_bit ()) /* 00110111 */ return (384);
  149. X        else /* 00110110 */ return (320);
  150. X          }
  151. X          else /* 0011010... */
  152. X          {
  153. X        if (next_bit ()) /* 00110101 */ return (0);
  154. X        else /* 00110100 */ return (63);
  155. X          }
  156. X        }
  157. X        else /* 001100... */
  158. X        {
  159. X          if (next_bit ()) /* 0011001... */
  160. X          {
  161. X        if (next_bit ()) /* 00110011 */ return (62);
  162. X        else /* 00110010 */ return (61);
  163. X          }
  164. X          else /* 0011000 */ return (28);
  165. X        }
  166. X      }
  167. X    }
  168. X    else /* 0010... */
  169. X    {
  170. X      if (next_bit ()) /* 00101... */
  171. X      {
  172. X        if (next_bit ()) /* 001011... */
  173. X        {
  174. X          if (next_bit ()) /* 0010111 */ return (21);
  175. X          else /* 0010110... */
  176. X          {
  177. X        if (next_bit ()) /* 00101101 */ return (44);
  178. X        else /* 00101100 */ return (43);
  179. X          }
  180. X        }
  181. X        else /* 001010... */
  182. X        {
  183. X          if (next_bit ()) /* 0010101... */
  184. X          {
  185. X        if (next_bit ()) /* 00101011 */ return (42);
  186. X        else /* 00101010 */ return (41);
  187. X          }
  188. X          else /* 0010100... */
  189. X          {
  190. X        if (next_bit ()) /* 00101001 */ return (40);
  191. X        else /* 00101000 */ return (39);
  192. X          }
  193. X        }
  194. X      }
  195. X      else /* 00100... */
  196. X      {
  197. X        if (next_bit ()) /* 001001... */
  198. X        {
  199. X          if (next_bit ()) /* 0010011 */ return (26);
  200. X          else /* 0010010... */
  201. X          {
  202. X        if (next_bit ()) /* 00100101 */ return (54);
  203. X        else /* 00100100 */ return (53);
  204. X          }
  205. X        }
  206. X        else /* 001000 */ return (12);
  207. X      }
  208. X    }
  209. X      }
  210. X      else /* 000... */
  211. X      {
  212. X    if (next_bit ()) /* 0001... */
  213. X    {
  214. X      if (next_bit ()) /* 00011... */
  215. X      {
  216. X        if (next_bit ()) /* 000111 */ return (1);
  217. X        else /* 000110... */
  218. X        {
  219. X          if (next_bit ()) /* 0001101... */
  220. X          {
  221. X        if (next_bit ()) /* 00011011 */ return (32);
  222. X        else /* 00011010 */ return (31);
  223. X          }
  224. X          else /* 0001100 */ return (19);
  225. X        }
  226. X      }
  227. X      else /* 00010... */
  228. X      {
  229. X        if (next_bit ()) /* 000101... */
  230. X        {
  231. X          if (next_bit ()) /* 0001011... */
  232. X          {
  233. X        if (next_bit ()) /* 00010111 */ return (38);
  234. X        else /* 00010110 */ return (37);
  235. X          }
  236. X          else /* 0001010... */
  237. X          {
  238. X        if (next_bit ()) /* 00010101 */ return (36);
  239. X        else /* 00010100 */ return (35);
  240. X          }
  241. X        }
  242. X        else /* 000100... */
  243. X        {
  244. X          if (next_bit ()) /* 0001001... */
  245. X          {
  246. X        if (next_bit ()) /* 00010011 */ return (34);
  247. X        else /* 00010010 */ return (33);
  248. X          }
  249. X          else /* 0001000 */ return (20);
  250. X        }
  251. X      }
  252. X    }
  253. X    else /* 0000... */
  254. X    {
  255. X      if (next_bit ()) /* 00001... */
  256. X      {
  257. X        if (next_bit ()) /* 000011 */ return (13);
  258. X        else /* 000010... */
  259. X        {
  260. X          if (next_bit ()) /* 0000101... */
  261. X          {
  262. X        if (next_bit ()) /* 00001011 */ return (48);
  263. X        else /* 00001010 */ return (47);
  264. X          }
  265. X          else /* 0000100 */ return (23);
  266. X        }
  267. X      }
  268. X      else /* 00000... */
  269. X      {
  270. X        if (next_bit ()) /* 000001... */
  271. X        {
  272. X          if (next_bit ()) /* 0000011 */ return (22);
  273. X          else /* 0000010... */
  274. X          {
  275. X        if (next_bit ()) /* 00000101 */ return (46);
  276. X        else /* 00000100 */ return (45);
  277. X          }
  278. X        }
  279. X        else /* 000000... */
  280. X        {
  281. X          if (next_bit ()) /* 0000001... */
  282. X          {
  283. X        if (next_bit ()) /* 00000011 */ return (30);
  284. X        else /* 00000010 */ return (29);
  285. X          }
  286. X          else /* 0000 000... */
  287. X          {
  288. X        if (next_bit ()) /* 0000 0001... */
  289. X        {
  290. X          if (next_bit ()) /* 0000 0001 1... */
  291. X          {
  292. X            if (next_bit ()) /* 0000 0001 11... */
  293. X            {
  294. X              if (next_bit ()) /* 0000 0001 111... */
  295. X              {
  296. X            if (next_bit ()) /* 0000 0001 1111 */ return (2560);
  297. X            else /* 0000 0001 1110 */ return (2496);
  298. X              }
  299. X              else /* 0000 0001 110... */
  300. X              {
  301. X            if (next_bit ()) /* 0000 0001 1101 */ return (2432);
  302. X            else /* 0000 0001 1100 */ return (2368);
  303. X              }
  304. X            }
  305. X            else /* 0000 0001 10... */
  306. X            {
  307. X              if (next_bit ()) /* 0000 0001 101 */ return (1920);
  308. X              else /* 0000 0001 100 */ return (1856);
  309. X            }
  310. X          }
  311. X          else /* 0000 0001 0... */
  312. X          {
  313. X            if (next_bit ()) /* 0000 0001 01... */
  314. X            {
  315. X              if (next_bit ()) /* 0000 0001 011... */
  316. X              {
  317. X            if (next_bit ()) /* 0000 0001 0111 */ return (2304);
  318. X            else /* 0000 0001 0110 */ return (2240);
  319. X              }
  320. X              else /* 0000 0001 010... */
  321. X              {
  322. X            if (next_bit ()) /* 0000 0001 0101 */ return (2176);
  323. X            else /* 0000 0001 0100 */ return (2112);
  324. X              }
  325. X            }
  326. X            else /* 0000 0001 00... */
  327. X            {
  328. X              if (next_bit ()) /* 0000 0001 001... */
  329. X              {
  330. X            if (next_bit ()) /* 0000 0001 0011 */ return (2048);
  331. X            else /* 0000 0001 0010 */ return (1984);
  332. X              }
  333. X              else /* 0000 0001 000 */ return (1792);
  334. X            }
  335. X          }
  336. X        }
  337. X        else /* 0000 0000... */
  338. X        {
  339. X          if (next_bit ()) /* 0000 0000 1 */ return (INVALID_CODE);
  340. X          else /* 0000 0000 0... */
  341. X          {
  342. X            if (next_bit ()) /* 0000 0000 01 */ return (INVALID_CODE);
  343. X            else /* 0000 0000 00... */
  344. X            {
  345. X              if (next_bit ()) /* 0000 0000 001 */
  346. X                            return (INVALID_CODE);
  347. X              else /* 0000 0000 000... */
  348. X              {
  349. X            if (next_bit ()) /* 0000 0000 0001 */ return (EOL_CODE);
  350. X            else /* 0000 0000 0000 */ return (INVALID_CODE);
  351. X              }
  352. X            }
  353. X          }
  354. X        }
  355. X          }
  356. X        }
  357. X      }
  358. X    }
  359. X      }
  360. X    }
  361. X  }
  362. X}
  363. X
  364. X/*    end $RCSfile: g4sdecod.c $ */
  365. SHAR_EOF
  366. chmod 0644 g4sdecod.c || echo "restore of g4sdecod.c fails"
  367. sed 's/^X//' << 'SHAR_EOF' > g4sencod.c &&
  368. X/*    $Id: g4sencod.c 1.2 90/06/09 18:24:10 marking Exp $
  369. X *
  370. X NAME
  371. X *    g4sencod.c -- encode group 4 data using nested if statements
  372. X *
  373. X TYPE
  374. X *    C procedures
  375. X *
  376. X SYNOPSIS
  377. X *    char    g4j_encode_black (short runlength);
  378. X *    char    g4j_encode_white (short runlength);
  379. X *    char    g4j_encode_EOFB (void);
  380. X *    char    g4j_encode_new_row (void);
  381. X *    char    g4j_initialize (short image_width, short image_length);
  382. X *
  383. X DESCRIPTION
  384. X *    Routines to encode group 4 images. Consecutive calls to encode
  385. X *    black or white runs will be combined.
  386. X *
  387. X RETURNS
  388. X *
  389. X LEGAL
  390. X *    Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
  391. X *    Scottsdale, Arizona 85252-8039. All rights reserved.
  392. X *
  393. X *    License is granted by the copyright holder to distribute and use this
  394. X *    code without payment of royalties or the necessity of notification as
  395. X *    long as this notice (all the text under "LEGAL") is included.
  396. X *
  397. X *    Reference: $Id: g4sencod.c 1.2 90/06/09 18:24:10 marking Exp $
  398. X *
  399. X *    This program is offered without any warranty of any kind. It includes
  400. X *    no warranty of merchantability or fitness for any purpose. Testing and
  401. X *    suitability for any use are the sole responsibility of the user.
  402. X * 
  403. X HISTORY
  404. X *    $Log:    g4sencod.c $
  405. X * Revision 1.2  90/06/09  18:24:10  marking
  406. X * clean up comments for release
  407. X * 
  408. X * Revision 1.1  90/05/01  02:00:00  marking
  409. X * Initial revision
  410. X * 
  411. X *
  412. X NOTES
  413. X *
  414. X PORTABILITY
  415. X *    Tested using Microsoft C 5.1. Some memory models may not work due to
  416. X *    the large encoding arrays.
  417. X *
  418. X *    There is a non-portable use of "global" variables in the file g3g4.h,
  419. X *    about which a minority of compilers will justifiably complain. Certain
  420. X *    variables are declared in g3g4.h without extern keywords. Strictly
  421. X *    speaking, they should be declared extern in all but one module, but
  422. X *    that would require complication of g3g4.h. If it gets past your
  423. X *    compiler and linker, you can probably ignore it.
  424. X *
  425. X SEE ALSO
  426. X *
  427. X INFORMATION
  428. X *    Although there is no support offered with this program, the author will
  429. X *    endeavor to correct errors. Updates will also be made available from
  430. X *    time to time.
  431. X *
  432. X *    Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
  433. X *    85252-8039 USA. Replies are not guaranteed to be swift. Beginning
  434. X *    July 1990, e-mail may be sent to uunet!ipel!marking.
  435. X *
  436. X *    Also beginning in July 1990, this code will be archived at the
  437. X *    ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
  438. X *    for 300/1200/2400 is (602)274-0462. When logging in, specify user
  439. X *    "public", system "bbs", and password "public".
  440. X *
  441. X *    This code is also available from the C Users Group in volume 317.
  442. X */
  443. X
  444. X#include "g3g4.h"
  445. X
  446. X/* #define TRACE 1 */
  447. X
  448. X/* implementation limits: Due to the sizes of arrays and variables, and not
  449. X   due to any restrictions in the algorithm, the following limits exist:
  450. X     maximum number of pixels per row: 65533
  451. X     maximum number of rows per image: none
  452. X     maximum or minimum k-factor: none
  453. X     maximum number of runs per row: 16382 white, 16382 black
  454. X   To increase (or decrease) these limits, it will be necessary to play with
  455. X   array and variable sizes.  On segmented machines (such as the 8086), a
  456. X   different memory model may be necessary.  The algorithm itself has no
  457. X   limits on image size or complexity, and the stack requirements are in-
  458. X   sensitive to changes in these limits or to image complexity. */
  459. X
  460. X#define EVEN 0
  461. X#define ODD 1
  462. X
  463. Xstatic short a0, a1, a2, b0, b1, b2, length_of_current_run;
  464. Xstatic unsigned char color, current_row, mode;
  465. Xstatic short even_runs [32768], odd_runs [32768];
  466. Xstatic unsigned short reference_index, coding_index;
  467. Xstatic short *reference_line, *coding_line;
  468. Xstatic short column_limit;
  469. X  /* Depending as current_row == EVEN or current_row == ODD, the runs of the
  470. X     current row are represented in even_runs [] or odd_runs [].  The white
  471. X     runs have even subscripts and the black runs have odd subscripts.  The
  472. X     values of the array elements are the offsets of the beginnings of the
  473. X     corresponding runs from the beginning of the row.  As defined by the
  474. X     specification,
  475. X    a0 is the reference or starting changing element on the coding line.
  476. X        It may be considered the "current position".
  477. X    a1 is the next changing element to the right of a0 on the coding line.
  478. X    a2 is the next changing element to the right of a1 on the coding line.
  479. X    b1 is the first changing element on the reference line to the right of
  480. X        a0 and of opposite color to a0.
  481. X    b2 is the next changing element to the right of b1 on the reference
  482. X        line.
  483. X     Furthermore,
  484. X    b0 is the "previous" value of b1. 
  485. X     */
  486. X
  487. Xchar g4j_initialize (short image_width, short image_length)
  488. X{
  489. X  initialize_encode ();
  490. X  color = WHITE;
  491. X  current_row = ODD;
  492. X  coding_line = odd_runs;
  493. X  reference_line = even_runs;
  494. X  coding_index = 0;
  495. X  coding_line [0] = 0;
  496. X  length_of_current_run = 0;
  497. X  column_limit = image_width;
  498. X  reference_line [0] = 0;
  499. X  reference_line [1] = column_limit;
  500. X  reference_line [2] = column_limit;
  501. X  reference_line [3] = column_limit;
  502. X  return (0);
  503. X}
  504. X
  505. Xchar g4j_encode_EOFB ()
  506. X{
  507. X  encode_word (EOL_code, EOL_length);
  508. X  encode_word (EOL_code, EOL_length);
  509. X  return (0);
  510. X}
  511. X
  512. Xchar g4j_encode_new_row ()
  513. X{
  514. X  short last_point;
  515. X  last_point  = coding_line [coding_index] + length_of_current_run;
  516. X  coding_index++;
  517. X  coding_line [coding_index] = last_point;
  518. X  coding_line [coding_index + 1] = last_point;
  519. X  coding_line [coding_index + 2] = last_point;
  520. X  coding_line [coding_index + 3] = last_point;
  521. X  /* encode the current row */
  522. X  #if defined (TRACE)
  523. X    if (trace_flag)
  524. X    {
  525. X      short j = 0, a;
  526. X      printf (" coding_line = < ");
  527. X      while ((a = coding_line [j]) < column_limit)
  528. X      {
  529. X        printf ("%hd@%hd ", (short) (coding_line [j + 1] - a), a);
  530. X        j++;
  531. X      }
  532. X      printf ("> ");
  533. X      j = 0;
  534. X      printf ("\nreference_line = < ");
  535. X      while ((a = reference_line [j]) < column_limit)
  536. X      {
  537. X        printf ("%hd@%hd ", (short) (reference_line [j + 1] - a), a);
  538. X        j++;
  539. X      }
  540. X      printf ("> ");
  541. X    };
  542. X  #endif
  543. X  reference_index = 0;
  544. X  coding_index = 0;
  545. X  a1 = coding_line [0];
  546. X  a2 = coding_line [1];
  547. X  if (a2 == 0 && reference_line [1] == 0)
  548. X    /* if the first (white) run is null as was in previous row */
  549. X  {
  550. X    encode_word (VERTICAL_V0_CODEWORD, VERTICAL_V0_CODELEN);
  551. X    coding_index++;
  552. X    a1 = coding_line [1];
  553. X    a2 = coding_line [2];
  554. X    #if defined (TRACE)
  555. X      if (trace_flag) printf ("V0 ");
  556. X    #endif
  557. X  }
  558. X  while (a1 < column_limit)
  559. X  {
  560. X    short effective_a0;
  561. X    a0 = a1;
  562. X    a1 = a2;
  563. X    a2 = coding_line [coding_index + 2];
  564. X    if (reference_index > 3) reference_index -= 3;
  565. X    else reference_index = 0;
  566. X    if (coding_index) effective_a0 = a0;
  567. X    else effective_a0 = -1;
  568. X    while (effective_a0 >= (b1 = reference_line [reference_index]))
  569. X      reference_index++;
  570. X      /* now the reference index points to the first changing point beyond a0,
  571. X     but it may or may not be the same color as a0 */
  572. X    if (! ((coding_index ^ reference_index) & 1)) /* if same colors */
  573. X    {
  574. X      reference_index++; /* now different color */
  575. X      b1 = reference_line [reference_index];
  576. X    }
  577. X    b2 = reference_line [reference_index + 1];
  578. X    #if defined (TRACE)
  579. X      if (trace_flag)
  580. X        printf ("\na0=%hd a1=%hd a2=%hd b1=%hd b2=%hd rx=%hd cx=%hd ",
  581. X      a0, a1, a2, b1, b2, reference_index, coding_index);
  582. X    #endif
  583. X    while (b2 < a1) /* PASS */
  584. X    {
  585. X      #if defined (TRACE)
  586. X    short old_a0 = a0;
  587. X      #endif
  588. X      encode_word (PASS_CODEWORD, PASS_CODELEN);
  589. X      a0 = b2;
  590. X      reference_index += 2;
  591. X      b1 = reference_line [reference_index];
  592. X      b2 = reference_line [reference_index + 1];
  593. X      #if defined (TRACE)
  594. X        if (trace_flag) printf ("PASS k%hd ", (short) (a0 - old_a0));
  595. X      #endif
  596. X    }
  597. X    if (a1 == b1) /* V0 */
  598. X    {
  599. X      encode_word (VERTICAL_V0_CODEWORD, VERTICAL_V0_CODELEN);
  600. X      coding_index++;
  601. X      #if defined (TRACE)
  602. X        if (trace_flag) printf ("V0 ");
  603. X      #endif
  604. X    }
  605. X    else if (a1 == b1 + 1) /* VR1 */
  606. X    {
  607. X      encode_word (VERTICAL_VR1_CODEWORD, VERTICAL_VR1_CODELEN);
  608. X      coding_index++;
  609. X      #if defined (TRACE)
  610. X        if (trace_flag) printf ("VR1 ");
  611. X      #endif
  612. X    }
  613. X    else if (a1 == b1 + 2) /* VR2 */
  614. X    {
  615. X      encode_word (VERTICAL_VR2_CODEWORD, VERTICAL_VR2_CODELEN);
  616. X      coding_index++;
  617. X      #if defined (TRACE)
  618. X        if (trace_flag) printf ("VR2 ");
  619. X      #endif
  620. X    }
  621. X    else if (a1 == b1 + 3) /* VR3 */
  622. X    {
  623. X      encode_word (VERTICAL_VR3_CODEWORD, VERTICAL_VR3_CODELEN);
  624. X      coding_index++;
  625. X      #if defined (TRACE)
  626. X        if (trace_flag) printf ("VR3 ");
  627. X      #endif
  628. X    }
  629. X    else if (a1 == b1 - 1) /* VL1 */
  630. X    {
  631. X      encode_word (VERTICAL_VL1_CODEWORD, VERTICAL_VL1_CODELEN);
  632. X      coding_index++;
  633. X      #if defined (TRACE)
  634. X        if (trace_flag) printf ("VL1 ");
  635. X      #endif
  636. X    }
  637. X    else if (a1 == b1 - 2) /* VL2 */
  638. X    {
  639. X      encode_word (VERTICAL_VL2_CODEWORD, VERTICAL_VL2_CODELEN);
  640. X      coding_index++;
  641. X      #if defined (TRACE)
  642. X        if (trace_flag) printf ("VL2 ");
  643. X      #endif
  644. X    }
  645. X    else if (a1 == b1 - 3) /* VL3 */
  646. X    {
  647. X      encode_word (VERTICAL_VL3_CODEWORD, VERTICAL_VL3_CODELEN);
  648. X      coding_index++;
  649. X      #if defined (TRACE)
  650. X        if (trace_flag) printf ("VL3 ");
  651. X      #endif
  652. X    }
  653. X    else /* HORIZONTAL */
  654. X    {
  655. X      short first_run, second_run;
  656. X      encode_word (HORIZONTAL_CODEWORD, HORIZONTAL_CODELEN);
  657. X      first_run = a1 - a0;
  658. X      second_run = a2 - a1;
  659. X      if (coding_index & 1) /* if BLACK, WHITE */
  660. X      {
  661. X    g3j_encode_black (first_run);
  662. X    g3j_encode_white (second_run);
  663. X    #if defined (TRACE)
  664. X      if (trace_flag) printf ("B%hd W%hd ", first_run, second_run);
  665. X    #endif
  666. X      }
  667. X      else /* WHITE, BLACK */
  668. X      {
  669. X    g3j_encode_white (first_run);
  670. X    g3j_encode_black (second_run);
  671. X    #if defined (TRACE)
  672. X      if (trace_flag) printf ("W%hd B%hd ", first_run, second_run);
  673. X    #endif
  674. X      }
  675. X      coding_index++;
  676. X      a0 = a1;
  677. X      a1 = a2;
  678. X      a2 = coding_line [coding_index + 2];
  679. X      coding_index++;
  680. X      #if defined (TRACE)
  681. X        if (trace_flag) printf ("HORIZ ");
  682. X      #endif
  683. X    }
  684. X  }
  685. X  /* now swap rows */
  686. X  if (current_row == EVEN)
  687. X  {
  688. X    current_row = ODD;
  689. X    coding_line = odd_runs;
  690. X    reference_line = even_runs;
  691. X  }
  692. X  else /* current_row == ODD */
  693. X  {
  694. X    current_row = EVEN;
  695. X    coding_line = even_runs;
  696. X    reference_line = odd_runs;
  697. X  }
  698. X  coding_index = 0;
  699. X  coding_line [coding_index] = 0;
  700. X  length_of_current_run = 0;
  701. X  return (0);
  702. X}
  703. X
  704. Xchar g4j_encode_black (short runlength)
  705. X{
  706. X  if (!(coding_index & 1)) /* if even number, is white */
  707. X  {
  708. X    coding_index++; /* move on to black */
  709. X    coding_line [coding_index]
  710. X      = coding_line [coding_index - 1] + length_of_current_run;
  711. X    length_of_current_run = 0;
  712. X  }
  713. X  length_of_current_run += runlength;
  714. X  return (0);
  715. X}
  716. X
  717. Xchar g4j_encode_white (short runlength)
  718. X{
  719. X  if (coding_index & 1) /* if odd number, is black */
  720. X  {
  721. X    coding_index++; /* move on to white */
  722. X    coding_line [coding_index]
  723. X      = coding_line [coding_index - 1] + length_of_current_run;
  724. X    length_of_current_run = 0;
  725. X  }
  726. X  length_of_current_run += runlength;
  727. X  return (0);
  728. X}
  729. X
  730. X/*    end $RCSfile: g4sencod.c $ */
  731. SHAR_EOF
  732. chmod 0644 g4sencod.c || echo "restore of g4sencod.c fails"
  733. sed 's/^X//' << 'SHAR_EOF' > g4tdecod.c &&
  734. X/*    $Id: g4tdecod.c 1.2 90/06/09 18:24:25 marking Exp $
  735. X *
  736. X NAME
  737. X *    g4tdecod.c -- decode group 4 data using tables
  738. X *
  739. X TYPE
  740. X *    C procedures
  741. X *
  742. X SYNOPSIS
  743. X *    char    g4i_initialize (short image_width, short image_length);
  744. X *    char    g4i_decode (void);
  745. X *
  746. X DESCRIPTION
  747. X *    In order to acquire data from the image and to return run lengths and
  748. X *    new line information, these routines invoke procedures provided by the
  749. X *    caller. These caller-provided procedures are invoked throught pointers
  750. X *    which have been stuffed by the caller with the procedure addresses.
  751. X *    To acquire a new data byte, g4i_decode () calls (*p_g41_next_byte) ().
  752. X *    To report the decoding of a black or white run, the routines
  753. X *    (*p_decode_black) () or (*p_decode_white) () are called.
  754. X *
  755. X RETURNS
  756. X *    Initialization always returns zero.
  757. X *
  758. X *    For decoding,
  759. X *        0    end of image reached
  760. X *        -1    on error (bad data)
  761. X *    The decode loop will be prematurely terminated if decode_return is
  762. X *    set to not zero, and the value of decode_return will be returned.
  763. X *    No code here does this, but it might be useful under certain
  764. X *    circumstances.
  765. X *
  766. X LEGAL
  767. X *    Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
  768. X *    Scottsdale, Arizona 85252-8039. All rights reserved.
  769. X *
  770. X *    License is granted by the copyright holder to distribute and use this
  771. X *    code without payment of royalties or the necessity of notification as
  772. X *    long as this notice (all the text under "LEGAL") is included.
  773. X *
  774. X *    Reference: $Id: g4tdecod.c 1.2 90/06/09 18:24:25 marking Exp $
  775. X *
  776. X *    This program is offered without any warranty of any kind. It includes
  777. X *    no warranty of merchantability or fitness for any purpose. Testing and
  778. X *    suitability for any use are the sole responsibility of the user.
  779. X * 
  780. X HISTORY
  781. X *    $Log:    g4tdecod.c $
  782. X * Revision 1.2  90/06/09  18:24:25  marking
  783. X * clean up comments for release
  784. X * 
  785. X * Revision 1.1  89/06/30  17:00:00  marking
  786. X * Initial revision
  787. X * 
  788. X *
  789. X NOTES
  790. X *
  791. X PORTABILITY
  792. X *    Tested using Microsoft C 5.1. Some memory models may not work due to
  793. X *    the large decoding arrays.
  794. X *
  795. X *    There is a non-portable use of "global" variables in the file g3g4.h,
  796. X *    about which a minority of compilers will justifiably complain. Certain
  797. X *    variables are declared in g3g4.h without extern keywords. Strictly
  798. X *    speaking, they should be declared extern in all but one module, but
  799. X *    that would require complication of g3g4.h. If it gets past your
  800. X *    compiler and linker, you can probably ignore it.
  801. X *
  802. X SEE ALSO
  803. X *    g3tdecod.c -- decode group 3 image using tables
  804. X *    builddec.c -- build image decoding tables
  805. X *
  806. X INFORMATION
  807. X *    Although there is no support offered with this program, the author will
  808. X *    endeavor to correct errors. Updates will also be made available from
  809. X *    time to time.
  810. X *
  811. X *    Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
  812. X *    85252-8039 USA. Replies are not guaranteed to be swift. Beginning
  813. X *    July 1990, e-mail may be sent to uunet!ipel!marking.
  814. X *
  815. X *    Also beginning in July 1990, this code will be archived at the
  816. X *    ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
  817. X *    for 300/1200/2400 is (602)274-0462. When logging in, specify user
  818. X *    "public", system "bbs", and password "public".
  819. X *
  820. X *    This code is also available from the C Users Group in volume 317.
  821. X */
  822. X
  823. X#include "g3g4.h"
  824. X
  825. X/* #define TRACE 1 */
  826. X#define TRACE_BEGIN 0
  827. X#define TRACE_END 30000
  828. X
  829. X/* implementation limits: Due to the sizes of arrays and variables, and not
  830. X   due to any restrictions in the algorithm, the following limits exist:
  831. X     maximum number of pixels per row: 65533
  832. X     maximum number of rows per image: none
  833. X     maximum or minimum k-factor: none
  834. X     maximum number of runs per row: 16382 white, 16382 black
  835. X   To increase (or decrease) these limits, it will be necessary to play with
  836. X   array and variable sizes.  On segmented machines (such as the 8086), a
  837. X   different memory model may be necessary.  The algorithm itself has no
  838. X   limits on image size or complexity, and the stack requirements are in-
  839. X   sensitive to changes in these limits or to image complexity. */
  840. X
  841. X#define EVEN 0
  842. X#define ODD 1
  843. X
  844. Xstatic short a0, a1, a2, b0, b1, b2, bit_number, code_byte;
  845. Xstatic unsigned char color, current_row, mode, next_state;
  846. Xstatic unsigned short even_runs [32768], odd_runs [32768];
  847. Xstatic unsigned short even_index, odd_index;
  848. Xstatic short column_limit;
  849. Xstatic short row_number = 0;
  850. X  /* Depending as current_row == EVEN or current_row == ODD, the runs of the
  851. X     current row are represented in even_runs [] or odd_runs [].  The white
  852. X     runs have even subscripts and the black runs have odd subscripts.  The
  853. X     values of the array elements are the offsets of the beginnings of the
  854. X     corresponding runs from the beginning of the row.  As defined by the
  855. X     specification,
  856. X    a0 is the reference or starting changing element on the coding line.
  857. X        It may be considered the "current position".
  858. X    a1 is the next changing element to the right of a0 on the coding line.
  859. X    a2 is the next changing element to the right of a1 on the coding line.
  860. X    b1 is the first changing element on the reference line to the right of
  861. X        a0 and of opposite color to a0.
  862. X    b2 is the next changing element to the right of b1 on the reference
  863. X        line.
  864. X     Furthermore,
  865. X    b0 is the "previous" value of b1. 
  866. X     Depending as current_row == EVEN or == ODD, even_index or odd_index is
  867. X     the subscript of the entry in even_runs [] or odd_runs [] corresponding
  868. X     to the run containing the current value of a0, and its counterpart cor-
  869. X     responds to the run containing b1. */
  870. X
  871. Xextern unsigned char huge null_mode [] [256];
  872. X  /* One of the entries PASS_MODE, HORIZONTAL_MODE, etc, or zero.  If the entry
  873. X     is zero, then the bit string is indigestible and null_mode_next_state [][]
  874. X     is consulted to decode the subsequent byte.  The row number (first sub-
  875. X     script) corresponds to the assumption about the state of the machine after
  876. X     decoding the previous codeword.  If < 8, then it refers to the starting
  877. X     bit number for this codeword.  If > 7, it implies a bit string to be pre-
  878. X     fixed to the first bit of the current byte.  The column number (second
  879. X     subscript) refers to the value of the current byte. */
  880. X
  881. Xextern unsigned char huge null_mode_next_state [] [256];
  882. Xextern unsigned char huge horiz_mode [] [256];
  883. Xextern unsigned char huge horiz_mode_next_state [] [256];
  884. X
  885. Xstatic void new_row (void);
  886. Xstatic short decode_white_run (void);
  887. Xstatic short decode_black_run (void);
  888. X
  889. Xstatic char decode_return;
  890. X
  891. X/* g4i_decode () successively invokes (*p_decode_next_byte) () for each byte of the
  892. X   encoded image, and calls (*p_decode_white) () or (*p_decode_black) () as
  893. X   required to return the image contents on a run-by-run basis. */
  894. Xchar g4i_decode ()
  895. X{
  896. X  /* At the beginning of this routine, we are in the NULL mode, which is to
  897. X     to say that no codewords are currently understood or digested.  The
  898. X     variable bit_number has been initialized to zero, to indicate that the
  899. X     next (first) codeword is to begin with bit zero of the next code byte.
  900. X     This betrays an assumption that all images begin on byte boundaries, a
  901. X     condition that can be changed by arranging for bit_number to be set
  902. X     otherwise by g4i_initialize () or elsewhere. */
  903. X  while (!decode_return)
  904. X  {
  905. X    /* No codewords have been digested, so no mode is currently understood.
  906. X       It is possible, however, that bits have been left over from the last
  907. X       code byte, and that these must be conceptually prefixed to the next
  908. X       bits at the beginning of the next code byte to establish which code
  909. X       word is next.  The decision is made based on bit_number, which is
  910. X       zero if the codeword begins on a byte boundary; 1, 2, ... 7 if the
  911. X       codeword begins with bit 1, 2, ... 7; or > 7 if the codeword begins
  912. X       with bit zero but is assumed to have a non-null bits string prefix.
  913. X       In any case, the bit_number corresponds to a row in the decoding
  914. X       tables. */
  915. X    if (bit_number == 0 || bit_number > 7) /* the code word will begin on
  916. X      the first bit of the next code byte, possibly with a bit string
  917. X      implicitly prefixed */
  918. X    {
  919. X      code_byte = (*p_decode_next_byte) (); /* invoke a user-supplied routine
  920. X        to provide the next byte of the encoded image */
  921. X      if (code_byte < 0) /* implying end-of-file or some error in
  922. X        reading the next code byte */
  923. X        return (ERROR_NEXT_BYTE);
  924. X    }
  925. X    /* else 0 < bit_number < 8, implying that the next code word begins within
  926. X      the current code byte; that is, a new byte need not be fetched */
  927. X    mode = null_mode [bit_number] [code_byte];
  928. X    next_state = null_mode_next_state [bit_number] [code_byte];
  929. X      /* The above two index operations involve muliplication (by the compiler)
  930. X         of the first subscript by 256, a procedure obviously a candidate for
  931. X     optimization in many architectures.  It may be worthwhile to hand-code
  932. X     this calculation, since this is a fairly tight loop.  Check also that
  933. X     the compiler does the calculation but once and saves the result in a
  934. X     temporary, since the two arrays are of identical size. */
  935. X    if (mode == NULL_MODE) /* the codeword (or partial codeword) is
  936. X      indigestible */
  937. X    {
  938. X      bit_number = next_state; /* to be continued... */
  939. X    }
  940. X    else
  941. X    {
  942. X      if (current_row == EVEN)
  943. X      {
  944. X    b0 = b1;
  945. X    b1 = odd_runs [odd_index];
  946. X    if ((b1 <= a0) && a0)
  947. X    {
  948. X      odd_index += 2;
  949. X      b0 = odd_runs [odd_index - 1];
  950. X      b1 = odd_runs [odd_index];
  951. X    }
  952. X    b2 = odd_runs [odd_index + 1];
  953. X      }
  954. X      else /* current_row == ODD */
  955. X      {
  956. X    b0 = b1;
  957. X    b1 = even_runs [even_index];
  958. X    if ((b1 <= a0) && a0)
  959. X    {
  960. X      even_index += 2;
  961. X      b0 = even_runs [even_index - 1];
  962. X      b1 = even_runs [even_index];
  963. X    }
  964. X    b2 = even_runs [even_index + 1];
  965. X      }
  966. X      #if defined (TRACE)
  967. X    if (row_number >= TRACE_BEGIN && row_number <= TRACE_END)
  968. X    {
  969. X      if (current_row == EVEN)
  970. X      {
  971. X        printf ("\n ref_index=%hd b1=%hd b2=%hd a0=%hd curr[%hd]=%hd "
  972. X          "color=%hd ",
  973. X          odd_index, b1, b2, a0, even_index, even_runs [even_index],
  974. X          (short) color);
  975. X      }
  976. X      else /* current_row == ODD */
  977. X      {
  978. X        printf ("\n ref_index=%hd b1=%hd b2=%hd a0=%hd curr[%hd]=%hd "
  979. X          "color=%hd ",
  980. X          even_index, b1, b2, a0, odd_index, odd_runs [odd_index],
  981. X          (short) color);
  982. X      }
  983. X    }
  984. X      #endif
  985. X      switch (mode)
  986. X      {
  987. X        case PASS_MODE: /* skip (pass) two color changes on the previous row */
  988. X      #if defined (TRACE)
  989. X            if (row_number >= TRACE_BEGIN && row_number <= TRACE_END)
  990. X              printf (" P ");
  991. X      #endif
  992. X          if (color == WHITE) (*p_decode_white) ((short) (b2 - a0));
  993. X          else /* color == BLACK */ (*p_decode_black) ((short) (b2 - a0));
  994. X      a0 = b2;
  995. X      if (current_row == EVEN)
  996. X      {
  997. X        odd_index += 2;
  998. X        b1 = odd_runs [odd_index];
  999. X      }
  1000. X      else /* current_row == ODD */
  1001. X      {
  1002. X        even_index += 2;
  1003. X        b1 = even_runs [even_index];
  1004. X      }
  1005. X          bit_number = next_state;
  1006. X          break;
  1007. X        case HORIZONTAL_MODE: /* revert to 1-dimensional modified Huffman
  1008. X          encoding for a pair of runs */
  1009. X          bit_number = next_state;
  1010. X      #if defined (TRACE)
  1011. X            if (row_number >= TRACE_BEGIN && row_number <= TRACE_END)
  1012. X              printf (" H ");
  1013. X          #endif
  1014. X          if (color == WHITE)
  1015. X          {
  1016. X        short black_runlength, white_runlength;
  1017. X            white_runlength = decode_white_run ();
  1018. X            (*p_decode_white) ((short) white_runlength);
  1019. X        a1 = (a0 += white_runlength);
  1020. X            black_runlength = decode_black_run ();
  1021. X            (*p_decode_black) ((short) black_runlength);
  1022. X        a2 = (a0 += black_runlength);
  1023. X          }
  1024. X          else /* color == BLACK */
  1025. X          {
  1026. X        short black_runlength, white_runlength;
  1027. X        black_runlength = decode_black_run ();
  1028. X        (*p_decode_black) ((short) black_runlength);
  1029. X        a1 = (a0 += black_runlength);
  1030. X        white_runlength = decode_white_run ();
  1031. X        (*p_decode_white) ((short) white_runlength);
  1032. X        a2 = (a0 += white_runlength);
  1033. X          }
  1034. X          if (current_row == EVEN)
  1035. X          {
  1036. X        even_runs [++even_index] = a1;
  1037. X        even_runs [++even_index] = a2;
  1038. X        while (a0 > odd_runs [odd_index]) odd_index += 2;
  1039. X        b1 = odd_runs [odd_index];
  1040. X          }
  1041. X          else /* current_row == ODD */
  1042. X          {
  1043. X        odd_runs [++odd_index] = a1;
  1044. X        odd_runs [++odd_index] = a2;
  1045. X        while (a0 > even_runs [even_index]) even_index += 2;
  1046. X        b1 = even_runs [even_index];
  1047. X          }
  1048. X          break;
  1049. X        case VERTICAL_V0_MODE: /* the next color change begins at the same
  1050. X          location as in the previous row */
  1051. X      #if defined (TRACE)
  1052. X            if (row_number >= TRACE_BEGIN && row_number <= TRACE_END)
  1053. X              printf (" V0 ");
  1054. X      #endif
  1055. X      if (color == WHITE)
  1056. X      {
  1057. X        (*p_decode_white) ((short) (b1 - a0));
  1058. X        color = BLACK;
  1059. X      }
  1060. X      else /* color == BLACK */
  1061. X      {
  1062. X        (*p_decode_black) ((short) (b1 - a0));
  1063. X        color = WHITE;
  1064. X      }
  1065. X      a0 = b1; 
  1066. X          if (current_row == EVEN)
  1067. X          {
  1068. X        even_runs [++even_index] = a0;
  1069. X        odd_index++;
  1070. X          }
  1071. X          else /* current_row == ODD */
  1072. X          {
  1073. X        odd_runs [++odd_index] = a0;
  1074. X        even_index++;
  1075. X          }
  1076. X          bit_number = next_state;
  1077. X          break;
  1078. X        case VERTICAL_VR1_MODE: /* the next color change begins one pixel to the
  1079. X          right of its location on the previous row */
  1080. X      #if defined (TRACE)
  1081. X            if (row_number >= TRACE_BEGIN && row_number <= TRACE_END)
  1082. X              printf (" VR1 ");
  1083. X      #endif
  1084. X      if (color == WHITE)
  1085. X      {
  1086. X        (*p_decode_white) ((short) (b1 - a0 + 1));
  1087. X        color = BLACK;
  1088. X      }
  1089. X      else /* color == BLACK */
  1090. X      {
  1091. X        (*p_decode_black) ((short) (b1 - a0 + 1));
  1092. X        color = WHITE;
  1093. X      }
  1094. X      a0 = b1 + 1; 
  1095. X          if (current_row == EVEN)
  1096. X          {
  1097. X        even_runs [++even_index] = a0;
  1098. X        odd_index++;
  1099. X          }
  1100. X          else /* current_row == ODD */
  1101. X          {
  1102. X        odd_runs [++odd_index] = a0;
  1103. X        even_index++;
  1104. X          }
  1105. X          bit_number = next_state;
  1106. X          break;
  1107. X        case VERTICAL_VR2_MODE: /* the next color change begins two pixels to
  1108. X          the right of its location on the previous row */
  1109. X      #if defined (TRACE)
  1110. X            if (row_number >= TRACE_BEGIN && row_number <= TRACE_END)
  1111. X              printf (" VR2 ");
  1112. X      #endif
  1113. X      if (color == WHITE)
  1114. X      {
  1115. X        (*p_decode_white) ((short) (b1 - a0 + 2));
  1116. X        color = BLACK;
  1117. X      }
  1118. X      else /* color == BLACK */
  1119. X      {
  1120. X        (*p_decode_black) ((short) (b1 - a0 + 2));
  1121. X        color = WHITE;
  1122. X      }
  1123. X      a0 = b1 + 2; 
  1124. X          if (current_row == EVEN)
  1125. X          {
  1126. X        even_runs [++even_index] = a0;
  1127. X        odd_index++;
  1128. X          }
  1129. X          else /* current_row == ODD */
  1130. X          {
  1131. X        odd_runs [++odd_index] = a0;
  1132. X        even_index++;
  1133. X          }
  1134. X          bit_number = next_state;
  1135. X          break;
  1136. X        case VERTICAL_VR3_MODE: /* the next color change begins three pixels to
  1137. X          the right of its location on the previous row */
  1138. X      #if defined (TRACE)
  1139. X            if (row_number >= TRACE_BEGIN && row_number <= TRACE_END)
  1140. X              printf (" VR3 ");
  1141. X      #endif
  1142. X      if (color == WHITE)
  1143. X      {
  1144. X        (*p_decode_white) ((short) (b1 - a0 + 3));
  1145. X        color = BLACK;
  1146. X      }
  1147. X      else /* color == BLACK */
  1148. X      {
  1149. X        (*p_decode_black) ((short) (b1 - a0 + 3));
  1150. X        color = WHITE;
  1151. X      }
  1152. X      a0 = b1 + 3; 
  1153. X          if (current_row == EVEN)
  1154. X          {
  1155. X        even_runs [++even_index] = a0;
  1156. X        odd_index++;
  1157. X          }
  1158. X          else /* current_row == ODD */
  1159. X          {
  1160. X        odd_runs [++odd_index] = a0;
  1161. X        even_index++;
  1162. X          }
  1163. X          bit_number = next_state;
  1164. X          break;
  1165. X        case VERTICAL_VL1_MODE: /* the next color change begins one pixel to the
  1166. X          left of its location on the previous row */
  1167. X      #if defined (TRACE)
  1168. X            if (row_number >= TRACE_BEGIN && row_number <= TRACE_END)
  1169. X              printf (" VL1 ");
  1170. X      #endif
  1171. X      if (color == WHITE)
  1172. X      {
  1173. X        (*p_decode_white) ((short) (b1 - a0 - 1));
  1174. X        color = BLACK;
  1175. X      }
  1176. X      else /* color == BLACK */
  1177. X      {
  1178. X        (*p_decode_black) ((short) (b1 - a0 - 1));
  1179. X        color = WHITE;
  1180. X      }
  1181. X      a0 = b1 - 1; 
  1182. X          if (current_row == EVEN)
  1183. X          {
  1184. X        even_runs [++even_index] = a0;
  1185. X        odd_index++;
  1186. X          }
  1187. X          else /* current_row == ODD */
  1188. X          {
  1189. X        odd_runs [++odd_index] = a0;
  1190. X        even_index++;
  1191. X          }
  1192. X          bit_number = next_state;
  1193. X          break;
  1194. X        case VERTICAL_VL2_MODE: /* the next color change begins two pixels to
  1195. X          the left of its location on the previous row */
  1196. X      #if defined (TRACE)
  1197. X            if (row_number >= TRACE_BEGIN && row_number <= TRACE_END)
  1198. X              printf (" VL2 ");
  1199. X      #endif
  1200. X      if (color == WHITE)
  1201. X      {
  1202. X        (*p_decode_white) ((short) (b1 - a0 - 2));
  1203. X        color = BLACK;
  1204. X      }
  1205. X      else /* color == BLACK */
  1206. X      {
  1207. X        (*p_decode_black) ((short) (b1 - a0 - 2));
  1208. X        color = WHITE;
  1209. X      }
  1210. X      a0 = b1 - 2; 
  1211. X          if (current_row == EVEN)
  1212. X          {
  1213. X        even_runs [++even_index] = a0;
  1214. X        if (a0 < b0) odd_index--;
  1215. X        else odd_index++;
  1216. X          }
  1217. X          else /* current_row == ODD */
  1218. X          {
  1219. X        odd_runs [++odd_index] = a0;
  1220. X        if (a0 < b0) even_index--;
  1221. X        else even_index++;
  1222. X          }
  1223. X          bit_number = next_state;
  1224. X          break;
  1225. X        case VERTICAL_VL3_MODE: /* the next color change begins three pixels to
  1226. X          the left of its location on the previous row */
  1227. X      #if defined (TRACE)
  1228. X            if (row_number >= TRACE_BEGIN && row_number <= TRACE_END)
  1229. X              printf (" VL3 ");
  1230. X      #endif
  1231. X      if (color == WHITE)
  1232. X      {
  1233. X        (*p_decode_white) ((short) (b1 - a0 - 3));
  1234. X        color = BLACK;
  1235. X      }
  1236. X      else /* color == BLACK */
  1237. X      {
  1238. X        (*p_decode_black) ((short) (b1 - a0 - 3));
  1239. X        color = WHITE;
  1240. X      }
  1241. X      a0 = b1 - 3; 
  1242. X          if (current_row == EVEN)
  1243. X          {
  1244. X        even_runs [++even_index] = a0;
  1245. X        if (a0 < b0) odd_index--;
  1246. X        else odd_index++;
  1247. X          }
  1248. X          else /* current_row == ODD */
  1249. X          {
  1250. X        odd_runs [++odd_index] = a0;
  1251. X        if (a0 < b0) even_index--;
  1252. X        else even_index++;
  1253. X          }
  1254. X          bit_number = next_state;
  1255. X          break;
  1256. X        case EXT_MODE_UNCOMPRESSED: /* enter extension type 7 ("111"), an
  1257. X          uncompressed encoding scheme */
  1258. X          return (ERROR_UNSUPPORTED_EXTENSION);
  1259. X          break;
  1260. X        case ERROR_MODE: /* The bit pattern found corresponds to an unknown or
  1261. X          invalid codeword.  This MAY be one of the seven possible extensions
  1262. X          not defined by the specification. */
  1263. X          return (ERROR_INVALID_CODEWORD);
  1264. X          break;
  1265. X        case ERROR_MODE_1: /* assumed in this implementation to be equivalent
  1266. X          to EOFB (end-of-facsimile-block) */
  1267. X          return (RETURN_OK);
  1268. X          break;
  1269. X        default: /* we should never get here; if we do, the tables are bad */
  1270. X          return (ERROR_PROGRAM_LOGIC);
  1271. X          break;
  1272. X      }
  1273. X    }
  1274. X    if (a0 >= column_limit) new_row ();
  1275. X  }
  1276. X  return (decode_return);
  1277. X}
  1278. X
  1279. X/* g4i_initialize () is called to set up to decode a new image.  All of the
  1280. X   static data (flags, etc) for g4i_decode () are initialized, allowing the
  1281. X   decoding of multiple images in a run as long as g4i_initialize () is
  1282. X   called before each one. */
  1283. Xchar g4i_initialize (short image_width, short image_length)
  1284. X{
  1285. X  color = WHITE;
  1286. X  bit_number= 0;
  1287. X  current_row = ODD;
  1288. X  even_runs [0] = 0;
  1289. X  even_runs [1] = image_width; /* initial b1 */
  1290. X  even_runs [2] = image_width; /* initial b2 */
  1291. X  odd_runs [0] = 0;
  1292. X  a0 = 0;
  1293. X  even_index = 1; odd_index = 0;
  1294. X  column_limit = image_width;
  1295. X  row_number = 0;
  1296. X  b1 = -1;
  1297. X  decode_return = 0;
  1298. X  return (0);
  1299. X}
  1300. X
  1301. Xstatic void new_row ()
  1302. X{
  1303. X  (*p_decode_new_row) ();
  1304. X  color = WHITE;
  1305. X  if (current_row == ODD)
  1306. X  {
  1307. X    current_row = EVEN;
  1308. X    odd_runs [++odd_index] = a0;
  1309. X    odd_runs [++odd_index] = a0;
  1310. X    odd_index = 1;
  1311. X    even_index = 0;
  1312. X  }
  1313. X  else /* current_row == EVEN */
  1314. X  {
  1315. X    current_row = ODD;
  1316. X    even_runs [++even_index] = a0;
  1317. X    even_runs [++even_index] = a0;
  1318. X    even_index = 1;
  1319. X    odd_index = 0;
  1320. X  }
  1321. X  a0 = 0;
  1322. X  b1 = -1;
  1323. X  #if defined (TRACE)
  1324. X    row_number++;
  1325. X  #endif
  1326. X}
  1327. X
  1328. Xstatic short run_length_table [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  1329. X  13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  1330. X  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
  1331. X  51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 128, 192, 256, 320,
  1332. X  384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024, 1088, 1152, 1216,
  1333. X  1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, 1984,
  1334. X  2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560};
  1335. X
  1336. Xstatic short decode_black_run ()
  1337. X{
  1338. X  short runlength, accum_runlength = 0;
  1339. X  next_state = (unsigned char) (bit_number + 8);
  1340. X  for (;;) /* exit with "return" */
  1341. X  {
  1342. X    if (!bit_number) code_byte = (*p_decode_next_byte) ();
  1343. X     /* this will fetch a new byte
  1344. X        if the previous codeword ended on a byte boundary */
  1345. X    mode = horiz_mode [next_state] [code_byte];
  1346. X    next_state = horiz_mode_next_state [next_state] [code_byte];
  1347. X    if (mode) /* if digestible */
  1348. X    {
  1349. X      bit_number = next_state;
  1350. X      runlength = run_length_table [mode - 106];
  1351. X      accum_runlength += runlength;
  1352. X      if (runlength < 64) return (accum_runlength);
  1353. X      next_state += 8;
  1354. X    }
  1355. X    else bit_number = 0;
  1356. X  }
  1357. X}
  1358. X
  1359. Xstatic short decode_white_run ()
  1360. X{
  1361. X  short runlength, accum_runlength = 0;
  1362. X  next_state = (unsigned char) bit_number;
  1363. X  for (;;) /* exit with "return" */
  1364. X  {
  1365. X    if (!bit_number) code_byte = (*p_decode_next_byte) ();
  1366. X     /* this will fetch a new byte
  1367. X        if the previous codeword ended on a byte boundary */
  1368. X    mode = horiz_mode [next_state] [code_byte];
  1369. X    next_state = horiz_mode_next_state [next_state] [code_byte];
  1370. X    if (mode) /* if digestible */
  1371. X    {
  1372. X      bit_number = next_state;
  1373. X      runlength = run_length_table [mode - 2];
  1374. X      accum_runlength += runlength;
  1375. X      if (runlength < 64) return (accum_runlength);
  1376. X    }
  1377. X    else bit_number = 0;
  1378. X  }
  1379. X}
  1380. X
  1381. X/*    end $RCSfile: g4tdecod.c $ */
  1382. SHAR_EOF
  1383. chmod 0644 g4tdecod.c || echo "restore of g4tdecod.c fails"
  1384. sed 's/^X//' << 'SHAR_EOF' > gnencode.c &&
  1385. X/*    $Id: gnencode.c 1.2 90/06/09 18:24:51 marking Exp $
  1386. X *
  1387. X NAME
  1388. X *    gnencode.c -- routines for bit and byte encoding
  1389. X *
  1390. X TYPE
  1391. X *    C procedures
  1392. X *
  1393. X SYNOPSIS
  1394. X *    void initialize_encode ();
  1395. X *    void encode_word (unsigned short codeword, short length);
  1396. X *
  1397. X DESCRIPTION
  1398. X *    Support routines used in encoding group 3 and group 4 images.
  1399. X *
  1400. X RETURNS
  1401. X *
  1402. X LEGAL
  1403. X *    Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
  1404. X *    Scottsdale, Arizona 85252-8039. All rights reserved.
  1405. X *
  1406. X *    License is granted by the copyright holder to distribute and use this
  1407. X *    code without payment of royalties or the necessity of notification as
  1408. X *    long as this notice (all the text under "LEGAL") is included.
  1409. X *
  1410. X *    Reference: $Id: gnencode.c 1.2 90/06/09 18:24:51 marking Exp $
  1411. X *
  1412. X *    This program is offered without any warranty of any kind. It includes
  1413. X *    no warranty of merchantability or fitness for any purpose. Testing and
  1414. X *    suitability for any use are the sole responsibility of the user.
  1415. X * 
  1416. X HISTORY
  1417. X *    $Log:    gnencode.c $
  1418. X * Revision 1.2  90/06/09  18:24:51  marking
  1419. X * clean up comments for release
  1420. X * 
  1421. X * Revision 1.1  89/06/30  17:00:00  marking
  1422. X * Initial revision
  1423. X * 
  1424. X *
  1425. X NOTES
  1426. X *    1.    There are two versions of encode_word (). Refer to the remark
  1427. X *        below and comment-out one or the other.
  1428. X *
  1429. X PORTABILITY
  1430. X *    Tested using Microsoft C 5.1. Some memory models may not work due to
  1431. X *    the large encoding arrays.
  1432. X *
  1433. X *    There is a non-portable use of "global" variables in the file g3g4.h,
  1434. X *    about which a minority of compilers will justifiably complain. Certain
  1435. X *    variables are declared in g3g4.h without extern keywords. Strictly
  1436. X *    speaking, they should be declared extern in all but one module, but
  1437. X *    that would require complication of g3g4.h. If it gets past your
  1438. X *    compiler and linker, you can probably ignore it.
  1439. X *
  1440. X SEE ALSO
  1441. X *    g3sencod.c, g4sencod.c
  1442. X *
  1443. X INFORMATION
  1444. X *    Although there is no support offered with this program, the author will
  1445. X *    endeavor to correct errors. Updates will also be made available from
  1446. X *    time to time.
  1447. X *
  1448. X *    Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
  1449. X *    85252-8039 USA. Replies are not guaranteed to be swift. Beginning
  1450. X *    July 1990, e-mail may be sent to uunet!ipel!marking.
  1451. X *
  1452. X *    Also beginning in July 1990, this code will be archived at the
  1453. X *    ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
  1454. X *    for 300/1200/2400 is (602)274-0462. When logging in, specify user
  1455. X *    "public", system "bbs", and password "public".
  1456. X *
  1457. X *    This code is also available from the C Users Group in volume 317.
  1458. X */
  1459. X
  1460. X#include "g3g4.h"
  1461. X
  1462. X/*
  1463. X *    initialize the bit-encoding routines
  1464. X */
  1465. X
  1466. Xvoid initialize_encode ()
  1467. X{
  1468. X  static unsigned char msb_mask [8] =
  1469. X    { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  1470. X  static unsigned char lsb_mask [8] =
  1471. X    { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
  1472. X  static unsigned char msb_head_mask [8] =
  1473. X    { 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF };
  1474. X  static unsigned char lsb_head_mask [8] =
  1475. X    { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF };
  1476. X  static unsigned char msb_tail_mask [8] =
  1477. X    { 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 };
  1478. X  static unsigned char lsb_tail_mask [8] =
  1479. X    { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
  1480. X  output_fill_order = MSB_FIRST;    /* some implementations might
  1481. X                        want to change this */
  1482. X  encode_buffer = 0;
  1483. X  encode_position = 0;
  1484. X  if (output_fill_order == MSB_FIRST)
  1485. X  {
  1486. X    encode_mask = msb_mask;
  1487. X    encode_head_mask = msb_head_mask;
  1488. X    encode_tail_mask = msb_tail_mask;
  1489. X  }
  1490. X  else /* output_fill_order == LSB_FIRST */
  1491. X  {
  1492. X    encode_mask = lsb_mask;
  1493. X    encode_head_mask = lsb_head_mask;
  1494. X    encode_tail_mask = lsb_tail_mask;
  1495. X  }
  1496. X  pending_black = 0;
  1497. X  pending_white = 0;
  1498. X}
  1499. X
  1500. X/*
  1501. X *    append a codeword of the specified length in bits to the end
  1502. X *    of the current output file
  1503. X */
  1504. X
  1505. Xvoid encode_word (unsigned short codeword, short length)
  1506. X{
  1507. X/*********
  1508. X    There are two versions of this procedure.  One or the other
  1509. X    is to be commented out.  The first is somewhat faster,
  1510. X    especially on a 386 because it makes use of the barrel
  1511. X    shifter.  Its limitation is the assumption that the output
  1512. X    file is filled most-significant-bit first.  The second is
  1513. X    a little slower, but doesn't make the assumption.
  1514. X********/
  1515. X
  1516. X/* the faster routine, with the assumption . . . */
  1517. X  short first_count, second_count, remaining, new_encode_position;
  1518. X  static char limit_8 [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8,
  1519. X    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
  1520. X  if (length)
  1521. X  {
  1522. X    new_encode_position = limit_8 [encode_position + length];
  1523. X    first_count = new_encode_position - encode_position;
  1524. X    encode_buffer |= (codeword >> (encode_position + 8));
  1525. X    encode_position = new_encode_position;
  1526. X    remaining = length - first_count;
  1527. X    if (encode_position > 7)
  1528. X    {
  1529. X      (*p_encode_next_byte) (encode_buffer);
  1530. X      if (remaining)
  1531. X      {
  1532. X    encode_position = limit_8 [remaining];
  1533. X    second_count = encode_position;
  1534. X    remaining -= second_count;
  1535. X    encode_buffer = ((unsigned char) (codeword >> (8 - first_count)))
  1536. X        & encode_head_mask [second_count - 1];
  1537. X    if (encode_position > 7)
  1538. X    {
  1539. X      (*p_encode_next_byte) (encode_buffer);
  1540. X      if (remaining)
  1541. X      {
  1542. X        encode_buffer
  1543. X          = ((unsigned char) (codeword << first_count))
  1544. X        & encode_head_mask [remaining - 1];
  1545. X        encode_position = remaining;
  1546. X      }
  1547. X      else { encode_buffer = 0; encode_position = 0; }
  1548. X    }
  1549. X      }
  1550. X      else { encode_buffer = 0; encode_position = 0; }
  1551. X    }
  1552. X  }
  1553. X
  1554. X/* the slower routine, with no assumption about output file bit order . . . */
  1555. X/*
  1556. X  static short read_mask [16] = {0x8000, 0x4000, 0x2000, 0x1000, 0x0800,
  1557. X    0x0400, 0x0200, 0x0100, 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004,
  1558. X    0x0002, 0x0001};
  1559. X  short j1;
  1560. X  for (j1 = 0; j1 < length; j1 ++)
  1561. X  {
  1562. X    if (read_mask [j1] & codeword)
  1563. X      encode_buffer |= encode_mask [encode_position];
  1564. X    encode_position++;
  1565. X    if (encode_position > 7)
  1566. X    {
  1567. X      (*p_encode_next_byte) (encode_buffer);
  1568. X      encode_position = 0;
  1569. X      encode_buffer = 0;
  1570. X    }
  1571. X  }
  1572. X*/
  1573. X}
  1574. X/*    end $RCSfile: gnencode.c $ */
  1575. SHAR_EOF
  1576. chmod 0644 gnencode.c || echo "restore of gnencode.c fails"
  1577. sed 's/^X//' << 'SHAR_EOF' > read.me &&
  1578. X$Id: read.me 1.2 90/06/09 18:28:33 marking Exp $
  1579. X
  1580. XFiles
  1581. X
  1582. X    builddec.c    build group 3 and group 4 decoding tables
  1583. X    g3g4.h        definitions for groups 3 and 4 decoding
  1584. X    g3sdecod.c    routines to decode group 3 images using if statements
  1585. X    g3sencod.c    routines to encode group 3 images using if statements
  1586. X    g3tdecod.c    routines using tables to decode group 3 images
  1587. X    g4sencod.c    routines to encode group 4 images using if statements
  1588. X    g4sdecod.c    routines to decode group 4 images using if statements
  1589. X    g4tdecod.c    routines using tables to decode group 4 images
  1590. X    gnencode.c    utilities for the encode routines
  1591. X    read.me        this file
  1592. X
  1593. XRemarks
  1594. X
  1595. X    This is the first release of the g3g4 utilities. Work in progress
  1596. X    to enhance the capabilities of the toolkit includes table encoding
  1597. X    of group 3 and group 4 images, and some optimization.
  1598. X
  1599. X    A tiff toolkit is also being prepared. Although the routines in this
  1600. X    collection can be used with g3 and g4 images in tiff files, they
  1601. X    have no provision for handling the structure of the files themselves.
  1602. X    The future tiff toolkit will add those features.
  1603. X
  1604. X    Note that the calling sequence of the user-provided support routines
  1605. X    differs slightly from that indicated in the C Users Journal article.
  1606. X    The versions here make indirect calls using pointers, so that at
  1607. X    one time one input routine might be used, and at other times another.
  1608. X    This allows considerably more flexible usage, since the source of
  1609. X    the file can be changed without relinking. The names have been
  1610. X    changed a little to prevent inadvertent use of the old method.
  1611. X
  1612. XLegal
  1613. X    Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
  1614. X    Scottsdale, Arizona 85252-8039. All rights reserved.
  1615. X
  1616. X    License is granted by the copyright holder to distribute and use this
  1617. X    code without payment of royalties or the necessity of notification as
  1618. X    long as this notice (all the text under "LEGAL") is included.
  1619. X
  1620. X    Reference: $Id: read.me 1.2 90/06/09 18:28:33 marking Exp $
  1621. X
  1622. X    This program is offered without any warranty of any kind. It includes
  1623. X    no warranty of merchantability or fitness for any purpose. Testing and
  1624. X    suitability for any use are the sole responsibility of the user.
  1625. X
  1626. XInformation
  1627. X    Although there is no support offered with these programs, the author
  1628. X    will endeavor to correct errors. Updates will also be made available
  1629. X    from time to time.
  1630. X
  1631. X    Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
  1632. X    85252-8039 USA. Replies are not guaranteed to be swift. Beginning
  1633. X    July 1990, e-mail may be sent to uunet!ipel!marking.
  1634. X
  1635. X    Also beginning in July 1990, this code will be archived at the
  1636. X    ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
  1637. X    for 300/1200/2400 is (602)274-0462. When logging in, specify user
  1638. X    "public", system "bbs", and password "public".
  1639. X
  1640. X    This code is also available from the C Users Group in volume 317.
  1641. X
  1642. XHistory
  1643. X
  1644. X$Log:    read.me $
  1645. X\" Revision 1.2  90/06/09  18:28:33  marking
  1646. X\" update for release
  1647. X\" 
  1648. X\" Revision 1.1  89/06/09  17:56:42  marking
  1649. X\" Initial revision
  1650. X\" 
  1651. X
  1652. X-- end read.me
  1653. SHAR_EOF
  1654. chmod 0644 read.me || echo "restore of read.me fails"
  1655. sed 's/^X//' << 'SHAR_EOF' > submit.dsk &&
  1656. XThe C Users' Group welcomes submissions for inclusion in the
  1657. XC public domain library. Please sign and return the following information
  1658. Xwith your submission. Thank you.
  1659. X
  1660. X
  1661. XAUTHOR'S RELEASE
  1662. X
  1663. XFor CUG Library Contribution
  1664. X    
  1665. XWe can not distribute your submission without this release.
  1666. XPlease fill out, sign and return this form.  Don't hesitate to
  1667. Xcall if you have questions.
  1668. X
  1669. XNAME______________________________DATE________________________
  1670. X
  1671. XADDRESS_______________________________________________________
  1672. X
  1673. XCITY___________________________STATE_______ZIP________________
  1674. X
  1675. XCOUNTRY_______________________________________________________
  1676. X
  1677. XPHONE__________________________AFFILIATION____________________
  1678. X
  1679. XDESCRIPTION OF SUBMITTED MATERIALS:
  1680. X
  1681. X
  1682. X
  1683. X
  1684. X
  1685. X
  1686. X
  1687. X
  1688. X
  1689. XThe submitted materials are:
  1690. X
  1691. X____Of unknown origin or status.
  1692. X
  1693. X____(Someone else's Public Domain or Shareware)
  1694. X    To the best of my knowledge currently in the public domain
  1695. X    or authorized for distribution as shareware.
  1696. X
  1697. X____(My Public Domain)
  1698. X    Written by me and hereby placed into the public domain.
  1699. X    Permission is hereby granted to The C Users' Group to distribute
  1700. X    the submitted materials freely for non-commercial personal use.
  1701. X
  1702. X____(My Shareware)
  1703. X    Written by me and protected by certain copyright restrictions
  1704. X    clearly specified in the files constituting the submission.
  1705. X    Permission is hereby granted to The C Users' Group to
  1706. X    distribute the submitted materials, without royalty or
  1707. X    other compensation, and to charge their normal distribution
  1708. X    fee for such distribution, provided that my copyright restrictions
  1709. X    are included unchanged in each copy distributed. 
  1710. X
  1711. XSigned:_____________________________________Date:____________
  1712. X
  1713. X
  1714. XSUBMISSION GUIDELINES
  1715. X
  1716. XPlease avoid sub-directories, squeezed files, library files or other
  1717. Xcompacted formats. CUG appreciates and prefers submissions with
  1718. Xcataloging headers on all text files (See the sample below and our directory
  1719. Xfor the additional information.)
  1720. X
  1721. X
  1722. XSAMPLE HEADER
  1723. X/*
  1724. XHEADER:        ;
  1725. XTITLE:        Diskette sector editor;
  1726. XVERSION:    1.4;
  1727. X
  1728. XDESCRIPTION:    "Lets you view, edit and write back a diskette sector.
  1729. X
  1730. X        It needs a 24*80 cursor-addressable terminal, and requires
  1731. X        your custom CLRSCREEN() and GOTOXY() functions.  The
  1732. X        definitions of these functions appear early in SE.C.
  1733. X
  1734. X        Compiling requires SENTER.C, included on the diskette.
  1735. X        Also included are SE.DOC and SE.SUB.";
  1736. X
  1737. XKEYWORDS:    Disk, utility, editor, sector;
  1738. XSYSTEM:        CP/M-80, V2.2;
  1739. XFILENAME:    SE.C;
  1740. XWARNINGS:    "Requires Version 2.x of CP/M.
  1741. X        SE is not designed to work with systems using the DEBLOCK
  1742. X        routine in the BIOS to handle physical sectors larger than
  1743. X        128 bytes, so if you have such a system, and want to use SE,
  1744. X        you must modify the routines in SE which write back the edited
  1745. X        sector.  The BitMap command is not implemented.";
  1746. X
  1747. XSEE-ALSO:    SE.DOC, SENTER.C;
  1748. XAUTHORS:    Jan Larsson;
  1749. XCOMPILERS:    BDS C, v1.43 and 1.5a;
  1750. X*/
  1751. X
  1752. XThe C Users' Group (CUG) collects, maintains and distributes
  1753. Xpublic domain C source code, publishes a magazine, The C Users' Journal
  1754. Xand serves as a resource for C users. Several vendors have named
  1755. XCUG as the official users group for their implementation of C.
  1756. XFor membership and subscription information contact
  1757. X
  1758. X    The C Users' Group
  1759. X    2601 Iowa
  1760. X    Lawrence, KS 66046
  1761. X    (913) 841-1631
  1762. X
  1763. SHAR_EOF
  1764. chmod 0644 submit.dsk || echo "restore of submit.dsk fails"
  1765. rm -f s2_seq_.tmp
  1766. echo "You have unpacked the last part"
  1767. exit 0
  1768.  
  1769.