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

📄 jmemmgr.pas

📁 DELPHI版的JPEG文件解码源程序
💻 PAS
📖 第 1 页 / 共 4 页
字号:
  bptr : jvirt_barray_ptr;
begin
  mem := my_mem_ptr (cinfo^.mem);
  { Compute the minimum space needed (maxaccess rows in each buffer)
    and the maximum space needed (full image height in each buffer).
    These may be of use to the system-dependent jpeg_mem_available routine. }

  space_per_minheight := 0;
  maximum_space := 0;
  sptr := mem^.virt_sarray_list;
  while (sptr <> NIL) do
  begin
    if (sptr^.mem_buffer = NIL) then
    begin { if not realized yet }
      Inc(space_per_minheight, long(sptr^.maxaccess) *
			     long(sptr^.samplesperrow) * SIZEOF(JSAMPLE));
      Inc(maximum_space, long(sptr^.rows_in_array) *
		       long(sptr^.samplesperrow) * SIZEOF(JSAMPLE));
    end;
    sptr := sptr^.next;
  end;
  bptr := mem^.virt_barray_list;
  while (bptr <> NIL) do
  begin
    if (bptr^.mem_buffer = NIL) then
    begin { if not realized yet }
      Inc(space_per_minheight, long(bptr^.maxaccess) *
			     long(bptr^.blocksperrow) * SIZEOF(JBLOCK));
      Inc(maximum_space, long(bptr^.rows_in_array) *
		       long(bptr^.blocksperrow) * SIZEOF(JBLOCK));
    end;
    bptr := bptr^.next;
  end;

  if (space_per_minheight <= 0) then
    exit;			{ no unrealized arrays, no work }

  { Determine amount of memory to actually use; this is system-dependent. }
  avail_mem := jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
				 mem^.total_space_allocated);

  { If the maximum space needed is available, make all the buffers full
    height; otherwise parcel it out with the same number of minheights
    in each buffer. }

  if (avail_mem >= maximum_space) then
    max_minheights := long(1000000000)
  else
  begin
    max_minheights := avail_mem div space_per_minheight;
    { If there doesn't seem to be enough space, try to get the minimum
      anyway.  This allows a "stub" implementation of jpeg_mem_available(). }
    if (max_minheights <= 0) then
      max_minheights := 1;
  end;

  { Allocate the in-memory buffers and initialize backing store as needed. }

  sptr := mem^.virt_sarray_list;
  while (sptr <> NIL) do
  begin
    if (sptr^.mem_buffer = NIL) then
    begin { if not realized yet }
      minheights := (long(sptr^.rows_in_array) - long(1)) div sptr^.maxaccess + long(1);
      if (minheights <= max_minheights) then
      begin
	{ This buffer fits in memory }
	sptr^.rows_in_mem := sptr^.rows_in_array;
      end
      else
      begin
	{ It doesn't fit in memory, create backing store. }
	sptr^.rows_in_mem := JDIMENSION (max_minheights * sptr^.maxaccess);
	jpeg_open_backing_store(cinfo,
                                @sptr^.b_s_info,
				long(sptr^.rows_in_array) *
				long(sptr^.samplesperrow) *
				long(SIZEOF(JSAMPLE)));
	sptr^.b_s_open := TRUE;
      end;
      sptr^.mem_buffer := alloc_sarray(cinfo, JPOOL_IMAGE,
				      sptr^.samplesperrow, sptr^.rows_in_mem);
      sptr^.rowsperchunk := mem^.last_rowsperchunk;
      sptr^.cur_start_row := 0;
      sptr^.first_undef_row := 0;
      sptr^.dirty := FALSE;
    end;
    sptr := sptr^.next;
  end;

  bptr := mem^.virt_barray_list;
  while (bptr <> NIL) do
  begin
    if (bptr^.mem_buffer = NIL) then
    begin { if not realized yet }
      minheights := (long(bptr^.rows_in_array) - long(1)) div bptr^.maxaccess + long(1);
      if (minheights <= max_minheights) then
      begin
	{ This buffer fits in memory }
	bptr^.rows_in_mem := bptr^.rows_in_array;
      end
      else
      begin
	{ It doesn't fit in memory, create backing store. }
	bptr^.rows_in_mem := JDIMENSION (max_minheights * bptr^.maxaccess);
	jpeg_open_backing_store(cinfo,
                                @bptr^.b_s_info,
				long(bptr^.rows_in_array) *
				long(bptr^.blocksperrow) *
				long(SIZEOF(JBLOCK)));
	bptr^.b_s_open := TRUE;
      end;
      bptr^.mem_buffer := alloc_barray(cinfo, JPOOL_IMAGE,
				      bptr^.blocksperrow, bptr^.rows_in_mem);
      bptr^.rowsperchunk := mem^.last_rowsperchunk;
      bptr^.cur_start_row := 0;
      bptr^.first_undef_row := 0;
      bptr^.dirty := FALSE;
    end;
    bptr := bptr^.next;
  end;
end;


{LOCAL}
procedure do_sarray_io (cinfo : j_common_ptr;
                        ptr : jvirt_sarray_ptr;
                        writing : boolean);
{ Do backing store read or write of a virtual sample array }
var
  bytesperrow, file_offset, byte_count, rows, thisrow, i : long;
begin

  bytesperrow := long(ptr^.samplesperrow * SIZEOF(JSAMPLE));
  file_offset := ptr^.cur_start_row * bytesperrow;
  { Loop to read or write each allocation chunk in mem_buffer }
  i := 0;
  while i < long(ptr^.rows_in_mem) do
  begin

    { One chunk, but check for short chunk at end of buffer }
    {rows := MIN(long(ptr^.rowsperchunk), long(ptr^.rows_in_mem - i));}
    rows := long(ptr^.rowsperchunk);
    if rows > long(ptr^.rows_in_mem - i) then
      rows := long(ptr^.rows_in_mem - i);
    { Transfer no more than is currently defined }
    thisrow := long (ptr^.cur_start_row) + i;
    {rows := MIN(rows, long(ptr^.first_undef_row) - thisrow);}
    if (rows > long(ptr^.first_undef_row) - thisrow) then
      rows := long(ptr^.first_undef_row) - thisrow;
    { Transfer no more than fits in file }
    {rows := MIN(rows, long(ptr^.rows_in_array) - thisrow);}
    if (rows > long(ptr^.rows_in_array) - thisrow) then
      rows := long(ptr^.rows_in_array) - thisrow;

    if (rows <= 0) then        { this chunk might be past end of file! }
      break;
    byte_count := rows * bytesperrow;
    if (writing) then
      ptr^.b_s_info.write_backing_store (cinfo,
                                        @ptr^.b_s_info,
					pointer {FAR} (ptr^.mem_buffer^[i]),
					file_offset, byte_count)
    else
      ptr^.b_s_info.read_backing_store (cinfo,
                                        @ptr^.b_s_info,
					pointer {FAR} (ptr^.mem_buffer^[i]),
					file_offset, byte_count);
    Inc(file_offset, byte_count);
    Inc(i, ptr^.rowsperchunk);
  end;
end;


{LOCAL}
procedure do_barray_io (cinfo : j_common_ptr;
                       ptr : jvirt_barray_ptr;
                       writing : boolean);
{ Do backing store read or write of a virtual coefficient-block array }
var
  bytesperrow, file_offset, byte_count, rows, thisrow, i : long;
begin
  bytesperrow := long (ptr^.blocksperrow) * SIZEOF(JBLOCK);
  file_offset := ptr^.cur_start_row * bytesperrow;
  { Loop to read or write each allocation chunk in mem_buffer }
  i := 0;
  while (i < long(ptr^.rows_in_mem)) do
  begin
    { One chunk, but check for short chunk at end of buffer }
    {rows := MIN(long(ptr^.rowsperchunk), long(ptr^.rows_in_mem - i));}
    rows := long(ptr^.rowsperchunk);
    if rows >long(ptr^.rows_in_mem - i) then
      rows := long(ptr^.rows_in_mem - i);
    { Transfer no more than is currently defined }
    thisrow := long (ptr^.cur_start_row) + i;
    {rows := MIN(rows, long(ptr^.first_undef_row - thisrow));}
    if rows > long(ptr^.first_undef_row - thisrow) then
      rows := long(ptr^.first_undef_row - thisrow);
    { Transfer no more than fits in file }
    {rows := MIN(rows, long (ptr^.rows_in_array - thisrow));}
    if (rows > long (ptr^.rows_in_array - thisrow)) then
      rows := long (ptr^.rows_in_array - thisrow);

    if (rows <= 0) then		{ this chunk might be past end of file! }
      break;
    byte_count := rows * bytesperrow;
    if (writing) then
      ptr^.b_s_info.write_backing_store (cinfo,
                                         @ptr^.b_s_info,
	                                 {FAR} pointer(ptr^.mem_buffer^[i]),
					  file_offset, byte_count)
    else
      ptr^.b_s_info.read_backing_store (cinfo,
                                        @ptr^.b_s_info,
					{FAR} pointer(ptr^.mem_buffer^[i]),
					file_offset, byte_count);
    Inc(file_offset, byte_count);
    Inc(i, ptr^.rowsperchunk);
  end;
end;


{METHODDEF}
function access_virt_sarray (cinfo : j_common_ptr;
                             ptr : jvirt_sarray_ptr;
		             start_row : JDIMENSION;
                             num_rows : JDIMENSION;
		             writable : boolean ) : JSAMPARRAY; far;
{ Access the part of a virtual sample 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;
var
  bytesperrow : size_t;
var
  ltemp : long;
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_sarray_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_sarray_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^.samplesperrow) * SIZEOF(JSAMPLE);
      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 }

⌨️ 快捷键说明

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