⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jmemmgr.c

📁 EVM板JPEG实现,Texas Instruments TMS320C54x EVM JPEG
💻 C
📖 第 1 页 / 共 3 页
字号:
  hdr = (small_sarray_ptr) alloc_small((size_t) (numrows * SIZEOF(JSAMPROW)
						 + SIZEOF(small_sarray_hdr)));

  result = (JSAMPARRAY) (hdr+1); /* advance past header */

  /* Insert into list now so free_all does right thing if I fail */
  /* after allocating only some of the rows... */
  hdr->next = small_sarray_list;
  hdr->numrows = 0;
  hdr->rowsperchunk = rowsperchunk;
  small_sarray_list = hdr;

  /* Get the rows themselves; on 80x86 these are "far" */
  currow = 0;
  while (currow < numrows) {
	rowsperchunk = MIN(rowsperchunk, numrows - currow);
#ifdef MEM_STATS
	total_bytes_sarray += rowsperchunk * samplesperrow * SIZEOF(JSAMPLE)
			  + MALLOC_FAR_OVERHEAD;
#endif
	workspace = (JSAMPROW) jget_large((size_t) (rowsperchunk * samplesperrow
						* SIZEOF(JSAMPLE)));
	if (workspace == NULL)
	  out_of_memory(3);
	for (i = rowsperchunk; i > 0; i--) {
	  result[currow++] = workspace;
	  workspace += samplesperrow;
	}
	hdr->numrows = currow;
  }

  return result;
}


METHODDEF void
free_small_sarray (JSAMPARRAY ptr)
/* Free a "small" (all-in-memory) 2-D sample array */
{
  small_sarray_ptr hdr;
  small_sarray_ptr * llink;
  long i;

  hdr = (small_sarray_ptr) ptr;
  hdr--;                        /* point back to header */

  /* Remove item from list -- linear search is fast enough */
  llink = &small_sarray_list;
  while (*llink != hdr) {
	llink = &( (*llink)->next );
  }
  *llink = hdr->next;

  /* Free the rows themselves; on 80x86 these are "far" */
  /* Note we only free the row-group headers! */
  for (i = 0; i < hdr->numrows; i += hdr->rowsperchunk) {
	jfree_large((void FAR *) ptr[i]);
  }

  /* Free header and row pointers */
  free_small((void *) hdr);

#ifdef MEM_STATS
  cur_num_sarray--;
#endif
}


/*
 * Management of "small" (all-in-memory) 2-D coefficient-block arrays.
 * This is essentially the same as the code for sample arrays, above.
 */

typedef struct small_barray_struct * small_barray_ptr;

typedef struct small_barray_struct {
	small_barray_ptr next;  /* next in list of allocated barrays */
	long numrows;           /* # of rows in this array */
	long rowsperchunk;      /* max # of rows per allocation chunk */
	JBLOCKROW dummy;        /* ensures alignment of following storage */
	  } small_barray_hdr;

static small_barray_ptr small_barray_list; /* head of list */


METHODDEF JBLOCKARRAY
alloc_small_barray (long blocksperrow, long numrows)
/* Allocate a "small" (all-in-memory) 2-D coefficient-block array */
{
  small_barray_ptr hdr;
  JBLOCKARRAY result;
  JBLOCKROW workspace;
  long rowsperchunk, currow, i;

#ifdef MEM_STATS
  total_num_barray++;
  cur_num_barray++;
  if (cur_num_barray > max_num_barray) max_num_barray = cur_num_barray;
#endif

  /* Calculate max # of rows allowed in one allocation chunk */
  rowsperchunk = MAX_ALLOC_CHUNK / (blocksperrow * SIZEOF(JBLOCK));

  /* Get space for header and row pointers; this is always "near" on 80x86 */
  hdr = (small_barray_ptr) alloc_small((size_t) (numrows * SIZEOF(JBLOCKROW)
						 + SIZEOF(small_barray_hdr)));

  result = (JBLOCKARRAY) (hdr+1); /* advance past header */

  /* Insert into list now so free_all does right thing if I fail */
  /* after allocating only some of the rows... */
  hdr->next = small_barray_list;
  hdr->numrows = 0;
  hdr->rowsperchunk = rowsperchunk;
  small_barray_list = hdr;

  /* Get the rows themselves; on 80x86 these are "far" */
  currow = 0;
  while (currow < numrows) {
	rowsperchunk = MIN(rowsperchunk, numrows - currow);
#ifdef MEM_STATS
	total_bytes_barray += rowsperchunk * blocksperrow * SIZEOF(JBLOCK)
			  + MALLOC_FAR_OVERHEAD;
#endif
	workspace = (JBLOCKROW) jget_large((size_t) (rowsperchunk * blocksperrow
						 * SIZEOF(JBLOCK)));
	if (workspace == NULL)
	  out_of_memory(4);
	for (i = rowsperchunk; i > 0; i--) {
	  result[currow++] = workspace;
	  workspace += blocksperrow;
	}
	hdr->numrows = currow;
  }

  return result;
}


