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