home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume36 / chiaro / part09 < prev    next >
Encoding:
Text File  |  1993-03-24  |  55.9 KB  |  1,676 lines

  1. Newsgroups: comp.sources.misc
  2. From: jwbirdsa@picarefy.picarefy.com (James W. Birdsall)
  3. Subject: v36i079:  chiaro - Image Utilities, Part09/18
  4. Message-ID: <1993Mar25.181210.20498@sparky.imd.sterling.com>
  5. X-Md4-Signature: 7cafa7059c40e27e147fb8c1957f3bef
  6. Date: Thu, 25 Mar 1993 18:12:10 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 79
  11. Archive-name: chiaro/part09
  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/Shorten src/gif.c.B src/jfif.c
  19. # Wrapped by kent@sparky on Thu Mar 25 11:20:04 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 9 (of 18)."'
  23. if test -f 'src/Shorten' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'src/Shorten'\"
  25. else
  26.   echo shar: Extracting \"'src/Shorten'\" \(706 characters\)
  27.   sed "s/^X//" >'src/Shorten' <<'END_OF_FILE'
  28. X#
  29. X# Makefile for shortening long #define'd names.
  30. X#
  31. X
  32. Xall:    startup final
  33. X
  34. X
  35. Xstartup:
  36. X    chmod u+w *.c *.h
  37. X
  38. X
  39. Xfoo:
  40. X    grep "^#[     ]*[Dd][Ee][Ff][Ii][Nn][Ee]" *.h *.c | \
  41. X    sed -e 's/#[     ][     ]*define/#define/g' | \
  42. X    awk '{print $$2}' | sed -e 's/(.*)//g' | awk 'length > 8' | \
  43. X    sort -r | uniq > foo
  44. X
  45. Xfoo2:    foo shorten.awk
  46. X    awk -f shorten.awk foo > foo2
  47. X    split -50 foo2 foo2.
  48. X
  49. Xfinal:    foo2
  50. X    for i in *.h; do \
  51. X        echo "Processing $$i..."; \
  52. X        for j in foo2.*; do \
  53. X            echo "  with $$j..."; \
  54. X            sed -f $$j < $$i > foo3; \
  55. X            mv foo3 $$i; \
  56. X        done \
  57. X    done
  58. X    for i in *.c; do \
  59. X        echo "Processing $$i..."; \
  60. X        for j in foo2.*; do \
  61. X            echo "  with $$j..."; \
  62. X            sed -f $$j < $$i > foo3; \
  63. X            mv foo3 $$i; \
  64. X        done \
  65. X    done
  66. END_OF_FILE
  67.   if test 706 -ne `wc -c <'src/Shorten'`; then
  68.     echo shar: \"'src/Shorten'\" unpacked with wrong size!
  69.   fi
  70.   # end of 'src/Shorten'
  71. fi
  72. if test -f 'src/gif.c.B' -a "${1}" != "-c" ; then 
  73.   echo shar: Will not clobber existing file \"'src/gif.c.B'\"
  74. else
  75.   echo shar: Extracting \"'src/gif.c.B'\" \(34397 characters\)
  76.   sed "s/^X//" >'src/gif.c.B' <<'END_OF_FILE'
  77. X
  78. X/***************************************************************************
  79. X*   FUNCTION: gif_skipsection                                              *
  80. X*                                                                          *
  81. X*   DESCRIPTION:                                                           *
  82. X*                                                                          *
  83. X*      Reads data blocks until it reaches a zero-length block.             *
  84. X*                                                                          *
  85. X*   ENTRY:                                                                 *
  86. X*                                                                          *
  87. X*      infile - FB handle of file                                          *
  88. X*                                                                          *
  89. X*   EXIT:                                                                  *
  90. X*                                                                          *
  91. X*      Returns an error/status code.                                       *
  92. X*                                                                          *
  93. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  94. X*                                                                          *
  95. X*      Assumes the file is positioned correctly. Repositions the file      *
  96. X*      pointer; leaves the file pointer pointing to the byte after the     *
  97. X*      zero-length block.                                                  *
  98. X*                                                                          *
  99. X***************************************************************************/
  100. XULONG
  101. X#ifdef __STDC__
  102. Xgif_skipsection(FB *infile)
  103. X#else
  104. Xgif_skipsection(infile)
  105. XFB *infile;
  106. X#endif
  107. X{
  108. X#ifndef NO_FB
  109. X    int length;
  110. X    UCHAR *data;
  111. X    ULONG status;
  112. X
  113. X    /* Read first block, return on error. */
  114. X
  115. X    if ((status = gif_readblock(infile, &data, &length)) != 0)
  116. X    {
  117. X        return status;
  118. X    }
  119. X    if (data != (UCHAR *) NULL)
  120. X    {
  121. X        free(data);
  122. X    }
  123. X
  124. X    /* Loop until hit zero length. */
  125. X
  126. X    while (length != 0)
  127. X    {
  128. X        /* Read block, return on error. */
  129. X
  130. X        if ((status = gif_readblock(infile, &data, &length)) != 0)
  131. X        {
  132. X            return status;
  133. X        }
  134. X        if (data != (UCHAR *) NULL)
  135. X        {
  136. X            free(data);
  137. X        }
  138. X    }
  139. X
  140. X    /* Return OK. */
  141. X    return 0;
  142. X
  143. X#else
  144. X
  145. X    return GIF_UNSUPRT_F;
  146. X
  147. X#endif /* NO_FB */
  148. X} /* end of gif_skipsection() */
  149. X
  150. X
  151. X/***************************************************************************
  152. X*   FUNCTION: gif_grafctrlext                                              *
  153. X*                                                                          *
  154. X*   DESCRIPTION:                                                           *
  155. X*                                                                          *
  156. X*      Reads and parses a GIF89a graphic control extension block, and      *
  157. X*      returns the results.                                                *
  158. X*                                                                          *
  159. X*   ENTRY:                                                                 *
  160. X*                                                                          *
  161. X*      infile - FB handle of file                                          *
  162. X*      gce    - pointer to GIF_GCE structure in which to return results    *
  163. X*                                                                          *
  164. X*   EXIT:                                                                  *
  165. X*                                                                          *
  166. X*      Returns an error/status code.                                       *
  167. X*                                                                          *
  168. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  169. X*                                                                          *
  170. X*      Assumes the file is positioned correctly. Leaves file pointer       *
  171. X*      pointing to byte after graphic control extension section.           *
  172. X*                                                                          *
  173. X***************************************************************************/
  174. XULONG
  175. X#ifdef __STDC__
  176. Xgif_grafctrlext(FB *infile, GIF_GCE *gce)
  177. X#else
  178. Xgif_grafctrlext(infile, gce)
  179. XFB *infile;
  180. XGIF_GCE *gce;
  181. X#endif
  182. X{
  183. X#ifndef NO_FB
  184. X    int length;
  185. X    UCHAR *rawgce;
  186. X    ULONG status;
  187. X
  188. X    /* Read data block, return on error. */
  189. X
  190. X    if ((status = gif_readblock(infile, &rawgce, &length)) != 0)
  191. X    {
  192. X        return status;
  193. X    }
  194. X
  195. X    /* Check length. */
  196. X
  197. X    if (length != GIF_GCE_LEN)
  198. X    {
  199. X        free(rawgce);
  200. X        return GIF_BADSECTION_E;
  201. X    }
  202. X
  203. X    /* Parse. */
  204. X
  205. X    gce->delay = CONSTRUCT_I_UINT(rawgce + GIF_GCE_DELAY_OFF);
  206. X    gce->transparent = (((int) *(rawgce + GIF_GCE_TRANSPARENT_OFF)) & 0x00FF);
  207. X
  208. X    /* Break out packed fields. */
  209. X
  210. X    gce->raw_packed = *(rawgce + GIF_GCE_PACKED_OFF);
  211. X    gce->disposal = ((((int) gce->raw_packed) &
  212. X                      GIF_GCE_DISPOSAL_MASK) >> GIF_GCE_DISPOSAL_SHIFT);
  213. X    gce->userinflag = ((gce->raw_packed & GIF_GCE_USERINFLAG_MASK) ? 1 : 0);
  214. X    gce->transflag = ((gce->raw_packed & GIF_GCE_TRANSFLAG_MASK) ? 1 : 0);
  215. X
  216. X    /* Clean up. */
  217. X
  218. X    free(rawgce);
  219. X
  220. X    /* Check next block -- should be zero-length. */
  221. X
  222. X    if ((status = gif_readblock(infile, &rawgce, &length)) != 0)
  223. X    {
  224. X        return status;
  225. X    }
  226. X    if (length != 0)
  227. X    {
  228. X        free(rawgce);
  229. X        return GIF_BADSECTION_E;
  230. X    }
  231. X
  232. X    /* Return OK. */
  233. X
  234. X    return 0;
  235. X
  236. X#else
  237. X
  238. X    return GIF_UNSUPRT_F;
  239. X
  240. X#endif /* NO_FB */
  241. X} /* end of gif_grafctrlext() */
  242. X
  243. X
  244. X/***************************************************************************
  245. X*   FUNCTION: gif_commentext                                               *
  246. X*                                                                          *
  247. X*   DESCRIPTION:                                                           *
  248. X*                                                                          *
  249. X*      Reads and parses a GIF89a comment extension block and returns the   *
  250. X*      results.                                                            *
  251. X*                                                                          *
  252. X*   ENTRY:                                                                 *
  253. X*                                                                          *
  254. X*      infile - FB handle of file                                          *
  255. X*      text   - pointer to pointer in which pointer to buffer containing   *
  256. X*               comment text is returned.                                  *
  257. X*      textln - pointer to unsigned int in which text buffer length is     *
  258. X*               returned                                                   *
  259. X*                                                                          *
  260. X*   EXIT:                                                                  *
  261. X*                                                                          *
  262. X*      Returns an error/status code.                                       *
  263. X*                                                                          *
  264. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  265. X*                                                                          *
  266. X*      Assumes the file is positioned correctly. Leaves file pointer       *
  267. X*      pointing to byte after comment extension section.                   *
  268. X*                                                                          *
  269. X*      The text buffer returned must be free()'ed.                         *
  270. X*                                                                          *
  271. X***************************************************************************/
  272. XULONG
  273. X#ifdef __STDC__
  274. Xgif_commentext(FB *infile, char **text, unsigned int *textln)
  275. X#else
  276. Xgif_commentext(infile, text, textln)
  277. XFB *infile;
  278. Xchar **text;
  279. Xunsigned int *textln;
  280. X#endif
  281. X{
  282. X#ifndef NO_FB
  283. X
  284. X    /* Read text block. */
  285. X    return (gif_gbytes(infile, text, textln));
  286. X
  287. X#else
  288. X
  289. X    return GIF_UNSUPRT_F;
  290. X
  291. X#endif /* NO_FB */
  292. X} /* end of gif_commentext() */
  293. X
  294. X
  295. X/***************************************************************************
  296. X*   FUNCTION: gif_plaintextext                                             *
  297. X*                                                                          *
  298. X*   DESCRIPTION:                                                           *
  299. X*                                                                          *
  300. X*      Reads and parses a GIF89a plain text extension block and returns    *
  301. X*      the results.                                                        *
  302. X*                                                                          *
  303. X*   ENTRY:                                                                 *
  304. X*                                                                          *
  305. X*      infile - FB handle of file                                          *
  306. X*      pte    - pointer to GIF_PTE structure in which to return results    *
  307. X*                                                                          *
  308. X*   EXIT:                                                                  *
  309. X*                                                                          *
  310. X*      Returns an error/status code.                                       *
  311. X*                                                                          *
  312. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  313. X*                                                                          *
  314. X*      Assumes the file is positioned correctly. Leaves file pointer       *
  315. X*      pointing to byte after comment extension section.                   *
  316. X*                                                                          *
  317. X*      The text buffer returned within the GIF_PTE must be free()'ed.      *
  318. X*                                                                          *
  319. X***************************************************************************/
  320. XULONG
  321. X#ifdef __STDC__
  322. Xgif_plaintextext(FB *infile, GIF_PTE *pte)
  323. X#else
  324. Xgif_plaintextext(infile, pte)
  325. XFB *infile;
  326. XGIF_PTE *pte;
  327. X#endif
  328. X{
  329. X#ifndef NO_FB
  330. X    int length;
  331. X    UCHAR *rawptehead;
  332. X    ULONG status;
  333. X
  334. X    /* Read data block, return on error. */
  335. X
  336. X    if ((status = gif_readblock(infile, &rawptehead, &length)) != 0)
  337. X    {
  338. X        return status;
  339. X    }
  340. X
  341. X    /* Check length. */
  342. X
  343. X    if (length != GIF_PTEHEAD_LEN)
  344. X    {
  345. X        free(rawptehead);
  346. X        return GIF_BADSECTION_E;
  347. X    }
  348. X
  349. X    /* Parse. */
  350. X
  351. X    pte->left = CONSTRUCT_I_UINT(rawptehead + GIF_PTEHEAD_LEFT_OFF);
  352. X    pte->top = CONSTRUCT_I_UINT(rawptehead + GIF_PTEHEAD_TOP_OFF);
  353. X    pte->wid = CONSTRUCT_I_UINT(rawptehead + GIF_PTEHEAD_WID_OFF);
  354. X    pte->hi = CONSTRUCT_I_UINT(rawptehead + GIF_PTEHEAD_HI_OFF);
  355. X    pte->cellwid = (unsigned int) *(rawptehead + GIF_PTEHEAD_CELLWID_OFF);
  356. X    pte->cellhi = (unsigned int) *(rawptehead + GIF_PTEHEAD_CELLHI_OFF);
  357. X    pte->forecolor = (((int) *(rawptehead + GIF_PTEHEAD_FORECLR_OFF)) & 0x00FF);
  358. X    pte->backcolor = (((int) *(rawptehead + GIF_PTEHEAD_BACKCLR_OFF)) & 0x00FF);
  359. X
  360. X    /* Clean up. */
  361. X
  362. X    free(rawptehead);
  363. X
  364. X    /* Read text block and return. */
  365. X
  366. X    return (gif_gbytes(infile, &(pte->text), &(pte->textln)));
  367. X
  368. X#else
  369. X
  370. X    return GIF_UNSUPRT_F;
  371. X
  372. X#endif /* NO_FB */
  373. X} /* end of gif_plaintextext() */
  374. X
  375. X
  376. X/***************************************************************************
  377. X*   FUNCTION: gif_applext                                                  *
  378. X*                                                                          *
  379. X*   DESCRIPTION:                                                           *
  380. X*                                                                          *
  381. X*      Reads and parses a GIF89a application extension block and returns   *
  382. X*      the results.                                                        *
  383. X*                                                                          *
  384. X*   ENTRY:                                                                 *
  385. X*                                                                          *
  386. X*      infile - FB handle of file                                          *
  387. X*      appl   - pointer to GIF_APPL structure in which to return results   *
  388. X*                                                                          *
  389. X*   EXIT:                                                                  *
  390. X*                                                                          *
  391. X*      Returns an error/status code.                                       *
  392. X*                                                                          *
  393. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  394. X*                                                                          *
  395. X*      Assumes the file is positioned correctly. Leaves file pointer       *
  396. X*      pointing to byte after the application extension section.           *
  397. X*                                                                          *
  398. X*      The data buffer returned within the GIF_APPL must be free()'ed.     *
  399. X*                                                                          *
  400. X***************************************************************************/
  401. XULONG
  402. X#ifdef __STDC__
  403. Xgif_applext(FB *infile, GIF_APPL *appl)
  404. X#else
  405. Xgif_applext(infile, appl)
  406. XFB *infile;
  407. XGIF_APPL *appl;
  408. X#endif
  409. X{
  410. X#ifndef NO_FB
  411. X    int length;
  412. X    UCHAR *rawapplhead;
  413. X    ULONG status;
  414. X
  415. X    /* Read data block, return on error. */
  416. X
  417. X    if ((status = gif_readblock(infile, &rawapplhead, &length)) != 0)
  418. X    {
  419. X        return status;
  420. X    }
  421. X
  422. X    /* Check length. */
  423. X
  424. X    if (length != GIF_APPL_LEN)
  425. X    {
  426. X        free(rawapplhead);
  427. X        return GIF_BADSECTION_E;
  428. X    }
  429. X
  430. X    /* Parse. */
  431. X    memcpy(appl->appl_id, (rawapplhead + GIF_APPL_APPLID_OFF),
  432. X           GIF_APPL_APPLID_LEN);
  433. X    memcpy(appl->appl_auth, (rawapplhead + GIF_APPL_AUTH_OFF),
  434. X           GIF_APPL_AUTH_LEN);
  435. X
  436. X    /* Clean up. */
  437. X
  438. X    free(rawapplhead);
  439. X
  440. X    /* Read data block and return. */
  441. X
  442. X    return (gif_gbytes(infile, (char **) &(appl->appldata),
  443. X                       &(appl->appldatlen)));
  444. X
  445. X#else
  446. X
  447. X    return GIF_UNSUPRT_F;
  448. X
  449. X#endif /* NO_FB */
  450. X} /* end of gif_applext() */
  451. X
  452. X
  453. X/***************************************************************************
  454. X*   FUNCTION: gif_readblock                                                *
  455. X*                                                                          *
  456. X*   DESCRIPTION:                                                           *
  457. X*                                                                          *
  458. X*      Reads and returns a single data block.                              *
  459. X*                                                                          *
  460. X*   ENTRY:                                                                 *
  461. X*                                                                          *
  462. X*      infile - FB handle of file                                          *
  463. X*      data   - pointer to pointer in which pointer to buffer is returned  *
  464. X*      length - pointer to int in which length of data block is returned   *
  465. X*                                                                          *
  466. X*   EXIT:                                                                  *
  467. X*                                                                          *
  468. X*      Returns an error/status code.                                       *
  469. X*                                                                          *
  470. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  471. X*                                                                          *
  472. X*      Assumes the file is positioned correctly. Leaves file pointer       *
  473. X*      pointing to byte after block.                                       *
  474. X*                                                                          *
  475. X*      Memory block returned in data must be free()'ed.                    *
  476. X*                                                                          *
  477. X***************************************************************************/
  478. XULONG
  479. X#ifdef __STDC__
  480. Xgif_readblock(FB *infile, UCHAR **data, int *length)
  481. X#else
  482. Xgif_readblock(infile, data, length)
  483. XFB *infile;
  484. XUCHAR **data;
  485. Xint *length;
  486. X#endif
  487. X{
  488. X#ifndef NO_FB
  489. X
  490. X    /* Read length byte. */
  491. X
  492. X    if ((*length = fb_getc(infile)) == -1)
  493. X    {
  494. X        /* 
  495. X        ** If not end of file, just pass error code along. Otherwise,
  496. X        ** is unexpected EOF.
  497. X        */
  498. X
  499. X        return ((fb_error != FB_EOF_W) ? fb_error : GIF_UNEOF_E);
  500. X    }
  501. X
  502. X    /* If zero-length block, set *data to NULL and return OK. */
  503. X
  504. X    if (*length == 0)
  505. X    {
  506. X        *data = (UCHAR *) NULL;
  507. X        return 0L;
  508. X    }
  509. X
  510. X    /* Allocate memory for data. */
  511. X
  512. X    if ((*data = (UCHAR *) malloc(*length)) == (UCHAR *) NULL)
  513. X    {
  514. X        return GIF_NOMEM_E;
  515. X    }
  516. X
  517. X    /* Read data. */
  518. X
  519. X    if (fb_read(infile, *data, *length) != *length)
  520. X    {
  521. X        /* Clean up. */
  522. X
  523. X        free(*data);
  524. X
  525. X        /* 
  526. X        ** If not end of file, just pass error code along. Otherwise,
  527. X        ** is unexpected EOF.
  528. X        */
  529. X
  530. X        return ((fb_error != FB_EOF_W) ? fb_error : GIF_UNEOF_E);
  531. X    }
  532. X
  533. X    /* Return OK. */
  534. X
  535. X    return 0;
  536. X
  537. X#else
  538. X
  539. X    return GIF_UNSUPRT_F;
  540. X
  541. X#endif /* NO_FB */
  542. X} /* end of gif_readblock() */
  543. X
  544. X
  545. X/***************************************************************************
  546. X*   FUNCTION: gif_errstring                                                *
  547. X*                                                                          *
  548. X*   DESCRIPTION:                                                           *
  549. X*                                                                          *
  550. X*      Returns a string corresponding to an error code.                    *
  551. X*                                                                          *
  552. X*   ENTRY:                                                                 *
  553. X*                                                                          *
  554. X*      errcode - error code to be translated                               *
  555. X*                                                                          *
  556. X*   EXIT:                                                                  *
  557. X*                                                                          *
  558. X*      Returns a pointer to the appropriate string, or NULL if there is    *
  559. X*      no appropriate string.                                              *
  560. X*                                                                          *
  561. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  562. X*                                                                          *
  563. X***************************************************************************/
  564. Xchar *
  565. X#ifdef __STDC__
  566. Xgif_errstring(ULONG errcode)
  567. X#else
  568. Xgif_errstring(errcode)
  569. XULONG errcode;
  570. X#endif
  571. X{
  572. X    char *temp;
  573. X
  574. X    /* If error code not from this module, return NULL. */
  575. X
  576. X    if (MODULE(errcode) != MODULE(GIF_MODULE))
  577. X    {
  578. X        return NULL;
  579. X    }
  580. X
  581. X    /* Process by code. */
  582. X
  583. X    switch (ERRSEV(errcode))
  584. X    {
  585. X        case ERRSEV(GIF_NOFILE_E):
  586. X            temp = "Cannot find named file.";
  587. X            break;
  588. X        case ERRSEV(GIF_FILEERR_E):
  589. X            temp = "Error accessing file.";
  590. X            break;
  591. X        case ERRSEV(GIF_NOTGIF_E):
  592. X            temp = "File is not a GIF format file.";
  593. X            break;
  594. X        case ERRSEV(GIF_UNEOF_E):
  595. X            temp = "Unexpected End of File";
  596. X            break;
  597. X        case ERRSEV(GIF_NOMEM_E):
  598. X            temp = "Out of memory in GIF module.";
  599. X            break;
  600. X        case ERRSEV(GIF_BADSECTION_E):
  601. X            temp = "Section data does not match format.";
  602. X            break;
  603. X
  604. X        case ERRSEV(GIF_UNSUPRT_F):
  605. X            temp = "This function not supported without FB module.";
  606. X            break;
  607. X        case ERRSEV(GIF_BUG_F):
  608. X            temp = "Internal error, should never happen.";
  609. X            break;
  610. X
  611. X        default:
  612. X            temp = NULL;
  613. X            break;
  614. X    }
  615. X
  616. X    return temp;
  617. X} /* end of gif_errstring() */
  618. X
  619. X
  620. X/***************************************************************************
  621. X*   FUNCTION: gif_vget STATIC                                              *
  622. X*                                                                          *
  623. X*   DESCRIPTION:                                                           *
  624. X*                                                                          *
  625. X*      This function obtains and parses the GIF version signature and      *
  626. X*      returns which GIF version, if any, the file is.                     *
  627. X*                                                                          *
  628. X*   ENTRY:                                                                 *
  629. X*                                                                          *
  630. X*      infile  - handle of file                                            *
  631. X*      version - pointer to unsigned long in which to return version info  *
  632. X*                                                                          *
  633. X*   EXIT:                                                                  *
  634. X*                                                                          *
  635. X*      Returns an error/status code.                                       *
  636. X*                                                                          *
  637. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  638. X*                                                                          *
  639. X*      Leaves file pointer pointing to byte after version signature.       *
  640. X*      Assumes file is positioned correctly.                               *
  641. X*                                                                          *
  642. X***************************************************************************/
  643. Xstatic ULONG
  644. X#ifdef __STDC__
  645. Xgif_vget(FILE *infile, ULONG *version)
  646. X#else
  647. Xgif_vget(infile, version)
  648. XFILE *infile;
  649. XULONG *version;
  650. X#endif
  651. X{
  652. X    char sigspace[GIF_SIG_LEN_MAX];      /* buffer for reading signatures */
  653. X    int bytesread;                       /* chars read in */
  654. X    ULONG retval;
  655. X
  656. X    /* Read in format signature. */
  657. X
  658. X    bytesread = fread(sigspace, 1, GIF_SIGNATURE_LEN, infile);
  659. X    if (bytesread != GIF_SIGNATURE_LEN)
  660. X    {
  661. X        if (feof(infile))
  662. X        {
  663. X            /* 
  664. X            ** If file is shorter than GIF signature, obviously not
  665. X            ** a GIF file. And since we hit EOF, the short read was
  666. X            ** caused by that and not a real error.
  667. X            */
  668. X
  669. X            *version = GIF_NOT;
  670. X
  671. X            return ST_SUCCESS;
  672. X        }
  673. X
  674. X        /* Otherwise, was a real error. */
  675. X
  676. X        return GIF_FILEERR_E;
  677. X    }
  678. X
  679. X    /* Check format signature. */
  680. X
  681. X    if (strncmp(GIF_SIGNATURE, sigspace, GIF_SIGNATURE_LEN))
  682. X    {
  683. X        /* Signature not OK. */
  684. X
  685. X        *version = GIF_NOT;
  686. X
  687. X        return 0L;
  688. X    }
  689. X
  690. X    /* Format signature OK. Read in version signature. */
  691. X
  692. X    bytesread = fread(sigspace, 1, GIF_VERS_SIG_LEN, infile);
  693. X    if (bytesread != GIF_VERS_SIG_LEN)
  694. X    {
  695. X        return GIF_FILEERR_E;
  696. X    }
  697. X
  698. X    /* Check version signature. */
  699. X
  700. X    if (strncmp(GIF_VERS87A_SIG, sigspace, GIF_VERS_SIG_LEN) == 0)
  701. X    {
  702. X        /* Version 87a. */
  703. X
  704. X        *version = GIF_87A;
  705. X    }
  706. X    else if (strncmp(GIF_VERS89A_SIG, sigspace, GIF_VERS_SIG_LEN) == 0)
  707. X    {
  708. X        /* Version 89a. */
  709. X
  710. X        *version = GIF_89A;
  711. X    }
  712. X    else
  713. X    {
  714. X        /* Unknown version -- oops. */
  715. X
  716. X        *version = GIF_NOT;
  717. X    }
  718. X
  719. X    /* Return OK. */
  720. X
  721. X    return 0;
  722. X} /* end of static gif_vget() */
  723. X
  724. X
  725. X#ifndef NO_FB
  726. X
  727. X/***************************************************************************
  728. X*   FUNCTION: gif_fgetvers STATIC                                          *
  729. X*                                                                          *
  730. X*   DESCRIPTION:                                                           *
  731. X*                                                                          *
  732. X*      This function obtains and parses the GIF version signature and      *
  733. X*      returns which GIF version, if any, the file is.                     *
  734. X*                                                                          *
  735. X*   ENTRY:                                                                 *
  736. X*                                                                          *
  737. X*      infile  - FB handle of file                                         *
  738. X*      version - pointer to unsigned long in which to return version info  *
  739. X*                                                                          *
  740. X*   EXIT:                                                                  *
  741. X*                                                                          *
  742. X*      Returns an error/status code.                                       *
  743. X*                                                                          *
  744. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  745. X*                                                                          *
  746. X*      Leaves file pointer pointing to byte after version signature.       *
  747. X*      Assumes file is positioned correctly.                               *
  748. X*                                                                          *
  749. X***************************************************************************/
  750. Xstatic ULONG
  751. X#ifdef __STDC__
  752. Xgif_fgetvers(FB *infile, ULONG *version)
  753. X#else
  754. Xgif_fgetvers(infile, version)
  755. XFB *infile;
  756. XULONG *version;
  757. X#endif
  758. X{
  759. X    char sigspace[GIF_SIG_LEN_MAX];    /* buffer for signatures */
  760. X    int bytesread;                     /* number of chars read in */
  761. X
  762. X    /* Read in format signature. */
  763. X
  764. X    bytesread = fb_read(infile, (UCHAR *) sigspace, GIF_SIGNATURE_LEN);
  765. X    if (bytesread != GIF_SIGNATURE_LEN)
  766. X    {
  767. X        return fb_error;
  768. X    }
  769. X
  770. X    /* Check format signature. */
  771. X
  772. X    if (strncmp(GIF_SIGNATURE, sigspace, GIF_SIGNATURE_LEN))
  773. X    {
  774. X        /* Signature not OK. */
  775. X
  776. X        *version = GIF_NOT;
  777. X
  778. X        return 0;
  779. X    }
  780. X
  781. X    /* Format signature OK. Read in version signature. */
  782. X
  783. X    bytesread = fb_read(infile, (unsigned char *) sigspace, GIF_VERS_SIG_LEN);
  784. X    if (bytesread != GIF_VERS_SIG_LEN)
  785. X    {
  786. X        fb_close(infile);
  787. X        return GIF_FILEERR_E;
  788. X    }
  789. X
  790. X    /* Check version signature. */
  791. X
  792. X    if (strncmp(GIF_VERS87A_SIG, sigspace, GIF_VERS_SIG_LEN) == 0)
  793. X    {
  794. X        /* Version 87a. */
  795. X
  796. X        *version = GIF_87A;
  797. X    }
  798. X    else if (strncmp(GIF_VERS89A_SIG, sigspace, GIF_VERS_SIG_LEN) == 0)
  799. X    {
  800. X        /* Version 89a. */
  801. X
  802. X        *version = GIF_89A;
  803. X    }
  804. X    else
  805. X    {
  806. X        /* Unknown version -- oops. */
  807. X
  808. X        *version = GIF_NOT;
  809. X    }
  810. X
  811. X    /* Return OK. */
  812. X
  813. X    return 0;
  814. X} /* end of static gif_fgetvers() */
  815. X
  816. X
  817. X/***************************************************************************
  818. X*   FUNCTION: gif_tblget STATIC                                            *
  819. X*                                                                          *
  820. X*   DESCRIPTION:                                                           *
  821. X*                                                                          *
  822. X*      This function reads and processes a GIF color table. The color      *
  823. X*      table is assumed to be the next thing in the file.                  *
  824. X*                                                                          *
  825. X*   ENTRY:                                                                 *
  826. X*                                                                          *
  827. X*      infile - FB handle of file                                          *
  828. X*      colors - pointer to array of RGB_TRIPLET in which to return colors  *
  829. X*      size   - size of color table, in triplets                           *
  830. X*                                                                          *
  831. X*   EXIT:                                                                  *
  832. X*                                                                          *
  833. X*      Returns an error/status code.                                       *
  834. X*                                                                          *
  835. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  836. X*                                                                          *
  837. X*      Assumes file is positioned correctly. Leaves file pointer pointing  *
  838. X*      to byte after end of color table.                                   *
  839. X*                                                                          *
  840. X***************************************************************************/
  841. Xstatic ULONG
  842. X#ifdef __STDC__
  843. Xgif_tblget(FB *infile, RGB_TRIPLET *colors, int size)
  844. X#else
  845. Xgif_tblget(infile, colors, size)
  846. XFB *infile;
  847. XRGB_TRIPLET *colors;
  848. Xint size;
  849. X#endif
  850. X{
  851. X    UCHAR *tempbuf;
  852. X    int i;
  853. X
  854. X    /* Allocate temporary buffer to hold raw color table. */
  855. X
  856. X    tempbuf = (UCHAR *) malloc(3 * size);
  857. X    if (tempbuf == (UCHAR *) NULL)
  858. X    {
  859. X        return GIF_NOMEM_E;
  860. X    }
  861. X
  862. X    /* Read into temporary buffer. */
  863. X
  864. X    if (fb_read(infile, tempbuf, (size * 3)) != (size * 3))
  865. X    {
  866. X        return fb_error;
  867. X    }
  868. X
  869. X    /* Extract colors from temporary buffer. */
  870. X
  871. X    for (i = 0; i < size; i++)
  872. X    {
  873. X        colors[i].red = *(tempbuf + (i * 3));
  874. X        colors[i].green = *(tempbuf + (i * 3) + 1);
  875. X        colors[i].blue = *(tempbuf + (i * 3) + 2);
  876. X    }
  877. X
  878. X    /* Free temporary buffer. */
  879. X
  880. X    free(tempbuf);
  881. X
  882. X    /* Return OK. */
  883. X
  884. X    return 0;
  885. X} /* end of static gif_tblget() */
  886. X
  887. X
  888. X/***************************************************************************
  889. X*   FUNCTION: gif_gbytes STATIC                                            *
  890. X*                                                                          *
  891. X*   DESCRIPTION:                                                           *
  892. X*                                                                          *
  893. X*      Accumulates data blocks into a buffer until reaching a zero-length  *
  894. X*      block. Does this by first determining number of data bytes, then    *
  895. X*      resetting position of file, allocating a buffer of the appropriate  *
  896. X*      size, then reading from file again but into buffer this time.       *
  897. X*                                                                          *
  898. X*   ENTRY:                                                                 *
  899. X*                                                                          *
  900. X*      infile - FB handle of file                                          *
  901. X*      bytes  - pointer to pointer in which pointer to buffer containing   *
  902. X*               data is returned        .                                  *
  903. X*      length - pointer to unsigned int in which data buffer length is     *
  904. X*               returned                                                   *
  905. X*                                                                          *
  906. X*   EXIT:                                                                  *
  907. X*                                                                          *
  908. X*      Returns an error/status code.                                       *
  909. X*                                                                          *
  910. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  911. X*                                                                          *
  912. X*      Assumes the file is positioned correctly. Leaves file pointer       *
  913. X*      pointing to byte after the zero-length data block.                  *
  914. X*                                                                          *
  915. X*      The data buffer returned in bytes must be free()'ed.                *
  916. X*                                                                          *
  917. X***************************************************************************/
  918. Xstatic ULONG
  919. X#ifdef __STDC__
  920. Xgif_gbytes(FB *infile, char **bytes, unsigned int *length)
  921. X#else
  922. Xgif_gbytes(infile, bytes, length)
  923. XFB *infile;
  924. Xchar **bytes;
  925. Xunsigned int *length;
  926. X#endif
  927. X{
  928. X    long filepos;
  929. X    int blocks;
  930. X    int blocklen;
  931. X    UCHAR *datablock;
  932. X    ULONG status;
  933. X
  934. X    /* Save current position in file. */
  935. X
  936. X    filepos = fb_tell(infile);
  937. X    if (fb_error != 0)
  938. X    {
  939. X        return fb_error;
  940. X    }
  941. X
  942. X    /* Read first block -- return on error. */
  943. X
  944. X    if ((status = gif_readblock(infile, &datablock, &blocklen)) != 0)
  945. X    {
  946. X        return status;
  947. X    }
  948. X
  949. X    /* If zero length, return. */
  950. X
  951. X    if (blocklen == 0)
  952. X    {
  953. X        *length = 0;
  954. X        *bytes = NULL;
  955. X        return 0;
  956. X    }
  957. X    free(datablock);
  958. X
  959. X
  960. X    /* Loop until terminator. */
  961. X
  962. X    *length = blocklen;
  963. X    blocks = 1;
  964. X    while (blocklen != 0)
  965. X    {
  966. X        /* Read next block -- return on error. */
  967. X
  968. X        if ((status = gif_readblock(infile, &datablock, &blocklen)) != 0)
  969. X        {
  970. X            return status;
  971. X        }
  972. X
  973. X        /* Update length. */
  974. X
  975. X        (*length) += blocklen;
  976. X
  977. X        /* Increment number of blocks. */
  978. X
  979. X        blocks++;
  980. X
  981. X        /* Clean up. */
  982. X
  983. X        if (datablock != (UCHAR *) NULL)
  984. X        {
  985. X            free(datablock);
  986. X        }
  987. X    }
  988. X
  989. X    /* Reset file position -- return on error. */
  990. X
  991. X    if ((status = fb_seek(infile, filepos)) != 0)
  992. X    {
  993. X        return status;
  994. X    }
  995. X
  996. X    /* Allocate text buffer. */
  997. X
  998. X    if ((*bytes = (char *) malloc(*length)) == NULL)
  999. X    {
  1000. X        return GIF_NOMEM_E;
  1001. X    }
  1002. X
  1003. X    /* Read all over again, starting with first block. */
  1004. X
  1005. X    *length = 0;
  1006. X    for (blocks--; blocks > 0; blocks--)
  1007. X    {
  1008. X        /* Read block. */
  1009. X
  1010. X        if ((status = gif_readblock(infile, &datablock, &blocklen)) != 0)
  1011. X        {
  1012. X            free(*bytes);
  1013. X            return status;
  1014. X        }
  1015. X
  1016. X        /* Copy into text buffer. */
  1017. X
  1018. X        memcpy(((*bytes) + *length), datablock, blocklen);
  1019. X        (*length) += blocklen;
  1020. X
  1021. X        /* Clean up. */
  1022. X
  1023. X        free(datablock);
  1024. X    }
  1025. X
  1026. X    /* Read terminator block. */
  1027. X
  1028. X    if ((status = gif_readblock(infile, &datablock, &blocklen)) != 0)
  1029. X    {
  1030. X        free(*bytes);
  1031. X        return status;
  1032. X    }
  1033. X
  1034. X    /* One last check. */
  1035. X
  1036. X    if (blocklen != 0)
  1037. X    {
  1038. X        /* Oops. */
  1039. X
  1040. X        if (datablock != (UCHAR *) NULL)
  1041. X        {
  1042. X            free(datablock);
  1043. X        }
  1044. X        free(*bytes);
  1045. X        return GIF_BUG_F;
  1046. X    }
  1047. X
  1048. X    /* Return OK. */
  1049. X
  1050. X    return 0;
  1051. X} /* end of gif_gbytes() */
  1052. X
  1053. X#endif /* !NO_FB */
  1054. X
  1055. END_OF_FILE
  1056.   if test 34397 -ne `wc -c <'src/gif.c.B'`; then
  1057.     echo shar: \"'src/gif.c.B'\" unpacked with wrong size!
  1058.   elif test -f 'src/gif.c.A'; then
  1059.     echo shar: Combining  \"'src/gif.c'\" \(63060 characters\)
  1060.     cat 'src/gif.c.A' 'src/gif.c.B' > 'src/gif.c'
  1061.     if test 63060 -ne `wc -c <'src/gif.c'`; then
  1062.       echo shar: \"'src/gif.c'\" combined with wrong size!
  1063.     else
  1064.       rm src/gif.c.A src/gif.c.B
  1065.     fi
  1066.   fi
  1067.   # end of 'src/gif.c.B'
  1068. fi
  1069. if test -f 'src/jfif.c' -a "${1}" != "-c" ; then 
  1070.   echo shar: Will not clobber existing file \"'src/jfif.c'\"
  1071. else
  1072.   echo shar: Extracting \"'src/jfif.c'\" \(17689 characters\)
  1073.   sed "s/^X//" >'src/jfif.c' <<'END_OF_FILE'
  1074. X/***************************************************************************
  1075. X*   JFIF.C                                                                 *
  1076. X*   MODULE:  JFIF                                                          *
  1077. X*   OS:      UNIX                                                          *
  1078. X*                                                                          *
  1079. X*   Copyright (c) 1993 James W. Birdsall. All Rights Reserved.             *
  1080. X*                                                                          *
  1081. X*   $Id: jfif.c,v 1.6 1993/03/02 00:56:24 jwbirdsa Exp $
  1082. X*                                                                          *
  1083. X*   This file contains functions to process JFIF format files.             *
  1084. X*                                                                          *
  1085. X***************************************************************************/
  1086. X
  1087. X#include "config.h"
  1088. X
  1089. X/*
  1090. X** system includes <>
  1091. X*/
  1092. X
  1093. X#include <stdio.h>
  1094. X#ifndef NO_STR_INC
  1095. X#ifdef STRING_PLURAL
  1096. X#include <strings.h>
  1097. X#else
  1098. X#include <string.h>
  1099. X#endif
  1100. X#endif
  1101. X
  1102. X
  1103. X/*
  1104. X** custom includes ""
  1105. X*/
  1106. X
  1107. X#include "depend.h"
  1108. X
  1109. X#include "fb.h"
  1110. X#include "formats.h"
  1111. X#include "jfif.h"
  1112. X
  1113. X
  1114. X/*
  1115. X** local #defines
  1116. X*/
  1117. X
  1118. X#define CHECK_FB()       if (fb_error != 0) return fb_error
  1119. X
  1120. X
  1121. X/*
  1122. X** misc: copyright strings, version macros, etc.
  1123. X*/
  1124. X
  1125. X/*
  1126. X** typedefs
  1127. X*/
  1128. X
  1129. X/*
  1130. X** global variables
  1131. X*/
  1132. X
  1133. X/*
  1134. X** static globals
  1135. X*/
  1136. X
  1137. Xstatic char CONST rcsid[] = "$Id: jfif.c,v 1.6 1993/03/02 00:56:24 jwbirdsa Exp $";
  1138. X
  1139. X
  1140. X/*
  1141. X** function prototypes
  1142. X*/
  1143. X
  1144. X#ifdef  __STDC__
  1145. X# define P_(s) s
  1146. X#else
  1147. X# define P_(s) ()
  1148. X#endif
  1149. X
  1150. Xstatic ULONG jfif_app0get P_((FB *jfif_file, JFIF_HDR *results));
  1151. X
  1152. X#undef P_
  1153. X
  1154. X#ifdef NO_STR_INC
  1155. Xextern char *strrchr();
  1156. Xextern int strcmp();
  1157. X#endif
  1158. X
  1159. X
  1160. X/*
  1161. X** functions
  1162. X*/
  1163. X
  1164. X
  1165. X/***************************************************************************
  1166. X*   FUNCTION:    jfif_verify                                               *
  1167. X*                                                                          *
  1168. X*   DESCRIPTION:                                                           *
  1169. X*                                                                          *
  1170. X*       Verifies that a file is a JFIF file by checking filename against   *
  1171. X*       list of extensions. Searches JFIF file for JFIF version number.    *
  1172. X*                                                                          *
  1173. X*   ENTRY:                                                                 *
  1174. X*                                                                          *
  1175. X*       filename - name of file to be verified                             *
  1176. X*       version  - pointer to unsigned long in which format/version value  *
  1177. X*                  is returned                                             *
  1178. X*       exts     - array of string pointers, list of extensions for JFIF   *
  1179. X*                  files                                                   *
  1180. X*                                                                          *
  1181. X*   EXIT:                                                                  *
  1182. X*                                                                          *
  1183. X*       Returns an error/status code.                                      *
  1184. X*                                                                          *
  1185. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  1186. X*                                                                          *
  1187. X***************************************************************************/
  1188. XULONG
  1189. X#ifdef __STDC__
  1190. Xjfif_verify(char *filename, ULONG *version, char **exts)
  1191. X#else
  1192. Xjfif_verify(filename, version, exts)
  1193. Xchar *filename;
  1194. XULONG *version;
  1195. Xchar **exts;
  1196. X#endif
  1197. X{
  1198. X    char *extptr;
  1199. X    int loop;
  1200. X    FB *jfif_file;
  1201. X    JFIF_HDR results;
  1202. X    long junk;
  1203. X    ULONG status;
  1204. X
  1205. X    /* Search for '.' marking extension. */
  1206. X
  1207. X    extptr = strrchr(filename, '.');
  1208. X    if (NULL == extptr)
  1209. X    {
  1210. X        /* No extension, cannot classify. */
  1211. X
  1212. X        *version = JFIF_NOT;
  1213. X        return 0;
  1214. X    }
  1215. X    extptr++;
  1216. X
  1217. X    /* Now we have the extension, check against list. */
  1218. X
  1219. X    for (loop = 0; exts[loop] != NULL; loop++)
  1220. X    {
  1221. X        /* Case-sensitive string compare. */
  1222. X
  1223. X        if (strcmp(extptr, exts[loop]) == 0)
  1224. X        {
  1225. X            /*  Match, so break out of loop. */
  1226. X
  1227. X            break;
  1228. X        }
  1229. X    }
  1230. X
  1231. X    /* Check exit from loop. */
  1232. X
  1233. X    if (NULL == exts[loop])
  1234. X    {
  1235. X        /* No match, return. */
  1236. X
  1237. X        *version = JFIF_NOT;
  1238. X        return 0;
  1239. X    }
  1240. X
  1241. X    /* Extension is valid for type JFIF, so process accordingly. */
  1242. X
  1243. X    if ((jfif_file = fb_open(filename, 'r', &junk)) == (FB *) NULL)
  1244. X    {
  1245. X        *version = JFIF_NOT;
  1246. X        return fb_error;
  1247. X    }
  1248. X    if ((status = jfif_app0get(jfif_file, &results)) != ST_SUCCESS)
  1249. X    {
  1250. X        *version = JFIF_NOT;
  1251. X        fb_close(jfif_file);
  1252. X        return ((FB_EOF_W == status) ? ST_SUCCESS : status);
  1253. X    }
  1254. X    *version = results.version;
  1255. X    if ((status = fb_close(jfif_file)) != ST_SUCCESS)
  1256. X    {
  1257. X        return status;
  1258. X    }
  1259. X
  1260. X    /* All done, return OK. */
  1261. X
  1262. X    return 0;
  1263. X} /* end of jfif_verify() */
  1264. X
  1265. X
  1266. X/***************************************************************************
  1267. X*   FUNCTION:    jfif_headerget                                            *
  1268. X*                                                                          *
  1269. X*   DESCRIPTION:                                                           *
  1270. X*                                                                          *
  1271. X*       Assumes that file is a JFIF file. Searches file for header         *
  1272. X*       information, extracts into JFIF_HDR structure.                     *
  1273. X*                                                                          *
  1274. X*   ENTRY:                                                                 *
  1275. X*                                                                          *
  1276. X*       jfif_file - file to be processed                                   *
  1277. X*       results   - pointer to JFIF_HDR structure in which data from APP0  *
  1278. X*                   and SOF0 is returned                                   *
  1279. X*                                                                          *
  1280. X*   EXIT:                                                                  *
  1281. X*                                                                          *
  1282. X*       Returns an error/status code.                                      *
  1283. X*                                                                          *
  1284. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  1285. X*                                                                          *
  1286. X*       Leaves file pointing wherever.                                     *
  1287. X*                                                                          *
  1288. X***************************************************************************/
  1289. XULONG
  1290. X#ifdef __STDC__
  1291. Xjfif_headerget(FB *jfif_file, JFIF_HDR *results)
  1292. X#else
  1293. Xjfif_headerget(jfif_file, results)
  1294. XFB *jfif_file;
  1295. XJFIF_HDR *results;
  1296. X#endif
  1297. X{
  1298. X    ULONG status;
  1299. X    long work, repos;
  1300. X    int c;
  1301. X    UCHAR buffer[JFIF_SOF0_LEN];
  1302. X
  1303. X    /* Make sure we're at beginning of file. */
  1304. X
  1305. X    fb_seek(jfif_file, 0L);
  1306. X    CHECK_FB();
  1307. X
  1308. X    /* Get APP0 stuff. */
  1309. X
  1310. X    if ((status = jfif_app0get(jfif_file, results)) != 0)
  1311. X    {
  1312. X        return status;
  1313. X    }
  1314. X
  1315. X    /* Search forward by blocks. */
  1316. X
  1317. X    c = 0;
  1318. X    while (1)
  1319. X    {
  1320. X        /* Search forward to next block. */
  1321. X
  1322. X        while (c != JFIF_SEPARATOR)
  1323. X        {
  1324. X            c = fb_getc(jfif_file);
  1325. X            CHECK_FB();
  1326. X        }
  1327. X        c = fb_getc(jfif_file);
  1328. X        CHECK_FB();
  1329. X
  1330. X        /* If c is 0, crud -- skip. */
  1331. X
  1332. X        if (0 == c)
  1333. X        {
  1334. X            continue;
  1335. X        }
  1336. X
  1337. X        if (c != JFIF_SOF0)
  1338. X        {
  1339. X            /* Not a SOF0 block, skip. */
  1340. X
  1341. X            work = fb_getc(jfif_file);
  1342. X            CHECK_FB();
  1343. X            work <<= 8;
  1344. X            work |= (fb_getc(jfif_file) & 0xFF);
  1345. X            CHECK_FB();
  1346. X            work -= 2;
  1347. X
  1348. X            /* Work now contains length of rest of block. */
  1349. X
  1350. X            repos = fb_tell(jfif_file);
  1351. X            CHECK_FB();
  1352. X
  1353. X            /* Add work to current position and reposition file pointer. */
  1354. X
  1355. X            fb_seek(jfif_file, (repos + work));
  1356. X            CHECK_FB();
  1357. X            continue;
  1358. X        }
  1359. X
  1360. X        /* Block is SOF0 -- but is it the right SOF0? Get length. */
  1361. X
  1362. X        work = fb_getc(jfif_file);
  1363. X        CHECK_FB();
  1364. X        work <<= 8;
  1365. X        work |= (fb_getc(jfif_file) & 0xFF);
  1366. X        CHECK_FB();
  1367. X        if (work < JFIF_SOF0_LEN)
  1368. X        {
  1369. X            /* Is wrong SOF0, skip. */
  1370. X            
  1371. X            work -= 2;
  1372. X            repos = fb_tell(jfif_file);
  1373. X            CHECK_FB();
  1374. X
  1375. X            /* Add work to current position and reposition file pointer. */
  1376. X
  1377. X            fb_seek(jfif_file, (repos + work));
  1378. X            CHECK_FB();
  1379. X            continue;
  1380. X        }
  1381. X
  1382. X        /* Read beginning into buffer. */
  1383. X
  1384. X        if (fb_read(jfif_file, (buffer + JFIF_SOF0_PREC_OFF),
  1385. X                    (JFIF_SOF0_LEN - JFIF_SOF0_PREC_OFF)) !=
  1386. X            (JFIF_SOF0_LEN - JFIF_SOF0_PREC_OFF))
  1387. X        {
  1388. X            return ((ST_SUCCESS == fb_error) ? JFIF_FILEERR_E : fb_error);
  1389. X        }
  1390. X
  1391. X        /* Check length one more time. */
  1392. X
  1393. X        results->components = (0x00FF & (int)(*(buffer + JFIF_SOF0_COMP_OFF)));
  1394. X        if (((results->components * 3) + JFIF_SOF0_STUFF_OFF) != work)
  1395. X        {
  1396. X            /* Bogus length, try again. */
  1397. X
  1398. X            work -= JFIF_SOF0_LEN;
  1399. X            repos = fb_tell(jfif_file);
  1400. X            CHECK_FB();
  1401. X
  1402. X            /* Add work to current position and reposition file pointer. */
  1403. X
  1404. X            fb_seek(jfif_file, (repos + work));
  1405. X            CHECK_FB();
  1406. X            continue;
  1407. X        }
  1408. X
  1409. X        /* Is the correct SOF0! */
  1410. X
  1411. X        break;
  1412. X    }
  1413. X
  1414. X    /* Extract data -- components already set, above. */
  1415. X
  1416. X    results->bits = (0x00FF & (int)(*(buffer + JFIF_SOF0_PREC_OFF)));
  1417. X    results->height = CONSTRUCT_M_UINT(buffer + JFIF_SOF0_HI_OFF);
  1418. X    results->width = CONSTRUCT_M_UINT(buffer + JFIF_SOF0_WID_OFF);
  1419. X
  1420. X    /* All OK. */
  1421. X
  1422. X    return 0;
  1423. X} /* end of jfif_headerget() */
  1424. X
  1425. X
  1426. X/***************************************************************************
  1427. X*   FUNCTION:    jfif_errstring                                            *
  1428. X*                                                                          *
  1429. X*   DESCRIPTION:                                                           *
  1430. X*                                                                          *
  1431. X*       Returns a string corresponding to an error code.                   *
  1432. X*                                                                          *
  1433. X*   ENTRY:                                                                 *
  1434. X*                                                                          *
  1435. X*       errcode - error code to be translated                              *
  1436. X*                                                                          *
  1437. X*   EXIT:                                                                  *
  1438. X*                                                                          *
  1439. X*       Returns a pointer to the appropriate string, or NULL if there is   *
  1440. X*       no appropriate string.                                             *
  1441. X*                                                                          *
  1442. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  1443. X*                                                                          *
  1444. X***************************************************************************/
  1445. Xchar *
  1446. X#ifdef __STDC__
  1447. Xjfif_errstring(ULONG errcode)
  1448. X#else
  1449. Xjfif_errstring(errcode)
  1450. XULONG errcode;
  1451. X#endif
  1452. X{
  1453. X    char *temp;
  1454. X
  1455. X    /* If error code not from this module, return NULL. */
  1456. X
  1457. X    if (MODULE(errcode) != MODULE(JFIF_MODULE))
  1458. X    {
  1459. X        return NULL;
  1460. X    }
  1461. X
  1462. X    /* Process by code. */
  1463. X
  1464. X    switch (ERRSEV(errcode))
  1465. X    {
  1466. X        case ERRSEV(JFIF_NOTJFIF_E):
  1467. X            temp = "File is not a JFIF format file.";
  1468. X            break;
  1469. X        case ERRSEV(JFIF_FILEERR_E):
  1470. X            temp = "Error accessing file.";
  1471. X            break;
  1472. X
  1473. X        default:
  1474. X            temp = NULL;
  1475. X            break;
  1476. X    }
  1477. X
  1478. X    return temp;
  1479. X} /* end of jfif_errstring() */
  1480. X
  1481. X
  1482. X/***************************************************************************
  1483. X*   FUNCTION:    jfif_app0get  STATIC                                      *
  1484. X*                                                                          *
  1485. X*   DESCRIPTION:                                                           *
  1486. X*                                                                          *
  1487. X*       This function searches through the JFIF file looking for the JFIF  *
  1488. X*       APP0 block and extracts data from it into JFIF_HDR structure.      *
  1489. X*                                                                          *
  1490. X*   ENTRY:                                                                 *
  1491. X*                                                                          *
  1492. X*       jfif_file - file to be processed                                   *
  1493. X*       results   - pointer to JFIF_HDR structure in which data from APP0  *
  1494. X*                   is returned                                            *
  1495. X*                                                                          *
  1496. X*   EXIT:                                                                  *
  1497. X*                                                                          *
  1498. X*       Returns an error/status code.                                      *
  1499. X*                                                                          *
  1500. X*   CONSTRAINTS/SIDE EFFECTS:                                              *
  1501. X*                                                                          *
  1502. X*       Assumes the file points to before the JFIF APP0 block.             *
  1503. X*                                                                          *
  1504. X*       Leaves the file pointing wherever.                                 *
  1505. X*                                                                          *
  1506. X***************************************************************************/
  1507. Xstatic ULONG
  1508. X#ifdef __STDC__
  1509. Xjfif_app0get(FB *jfif_file, JFIF_HDR *results)
  1510. X#else
  1511. Xjfif_app0get(jfif_file, results)
  1512. XFB *jfif_file;
  1513. XJFIF_HDR *results;
  1514. X#endif
  1515. X{
  1516. X    int c;
  1517. X    long work;
  1518. X    long repos;
  1519. X    UCHAR buffer[JFIF_APP0_LEN];
  1520. X
  1521. X    /* Search forward for SOI. */
  1522. X
  1523. X    c = 0;
  1524. X    while (c != JFIF_SOI)
  1525. X    {
  1526. X        while (c != JFIF_SEPARATOR)
  1527. X        {
  1528. X            c = fb_getc(jfif_file);
  1529. X            CHECK_FB();
  1530. X        }
  1531. X        c = fb_getc(jfif_file);
  1532. X        CHECK_FB();
  1533. X    }
  1534. X
  1535. X    /* Search forward by blocks. */
  1536. X
  1537. X    while (1)
  1538. X    {
  1539. X        /* Search forward to next block. */
  1540. X
  1541. X        while (c != JFIF_SEPARATOR)
  1542. X        {
  1543. X            c = fb_getc(jfif_file);
  1544. X            CHECK_FB();
  1545. X        }
  1546. X        c = fb_getc(jfif_file);
  1547. X        CHECK_FB();
  1548. X
  1549. X        /* If c is 0, crud -- skip. */
  1550. X
  1551. X        if (0 == c)
  1552. X        {
  1553. X            continue;
  1554. X        }
  1555. X        if (c != JFIF_APP0)
  1556. X        {
  1557. X            /* Not an APP0 block, skip. */
  1558. X
  1559. X            work = fb_getc(jfif_file);
  1560. X            CHECK_FB();
  1561. X            work <<= 8;
  1562. X            work |= (fb_getc(jfif_file) & 0xFF);
  1563. X            CHECK_FB();
  1564. X            work -= 2;
  1565. X            repos = fb_tell(jfif_file);
  1566. X            CHECK_FB();
  1567. X
  1568. X            /* Add work to current position and reposition file pointer. */
  1569. X
  1570. X            fb_seek(jfif_file, (repos + work));
  1571. X            CHECK_FB();
  1572. X            continue;
  1573. X        }
  1574. X
  1575. X        /* Block is APP0 -- but is it the right APP0? Get length. */
  1576. X
  1577. X        work = fb_getc(jfif_file);
  1578. X        CHECK_FB();
  1579. X        work <<= 8;
  1580. X        work |= (fb_getc(jfif_file) & 0xFF);
  1581. X        CHECK_FB();
  1582. X        if (work < JFIF_APP0_LEN)
  1583. X        {
  1584. X            /* Is wrong APP0, skip. */
  1585. X
  1586. X            work -= 2;
  1587. X            repos = fb_tell(jfif_file);
  1588. X            CHECK_FB();
  1589. X
  1590. X            /* Add work to current position and reposition file pointer. */
  1591. X
  1592. X            fb_seek(jfif_file, (repos + work));
  1593. X            CHECK_FB();
  1594. X            continue;
  1595. X        }
  1596. X
  1597. X        /* Check signature -- read into buffer. */
  1598. X
  1599. X        if (fb_read(jfif_file, (buffer + JFIF_APP0_SIGNATURE_OFF),
  1600. X                    (JFIF_APP0_LEN - JFIF_APP0_SIGNATURE_OFF)) !=
  1601. X            (JFIF_APP0_LEN - JFIF_APP0_SIGNATURE_OFF))
  1602. X        {
  1603. X            return ((ST_SUCCESS == fb_error) ? JFIF_FILEERR_E : fb_error);
  1604. X        }
  1605. X        if (memcmp((buffer + JFIF_APP0_SIGNATURE_OFF), JFIF_SIGNATURE,
  1606. X                   JFIF_SIGNATURE_LEN) != 0)
  1607. X        {
  1608. X            /* Wrong APP0, skip. */
  1609. X
  1610. X            work -= JFIF_APP0_LEN;
  1611. X            repos = fb_tell(jfif_file);
  1612. X            CHECK_FB();
  1613. X
  1614. X            /* Add work to current position and reposition file pointer. */
  1615. X
  1616. X            fb_seek(jfif_file, (repos + work));
  1617. X            CHECK_FB();
  1618. X            continue;
  1619. X        }
  1620. X
  1621. X        /* Is the correct APP0! */
  1622. X
  1623. X        break;
  1624. X    }
  1625. X
  1626. X    /* Extract data. */
  1627. X
  1628. X    if (*(buffer + JFIF_APP0_VERS_OFF) != 1)
  1629. X    {
  1630. X        /* Wrong version! */
  1631. X
  1632. X        return JFIF_NOTJFIF_E;
  1633. X    }
  1634. X    if ((*(buffer + JFIF_APP0_VERS_OFF + 1) != 1) &&
  1635. X        (*(buffer + JFIF_APP0_VERS_OFF + 1) != 0))
  1636. X    {
  1637. X        /* Wrong version! */
  1638. X
  1639. X        return JFIF_NOTJFIF_E;
  1640. X    }
  1641. X    results->version = JFIF_VER101;
  1642. X    results->densunit = (0x00FF & (int)(*(buffer + JFIF_APP0_DENSUNIT_OFF)));
  1643. X    results->xdens = CONSTRUCT_M_UINT(buffer + JFIF_APP0_XDENS_OFF);
  1644. X    results->ydens = CONSTRUCT_M_UINT(buffer + JFIF_APP0_YDENS_OFF);
  1645. X    results->xthumb = (0x00FF & (int)(*(buffer + JFIF_APP0_XTHUMB_OFF)));
  1646. X    results->ythumb = (0x00FF & (int)(*(buffer + JFIF_APP0_YTHUMB_OFF)));
  1647. X
  1648. X    /* All done. */
  1649. X
  1650. X    return 0;
  1651. X} /* end of static jfif_app0get() */
  1652. X
  1653. END_OF_FILE
  1654.   if test 17689 -ne `wc -c <'src/jfif.c'`; then
  1655.     echo shar: \"'src/jfif.c'\" unpacked with wrong size!
  1656.   fi
  1657.   # end of 'src/jfif.c'
  1658. fi
  1659. echo shar: End of archive 9 \(of 18\).
  1660. cp /dev/null ark9isdone
  1661. MISSING=""
  1662. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
  1663.     if test ! -f ark${I}isdone ; then
  1664.     MISSING="${MISSING} ${I}"
  1665.     fi
  1666. done
  1667. if test "${MISSING}" = "" ; then
  1668.     echo You have unpacked all 18 archives.
  1669.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1670. else
  1671.     echo You still must unpack the following archives:
  1672.     echo "        " ${MISSING}
  1673. fi
  1674. exit 0
  1675. exit 0 # Just in case...
  1676.