home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume36 / chiaro / part13 < prev    next >
Text File  |  1993-03-26  |  57KB  |  1,877 lines

  1. Newsgroups: comp.sources.misc
  2. From: jwbirdsa@picarefy.picarefy.com (James W. Birdsall)
  3. Subject: v36i083:  chiaro - Image Utilities, Part13/18
  4. Message-ID: <1993Mar26.202851.14852@sparky.imd.sterling.com>
  5. X-Md4-Signature: f722aa48bbec0ab1f49169467a808a54
  6. Date: Fri, 26 Mar 1993 20:28:51 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jwbirdsa@picarefy.picarefy.com (James W. Birdsall)
  10. Posting-number: Volume 36, Issue 83
  11. Archive-name: chiaro/part13
  12. Environment: UNIX, Sun, DECstation, 3B1
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  src/blocproc.c.A src/gifstrip.1 src/pcx.c
  19. # Wrapped by kent@sparky on Thu Mar 25 11:20:06 1993
  20. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 13 (of 18)."'
  23. if test -f 'src/blocproc.c.A' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'src/blocproc.c.A'\"
  25. else
  26.   echo shar: Extracting \"'src/blocproc.c.A'\" \(29781 characters\)
  27.   sed "s/^X//" >'src/blocproc.c.A' <<'END_OF_FILE'
  28. X/***************************************************************************
  29. X*   BLOCPROC.C                                                             *
  30. X*   MODULE:  -                                                             *
  31. X*   OS:      UNIX                                                          *
  32. X*                                                                          *
  33. X*   Copyright (c) 1993 James W. Birdsall. All Rights Reserved.             *
  34. X*                                                                          *
  35. X*   The Graphics Interchange Format(c) is the Copyright property of        *
  36. X*   CompuServe Incorporated. GIF(sm) is a Service Mark property of         *
  37. X*   CompuServe Incorporated.                                               *
  38. X*                                                                          *
  39. X*   GIF and "Graphic Interchange Format" are trademarks (tm) of            *
  40. X*   CompuServe, Inc., an H&R Block company.                                *
  41. X*                                                                          *
  42. X*   $Id: blocproc.c,v 1.6 1993/02/10 01:59:38 jwbirdsa Exp $
  43. X*                                                                          *
  44. X***************************************************************************/
  45. X
  46. X#include "config.h"
  47. X
  48. X/*
  49. X** system includes <>
  50. X*/
  51. X
  52. X#include <stdio.h>
  53. X#ifndef NO_STDLIB
  54. X#include <stdlib.h>
  55. X#endif
  56. X#include <ctype.h>
  57. X#ifndef NO_MALLOCHDR
  58. X#include <malloc.h>
  59. X#endif
  60. X
  61. X
  62. X/*
  63. X** custom includes ""
  64. X*/
  65. X
  66. X#include "depend.h"
  67. X
  68. X#include "fb.h"
  69. X
  70. X#include "formats.h"
  71. X#include "gif.h"
  72. X#include "gld.h"
  73. X
  74. X#include "colors.h"
  75. X
  76. X#include "gifcheck.h"
  77. X#include "blocproc.h"
  78. X
  79. X
  80. X/*
  81. X** local #defines
  82. X*/
  83. X
  84. X/* Sizes of various displays. */
  85. X
  86. X#define HEXLINELEN           8
  87. X#define COLORLINELEN         5
  88. X
  89. X/* Fast decompression overhead. */
  90. X
  91. X#ifndef SMALL_MEM
  92. X#define EXTRA_TABLESIZE      20000
  93. X#else
  94. X#define EXTRA_TABLESIZE      2000
  95. X#endif
  96. X
  97. X
  98. X/*
  99. X** misc: copyright strings, version macros, etc.
  100. X*/
  101. X
  102. Xstatic char CONST rcsid[] = "$Id: blocproc.c,v 1.6 1993/02/10 01:59:38 jwbirdsa Exp $";
  103. X
  104. X
  105. X/*
  106. X** typedefs
  107. X*/
  108. X
  109. X/*
  110. X** global variables
  111. X*/
  112. X
  113. X/* Global color table. */
  114. X
  115. XRGB_TRIPLET *gct = (RGB_TRIPLET *) NULL;
  116. X
  117. X/* Last state. */
  118. X
  119. Xint laststate;
  120. X
  121. X
  122. X/* Default: allow leading junk. */
  123. X
  124. Xextern int lead;
  125. X
  126. X/* Default: do decompression. */
  127. X
  128. Xextern int decomp;
  129. X
  130. X/* Default: don't dump color tables. */
  131. X
  132. Xextern int do_colordump;
  133. X
  134. X/* Default: display FASCINATING and above, abort on VIOLATION and above. */
  135. X
  136. Xextern int dlevel;
  137. Xextern int elevel;
  138. X
  139. X/* Default: terse displays. */
  140. X
  141. Xextern int verbose;
  142. X
  143. X/* Default: don't do hex dump of PTEs, comments, app & generic extensions. */
  144. X
  145. Xextern int do_hexdump;
  146. X
  147. X/* Display progress indicator? */
  148. X
  149. X#ifdef PROGRESS_IND
  150. Xextern int prog_ind;
  151. X#endif
  152. X
  153. X/* File descriptors for standard and error output. */
  154. X
  155. Xextern FILE *outstr;
  156. Xextern FILE *outerr;
  157. X
  158. X/* Global scratch space. */
  159. X
  160. Xextern char scratch[];
  161. X
  162. X
  163. X/*
  164. X** static globals
  165. X*/
  166. X
  167. X/* Global color table stuff. */
  168. X
  169. Xstatic int globcolors;
  170. Xstatic int globsize;
  171. X
  172. X/* Size of logical screen. */
  173. X
  174. Xstatic unsigned int logwid;
  175. Xstatic unsigned int loghi;
  176. X
  177. X/* Transparency index. */
  178. X
  179. Xstatic int transparent = -1;
  180. X
  181. X/* For progress indication. */
  182. X
  183. X#ifdef PROGRESS_IND
  184. Xstatic char clockface[] = "|/-\\";
  185. X#endif
  186. X
  187. X/* State names array. */
  188. X
  189. Xstatic char *state_names[] = { "logical screen descriptor & global color table",
  190. X                               "graphic control extension",
  191. X                               "image",
  192. X                               "plain-text extension",
  193. X                               "generic extension",
  194. X                               "comment extension",
  195. X                               "application extension" };
  196. X
  197. X/* State transition table. */
  198. X
  199. Xstatic int state_trans[STATE_MAX][STATE_MAX] = {
  200. X/*          BEGIN   GCE IMAGE   PTE GENEXT  COMMENT APP TERM */
  201. X/* BEGIN */ 0,      1,  1,      1,  1,      1,      1,  1,
  202. X/* GCE   */ 0,      0,  1,      1,  0,      0,      0,  0,
  203. X/* IMAGE */ 0,      1,  1,      1,  1,      1,      1,  1,
  204. X/* PTE   */ 0,      1,  1,      1,  1,      1,      1,  1,
  205. X/* GEN   */ 0,      1,  1,      1,  1,      1,      1,  1,
  206. X/* COMNT */ 0,      1,  1,      1,  1,      1,      1,  1,
  207. X/* APP   */ 0,      1,  1,      1,  1,      1,      1,  1,
  208. X/* TERM  */ 0,      0,  0,      0,  0,      0,      0,  0 } ;
  209. X
  210. X
  211. X/*
  212. X** function prototypes
  213. X*/
  214. X
  215. X#ifdef  __STDC__
  216. X# define P_(s) s
  217. X#else
  218. X# define P_(s) ()
  219. X#endif
  220. X
  221. Xstatic unsigned int count_unprint P_((UCHAR *data, unsigned int len));
  222. Xstatic VOID hexdump P_((UCHAR *data, unsigned int len));
  223. Xstatic VOID colordump P_((RGB_TRIPLET *ctable, int colors));
  224. X
  225. Xstatic VOID callback P_((long donelen, UCHAR **buffer, long *availlen, long *bufpos));
  226. X
  227. X#undef P_
  228. X
  229. X
  230. X/*
  231. X** functions
  232. X*/
  233. X
  234. X
  235. X/***************************************************************************
  236. X*   FUNCTION: GLOBAL_PRINTOUT                                              *
  237. X*                                                                          *
  238. X*   DESCRIPTION:                                                           *
  239. X*                                                                          *
  240. X*       Prints out info from Logical Screen Descriptor and global color    *
  241. X*       table.                                                             *
  242. X*                                                                          *
  243. X*   ENTRY:                                                                 *
  244. X*                                                                          *
  245. X*       infile   - handle of file                                          *
  246. X*       filename - name of file                                            *
  247. X*       lsd      - LSD data from file                                      *
  248. X*       size     - length of file                                          *
  249. X*                                                                          *
  250. X*   EXIT:                                                                  *
  251. X*                                                                          *
  252. X*       Returns an errorlevel code.                                        *
  253. X*                                                                          *
  254. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  255. X*                                                                          *
  256. X***************************************************************************/
  257. Xint 
  258. X#ifdef __STDC__
  259. Xglobal_printout(FB *infile, char *filename, GIF_LSD *lsd, long size)
  260. X#else
  261. Xglobal_printout(infile, filename, lsd, size)
  262. XFB *infile;
  263. Xchar *filename;
  264. XGIF_LSD *lsd;
  265. Xlong size;
  266. X#endif
  267. X{
  268. X    ULONG status;
  269. X    int loop;
  270. X    long uniques, entries;
  271. X    int chandle;
  272. X    int denom;
  273. X
  274. X    /* Print some info from logical screen descriptor. */
  275. X
  276. X    fprintf(outstr, "FILE %s", filename);
  277. X    if (verbose != 0)
  278. X    {
  279. X        fprintf(outstr, " is GIF version GIF%s:\n",
  280. X                ((GIF_89A == lsd->version) ? "89a" : "87a"));
  281. X        fprintf(outstr, "   file size (bytes): %8ld\n", size);
  282. X        fprintf(outstr,
  283. X                "   logical screen size (pixels, width x height): %5u x %5u\n",
  284. X                lsd->scr_wid, lsd->scr_hi);
  285. X    }
  286. X    else
  287. X    {
  288. X        fprintf(outstr, "   GIF%s   %8ld bytes\n",
  289. X                ((GIF_89A == lsd->version) ? "89a" : "87a"), size);
  290. X        fprintf(outstr, "   logical screen:  %5u x %5u", lsd->scr_wid,
  291. X                lsd->scr_hi);
  292. X    }
  293. X
  294. X    if (lsd->aspect != 0)
  295. X    {
  296. X        if (GIF_89A == lsd->version)
  297. X        {
  298. X            for (denom = 64, loop = lsd->aspect; ((loop & 0x1) == 0);
  299. X                 denom >>= 1, loop >>= 1) ;
  300. X            if (verbose != 0)
  301. X            {
  302. X                fprintf(outstr, "   logical screen aspect ratio: ");
  303. X            }
  304. X            else
  305. X            {
  306. X                fprintf(outstr, "   aspect ");
  307. X            }
  308. X            fprintf(outstr, "%3d/%2d\n", loop, denom);
  309. X        }
  310. X        else
  311. X        {
  312. X            if (dlevel >= DLEVEL_NITPICK)
  313. X            {
  314. X                fprintf(outstr, "\nNITPICK: byte 6 of logical screen descriptor should be 0 for GIF87A\n");
  315. X            }
  316. X        }
  317. X    }
  318. X    else if (GIF_89A == lsd->version)
  319. X    {
  320. X        if (verbose != 0)
  321. X        {
  322. X            fprintf(outstr, "   logical screen aspect ratio not given.\n");
  323. X        }
  324. X        else
  325. X        {
  326. X            fprintf(outstr, "   aspect ---\n");
  327. X        }
  328. X    }
  329. X    else if (0 == verbose)
  330. X    {
  331. X        fputc('\n', outstr);
  332. X    }
  333. X    fprintf(outstr, "   %d bits per color available on source\n", lsd->clr_res);
  334. X    if (verbose != 0)
  335. X    {
  336. X        if (lsd->gct_flag)
  337. X        {
  338. X            fprintf(outstr, "   This file has a global color table.\n");
  339. X        }
  340. X        else
  341. X        {
  342. X            fprintf(outstr,
  343. X                         "   This file does not have a global color table.\n");
  344. X        }
  345. X    }
  346. X
  347. X    /* Save logical screen dimensions. */
  348. X
  349. X    logwid = lsd->scr_wid;
  350. X    loghi = lsd->scr_hi;
  351. X
  352. X    /* Get global color table, if any. */
  353. X
  354. X    if (lsd->gct_flag)
  355. X    {
  356. X        fprintf(outstr, "GLOBAL COLOR TABLE:\n");
  357. X        globcolors = 0x1 << lsd->gct_size;
  358. X        globsize = lsd->gct_size;
  359. X        if (verbose != 0)
  360. X        {
  361. X            fprintf(outstr, "   %d bits per index for a table size of %d\n",
  362. X                    lsd->gct_size, globcolors);
  363. X        }
  364. X        else
  365. X        {
  366. X            fprintf(outstr, "   %d bits (%d colors)", lsd->gct_size,
  367. X                    globcolors);
  368. X        }
  369. X        if (lsd->sort_flag)
  370. X        {
  371. X            if (GIF_89A == lsd->version)
  372. X            {
  373. X                if (verbose != 0)
  374. X                {
  375. X                    fprintf(outstr, "   The global color table is sorted by decreasing importance.\n");
  376. X                }
  377. X                else
  378. X                {
  379. X                    fprintf(outstr, "   sorted  ");
  380. X                }
  381. X            }
  382. X            else
  383. X            {
  384. X                if (dlevel >= DLEVEL_NITPICK)
  385. X                {
  386. X                    fprintf(outstr, "\nNITPICK: bit 3, byte 4 of logical screen descriptor should be 0 for GIF87A\n");
  387. X                }
  388. X            }
  389. X        }
  390. X        else if (GIF_89A == lsd->version)
  391. X        {
  392. X            if (verbose != 0)
  393. X            {
  394. X                fprintf(outstr, "   The global color table is not sorted.\n");
  395. X            }
  396. X            else
  397. X            {
  398. X                fprintf(outstr, "   unsorted");
  399. X            }
  400. X        }
  401. X
  402. X        if ((status = gif_gctget(infile, &gct, globcolors)) != ST_SUCCESS)
  403. X        {
  404. X            fprintf(outerr, "%s\n", errxlate(status));
  405. X            fb_close(infile);
  406. X            return ((GIF_UNEOF_E == status) ? EXIT_UNEOF : EXIT_ERROR);
  407. X        }
  408. X
  409. X        if (verbose != 0)
  410. X        {
  411. X            fprintf(outstr,
  412. X                    "   background index %d, RGB value %03d/%03d/%03d\n",
  413. X                    lsd->background, gct[lsd->background].red,
  414. X                    gct[lsd->background].green, gct[lsd->background].blue);
  415. X        }
  416. X        else
  417. X        {
  418. X            fprintf(outstr, "   bg index %d (%03d/%03d/%03d)\n",
  419. X                    lsd->background, gct[lsd->background].red,
  420. X                    gct[lsd->background].green, gct[lsd->background].blue);
  421. X        }
  422. X
  423. X        if ((chandle = col_open()) != 0)
  424. X        {
  425. X            fprintf(outerr, "ERROR: Cannot open color hash table.\n");
  426. X            fb_close(infile);
  427. X            return EXIT_ERROR;
  428. X        }
  429. X        for (loop = 0; loop < globcolors; loop++)
  430. X        {
  431. X            if (col_enter(chandle, &(gct[loop])) != 0)
  432. X            {
  433. X                fprintf(outerr, "ERROR: Error entering in color hash table.\n");
  434. X                col_close(chandle, (HASHIT **) NULL);
  435. X                fb_close(infile);
  436. X                return EXIT_ERROR;
  437. X            }
  438. X        }
  439. X        if (col_getstat(chandle, &uniques, &entries) != 0)
  440. X        {
  441. X            fprintf(outerr, "ERROR: Error retrieving from color hash table.\n");
  442. X            col_close(chandle, (HASHIT **) NULL);
  443. X            fb_close(infile);
  444. X            return EXIT_ERROR;
  445. X        }
  446. X        fprintf(outstr, "   %ld unique colors.\n", uniques);
  447. X        if (col_close(chandle, (HASHIT **) NULL) != 0)
  448. X        {
  449. X            fprintf(outerr, "ERROR: Error closing color hash table.\n");
  450. X            fb_close(infile);
  451. X            return EXIT_ERROR;
  452. X        }
  453. X
  454. X        if (do_colordump)
  455. X        {
  456. X            colordump(gct, globcolors);
  457. X        }
  458. X    }
  459. X    else
  460. X    {
  461. X        fprintf(outstr,
  462. X                "   No global color table, table size field has value %d.\n",
  463. X                lsd->gct_size);
  464. X    }
  465. X
  466. X    /* Return OK. */
  467. X
  468. X    return EXIT_OK;
  469. X} /* end of global_printout() */
  470. X
  471. X
  472. X/***************************************************************************
  473. X*   FUNCTION: IMAGE_PRINTOUT                                               *
  474. X*                                                                          *
  475. X*   DESCRIPTION:                                                           *
  476. X*                                                                          *
  477. X*       Prints out info from Image Descriptor, local color table (if any), *
  478. X*       and decompresses image.                                            *
  479. X*                                                                          *
  480. X*   ENTRY:                                                                 *
  481. X*                                                                          *
  482. X*       infile   - handle of file                                          *
  483. X*       imd      - Image Descriptor data from file                         *
  484. X*       version  - GIF format version                                      *
  485. X*       gct_size - size of global color table                              *
  486. X*                                                                          *
  487. X*   EXIT:                                                                  *
  488. X*                                                                          *
  489. X*       Returns an errorlevel code.                                        *
  490. X*                                                                          *
  491. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  492. X*                                                                          *
  493. X***************************************************************************/
  494. Xint 
  495. X#ifdef __STDC__
  496. Ximage_printout(FB *infile, GIF_IMD *imd, int images, ULONG version,
  497. X               int gct_size)
  498. X#else
  499. Ximage_printout(infile, imd, images, version, gct_size)
  500. XFB *infile;
  501. XGIF_IMD *imd;
  502. Xint images;
  503. XULONG version;
  504. Xint gct_size;
  505. X#endif
  506. X{
  507. X    ULONG status;
  508. X    int colors;
  509. X    int loop;
  510. X    ULONG blockbytes;
  511. X    unsigned int blocks;
  512. X    long uniques, entries;
  513. X    int chandle;
  514. X    codeinfo *table;
  515. X    UCHAR *holding_space;
  516. X    int clockseq = 0;
  517. X    long cratio;
  518. X    int compon = 1;
  519. X    unsigned int endblock;
  520. X
  521. X    RGB_TRIPLET *ctable = (RGB_TRIPLET *) NULL;
  522. X    UCHAR codesize;
  523. X    UCHAR *data;
  524. X    int datalen;
  525. X
  526. X    /* Print some info from image descriptor. */
  527. X
  528. X    if (verbose != 0)
  529. X    {
  530. X        fprintf(outstr, "   image size (pixels, width x height): %5u x %5u\n",
  531. X                imd->im_wid, imd->im_hi);
  532. X        fprintf(outstr, "   image upper left corner (column, row): %5u, %5u\n",
  533. X                imd->im_left, imd->im_top);
  534. X        fprintf(outstr, "   image is stored %s\n",
  535. X                ((0 == imd->interlace_flag) ? "sequentially" : "interlaced"));
  536. X    }
  537. X    else
  538. X    {
  539. X        fprintf(outstr, "   size %5u x %5u   corner %5u, %5u   %s\n",
  540. X                imd->im_wid, imd->im_hi, imd->im_left, imd->im_top,
  541. X                ((0 == imd->interlace_flag) ? "sequentially" : "interlaced"));
  542. X    }
  543. X
  544. X    if ((imd->raw_packed & 0x18) != 0)
  545. X    {
  546. X        if (dlevel >= DLEVEL_NITPICK)
  547. X        {
  548. X            fprintf(outstr, "\nNITPICK: bits 3 and 4, byte 9 of image descriptor should be 0\n");
  549. X        }
  550. X    }
  551. X
  552. X    if (((imd->im_left + imd->im_wid) > logwid) ||
  553. X        ((imd->im_top + imd->im_hi) > loghi))
  554. X    {
  555. X        if (dlevel >= DLEVEL_VIOLATION)
  556. X        {
  557. X            fprintf(outstr, 
  558. X                    "\nVIOLATION: image does not fit on logical screen.\n");
  559. X        }
  560. X        if (elevel >= ELEVEL_VIOLATION)
  561. X        {
  562. X            fb_close(infile);
  563. X            return EXIT_NOTGIF;
  564. X        }
  565. X    }
  566. X
  567. X    if (imd->lct_flag)
  568. X    {
  569. X        fprintf(outstr, "   This image has a local color table.\n");
  570. X    }
  571. X    else
  572. X    {
  573. X        fprintf(outstr, "   This image uses the global color table (no local color table).\n");
  574. X        if (((RGB_TRIPLET *) NULL) == gct)
  575. X        {
  576. X            if (dlevel >= DLEVEL_FASCINATING)
  577. X            {
  578. X                fprintf(outstr, "\nFASCINATING: this file does not contain a global color table\n");
  579. X            }
  580. X            if (elevel >= ELEVEL_FASCINATING)
  581. X            {
  582. X                fb_close(infile);
  583. X                return EXIT_NOTGIF;
  584. X            }
  585. X        }
  586. X    }
  587. X
  588. X    /* Read local color table, if any. */
  589. X
  590. X    if (imd->lct_flag)
  591. X    {
  592. X        fprintf(outstr, "   LOCAL COLOR TABLE FOR IMAGE %d:\n", images);
  593. X        colors = 0x1 << imd->lct_size;
  594. X        if (verbose != 0)
  595. X        {
  596. X            fprintf(outstr, "   %d bits per index for a table size of %d\n",
  597. X                    imd->lct_size, colors);
  598. X        }
  599. X        else
  600. X        {
  601. X            fprintf(outstr, "   %d bits (%d colors)", imd->lct_size, colors);
  602. X        }
  603. X        if (imd->sort_flag)
  604. X        {
  605. X            if (GIF_89A == version)
  606. X            {
  607. X                if (verbose != 0)
  608. X                {
  609. X                    fprintf(outstr, "   The local color table is sorted by decreasing importance.\n");
  610. X                }
  611. X                else
  612. X                {
  613. X                    fprintf(outstr, "   sorted\n");
  614. X                }
  615. X            }
  616. X            else
  617. X            {
  618. X                if (dlevel >= DLEVEL_NITPICK)
  619. X                {
  620. X                    fprintf(outstr, "\nNITPICK: bit 5, byte 9 of image descriptor should be 0 for GIF87A\n");
  621. X                }
  622. X            }
  623. X        }
  624. X        else if (GIF_89A == version)
  625. X        {
  626. X            if (verbose != 0)
  627. X            {
  628. X                fprintf(outstr, "   The local color table is not sorted.\n");
  629. X            }
  630. X            else
  631. X            {
  632. X                fprintf(outstr, "   unsorted\n");
  633. X            }
  634. X        }
  635. X
  636. X        if ((status = gif_lctget(infile, &ctable, colors)) != ST_SUCCESS)
  637. X        {
  638. X            fprintf(outerr, "%s\n", errxlate(status));
  639. X            fb_close(infile);
  640. X            return ((GIF_UNEOF_E == status) ? EXIT_UNEOF : EXIT_ERROR);
  641. X        }
  642. X
  643. X        if ((chandle = col_open()) != 0)
  644. X        {
  645. X            fprintf(outerr, "ERROR: Cannot open color hash table.\n");
  646. X            if (imd->lct_flag)
  647. X            {
  648. X                free(ctable);
  649. X            }
  650. X            fb_close(infile);
  651. X            return EXIT_ERROR;
  652. X        }
  653. X        for (loop = 0; loop < colors; loop++)
  654. X        {
  655. X            if (col_enter(chandle, &(ctable[loop])) != 0)
  656. X            {
  657. X                fprintf(outerr, "ERROR: Error entering in color hash table.\n");
  658. X                col_close(chandle, (HASHIT **) NULL);
  659. X                fb_close(infile);
  660. X                if (imd->lct_flag)
  661. X                {
  662. X                    free(ctable);
  663. X                }
  664. X                return EXIT_ERROR;
  665. X            }
  666. X        }
  667. X        if (col_getstat(chandle, &uniques, &entries) != 0)
  668. X        {
  669. X            fprintf(outerr, "ERROR: Error retrieving from color hash table.\n");
  670. X            col_close(chandle, (HASHIT **) NULL);
  671. X            fb_close(infile);
  672. X            if (imd->lct_flag)
  673. X            {
  674. X                free(ctable);
  675. X            }
  676. X            return EXIT_ERROR;
  677. X        }
  678. X        fprintf(outstr, "   %ld unique colors.\n", uniques);
  679. X        if (col_close(chandle, (HASHIT **) NULL) != 0)
  680. X        {
  681. X            fprintf(outerr, "ERROR: Error closing color hash table.\n");
  682. X            fb_close(infile);
  683. X            if (imd->lct_flag)
  684. X            {
  685. X                free(ctable);
  686. X            }
  687. X            return EXIT_ERROR;
  688. X        }
  689. X
  690. X        if (do_colordump)
  691. X        {
  692. X            colordump(ctable, colors);
  693. X        }
  694. X    }
  695. X    else
  696. X    {
  697. X        if ((imd->lct_size != 0) && (dlevel >= DLEVEL_NITPICK))
  698. X        {
  699. X            fprintf(outstr, "\nNITPICK: local color table size is nonzero.\n");
  700. X        }
  701. X    }
  702. X
  703. X    /* Check for transparency. */
  704. X
  705. X    if (transparent != -1)
  706. X    {
  707. X        if (transparent > ((imd->lct_flag != 0) ? colors : globcolors))
  708. X        {
  709. X            if (dlevel >= DLEVEL_VIOLATION)
  710. X            {
  711. X                fprintf(outstr, "\nVIOLATION: bad transparency index (%d)\n",
  712. X                        transparent);
  713. X            }
  714. X            if (elevel >= ELEVEL_VIOLATION)
  715. X            {
  716. X                fb_close(infile);
  717. X                if (imd->lct_flag)
  718. X                {
  719. X                    free(ctable);
  720. X                }
  721. X                return EXIT_NOTGIF;
  722. X            }
  723. X        }
  724. X    }
  725. X    transparent = -1;
  726. X
  727. X    /* Read codesize. */
  728. X
  729. X    codesize = (UCHAR) fb_getc(infile);
  730. X    if (fb_error != ST_SUCCESS)
  731. X    {
  732. X        fprintf(outerr, "%s\n", errxlate(status));
  733. X        fb_close(infile);
  734. X        if (imd->lct_flag)
  735. X        {
  736. X            free(ctable);
  737. X        }
  738. X        return ((FB_EOF_W == status) ? EXIT_UNEOF : EXIT_ERROR);
  739. X    }
  740. X    fprintf(outstr, "   IMAGE DATA FOR IMAGE %d:\n", images);
  741. X    fprintf(outstr, "   code size %d bits\n", (int) codesize);
  742. X
  743. X    /* Initialize decompressor. */
  744. X
  745. X    if (decomp != 0)
  746. X    {
  747. X        table = (codeinfo *) calloc(CODES, sizeof(codeinfo));
  748. X        if (((codeinfo *) NULL) == table)
  749. X        {
  750. X            fprintf(outerr,
  751. X                    "ERROR: Cannot allocate memory for decompressor table.\n");
  752. X            fb_close(infile);
  753. X            if (imd->lct_flag)
  754. X            {
  755. X                free(ctable);
  756. X            }
  757. X            return EXIT_ERROR;
  758. X        }
  759. X        holding_space = (UCHAR *) malloc(EXTRA_TABLESIZE);
  760. X        if (((UCHAR *) NULL) == holding_space)
  761. X        {
  762. X            fprintf(outerr,
  763. X                    "ERROR: Cannot allocate memory for decompressor table.\n");
  764. X            fb_close(infile);
  765. X            if (imd->lct_flag)
  766. X            {
  767. X                free(ctable);
  768. X            }
  769. X            return EXIT_ERROR;
  770. X        }
  771. X        status = gld_init(codesize, (imd->lct_flag ? imd->lct_size : gct_size),
  772. X                          table, holding_space, EXTRA_TABLESIZE);
  773. X        if (status != ST_SUCCESS)
  774. X        {
  775. X            fprintf(outerr, "%s\n", errxlate(status));
  776. X            fb_close(infile);
  777. X            if (imd->lct_flag)
  778. X            {
  779. X                free(ctable);
  780. X            }
  781. X            return EXIT_ERROR;
  782. X        }
  783. X    }
  784. X
  785. X    /* Read data blocks until done. */
  786. X
  787. X    blockbytes = 0;
  788. X    blocks = 0;
  789. X#ifdef PROGRESS_IND
  790. X    if (prog_ind != 0)
  791. X    {
  792. X        fputc(clockface[(clockseq % 4)], outstr);
  793. X        clockseq++;
  794. X    }
  795. X#endif
  796. X    while (1)
  797. X    {
  798. X        /* Read block. */
  799. X
  800. X        if ((status = gif_readblock(infile, &data, &datalen)) != ST_SUCCESS)
  801. X        {
  802. X#ifdef PROGRESS_IND
  803. X            if (prog_ind != 0)
  804. X            {
  805. X                fputc('\10', outstr);
  806. X            }
  807. X#endif
  808. X            fprintf(outerr, "%s\n", errxlate(status));
  809. X            fprintf(outstr, "\n   %ld good codes found yielding %lu pixels ",
  810. X                    gld_codes, gld_pixout);
  811. X            fprintf(outstr, " (%lu", (gld_pixout / imd->im_wid));
  812. X            if ((gld_pixout % imd->im_wid) != 0)
  813. X            {
  814. X                fputc('+', outstr);
  815. X            }
  816. X            fprintf(outstr, " lines, %lu%% of image)\n",
  817. X                    ((100L * gld_pixout) / ((ULONG) imd->im_wid *
  818. X                                            (ULONG) imd->im_hi)));
  819. X            fb_close(infile);
  820. X            if (imd->lct_flag)
  821. X            {
  822. X                free(ctable);
  823. X            }
  824. X            if (decomp != 0)
  825. X            {
  826. X                free(table);
  827. X                free(holding_space);
  828. X            }
  829. X            return ((GIF_UNEOF_E == status) ? EXIT_UNEOF : EXIT_ERROR);
  830. X        }
  831. X
  832. X        /* Check length. */
  833. X
  834. X        if (0 == datalen)
  835. X        {
  836. X            /* If zero length, at end. */
  837. X
  838. X            if (0 == compon)
  839. X            {
  840. X                /* Compression already turned off -- reached end of codes. */
  841. X
  842. X                break;
  843. X            }
  844. X            if (0 == decomp)
  845. X            {
  846. X                /*
  847. X                ** Not doing decompression -- all OK. Set endblock so don't
  848. X                ** get message about extra blocks
  849. X                */
  850. X
  851. X                endblock = blocks - 1;
  852. X                break;
  853. X            }
  854. X            fprintf(outerr,
  855. X                    "\nANOMALY: end of data reached before end of codes\n");
  856. X            fprintf(outstr, "   %ld good codes found yielding %lu pixels ",
  857. X                    gld_codes, gld_pixout);
  858. X            fprintf(outstr, " (%lu", (gld_pixout / imd->im_wid));
  859. X            if ((gld_pixout % imd->im_wid) != 0)
  860. X            {
  861. X                fputc('+', outstr);
  862. X            }
  863. X            fprintf(outstr, " lines, %lu%% of image)\n",
  864. X                    ((100L * gld_pixout) / ((ULONG) imd->im_wid *
  865. X                                            (ULONG) imd->im_hi)));
  866. X            /* Set endblock so don't get message about extra blocks. */
  867. X            endblock = blocks - 1;
  868. X            break;
  869. X        }
  870. X
  871. X        /* Do decompression. */
  872. X
  873. X        if ((decomp != 0) && (compon != 0))
  874. X        {
  875. X            status = gld_process(datalen, data, NULL, 0, callback);
  876. X            if ((status != ST_SUCCESS) && (status != GLD_EOI_S))
  877. X            {
  878. X#ifdef PROGRESS_IND
  879. X                if (prog_ind != 0)
  880. X                {
  881. X                    fputc('\10', outstr);
  882. X                }
  883. X#endif
  884. X                fprintf(outerr,
  885. X                  "\nANOMALY: decompression error in block %u at offset %ld\n",
  886. X                  blocks, (fb_tell(infile) - datalen));
  887. X                fprintf(outstr, "   %ld good codes found yielding %lu pixels ",
  888. X                        gld_codes, gld_pixout);
  889. X                fprintf(outstr, " (%lu", (gld_pixout / imd->im_wid));
  890. X                if ((gld_pixout % imd->im_wid) != 0)
  891. X                {
  892. X                    fputc('+', outstr);
  893. X                }
  894. X                fprintf(outstr, " lines, %lu%% of image)\n",
  895. X                        ((100L * gld_pixout) / ((ULONG) imd->im_wid *
  896. X                                                (ULONG) imd->im_hi)));
  897. X                fb_close(infile);
  898. X                if (decomp != 0)
  899. X                {
  900. X                    free(table);
  901. X                    free(holding_space);
  902. X                }
  903. X                if (imd->lct_flag)
  904. X                {
  905. X                    free(ctable);
  906. X                }
  907. X                return EXIT_ERROR;
  908. X            }
  909. X            if (GLD_EOI_S == status)
  910. X            {
  911. X#ifdef PROGRESS_IND
  912. X                if (prog_ind != 0)
  913. X                {
  914. X                    fputc('\10', outstr);
  915. X                }
  916. X#endif
  917. X                fprintf(outstr, "   Reached end of codes in block %u\n",
  918. X                        blocks);
  919. X                endblock = blocks;
  920. X                compon = 0;
  921. X            }
  922. X        }
  923. X#ifdef PROGRESS_IND
  924. X        if (prog_ind != 0)
  925. X        {
  926. X            fputc('\10', outstr);
  927. X            fputc(clockface[(clockseq++ % 4)], outstr);
  928. X        }
  929. X#endif
  930. X        blockbytes += (ULONG) datalen;
  931. X        blocks++;
  932. X
  933. X        /* Free data block. */
  934. X
  935. X        free(data);
  936. X    }
  937. X
  938. X    /* Check for extra blocks. */
  939. X
  940. X    if ((blocks - 1) != endblock)
  941. X    {
  942. X        if (dlevel >= DLEVEL_FASCINATING)
  943. X        {
  944. X            fprintf(outstr,
  945. X                    "\n   FASCINATING: %u extra blocks on end of image\n",
  946. X                    ((blocks - 1) - endblock));
  947. X        }
  948. X        if (elevel >= ELEVEL_FASCINATING)
  949. X        {
  950. X            fb_close(infile);
  951. X            if (imd->lct_flag)
  952. X            {
  953. X                free(ctable);
  954. X            }
  955. X            return EXIT_NOTGIF;
  956. X        }
  957. X    }
  958. X
  959. X    /* If doing decompression, clean up. */
  960. X
  961. X    if (decomp != 0)
  962. X    {
  963. X        free(table);
  964. X        free(holding_space);
  965. X    }
  966. X
  967. X    /* Print more info. */
  968. X
  969. X    fprintf(outstr, "   totals: ");
  970. X    if (decomp != 0)
  971. X    {
  972. X        fprintf(outstr, "%ld codes packed into ", gld_codes);
  973. X    }
  974. X    fprintf(outstr, "%lu bytes in %u blocks\n", blockbytes, blocks);
  975. X    if (decomp != 0)
  976. X    {
  977. X        fprintf(outstr, "        %lu pixels extracted\n", gld_pixout);
  978. X        if (gld_pixout < ((ULONG) imd->im_wid * (ULONG) imd->im_hi))
  979. X        {
  980. X            if (dlevel >= DLEVEL_FASCINATING)
  981. X            {
  982. X                fprintf(outstr, "\nFASCINATING: too few pixels extracted ");
  983. X                fprintf(outstr, "(%lu", (gld_pixout / imd->im_wid));
  984. X                if ((gld_pixout % imd->im_wid) != 0)
  985. X                {
  986. X                    fputc('+', outstr);
  987. X                }
  988. X                fprintf(outstr, " lines found, %lu pixels missing)\n",
  989. X                        (((ULONG) imd->im_wid *
  990. X                          (ULONG) imd->im_hi) - gld_pixout));
  991. X            }
  992. X            if (elevel >= ELEVEL_FASCINATING)
  993. X            {
  994. X                fb_close(infile);
  995. X                if (imd->lct_flag)
  996. X                {
  997. X                    free(ctable);
  998. X                }
  999. X                return EXIT_NOTGIF;
  1000. X            }
  1001. X        }
  1002. X        else if (gld_pixout > ((ULONG) imd->im_wid * (ULONG) imd->im_hi))
  1003. X        {
  1004. X            if (dlevel >= DLEVEL_FASCINATING)
  1005. X            {
  1006. X                fprintf(outstr, "\nFASCINATING: too many pixels extracted ");
  1007. X                fprintf(outstr, " (%lu extra)\n",
  1008. X                        (gld_pixout - ((ULONG) imd->im_wid *
  1009. X                                       (ULONG) imd->im_hi)));
  1010. X            }
  1011. X            if (elevel >= ELEVEL_FASCINATING)
  1012. X            {
  1013. X                fb_close(infile);
  1014. X                if (imd->lct_flag)
  1015. X                {
  1016. X                    free(ctable);
  1017. X                }
  1018. X                return EXIT_NOTGIF;
  1019. X            }
  1020. X        }
  1021. X    }
  1022. X    if (gld_clears >= 1)
  1023. X    {
  1024. X        fprintf(outstr, "        code table cleared %d times\n", gld_clears);
  1025. X    }
  1026. X    else if (decomp != 0)
  1027. X    {
  1028. END_OF_FILE
  1029.   if test 29781 -ne `wc -c <'src/blocproc.c.A'`; then
  1030.     echo shar: \"'src/blocproc.c.A'\" unpacked with wrong size!
  1031.   elif test -f 'src/blocproc.c.B'; then
  1032.     echo shar: Combining  \"'src/blocproc.c'\" \(64047 characters\)
  1033.     cat 'src/blocproc.c.A' 'src/blocproc.c.B' > 'src/blocproc.c'
  1034.     if test 64047 -ne `wc -c <'src/blocproc.c'`; then
  1035.       echo shar: \"'src/blocproc.c'\" combined with wrong size!
  1036.     else  
  1037.       rm src/blocproc.c.A src/blocproc.c.B 
  1038.     fi  
  1039.   fi  
  1040.   # end of 'src/blocproc.c.A'
  1041. fi
  1042. if test -f 'src/gifstrip.1' -a "${1}" != "-c" ; then 
  1043.   echo shar: Will not clobber existing file \"'src/gifstrip.1'\"
  1044. else
  1045.   echo shar: Extracting \"'src/gifstrip.1'\" \(10723 characters\)
  1046.   sed "s/^X//" >'src/gifstrip.1' <<'END_OF_FILE'
  1047. X.\"
  1048. X.\" $Id: gifstrip.1,v 1.3 1993/03/02 00:44:17 jwbirdsa Exp $
  1049. X.\"
  1050. X.TH GIFSTRIP 1 "$Date: 1993/03/02 00:44:17 $"
  1051. X.PD 1
  1052. X.SH NAME
  1053. Xgifstrip \- GIF file rebuilder
  1054. X.SH SYNOPSIS
  1055. X.B gifstrip
  1056. X[
  1057. X.B \-b
  1058. X][
  1059. X.B \-r
  1060. X][
  1061. X.B \-\-
  1062. X][
  1063. X.B \-f
  1064. X][
  1065. X.B \-n
  1066. X][
  1067. X.B \-m
  1068. X][
  1069. X.B \-o
  1070. X][
  1071. X.B \-h
  1072. X][
  1073. X.B \-c
  1074. X][
  1075. X.B \-d
  1076. X][
  1077. X.B \-s
  1078. X][
  1079. X.B \-tpath
  1080. X] target [ target... ]
  1081. X.br
  1082. X.SH DESCRIPTION
  1083. X.I Gifstrip
  1084. Xis used to remove excess characters from the beginning and/or end of a GIF
  1085. Xfile (usually the end). These excess characters may be added in a variety
  1086. Xof ways, including XMODEM-protocol file transfers or transfer from a
  1087. XMacintosh computer.
  1088. X.I Gifstrip
  1089. Xalso does some basic file analysis and enforces a few format requirements
  1090. Xwhich are sometimes ignored. For temporary storage, it can use memory or
  1091. Xdisk. By default, it uses memory first and only uses disk space to make up
  1092. Xthe shortfall if there is not enough memory. By default,
  1093. X.I gifstrip
  1094. Xalso keeps the original file around until the new file has been written to
  1095. Xdisk successfully, and attempts to preserve the timestamp, owner, and
  1096. Xpermissions of the original file.
  1097. X.SH TARGETS
  1098. XA target is a filename or directory. Multiple targets may be specified on
  1099. Xthe command line. If a target is a directory, all files in that directory
  1100. Xwill be processed. If no targets are specified on the command line, a usage
  1101. Xmessage will be printed.
  1102. X.SH OPTIONS
  1103. XOptions may not be combined. In the case of the
  1104. X.B \-t
  1105. Xoption, there cannot be a space between the option and the argument to the
  1106. Xoption.
  1107. X.TP
  1108. X.B \-b
  1109. XOperate in batch mode. All output is suppressed. This option should be
  1110. Xfirst on the command line or other options may generate output before this
  1111. Xoption is found. When in batch mode,
  1112. X.I gifstrip
  1113. Xadjusts its status return to reflect the results of processing. The status
  1114. Xmay be:
  1115. X.RS 10
  1116. X.PP
  1117. X.nf
  1118. X0     the file is GIF format and did not need
  1119. X       stripping, or was stripped OK
  1120. X1     file is not GIF format
  1121. X2     an unexpected EOF was encountered
  1122. X       (usually indicates a corrupt file)
  1123. X3     any other error 
  1124. X.fi
  1125. X.RE
  1126. X.RS 5
  1127. X.PP
  1128. XNote that the status reflects the result of only the last file processed.
  1129. XTherefore, in batch mode only one file should be specified on the command
  1130. Xline.
  1131. X.RE
  1132. X.TP
  1133. X.B \-\-
  1134. XRead targets from stdin. The list of targets must have only one target per
  1135. Xline. Targets which are directories will be expanded as usual, but
  1136. Xwildcards will not be expanded. Targets on the command line will be ignored.
  1137. XFor use with the
  1138. X.B \-f
  1139. Xoption of
  1140. X.I
  1141. Xchils.
  1142. X.TP
  1143. X.B \-r
  1144. XRedirects error messages to stderr.
  1145. X.TP
  1146. X.B \-f
  1147. XForces
  1148. X.I gifstrip
  1149. Xto rebuild the file. Normally, files are rebuilt only when extra characters
  1150. Xare found or if the file does not meet strict format requirements (see the
  1151. X.B \-n
  1152. Xoption below).
  1153. X.TP
  1154. X.B \-m
  1155. XEnables the stripping of files which have excess characters at the
  1156. Xbeginning. Ordinarily, such files are not recognized as GIF format files.
  1157. XWith this option,
  1158. X.I gifstrip
  1159. Xsearches through the file looking for the GIF format signature, and starts
  1160. Xrebuilding the file when it finds it. Files without excess characters at
  1161. Xthe beginning will be processed normally.
  1162. X.TP
  1163. X.B \-n
  1164. XDisables strict format checking. Normally, the following violations are
  1165. Xchecked for, and the file rebuilt if any are found:
  1166. X.RS 10
  1167. X.PP
  1168. X.nf
  1169. X(GIF87a only)    Global or local color table sorted
  1170. X                  flag set
  1171. X(GIF87a only)    Aspect ratio value nonzero
  1172. X(GIF87a, GIF89a) Local color table size given but local
  1173. X                  color table flag not set (no local
  1174. X                  color table)
  1175. X(GIF89a only)    Local color table sorted flag set but
  1176. X                  local color table flag not set (no
  1177. X                  local color table)
  1178. X.fi
  1179. X.RE
  1180. X.RS 5
  1181. X.PP
  1182. XIf the
  1183. X.B \-n
  1184. Xoption is used, these violations are ignored. If the file is rebuilt due to
  1185. Xexcess characters, any violations will be propagated into the rebuilt
  1186. Xfile.
  1187. X.RE
  1188. X.TP
  1189. X.B \-o
  1190. XErases the original file before writing the rebuilt file. By default,
  1191. X.I gifstrip
  1192. Xretains the original file until the rebuilt file has been completely
  1193. Xwritten to disk. Thus, in case of error, either the original file or the
  1194. Xrebuilt file will exist on disk no matter when
  1195. X.I gifstrip
  1196. Xis aborted, providing a measure of security. However, sometimes it is
  1197. Xnecessary to process a file which is on a nearly-full drive, with
  1198. Xinsufficient room for a second copy of the file. This option allows for
  1199. Xthat case.
  1200. X.TP
  1201. X.B \-h
  1202. XPrints a usage message. No files are processed and all other options are
  1203. Xignored.
  1204. X.TP
  1205. X.B \-c
  1206. XDisables use of memory for temporary storage. Cannot be combined with the
  1207. X.B \-d
  1208. Xoption.
  1209. X.TP
  1210. X.B \-d
  1211. XDisables use of disk for temporary storage. Cannot be combined with the
  1212. X.B \-c
  1213. Xoption.
  1214. X.TP
  1215. X.B \-s
  1216. XEquivalent to
  1217. X.B \-c.
  1218. X.TP
  1219. X.B \-tpath
  1220. XSpecifies a path for the disk temporary file. There must not be space
  1221. Xbetween the "-t" and the path.
  1222. X.SH OUTPUT
  1223. X.I Gifstrip
  1224. Xproduces at least two lines of output for each file. In some cases, it may
  1225. Xproduce several pages of output.
  1226. X.PP
  1227. XFor each file specified,
  1228. X.I gifstrip
  1229. Xoutputs the line "Processing 
  1230. X.IR filename ...
  1231. X". If the file is not a GIF format file,
  1232. X.I gifstrip
  1233. Xthen outputs the message "ERROR: File is not a GIF format file." and
  1234. Xproceeds to the next file.
  1235. X.RS 3
  1236. X.SS "FILE HEADER LINE"
  1237. X.nf
  1238. XGIF87A  G--   21463    250 x   200 @ 128   junk/vla.gif
  1239. XGIF89A  G-A   34256    320 x   200 @ 256   junk/glass.gif
  1240. X.fi
  1241. X.PP
  1242. XThe columns from left to right are:
  1243. X.RS 3
  1244. X.PD 0
  1245. X.HP
  1246. X\(bu  the format identifier (GIF87A or GIF89A)
  1247. X.HP
  1248. X\(bu  G file has a global color table
  1249. X.HP
  1250. X   - file does not have a global color table
  1251. X.HP
  1252. X\(bu  S global color table is sorted
  1253. X.HP
  1254. X   - global color table is not sorted
  1255. X.HP
  1256. X\(bu  A aspect ratio is specified
  1257. X.HP
  1258. X   - no aspect ratio
  1259. X.HP
  1260. X\(bu  the file size
  1261. X.HP
  1262. X\(bu  the width in pixels of the logical screen
  1263. X.HP
  1264. X\(bu  the height in pixels of the logical screen
  1265. X.HP
  1266. X\(bu  the number of colors in the global color table (--- if no global
  1267. Xcolor table)
  1268. X.HP
  1269. X\(bu  the filename
  1270. X.PD 1
  1271. X.RE
  1272. X.PP
  1273. XIf
  1274. X.I gifstrip
  1275. Xencounters in the file header one of the format violations listed under the
  1276. X.B \-n
  1277. Xoption, and the
  1278. X.B \-n
  1279. Xoption is not in effect, it will print a message describing the violation
  1280. Xafter the file header line. This message will start with "FYI:".
  1281. X.SS "IMAGE LINE"
  1282. X.nf
  1283. XG-S  (  0,  0)    250 x   200 @ 128   20970BY    83BL
  1284. X.fi
  1285. X.PP
  1286. XThe columns from left to right are:
  1287. X.RS 3
  1288. X.PD 0
  1289. X.HP
  1290. X\(bu  G image uses global color table
  1291. X.HP
  1292. X   L image uses local color table
  1293. X.HP
  1294. X\(bu  S local color table is sorted
  1295. X.HP
  1296. X   - local color table is not sorted
  1297. X.HP
  1298. X\(bu  S image is stored sequentially
  1299. X.HP
  1300. X   I image is stored interlaced
  1301. X.HP
  1302. X\(bu  offset of upper left corner of the image on the logical screen,
  1303. X(horizontal,vertical)
  1304. X.HP
  1305. X\(bu  the width in pixels of the image
  1306. X.HP
  1307. X\(bu  the height in pixels of the image
  1308. X.HP
  1309. X\(bu  the number of colors in either the global or local color table,
  1310. Xwhichever the image uses
  1311. X.HP
  1312. X\(bu  the number of data bytes in the image
  1313. X.HP
  1314. X\(bu  the number of blocks into which the data bytes are broken up
  1315. X.PD 1
  1316. X.RE
  1317. X.PP
  1318. XIf
  1319. X.I gifstrip
  1320. Xencounters in an image one of the format violations listed under the
  1321. X.B \-n
  1322. Xoption, and the
  1323. X.B \-n
  1324. Xoption is not in effect, it will print a mesasge describing the violation
  1325. XBEFORE it prints the image line for that image. This message will start
  1326. Xwith "FYI:".
  1327. X.SS "EXTENSION BLOCK LINE"
  1328. XWhen an extension block is encountered,
  1329. X.I gifstrip
  1330. Xwill print one of several lines. If the format is GIF87a, or the extension
  1331. Xblock is not one of the four dedicated types defined in GIF89a,
  1332. X.I gifstrip
  1333. Xprints:
  1334. X.PP
  1335. X.RS 3
  1336. XType
  1337. X.I xxx
  1338. XExtension Block
  1339. X.RE
  1340. X.PP
  1341. Xwhere xxx is the type number given in the extension block header. If it is
  1342. Xone of the four dedicated types defined in GIF89a,
  1343. X.I gifstrip
  1344. Xprints:
  1345. X.PP
  1346. X.nf
  1347. X   Plain Text Extension Block
  1348. X   Graphic Control Extension Block
  1349. X   Comment Extension Block
  1350. X   Application Extension Block
  1351. X.fi
  1352. X.PP
  1353. Xas appropriate.
  1354. X.PP
  1355. XAfter identifying the extenion type,
  1356. X.I gifstrip
  1357. Xprints the number of data bytes and data blocks in the extension block, on
  1358. Xthe same line, in the same format as for an image.
  1359. X.SS "TERMINATOR LINE"
  1360. XIf the file is not corrupt,
  1361. X.I gifstrip
  1362. Xwill eventually come to the GIF format terminator character. When it
  1363. Xencounters this, it prints:
  1364. X.PP
  1365. X.nf
  1366. X   GIF Terminator
  1367. X.fi
  1368. X.PP
  1369. Xand ceases processing the original file. It then determines whether the
  1370. Xfile needs to be rebuilt or not.
  1371. X.SS "NO REBUILD"
  1372. XIf the file does not have excess characters on either the beginning or the
  1373. Xend, and either does not have any format violations or the
  1374. X.B \-n
  1375. Xoption is in effect, and the
  1376. X.B \-f
  1377. Xoption is not in effect, the file will not be rebuilt.
  1378. X.I Gifstrip
  1379. Xprints:
  1380. X.PP
  1381. X.nf
  1382. X   No work to be done. File unchanged.
  1383. X.fi
  1384. X.PP
  1385. Xand proceeds to the next file.
  1386. X.SS REBUILD
  1387. XIf the file does need to be rebuilt,
  1388. X.I gifstrip
  1389. Xprints:
  1390. X.PP
  1391. X.nf
  1392. X    New size:    xxx   Bytes removed:    yyy
  1393. XRecopying... done.
  1394. X.fi
  1395. X.PP
  1396. Xwhere xxx is the size in bytes of the rebuilt file, and yyy is the
  1397. Xdifference between the size of the original file and the size of the
  1398. Xrebuilt file. The next line ("Recopying...") is simply to indicate that
  1399. X.I gifstrip
  1400. Xis doing something. When
  1401. X.I gifstrip
  1402. Xprints "done." it is finished writing the rebuilt file and proceeds to the
  1403. Xnext file. The timestamp, owner, and permissions of the original file are
  1404. Xpreserved as well as possible in the rebuilt file.
  1405. X.SS "OTHER LINES"
  1406. X.I Gifstrip
  1407. Xmay issue error messages at any time. These will begin with "WARNING:",
  1408. X"ERROR:", or "FATAL ERROR:".
  1409. X.PP
  1410. XThere are two other messages that
  1411. X.I gifstrip
  1412. Xmay issue:
  1413. X.PP
  1414. XIf
  1415. X.I gifstrip
  1416. Xis used with the
  1417. X.B \-m
  1418. Xoption and encounters excess characters at the beginning of a file, it
  1419. Xprints an "FYI:" message stating that leading junk bytes have been skipped
  1420. Xover and gives the number of bytes skipped. This message appears before the
  1421. Xfile header line.
  1422. X.PP
  1423. XIf
  1424. X.I gifstrip
  1425. Xencounters extraneous characters between sections, it will issue an "FYI:"
  1426. Xmessage describing the violation and giving the number of extraneous
  1427. Xcharacters. This message appears between the lines describing the sections
  1428. Xon either side of the extraneous characters. This is an FYI message
  1429. Xbecause, technically,
  1430. X.I gifstrip
  1431. Xcan fix the problem. However, extraneous characters between sections are
  1432. Xforbidden by the format specification. If present, they indicate a serious
  1433. Xproblem in the encoder which produced the image, or, more likely, a corrupt
  1434. XGIF file.
  1435. X.RE
  1436. X.SH COPYRIGHT
  1437. X.I Gifstrip
  1438. Xis copyright 1993 by James W. Birdsall, all rights reserved.
  1439. X.PP
  1440. XThe Graphics Interchange Format(c) is the Copyright property of CompuServe
  1441. XIncorporated. GIF(sm) is a Service Mark property of CompuServe
  1442. XIncorporated.
  1443. X.SH AUTHOR
  1444. XJames W. Birdsall
  1445. X.RS 3
  1446. X.nf
  1447. Xsupport@picarefy.com
  1448. Xuunet!uw-coco!amc-gw!picarefy!support
  1449. XCompuServe: 71261,1731
  1450. XGEnie: J.BIRDSALL2
  1451. X.fi
  1452. X.RE
  1453. X.SH "SEE ALSO"
  1454. Xchils(1),
  1455. Xgifcheck(1)
  1456. END_OF_FILE
  1457.   if test 10723 -ne `wc -c <'src/gifstrip.1'`; then
  1458.     echo shar: \"'src/gifstrip.1'\" unpacked with wrong size!
  1459.   fi
  1460.   # end of 'src/gifstrip.1'
  1461. fi
  1462. if test -f 'src/pcx.c' -a "${1}" != "-c" ; then 
  1463.   echo shar: Will not clobber existing file \"'src/pcx.c'\"
  1464. else
  1465.   echo shar: Extracting \"'src/pcx.c'\" \(12105 characters\)
  1466.   sed "s/^X//" >'src/pcx.c' <<'END_OF_FILE'
  1467. X/***************************************************************************
  1468. X*   PCX.C                                                                  *
  1469. X*   MODULE:  PCX                                                           *
  1470. X*   OS:      UNIX                                                          *
  1471. X*                                                                          *
  1472. X*   Copyright (c) 1993 James W. Birdsall. All Rights Reserved.             *
  1473. X*                                                                          *
  1474. X*   $Id: pcx.c,v 1.1 1993/03/02 00:57:05 jwbirdsa Exp $
  1475. X*                                                                          *
  1476. X*   This file contains functions to process PCX format files.              *
  1477. X*   Functions:                                                             *
  1478. X*      pcx_verify    - checks filename to see if it is an PCX file         *
  1479. X*      pcx_getheader - extracts header data from PCX file                  *
  1480. X*                                                                          *
  1481. X*      pcx_errstring - converts error code into message                    *
  1482. X*                                                                          *
  1483. X***************************************************************************/
  1484. X
  1485. X#include "config.h"
  1486. X
  1487. X/*
  1488. X** system includes <>
  1489. X*/
  1490. X
  1491. X#include <stdio.h>
  1492. X#ifndef NO_STR_INC
  1493. X#ifdef STRING_PLURAL
  1494. X#include <strings.h>
  1495. X#else
  1496. X#include <string.h>
  1497. X#endif
  1498. X#endif
  1499. X
  1500. X
  1501. X/*
  1502. X** custom includes ""
  1503. X*/
  1504. X
  1505. X#include "depend.h"
  1506. X#include "formats.h"
  1507. X#include "pcx.h"
  1508. X
  1509. X
  1510. X/*
  1511. X** local #defines
  1512. X*/
  1513. X
  1514. X/*
  1515. X** misc: copyright strings, version macros, etc.
  1516. X*/
  1517. X
  1518. X/*
  1519. X** typedefs
  1520. X*/
  1521. X
  1522. X/*
  1523. X** global variables
  1524. X*/
  1525. X
  1526. X/*
  1527. X** static globals
  1528. X*/
  1529. X
  1530. Xstatic char CONST rcsid[] = "$Id: pcx.c,v 1.1 1993/03/02 00:57:05 jwbirdsa Exp $";
  1531. X
  1532. X
  1533. X/*
  1534. X** function prototypes
  1535. X*/
  1536. X
  1537. X#ifdef NO_STR_INC
  1538. Xextern char *strrchr();
  1539. Xextern int strcmp();
  1540. X#endif
  1541. X
  1542. X
  1543. X/*
  1544. X** functions
  1545. X*/
  1546. X
  1547. X
  1548. X/***************************************************************************
  1549. X*   FUNCTION:    pcx_verify                                                *
  1550. X*                                                                          *
  1551. X*   DESCRIPTION:                                                           *
  1552. X*                                                                          *
  1553. X*       Verifies that a file is an PCX file by checking filename against   *
  1554. X*       list of extensions. Reads PCX version number from start of file.   *
  1555. X*                                                                          *
  1556. X*   ENTRY:                                                                 *
  1557. X*                                                                          *
  1558. X*       filename - name of file to be verified                             *
  1559. X*       version  - pointer to unsigned long in which format/version value  *
  1560. X*                  is returned                                             *
  1561. X*       exts     - array of string pointers, list of extensions for PCX    *
  1562. X*                  files                                                   *
  1563. X*                                                                          *
  1564. X*   EXIT:                                                                  *
  1565. X*                                                                          *
  1566. X*       Returns an error/status code.                                      *
  1567. X*                                                                          *
  1568. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  1569. X*                                                                          *
  1570. X***************************************************************************/
  1571. XULONG
  1572. X#ifdef __STDC__
  1573. Xpcx_verify(char *filename, ULONG *version, char **exts)
  1574. X#else
  1575. Xpcx_verify(filename, version, exts)
  1576. Xchar *filename;
  1577. XULONG *version;
  1578. Xchar **exts;
  1579. X#endif
  1580. X{
  1581. X    char *extptr;
  1582. X    int loop;
  1583. X    FILE *pcxfile;
  1584. X    int magic;
  1585. X    ULONG retval;
  1586. X
  1587. X    /* Search for '.' marking extension. */
  1588. X
  1589. X    extptr = strrchr(filename, '.');
  1590. X    if (NULL == extptr)
  1591. X    {
  1592. X        /* No extension, cannot classify. */
  1593. X
  1594. X        *version = PCX_NOT;
  1595. X        return 0;
  1596. X    }
  1597. X    extptr++;
  1598. X
  1599. X    /* Now we have the extension, check against list. */
  1600. X
  1601. X    for (loop = 0; exts[loop] != NULL; loop++)
  1602. X    {
  1603. X        /* Case-sensitive string compare. */
  1604. X
  1605. X        if (strcmp(extptr, exts[loop]) == 0)
  1606. X        {
  1607. X            /* Match, so break out of loop. */
  1608. X
  1609. X            break;
  1610. X        }
  1611. X    }
  1612. X
  1613. X    /* Check exit from loop. */
  1614. X
  1615. X    if (NULL == exts[loop])
  1616. X    {
  1617. X        /* No match, return. */
  1618. X
  1619. X        *version = PCX_NOT;
  1620. X        return 0;
  1621. X    }
  1622. X
  1623. X    /* Extension is valid for type PCX, so process accordingly. */
  1624. X
  1625. X    if ((pcxfile = fopen(filename, FOPEN_READ_BINARY)) == (FILE *) NULL)
  1626. X    {
  1627. X        return PCX_FILEERR_E;
  1628. X    }
  1629. X
  1630. X    /* Read magic number. */
  1631. X
  1632. X    if ((magic = fgetc(pcxfile)) == EOF)
  1633. X    {
  1634. X        *version = PCX_NOT;
  1635. X        retval = (feof(pcxfile) ? ST_SUCCESS : PCX_FILEERR_E);
  1636. X        fclose(pcxfile);
  1637. X        return retval;
  1638. X    }
  1639. X    if (PCX_MAGIC != magic)
  1640. X    {
  1641. X        *version = PCX_NOT;
  1642. X        fclose(pcxfile);
  1643. X        return ST_SUCCESS;
  1644. X    }
  1645. X
  1646. X    /* Read version number, which immediately follows. */
  1647. X
  1648. X    if ((magic = fgetc(pcxfile)) == EOF)
  1649. X    {
  1650. X        *version = PCX_NOT;
  1651. X        retval = (feof(pcxfile) ? ST_SUCCESS : PCX_FILEERR_E);
  1652. X        fclose(pcxfile);
  1653. X        return retval;
  1654. X    }
  1655. X
  1656. X    /* Close file. */
  1657. X
  1658. X    if (fclose(pcxfile))
  1659. X    {
  1660. X        return PCX_FILEERR_E;
  1661. X    }
  1662. X
  1663. X    /* Set version according to magic. */
  1664. X
  1665. X    switch (magic)
  1666. X    {
  1667. X        case PCX_VER25_MAGIC:
  1668. X            *version = PCX_VER25;
  1669. X            break;
  1670. X
  1671. X        case PCX_VER28_MAGIC:
  1672. X            *version = PCX_VER28;
  1673. X            break;
  1674. X
  1675. X        case PCX_VER28P_MAGIC:
  1676. X            *version = PCX_VER28P;
  1677. X            break;
  1678. X
  1679. X        case PCX_VER30_MAGIC:
  1680. X            *version = PCX_VER30;
  1681. X            break;
  1682. X
  1683. X        default:
  1684. X            *version = PCX_NOT;
  1685. X            break;
  1686. X    }
  1687. X
  1688. X    /* Return OK. */
  1689. X
  1690. X    return ST_SUCCESS;
  1691. X} /* end of pcx_verify() */
  1692. X
  1693. X
  1694. X/***************************************************************************
  1695. X*   FUNCTION:    pcx_getheader                                             *
  1696. X*                                                                          *
  1697. X*   DESCRIPTION:                                                           *
  1698. X*                                                                          *
  1699. X*       Assumes that file is an PCX file. Reads header from file, extracts *
  1700. X*       data into PCX_HDR structure.                                       *
  1701. X*                                                                          *
  1702. X*   ENTRY:                                                                 *
  1703. X*                                                                          *
  1704. X*       infile  - file to be processed                                     *
  1705. X*       results - pointer to PCX_HDR structure in which data from header   *
  1706. X*                 is returned                                              *
  1707. X*                                                                          *
  1708. X*   EXIT:                                                                  *
  1709. X*                                                                          *
  1710. X*       Returns an error/status code.                                      *
  1711. X*                                                                          *
  1712. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  1713. X*                                                                          *
  1714. X*       Leaves file pointing to beginning of image data.                   *
  1715. X*                                                                          *
  1716. X***************************************************************************/
  1717. XULONG
  1718. X#ifdef __STDC__
  1719. Xpcx_getheader(FILE *infile, PCX_HDR *results)
  1720. X#else
  1721. Xpcx_getheader(infile, results)
  1722. XFILE *infile;
  1723. XPCX_HDR *results;
  1724. X#endif
  1725. X{
  1726. X    UCHAR rawhdr[PCX_HDR_LEN];
  1727. X
  1728. X    /* Make sure we're at beginning of file. */
  1729. X
  1730. X    if (fseek(infile, 0L, SEEK_SET))
  1731. X    {
  1732. X        return PCX_FILEERR_E;
  1733. X    }
  1734. X
  1735. X    /* Read raw bytes into buffer. */
  1736. X
  1737. X    if (fread(rawhdr, 1, PCX_HDR_LEN, infile) != PCX_HDR_LEN)
  1738. X    {
  1739. X        return (feof(infile) ? PCX_UNEOF_E : PCX_FILEERR_E);
  1740. X    }
  1741. X
  1742. X    /* Extract info from raw header. */
  1743. X
  1744. X    if (PCX_MAGIC != *(rawhdr + PCX_HDR_MAGIC_OFF))
  1745. X    {
  1746. X        return PCX_NOTPCX_E;
  1747. X    }
  1748. X    switch (*(rawhdr + PCX_HDR_VERS_OFF))
  1749. X    {
  1750. X        case PCX_VER25_MAGIC:
  1751. X            results->version = PCX_VER25;
  1752. X            break;
  1753. X
  1754. X        case PCX_VER28_MAGIC:
  1755. X            results->version = PCX_VER28;
  1756. X            break;
  1757. X
  1758. X        case PCX_VER28P_MAGIC:
  1759. X            results->version = PCX_VER28P;
  1760. X            break;
  1761. X
  1762. X        case PCX_VER30_MAGIC:
  1763. X            results->version = PCX_VER30;
  1764. X            break;
  1765. X
  1766. X        default:
  1767. X            return PCX_NOTPCX_E;
  1768. X            break;
  1769. X    }
  1770. X    results->planes = (unsigned int)(*(rawhdr + PCX_HDR_PLANES_OFF));
  1771. X    results->pixbits = (unsigned int)(*(rawhdr + PCX_HDR_BITS_OFF));
  1772. X    results->imwid = CONSTRUCT_I_UINT(rawhdr + PCX_HDR_XMAX_OFF);
  1773. X    results->imhi = CONSTRUCT_I_UINT(rawhdr + PCX_HDR_YMAX_OFF);
  1774. X    results->imleft = CONSTRUCT_I_UINT(rawhdr + PCX_HDR_XMIN_OFF);
  1775. X    results->imtop = CONSTRUCT_I_UINT(rawhdr + PCX_HDR_YMIN_OFF);
  1776. X    results->imwid -= (results->imleft - 1);
  1777. X    results->imhi -= (results->imtop - 1);
  1778. X    results->encoding = (unsigned int)(*(rawhdr + PCX_HDR_ENC_OFF));
  1779. X    results->hres = CONSTRUCT_I_UINT(rawhdr + PCX_HDR_HRES_OFF);
  1780. X    results->vres = CONSTRUCT_I_UINT(rawhdr + PCX_HDR_VRES_OFF);
  1781. X    results->palfmt = CONSTRUCT_I_UINT(rawhdr + PCX_HDR_PFMT_OFF);
  1782. X
  1783. X    /* Set file to point to start of data. */
  1784. X
  1785. X    if (fseek(infile, (long)(PCX_HDR_MAXLEN), SEEK_SET))
  1786. X    {
  1787. X        return PCX_FILEERR_E;
  1788. X    }
  1789. X
  1790. X    /* Return OK. */
  1791. X
  1792. X    return 0;
  1793. X} /* end of pcx_getheader() */
  1794. X
  1795. X
  1796. X/***************************************************************************
  1797. X*   FUNCTION: pcx_errstring                                                *
  1798. X*                                                                          *
  1799. X*   DESCRIPTION:                                                           *
  1800. X*                                                                          *
  1801. X*      Returns a string corresponding to an error code.                    *
  1802. X*                                                                          *
  1803. X*   ENTRY:                                                                 *
  1804. X*                                                                          *
  1805. X*      errcode - error code to be translated                               *
  1806. X*                                                                          *
  1807. X*   EXIT:                                                                  *
  1808. X*                                                                          *
  1809. X*      Returns a pointer to the appropriate string, or NULL if there is    *
  1810. X*      no appropriate string.                                              *
  1811. X*                                                                          *
  1812. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  1813. X*                                                                          *
  1814. X***************************************************************************/
  1815. Xchar *
  1816. X#ifdef __STDC__
  1817. Xpcx_errstring(ULONG errcode)
  1818. X#else
  1819. Xpcx_errstring(errcode)
  1820. XULONG errcode;
  1821. X#endif
  1822. X{
  1823. X    char *temp;
  1824. X
  1825. X    /* If error code not from this module, return NULL. */
  1826. X
  1827. X    if ((errcode & ST_MOD_MASK) != PCX_MODULE)
  1828. X    {
  1829. X        return NULL;
  1830. X    }
  1831. X
  1832. X    /* Process by code. */
  1833. X
  1834. X    switch (ERRSEV(errcode))
  1835. X    {
  1836. X        case ERRSEV(PCX_NOTPCX_E):
  1837. X            temp = "File is not a PCX format file.";
  1838. X            break;
  1839. X        case ERRSEV(PCX_FILEERR_E):
  1840. X            temp = "Error accessing file.";
  1841. X            break;
  1842. X        case ERRSEV(PCX_UNEOF_E):
  1843. X            temp = "Unexpected End of File";
  1844. X            break;
  1845. X
  1846. X        default:
  1847. X            temp = NULL;
  1848. X            break;
  1849. X    }
  1850. X
  1851. X    return temp;
  1852. X} /* end of pcx_errstring() */
  1853. X
  1854. END_OF_FILE
  1855.   if test 12105 -ne `wc -c <'src/pcx.c'`; then
  1856.     echo shar: \"'src/pcx.c'\" unpacked with wrong size!
  1857.   fi
  1858.   # end of 'src/pcx.c'
  1859. fi
  1860. echo shar: End of archive 13 \(of 18\).
  1861. cp /dev/null ark13isdone
  1862. MISSING=""
  1863. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
  1864.     if test ! -f ark${I}isdone ; then
  1865.     MISSING="${MISSING} ${I}"
  1866.     fi
  1867. done
  1868. if test "${MISSING}" = "" ; then
  1869.     echo You have unpacked all 18 archives.
  1870.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1871. else
  1872.     echo You still must unpack the following archives:
  1873.     echo "        " ${MISSING}
  1874. fi
  1875. exit 0
  1876. exit 0 # Just in case...
  1877.