METHODDEF void
free_small_barray (JBLOCKARRAY ptr)
/* Free a "small" (all-in-memory) 2-D coefficient-block array */
{
  small_barray_ptr hdr;
  small_barray_ptr * llink;
  long i;

  hdr = (small_barray_ptr) ptr;
  hdr--;                        /* point back to header */

  /* Remove item from list -- linear search is fast enough */
  llink = &small_barray_list;
  while (*llink != hdr) {
	llink = &( (*llink)->next );
  }
  *llink = hdr->next;

  /* Free the rows themselves; on 80x86 these are "far" */
  /* Note we only free the row-group headers! */
  for (i = 0; i < hdr->numrows; i += hdr->rowsperchunk) {
	jfree_large((void FAR *) ptr[i]);
  }

  /* Free header and row pointers */
  free_small((void *) hdr);

#ifdef MEM_STATS
  cur_num_barray--;
#endif
}



/*
 * About "big" array management:
 *
 * To allow machines with limited memory to handle large images,
 * all processing in the JPEG system is done a few pixel or block rows
 * at a time.  The above "small" array routines are only used to allocate
 * strip buffers (as wide as the image, but just a few rows high).
 * In some cases multiple passes must be made over the data.  In these
 * cases the "big" array routines are used.  The array is still accessed
 * a strip at a time, but the memory manager must save the whole array
 * for repeated accesses.  The intended implementation is that there is
 * a strip buffer in memory (as high as is possible given the desired memory
 * limit), plus a backing file that holds the rest of the array.
 *
 * The request_big_array routines are told the total size of the image (in case
 * it is useful to know the total file size that will be needed).  They are
 * also given the unit height, which is the number of rows that will be
 * accessed at once; the in-memory buffer should be made a multiple of
 * this height for best efficiency.
 *
 * The request routines create control blocks (and may open backing files),
 * but they don't create the in-memory buffers.  This is postponed until
 * alloc_big_arrays is called.  At that time the total amount of space needed
 * is known (approximately, anyway), so free memory can be divided up fairly.
 *
 * The access_big_array routines are responsible for making a specific strip
 * area accessible (after reading or writing the backing file, if necessary).
 * Note that the access routines are told whether the caller intends to modify
 * the accessed strip; during a read-only pass this saves having to rewrite
 * data to disk.
 *
 * The typical access pattern is one top-to-bottom pass to write the data,
 * followed by one or more read-only top-to-bottom passes.  However, other
 * access patterns may occur while reading.  For example, translation of image
 * formats that use bottom-to-top scan order will require bottom-to-top read
 * passes.  The memory manager need not support multiple write passes nor
 * funny write orders (meaning that rearranging rows must be handled while
 * reading data out of the big array, not while putting it in).
 *
 * In current usage, the access requests are always for nonoverlapping strips;
 * that is, successive access start_row numbers always differ by exactly the
 * unitheight.  This allows fairly simple buffer dump/reload logic if the
 * in-memory buffer is made a multiple of the unitheight.  It would be
 * possible to keep downsampled rather than fullsize data in the "big" arrays,
 * thus reducing temp file size, if we supported overlapping strip access
 * (access requests differing by less than the unitheight).  At the moment
 * I don't believe this is worth the extra complexity.
 */



/* The control blocks for virtual arrays.
 * System-dependent info for the associated backing store is hidden inside
 * the backing_store_info struct.
 */

struct big_sarray_control {
	long rows_in_array;     /* total virtual array height */
	long samplesperrow;     /* width of array (and of memory buffer) */
	long unitheight;        /* # of rows accessed by access_big_sarray() */
	JSAMPARRAY mem_buffer;  /* the in-memory buffer */
	long rows_in_mem;       /* height of memory buffer */
	long rowsperchunk;      /* allocation chunk size in mem_buffer */
	long cur_start_row;     /* first logical row # in the buffer */
	boolean dirty;          /* do current buffer contents need written? */
	boolean b_s_open;       /* is backing-store data valid? */
	big_sarray_ptr next;    /* link to next big sarray control block */
	backing_store_info b_s_info; /* System-dependent control info */
};

static big_sarray_ptr big_sarray_list; /* head of list */

