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

📄 jmemmgr.pas

📁 DELPHI版的JPEG文件解码源程序
💻 PAS
📖 第 1 页 / 共 4 页
字号:
  access_virt_sarray := JSAMPARRAY(@ ptr^.mem_buffer^[start_row - ptr^.cur_start_row]);
end;


{METHODDEF}
function access_virt_barray (cinfo : j_common_ptr;
                             ptr : jvirt_barray_ptr;
		             start_row : JDIMENSION;
                             num_rows : JDIMENSION;
		             writable : boolean) : JBLOCKARRAY; far;
{ Access the part of a virtual block array starting at start_row }
{ and extending for num_rows rows.  writable is true if  }
{ caller intends to modify the accessed area. }
var
  end_row : JDIMENSION;
  undef_row : JDIMENSION;
  ltemp : long;
var
  bytesperrow : size_t;
begin
  end_row := start_row + num_rows;

  { debugging check }
  if (end_row > ptr^.rows_in_array) or (num_rows > ptr^.maxaccess) or
     (ptr^.mem_buffer = NIL) then
    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);

  { Make the desired part of the virtual array accessible }
  if (start_row < ptr^.cur_start_row) or
     (end_row > ptr^.cur_start_row+ptr^.rows_in_mem) then
  begin
    if (not ptr^.b_s_open) then
      ERREXIT(cinfo, JERR_VIRTUAL_BUG);
    { Flush old buffer contents if necessary }
    if (ptr^.dirty) then
    begin
      do_barray_io(cinfo, ptr, TRUE);
      ptr^.dirty := FALSE;
    end;
    { Decide what part of virtual array to access.
      Algorithm: if target address > current window, assume forward scan,
      load starting at target address.  If target address < current window,
      assume backward scan, load so that target area is top of window.
      Note that when switching from forward write to forward read, will have
      start_row := 0, so the limiting case applies and we load from 0 anyway. }

    if (start_row > ptr^.cur_start_row) then
    begin
      ptr^.cur_start_row := start_row;
    end
    else
    begin
      { use long arithmetic here to avoid overflow & unsigned problems }

      ltemp := long(end_row) - long(ptr^.rows_in_mem);
      if (ltemp < 0) then
	ltemp := 0;		{ don't fall off front end of file }
      ptr^.cur_start_row := JDIMENSION (ltemp);
    end;
    { Read in the selected part of the array.
      During the initial write pass, we will do no actual read
      because the selected part is all undefined. }

    do_barray_io(cinfo, ptr, FALSE);
  end;
  { Ensure the accessed part of the array is defined; prezero if needed.
    To improve locality of access, we only prezero the part of the array
    that the caller is about to access, not the entire in-memory array. }

  if (ptr^.first_undef_row < end_row) then
  begin
    if (ptr^.first_undef_row < start_row) then
    begin
      if (writable) then	{ writer skipped over a section of array }
	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
      undef_row := start_row;	{ but reader is allowed to read ahead }
    end
    else
    begin
      undef_row := ptr^.first_undef_row;
    end;
    if (writable) then
      ptr^.first_undef_row := end_row;
    if (ptr^.pre_zero) then
    begin
      bytesperrow := size_t (ptr^.blocksperrow) * SIZEOF(JBLOCK);
      Dec(undef_row, ptr^.cur_start_row); { make indexes relative to buffer }
      Dec(end_row, ptr^.cur_start_row);
      while (undef_row < end_row) do
      begin
	jzero_far({FAR}pointer(ptr^.mem_buffer^[undef_row]), bytesperrow);
	Inc(undef_row);
      end;
    end
    else
    begin
      if (not writable) then	{ reader looking at undefined data }
	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
    end;
  end;
  { Flag the buffer dirty if caller will write in it }
  if (writable) then
    ptr^.dirty := TRUE;
  { Return address of proper part of the buffer }
  access_virt_barray := JBLOCKARRAY(@ ptr^.mem_buffer^[start_row - ptr^.cur_start_row]);
end;


{ Release all objects belonging to a specified pool. }

{METHODDEF}
procedure free_pool (cinfo : j_common_ptr; pool_id : int); far;
var
  mem : my_mem_ptr;
  shdr_ptr : small_pool_ptr;
  lhdr_ptr : large_pool_ptr;
  space_freed : size_t;
var
  sptr : jvirt_sarray_ptr;
  bptr : jvirt_barray_ptr;
var
  next_lhdr_ptr : large_pool_ptr;
  next_shdr_ptr : small_pool_ptr;
begin
  mem := my_mem_ptr(cinfo^.mem);

  if (pool_id < 0) or (pool_id >= JPOOL_NUMPOOLS) then
    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	{ safety check }

{$ifdef MEM_STATS}
  if (cinfo^.err^.trace_level > 1) then
    print_mem_stats(cinfo, pool_id); { print pool's memory usage statistics }
{$endif}

  { If freeing IMAGE pool, close any virtual arrays first }
  if (pool_id = JPOOL_IMAGE) then
  begin
    sptr := mem^.virt_sarray_list;
    while (sptr <> NIL) do
    begin
      if (sptr^.b_s_open) then
      begin	{ there may be no backing store }
	sptr^.b_s_open := FALSE;	{ prevent recursive close if error }
	sptr^.b_s_info.close_backing_store (cinfo, @sptr^.b_s_info);
      end;
      sptr := sptr^.next;
    end;
    mem^.virt_sarray_list := NIL;
    bptr := mem^.virt_barray_list;
    while (bptr <> NIL) do
    begin
      if (bptr^.b_s_open) then
      begin	{ there may be no backing store }
	bptr^.b_s_open := FALSE;	{ prevent recursive close if error }
	bptr^.b_s_info.close_backing_store (cinfo, @bptr^.b_s_info);
      end;
      bptr := bptr^.next;
    end;
    mem^.virt_barray_list := NIL;
  end;

  { Release large objects }
  lhdr_ptr := mem^.large_list[pool_id];
  mem^.large_list[pool_id] := NIL;

  while (lhdr_ptr <> NIL) do
  begin
    next_lhdr_ptr := lhdr_ptr^.hdr.next;
    space_freed := lhdr_ptr^.hdr.bytes_used +
		  lhdr_ptr^.hdr.bytes_left +
		  SIZEOF(large_pool_hdr);
    jpeg_free_large(cinfo, {FAR} pointer(lhdr_ptr), space_freed);
    Dec(mem^.total_space_allocated, space_freed);
    lhdr_ptr := next_lhdr_ptr;
  end;

  { Release small objects }
  shdr_ptr := mem^.small_list[pool_id];
  mem^.small_list[pool_id] := NIL;

  while (shdr_ptr <> NIL) do
  begin
    next_shdr_ptr := shdr_ptr^.hdr.next;
    space_freed := shdr_ptr^.hdr.bytes_used +
		  shdr_ptr^.hdr.bytes_left +
		  SIZEOF(small_pool_hdr);
    jpeg_free_small(cinfo, pointer(shdr_ptr), space_freed);
    Dec(mem^.total_space_allocated, space_freed);
    shdr_ptr := next_shdr_ptr;
  end;
end;


{ Close up shop entirely.
  Note that this cannot be called unless cinfo^.mem is non-NIL. }

{METHODDEF}
procedure self_destruct (cinfo : j_common_ptr); far;
var
  pool : int;
begin
  { Close all backing store, release all memory.
    Releasing pools in reverse order might help avoid fragmentation
    with some (brain-damaged) malloc libraries. }

  for pool := JPOOL_NUMPOOLS-1 downto JPOOL_PERMANENT do
  begin
    free_pool(cinfo, pool);
  end;

  { Release the memory manager control block too. }
  jpeg_free_small(cinfo, pointer(cinfo^.mem), SIZEOF(my_memory_mgr));
  cinfo^.mem := NIL;		{ ensures I will be called only once }

  jpeg_mem_term(cinfo);		{ system-dependent cleanup }
end;


{ Memory manager initialization.
  When this is called, only the error manager pointer is valid in cinfo! }

{GLOBAL}
procedure jinit_memory_mgr (cinfo : j_common_ptr);
var
  mem : my_mem_ptr;
  max_to_use : long;
  pool : int;
  test_mac : size_t;
{$ifndef NO_GETENV}
var
  memenv : string;
  code : integer;
{$endif}
begin
  cinfo^.mem := NIL;		{ for safety if init fails }

  { Check for configuration errors.
    SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
    doesn't reflect any real hardware alignment requirement.
    The test is a little tricky: for X>0, X and X-1 have no one-bits
    in common if and only if X is a power of 2, ie has only one one-bit.
    Some compilers may give an "unreachable code" warning here; ignore it. }
  if ((SIZEOF(ALIGN_TYPE) and (SIZEOF(ALIGN_TYPE)-1)) <> 0) then
    ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
  { MAX_ALLOC_CHUNK must be representable as type size_t, and must be
    a multiple of SIZEOF(ALIGN_TYPE).
    Again, an "unreachable code" warning may be ignored here.
    But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. }

  test_mac := size_t (MAX_ALLOC_CHUNK);
  if (long (test_mac) <> MAX_ALLOC_CHUNK) or
      ((MAX_ALLOC_CHUNK mod SIZEOF(ALIGN_TYPE)) <> 0) then
    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);

  max_to_use := jpeg_mem_init(cinfo); { system-dependent initialization }

  { Attempt to allocate memory manager's control block }
  mem := my_mem_ptr (jpeg_get_small(cinfo, SIZEOF(my_memory_mgr)));

  if (mem = NIL) then
  begin
    jpeg_mem_term(cinfo);	{ system-dependent cleanup }
    ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
  end;

  { OK, fill in the method pointers }
  mem^.pub.alloc_small := alloc_small;
  mem^.pub.alloc_large := alloc_large;
  mem^.pub.alloc_sarray := alloc_sarray;
  mem^.pub.alloc_barray := alloc_barray;
  mem^.pub.request_virt_sarray := request_virt_sarray;
  mem^.pub.request_virt_barray := request_virt_barray;
  mem^.pub.realize_virt_arrays := realize_virt_arrays;
  mem^.pub.access_virt_sarray := access_virt_sarray;
  mem^.pub.access_virt_barray := access_virt_barray;
  mem^.pub.free_pool := free_pool;
  mem^.pub.self_destruct := self_destruct;

  { Make MAX_ALLOC_CHUNK accessible to other modules }
  mem^.pub.max_alloc_chunk := MAX_ALLOC_CHUNK;

  { Initialize working state }
  mem^.pub.max_memory_to_use := max_to_use;

  for pool := JPOOL_NUMPOOLS-1 downto JPOOL_PERMANENT do
  begin
    mem^.small_list[pool] := NIL;
    mem^.large_list[pool] := NIL;
  end;
  mem^.virt_sarray_list := NIL;
  mem^.virt_barray_list := NIL;

  mem^.total_space_allocated := SIZEOF(my_memory_mgr);

  { Declare ourselves open for business }
  cinfo^.mem := @mem^.pub;

  { Check for an environment variable JPEGMEM; if found, override the
    default max_memory setting from jpeg_mem_init.  Note that the
    surrounding application may again override this value.
    If your system doesn't support getenv(), define NO_GETENV to disable
    this feature. }

{$ifndef NO_GETENV}
  memenv := getenv('JPEGMEM');
  if (memenv <> '') then
  begin
    Val(memenv, max_to_use, code);
    if (Code = 0) then
    begin
      max_to_use := max_to_use * long(1000);
      mem^.pub.max_memory_to_use := max_to_use * long(1000);
    end;
  end;
{$endif}

end;

end.

⌨️ 快捷键说明

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