home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume29 / jpeg / part05 < prev    next >
Encoding:
Text File  |  1992-03-23  |  53.6 KB  |  1,643 lines

  1. Newsgroups: comp.sources.misc
  2. From: jpeg-info@uunet.uu.net (Independent JPEG Group)
  3. Subject:  v29i005:  jpeg - JPEG image compression, Part05/18
  4. Message-ID: <1992Mar24.144353.18159@sparky.imd.sterling.com>
  5. X-Md4-Signature: 03debc23022cdfd5ce649799bb12abfb
  6. Date: Tue, 24 Mar 1992 14:43:53 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jpeg-info@uunet.uu.net (Independent JPEG Group)
  10. Posting-number: Volume 29, Issue 5
  11. Archive-name: jpeg/part05
  12. Environment: UNIX, VMS, MS-DOS, Mac, Amiga, Cray
  13.  
  14. #! /bin/sh
  15. # into a shell via "sh file" or similar.  To overwrite existing files,
  16. # type "sh file -c".
  17. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  18. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  19. # Contents:  jcarith.c jmemmgr.c jrdtarga.c makvms.opt
  20. # Wrapped by kent@sparky on Mon Mar 23 16:02:42 1992
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. echo If this archive is complete, you will see the following message:
  23. echo '          "shar: End of archive 5 (of 18)."'
  24. if test -f 'jcarith.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'jcarith.c'\"
  26. else
  27.   echo shar: Extracting \"'jcarith.c'\" \(1161 characters\)
  28.   sed "s/^X//" >'jcarith.c' <<'END_OF_FILE'
  29. X/*
  30. X * jcarith.c
  31. X *
  32. X * Copyright (C) 1991, 1992, Thomas G. Lane.
  33. X * This file is part of the Independent JPEG Group's software.
  34. X * For conditions of distribution and use, see the accompanying README file.
  35. X *
  36. X * This file contains arithmetic entropy encoding routines.
  37. X * These routines are invoked via the methods entropy_encode,
  38. X * entropy_encoder_init/term, and entropy_optimize.
  39. X */
  40. X
  41. X#include "jinclude.h"
  42. X
  43. X#ifdef ARITH_CODING_SUPPORTED
  44. X
  45. X
  46. X/*
  47. X * The arithmetic coding option of the JPEG standard specifies Q-coding,
  48. X * which is covered by patents held by IBM (and possibly AT&T and Mitsubishi).
  49. X * At this time it does not appear to be legal for the Independent JPEG
  50. X * Group to distribute software that implements arithmetic coding.
  51. X * We have therefore removed arithmetic coding support from the
  52. X * distributed source code.
  53. X *
  54. X * We're not happy about it either.
  55. X */
  56. X
  57. X
  58. X/*
  59. X * The method selection routine for arithmetic entropy encoding.
  60. X */
  61. X
  62. XGLOBAL void
  63. Xjselcarithmetic (compress_info_ptr cinfo)
  64. X{
  65. X  if (cinfo->arith_code) {
  66. X    ERREXIT(cinfo->emethods, "Sorry, there are legal restrictions on arithmetic coding");
  67. X  }
  68. X}
  69. X
  70. X#endif /* ARITH_CODING_SUPPORTED */
  71. END_OF_FILE
  72.   if test 1161 -ne `wc -c <'jcarith.c'`; then
  73.     echo shar: \"'jcarith.c'\" unpacked with wrong size!
  74.   fi
  75.   # end of 'jcarith.c'
  76. fi
  77. if test -f 'jmemmgr.c' -a "${1}" != "-c" ; then 
  78.   echo shar: Will not clobber existing file \"'jmemmgr.c'\"
  79. else
  80.   echo shar: Extracting \"'jmemmgr.c'\" \(35862 characters\)
  81.   sed "s/^X//" >'jmemmgr.c' <<'END_OF_FILE'
  82. X/*
  83. X * jmemmgr.c
  84. X *
  85. X * Copyright (C) 1991, 1992, Thomas G. Lane.
  86. X * This file is part of the Independent JPEG Group's software.
  87. X * For conditions of distribution and use, see the accompanying README file.
  88. X *
  89. X * This file provides the standard system-independent memory management
  90. X * routines.  This code is usable across a wide variety of machines; most
  91. X * of the system dependencies have been isolated in a separate file.
  92. X * The major functions provided here are:
  93. X *   * bookkeeping to allow all allocated memory to be freed upon exit;
  94. X *   * policy decisions about how to divide available memory among the
  95. X *     various large arrays;
  96. X *   * control logic for swapping virtual arrays between main memory and
  97. X *     backing storage.
  98. X * The separate system-dependent file provides the actual backing-storage
  99. X * access code, and it contains the policy decision about how much total
  100. X * main memory to use.
  101. X * This file is system-dependent in the sense that some of its functions
  102. X * are unnecessary in some systems.  For example, if there is enough virtual
  103. X * memory so that backing storage will never be used, much of the big-array
  104. X * control logic could be removed.  (Of course, if you have that much memory
  105. X * then you shouldn't care about a little bit of unused code...)
  106. X *
  107. X * These routines are invoked via the methods alloc_small, free_small,
  108. X * alloc_medium, free_medium, alloc_small_sarray, free_small_sarray,
  109. X * alloc_small_barray, free_small_barray, request_big_sarray,
  110. X * request_big_barray, alloc_big_arrays, access_big_sarray, access_big_barray,
  111. X * free_big_sarray, free_big_barray, and free_all.
  112. X */
  113. X
  114. X#define AM_MEMORY_MANAGER    /* we define big_Xarray_control structs */
  115. X
  116. X#include "jinclude.h"
  117. X#include "jmemsys.h"        /* import the system-dependent declarations */
  118. X
  119. X
  120. X/*
  121. X * On many systems it is not necessary to distinguish alloc_small from
  122. X * alloc_medium; the main case where they must be distinguished is when
  123. X * FAR pointers are distinct from regular pointers.  However, you might
  124. X * want to keep them separate if you have different system-dependent logic
  125. X * for small and large memory requests (i.e., jget_small and jget_large
  126. X * do different things).
  127. X */
  128. X
  129. X#ifdef NEED_FAR_POINTERS
  130. X#define NEED_ALLOC_MEDIUM    /* flags alloc_medium really exists */
  131. X#endif
  132. X
  133. X
  134. X/*
  135. X * Some important notes:
  136. X *   The allocation routines provided here must never return NULL.
  137. X *   They should exit to error_exit if unsuccessful.
  138. X *
  139. X *   It's not a good idea to try to merge the sarray and barray routines,
  140. X *   even though they are textually almost the same, because samples are
  141. X *   usually stored as bytes while coefficients are shorts.  Thus, in machines
  142. X *   where byte pointers have a different representation from word pointers,
  143. X *   the resulting machine code could not be the same.
  144. X */
  145. X
  146. X
  147. Xstatic external_methods_ptr methods; /* saved for access to error_exit */
  148. X
  149. X
  150. X#ifdef MEM_STATS        /* optional extra stuff for statistics */
  151. X
  152. X/* These macros are the assumed overhead per block for malloc().
  153. X * They don't have to be accurate, but the printed statistics will be
  154. X * off a little bit if they are not.
  155. X */
  156. X#define MALLOC_OVERHEAD  (SIZEOF(void *)) /* overhead for jget_small() */
  157. X#define MALLOC_FAR_OVERHEAD  (SIZEOF(void FAR *)) /* for jget_large() */
  158. X
  159. Xstatic long total_num_small = 0;    /* total # of small objects alloced */
  160. Xstatic long total_bytes_small = 0;    /* total bytes requested */
  161. Xstatic long cur_num_small = 0;        /* # currently alloced */
  162. Xstatic long max_num_small = 0;        /* max simultaneously alloced */
  163. X
  164. X#ifdef NEED_ALLOC_MEDIUM
  165. Xstatic long total_num_medium = 0;    /* total # of medium objects alloced */
  166. Xstatic long total_bytes_medium = 0;    /* total bytes requested */
  167. Xstatic long cur_num_medium = 0;        /* # currently alloced */
  168. Xstatic long max_num_medium = 0;        /* max simultaneously alloced */
  169. X#endif
  170. X
  171. Xstatic long total_num_sarray = 0;    /* total # of sarray objects alloced */
  172. Xstatic long total_bytes_sarray = 0;    /* total bytes requested */
  173. Xstatic long cur_num_sarray = 0;        /* # currently alloced */
  174. Xstatic long max_num_sarray = 0;        /* max simultaneously alloced */
  175. X
  176. Xstatic long total_num_barray = 0;    /* total # of barray objects alloced */
  177. Xstatic long total_bytes_barray = 0;    /* total bytes requested */
  178. Xstatic long cur_num_barray = 0;        /* # currently alloced */
  179. Xstatic long max_num_barray = 0;        /* max simultaneously alloced */
  180. X
  181. X
  182. XLOCAL void
  183. Xprint_mem_stats (void)
  184. X{
  185. X  /* since this is only a debugging stub, we can cheat a little on the
  186. X   * trace message mechanism... helpful 'cuz trace_message can't handle longs.
  187. X   */
  188. X  fprintf(stderr, "total_num_small = %ld\n", total_num_small);
  189. X  fprintf(stderr, "total_bytes_small = %ld\n", total_bytes_small);
  190. X  if (cur_num_small)
  191. X    fprintf(stderr, "cur_num_small = %ld\n", cur_num_small);
  192. X  fprintf(stderr, "max_num_small = %ld\n", max_num_small);
  193. X  
  194. X#ifdef NEED_ALLOC_MEDIUM
  195. X  fprintf(stderr, "total_num_medium = %ld\n", total_num_medium);
  196. X  fprintf(stderr, "total_bytes_medium = %ld\n", total_bytes_medium);
  197. X  if (cur_num_medium)
  198. X    fprintf(stderr, "cur_num_medium = %ld\n", cur_num_medium);
  199. X  fprintf(stderr, "max_num_medium = %ld\n", max_num_medium);
  200. X#endif
  201. X  
  202. X  fprintf(stderr, "total_num_sarray = %ld\n", total_num_sarray);
  203. X  fprintf(stderr, "total_bytes_sarray = %ld\n", total_bytes_sarray);
  204. X  if (cur_num_sarray)
  205. X    fprintf(stderr, "cur_num_sarray = %ld\n", cur_num_sarray);
  206. X  fprintf(stderr, "max_num_sarray = %ld\n", max_num_sarray);
  207. X  
  208. X  fprintf(stderr, "total_num_barray = %ld\n", total_num_barray);
  209. X  fprintf(stderr, "total_bytes_barray = %ld\n", total_bytes_barray);
  210. X  if (cur_num_barray)
  211. X    fprintf(stderr, "cur_num_barray = %ld\n", cur_num_barray);
  212. X  fprintf(stderr, "max_num_barray = %ld\n", max_num_barray);
  213. X}
  214. X
  215. X#endif /* MEM_STATS */
  216. X
  217. X
  218. XLOCAL void
  219. Xout_of_memory (int which)
  220. X/* Report an out-of-memory error and stop execution */
  221. X/* If we compiled MEM_STATS support, report alloc requests before dying */
  222. X{
  223. X#ifdef MEM_STATS
  224. X  if (methods->trace_level <= 0) /* don't do it if free_all() will */
  225. X    print_mem_stats();        /* print optional memory usage statistics */
  226. X#endif
  227. X  ERREXIT1(methods, "Insufficient memory (case %d)", which);
  228. X}
  229. X
  230. X
  231. X/*
  232. X * Management of "small" objects.
  233. X * These are all-in-memory, and are in near-heap space on an 80x86.
  234. X */
  235. X
  236. Xtypedef struct small_struct * small_ptr;
  237. X
  238. Xtypedef struct small_struct {
  239. X    small_ptr next;        /* next in list of allocated objects */
  240. X      } small_hdr;
  241. X
  242. Xstatic small_ptr small_list;    /* head of list */
  243. X
  244. X
  245. XMETHODDEF void *
  246. Xalloc_small (size_t sizeofobject)
  247. X/* Allocate a "small" object */
  248. X{
  249. X  small_ptr result;
  250. X
  251. X  sizeofobject += SIZEOF(small_hdr); /* add space for header */
  252. X
  253. X#ifdef MEM_STATS
  254. X  total_num_small++;
  255. X  total_bytes_small += sizeofobject + MALLOC_OVERHEAD;
  256. X  cur_num_small++;
  257. X  if (cur_num_small > max_num_small) max_num_small = cur_num_small;
  258. X#endif
  259. X
  260. X  result = (small_ptr) jget_small(sizeofobject);
  261. X  if (result == NULL)
  262. X    out_of_memory(1);
  263. X
  264. X  result->next = small_list;
  265. X  small_list = result;
  266. X  result++;            /* advance past header */
  267. X
  268. X  return (void *) result;
  269. X}
  270. X
  271. X
  272. XMETHODDEF void
  273. Xfree_small (void *ptr)
  274. X/* Free a "small" object */
  275. X{
  276. X  small_ptr hdr;
  277. X  small_ptr * llink;
  278. X
  279. X  hdr = (small_ptr) ptr;
  280. X  hdr--;            /* point back to header */
  281. X
  282. X  /* Remove item from list -- linear search is fast enough */
  283. X  llink = &small_list;
  284. X  while (*llink != hdr) {
  285. X    if (*llink == NULL)
  286. X      ERREXIT(methods, "Bogus free_small request");
  287. X    llink = &( (*llink)->next );
  288. X  }
  289. X  *llink = hdr->next;
  290. X
  291. X  jfree_small((void *) hdr);
  292. X
  293. X#ifdef MEM_STATS
  294. X  cur_num_small--;
  295. X#endif
  296. X}
  297. X
  298. X
  299. X/*
  300. X * Management of "medium-size" objects.
  301. X * These are just like small objects except they are in the FAR heap.
  302. X */
  303. X
  304. X#ifdef NEED_ALLOC_MEDIUM
  305. X
  306. Xtypedef struct medium_struct FAR * medium_ptr;
  307. X
  308. Xtypedef struct medium_struct {
  309. X    medium_ptr next;    /* next in list of allocated objects */
  310. X      } medium_hdr;
  311. X
  312. Xstatic medium_ptr medium_list;    /* head of list */
  313. X
  314. X
  315. XMETHODDEF void FAR *
  316. Xalloc_medium (size_t sizeofobject)
  317. X/* Allocate a "medium-size" object */
  318. X{
  319. X  medium_ptr result;
  320. X
  321. X  sizeofobject += SIZEOF(medium_hdr); /* add space for header */
  322. X
  323. X#ifdef MEM_STATS
  324. X  total_num_medium++;
  325. X  total_bytes_medium += sizeofobject + MALLOC_FAR_OVERHEAD;
  326. X  cur_num_medium++;
  327. X  if (cur_num_medium > max_num_medium) max_num_medium = cur_num_medium;
  328. X#endif
  329. X
  330. X  result = (medium_ptr) jget_large(sizeofobject);
  331. X  if (result == NULL)
  332. X    out_of_memory(2);
  333. X
  334. X  result->next = medium_list;
  335. X  medium_list = result;
  336. X  result++;            /* advance past header */
  337. X
  338. X  return (void FAR *) result;
  339. X}
  340. X
  341. X
  342. XMETHODDEF void
  343. Xfree_medium (void FAR *ptr)
  344. X/* Free a "medium-size" object */
  345. X{
  346. X  medium_ptr hdr;
  347. X  medium_ptr FAR * llink;
  348. X
  349. X  hdr = (medium_ptr) ptr;
  350. X  hdr--;            /* point back to header */
  351. X
  352. X  /* Remove item from list -- linear search is fast enough */
  353. X  llink = &medium_list;
  354. X  while (*llink != hdr) {
  355. X    if (*llink == NULL)
  356. X      ERREXIT(methods, "Bogus free_medium request");
  357. X    llink = &( (*llink)->next );
  358. X  }
  359. X  *llink = hdr->next;
  360. X
  361. X  jfree_large((void FAR *) hdr);
  362. X
  363. X#ifdef MEM_STATS
  364. X  cur_num_medium--;
  365. X#endif
  366. X}
  367. X
  368. X#endif /* NEED_ALLOC_MEDIUM */
  369. X
  370. X
  371. X/*
  372. X * Management of "small" (all-in-memory) 2-D sample arrays.
  373. X * The pointers are in near heap, the samples themselves in FAR heap.
  374. X * The header structure is adjacent to the row pointers.
  375. X * To minimize allocation overhead and to allow I/O of large contiguous
  376. X * blocks, we allocate the sample rows in groups of as many rows as possible
  377. X * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
  378. X * Note that the big-array control routines, later in this file, know about
  379. X * this chunking of rows ... and also how to get the rowsperchunk value!
  380. X */
  381. X
  382. Xtypedef struct small_sarray_struct * small_sarray_ptr;
  383. X
  384. Xtypedef struct small_sarray_struct {
  385. X    small_sarray_ptr next;    /* next in list of allocated sarrays */
  386. X    long numrows;        /* # of rows in this array */
  387. X    long rowsperchunk;    /* max # of rows per allocation chunk */
  388. X      } small_sarray_hdr;
  389. X
  390. Xstatic small_sarray_ptr small_sarray_list; /* head of list */
  391. X
  392. X
  393. XMETHODDEF JSAMPARRAY
  394. Xalloc_small_sarray (long samplesperrow, long numrows)
  395. X/* Allocate a "small" (all-in-memory) 2-D sample array */
  396. X{
  397. X  small_sarray_ptr hdr;
  398. X  JSAMPARRAY result;
  399. X  JSAMPROW workspace;
  400. X  long rowsperchunk, currow, i;
  401. X
  402. X#ifdef MEM_STATS
  403. X  total_num_sarray++;
  404. X  cur_num_sarray++;
  405. X  if (cur_num_sarray > max_num_sarray) max_num_sarray = cur_num_sarray;
  406. X#endif
  407. X
  408. X  /* Calculate max # of rows allowed in one allocation chunk */
  409. X  rowsperchunk = MAX_ALLOC_CHUNK / (samplesperrow * SIZEOF(JSAMPLE));
  410. X  if (rowsperchunk <= 0)
  411. X      ERREXIT(methods, "Image too wide for this implementation");
  412. X
  413. X  /* Get space for header and row pointers; this is always "near" on 80x86 */
  414. X  hdr = (small_sarray_ptr) alloc_small((size_t) (numrows * SIZEOF(JSAMPROW)
  415. X                         + SIZEOF(small_sarray_hdr)));
  416. X
  417. X  result = (JSAMPARRAY) (hdr+1); /* advance past header */
  418. X
  419. X  /* Insert into list now so free_all does right thing if I fail */
  420. X  /* after allocating only some of the rows... */
  421. X  hdr->next = small_sarray_list;
  422. X  hdr->numrows = 0;
  423. X  hdr->rowsperchunk = rowsperchunk;
  424. X  small_sarray_list = hdr;
  425. X
  426. X  /* Get the rows themselves; on 80x86 these are "far" */
  427. X  currow = 0;
  428. X  while (currow < numrows) {
  429. X    rowsperchunk = MIN(rowsperchunk, numrows - currow);
  430. X#ifdef MEM_STATS
  431. X    total_bytes_sarray += rowsperchunk * samplesperrow * SIZEOF(JSAMPLE)
  432. X              + MALLOC_FAR_OVERHEAD;
  433. X#endif
  434. X    workspace = (JSAMPROW) jget_large((size_t) (rowsperchunk * samplesperrow
  435. X                        * SIZEOF(JSAMPLE)));
  436. X    if (workspace == NULL)
  437. X      out_of_memory(3);
  438. X    for (i = rowsperchunk; i > 0; i--) {
  439. X      result[currow++] = workspace;
  440. X      workspace += samplesperrow;
  441. X    }
  442. X    hdr->numrows = currow;
  443. X  }
  444. X
  445. X  return result;
  446. X}
  447. X
  448. X
  449. XMETHODDEF void
  450. Xfree_small_sarray (JSAMPARRAY ptr)
  451. X/* Free a "small" (all-in-memory) 2-D sample array */
  452. X{
  453. X  small_sarray_ptr hdr;
  454. X  small_sarray_ptr * llink;
  455. X  long i;
  456. X
  457. X  hdr = (small_sarray_ptr) ptr;
  458. X  hdr--;            /* point back to header */
  459. X
  460. X  /* Remove item from list -- linear search is fast enough */
  461. X  llink = &small_sarray_list;
  462. X  while (*llink != hdr) {
  463. X    if (*llink == NULL)
  464. X      ERREXIT(methods, "Bogus free_small_sarray request");
  465. X    llink = &( (*llink)->next );
  466. X  }
  467. X  *llink = hdr->next;
  468. X
  469. X  /* Free the rows themselves; on 80x86 these are "far" */
  470. X  /* Note we only free the row-group headers! */
  471. X  for (i = 0; i < hdr->numrows; i += hdr->rowsperchunk) {
  472. X    jfree_large((void FAR *) ptr[i]);
  473. X  }
  474. X
  475. X  /* Free header and row pointers */
  476. X  free_small((void *) hdr);
  477. X
  478. X#ifdef MEM_STATS
  479. X  cur_num_sarray--;
  480. X#endif
  481. X}
  482. X
  483. X
  484. X/*
  485. X * Management of "small" (all-in-memory) 2-D coefficient-block arrays.
  486. X * This is essentially the same as the code for sample arrays, above.
  487. X */
  488. X
  489. Xtypedef struct small_barray_struct * small_barray_ptr;
  490. X
  491. Xtypedef struct small_barray_struct {
  492. X    small_barray_ptr next;    /* next in list of allocated barrays */
  493. X    long numrows;        /* # of rows in this array */
  494. X    long rowsperchunk;    /* max # of rows per allocation chunk */
  495. X      } small_barray_hdr;
  496. X
  497. Xstatic small_barray_ptr small_barray_list; /* head of list */
  498. X
  499. X
  500. XMETHODDEF JBLOCKARRAY
  501. Xalloc_small_barray (long blocksperrow, long numrows)
  502. X/* Allocate a "small" (all-in-memory) 2-D coefficient-block array */
  503. X{
  504. X  small_barray_ptr hdr;
  505. X  JBLOCKARRAY result;
  506. X  JBLOCKROW workspace;
  507. X  long rowsperchunk, currow, i;
  508. X
  509. X#ifdef MEM_STATS
  510. X  total_num_barray++;
  511. X  cur_num_barray++;
  512. X  if (cur_num_barray > max_num_barray) max_num_barray = cur_num_barray;
  513. X#endif
  514. X
  515. X  /* Calculate max # of rows allowed in one allocation chunk */
  516. X  rowsperchunk = MAX_ALLOC_CHUNK / (blocksperrow * SIZEOF(JBLOCK));
  517. X  if (rowsperchunk <= 0)
  518. X      ERREXIT(methods, "Image too wide for this implementation");
  519. X
  520. X  /* Get space for header and row pointers; this is always "near" on 80x86 */
  521. X  hdr = (small_barray_ptr) alloc_small((size_t) (numrows * SIZEOF(JBLOCKROW)
  522. X                         + SIZEOF(small_barray_hdr)));
  523. X
  524. X  result = (JBLOCKARRAY) (hdr+1); /* advance past header */
  525. X
  526. X  /* Insert into list now so free_all does right thing if I fail */
  527. X  /* after allocating only some of the rows... */
  528. X  hdr->next = small_barray_list;
  529. X  hdr->numrows = 0;
  530. X  hdr->rowsperchunk = rowsperchunk;
  531. X  small_barray_list = hdr;
  532. X
  533. X  /* Get the rows themselves; on 80x86 these are "far" */
  534. X  currow = 0;
  535. X  while (currow < numrows) {
  536. X    rowsperchunk = MIN(rowsperchunk, numrows - currow);
  537. X#ifdef MEM_STATS
  538. X    total_bytes_barray += rowsperchunk * blocksperrow * SIZEOF(JBLOCK)
  539. X              + MALLOC_FAR_OVERHEAD;
  540. X#endif
  541. X    workspace = (JBLOCKROW) jget_large((size_t) (rowsperchunk * blocksperrow
  542. X                         * SIZEOF(JBLOCK)));
  543. X    if (workspace == NULL)
  544. X      out_of_memory(4);
  545. X    for (i = rowsperchunk; i > 0; i--) {
  546. X      result[currow++] = workspace;
  547. X      workspace += blocksperrow;
  548. X    }
  549. X    hdr->numrows = currow;
  550. X  }
  551. X
  552. X  return result;
  553. X}
  554. X
  555. X
  556. XMETHODDEF void
  557. Xfree_small_barray (JBLOCKARRAY ptr)
  558. X/* Free a "small" (all-in-memory) 2-D coefficient-block array */
  559. X{
  560. X  small_barray_ptr hdr;
  561. X  small_barray_ptr * llink;
  562. X  long i;
  563. X
  564. X  hdr = (small_barray_ptr) ptr;
  565. X  hdr--;            /* point back to header */
  566. X
  567. X  /* Remove item from list -- linear search is fast enough */
  568. X  llink = &small_barray_list;
  569. X  while (*llink != hdr) {
  570. X    if (*llink == NULL)
  571. X      ERREXIT(methods, "Bogus free_small_barray request");
  572. X    llink = &( (*llink)->next );
  573. X  }
  574. X  *llink = hdr->next;
  575. X
  576. X  /* Free the rows themselves; on 80x86 these are "far" */
  577. X  /* Note we only free the row-group headers! */
  578. X  for (i = 0; i < hdr->numrows; i += hdr->rowsperchunk) {
  579. X    jfree_large((void FAR *) ptr[i]);
  580. X  }
  581. X
  582. X  /* Free header and row pointers */
  583. X  free_small((void *) hdr);
  584. X
  585. X#ifdef MEM_STATS
  586. X  cur_num_barray--;
  587. X#endif
  588. X}
  589. X
  590. X
  591. X
  592. X/*
  593. X * About "big" array management:
  594. X *
  595. X * To allow machines with limited memory to handle large images,
  596. X * all processing in the JPEG system is done a few pixel or block rows
  597. X * at a time.  The above "small" array routines are only used to allocate
  598. X * strip buffers (as wide as the image, but just a few rows high).
  599. X * In some cases multiple passes must be made over the data.  In these
  600. X * cases the "big" array routines are used.  The array is still accessed
  601. X * a strip at a time, but the memory manager must save the whole array
  602. X * for repeated accesses.  The intended implementation is that there is
  603. X * a strip buffer in memory (as high as is possible given the desired memory
  604. X * limit), plus a backing file that holds the rest of the array.
  605. X *
  606. X * The request_big_array routines are told the total size of the image (in case
  607. X * it is useful to know the total file size that will be needed).  They are
  608. X * also given the unit height, which is the number of rows that will be
  609. X * accessed at once; the in-memory buffer should be made a multiple of
  610. X * this height for best efficiency.
  611. X *
  612. X * The request routines create control blocks (and may open backing files),
  613. X * but they don't create the in-memory buffers.  This is postponed until
  614. X * alloc_big_arrays is called.  At that time the total amount of space needed
  615. X * is known (approximately, anyway), so free memory can be divided up fairly.
  616. X *
  617. X * The access_big_array routines are responsible for making a specific strip
  618. X * area accessible (after reading or writing the backing file, if necessary).
  619. X * Note that the access routines are told whether the caller intends to modify
  620. X * the accessed strip; during a read-only pass this saves having to rewrite
  621. X * data to disk.
  622. X *
  623. X * The typical access pattern is one top-to-bottom pass to write the data,
  624. X * followed by one or more read-only top-to-bottom passes.  However, other
  625. X * access patterns may occur while reading.  For example, translation of image
  626. X * formats that use bottom-to-top scan order will require bottom-to-top read
  627. X * passes.  The memory manager need not support multiple write passes nor
  628. X * funny write orders (meaning that rearranging rows must be handled while
  629. X * reading data out of the big array, not while putting it in).
  630. X *
  631. X * In current usage, the access requests are always for nonoverlapping strips;
  632. X * that is, successive access start_row numbers always differ by exactly the
  633. X * unitheight.  This allows fairly simple buffer dump/reload logic if the
  634. X * in-memory buffer is made a multiple of the unitheight.  It would be
  635. X * possible to keep subsampled rather than fullsize data in the "big" arrays,
  636. X * thus reducing temp file size, if we supported overlapping strip access
  637. X * (access requests differing by less than the unitheight).  At the moment
  638. X * I don't believe this is worth the extra complexity.
  639. X */
  640. X
  641. X
  642. X
  643. X/* The control blocks for virtual arrays.
  644. X * System-dependent info for the associated backing store is hidden inside
  645. X * the backing_store_info struct.
  646. X */
  647. X
  648. Xstruct big_sarray_control {
  649. X    long rows_in_array;    /* total virtual array height */
  650. X    long samplesperrow;    /* width of array (and of memory buffer) */
  651. X    long unitheight;    /* # of rows accessed by access_big_sarray() */
  652. X    JSAMPARRAY mem_buffer;    /* the in-memory buffer */
  653. X    long rows_in_mem;    /* height of memory buffer */
  654. X    long rowsperchunk;    /* allocation chunk size in mem_buffer */
  655. X    long cur_start_row;    /* first logical row # in the buffer */
  656. X    boolean dirty;        /* do current buffer contents need written? */
  657. X    boolean b_s_open;    /* is backing-store data valid? */
  658. X    big_sarray_ptr next;    /* link to next big sarray control block */
  659. X    backing_store_info b_s_info; /* System-dependent control info */
  660. X};
  661. X
  662. Xstatic big_sarray_ptr big_sarray_list; /* head of list */
  663. X
  664. Xstruct big_barray_control {
  665. X    long rows_in_array;    /* total virtual array height */
  666. X    long blocksperrow;    /* width of array (and of memory buffer) */
  667. X    long unitheight;    /* # of rows accessed by access_big_barray() */
  668. X    JBLOCKARRAY mem_buffer;    /* the in-memory buffer */
  669. X    long rows_in_mem;    /* height of memory buffer */
  670. X    long rowsperchunk;    /* allocation chunk size in mem_buffer */
  671. X    long cur_start_row;    /* first logical row # in the buffer */
  672. X    boolean dirty;        /* do current buffer contents need written? */
  673. X    boolean b_s_open;    /* is backing-store data valid? */
  674. X    big_barray_ptr next;    /* link to next big barray control block */
  675. X    backing_store_info b_s_info; /* System-dependent control info */
  676. X};
  677. X
  678. Xstatic big_barray_ptr big_barray_list; /* head of list */
  679. X
  680. X
  681. XMETHODDEF big_sarray_ptr
  682. Xrequest_big_sarray (long samplesperrow, long numrows, long unitheight)
  683. X/* Request a "big" (virtual-memory) 2-D sample array */
  684. X{
  685. X  big_sarray_ptr result;
  686. X
  687. X  /* get control block */
  688. X  result = (big_sarray_ptr) alloc_small(SIZEOF(struct big_sarray_control));
  689. X
  690. X  result->rows_in_array = numrows;
  691. X  result->samplesperrow = samplesperrow;
  692. X  result->unitheight = unitheight;
  693. X  result->mem_buffer = NULL;    /* marks array not yet realized */
  694. X  result->b_s_open = FALSE;    /* no associated backing-store object */
  695. X  result->next = big_sarray_list; /* add to list of big arrays */
  696. X  big_sarray_list = result;
  697. X
  698. X  return result;
  699. X}
  700. X
  701. X
  702. XMETHODDEF big_barray_ptr
  703. Xrequest_big_barray (long blocksperrow, long numrows, long unitheight)
  704. X/* Request a "big" (virtual-memory) 2-D coefficient-block array */
  705. X{
  706. X  big_barray_ptr result;
  707. X
  708. X  /* get control block */
  709. X  result = (big_barray_ptr) alloc_small(SIZEOF(struct big_barray_control));
  710. X
  711. X  result->rows_in_array = numrows;
  712. X  result->blocksperrow = blocksperrow;
  713. X  result->unitheight = unitheight;
  714. X  result->mem_buffer = NULL;    /* marks array not yet realized */
  715. X  result->b_s_open = FALSE;    /* no associated backing-store object */
  716. X  result->next = big_barray_list; /* add to list of big arrays */
  717. X  big_barray_list = result;
  718. X
  719. X  return result;
  720. X}
  721. X
  722. X
  723. XMETHODDEF void
  724. Xalloc_big_arrays (long extra_small_samples, long extra_small_blocks,
  725. X          long extra_medium_space)
  726. X/* Allocate the in-memory buffers for any unrealized "big" arrays */
  727. X/* 'extra' values are upper bounds for total future small-array requests */
  728. X/* and far-heap requests */
  729. X{
  730. X  long total_extra_space = extra_small_samples * SIZEOF(JSAMPLE)
  731. X               + extra_small_blocks * SIZEOF(JBLOCK)
  732. X               + extra_medium_space;
  733. X  long space_per_unitheight, maximum_space, avail_mem;
  734. X  long unitheights, max_unitheights;
  735. X  big_sarray_ptr sptr;
  736. X  big_barray_ptr bptr;
  737. X
  738. X  /* Compute the minimum space needed (unitheight rows in each buffer)
  739. X   * and the maximum space needed (full image height in each buffer).
  740. X   * These may be of use to the system-dependent jmem_available routine.
  741. X   */
  742. X  space_per_unitheight = 0;
  743. X  maximum_space = total_extra_space;
  744. X  for (sptr = big_sarray_list; sptr != NULL; sptr = sptr->next) {
  745. X    if (sptr->mem_buffer == NULL) { /* if not realized yet */
  746. X      space_per_unitheight += sptr->unitheight *
  747. X                  sptr->samplesperrow * SIZEOF(JSAMPLE);
  748. X      maximum_space += sptr->rows_in_array *
  749. X               sptr->samplesperrow * SIZEOF(JSAMPLE);
  750. X    }
  751. X  }
  752. X  for (bptr = big_barray_list; bptr != NULL; bptr = bptr->next) {
  753. X    if (bptr->mem_buffer == NULL) { /* if not realized yet */
  754. X      space_per_unitheight += bptr->unitheight *
  755. X                  bptr->blocksperrow * SIZEOF(JBLOCK);
  756. X      maximum_space += bptr->rows_in_array *
  757. X               bptr->blocksperrow * SIZEOF(JBLOCK);
  758. X    }
  759. X  }
  760. X
  761. X  if (space_per_unitheight <= 0)
  762. X    return;            /* no unrealized arrays, no work */
  763. X
  764. X  /* Determine amount of memory to actually use; this is system-dependent. */
  765. X  avail_mem = jmem_available(space_per_unitheight + total_extra_space,
  766. X                 maximum_space);
  767. X
  768. X  /* If the maximum space needed is available, make all the buffers full
  769. X   * height; otherwise parcel it out with the same number of unitheights
  770. X   * in each buffer.
  771. X   */
  772. X  if (avail_mem >= maximum_space)
  773. X    max_unitheights = 1000000000L;
  774. X  else {
  775. X    max_unitheights = (avail_mem - total_extra_space) / space_per_unitheight;
  776. X    /* If there doesn't seem to be enough space, try to get the minimum
  777. X     * anyway.  This allows a "stub" implementation of jmem_available().
  778. X     */
  779. X    if (max_unitheights <= 0)
  780. X      max_unitheights = 1;
  781. X  }
  782. X
  783. X  /* Allocate the in-memory buffers and initialize backing store as needed. */
  784. X
  785. X  for (sptr = big_sarray_list; sptr != NULL; sptr = sptr->next) {
  786. X    if (sptr->mem_buffer == NULL) { /* if not realized yet */
  787. X      unitheights = (sptr->rows_in_array + sptr->unitheight - 1L)
  788. X            / sptr->unitheight;
  789. X      if (unitheights <= max_unitheights) {
  790. X    /* This buffer fits in memory */
  791. X    sptr->rows_in_mem = sptr->rows_in_array;
  792. X      } else {
  793. X    /* It doesn't fit in memory, create backing store. */
  794. X    sptr->rows_in_mem = max_unitheights * sptr->unitheight;
  795. X    jopen_backing_store(& sptr->b_s_info,
  796. X                sptr->rows_in_array
  797. X                * sptr->samplesperrow * SIZEOF(JSAMPLE));
  798. X    sptr->b_s_open = TRUE;
  799. X      }
  800. X      sptr->mem_buffer = alloc_small_sarray(sptr->samplesperrow,
  801. X                        sptr->rows_in_mem);
  802. X      /* Reach into the small_sarray header and get the rowsperchunk field.
  803. X       * Yes, I know, this is horrible coding practice.
  804. X       */
  805. X      sptr->rowsperchunk =
  806. X    ((small_sarray_ptr) sptr->mem_buffer)[-1].rowsperchunk;
  807. X      sptr->cur_start_row = 0;
  808. X      sptr->dirty = FALSE;
  809. X    }
  810. X  }
  811. X
  812. X  for (bptr = big_barray_list; bptr != NULL; bptr = bptr->next) {
  813. X    if (bptr->mem_buffer == NULL) { /* if not realized yet */
  814. X      unitheights = (bptr->rows_in_array + bptr->unitheight - 1L)
  815. X            / bptr->unitheight;
  816. X      if (unitheights <= max_unitheights) {
  817. X    /* This buffer fits in memory */
  818. X    bptr->rows_in_mem = bptr->rows_in_array;
  819. X      } else {
  820. X    /* It doesn't fit in memory, create backing store. */
  821. X    bptr->rows_in_mem = max_unitheights * bptr->unitheight;
  822. X    jopen_backing_store(& bptr->b_s_info,
  823. X                bptr->rows_in_array
  824. X                * bptr->blocksperrow * SIZEOF(JBLOCK));
  825. X    bptr->b_s_open = TRUE;
  826. X      }
  827. X      bptr->mem_buffer = alloc_small_barray(bptr->blocksperrow,
  828. X                        bptr->rows_in_mem);
  829. X      /* Reach into the small_barray header and get the rowsperchunk field. */
  830. X      bptr->rowsperchunk =
  831. X    ((small_barray_ptr) bptr->mem_buffer)[-1].rowsperchunk;
  832. X      bptr->cur_start_row = 0;
  833. X      bptr->dirty = FALSE;
  834. X    }
  835. X  }
  836. X}
  837. X
  838. X
  839. XLOCAL void
  840. Xdo_sarray_io (big_sarray_ptr ptr, boolean writing)
  841. X/* Do backing store read or write of a "big" sample array */
  842. X{
  843. X  long bytesperrow, file_offset, byte_count, rows, i;
  844. X
  845. X  bytesperrow = ptr->samplesperrow * SIZEOF(JSAMPLE);
  846. X  file_offset = ptr->cur_start_row * bytesperrow;
  847. X  /* Loop to read or write each allocation chunk in mem_buffer */
  848. X  for (i = 0; i < ptr->rows_in_mem; i += ptr->rowsperchunk) {
  849. X    /* One chunk, but check for short chunk at end of buffer */
  850. X    rows = MIN(ptr->rowsperchunk, ptr->rows_in_mem - i);
  851. X    /* Transfer no more than fits in file */
  852. X    rows = MIN(rows, ptr->rows_in_array - (ptr->cur_start_row + i));
  853. X    if (rows <= 0)        /* this chunk might be past end of file! */
  854. X      break;
  855. X    byte_count = rows * bytesperrow;
  856. X    if (writing)
  857. X      (*ptr->b_s_info.write_backing_store) (& ptr->b_s_info,
  858. X                        (void FAR *) ptr->mem_buffer[i],
  859. X                        file_offset, byte_count);
  860. X    else
  861. X      (*ptr->b_s_info.read_backing_store) (& ptr->b_s_info,
  862. X                       (void FAR *) ptr->mem_buffer[i],
  863. X                       file_offset, byte_count);
  864. X    file_offset += byte_count;
  865. X  }
  866. X}
  867. X
  868. X
  869. XLOCAL void
  870. Xdo_barray_io (big_barray_ptr ptr, boolean writing)
  871. X/* Do backing store read or write of a "big" coefficient-block array */
  872. X{
  873. X  long bytesperrow, file_offset, byte_count, rows, i;
  874. X
  875. X  bytesperrow = ptr->blocksperrow * SIZEOF(JBLOCK);
  876. X  file_offset = ptr->cur_start_row * bytesperrow;
  877. X  /* Loop to read or write each allocation chunk in mem_buffer */
  878. X  for (i = 0; i < ptr->rows_in_mem; i += ptr->rowsperchunk) {
  879. X    /* One chunk, but check for short chunk at end of buffer */
  880. X    rows = MIN(ptr->rowsperchunk, ptr->rows_in_mem - i);
  881. X    /* Transfer no more than fits in file */
  882. X    rows = MIN(rows, ptr->rows_in_array - (ptr->cur_start_row + i));
  883. X    if (rows <= 0)        /* this chunk might be past end of file! */
  884. X      break;
  885. X    byte_count = rows * bytesperrow;
  886. X    if (writing)
  887. X      (*ptr->b_s_info.write_backing_store) (& ptr->b_s_info,
  888. X                        (void FAR *) ptr->mem_buffer[i],
  889. X                        file_offset, byte_count);
  890. X    else
  891. X      (*ptr->b_s_info.read_backing_store) (& ptr->b_s_info,
  892. X                       (void FAR *) ptr->mem_buffer[i],
  893. X                       file_offset, byte_count);
  894. X    file_offset += byte_count;
  895. X  }
  896. X}
  897. X
  898. X
  899. XMETHODDEF JSAMPARRAY
  900. Xaccess_big_sarray (big_sarray_ptr ptr, long start_row, boolean writable)
  901. X/* Access the part of a "big" sample array starting at start_row */
  902. X/* and extending for ptr->unitheight rows.  writable is true if  */
  903. X/* caller intends to modify the accessed area. */
  904. X{
  905. X  /* debugging check */
  906. X  if (start_row < 0 || start_row+ptr->unitheight > ptr->rows_in_array ||
  907. X      ptr->mem_buffer == NULL)
  908. X    ERREXIT(methods, "Bogus access_big_sarray request");
  909. X
  910. X  /* Make the desired part of the virtual array accessible */
  911. X  if (start_row < ptr->cur_start_row ||
  912. X      start_row+ptr->unitheight > ptr->cur_start_row+ptr->rows_in_mem) {
  913. X    if (! ptr->b_s_open)
  914. X      ERREXIT(methods, "Virtual array controller messed up");
  915. X    /* Flush old buffer contents if necessary */
  916. X    if (ptr->dirty) {
  917. X      do_sarray_io(ptr, TRUE);
  918. X      ptr->dirty = FALSE;
  919. X    }
  920. X    /* Decide what part of virtual array to access.
  921. X     * Algorithm: if target address > current window, assume forward scan,
  922. X     * load starting at target address.  If target address < current window,
  923. X     * assume backward scan, load so that target address is top of window.
  924. X     * Note that when switching from forward write to forward read, will have
  925. X     * start_row = 0, so the limiting case applies and we load from 0 anyway.
  926. X     */
  927. X    if (start_row > ptr->cur_start_row) {
  928. X      ptr->cur_start_row = start_row;
  929. X    } else {
  930. X      ptr->cur_start_row = start_row + ptr->unitheight - ptr->rows_in_mem;
  931. X      if (ptr->cur_start_row < 0)
  932. X    ptr->cur_start_row = 0;    /* don't fall off front end of file */
  933. X    }
  934. X    /* If reading, read in the selected part of the array. 
  935. X     * If we are writing, we need not pre-read the selected portion,
  936. X     * since the access sequence constraints ensure it would be garbage.
  937. X     */
  938. X    if (! writable) {
  939. X      do_sarray_io(ptr, FALSE);
  940. X    }
  941. X  }
  942. X  /* Flag the buffer dirty if caller will write in it */
  943. X  if (writable)
  944. X    ptr->dirty = TRUE;
  945. X  /* Return address of proper part of the buffer */
  946. X  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
  947. X}
  948. X
  949. X
  950. XMETHODDEF JBLOCKARRAY
  951. Xaccess_big_barray (big_barray_ptr ptr, long start_row, boolean writable)
  952. X/* Access the part of a "big" coefficient-block array starting at start_row */
  953. X/* and extending for ptr->unitheight rows.  writable is true if  */
  954. X/* caller intends to modify the accessed area. */
  955. X{
  956. X  /* debugging check */
  957. X  if (start_row < 0 || start_row+ptr->unitheight > ptr->rows_in_array ||
  958. X      ptr->mem_buffer == NULL)
  959. X    ERREXIT(methods, "Bogus access_big_barray request");
  960. X
  961. X  /* Make the desired part of the virtual array accessible */
  962. X  if (start_row < ptr->cur_start_row ||
  963. X      start_row+ptr->unitheight > ptr->cur_start_row+ptr->rows_in_mem) {
  964. X    if (! ptr->b_s_open)
  965. X      ERREXIT(methods, "Virtual array controller messed up");
  966. X    /* Flush old buffer contents if necessary */
  967. X    if (ptr->dirty) {
  968. X      do_barray_io(ptr, TRUE);
  969. X      ptr->dirty = FALSE;
  970. X    }
  971. X    /* Decide what part of virtual array to access.
  972. X     * Algorithm: if target address > current window, assume forward scan,
  973. X     * load starting at target address.  If target address < current window,
  974. X     * assume backward scan, load so that target address is top of window.
  975. X     * Note that when switching from forward write to forward read, will have
  976. X     * start_row = 0, so the limiting case applies and we load from 0 anyway.
  977. X     */
  978. X    if (start_row > ptr->cur_start_row) {
  979. X      ptr->cur_start_row = start_row;
  980. X    } else {
  981. X      ptr->cur_start_row = start_row + ptr->unitheight - ptr->rows_in_mem;
  982. X      if (ptr->cur_start_row < 0)
  983. X    ptr->cur_start_row = 0;    /* don't fall off front end of file */
  984. X    }
  985. X    /* If reading, read in the selected part of the array. 
  986. X     * If we are writing, we need not pre-read the selected portion,
  987. X     * since the access sequence constraints ensure it would be garbage.
  988. X     */
  989. X    if (! writable) {
  990. X      do_barray_io(ptr, FALSE);
  991. X    }
  992. X  }
  993. X  /* Flag the buffer dirty if caller will write in it */
  994. X  if (writable)
  995. X    ptr->dirty = TRUE;
  996. X  /* Return address of proper part of the buffer */
  997. X  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
  998. X}
  999. X
  1000. X
  1001. XMETHODDEF void
  1002. Xfree_big_sarray (big_sarray_ptr ptr)
  1003. X/* Free a "big" (virtual-memory) 2-D sample array */
  1004. X{
  1005. X  big_sarray_ptr * llink;
  1006. X
  1007. X  /* Remove item from list -- linear search is fast enough */
  1008. X  llink = &big_sarray_list;
  1009. X  while (*llink != ptr) {
  1010. X    if (*llink == NULL)
  1011. X      ERREXIT(methods, "Bogus free_big_sarray request");
  1012. X    llink = &( (*llink)->next );
  1013. X  }
  1014. X  *llink = ptr->next;
  1015. X
  1016. X  if (ptr->b_s_open)        /* there may be no backing store */
  1017. X    (*ptr->b_s_info.close_backing_store) (& ptr->b_s_info);
  1018. X
  1019. X  if (ptr->mem_buffer != NULL)    /* just in case never realized */
  1020. X    free_small_sarray(ptr->mem_buffer);
  1021. X
  1022. X  free_small((void *) ptr);    /* free the control block too */
  1023. X}
  1024. X
  1025. X
  1026. XMETHODDEF void
  1027. Xfree_big_barray (big_barray_ptr ptr)
  1028. X/* Free a "big" (virtual-memory) 2-D coefficient-block array */
  1029. X{
  1030. X  big_barray_ptr * llink;
  1031. X
  1032. X  /* Remove item from list -- linear search is fast enough */
  1033. X  llink = &big_barray_list;
  1034. X  while (*llink != ptr) {
  1035. X    if (*llink == NULL)
  1036. X      ERREXIT(methods, "Bogus free_big_barray request");
  1037. X    llink = &( (*llink)->next );
  1038. X  }
  1039. X  *llink = ptr->next;
  1040. X
  1041. X  if (ptr->b_s_open)        /* there may be no backing store */
  1042. X    (*ptr->b_s_info.close_backing_store) (& ptr->b_s_info);
  1043. X
  1044. X  if (ptr->mem_buffer != NULL)    /* just in case never realized */
  1045. X    free_small_barray(ptr->mem_buffer);
  1046. X
  1047. X  free_small((void *) ptr);    /* free the control block too */
  1048. X}
  1049. X
  1050. X
  1051. X/*
  1052. X * Cleanup: free anything that's been allocated since jselmemmgr().
  1053. X */
  1054. X
  1055. XMETHODDEF void
  1056. Xfree_all (void)
  1057. X{
  1058. X  /* First free any open "big" arrays -- these may release small arrays */
  1059. X  while (big_sarray_list != NULL)
  1060. X    free_big_sarray(big_sarray_list);
  1061. X  while (big_barray_list != NULL)
  1062. X    free_big_barray(big_barray_list);
  1063. X  /* Free any open small arrays -- these may release small objects */
  1064. X  /* +1's are because we must pass a pointer to the data, not the header */
  1065. X  while (small_sarray_list != NULL)
  1066. X    free_small_sarray((JSAMPARRAY) (small_sarray_list + 1));
  1067. X  while (small_barray_list != NULL)
  1068. X    free_small_barray((JBLOCKARRAY) (small_barray_list + 1));
  1069. X  /* Free any remaining small objects */
  1070. X  while (small_list != NULL)
  1071. X    free_small((void *) (small_list + 1));
  1072. X#ifdef NEED_ALLOC_MEDIUM
  1073. X  while (medium_list != NULL)
  1074. X    free_medium((void FAR *) (medium_list + 1));
  1075. X#endif
  1076. X
  1077. X  jmem_term();            /* system-dependent cleanup */
  1078. X
  1079. X#ifdef MEM_STATS
  1080. X  if (methods->trace_level > 0)
  1081. X    print_mem_stats();        /* print optional memory usage statistics */
  1082. X#endif
  1083. X}
  1084. X
  1085. X
  1086. X/*
  1087. X * The method selection routine for virtual memory systems.
  1088. X * The system-dependent setup routine should call this routine
  1089. X * to install the necessary method pointers in the supplied struct.
  1090. X */
  1091. X
  1092. XGLOBAL void
  1093. Xjselmemmgr (external_methods_ptr emethods)
  1094. X{
  1095. X  methods = emethods;        /* save struct addr for error exit access */
  1096. X
  1097. X  emethods->alloc_small = alloc_small;
  1098. X  emethods->free_small = free_small;
  1099. X#ifdef NEED_ALLOC_MEDIUM
  1100. X  emethods->alloc_medium = alloc_medium;
  1101. X  emethods->free_medium = free_medium;
  1102. X#else
  1103. X  emethods->alloc_medium = alloc_small;
  1104. X  emethods->free_medium = free_small;
  1105. X#endif
  1106. X  emethods->alloc_small_sarray = alloc_small_sarray;
  1107. X  emethods->free_small_sarray = free_small_sarray;
  1108. X  emethods->alloc_small_barray = alloc_small_barray;
  1109. X  emethods->free_small_barray = free_small_barray;
  1110. X  emethods->request_big_sarray = request_big_sarray;
  1111. X  emethods->request_big_barray = request_big_barray;
  1112. X  emethods->alloc_big_arrays = alloc_big_arrays;
  1113. X  emethods->access_big_sarray = access_big_sarray;
  1114. X  emethods->access_big_barray = access_big_barray;
  1115. X  emethods->free_big_sarray = free_big_sarray;
  1116. X  emethods->free_big_barray = free_big_barray;
  1117. X  emethods->free_all = free_all;
  1118. X
  1119. X  /* Initialize list headers to empty */
  1120. X  small_list = NULL;
  1121. X#ifdef NEED_ALLOC_MEDIUM
  1122. X  medium_list = NULL;
  1123. X#endif
  1124. X  small_sarray_list = NULL;
  1125. X  small_barray_list = NULL;
  1126. X  big_sarray_list = NULL;
  1127. X  big_barray_list = NULL;
  1128. X
  1129. X  jmem_init(emethods);        /* system-dependent initialization */
  1130. X}
  1131. END_OF_FILE
  1132.   if test 35862 -ne `wc -c <'jmemmgr.c'`; then
  1133.     echo shar: \"'jmemmgr.c'\" unpacked with wrong size!
  1134.   fi
  1135.   # end of 'jmemmgr.c'
  1136. fi
  1137. if test -f 'jrdtarga.c' -a "${1}" != "-c" ; then 
  1138.   echo shar: Will not clobber existing file \"'jrdtarga.c'\"
  1139. else
  1140.   echo shar: Extracting \"'jrdtarga.c'\" \(13177 characters\)
  1141.   sed "s/^X//" >'jrdtarga.c' <<'END_OF_FILE'
  1142. X/*
  1143. X * jrdtarga.c
  1144. X *
  1145. X * Copyright (C) 1991, 1992, Thomas G. Lane.
  1146. X * This file is part of the Independent JPEG Group's software.
  1147. X * For conditions of distribution and use, see the accompanying README file.
  1148. X *
  1149. X * This file contains routines to read input images in Targa format.
  1150. X *
  1151. X * These routines may need modification for non-Unix environments or
  1152. X * specialized applications.  As they stand, they assume input from
  1153. X * an ordinary stdio stream.  They further assume that reading begins
  1154. X * at the start of the file; input_init may need work if the
  1155. X * user interface has already read some data (e.g., to determine that
  1156. X * the file is indeed Targa format).
  1157. X *
  1158. X * These routines are invoked via the methods get_input_row
  1159. X * and input_init/term.
  1160. X *
  1161. X * Based on code contributed by Lee Daniel Crocker.
  1162. X */
  1163. X
  1164. X#include "jinclude.h"
  1165. X
  1166. X#ifdef TARGA_SUPPORTED
  1167. X
  1168. X
  1169. X/* Macros to deal with unsigned chars as efficiently as compiler allows */
  1170. X
  1171. X#ifdef HAVE_UNSIGNED_CHAR
  1172. Xtypedef unsigned char U_CHAR;
  1173. X#define UCH(x)    ((int) (x))
  1174. X#else /* !HAVE_UNSIGNED_CHAR */
  1175. X#ifdef CHAR_IS_UNSIGNED
  1176. Xtypedef char U_CHAR;
  1177. X#define UCH(x)    ((int) (x))
  1178. X#else
  1179. Xtypedef char U_CHAR;
  1180. X#define UCH(x)    ((int) (x) & 0xFF)
  1181. X#endif
  1182. X#endif /* HAVE_UNSIGNED_CHAR */
  1183. X
  1184. X
  1185. X#define    ReadOK(file,buffer,len)    (JFREAD(file,buffer,len) == ((size_t) (len)))
  1186. X
  1187. X
  1188. Xstatic JSAMPARRAY colormap;    /* Targa colormap (converted to my format) */
  1189. X
  1190. Xstatic big_sarray_ptr whole_image; /* Needed if funny input row order */
  1191. Xstatic long current_row;    /* Current logical row number to read */
  1192. X
  1193. X/* Pointer to routine to extract next Targa pixel from input file */
  1194. Xstatic void (*read_pixel) PP((compress_info_ptr cinfo));
  1195. X
  1196. X/* Result of read_pixel is delivered here: */
  1197. Xstatic U_CHAR tga_pixel[4];
  1198. X
  1199. Xstatic int pixel_size;        /* Bytes per Targa pixel (1 to 4) */
  1200. X
  1201. X/* State info for reading RLE-coded pixels; both counts must be init to 0 */
  1202. Xstatic int block_count;        /* # of pixels remaining in RLE block */
  1203. Xstatic int dup_pixel_count;    /* # of times to duplicate previous pixel */
  1204. X
  1205. X/* This saves the correct pixel-row-expansion method for preload_image */
  1206. Xstatic void (*get_pixel_row) PP((compress_info_ptr cinfo,
  1207. X                 JSAMPARRAY pixel_row));
  1208. X
  1209. X
  1210. X/* For expanding 5-bit pixel values to 8-bit with best rounding */
  1211. X
  1212. Xstatic const UINT8 c5to8bits[32] = {
  1213. X    0,   8,  16,  24,  32,  41,  49,  57,
  1214. X   65,  74,  82,  90,  98, 106, 115, 123,
  1215. X  131, 139, 148, 156, 164, 172, 180, 189,
  1216. X  197, 205, 213, 222, 230, 238, 246, 255
  1217. X};
  1218. X
  1219. X
  1220. X
  1221. XLOCAL int
  1222. Xread_byte (compress_info_ptr cinfo)
  1223. X/* Read next byte from Targa file */
  1224. X{
  1225. X  register FILE *infile = cinfo->input_file;
  1226. X  register int c;
  1227. X
  1228. X  if ((c = getc(infile)) == EOF)
  1229. X    ERREXIT(cinfo->emethods, "Premature EOF in Targa file");
  1230. X  return c;
  1231. X}
  1232. X
  1233. X
  1234. XLOCAL void
  1235. Xread_colormap (compress_info_ptr cinfo, int cmaplen, int mapentrysize)
  1236. X/* Read the colormap from a Targa file */
  1237. X{
  1238. X  int i;
  1239. X
  1240. X  /* Presently only handles 24-bit BGR format */
  1241. X  if (mapentrysize != 24)
  1242. X    ERREXIT(cinfo->emethods, "Unsupported Targa colormap format");
  1243. X
  1244. X  for (i = 0; i < cmaplen; i++) {
  1245. X    colormap[2][i] = (JSAMPLE) read_byte(cinfo);
  1246. X    colormap[1][i] = (JSAMPLE) read_byte(cinfo);
  1247. X    colormap[0][i] = (JSAMPLE) read_byte(cinfo);
  1248. X  }
  1249. X}
  1250. X
  1251. X
  1252. X/*
  1253. X * read_pixel methods: get a single pixel from Targa file into tga_pixel[]
  1254. X */
  1255. X
  1256. XLOCAL void
  1257. Xread_non_rle_pixel (compress_info_ptr cinfo)
  1258. X/* Read one Targa pixel from the input file; no RLE expansion */
  1259. X{
  1260. X  register FILE * infile = cinfo->input_file;
  1261. X  register int i;
  1262. X
  1263. X  for (i = 0; i < pixel_size; i++) {
  1264. X    tga_pixel[i] = (U_CHAR) getc(infile);
  1265. X  }
  1266. X}
  1267. X
  1268. X
  1269. XLOCAL void
  1270. Xread_rle_pixel (compress_info_ptr cinfo)
  1271. X/* Read one Targa pixel from the input file, expanding RLE data as needed */
  1272. X{
  1273. X  register FILE * infile = cinfo->input_file;
  1274. X  register int i;
  1275. X
  1276. X  /* Duplicate previously read pixel? */
  1277. X  if (dup_pixel_count > 0) {
  1278. X    dup_pixel_count--;
  1279. X    return;
  1280. X  }
  1281. X
  1282. X  /* Time to read RLE block header? */
  1283. X  if (--block_count < 0) {    /* decrement pixels remaining in block */
  1284. X    i = read_byte(cinfo);
  1285. X    if (i & 0x80) {        /* Start of duplicate-pixel block? */
  1286. X      dup_pixel_count = i & 0x7F; /* number of duplications after this one */
  1287. X      block_count = 0;        /* then read new block header */
  1288. X    } else {
  1289. X      block_count = i & 0x7F;    /* number of pixels after this one */
  1290. X    }
  1291. X  }
  1292. X
  1293. X  /* Read next pixel */
  1294. X  for (i = 0; i < pixel_size; i++) {
  1295. X    tga_pixel[i] = (U_CHAR) getc(infile);
  1296. X  }
  1297. X}
  1298. X
  1299. X
  1300. X/*
  1301. X * Read one row of pixels.
  1302. X *
  1303. X * We provide several different versions depending on input file format.
  1304. X */
  1305. X
  1306. X
  1307. XMETHODDEF void
  1308. Xget_8bit_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  1309. X/* This version is for reading 8-bit grayscale pixels */
  1310. X{
  1311. X  register JSAMPROW ptr0;
  1312. X  register long col;
  1313. X  
  1314. X  ptr0 = pixel_row[0];
  1315. X  for (col = cinfo->image_width; col > 0; col--) {
  1316. X    (*read_pixel) (cinfo);    /* Load next pixel into tga_pixel */
  1317. X    *ptr0++ = (JSAMPLE) UCH(tga_pixel[0]);
  1318. X  }
  1319. X}
  1320. X
  1321. XMETHODDEF void
  1322. Xget_8bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  1323. X/* This version is for reading 8-bit colormap indexes */
  1324. X{
  1325. X  register int t;
  1326. X  register JSAMPROW ptr0, ptr1, ptr2;
  1327. X  register long col;
  1328. X  
  1329. X  ptr0 = pixel_row[0];
  1330. X  ptr1 = pixel_row[1];
  1331. X  ptr2 = pixel_row[2];
  1332. X  for (col = cinfo->image_width; col > 0; col--) {
  1333. X    (*read_pixel) (cinfo);    /* Load next pixel into tga_pixel */
  1334. X    t = UCH(tga_pixel[0]);
  1335. X    *ptr0++ = colormap[0][t];
  1336. X    *ptr1++ = colormap[1][t];
  1337. X    *ptr2++ = colormap[2][t];
  1338. X  }
  1339. X}
  1340. X
  1341. XMETHODDEF void
  1342. Xget_16bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  1343. X/* This version is for reading 16-bit pixels */
  1344. X{
  1345. X  register int t;
  1346. X  register JSAMPROW ptr0, ptr1, ptr2;
  1347. X  register long col;
  1348. X  
  1349. X  ptr0 = pixel_row[0];
  1350. X  ptr1 = pixel_row[1];
  1351. X  ptr2 = pixel_row[2];
  1352. X  for (col = cinfo->image_width; col > 0; col--) {
  1353. X    (*read_pixel) (cinfo);    /* Load next pixel into tga_pixel */
  1354. X    t = UCH(tga_pixel[0]);
  1355. X    t += UCH(tga_pixel[1]) << 8;
  1356. X    /* We expand 5 bit data to 8 bit sample width.
  1357. X     * The format of the 16-bit (LSB first) input word is
  1358. X     *     xRRRRRGGGGGBBBBB
  1359. X     */
  1360. X    *ptr2++ = (JSAMPLE) c5to8bits[t & 0x1F];
  1361. X    t >>= 5;
  1362. X    *ptr1++ = (JSAMPLE) c5to8bits[t & 0x1F];
  1363. X    t >>= 5;
  1364. X    *ptr0++ = (JSAMPLE) c5to8bits[t & 0x1F];
  1365. X  }
  1366. X}
  1367. X
  1368. XMETHODDEF void
  1369. Xget_24bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  1370. X/* This version is for reading 24-bit pixels */
  1371. X{
  1372. X  register JSAMPROW ptr0, ptr1, ptr2;
  1373. X  register long col;
  1374. X  
  1375. X  ptr0 = pixel_row[0];
  1376. X  ptr1 = pixel_row[1];
  1377. X  ptr2 = pixel_row[2];
  1378. X  for (col = cinfo->image_width; col > 0; col--) {
  1379. X    (*read_pixel) (cinfo);    /* Load next pixel into tga_pixel */
  1380. X    *ptr0++ = (JSAMPLE) UCH(tga_pixel[2]); /* convert BGR to RGB order */
  1381. X    *ptr1++ = (JSAMPLE) UCH(tga_pixel[1]);
  1382. X    *ptr2++ = (JSAMPLE) UCH(tga_pixel[0]);
  1383. X  }
  1384. X}
  1385. X
  1386. X/*
  1387. X * Targa also defines a 32-bit pixel format with order B,G,R,A.
  1388. X * We presently ignore the attribute byte, so the code for reading
  1389. X * these pixels is identical to the 24-bit routine above.
  1390. X * This works because the actual pixel length is only known to read_pixel.
  1391. X */
  1392. X
  1393. X#define get_32bit_row  get_24bit_row
  1394. X
  1395. X
  1396. X/*
  1397. X * This method is for re-reading the input data in standard top-down
  1398. X * row order.  The entire image has already been read into whole_image
  1399. X * with proper conversion of pixel format, but it's in a funny row order.
  1400. X */
  1401. X
  1402. XMETHODDEF void
  1403. Xget_memory_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  1404. X{
  1405. X  JSAMPARRAY image_ptr;
  1406. X  long source_row;
  1407. X
  1408. X  /* Compute row of source that maps to current_row of normal order */
  1409. X  /* For now, assume image is bottom-up and not interlaced. */
  1410. X  /* NEEDS WORK to support interlaced images! */
  1411. X  source_row = cinfo->image_height - current_row - 1;
  1412. X
  1413. X  /* Fetch that row from virtual array */
  1414. X  image_ptr = (*cinfo->emethods->access_big_sarray)
  1415. X        (whole_image, source_row * cinfo->input_components, FALSE);
  1416. X
  1417. X  jcopy_sample_rows(image_ptr, 0, pixel_row, 0,
  1418. X            cinfo->input_components, cinfo->image_width);
  1419. X
  1420. X  current_row++;
  1421. X}
  1422. X
  1423. X
  1424. X/*
  1425. X * This method loads the image into whole_image during the first call on
  1426. X * get_input_row.  The get_input_row pointer is then adjusted to call
  1427. X * get_memory_row on subsequent calls.
  1428. X */
  1429. X
  1430. XMETHODDEF void
  1431. Xpreload_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  1432. X{
  1433. X  JSAMPARRAY image_ptr;
  1434. X  long row;
  1435. X
  1436. X  /* Read the data into a virtual array in input-file row order */
  1437. X  for (row = 0; row < cinfo->image_height; row++) {
  1438. X    (*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
  1439. X    image_ptr = (*cinfo->emethods->access_big_sarray)
  1440. X            (whole_image, row * cinfo->input_components, TRUE);
  1441. X    (*get_pixel_row) (cinfo, image_ptr);
  1442. X  }
  1443. X  cinfo->completed_passes++;
  1444. X
  1445. X  /* Set up to read from the virtual array in unscrambled order */
  1446. X  cinfo->methods->get_input_row = get_memory_row;
  1447. X  current_row = 0;
  1448. X  /* And read the first row */
  1449. X  get_memory_row(cinfo, pixel_row);
  1450. X}
  1451. X
  1452. X
  1453. X/*
  1454. X * Read the file header; return image size and component count.
  1455. X */
  1456. X
  1457. XMETHODDEF void
  1458. Xinput_init (compress_info_ptr cinfo)
  1459. X{
  1460. X  U_CHAR targaheader[18];
  1461. X  int idlen, cmaptype, subtype, flags, interlace_type, components;
  1462. X  UINT16 width, height, maplen;
  1463. X  boolean is_bottom_up;
  1464. X
  1465. X#define GET_2B(offset)    ((unsigned int) UCH(targaheader[offset]) + \
  1466. X             (((unsigned int) UCH(targaheader[offset+1])) << 8))
  1467. X  
  1468. X  if (! ReadOK(cinfo->input_file, targaheader, 18))
  1469. X    ERREXIT(cinfo->emethods, "Unexpected end of file");
  1470. X
  1471. X  /* Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway */
  1472. X  if (targaheader[16] == 15)
  1473. X    targaheader[16] = 16;
  1474. X
  1475. X  idlen = UCH(targaheader[0]);
  1476. X  cmaptype = UCH(targaheader[1]);
  1477. X  subtype = UCH(targaheader[2]);
  1478. X  maplen = GET_2B(5);
  1479. X  width = GET_2B(12);
  1480. X  height = GET_2B(14);
  1481. X  pixel_size = UCH(targaheader[16]) >> 3;
  1482. X  flags = UCH(targaheader[17]);    /* Image Descriptor byte */
  1483. X
  1484. X  is_bottom_up = ((flags & 0x20) == 0);    /* bit 5 set => top-down */
  1485. X  interlace_type = flags >> 6;    /* bits 6/7 are interlace code */
  1486. X
  1487. X  if (cmaptype > 1 ||        /* cmaptype must be 0 or 1 */
  1488. X      pixel_size < 1 || pixel_size > 4 ||
  1489. X      (UCH(targaheader[16]) & 7) != 0 || /* bits/pixel must be multiple of 8 */
  1490. X      interlace_type != 0)    /* currently don't allow interlaced image */
  1491. X    ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
  1492. X  
  1493. X  if (subtype > 8) {
  1494. X    /* It's an RLE-coded file */
  1495. X    read_pixel = read_rle_pixel;
  1496. X    block_count = dup_pixel_count = 0;
  1497. X    subtype -= 8;
  1498. X  } else {
  1499. X    /* Non-RLE file */
  1500. X    read_pixel = read_non_rle_pixel;
  1501. X  }
  1502. X
  1503. X  /* Now should have subtype 1, 2, or 3 */
  1504. X  components = 3;        /* until proven different */
  1505. X  cinfo->in_color_space = CS_RGB;
  1506. X
  1507. X  switch (subtype) {
  1508. X  case 1:            /* colormapped image */
  1509. X    if (pixel_size == 1 && cmaptype == 1)
  1510. X      get_pixel_row = get_8bit_row;
  1511. X    else
  1512. X      ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
  1513. X    break;
  1514. X  case 2:            /* RGB image */
  1515. X    switch (pixel_size) {
  1516. X    case 2:
  1517. X      get_pixel_row = get_16bit_row;
  1518. X      break;
  1519. X    case 3:
  1520. X      get_pixel_row = get_24bit_row;
  1521. X      break;
  1522. X    case 4:
  1523. X      get_pixel_row = get_32bit_row;
  1524. X      break;
  1525. X    default:
  1526. X      ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
  1527. X      break;
  1528. X    }
  1529. X    break;
  1530. X  case 3:            /* Grayscale image */
  1531. X    components = 1;
  1532. X    cinfo->in_color_space = CS_GRAYSCALE;
  1533. X    if (pixel_size == 1)
  1534. X      get_pixel_row = get_8bit_gray_row;
  1535. X    else
  1536. X      ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
  1537. X    break;
  1538. X  default:
  1539. X    ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
  1540. X    break;
  1541. X  }
  1542. X
  1543. X  if (is_bottom_up) {
  1544. X    whole_image = (*cinfo->emethods->request_big_sarray)
  1545. X            ((long) width, (long) height * components,
  1546. X             (long) components);
  1547. X    cinfo->methods->get_input_row = preload_image;
  1548. X    cinfo->total_passes++;    /* count file reading as separate pass */
  1549. X  } else {
  1550. X    whole_image = NULL;
  1551. X    cinfo->methods->get_input_row = get_pixel_row;
  1552. X  }
  1553. X  
  1554. X  while (idlen--)        /* Throw away ID field */
  1555. X    (void) read_byte(cinfo);
  1556. X
  1557. X  if (maplen > 0) {
  1558. X    if (maplen > 256 || GET_2B(3) != 0)
  1559. X      ERREXIT(cinfo->emethods, "Colormap too large");
  1560. X    /* Allocate space to store the colormap */
  1561. X    colormap = (*cinfo->emethods->alloc_small_sarray)
  1562. X            ((long) maplen, 3L);
  1563. X    /* and read it from the file */
  1564. X    read_colormap(cinfo, (int) maplen, UCH(targaheader[7]));
  1565. X  } else {
  1566. X    if (cmaptype)        /* but you promised a cmap! */
  1567. X      ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
  1568. X    colormap = NULL;
  1569. X  }
  1570. X
  1571. X  cinfo->input_components = components;
  1572. X  cinfo->image_width = width;
  1573. X  cinfo->image_height = height;
  1574. X  cinfo->data_precision = 8;    /* always, even if 12-bit JSAMPLEs */
  1575. X}
  1576. X
  1577. X
  1578. X/*
  1579. X * Finish up at the end of the file.
  1580. X */
  1581. X
  1582. XMETHODDEF void
  1583. Xinput_term (compress_info_ptr cinfo)
  1584. X{
  1585. X  /* no work (we let free_all release the workspace) */
  1586. X}
  1587. X
  1588. X
  1589. X/*
  1590. X * The method selection routine for Targa format input.
  1591. X * Note that this must be called by the user interface before calling
  1592. X * jpeg_compress.  If multiple input formats are supported, the
  1593. X * user interface is responsible for discovering the file format and
  1594. X * calling the appropriate method selection routine.
  1595. X */
  1596. X
  1597. XGLOBAL void
  1598. Xjselrtarga (compress_info_ptr cinfo)
  1599. X{
  1600. X  cinfo->methods->input_init = input_init;
  1601. X  /* cinfo->methods->get_input_row is set by input_init */
  1602. X  cinfo->methods->input_term = input_term;
  1603. X}
  1604. X
  1605. X#endif /* TARGA_SUPPORTED */
  1606. END_OF_FILE
  1607.   if test 13177 -ne `wc -c <'jrdtarga.c'`; then
  1608.     echo shar: \"'jrdtarga.c'\" unpacked with wrong size!
  1609.   fi
  1610.   # end of 'jrdtarga.c'
  1611. fi
  1612. if test -f 'makvms.opt' -a "${1}" != "-c" ; then 
  1613.   echo shar: Will not clobber existing file \"'makvms.opt'\"
  1614. else
  1615.   echo shar: Extracting \"'makvms.opt'\" \(142 characters\)
  1616.   sed "s/^X//" >'makvms.opt' <<'END_OF_FILE'
  1617. X! a pointer to the VAX/VMS C Run-Time Shareable Library
  1618. X! This file is needed by makefile.mms and makefile.vms
  1619. XSys$Library:VAXCRTL.EXE /Share
  1620. END_OF_FILE
  1621.   if test 142 -ne `wc -c <'makvms.opt'`; then
  1622.     echo shar: \"'makvms.opt'\" unpacked with wrong size!
  1623.   fi
  1624.   # end of 'makvms.opt'
  1625. fi
  1626. echo shar: End of archive 5 \(of 18\).
  1627. cp /dev/null ark5isdone
  1628. MISSING=""
  1629. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
  1630.     if test ! -f ark${I}isdone ; then
  1631.     MISSING="${MISSING} ${I}"
  1632.     fi
  1633. done
  1634. if test "${MISSING}" = "" ; then
  1635.     echo You have unpacked all 18 archives.
  1636.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1637. else
  1638.     echo You still must unpack the following archives:
  1639.     echo "        " ${MISSING}
  1640. fi
  1641. exit 0
  1642. exit 0 # Just in case...
  1643.