struct big_barray_control {
	long rows_in_array;     /* total virtual array height */
	long blocksperrow;      /* width of array (and of memory buffer) */
	long unitheight;        /* # of rows accessed by access_big_barray() */
	JBLOCKARRAY mem_buffer; /* the in-memory buffer */
	long rows_in_mem;       /* height of memory buffer */
	long rowsperchunk;      /* allocation chunk size in mem_buffer */
	long cur_start_row;     /* first logical row # in the buffer */
	boolean dirty;          /* do current buffer contents need written? */
	boolean b_s_open;       /* is backing-store data valid? */
	big_barray_ptr next;    /* link to next big barray control block */
	backing_store_info b_s_info; /* System-dependent control info */
};

static big_barray_ptr big_barray_list; /* head of list */


METHODDEF big_sarray_ptr
request_big_sarray (long samplesperrow, long numrows, long unitheight)
/* Request a "big" (virtual-memory) 2-D sample array */
{
  big_sarray_ptr result;

  /* get control block */
  result = (big_sarray_ptr) alloc_small(SIZEOF(struct big_sarray_control));

  result->rows_in_array = numrows;
  result->samplesperrow = samplesperrow;
  result->unitheight = unitheight;
  result->mem_buffer = NULL;    /* marks array not yet realized */
  result->b_s_open = FALSE;     /* no associated backing-store object */
  result->next = big_sarray_list; /* add to list of big arrays */
  big_sarray_list = result;

  return result;
}


METHODDEF big_barray_ptr
request_big_barray (long blocksperrow, long numrows, long unitheight)
/* Request a "big" (virtual-memory) 2-D coefficient-block array */
{
  big_barray_ptr result;

  /* get control block */
  result = (big_barray_ptr) alloc_small(SIZEOF(struct big_barray_control));

  result->rows_in_array = numrows;
  result->blocksperrow = blocksperrow;
  result->unitheight = unitheight;
  result->mem_buffer = NULL;    /* marks array not yet realized */
  result->b_s_open = FALSE;     /* no associated backing-store object */
  result->next = big_barray_list; /* add to list of big arrays */
  big_barray_list = result;

  return result;
}


METHODDEF void
alloc_big_arrays (long extra_small_samples, long extra_small_blocks,
		  long extra_medium_space)
/* Allocate the in-memory buffers for any unrealized "big" arrays */
/* 'extra' values are upper bounds for total future small-array requests */
/* and far-heap requests */
{
  long total_extra_space = extra_small_samples * SIZEOF(JSAMPLE)
			   + extra_small_blocks * SIZEOF(JBLOCK)
			   + extra_medium_space;
  long space_per_unitheight, maximum_space, avail_mem;
  long unitheights, max_unitheights;
  big_sarray_ptr sptr;
  big_barray_ptr bptr;

  /* Compute the minimum space needed (unitheight rows in each buffer)
   * and the maximum space needed (full image height in each buffer).
   * These may be of use to the system-dependent jmem_available routine.
   */
  space_per_unitheight = 0;
  maximum_space = total_extra_space;
  for (sptr = big_sarray_list; sptr != NULL; sptr = sptr->next) {
	if (sptr->mem_buffer == NULL) { /* if not realized yet */
	  space_per_unitheight += sptr->unitheight *
				  sptr->samplesperrow * SIZEOF(JSAMPLE);
	  maximum_space += sptr->rows_in_array *
			   sptr->samplesperrow * SIZEOF(JSAMPLE);
	}
  }
  for (bptr = big_barray_list; bptr != NULL; bptr = bptr->next) {
	if (bptr->mem_buffer == NULL) { /* if not realized yet */
	  space_per_unitheight += bptr->unitheight *
				  bptr->blocksperrow * SIZEOF(JBLOCK);
	  maximum_space += bptr->rows_in_array *
			   bptr->blocksperrow * SIZEOF(JBLOCK);
	}
  }

  if (space_per_unitheight <= 0)
	return;                     /* no unrealized arrays, no work */

  /* Determine amount of memory to actually use; this is system-dependent. */
  avail_mem = jmem_available(space_per_unitheight + total_extra_space,
				 maximum_space);

  /* If the maximum space needed is available, make all the buffers full
   * height; otherwise parcel it out with the same number of unitheights
   * in each buffer.
   */
  if (avail_mem >= maximum_space)
	max_unitheights = 1000000000L;
  else {
	max_unitheights = (avail_mem - total_extra_space) / space_per_unitheight;
	/* If there doesn't seem to be enough space, try to get the minimum
	 * anyway.  This allows a "stub" implementation of jmem_available().
	 */
	if (max_unitheights <= 0)
	  max_unitheights = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -