home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / unix / xenix / sco / 2714 < prev    next >
Encoding:
Text File  |  1992-08-19  |  13.6 KB  |  622 lines

  1. Newsgroups: comp.unix.xenix.sco
  2. Path: sparky!uunet!mercury.hsi.com!mlfarm!rosie!ron
  3. From: ron@mlfarm.com (Ronald Florence)
  4. Subject: Re: GIF viewer for Xenix
  5. In-Reply-To: vid@zooid.guild.org's message of 18 Aug 92 17:23:41 GMT
  6. Message-ID: <1992Aug19.125433.12290@mlfarm.com>
  7. Sender: news@rosie.mlfarm.com
  8. Organization: Maple Lawn Farm, Stonington, CT
  9. References: <714158621.25081@zooid.guild.org>
  10. Date: Wed, 19 Aug 1992 12:54:33 GMT
  11. Lines: 609
  12.  
  13. David Mason writes:
  14.  
  15.   [...] is there a .GIF viewer even for standard VGA for SCO Xenix 386
  16.   2.3.2?
  17.  
  18. This works, or at least did when we had a Xenix box here.  You will
  19. need the CGI package, and the CGIDISP and CGIPATH environmental
  20. variables.  With a little work, someone could add panning with mouse
  21. control for large gifs.  I'm not sure whether the SCO CGI includes a
  22. driver for super-VGA displays.
  23.  
  24.  
  25.                 Ronald Florence
  26.                 ron@mlfarm.com
  27.  
  28.  
  29.  
  30. #! /bin/sh
  31. # This is a shell archive, meaning:
  32. # 1. Remove everything above the #! /bin/sh line.
  33. # 2. Save the resulting text in a file.
  34. # 3. Execute the file with /bin/sh (not csh) to create:
  35. #    Makefile
  36. #    gif.c
  37. # This archive created: Wed Aug 19 08:48:11 1992
  38. # By:    Ronald Florence (Maple Lawn Farm, Stonington, CT )
  39. export PATH; PATH=/bin:/usr/bin:$PATH
  40. echo shar: "extracting 'Makefile'" '(181 characters)'
  41. if test -f 'Makefile'
  42. then
  43.     echo shar: "will not over-write existing file 'Makefile'"
  44. else
  45. sed 's/^X//' << \SHAR_EOF > 'Makefile'
  46. X# tek/gif makefile
  47. X# copyright 1990 Ronald Florence
  48. X# 
  49. X# add -DBROKEN_MONO_VGA to CFLAGS if needed
  50. X
  51. XCC = gcc -m80387
  52. XCFLAGS= -O -DBROKEN_MONO_VGA
  53. XLDFLAGS= /usr/lib/386/Slibccgi.a
  54. X
  55. X
  56. SHAR_EOF
  57. if test 181 -ne "`wc -c < 'Makefile'`"
  58. then
  59.     echo shar: "error transmitting 'Makefile'" '(should have been 181 characters)'
  60. fi
  61. fi
  62. echo shar: "extracting 'gif.c'" '(11281 characters)'
  63. if test -f 'gif.c'
  64. then
  65.     echo shar: "will not over-write existing file 'gif.c'"
  66. else
  67. sed 's/^X//' << \SHAR_EOF > 'gif.c'
  68. X/*
  69. Xgif.c - gif viewer for SCO CGI
  70. Xcopyright 1990 Ronald Florence (ron@mlfarm, 6.18.90)
  71. X(parts based on an SGI Iris viewer of unknown origins)
  72. X
  73. XTo use this viewer, you need both the CGIPATH and CGIDISP
  74. Xenvironmental variables declared.
  75. X
  76. XPermission is hereby granted for unlimited non-commercial
  77. Xuse of this program, on condition that the copyright notices
  78. Xare left intact and any modifications to the source code are
  79. Xnoted as such.  No warranty of any kind is implied or
  80. Xgranted for this material.  
  81. X
  82. X*/
  83. X
  84. X
  85. X#include <stdio.h>
  86. X#include <signal.h>
  87. X
  88. Xtypedef unsigned char Uchar;
  89. Xshort    cgidev, Ystep, Xmax;
  90. X
  91. Xtypedef struct {
  92. X  int    dx, dy;            /* size */
  93. X  int    colors,            /* # colors */
  94. X    bits,            /* bits/pixel */
  95. X    cr;            /* color resolution */
  96. X  char    gcm,            /* global color map flag */
  97. X    bgnd;            /* background color */
  98. X} screen_dscrp;
  99. X
  100. Xtypedef struct {
  101. X  int    x, y, dx, dy,        /* position, size */
  102. X    colors, bits;        /* num colors, bits/pixel */
  103. X  char    gcm,            /* use global color map */
  104. X    order;            /* seq. or interlaced */
  105. X} image_dscrp;
  106. X
  107. XUchar        g_colors[256][3],    /* Global color map */
  108. X        pixel_row[4096];
  109. Xint        bits_left, 
  110. X        byte_count,
  111. X        mask[14] = {0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff,
  112. X            0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff},
  113. X        code_size, countsize, countdown,
  114. X        dy_table[4] = {8, 8, 4, 2}, 
  115. X        offset_table[4] = {0, 4, 2, 1},
  116. X        last_char, bit_mask, least_bits;
  117. Xshort        code_table[4096][2], 
  118. X        cmap;
  119. XFILE        *stream_source;        /* file for input */
  120. Xscreen_dscrp    si;            /* global screen descriptor */
  121. X
  122. X
  123. X
  124. Xint    mscanf(infile, parse)
  125. X     FILE *infile; 
  126. X     char *parse;
  127. X{
  128. X  char    *scan;
  129. X  int    dx, dy;
  130. X
  131. X  for (scan = parse; *scan; scan++)
  132. X    if (getc(infile) != (int)*scan) 
  133. X      return(0);
  134. X  return(!0);
  135. X}
  136. X
  137. X
  138. Xint    scan_SD(infile, sd)
  139. X     FILE *infile;
  140. X     screen_dscrp *sd;
  141. X{
  142. X  Uchar    data;
  143. X
  144. X  data = (Uchar)getc(infile);
  145. X  sd->dx = data + ((Uchar)getc(infile) << 8);
  146. X  data = (Uchar)getc(infile);
  147. X  sd->dy = data + ((Uchar)getc(infile) << 8);
  148. X  data = getc(infile);
  149. X  if (data & 8) 
  150. X    return(0);
  151. X  sd->gcm = data & 0x80;
  152. X  sd->cr = (data & 0x70) >> 4;
  153. X  sd->bits = (data & 7) + 1;
  154. X  sd->colors = 1 << sd->bits;
  155. X  sd->bgnd = getc(infile);
  156. X  if (getc(infile) != 0) 
  157. X    return(0);
  158. X  return(!0);
  159. X}
  160. X
  161. X
  162. Xvoid    skip_EB(infile)
  163. X     FILE *infile;
  164. X{
  165. X  int    count;
  166. X  char    garbage[256];
  167. X
  168. X  getc(infile);        /* get function */
  169. X  while (count = getc(infile)) 
  170. X    fread(garbage, 1, count, infile);
  171. X}
  172. X
  173. X
  174. Xint    scan_ID(infile, id)
  175. X     FILE *infile;
  176. X     image_dscrp *id;
  177. X{
  178. X  Uchar    data;
  179. X
  180. X  do 
  181. X    {
  182. X      data = (Uchar)getc(infile);
  183. X      if (data == ';') 
  184. X    return(1);
  185. X      if (feof(infile)) 
  186. X    return(0);
  187. X      if (data ==0x21) 
  188. X    skip_EB(infile);
  189. X    } while (data != 0x2c);
  190. X  data = (Uchar)getc(infile);
  191. X  id->x = data + ((Uchar)getc(infile) << 8);
  192. X  data = (Uchar)getc(infile);
  193. X  id->y = data + ((Uchar)getc(infile) << 8);
  194. X  data = (Uchar)getc(infile);
  195. X  id->dx = data + ((Uchar)getc(infile) << 8);
  196. X  data = (Uchar)getc(infile);
  197. X  id->dy = data + ((Uchar)getc(infile) << 8);
  198. X  data = (Uchar)getc(infile);
  199. X  id->gcm = data & 0x80;
  200. X  id->order = data & 0x40;
  201. X  id->bits = (data & 7) + 1;
  202. X  id->colors = 1 << id->bits;
  203. X  return(2);
  204. X}
  205. X
  206. X
  207. Xvoid    scan_CM(infile, colors, cm)
  208. X     FILE *infile;
  209. X     int colors;
  210. X     Uchar *cm;
  211. X{
  212. X  Uchar    *scan;
  213. X  int    i;
  214. X
  215. X  for (scan = cm, i = 3 * colors; i > 0; i--)
  216. X    *scan++ = (Uchar)getc(infile);
  217. X}
  218. X
  219. X
  220. Xvoid    reset_codes()
  221. X{
  222. X  code_size = least_bits + 1;
  223. X  if (code_size <= 2) 
  224. X    code_size = 3;
  225. X  countsize = 1 << code_size;
  226. X  countdown = countsize - (1 << least_bits) - 2;
  227. X  bit_mask = (long)mask[code_size];
  228. X}
  229. X
  230. X
  231. Xvoid    clear_stream(infile, bits)
  232. X     FILE *infile;
  233. X     int bits;
  234. X{
  235. X  getc(infile);        /* skip minimum bit size */
  236. X  byte_count = 0;
  237. X  last_char = 0;
  238. X  bits_left = 0;
  239. X  least_bits = bits;
  240. X  stream_source = infile;
  241. X  reset_codes();
  242. X}
  243. X
  244. X
  245. Xshort    get_code()
  246. X{
  247. X  static char    flag = 0;
  248. X  short        code;
  249. X  int        new;
  250. X
  251. X  if (byte_count == 0) 
  252. X    byte_count = getc(stream_source);
  253. X  if (bits_left < code_size) 
  254. X    {
  255. X      new = (int)getc(stream_source);
  256. X      byte_count--;
  257. X      if (bits_left + 8 < code_size) 
  258. X    {
  259. X      if (byte_count == 0) 
  260. X        byte_count = getc(stream_source);
  261. X      byte_count--;
  262. X      new |= ((int)getc(stream_source) << 8);
  263. X      code = 16; 
  264. X    }
  265. X      else 
  266. X    code = 8;
  267. X      if (bits_left) 
  268. X    new <<= bits_left;
  269. X      last_char |= new;
  270. X      bits_left += code;
  271. X    }
  272. X  code = (short)(last_char & bit_mask);
  273. X  last_char >>= code_size;
  274. X  bits_left -= code_size;
  275. X  if (flag) 
  276. X    {
  277. X      flag = 0;
  278. X      reset_codes();
  279. X    }
  280. X  else if (--countdown == 0) 
  281. X    {
  282. X      countdown = countsize;
  283. X      countsize <<= 1;
  284. X      if (++code_size == 13) 
  285. X    { 
  286. X      flag = 1; 
  287. X      code_size--; 
  288. X    }
  289. X      else 
  290. X    bit_mask = (int)mask[code_size];
  291. X    }
  292. X  return(code);
  293. X}
  294. X
  295. X
  296. Xvoid    install_cmap(colors, cm)
  297. X     int colors;
  298. X     Uchar *cm;
  299. X{
  300. X  Uchar    *scan;
  301. X  unsigned int color;
  302. X  int    i;
  303. X  short rgb[3], rgb_out[3];
  304. X
  305. X  for (scan = cm, i = cmap; colors > 0; scan += 3, i++, colors--)
  306. X    {
  307. X#ifndef BROKEN_MONO_VGA
  308. X      rgb[0] = *scan << 2;
  309. X      rgb[1] = *(scan + 1) << 2;
  310. X      rgb[2] = *(scan + 2) << 2;
  311. X#else
  312. X      color = 77 * *scan + 150 * *(scan + 1) + 29 * *(scan +2);
  313. X      rgb[0] = rgb[1] = rgb[2] = color >> 6;
  314. X#endif
  315. X      vs_color(cgidev, i, rgb, rgb_out);
  316. X    }
  317. X}
  318. X
  319. X
  320. Xvoid    setup_codes(colors)
  321. X     int colors;
  322. X{
  323. X  int    i;
  324. X
  325. X  for (i = 0; i < colors; i++) 
  326. X    code_table[i][0] = code_table[i][1] = i;
  327. X}
  328. X
  329. X
  330. Xvoid    read_interlaced(id)
  331. X     image_dscrp *id;
  332. X{
  333. X  int    table_ptr, row_count, dy, y, pass, end_code, clear_code;
  334. X  short    prefix, suffix, save, stack[4096], *stack_ptr;
  335. X  Uchar *pixel = pixel_row;
  336. X  short origin[2], v_width[2], v_height[2];
  337. X
  338. X  v_width[0] = id->x;
  339. X  v_width[1] = (id->x + id->dx - 1 > Xmax) ? Xmax : id->x + id->dx - 1;
  340. X  v_height[0] = v_height[1] = 0;
  341. X  origin[0] = 0;
  342. X
  343. X  row_count = id->dx;
  344. X  clear_code = id->colors;
  345. X  end_code = clear_code + 1;
  346. X  while ((prefix = get_code()) == clear_code)
  347. X    ;
  348. X  reset_codes();
  349. X  table_ptr = clear_code + 2;
  350. X  for (pass = 0; pass < 4; pass++) 
  351. X    {
  352. X      y = id->y + id->dy - 1 - offset_table[pass];
  353. X      dy = dy_table[pass];
  354. X      while (y >= 0 && (save = suffix = get_code()) != end_code) 
  355. X    {
  356. X      if (suffix == clear_code) 
  357. X        {
  358. X          reset_codes();
  359. X          while ((save = get_code()) == clear_code)
  360. X        ;
  361. X          reset_codes();
  362. X          table_ptr = clear_code + 1;
  363. X        }
  364. X          else 
  365. X        {
  366. X          code_table[table_ptr][0] = prefix;
  367. X          if (suffix == table_ptr)
  368. X        code_table[table_ptr][1] = code_table[prefix][1];
  369. X          else 
  370. X        {
  371. X          while (suffix >= id->colors) 
  372. X            suffix = code_table[suffix][0];
  373. X          code_table[table_ptr][1] = suffix;
  374. X        }
  375. X        }
  376. X      suffix = 1;
  377. X      stack_ptr = stack;
  378. X      while (prefix >= id->colors) 
  379. X        {
  380. X          *stack_ptr++ = code_table[prefix][1];
  381. X          prefix = code_table[prefix][0];
  382. X          suffix++;
  383. X        }
  384. X      *stack_ptr = prefix;
  385. X      for ( ; suffix > 0; stack_ptr--, suffix--) 
  386. X        {
  387. X          *pixel++ = (Uchar)(cmap + *stack_ptr);
  388. X          if (--row_count == 0) 
  389. X        {
  390. X          row_count = id->dx;
  391. X          pixel = pixel_row;
  392. X
  393. X          origin[1] = (short)(y * Ystep);
  394. X          vb_pixels(cgidev, origin, 4096, 1, v_width, v_height,
  395. X               pixel_row);
  396. X          y -= dy;
  397. X        }
  398. X        }
  399. X      table_ptr++;
  400. X      prefix = save;
  401. X    }
  402. X    }
  403. X}
  404. X
  405. Xvoid    read_sequential(id)
  406. X     image_dscrp *id;
  407. X{
  408. X  int    table_ptr, row_count, y, end_code, clear_code;
  409. X  Uchar    *pixel = pixel_row;
  410. X  short prefix, suffix, save, stack[4096], *stack_ptr;
  411. X  short origin[2], v_width[2], v_height[2];
  412. X
  413. X  v_width[0] = id->x;
  414. X  v_width[1] = (id->x + id->dx - 1 > Xmax) ? Xmax : id->x + id->dx - 1;
  415. X  v_height[0] = v_height[1] = 0;
  416. X  origin[0] = 0;
  417. X
  418. X  y = id->y + id->dy - 1;
  419. X  row_count = id->dx;
  420. X  clear_code = id->colors;
  421. X  end_code = clear_code + 1;
  422. X  while ((prefix = get_code()) == clear_code)
  423. X    ;
  424. X  reset_codes();
  425. X  table_ptr = clear_code + 2;
  426. X  while ((save = suffix = get_code()) != end_code) 
  427. X    {
  428. X      if (suffix == clear_code) 
  429. X    {
  430. X      reset_codes();
  431. X      while ((save = get_code()) == clear_code)
  432. X        ;
  433. X      reset_codes();
  434. X      table_ptr = clear_code + 1;
  435. X    }
  436. X      else 
  437. X    {
  438. X      code_table[table_ptr][0] = prefix;
  439. X      if (suffix == table_ptr)
  440. X        code_table[table_ptr][1] = code_table[prefix][1];
  441. X      else 
  442. X        {
  443. X          while (suffix >= id->colors) suffix = code_table[suffix][0];
  444. X          code_table[table_ptr][1] = suffix;
  445. X        }
  446. X    }
  447. X      suffix = 1;
  448. X      stack_ptr = stack;
  449. X      while (prefix >= id->colors) 
  450. X    {
  451. X      *stack_ptr++ = code_table[prefix][1];
  452. X      prefix = code_table[prefix][0];
  453. X      suffix++;
  454. X    }
  455. X      *stack_ptr = prefix;
  456. X      for ( ; suffix > 0; stack_ptr--, suffix--) 
  457. X    {
  458. X      *pixel++ = (Uchar)(cmap + *stack_ptr);
  459. X      if (--row_count == 0) 
  460. X        {
  461. X          row_count = id->dx;
  462. X          pixel = pixel_row;
  463. X          origin[1] = (short)(y * Ystep);
  464. X          vb_pixels(cgidev, origin, 4096, 1, v_width, v_height, pixel_row);
  465. X          y--;
  466. X        }
  467. X    }
  468. X      table_ptr++;
  469. X      prefix = save;
  470. X    }
  471. X}
  472. X
  473. Xint    draw_image(infile)
  474. X     FILE *infile;
  475. X{
  476. X  Uchar        lcm[256][3];
  477. X  int        flag;
  478. X  image_dscrp    id;
  479. X
  480. X  flag = scan_ID(infile, &id);
  481. X  if (flag == 0) 
  482. X    {
  483. X      printf("unexpected eof.\n");
  484. X      exit(3);
  485. X    }
  486. X  if (flag == 1) 
  487. X    return(0);
  488. X  if (id.gcm) 
  489. X    {
  490. X      scan_CM(infile, id.colors, (Uchar *)lcm);
  491. X      install_cmap(id.colors, (Uchar *)lcm);
  492. X    }
  493. X  else 
  494. X    {
  495. X      install_cmap(si.colors, (Uchar *)g_colors);
  496. X      id.colors = si.colors;
  497. X      id.bits = si.bits;
  498. X    }
  499. X
  500. X  if (id.bits == 1) 
  501. X    {    /* Need extra bit for 2 color pic. */
  502. X      id.bits = 2;
  503. X      id.colors = 4;
  504. X    }
  505. X  clear_stream(infile, id.bits);
  506. X  setup_codes(id.colors);
  507. X
  508. X  if (id.order) 
  509. X    read_interlaced(&id);
  510. X  else 
  511. X    read_sequential(&id);
  512. X  return(!0);
  513. X}
  514. X
  515. Xvoid    main(argc, argv)
  516. X     int argc;
  517. X     char **argv;
  518. X{
  519. X  FILE    *gif_data;
  520. X  short    gin[19], gout[66];
  521. X  int    i = 1;
  522. X  char    *cgidriver, *getenv();
  523. X  void    (*sig_handler)();
  524. X
  525. X  if (argc < 2 || argc > 3) 
  526. X    {
  527. X      printf("usage: %s [-v] GIF_file\n", argv[0]);
  528. X      exit(1);
  529. X    }
  530. X  if (!strcmp(argv[i], "-v"))
  531. X    i++;
  532. X    
  533. X  gif_data = fopen(argv[i], "r");
  534. X  if (gif_data == NULL) 
  535. X    {
  536. X      printf("can't open %s.\n", argv[i]);
  537. X      exit(1);
  538. X    }
  539. X  if (!mscanf(gif_data, "GIF87a")) 
  540. X    {
  541. X      printf("%s not a gif file.\n", argv[i]);
  542. X      exit(2);
  543. X    }
  544. X
  545. X  if (!scan_SD(gif_data, &si)) 
  546. X    {
  547. X      printf("data format error.\n");
  548. X      exit(3);
  549. X    }
  550. X  if (i == 2)
  551. X    {
  552. X      printf("File %s:\nresolution: %dx%d\ncolors: %d\n",
  553. X         argv[i], si.dx, si.dy, si.colors);
  554. X      sleep(2);
  555. X    }
  556. X  if (si.gcm) 
  557. X    scan_CM(gif_data, si.colors, (Uchar *)g_colors);
  558. X
  559. X  if (!getenv(cgidriver = "CGIDISP"))
  560. X    {
  561. X      printf("%s: no cgi driver\n", argv[0]);
  562. X      exit(4);
  563. X    }
  564. X  for (i = 0; cgidriver[i]; i++) 
  565. X    gin[11+i] = cgidriver[i];
  566. X  gin[18] = ' ';
  567. X
  568. X  for (i = 1; i < SIGQUIT; i++)
  569. X    signal(i, sig_handler);
  570. X
  571. X  if (v_opnwk(gin, &cgidev, gout) < 0) 
  572. X    {
  573. X      printf("CGI error %d opening %s\n", -vq_error(), cgidriver);
  574. X      exit(5);
  575. X    }
  576. X  if (gout[38] = 0)
  577. X    {
  578. X      printf("%s: %s device is not capable of pixel operations\n",
  579. X         argv[0], cgidriver);
  580. X      sleep(2);
  581. X      v_clswk(cgidev);
  582. X      exit(6);
  583. X    }
  584. X  Ystep = (short)((long)(gout[52] + 1L) / (long)si.dy);
  585. X  Xmax = gout[51];
  586. X
  587. X  while (draw_image(gif_data))
  588. X    ;
  589. X
  590. X  if (gout[45] == 0)
  591. X    {
  592. X      short ptin[2];
  593. X      char  strin[2];
  594. X      
  595. X      ptin[0] = 0;
  596. X      ptin[1] = 0;
  597. X      vrq_string(cgidev, 1, 0, ptin, strin);
  598. X    }
  599. X  v_clswk(cgidev);
  600. X  exit(0);
  601. X}
  602. X
  603. Xvoid    sig_handler(sig)
  604. X     int sig;
  605. X{
  606. X  v_clswk(cgidev);
  607. X  exit (-sig);
  608. X}
  609. SHAR_EOF
  610. if test 11281 -ne "`wc -c < 'gif.c'`"
  611. then
  612.     echo shar: "error transmitting 'gif.c'" '(should have been 11281 characters)'
  613. fi
  614. fi
  615. exit 0
  616. #    End of shell archive
  617. -- 
  618.  
  619.                 Ronald Florence
  620.                 ron@mlfarm.com
  621.