ReactOS 0.4.15-dev-7842-g558ab78
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-2019 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() */
36extern 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
92typedef 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
103typedef 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 */
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
117typedef 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 */
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
186LOCAL(void)
187print_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, (long) 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
242static const size_t first_pool_slop[JPOOL_NUMPOOLS] =
243{
244 1600, /* first PERMANENT pool */
245 16000 /* first IMAGE pool */
246};
247
248static 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
257METHODDEF(void *)
258alloc_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 size_t odd_bytes, min_request, slop;
264 char * data_ptr;
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
342METHODDEF(void FAR *)
343alloc_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
396alloc_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) rowsperchunk * (size_t) samplesperrow * SIZEOF(JSAMPLE));
427 for (i = rowsperchunk; i > 0; i--) {
428 result[currow++] = workspace;
429 workspace += samplesperrow;
430 }
431 }
432
433 return result;
434}
435
436
437/*
438 * Creation of 2-D coefficient-block arrays.
439 * This is essentially the same as the code for sample arrays, above.
440 */
441
443alloc_barray (j_common_ptr cinfo, int pool_id,
444 JDIMENSION blocksperrow, JDIMENSION numrows)
445/* Allocate a 2-D coefficient-block array */
446{
447 my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
449 JBLOCKROW workspace;
450 JDIMENSION rowsperchunk, currow, i;
451 long ltemp;
452
453 /* Calculate max # of rows allowed in one allocation chunk */
455 ((long) blocksperrow * SIZEOF(JBLOCK));
456 if (ltemp <= 0)
457 ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
458 if (ltemp < (long) numrows)
459 rowsperchunk = (JDIMENSION) ltemp;
460 else
461 rowsperchunk = numrows;
462 mem->last_rowsperchunk = rowsperchunk;
463
464 /* Get space for row pointers (small object) */
465 result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
466 (size_t) numrows * SIZEOF(JBLOCKROW));
467
468 /* Get the rows themselves (large objects) */
469 currow = 0;
470 while (currow < numrows) {
471 rowsperchunk = MIN(rowsperchunk, numrows - currow);
472 workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
473 (size_t) rowsperchunk * (size_t) blocksperrow * SIZEOF(JBLOCK));
474 for (i = rowsperchunk; i > 0; i--) {
475 result[currow++] = workspace;
476 workspace += blocksperrow;
477 }
478 }
479
480 return result;
481}
482
483
484/*
485 * About virtual array management:
486 *
487 * The above "normal" array routines are only used to allocate strip buffers
488 * (as wide as the image, but just a few rows high). Full-image-sized buffers
489 * are handled as "virtual" arrays. The array is still accessed a strip at a
490 * time, but the memory manager must save the whole array for repeated
491 * accesses. The intended implementation is that there is a strip buffer in
492 * memory (as high as is possible given the desired memory limit), plus a
493 * backing file that holds the rest of the array.
494 *
495 * The request_virt_array routines are told the total size of the image and
496 * the maximum number of rows that will be accessed at once. The in-memory
497 * buffer must be at least as large as the maxaccess value.
498 *
499 * The request routines create control blocks but not the in-memory buffers.
500 * That is postponed until realize_virt_arrays is called. At that time the
501 * total amount of space needed is known (approximately, anyway), so free
502 * memory can be divided up fairly.
503 *
504 * The access_virt_array routines are responsible for making a specific strip
505 * area accessible (after reading or writing the backing file, if necessary).
506 * Note that the access routines are told whether the caller intends to modify
507 * the accessed strip; during a read-only pass this saves having to rewrite
508 * data to disk. The access routines are also responsible for pre-zeroing
509 * any newly accessed rows, if pre-zeroing was requested.
510 *
511 * In current usage, the access requests are usually for nonoverlapping
512 * strips; that is, successive access start_row numbers differ by exactly
513 * num_rows = maxaccess. This means we can get good performance with simple
514 * buffer dump/reload logic, by making the in-memory buffer be a multiple
515 * of the access height; then there will never be accesses across bufferload
516 * boundaries. The code will still work with overlapping access requests,
517 * but it doesn't handle bufferload overlaps very efficiently.
518 */
519
520
522request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
523 JDIMENSION samplesperrow, JDIMENSION numrows,
524 JDIMENSION maxaccess)
525/* Request a virtual 2-D sample array */
526{
527 my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
529
530 /* Only IMAGE-lifetime virtual arrays are currently supported */
531 if (pool_id != JPOOL_IMAGE)
532 ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
533
534 /* get control block */
535 result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
537
538 result->mem_buffer = NULL; /* marks array not yet realized */
539 result->rows_in_array = numrows;
540 result->samplesperrow = samplesperrow;
541 result->maxaccess = maxaccess;
542 result->pre_zero = pre_zero;
543 result->b_s_open = FALSE; /* no associated backing-store object */
544 result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
545 mem->virt_sarray_list = result;
546
547 return result;
548}
549
550
552request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
553 JDIMENSION blocksperrow, JDIMENSION numrows,
554 JDIMENSION maxaccess)
555/* Request a virtual 2-D coefficient-block array */
556{
557 my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
559
560 /* Only IMAGE-lifetime virtual arrays are currently supported */
561 if (pool_id != JPOOL_IMAGE)
562 ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
563
564 /* get control block */
565 result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
567
568 result->mem_buffer = NULL; /* marks array not yet realized */
569 result->rows_in_array = numrows;
570 result->blocksperrow = blocksperrow;
571 result->maxaccess = maxaccess;
572 result->pre_zero = pre_zero;
573 result->b_s_open = FALSE; /* no associated backing-store object */
574 result->next = mem->virt_barray_list; /* add to list of virtual arrays */
575 mem->virt_barray_list = result;
576
577 return result;
578}
579
580
581METHODDEF(void)
583/* Allocate the in-memory buffers for any unrealized virtual arrays */
584{
585 my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
586 long bytesperrow, space_per_minheight, maximum_space;
587 long avail_mem, minheights, max_minheights;
588 jvirt_sarray_ptr sptr;
589 jvirt_barray_ptr bptr;
590
591 /* Compute the minimum space needed (maxaccess rows in each buffer)
592 * and the maximum space needed (full image height in each buffer).
593 * These may be of use to the system-dependent jpeg_mem_available routine.
594 */
595 space_per_minheight = 0;
596 maximum_space = 0;
597 for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
598 if (sptr->mem_buffer == NULL) { /* if not realized yet */
599 bytesperrow = (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
600 space_per_minheight += (long) sptr->maxaccess * bytesperrow;
601 maximum_space += (long) sptr->rows_in_array * bytesperrow;
602 }
603 }
604 for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
605 if (bptr->mem_buffer == NULL) { /* if not realized yet */
606 bytesperrow = (long) bptr->blocksperrow * SIZEOF(JBLOCK);
607 space_per_minheight += (long) bptr->maxaccess * bytesperrow;
608 maximum_space += (long) bptr->rows_in_array * bytesperrow;
609 }
610 }
611
612 if (space_per_minheight <= 0)
613 return; /* no unrealized arrays, no work */
614
615 /* Determine amount of memory to actually use; this is system-dependent. */
616 avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
617 (long) mem->total_space_allocated);
618
619 /* If the maximum space needed is available, make all the buffers full
620 * height; otherwise parcel it out with the same number of minheights
621 * in each buffer.
622 */
623 if (avail_mem >= maximum_space)
624 max_minheights = 1000000000L;
625 else {
626 max_minheights = avail_mem / space_per_minheight;
627 /* If there doesn't seem to be enough space, try to get the minimum
628 * anyway. This allows a "stub" implementation of jpeg_mem_available().
629 */
630 if (max_minheights <= 0)
631 max_minheights = 1;
632 }
633
634 /* Allocate the in-memory buffers and initialize backing store as needed. */
635
636 for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
637 if (sptr->mem_buffer == NULL) { /* if not realized yet */
638 minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L;
639 if (minheights <= max_minheights) {
640 /* This buffer fits in memory */
641 sptr->rows_in_mem = sptr->rows_in_array;
642 } else {
643 /* It doesn't fit in memory, create backing store. */
644 sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess);
645 jpeg_open_backing_store(cinfo, & sptr->b_s_info,
646 (long) sptr->rows_in_array *
647 (long) sptr->samplesperrow *
648 (long) SIZEOF(JSAMPLE));
649 sptr->b_s_open = TRUE;
650 }
651 sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
652 sptr->samplesperrow, sptr->rows_in_mem);
653 sptr->rowsperchunk = mem->last_rowsperchunk;
654 sptr->cur_start_row = 0;
655 sptr->first_undef_row = 0;
656 sptr->dirty = FALSE;
657 }
658 }
659
660 for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
661 if (bptr->mem_buffer == NULL) { /* if not realized yet */
662 minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
663 if (minheights <= max_minheights) {
664 /* This buffer fits in memory */
665 bptr->rows_in_mem = bptr->rows_in_array;
666 } else {
667 /* It doesn't fit in memory, create backing store. */
668 bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess);
669 jpeg_open_backing_store(cinfo, & bptr->b_s_info,
670 (long) bptr->rows_in_array *
671 (long) bptr->blocksperrow *
672 (long) SIZEOF(JBLOCK));
673 bptr->b_s_open = TRUE;
674 }
675 bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
676 bptr->blocksperrow, bptr->rows_in_mem);
677 bptr->rowsperchunk = mem->last_rowsperchunk;
678 bptr->cur_start_row = 0;
679 bptr->first_undef_row = 0;
680 bptr->dirty = FALSE;
681 }
682 }
683}
684
685
686LOCAL(void)
688/* Do backing store read or write of a virtual sample array */
689{
690 long bytesperrow, file_offset, byte_count, rows, thisrow, i;
691
692 bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
693 file_offset = (long) ptr->cur_start_row * bytesperrow;
694 /* Loop to read or write each allocation chunk in mem_buffer */
695 for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
696 /* One chunk, but check for short chunk at end of buffer */
697 rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
698 /* Transfer no more than is currently defined */
699 thisrow = (long) ptr->cur_start_row + i;
700 rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
701 /* Transfer no more than fits in file */
702 rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
703 if (rows <= 0) /* this chunk might be past end of file! */
704 break;
705 byte_count = rows * bytesperrow;
706 if (writing)
707 (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
708 (void FAR *) ptr->mem_buffer[i],
709 file_offset, byte_count);
710 else
711 (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
712 (void FAR *) ptr->mem_buffer[i],
713 file_offset, byte_count);
714 file_offset += byte_count;
715 }
716}
717
718
719LOCAL(void)
721/* Do backing store read or write of a virtual coefficient-block array */
722{
723 long bytesperrow, file_offset, byte_count, rows, thisrow, i;
724
725 bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
726 file_offset = (long) ptr->cur_start_row * bytesperrow;
727 /* Loop to read or write each allocation chunk in mem_buffer */
728 for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
729 /* One chunk, but check for short chunk at end of buffer */
730 rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
731 /* Transfer no more than is currently defined */
732 thisrow = (long) ptr->cur_start_row + i;
733 rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
734 /* Transfer no more than fits in file */
735 rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
736 if (rows <= 0) /* this chunk might be past end of file! */
737 break;
738 byte_count = rows * bytesperrow;
739 if (writing)
740 (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
741 (void FAR *) ptr->mem_buffer[i],
742 file_offset, byte_count);
743 else
744 (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
745 (void FAR *) ptr->mem_buffer[i],
746 file_offset, byte_count);
747 file_offset += byte_count;
748 }
749}
750
751
754 JDIMENSION start_row, JDIMENSION num_rows,
755 boolean writable)
756/* Access the part of a virtual sample array starting at start_row */
757/* and extending for num_rows rows. writable is true if */
758/* caller intends to modify the accessed area. */
759{
760 JDIMENSION end_row = start_row + num_rows;
761 JDIMENSION undef_row;
762
763 /* debugging check */
764 if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
765 ptr->mem_buffer == NULL)
766 ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
767
768 /* Make the desired part of the virtual array accessible */
769 if (start_row < ptr->cur_start_row ||
770 end_row > ptr->cur_start_row + ptr->rows_in_mem) {
771 if (! ptr->b_s_open)
772 ERREXIT(cinfo, JERR_VIRTUAL_BUG);
773 /* Flush old buffer contents if necessary */
774 if (ptr->dirty) {
775 do_sarray_io(cinfo, ptr, TRUE);
776 ptr->dirty = FALSE;
777 }
778 /* Decide what part of virtual array to access.
779 * Algorithm: if target address > current window, assume forward scan,
780 * load starting at target address. If target address < current window,
781 * assume backward scan, load so that target area is top of window.
782 * Note that when switching from forward write to forward read, will have
783 * start_row = 0, so the limiting case applies and we load from 0 anyway.
784 */
785 if (start_row > ptr->cur_start_row) {
786 ptr->cur_start_row = start_row;
787 } else {
788 /* use long arithmetic here to avoid overflow & unsigned problems */
789 long ltemp;
790
791 ltemp = (long) end_row - (long) ptr->rows_in_mem;
792 if (ltemp < 0)
793 ltemp = 0; /* don't fall off front end of file */
794 ptr->cur_start_row = (JDIMENSION) ltemp;
795 }
796 /* Read in the selected part of the array.
797 * During the initial write pass, we will do no actual read
798 * because the selected part is all undefined.
799 */
800 do_sarray_io(cinfo, ptr, FALSE);
801 }
802 /* Ensure the accessed part of the array is defined; prezero if needed.
803 * To improve locality of access, we only prezero the part of the array
804 * that the caller is about to access, not the entire in-memory array.
805 */
806 if (ptr->first_undef_row < end_row) {
807 if (ptr->first_undef_row < start_row) {
808 if (writable) /* writer skipped over a section of array */
809 ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
810 undef_row = start_row; /* but reader is allowed to read ahead */
811 } else {
812 undef_row = ptr->first_undef_row;
813 }
814 if (writable)
815 ptr->first_undef_row = end_row;
816 if (ptr->pre_zero) {
817 size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
818 undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
819 end_row -= ptr->cur_start_row;
820 while (undef_row < end_row) {
821 FMEMZERO((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
822 undef_row++;
823 }
824 } else {
825 if (! writable) /* reader looking at undefined data */
826 ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
827 }
828 }
829 /* Flag the buffer dirty if caller will write in it */
830 if (writable)
831 ptr->dirty = TRUE;
832 /* Return address of proper part of the buffer */
833 return ptr->mem_buffer + (start_row - ptr->cur_start_row);
834}
835
836
839 JDIMENSION start_row, JDIMENSION num_rows,
840 boolean writable)
841/* Access the part of a virtual block array starting at start_row */
842/* and extending for num_rows rows. writable is true if */
843/* caller intends to modify the accessed area. */
844{
845 JDIMENSION end_row = start_row + num_rows;
846 JDIMENSION undef_row;
847
848 /* debugging check */
849 if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
850 ptr->mem_buffer == NULL)
851 ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
852
853 /* Make the desired part of the virtual array accessible */
854 if (start_row < ptr->cur_start_row ||
855 end_row > ptr->cur_start_row + ptr->rows_in_mem) {
856 if (! ptr->b_s_open)
857 ERREXIT(cinfo, JERR_VIRTUAL_BUG);
858 /* Flush old buffer contents if necessary */
859 if (ptr->dirty) {
860 do_barray_io(cinfo, ptr, TRUE);
861 ptr->dirty = FALSE;
862 }
863 /* Decide what part of virtual array to access.
864 * Algorithm: if target address > current window, assume forward scan,
865 * load starting at target address. If target address < current window,
866 * assume backward scan, load so that target area is top of window.
867 * Note that when switching from forward write to forward read, will have
868 * start_row = 0, so the limiting case applies and we load from 0 anyway.
869 */
870 if (start_row > ptr->cur_start_row) {
871 ptr->cur_start_row = start_row;
872 } else {
873 /* use long arithmetic here to avoid overflow & unsigned problems */
874 long ltemp;
875
876 ltemp = (long) end_row - (long) ptr->rows_in_mem;
877 if (ltemp < 0)
878 ltemp = 0; /* don't fall off front end of file */
879 ptr->cur_start_row = (JDIMENSION) ltemp;
880 }
881 /* Read in the selected part of the array.
882 * During the initial write pass, we will do no actual read
883 * because the selected part is all undefined.
884 */
885 do_barray_io(cinfo, ptr, FALSE);
886 }
887 /* Ensure the accessed part of the array is defined; prezero if needed.
888 * To improve locality of access, we only prezero the part of the array
889 * that the caller is about to access, not the entire in-memory array.
890 */
891 if (ptr->first_undef_row < end_row) {
892 if (ptr->first_undef_row < start_row) {
893 if (writable) /* writer skipped over a section of array */
894 ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
895 undef_row = start_row; /* but reader is allowed to read ahead */
896 } else {
897 undef_row = ptr->first_undef_row;
898 }
899 if (writable)
900 ptr->first_undef_row = end_row;
901 if (ptr->pre_zero) {
902 size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
903 undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
904 end_row -= ptr->cur_start_row;
905 while (undef_row < end_row) {
906 FMEMZERO((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
907 undef_row++;
908 }
909 } else {
910 if (! writable) /* reader looking at undefined data */
911 ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
912 }
913 }
914 /* Flag the buffer dirty if caller will write in it */
915 if (writable)
916 ptr->dirty = TRUE;
917 /* Return address of proper part of the buffer */
918 return ptr->mem_buffer + (start_row - ptr->cur_start_row);
919}
920
921
922/*
923 * Release all objects belonging to a specified pool.
924 */
925
926METHODDEF(void)
927free_pool (j_common_ptr cinfo, int pool_id)
928{
929 my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
930 small_pool_ptr shdr_ptr;
931 large_pool_ptr lhdr_ptr;
932 size_t space_freed;
933
934 if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
935 ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
936
937#ifdef MEM_STATS
938 if (cinfo->err->trace_level > 1)
939 print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */
940#endif
941
942 /* If freeing IMAGE pool, close any virtual arrays first */
943 if (pool_id == JPOOL_IMAGE) {
944 jvirt_sarray_ptr sptr;
945 jvirt_barray_ptr bptr;
946
947 for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
948 if (sptr->b_s_open) { /* there may be no backing store */
949 sptr->b_s_open = FALSE; /* prevent recursive close if error */
950 (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info);
951 }
952 }
953 mem->virt_sarray_list = NULL;
954 for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
955 if (bptr->b_s_open) { /* there may be no backing store */
956 bptr->b_s_open = FALSE; /* prevent recursive close if error */
957 (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info);
958 }
959 }
960 mem->virt_barray_list = NULL;
961 }
962
963 /* Release large objects */
964 lhdr_ptr = mem->large_list[pool_id];
965 mem->large_list[pool_id] = NULL;
966
967 while (lhdr_ptr != NULL) {
968 large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
969 space_freed = lhdr_ptr->hdr.bytes_used +
970 lhdr_ptr->hdr.bytes_left +
972 jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
973 mem->total_space_allocated -= space_freed;
974 lhdr_ptr = next_lhdr_ptr;
975 }
976
977 /* Release small objects */
978 shdr_ptr = mem->small_list[pool_id];
979 mem->small_list[pool_id] = NULL;
980
981 while (shdr_ptr != NULL) {
982 small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
983 space_freed = shdr_ptr->hdr.bytes_used +
984 shdr_ptr->hdr.bytes_left +
986 jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
987 mem->total_space_allocated -= space_freed;
988 shdr_ptr = next_shdr_ptr;
989 }
990}
991
992
993/*
994 * Close up shop entirely.
995 * Note that this cannot be called unless cinfo->mem is non-NULL.
996 */
997
998METHODDEF(void)
1000{
1001 int pool;
1002
1003 /* Close all backing store, release all memory.
1004 * Releasing pools in reverse order might help avoid fragmentation
1005 * with some (brain-damaged) malloc libraries.
1006 */
1007 for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
1008 free_pool(cinfo, pool);
1009 }
1010
1011 /* Release the memory manager control block too. */
1012 jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr));
1013 cinfo->mem = NULL; /* ensures I will be called only once */
1014
1015 jpeg_mem_term(cinfo); /* system-dependent cleanup */
1016}
1017
1018
1019/*
1020 * Memory manager initialization.
1021 * When this is called, only the error manager pointer is valid in cinfo!
1022 */
1023
1024GLOBAL(void)
1026{
1028 long max_to_use;
1029 int pool;
1030 size_t test_mac;
1031
1032 cinfo->mem = NULL; /* for safety if init fails */
1033
1034 /* Check for configuration errors.
1035 * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
1036 * doesn't reflect any real hardware alignment requirement.
1037 * The test is a little tricky: for X>0, X and X-1 have no one-bits
1038 * in common if and only if X is a power of 2, ie has only one one-bit.
1039 * Some compilers may give an "unreachable code" warning here; ignore it.
1040 */
1041 if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
1042 ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
1043 /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
1044 * a multiple of SIZEOF(ALIGN_TYPE).
1045 * Again, an "unreachable code" warning may be ignored here.
1046 * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
1047 */
1049 if ((long) test_mac != MAX_ALLOC_CHUNK ||
1051 ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
1052
1053 max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
1054
1055 /* Attempt to allocate memory manager's control block */
1057
1058 if (mem == NULL) {
1059 jpeg_mem_term(cinfo); /* system-dependent cleanup */
1060 ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
1061 }
1062
1063 /* OK, fill in the method pointers */
1064 mem->pub.alloc_small = alloc_small;
1065 mem->pub.alloc_large = alloc_large;
1066 mem->pub.alloc_sarray = alloc_sarray;
1067 mem->pub.alloc_barray = alloc_barray;
1068 mem->pub.request_virt_sarray = request_virt_sarray;
1069 mem->pub.request_virt_barray = request_virt_barray;
1070 mem->pub.realize_virt_arrays = realize_virt_arrays;
1071 mem->pub.access_virt_sarray = access_virt_sarray;
1072 mem->pub.access_virt_barray = access_virt_barray;
1073 mem->pub.free_pool = free_pool;
1074 mem->pub.self_destruct = self_destruct;
1075
1076 /* Make MAX_ALLOC_CHUNK accessible to other modules */
1077 mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
1078
1079 /* Initialize working state */
1080 mem->pub.max_memory_to_use = max_to_use;
1081
1082 for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
1083 mem->small_list[pool] = NULL;
1084 mem->large_list[pool] = NULL;
1085 }
1086 mem->virt_sarray_list = NULL;
1087 mem->virt_barray_list = NULL;
1088
1089 mem->total_space_allocated = SIZEOF(my_memory_mgr);
1090
1091 /* Declare ourselves open for business */
1092 cinfo->mem = &mem->pub;
1093
1094 /* Check for an environment variable JPEGMEM; if found, override the
1095 * default max_memory setting from jpeg_mem_init. Note that the
1096 * surrounding application may again override this value.
1097 * If your system doesn't support getenv(), define NO_GETENV to disable
1098 * this feature.
1099 */
1100#ifndef NO_GETENV
1101 { char * memenv;
1102
1103 if ((memenv = getenv("JPEGMEM")) != NULL) {
1104 char ch = 'x';
1105
1106 if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
1107 if (ch == 'm' || ch == 'M')
1108 max_to_use *= 1000L;
1109 mem->pub.max_memory_to_use = max_to_use * 1000L;
1110 }
1111 }
1112 }
1113#endif
1114
1115}
#define MIN(x, y)
Definition: rdesktop.h:171
#define SIZEOF(_ar)
Definition: calc.h:97
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define FAR
Definition: zlib.h:34
__kernel_size_t size_t
Definition: linux.h:237
GLuint64EXT * result
Definition: glext.h:11304
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
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
#define ERREXIT1(cinfo, code, p1)
Definition: jerror.h:212
jpeg_free_large(j_common_ptr cinfo, void FAR *object, size_t sizeofobject)
Definition: jmemansi.c:62
jpeg_get_large(j_common_ptr cinfo, size_t sizeofobject)
Definition: jmemansi.c:56
jpeg_free_small(j_common_ptr cinfo, void *object, size_t sizeofobject)
Definition: jmemansi.c:42
jpeg_get_small(j_common_ptr cinfo, size_t sizeofobject)
Definition: jmemansi.c:36
jpeg_mem_term(j_common_ptr cinfo)
Definition: jmemansi.c:164
jpeg_open_backing_store(j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed)
Definition: jmemansi.c:141
jpeg_mem_available(j_common_ptr cinfo, long min_bytes_needed, long max_bytes_needed, long already_allocated)
Definition: jmemansi.c:81
jpeg_mem_init(j_common_ptr cinfo)
Definition: jmemansi.c:158
union large_pool_struct FAR * large_pool_ptr
Definition: jmemmgr.c:101
self_destruct(j_common_ptr cinfo)
Definition: jmemmgr.c:999
alloc_sarray(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow, JDIMENSION numrows)
Definition: jmemmgr.c:396
request_virt_sarray(j_common_ptr cinfo, int pool_id, boolean pre_zero, JDIMENSION samplesperrow, JDIMENSION numrows, JDIMENSION maxaccess)
Definition: jmemmgr.c:522
access_virt_barray(j_common_ptr cinfo, jvirt_barray_ptr ptr, JDIMENSION start_row, JDIMENSION num_rows, boolean writable)
Definition: jmemmgr.c:838
#define ALIGN_TYPE
Definition: jmemmgr.c:74
union small_pool_struct * small_pool_ptr
Definition: jmemmgr.c:90
union large_pool_struct large_pool_hdr
request_virt_barray(j_common_ptr cinfo, int pool_id, boolean pre_zero, JDIMENSION blocksperrow, JDIMENSION numrows, JDIMENSION maxaccess)
Definition: jmemmgr.c:552
access_virt_sarray(j_common_ptr cinfo, jvirt_sarray_ptr ptr, JDIMENSION start_row, JDIMENSION num_rows, boolean writable)
Definition: jmemmgr.c:753
union small_pool_struct small_pool_hdr
alloc_small(j_common_ptr cinfo, int pool_id, size_t sizeofobject)
Definition: jmemmgr.c:258
my_memory_mgr * my_mem_ptr
Definition: jmemmgr.c:141
static const size_t extra_pool_slop[JPOOL_NUMPOOLS]
Definition: jmemmgr.c:248
do_barray_io(j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
Definition: jmemmgr.c:720
jinit_memory_mgr(j_common_ptr cinfo)
Definition: jmemmgr.c:1025
free_pool(j_common_ptr cinfo, int pool_id)
Definition: jmemmgr.c:927
out_of_memory(j_common_ptr cinfo, int which)
Definition: jmemmgr.c:218
realize_virt_arrays(j_common_ptr cinfo)
Definition: jmemmgr.c:582
#define MIN_SLOP
Definition: jmemmgr.c:254
static const size_t first_pool_slop[JPOOL_NUMPOOLS]
Definition: jmemmgr.c:242
do_sarray_io(j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
Definition: jmemmgr.c:687
alloc_large(j_common_ptr cinfo, int pool_id, size_t sizeofobject)
Definition: jmemmgr.c:343
alloc_barray(j_common_ptr cinfo, int pool_id, JDIMENSION blocksperrow, JDIMENSION numrows)
Definition: jmemmgr.c:443
size_t sizeofobject
Definition: jmemsys.h:47
#define MAX_ALLOC_CHUNK
Definition: jmemsys.h:78
unsigned int JDIMENSION
Definition: jmorecfg.h:229
char JSAMPLE
Definition: jmorecfg.h:74
#define LOCAL(type)
Definition: jmorecfg.h:289
#define METHODDEF(type)
Definition: jmorecfg.h:287
#define GLOBAL(type)
Definition: jmorecfg.h:291
#define FMEMZERO(target, size)
Definition: jpegint.h:368
int JSAMPARRAY int int num_rows
Definition: jpegint.h:421
JBLOCK FAR * JBLOCKROW
Definition: jpeglib.h:80
#define JPOOL_NUMPOOLS
Definition: jpeglib.h:809
#define JPP(arglist)
Definition: jpeglib.h:877
JCOEF JBLOCK[DCTSIZE2]
Definition: jpeglib.h:79
struct jvirt_barray_control * jvirt_barray_ptr
Definition: jpeglib.h:812
JBLOCKROW * JBLOCKARRAY
Definition: jpeglib.h:81
struct jvirt_sarray_control * jvirt_sarray_ptr
Definition: jpeglib.h:811
JSAMPROW * JSAMPARRAY
Definition: jpeglib.h:76
#define JPOOL_PERMANENT
Definition: jpeglib.h:807
JSAMPLE FAR * JSAMPROW
Definition: jpeglib.h:75
#define JPOOL_IMAGE
Definition: jpeglib.h:808
if(dx< 0)
Definition: linetemp.h:194
#define for
Definition: utility.h:88
static PVOID ptr
Definition: dispmode.c:27
static void test_mac(void)
Definition: rsaenh.c:1849
#define long
Definition: qsort.c:33
#define ERREXIT(msg)
Definition: rdjpgcom.c:72
struct define * next
Definition: compiler.c:65
JDIMENSION rows_in_mem
Definition: jmemmgr.c:172
JDIMENSION maxaccess
Definition: jmemmgr.c:171
JDIMENSION rows_in_array
Definition: jmemmgr.c:169
backing_store_info b_s_info
Definition: jmemmgr.c:180
JDIMENSION blocksperrow
Definition: jmemmgr.c:170
JBLOCKARRAY mem_buffer
Definition: jmemmgr.c:168
JDIMENSION first_undef_row
Definition: jmemmgr.c:175
JDIMENSION rowsperchunk
Definition: jmemmgr.c:173
JDIMENSION cur_start_row
Definition: jmemmgr.c:174
jvirt_barray_ptr next
Definition: jmemmgr.c:179
JDIMENSION first_undef_row
Definition: jmemmgr.c:159
JDIMENSION rows_in_array
Definition: jmemmgr.c:153
JDIMENSION samplesperrow
Definition: jmemmgr.c:154
JDIMENSION maxaccess
Definition: jmemmgr.c:155
JDIMENSION cur_start_row
Definition: jmemmgr.c:158
JDIMENSION rows_in_mem
Definition: jmemmgr.c:156
backing_store_info b_s_info
Definition: jmemmgr.c:164
JSAMPARRAY mem_buffer
Definition: jmemmgr.c:152
JDIMENSION rowsperchunk
Definition: jmemmgr.c:157
jvirt_sarray_ptr next
Definition: jmemmgr.c:163
Definition: mem.c:156
jvirt_barray_ptr virt_barray_list
Definition: jmemmgr.c:130
size_t total_space_allocated
Definition: jmemmgr.c:133
JDIMENSION last_rowsperchunk
Definition: jmemmgr.c:138
jvirt_sarray_ptr virt_sarray_list
Definition: jmemmgr.c:129
Definition: name.c:39
size_t bytes_used
Definition: jmemmgr.c:106
ALIGN_TYPE dummy
Definition: jmemmgr.c:109
size_t bytes_left
Definition: jmemmgr.c:107
struct large_pool_struct::@188 hdr
large_pool_ptr next
Definition: jmemmgr.c:105
small_pool_ptr next
Definition: jmemmgr.c:94
ALIGN_TYPE dummy
Definition: jmemmgr.c:98
size_t bytes_left
Definition: jmemmgr.c:96
size_t bytes_used
Definition: jmemmgr.c:95
struct small_pool_struct::@187 hdr
static GLenum which
Definition: wgl_font.c:159