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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019