w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

jmemmgr.c
Go to the documentation of this file.
1 /*
2  * jmemmgr.c
3  *
4  * Copyright (C) 1991-1997, Thomas G. Lane.
5  * This file is part of the Independent JPEG Group's software.
6  * For conditions of distribution and use, see the accompanying README file.
7  *
8  * This file contains the JPEG system-independent memory management
9  * routines. This code is usable across a wide variety of machines; most
10  * of the system dependencies have been isolated in a separate file.
11  * The major functions provided here are:
12  * * pool-based allocation and freeing of memory;
13  * * policy decisions about how to divide available memory among the
14  * virtual arrays;
15  * * control logic for swapping virtual arrays between main memory and
16  * backing storage.
17  * The separate system-dependent file provides the actual backing-storage
18  * access code, and it contains the policy decision about how much total
19  * main memory to use.
20  * This file is system-dependent in the sense that some of its functions
21  * are unnecessary in some systems. For example, if there is enough virtual
22  * memory so that backing storage will never be used, much of the virtual
23  * array control logic could be removed. (Of course, if you have that much
24  * memory then you shouldn't care about a little bit of unused code...)
25  */
26 
27 #define JPEG_INTERNALS
28 #define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */
29 #include "jinclude.h"
30 #include "jpeglib.h"
31 #include "jmemsys.h" /* import the system-dependent declarations */
32 
33 #ifndef NO_GETENV
34 #ifndef HAVE_STDLIB_H /* <stdlib.h> should declare getenv() */
35 extern char * getenv JPP((const char * name));
36 #endif
37 #endif
38 
39 
40 /*
41  * Some important notes:
42  * The allocation routines provided here must never return NULL.
43  * They should exit to error_exit if unsuccessful.
44  *
45  * It's not a good idea to try to merge the sarray and barray routines,
46  * even though they are textually almost the same, because samples are
47  * usually stored as bytes while coefficients are shorts or ints. Thus,
48  * in machines where byte pointers have a different representation from
49  * word pointers, the resulting machine code could not be the same.
50  */
51 
52 
53 /*
54  * Many machines require storage alignment: longs must start on 4-byte
55  * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc()
56  * always returns pointers that are multiples of the worst-case alignment
57  * requirement, and we had better do so too.
58  * There isn't any really portable way to determine the worst-case alignment
59  * requirement. This module assumes that the alignment requirement is
60  * multiples of sizeof(ALIGN_TYPE).
61  * By default, we define ALIGN_TYPE as double. This is necessary on some
62  * workstations (where doubles really do need 8-byte alignment) and will work
63  * fine on nearly everything. If your machine has lesser alignment needs,
64  * you can save a few bytes by making ALIGN_TYPE smaller.
65  * The only place I know of where this will NOT work is certain Macintosh
66  * 680x0 compilers that define double as a 10-byte IEEE extended float.
67  * Doing 10-byte alignment is counterproductive because longwords won't be
68  * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have
69  * such a compiler.
70  */
71 
72 #ifndef ALIGN_TYPE /* so can override from jconfig.h */
73 #define ALIGN_TYPE double
74 #endif
75 
76 
77 /*
78  * We allocate objects from "pools", where each pool is gotten with a single
79  * request to jpeg_get_small() or jpeg_get_large(). There is no per-object
80  * overhead within a pool, except for alignment padding. Each pool has a
81  * header with a link to the next pool of the same class.
82  * Small and large pool headers are identical except that the latter's
83  * link pointer must be FAR on 80x86 machines.
84  * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
85  * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
86  * of the alignment requirement of ALIGN_TYPE.
87  */
88 
90 
91 typedef union small_pool_struct {
92  struct {
93  small_pool_ptr next; /* next in list of pools */
94  size_t bytes_used; /* how many bytes already used within pool */
95  size_t bytes_left; /* bytes still available in this pool */
96  } hdr;
97  ALIGN_TYPE dummy; /* included in union to ensure alignment */
99 
101 
102 typedef union large_pool_struct {
103  struct {
104  large_pool_ptr next; /* next in list of pools */
105  size_t bytes_used; /* how many bytes already used within pool */
106  size_t bytes_left; /* bytes still available in this pool */
107  } hdr;
108  ALIGN_TYPE dummy; /* included in union to ensure alignment */
110 
111 
112 /*
113  * Here is the full definition of a memory manager object.
114  */
115 
116 typedef struct {
117  struct jpeg_memory_mgr pub; /* public fields */
118 
119  /* Each pool identifier (lifetime class) names a linked list of pools. */
122 
123  /* Since we only have one lifetime class of virtual arrays, only one
124  * linked list is necessary (for each datatype). Note that the virtual
125  * array control blocks being linked together are actually stored somewhere
126  * in the small-pool list.
127  */
130 
131  /* This counts total space obtained from jpeg_get_small/large */
133 
134  /* alloc_sarray and alloc_barray set this value for use by virtual
135  * array routines.
136  */
137  JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */
138 } my_memory_mgr;
139 
141 
142 
143 /*
144  * The control blocks for virtual arrays.
145  * Note that these blocks are allocated in the "small" pool area.
146  * System-dependent info for the associated backing store (if any) is hidden
147  * inside the backing_store_info struct.
148  */
149 
151  JSAMPARRAY mem_buffer; /* => the in-memory buffer */
152  JDIMENSION rows_in_array; /* total virtual array height */
153  JDIMENSION samplesperrow; /* width of array (and of memory buffer) */
154  JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */
155  JDIMENSION rows_in_mem; /* height of memory buffer */
156  JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
157  JDIMENSION cur_start_row; /* first logical row # in the buffer */
158  JDIMENSION first_undef_row; /* row # of first uninitialized row */
159  boolean pre_zero; /* pre-zero mode requested? */
160  boolean dirty; /* do current buffer contents need written? */
161  boolean b_s_open; /* is backing-store data valid? */
162  jvirt_sarray_ptr next; /* link to next virtual sarray control block */
163  backing_store_info b_s_info; /* System-dependent control info */
164 };
165 
167  JBLOCKARRAY mem_buffer; /* => the in-memory buffer */
168  JDIMENSION rows_in_array; /* total virtual array height */
169  JDIMENSION blocksperrow; /* width of array (and of memory buffer) */
170  JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */
171  JDIMENSION rows_in_mem; /* height of memory buffer */
172  JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
173  JDIMENSION cur_start_row; /* first logical row # in the buffer */
174  JDIMENSION first_undef_row; /* row # of first uninitialized row */
175  boolean pre_zero; /* pre-zero mode requested? */
176  boolean dirty; /* do current buffer contents need written? */
177  boolean b_s_open; /* is backing-store data valid? */
178  jvirt_barray_ptr next; /* link to next virtual barray control block */
179  backing_store_info b_s_info; /* System-dependent control info */
180 };
181 
182 
183 #ifdef MEM_STATS /* optional extra stuff for statistics */
184 
185 LOCAL(void)
186 print_mem_stats (j_common_ptr cinfo, int pool_id)
187 {
188  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
189  small_pool_ptr shdr_ptr;
190  large_pool_ptr lhdr_ptr;
191 
192  /* Since this is only a debugging stub, we can cheat a little by using
193  * fprintf directly rather than going through the trace message code.
194  * This is helpful because message parm array can't handle longs.
195  */
196  fprintf(stderr, "Freeing pool %d, total space = %ld\n",
197  pool_id, mem->total_space_allocated);
198 
199  for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
200  lhdr_ptr = lhdr_ptr->hdr.next) {
201  fprintf(stderr, " Large chunk used %ld\n",
202  (long) lhdr_ptr->hdr.bytes_used);
203  }
204 
205  for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
206  shdr_ptr = shdr_ptr->hdr.next) {
207  fprintf(stderr, " Small chunk used %ld free %ld\n",
208  (long) shdr_ptr->hdr.bytes_used,
209  (long) shdr_ptr->hdr.bytes_left);
210  }
211 }
212 
213 #endif /* MEM_STATS */
214 
215 
216 LOCAL(void)
217 out_of_memory (j_common_ptr cinfo, int which)
218 /* Report an out-of-memory error and stop execution */
219 /* If we compiled MEM_STATS support, report alloc requests before dying */
220 {
221 #ifdef MEM_STATS
222  cinfo->err->trace_level = 2; /* force self_destruct to report stats */
223 #endif
224  ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which);
225 }
226 
227 
228 /*
229  * Allocation of "small" objects.
230  *
231  * For these, we use pooled storage. When a new pool must be created,
232  * we try to get enough space for the current request plus a "slop" factor,
233  * where the slop will be the amount of leftover space in the new pool.
234  * The speed vs. space tradeoff is largely determined by the slop values.
235  * A different slop value is provided for each pool class (lifetime),
236  * and we also distinguish the first pool of a class from later ones.
237  * NOTE: the values given work fairly well on both 16- and 32-bit-int
238  * machines, but may be too small if longs are 64 bits or more.
239  */
240 
241 static const size_t first_pool_slop[JPOOL_NUMPOOLS] =
242 {
243  1600, /* first PERMANENT pool */
244  16000 /* first IMAGE pool */
245 };
246 
247 static const size_t extra_pool_slop[JPOOL_NUMPOOLS] =
248 {
249  0, /* additional PERMANENT pools */
250  5000 /* additional IMAGE pools */
251 };
252 
253 #define MIN_SLOP 50 /* greater than 0 to avoid futile looping */
254 
255 
256 METHODDEF(void *)
257 alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
258 /* Allocate a "small" object */
259 {
260  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
261  small_pool_ptr hdr_ptr, prev_hdr_ptr;
262  char * data_ptr;
263  size_t odd_bytes, min_request, slop;
264 
265  /* Check for unsatisfiable request (do now to ensure no overflow below) */
267  out_of_memory(cinfo, 1); /* request exceeds malloc's ability */
268 
269  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
270  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
271  if (odd_bytes > 0)
272  sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
273 
274  /* See if space is available in any existing pool */
275  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
276  ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
277  prev_hdr_ptr = NULL;
278  hdr_ptr = mem->small_list[pool_id];
279  while (hdr_ptr != NULL) {
280  if (hdr_ptr->hdr.bytes_left >= sizeofobject)
281  break; /* found pool with enough space */
282  prev_hdr_ptr = hdr_ptr;
283  hdr_ptr = hdr_ptr->hdr.next;
284  }
285 
286  /* Time to make a new pool? */
287  if (hdr_ptr == NULL) {
288  /* min_request is what we need now, slop is what will be leftover */
289  min_request = sizeofobject + SIZEOF(small_pool_hdr);
290  if (prev_hdr_ptr == NULL) /* first pool in class? */
291  slop = first_pool_slop[pool_id];
292  else
293  slop = extra_pool_slop[pool_id];
294  /* Don't ask for more than MAX_ALLOC_CHUNK */
295  if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
296  slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
297  /* Try to get space, if fail reduce slop and try again */
298  for (;;) {
299  hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
300  if (hdr_ptr != NULL)
301  break;
302  slop /= 2;
303  if (slop < MIN_SLOP) /* give up when it gets real small */
304  out_of_memory(cinfo, 2); /* jpeg_get_small failed */
305  }
306  mem->total_space_allocated += min_request + slop;
307  /* Success, initialize the new pool header and add to end of list */
308  hdr_ptr->hdr.next = NULL;
309  hdr_ptr->hdr.bytes_used = 0;
310  hdr_ptr->hdr.bytes_left = sizeofobject + slop;
311  if (prev_hdr_ptr == NULL) /* first pool in class? */
312  mem->small_list[pool_id] = hdr_ptr;
313  else
314  prev_hdr_ptr->hdr.next = hdr_ptr;
315  }
316 
317  /* OK, allocate the object from the current pool */
318  data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
319  data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
320  hdr_ptr->hdr.bytes_used += sizeofobject;
321  hdr_ptr->hdr.bytes_left -= sizeofobject;
322 
323  return (void *) data_ptr;
324 }
325 
326 
327 /*
328  * Allocation of "large" objects.
329  *
330  * The external semantics of these are the same as "small" objects,
331  * except that FAR pointers are used on 80x86. However the pool
332  * management heuristics are quite different. We assume that each
333  * request is large enough that it may as well be passed directly to
334  * jpeg_get_large; the pool management just links everything together
335  * so that we can free it all on demand.
336  * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
337  * structures. The routines that create these structures (see below)
338  * deliberately bunch rows together to ensure a large request size.
339  */
340 
341 METHODDEF(void FAR *)
342 alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
343 /* Allocate a "large" object */
344 {
345  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
346  large_pool_ptr hdr_ptr;
347  size_t odd_bytes;
348 
349  /* Check for unsatisfiable request (do now to ensure no overflow below) */
351  out_of_memory(cinfo, 3); /* request exceeds malloc's ability */
352 
353  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
354  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
355  if (odd_bytes > 0)
356  sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
357 
358  /* Always make a new pool */
359  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
360  ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
361 
362  hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
364  if (hdr_ptr == NULL)
365  out_of_memory(cinfo, 4); /* jpeg_get_large failed */
366  mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
367 
368  /* Success, initialize the new pool header and add to list */
369  hdr_ptr->hdr.next = mem->large_list[pool_id];
370  /* We maintain space counts in each pool header for statistical purposes,
371  * even though they are not needed for allocation.
372  */
373  hdr_ptr->hdr.bytes_used = sizeofobject;
374  hdr_ptr->hdr.bytes_left = 0;
375  mem->large_list[pool_id] = hdr_ptr;
376 
377  return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
378 }
379 
380 
381 /*
382  * Creation of 2-D sample arrays.
383  * The pointers are in near heap, the samples themselves in FAR heap.
384  *
385  * To minimize allocation overhead and to allow I/O of large contiguous
386  * blocks, we allocate the sample rows in groups of as many rows as possible
387  * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
388  * NB: the virtual array control routines, later in this file, know about
389  * this chunking of rows. The rowsperchunk value is left in the mem manager
390  * object so that it can be saved away if this sarray is the workspace for
391  * a virtual array.
392  */
393 
395 alloc_sarray (j_common_ptr cinfo, int pool_id,
396  JDIMENSION samplesperrow, JDIMENSION numrows)
397 /* Allocate a 2-D sample array */
398 {
399  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
401  JSAMPROW workspace;
402  JDIMENSION rowsperchunk, currow, i;
403  long ltemp;
404 
405  /* Calculate max # of rows allowed in one allocation chunk */
407  ((long) samplesperrow * SIZEOF(JSAMPLE));
408  if (ltemp <= 0)
410  if (ltemp < (long) numrows)
411  rowsperchunk = (JDIMENSION) ltemp;
412  else
413  rowsperchunk = numrows;
414  mem->last_rowsperchunk = rowsperchunk;
415 
416  /* Get space for row pointers (small object) */
417  result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
418  (size_t) (numrows * SIZEOF(JSAMPROW)));
419 
420  /* Get the rows themselves (large objects) */
421  currow = 0;
422  while (currow < numrows) {
423  rowsperchunk = MIN(rowsperchunk, numrows - currow);
424  workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
425  (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
426  * SIZEOF(JSAMPLE)));
427  for (i = rowsperchunk; i > 0; i--) {
428  result[currow++] = workspace;
429  workspace += samplesperrow;
430  }
431  }
432 
433  return result;
434 }
435 
436 
437 /*
438  * Creation of 2-D coefficient-block arrays.
439  * This is essentially the same as the code for sample arrays, above.
440  */
441 
443 alloc_barray (j_common_ptr cinfo, int pool_id,
444  JDIMENSION blocksperrow, JDIMENSION numrows)
445 /* Allocate a 2-D coefficient-block array */
446 {
447  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
449  JBLOCKROW workspace;
450  JDIMENSION rowsperchunk, currow, i;
451  long ltemp;
452 
453  /* Calculate max # of rows allowed in one allocation chunk */
455  ((long) blocksperrow * SIZEOF(JBLOCK));
456  if (ltemp <= 0)
458  if (ltemp < (long) numrows)
459  rowsperchunk = (JDIMENSION) ltemp;
460  else
461  rowsperchunk = numrows;
462  mem->last_rowsperchunk = rowsperchunk;
463 
464  /* Get space for row pointers (small object) */
465  result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
466  (size_t) (numrows * SIZEOF(JBLOCKROW)));
467 
468  /* Get the rows themselves (large objects) */
469  currow = 0;
470  while (currow < numrows) {
471  rowsperchunk = MIN(rowsperchunk, numrows - currow);
472  workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
473  (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
474  * SIZEOF(JBLOCK)));
475  for (i = rowsperchunk; i > 0; i--) {
476  result[currow++] = workspace;
477  workspace += blocksperrow;
478  }
479  }
480 
481  return result;
482 }
483 
484 
485 /*
486  * About virtual array management:
487  *
488  * The above "normal" array routines are only used to allocate strip buffers
489  * (as wide as the image, but just a few rows high). Full-image-sized buffers
490  * are handled as "virtual" arrays. The array is still accessed a strip at a
491  * time, but the memory manager must save the whole array for repeated
492  * accesses. The intended implementation is that there is a strip buffer in
493  * memory (as high as is possible given the desired memory limit), plus a
494  * backing file that holds the rest of the array.
495  *
496  * The request_virt_array routines are told the total size of the image and
497  * the maximum number of rows that will be accessed at once. The in-memory
498  * buffer must be at least as large as the maxaccess value.
499  *
500  * The request routines create control blocks but not the in-memory buffers.
501  * That is postponed until realize_virt_arrays is called. At that time the
502  * total amount of space needed is known (approximately, anyway), so free
503  * memory can be divided up fairly.
504  *
505  * The access_virt_array routines are responsible for making a specific strip
506  * area accessible (after reading or writing the backing file, if necessary).
507  * Note that the access routines are told whether the caller intends to modify
508  * the accessed strip; during a read-only pass this saves having to rewrite
509  * data to disk. The access routines are also responsible for pre-zeroing
510  * any newly accessed rows, if pre-zeroing was requested.
511  *
512  * In current usage, the access requests are usually for nonoverlapping
513  * strips; that is, successive access start_row numbers differ by exactly
514  * num_rows = maxaccess. This means we can get good performance with simple
515  * buffer dump/reload logic, by making the in-memory buffer be a multiple
516  * of the access height; then there will never be accesses across bufferload
517  * boundaries. The code will still work with overlapping access requests,
518  * but it doesn't handle bufferload overlaps very efficiently.
519  */
520 
521 
523 request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
524  JDIMENSION samplesperrow, JDIMENSION numrows,
525  JDIMENSION maxaccess)
526 /* Request a virtual 2-D sample array */
527 {
528  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
530 
531  /* Only IMAGE-lifetime virtual arrays are currently supported */
532  if (pool_id != JPOOL_IMAGE)
533  ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
534 
535  /* get control block */
536  result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
537  SIZEOF(struct jvirt_sarray_control));
538 
539  result->mem_buffer = NULL; /* marks array not yet realized */
540  result->rows_in_array = numrows;
541  result->samplesperrow = samplesperrow;
542  result->maxaccess = maxaccess;
543  result->pre_zero = pre_zero;
544  result->b_s_open = FALSE; /* no associated backing-store object */
545  result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
546  mem->virt_sarray_list = result;
547 
548  return result;
549 }
550 
551 
553 request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
554  JDIMENSION blocksperrow, JDIMENSION numrows,
555  JDIMENSION maxaccess)
556 /* Request a virtual 2-D coefficient-block array */
557 {
558  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
560 
561  /* Only IMAGE-lifetime virtual arrays are currently supported */
562  if (pool_id != JPOOL_IMAGE)
563  ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
564 
565  /* get control block */
566  result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
567  SIZEOF(struct jvirt_barray_control));
568 
569  result->mem_buffer = NULL; /* marks array not yet realized */
570  result->rows_in_array = numrows;
571  result->blocksperrow = blocksperrow;
572  result->maxaccess = maxaccess;
573  result->pre_zero = pre_zero;
574  result->b_s_open = FALSE; /* no associated backing-store object */
575  result->next = mem->virt_barray_list; /* add to list of virtual arrays */
576  mem->virt_barray_list = result;
577 
578  return result;
579 }
580 
581 
582 METHODDEF(void)
584 /* Allocate the in-memory buffers for any unrealized virtual arrays */
585 {
586  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
587  long space_per_minheight, maximum_space, avail_mem;
588  long minheights, max_minheights;
590  jvirt_barray_ptr bptr;
591 
592  /* Compute the minimum space needed (maxaccess rows in each buffer)
593  * and the maximum space needed (full image height in each buffer).
594  * These may be of use to the system-dependent jpeg_mem_available routine.
595  */
596  space_per_minheight = 0;
597  maximum_space = 0;
598  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
599  if (sptr->mem_buffer == NULL) { /* if not realized yet */
600  space_per_minheight += (long) sptr->maxaccess *
601  (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
602  maximum_space += (long) sptr->rows_in_array *
603  (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
604  }
605  }
606  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
607  if (bptr->mem_buffer == NULL) { /* if not realized yet */
608  space_per_minheight += (long) bptr->maxaccess *
609  (long) bptr->blocksperrow * SIZEOF(JBLOCK);
610  maximum_space += (long) bptr->rows_in_array *
611  (long) bptr->blocksperrow * SIZEOF(JBLOCK);
612  }
613  }
614 
615  if (space_per_minheight <= 0)
616  return; /* no unrealized arrays, no work */
617 
618  /* Determine amount of memory to actually use; this is system-dependent. */
619  avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
620  mem->total_space_allocated);
621 
622  /* If the maximum space needed is available, make all the buffers full
623  * height; otherwise parcel it out with the same number of minheights
624  * in each buffer.
625  */
626  if (avail_mem >= maximum_space)
627  max_minheights = 1000000000L;
628  else {
629  max_minheights = avail_mem / space_per_minheight;
630  /* If there doesn't seem to be enough space, try to get the minimum
631  * anyway. This allows a "stub" implementation of jpeg_mem_available().
632  */
633  if (max_minheights <= 0)
634  max_minheights = 1;
635  }
636 
637  /* Allocate the in-memory buffers and initialize backing store as needed. */
638 
639  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
640  if (sptr->mem_buffer == NULL) { /* if not realized yet */
641  minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L;
642  if (minheights <= max_minheights) {
643  /* This buffer fits in memory */
644  sptr->rows_in_mem = sptr->rows_in_array;
645  } else {
646  /* It doesn't fit in memory, create backing store. */
647  sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess);
648  jpeg_open_backing_store(cinfo, & sptr->b_s_info,
649  (long) sptr->rows_in_array *
650  (long) sptr->samplesperrow *
651  (long) SIZEOF(JSAMPLE));
652  sptr->b_s_open = TRUE;
653  }
654  sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
655  sptr->samplesperrow, sptr->rows_in_mem);
656  sptr->rowsperchunk = mem->last_rowsperchunk;
657  sptr->cur_start_row = 0;
658  sptr->first_undef_row = 0;
659  sptr->dirty = FALSE;
660  }
661  }
662 
663  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
664  if (bptr->mem_buffer == NULL) { /* if not realized yet */
665  minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
666  if (minheights <= max_minheights) {
667  /* This buffer fits in memory */
668  bptr->rows_in_mem = bptr->rows_in_array;
669  } else {
670  /* It doesn't fit in memory, create backing store. */
671  bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess);
672  jpeg_open_backing_store(cinfo, & bptr->b_s_info,
673  (long) bptr->rows_in_array *
674  (long) bptr->blocksperrow *
675  (long) SIZEOF(JBLOCK));
676  bptr->b_s_open = TRUE;
677  }
678  bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
679  bptr->blocksperrow, bptr->rows_in_mem);
680  bptr->rowsperchunk = mem->last_rowsperchunk;
681  bptr->cur_start_row = 0;
682  bptr->first_undef_row = 0;
683  bptr->dirty = FALSE;
684  }
685  }
686 }
687 
688 
689 LOCAL(void)
691 /* Do backing store read or write of a virtual sample array */
692 {
693  long bytesperrow, file_offset, byte_count, rows, thisrow, i;
694 
695  bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
696  file_offset = ptr->cur_start_row * bytesperrow;
697  /* Loop to read or write each allocation chunk in mem_buffer */
698  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
699  /* One chunk, but check for short chunk at end of buffer */
700  rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
701  /* Transfer no more than is currently defined */
702  thisrow = (long) ptr->cur_start_row + i;
703  rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
704  /* Transfer no more than fits in file */
705  rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
706  if (rows <= 0) /* this chunk might be past end of file! */
707  break;
708  byte_count = rows * bytesperrow;
709  if (writing)
710  (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
711  (void FAR *) ptr->mem_buffer[i],
712  file_offset, byte_count);
713  else
714  (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
715  (void FAR *) ptr->mem_buffer[i],
716  file_offset, byte_count);
717  file_offset += byte_count;
718  }
719 }
720 
721 
722 LOCAL(void)
724 /* Do backing store read or write of a virtual coefficient-block array */
725 {
726  long bytesperrow, file_offset, byte_count, rows, thisrow, i;
727 
728  bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
729  file_offset = ptr->cur_start_row * bytesperrow;
730  /* Loop to read or write each allocation chunk in mem_buffer */
731  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
732  /* One chunk, but check for short chunk at end of buffer */
733  rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
734  /* Transfer no more than is currently defined */
735  thisrow = (long) ptr->cur_start_row + i;
736  rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
737  /* Transfer no more than fits in file */
738  rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
739  if (rows <= 0) /* this chunk might be past end of file! */
740  break;
741  byte_count = rows * bytesperrow;
742  if (writing)
743  (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
744  (void FAR *) ptr->mem_buffer[i],
745  file_offset, byte_count);
746  else
747  (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
748  (void FAR *) ptr->mem_buffer[i],
749  file_offset, byte_count);
750  file_offset += byte_count;
751  }
752 }
753 
754 
758  boolean writable)
759 /* Access the part of a virtual sample array starting at start_row */
760 /* and extending for num_rows rows. writable is true if */
761 /* caller intends to modify the accessed area. */
762 {
763  JDIMENSION end_row = start_row + num_rows;
764  JDIMENSION undef_row;
765 
766  /* debugging check */
767  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
768  ptr->mem_buffer == NULL)
770 
771  /* Make the desired part of the virtual array accessible */
772  if (start_row < ptr->cur_start_row ||
773  end_row > ptr->cur_start_row+ptr->rows_in_mem) {
774  if (! ptr->b_s_open)
775  ERREXIT(cinfo, JERR_VIRTUAL_BUG);
776  /* Flush old buffer contents if necessary */
777  if (ptr->dirty) {
778  do_sarray_io(cinfo, ptr, TRUE);
779  ptr->dirty = FALSE;
780  }
781  /* Decide what part of virtual array to access.
782  * Algorithm: if target address > current window, assume forward scan,
783  * load starting at target address. If target address < current window,
784  * assume backward scan, load so that target area is top of window.
785  * Note that when switching from forward write to forward read, will have
786  * start_row = 0, so the limiting case applies and we load from 0 anyway.
787  */
788  if (start_row > ptr->cur_start_row) {
789  ptr->cur_start_row = start_row;
790  } else {
791  /* use long arithmetic here to avoid overflow & unsigned problems */
792  long ltemp;
793 
794  ltemp = (long) end_row - (long) ptr->rows_in_mem;
795  if (ltemp < 0)
796  ltemp = 0; /* don't fall off front end of file */
797  ptr->cur_start_row = (JDIMENSION) ltemp;
798  }
799  /* Read in the selected part of the array.
800  * During the initial write pass, we will do no actual read
801  * because the selected part is all undefined.
802  */
803  do_sarray_io(cinfo, ptr, FALSE);
804  }
805  /* Ensure the accessed part of the array is defined; prezero if needed.
806  * To improve locality of access, we only prezero the part of the array
807  * that the caller is about to access, not the entire in-memory array.
808  */
809  if (ptr->first_undef_row < end_row) {
810  if (ptr->first_undef_row < start_row) {
811  if (writable) /* writer skipped over a section of array */
813  undef_row = start_row; /* but reader is allowed to read ahead */
814  } else {
815  undef_row = ptr->first_undef_row;
816  }
817  if (writable)
818  ptr->first_undef_row = end_row;
819  if (ptr->pre_zero) {
820  size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
821  undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
822  end_row -= ptr->cur_start_row;
823  while (undef_row < end_row) {
824  jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
825  undef_row++;
826  }
827  } else {
828  if (! writable) /* reader looking at undefined data */
830  }
831  }
832  /* Flag the buffer dirty if caller will write in it */
833  if (writable)
834  ptr->dirty = TRUE;
835  /* Return address of proper part of the buffer */
836  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
837 }
838 
839 
843  boolean writable)
844 /* Access the part of a virtual block array starting at start_row */
845 /* and extending for num_rows rows. writable is true if */
846 /* caller intends to modify the accessed area. */
847 {
848  JDIMENSION end_row = start_row + num_rows;
849  JDIMENSION undef_row;
850 
851  /* debugging check */
852  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
853  ptr->mem_buffer == NULL)
855 
856  /* Make the desired part of the virtual array accessible */
857  if (start_row < ptr->cur_start_row ||
858  end_row > ptr->cur_start_row+ptr->rows_in_mem) {
859  if (! ptr->b_s_open)
860  ERREXIT(cinfo, JERR_VIRTUAL_BUG);
861  /* Flush old buffer contents if necessary */
862  if (ptr->dirty) {
863  do_barray_io(cinfo, ptr, TRUE);
864  ptr->dirty = FALSE;
865  }
866  /* Decide what part of virtual array to access.
867  * Algorithm: if target address > current window, assume forward scan,
868  * load starting at target address. If target address < current window,
869  * assume backward scan, load so that target area is top of window.
870  * Note that when switching from forward write to forward read, will have
871  * start_row = 0, so the limiting case applies and we load from 0 anyway.
872  */
873  if (start_row > ptr->cur_start_row) {
874  ptr->cur_start_row = start_row;
875  } else {
876  /* use long arithmetic here to avoid overflow & unsigned problems */
877  long ltemp;
878 
879  ltemp = (long) end_row - (long) ptr->rows_in_mem;
880  if (ltemp < 0)
881  ltemp = 0; /* don't fall off front end of file */
882  ptr->cur_start_row = (JDIMENSION) ltemp;
883  }
884  /* Read in the selected part of the array.
885  * During the initial write pass, we will do no actual read
886  * because the selected part is all undefined.
887  */
888  do_barray_io(cinfo, ptr, FALSE);
889  }
890  /* Ensure the accessed part of the array is defined; prezero if needed.
891  * To improve locality of access, we only prezero the part of the array
892  * that the caller is about to access, not the entire in-memory array.
893  */
894  if (ptr->first_undef_row < end_row) {
895  if (ptr->first_undef_row < start_row) {
896  if (writable) /* writer skipped over a section of array */
898  undef_row = start_row; /* but reader is allowed to read ahead */
899  } else {
900  undef_row = ptr->first_undef_row;
901  }
902  if (writable)
903  ptr->first_undef_row = end_row;
904  if (ptr->pre_zero) {
905  size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
906  undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
907  end_row -= ptr->cur_start_row;
908  while (undef_row < end_row) {
909  jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
910  undef_row++;
911  }
912  } else {
913  if (! writable) /* reader looking at undefined data */
915  }
916  }
917  /* Flag the buffer dirty if caller will write in it */
918  if (writable)
919  ptr->dirty = TRUE;
920  /* Return address of proper part of the buffer */
921  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
922 }
923 
924 
925 /*
926  * Release all objects belonging to a specified pool.
927  */
928 
929 METHODDEF(void)
930 free_pool (j_common_ptr cinfo, int pool_id)
931 {
932  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
933  small_pool_ptr shdr_ptr;
934  large_pool_ptr lhdr_ptr;
935  size_t space_freed;
936 
937  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
938  ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
939 
940 #ifdef MEM_STATS
941  if (cinfo->err->trace_level > 1)
942  print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */
943 #endif
944 
945  /* If freeing IMAGE pool, close any virtual arrays first */
946  if (pool_id == JPOOL_IMAGE) {
948  jvirt_barray_ptr bptr;
949 
950  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
951  if (sptr->b_s_open) { /* there may be no backing store */
952  sptr->b_s_open = FALSE; /* prevent recursive close if error */
953  (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info);
954  }
955  }
956  mem->virt_sarray_list = NULL;
957  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
958  if (bptr->b_s_open) { /* there may be no backing store */
959  bptr->b_s_open = FALSE; /* prevent recursive close if error */
960  (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info);
961  }
962  }
963  mem->virt_barray_list = NULL;
964  }
965 
966  /* Release large objects */
967  lhdr_ptr = mem->large_list[pool_id];
968  mem->large_list[pool_id] = NULL;
969 
970  while (lhdr_ptr != NULL) {
971  large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
972  space_freed = lhdr_ptr->hdr.bytes_used +
973  lhdr_ptr->hdr.bytes_left +
975  jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
976  mem->total_space_allocated -= space_freed;
977  lhdr_ptr = next_lhdr_ptr;
978  }
979 
980  /* Release small objects */
981  shdr_ptr = mem->small_list[pool_id];
982  mem->small_list[pool_id] = NULL;
983 
984  while (shdr_ptr != NULL) {
985  small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
986  space_freed = shdr_ptr->hdr.bytes_used +
987  shdr_ptr->hdr.bytes_left +
989  jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
990  mem->total_space_allocated -= space_freed;
991  shdr_ptr = next_shdr_ptr;
992  }
993 }
994 
995 
996 /*
997  * Close up shop entirely.
998  * Note that this cannot be called unless cinfo->mem is non-NULL.
999  */
1000 
1001 METHODDEF(void)
1003 {
1004  int pool;
1005 
1006  /* Close all backing store, release all memory.
1007  * Releasing pools in reverse order might help avoid fragmentation
1008  * with some (brain-damaged) malloc libraries.
1009  */
1010  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
1011  free_pool(cinfo, pool);
1012  }
1013 
1014  /* Release the memory manager control block too. */
1015  jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr));
1016  cinfo->mem = NULL; /* ensures I will be called only once */
1017 
1018  jpeg_mem_term(cinfo); /* system-dependent cleanup */
1019 }
1020 
1021 
1022 /*
1023  * Memory manager initialization.
1024  * When this is called, only the error manager pointer is valid in cinfo!
1025  */
1026 
1027 GLOBAL(void)
1029 {
1030  my_mem_ptr mem;
1031  long max_to_use;
1032  int pool;
1033  size_t test_mac;
1034 
1035  cinfo->mem = NULL; /* for safety if init fails */
1036 
1037  /* Check for configuration errors.
1038  * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
1039  * doesn't reflect any real hardware alignment requirement.
1040  * The test is a little tricky: for X>0, X and X-1 have no one-bits
1041  * in common if and only if X is a power of 2, ie has only one one-bit.
1042  * Some compilers may give an "unreachable code" warning here; ignore it.
1043  */
1044  if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
1045  ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
1046  /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
1047  * a multiple of SIZEOF(ALIGN_TYPE).
1048  * Again, an "unreachable code" warning may be ignored here.
1049  * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
1050  */
1051  test_mac = (size_t) MAX_ALLOC_CHUNK;
1052  if ((long) test_mac != MAX_ALLOC_CHUNK ||
1053  (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
1054  ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
1055 
1056  max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
1057 
1058  /* Attempt to allocate memory manager's control block */
1060 
1061  if (mem == NULL) {
1062  jpeg_mem_term(cinfo); /* system-dependent cleanup */
1063  ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
1064  }
1065 
1066  /* OK, fill in the method pointers */
1067  mem->pub.alloc_small = alloc_small;
1068  mem->pub.alloc_large = alloc_large;
1069  mem->pub.alloc_sarray = alloc_sarray;
1070  mem->pub.alloc_barray = alloc_barray;
1071  mem->pub.request_virt_sarray = request_virt_sarray;
1072  mem->pub.request_virt_barray = request_virt_barray;
1073  mem->pub.realize_virt_arrays = realize_virt_arrays;
1074  mem->pub.access_virt_sarray = access_virt_sarray;
1075  mem->pub.access_virt_barray = access_virt_barray;
1076  mem->pub.free_pool = free_pool;
1077  mem->pub.self_destruct = self_destruct;
1078 
1079  /* Make MAX_ALLOC_CHUNK accessible to other modules */
1080  mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
1081 
1082  /* Initialize working state */
1083  mem->pub.max_memory_to_use = max_to_use;
1084 
1085  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
1086  mem->small_list[pool] = NULL;
1087  mem->large_list[pool] = NULL;
1088  }
1089  mem->virt_sarray_list = NULL;
1090  mem->virt_barray_list = NULL;
1091 
1092  mem->total_space_allocated = SIZEOF(my_memory_mgr);
1093 
1094  /* Declare ourselves open for business */
1095  cinfo->mem = & mem->pub;
1096 
1097  /* Check for an environment variable JPEGMEM; if found, override the
1098  * default max_memory setting from jpeg_mem_init. Note that the
1099  * surrounding application may again override this value.
1100  * If your system doesn't support getenv(), define NO_GETENV to disable
1101  * this feature.
1102  */
1103 #ifndef NO_GETENV
1104  { char * memenv;
1105 
1106  if ((memenv = getenv("JPEGMEM")) != NULL) {
1107  char ch = 'x';
1108 
1109  if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
1110  if (ch == 'm' || ch == 'M')
1111  max_to_use *= 1000L;
1112  mem->pub.max_memory_to_use = max_to_use * 1000L;
1113  }
1114  }
1115  }
1116 #endif
1117 
1118 }
NSAutoreleasePool * pool
#define name
static integer file_offset
Definition: aptex.h:309
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
int sscanf()
int sptr
Definition: dvistuff.c:186
#define ERREXIT(cinfo, code)
Definition: jerror.h:205
@ JERR_WIDTH_OVERFLOW
Definition: jerror.h:119
@ JERR_BAD_POOL_ID
Definition: jerror.h:57
@ JERR_BAD_ALLOC_CHUNK
Definition: jerror.h:45
@ JERR_BAD_VIRTUAL_ACCESS
Definition: jerror.h:68
@ JERR_OUT_OF_MEMORY
Definition: jerror.h:101
@ JERR_VIRTUAL_BUG
Definition: jerror.h:118
@ JERR_BAD_ALIGN_TYPE
Definition: jerror.h:44
#define ERREXIT1(cinfo, code, p1)
Definition: jerror.h:208
#define SIZEOF(object)
Definition: jinclude.h:80
void jpeg_mem_term(j_common_ptr cinfo)
Definition: jmemansi.c:164
void jpeg_free_small(j_common_ptr cinfo, void *object, size_t sizeofobject)
Definition: jmemansi.c:42
void * jpeg_get_large(j_common_ptr cinfo, size_t sizeofobject)
Definition: jmemansi.c:56
void jpeg_open_backing_store(j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed)
Definition: jmemansi.c:141
long jpeg_mem_available(j_common_ptr cinfo, long min_bytes_needed, long max_bytes_needed, long already_allocated)
Definition: jmemansi.c:81
void * jpeg_get_small(j_common_ptr cinfo, size_t sizeofobject)
Definition: jmemansi.c:36
long jpeg_mem_init(j_common_ptr cinfo)
Definition: jmemansi.c:158
void jpeg_free_large(j_common_ptr cinfo, void *object, size_t sizeofobject)
Definition: jmemansi.c:62
static void do_sarray_io(j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
Definition: jmemmgr.c:690
static void self_destruct(j_common_ptr cinfo)
Definition: jmemmgr.c:1002
static void do_barray_io(j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
Definition: jmemmgr.c:723
static jvirt_sarray_ptr request_virt_sarray(j_common_ptr cinfo, int pool_id, boolean pre_zero, JDIMENSION samplesperrow, JDIMENSION numrows, JDIMENSION maxaccess)
Definition: jmemmgr.c:523
static JSAMPARRAY alloc_sarray(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow, JDIMENSION numrows)
Definition: jmemmgr.c:395
static jvirt_barray_ptr request_virt_barray(j_common_ptr cinfo, int pool_id, boolean pre_zero, JDIMENSION blocksperrow, JDIMENSION numrows, JDIMENSION maxaccess)
Definition: jmemmgr.c:553
#define ALIGN_TYPE
Definition: jmemmgr.c:73
static void free_pool(j_common_ptr cinfo, int pool_id)
Definition: jmemmgr.c:930
union small_pool_struct * small_pool_ptr
Definition: jmemmgr.c:89
static JBLOCKARRAY access_virt_barray(j_common_ptr cinfo, jvirt_barray_ptr ptr, JDIMENSION start_row, JDIMENSION num_rows, boolean writable)
Definition: jmemmgr.c:841
union large_pool_struct large_pool_hdr
static void out_of_memory(j_common_ptr cinfo, int which)
Definition: jmemmgr.c:217
union small_pool_struct small_pool_hdr
static const size_t extra_pool_slop[2]
Definition: jmemmgr.c:247
my_memory_mgr * my_mem_ptr
Definition: jmemmgr.c:140
static JBLOCKARRAY alloc_barray(j_common_ptr cinfo, int pool_id, JDIMENSION blocksperrow, JDIMENSION numrows)
Definition: jmemmgr.c:443
static JSAMPARRAY access_virt_sarray(j_common_ptr cinfo, jvirt_sarray_ptr ptr, JDIMENSION start_row, JDIMENSION num_rows, boolean writable)
Definition: jmemmgr.c:756
union large_pool_struct * large_pool_ptr
Definition: jmemmgr.c:100
static void * alloc_small(j_common_ptr cinfo, int pool_id, size_t sizeofobject)
Definition: jmemmgr.c:257
#define MIN_SLOP
Definition: jmemmgr.c:253
static const size_t first_pool_slop[2]
Definition: jmemmgr.c:241
static void realize_virt_arrays(j_common_ptr cinfo)
Definition: jmemmgr.c:583
void jinit_memory_mgr(j_common_ptr cinfo)
Definition: jmemmgr.c:1028
static void * alloc_large(j_common_ptr cinfo, int pool_id, size_t sizeofobject)
Definition: jmemmgr.c:342
size_t sizeofobject
Definition: jmemsys.h:47
#define MAX_ALLOC_CHUNK
Definition: jmemsys.h:78
unsigned int JDIMENSION
Definition: jmorecfg.h:171
char JSAMPLE
Definition: jmorecfg.h:64
#define LOCAL(type)
Definition: jmorecfg.h:186
#define METHODDEF(type)
Definition: jmorecfg.h:184
#define FAR
Definition: jmorecfg.h:217
#define GLOBAL(type)
Definition: jmorecfg.h:188
#define MIN(a, b)
Definition: jpegint.h:269
int JSAMPARRAY int int num_rows
Definition: jpegint.h:375
#define JPOOL_NUMPOOLS
Definition: jpeglib.h:750
#define JPP(arglist)
Definition: jpeglib.h:818
JSAMPLE * JSAMPROW
Definition: jpeglib.h:66
struct jvirt_barray_control * jvirt_barray_ptr
Definition: jpeglib.h:753
JBLOCKROW * JBLOCKARRAY
Definition: jpeglib.h:72
JCOEF JBLOCK[64]
Definition: jpeglib.h:70
struct jvirt_sarray_control * jvirt_sarray_ptr
Definition: jpeglib.h:752
JBLOCK * JBLOCKROW
Definition: jpeglib.h:71
JSAMPROW * JSAMPARRAY
Definition: jpeglib.h:67
#define JPOOL_PERMANENT
Definition: jpeglib.h:748
#define JPOOL_IMAGE
Definition: jpeglib.h:749
void jzero_far(void *target, size_t bytestozero)
Definition: jutils.c:165
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
for(n=0;n< outline->n_points;n++)
Definition: ftbbox.c:494
#define JSAMPROW
Definition: gd_topal.c:66
#define JDIMENSION
Definition: gd_topal.c:67
char * getenv()
#define fprintf
Definition: mendex.h:64
#define mem
Definition: synctex.c:171
#define size_t
Definition: glob.c:257
static int rows
Definition: pbmclean.c:15
#define thisrow
Definition: pbmclean.c:18
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
#define start_row(state)
Definition: utilfpred.c:193
struct jpeg_memory_mgr * mem
Definition: jpeglib.h:254
JDIMENSION rows_in_mem
Definition: jmemmgr.c:171
JDIMENSION maxaccess
Definition: jmemmgr.c:170
JDIMENSION rows_in_array
Definition: jmemmgr.c:168
backing_store_info b_s_info
Definition: jmemmgr.c:179
JDIMENSION blocksperrow
Definition: jmemmgr.c:169
JBLOCKARRAY mem_buffer
Definition: jmemmgr.c:167
JDIMENSION first_undef_row
Definition: jmemmgr.c:174
JDIMENSION rowsperchunk
Definition: jmemmgr.c:172
JDIMENSION cur_start_row
Definition: jmemmgr.c:173
jvirt_barray_ptr next
Definition: jmemmgr.c:178
JDIMENSION first_undef_row
Definition: jmemmgr.c:158
JDIMENSION rows_in_array
Definition: jmemmgr.c:152
JDIMENSION samplesperrow
Definition: jmemmgr.c:153
JDIMENSION maxaccess
Definition: jmemmgr.c:154
JDIMENSION cur_start_row
Definition: jmemmgr.c:157
JDIMENSION rows_in_mem
Definition: jmemmgr.c:155
backing_store_info b_s_info
Definition: jmemmgr.c:163
JSAMPARRAY mem_buffer
Definition: jmemmgr.c:151
JDIMENSION rowsperchunk
Definition: jmemmgr.c:156
jvirt_sarray_ptr next
Definition: jmemmgr.c:162
jvirt_barray_ptr virt_barray_list
Definition: jmemmgr.c:129
JDIMENSION last_rowsperchunk
Definition: jmemmgr.c:137
long total_space_allocated
Definition: jmemmgr.c:132
jvirt_sarray_ptr virt_sarray_list
Definition: jmemmgr.c:128
ch
Definition: t4ht.c:1443
struct large_pool_struct::@1 hdr
size_t bytes_used
Definition: jmemmgr.c:105
size_t bytes_left
Definition: jmemmgr.c:106
large_pool_ptr next
Definition: jmemmgr.c:104
small_pool_ptr next
Definition: jmemmgr.c:93
struct small_pool_struct::@0 hdr
size_t bytes_left
Definition: jmemmgr.c:95
double dummy
Definition: jmemmgr.c:97
size_t bytes_used
Definition: jmemmgr.c:94