Repository URL to install this package:
Version:
2.0.10 ▾
|
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4 (Public License)
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
// Pascal Port By: Milan Marusinec alias Milano
// milan@marusinec.sk
// http://www.aggpas.org
// Copyright (c) 2005-2006
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//
// [Pascal Port History] -----------------------------------------------------
//
// 23.06.2006-Milano: ptrcomp adjustments
// 18.02.2006-MIlano: pod_array_adaptor, quick_sort
// 16.02.2006-Milano: pod_allocator
// 19.12.2005-Milano: pod_deque
// 15.11.2005-Milano: Unit port establishment
//
{ agg_array.pas }
unit
agg_array ;
INTERFACE
{$I agg_mode.inc }
uses
agg_basics ;
{ TYPES DEFINITION }
type
func_less = function(e1 ,e2 : pointer ) : boolean;
func_equal = function(e1 ,e2 : pointer ) : boolean;
array_base_ptr = ^array_base;
array_base = object
function size : unsigned; virtual; abstract;
function entry : unsigned; virtual; abstract;
function array_operator(i : unsigned ) : pointer; virtual; abstract;
function at(i : unsigned ) : pointer; virtual;
end;
//----------------------------------------------------------range_adaptor
range_adaptor = object(array_base )
private
m_array : array_base_ptr;
m_start ,
m_size : unsigned;
public
constructor Construct(array_ : array_base_ptr; start ,size_ : unsigned );
function size : unsigned; virtual;
function entry : unsigned; virtual;
function array_operator(i : unsigned ) : pointer; virtual;
end;
//-------------------------------------------------------pod_array_adaptor
pod_array_adaptor_ptr = ^pod_array_adaptor;
pod_array_adaptor = object(array_base )
m_array : pointer;
m_size ,
m_entry : unsigned;
constructor Construct(array_ : pointer; size_ ,entry_ : unsigned );
function size : unsigned; virtual;
function entry : unsigned; virtual;
function array_operator(i : unsigned ) : pointer; virtual;
function at(i : unsigned ) : pointer; virtual;
end;
//---------------------------------------------------------pod_auto_array
pod_auto_array_ptr = ^pod_auto_array;
pod_auto_array = object(array_base )
m_size ,
m_entry_sz : unsigned;
m_array : pointer;
constructor Construct(size_ ,entry_sz : unsigned );
destructor Destruct;
function size : unsigned; virtual;
function entry : unsigned; virtual;
function array_operator(i : unsigned ) : pointer; virtual;
end;
//---------------------------------------------------------------pod_array
// A simple class template to store Plain Old Data, a vector
// of a fixed size. The data is continous in memory
//------------------------------------------------------------------------
pod_array = object(array_base )
m_entry_sz ,
m_size ,
m_capacity : unsigned;
m_array : pointer;
constructor Construct(entry_sz : unsigned ); overload;
constructor Construct(entry_sz ,size_ : unsigned ); overload;
constructor Create (entry_sz ,size_ : unsigned );
destructor Destruct;
procedure allocate(size_ : unsigned; extra_tail : unsigned = 0 );
procedure resize (new_size : unsigned );
procedure capacity(cap ,extra_tail : unsigned );
procedure zero;
procedure add(v : pointer );
function data : pointer;
function size : unsigned; virtual;
function entry : unsigned; virtual;
function array_operator(i : unsigned ) : pointer; virtual;
end;
pod_vector = pod_array;
//---------------------------------------------------------------pod_deque
// A simple class template to store Plain Old Data, similar to std::deque
// It doesn't reallocate memory but instead, uses blocks of data of size
// of (1 << S), that is, power of two. The data is NOT contiguous in memory,
// so the only valid access method is operator [] or curr(), prev(), next()
//
// There reallocs occure only when the pool of pointers to blocks needs
// to be extended (it happens very rarely). You can control the value
// of increment to reallocate the pointer buffer. See the second constructor.
// By default, the incremeent value equals (1 << S), i.e., the block size.
//------------------------------------------------------------------------
pod_deque_ptr = ^pod_deque;
pod_deque = object(array_base )
block_shift ,
block_size ,
block_mask : unsigned;
m_size ,
m_num_blocks ,
m_max_blocks ,
m_block_ptr_inc : unsigned;
m_blocks : pointer;
m_entry_sz : unsigned;
constructor Construct(entry_sz : unsigned; s_ : unsigned = 6 ); overload;
constructor Construct(block_ptr_inc ,entry_sz : unsigned; s_ : unsigned ); overload;
destructor Destruct;
procedure remove_all;
procedure remove_last;
procedure add (val : pointer );
procedure modify_last(val : pointer );
procedure cut_at(size_ : unsigned );
function size : unsigned; virtual;
function entry : unsigned; virtual;
function array_operator (i : unsigned ) : pointer; virtual;
procedure assign_operator(v : pod_deque_ptr );
function curr(idx : unsigned ) : pointer;
function prev(idx : unsigned ) : pointer;
function next(idx : unsigned ) : pointer;
function last : pointer;
function allocate_continuous_block(num_elements : unsigned ) : int;
procedure allocate_block (nb : unsigned );
function data_ptr : pointer;
end;
pod_bvector_ptr = ^pod_bvector;
pod_bvector = pod_deque;
//-----------------------------------------------------------pod_allocator
// Allocator for arbitrary POD data. Most usable in different cache
// systems for efficient memory allocations.
// Memory is allocated with blocks of fixed size ("block_size" in
// the constructor). If required size exceeds the block size the allocator
// creates a new block of the required size. However, the most efficient
// use is when the average reqired size is much less than the block size.
//------------------------------------------------------------------------
pod_alloc_ptr = ^pod_alloc;
pod_alloc = record
ptr : int8u_ptr;
sz : unsigned;
end;
pod_allocator = object
m_block_size ,
m_block_ptr_inc ,
m_num_blocks ,
m_max_blocks : unsigned;
m_blocks : pod_alloc_ptr;
m_buf_ptr : int8u_ptr;
m_rest : unsigned;
constructor Construct(block_size : unsigned; block_ptr_inc : unsigned = 256 - 8 );
destructor Destruct;
procedure remove_all;
function allocate(size : unsigned; alignment : unsigned = 1 ) : int8u_ptr;
procedure allocate_block(size : unsigned );
end;
{ GLOBAL VARIABLES & CONSTANTS }
{ GLOBAL PROCEDURES }
procedure quick_sort (arr : array_base_ptr; less : func_less );
function remove_duplicates(arr : array_base_ptr; equal : func_equal ) : unsigned;
function int_less (a ,b : pointer ) : boolean;
function int_greater(a ,b : pointer ) : boolean;
function unsigned_less (a ,b : pointer ) : boolean;
function unsigned_greater(a ,b : pointer ) : boolean;
IMPLEMENTATION
{ LOCAL VARIABLES & CONSTANTS }
{ QUICK_SORT }
procedure quick_sort;
const
quick_sort_threshold = 9;
type
int80_ptr = ^int80;
int80 = array[0..79 ] of int;
var
temp ,e1 ,e2 : pointer;
swap : unsigned;
stack : int80;
top : int80_ptr;
limit ,base ,len ,i ,j ,pivot : int;
begin
if arr.size < 2 then
exit;
agg_getmem(temp ,arr.entry );
swap :=arr.entry;
top :=@stack;
limit:=arr.size;
base :=0;
repeat
len:=limit - base;
if len > quick_sort_threshold then
begin
// we use base + len/2 as the pivot
pivot:=base + len div 2;
// swap_elements(arr[base], arr[pivot]);
move(arr.at(base )^ ,temp^ ,swap );
move(arr.at(pivot )^ ,arr.at(base )^ ,swap );
move(temp^ ,arr.at(pivot )^ ,swap );
i:=base + 1;
j:=limit - 1;
// now ensure that *i <= *base <= *j
e1:=arr.at(j );
e2:=arr.at(i );
if less(e1 ,e2 ) then
begin
// swap_elements(*e1, *e2);
move(e1^ ,temp^ ,swap );
move(e2^ ,e1^ ,swap );
move(temp^ ,e2^ ,swap );
end;
e1:=arr.at(base );
e2:=arr.at(i );
if less(e1 ,e2 ) then
begin
// swap_elements(*e1, *e2);
move(e1^ ,temp^ ,swap );
move(e2^ ,e1^ ,swap );
move(temp^ ,e2^ ,swap );
end;
e1:=arr.at(j );
e2:=arr.at(base );
if less(e1 ,e2 ) then
begin
// swap_elements(*e1, *e2);
move(e1^ ,temp^ ,swap );
move(e2^ ,e1^ ,swap );
move(temp^ ,e2^ ,swap );
end;
repeat
repeat
inc(i )
until not less(arr.at(i ) ,arr.at(base ) );
repeat
dec(j );
until not less(arr.at(base ) ,arr.at(j ) );
if i > j then
break;
// swap_elements(arr[i], arr[j]);
move(arr.at(i )^ ,temp^ ,swap );
move(arr.at(j )^ ,arr.at(i )^ ,swap );
move(temp^ ,arr.at(j )^ ,swap );
until false;
// swap_elements(arr[base], arr[j]);
move(arr.at(base )^ ,temp^ ,swap );
move(arr.at(j )^ ,arr.at(base )^ ,swap );
move(temp^ ,arr.at(j )^ ,swap );
// now, push the largest sub-array
if j - base > limit - i then
begin
top^[0 ]:=base;
top^[1 ]:=j;
base :=i;
end
else
begin
top^[0 ]:=i;
top^[1 ]:=limit;
limit :=j;
end;
inc(ptrcomp(top ) ,2 * sizeof(int ) );
end
else
begin
// the sub-array is small, perform insertion sort
j:=base;
i:=j + 1;
while i < limit do
begin
e1:=arr.at(j + 1 );
e2:=arr.at(j );
while less(e1 ,e2 ) do
begin
// swap_elements(*e1, *e2);
move(e1^ ,temp^ ,swap );
move(e2^ ,e1^ ,swap );
move(temp^ ,e2^ ,swap );
if j = base then
break;
dec(j );
e1:=arr.at(j + 1 );
e2:=arr.at(j );
end;
j:=i;
inc(i );
end;
if ptrcomp(top ) > ptrcomp(@stack ) then
begin
dec(ptrcomp(top ) ,2 * sizeof(int ) );
base :=top^[0 ];
limit:=top^[1 ];
end
else
break;
end;
until false;
agg_freemem(temp ,arr.entry );
end;
{ REMOVE_DUPLICATES }
// Remove duplicates from a sorted array. It doesn't cut the
// tail of the array, it just returns the number of remaining elements.
function remove_duplicates(arr : array_base_ptr; equal : func_equal ) : unsigned;
var
i ,j : unsigned;
e : pointer;
begin
if arr.size < 2 then
begin
result:=arr.size;
exit;
end;
i:=1;
j:=1;
while i < arr.size do
begin
e:=arr.array_operator(i );
if not equal(e ,arr.array_operator(i - 1 ) ) then
begin
move(e^ ,arr.array_operator(j )^ ,arr.entry );
inc (j );
end;
inc(i );
end;
result:=j;
end;
{ INT_LESS }
function int_less(a ,b : pointer ) : boolean;
begin
result:=int_ptr(a )^ < int_ptr(b )^;
end;
{ INT_GREATER }
function int_greater(a ,b : pointer ) : boolean;
begin
result:=int_ptr(a )^ > int_ptr(b )^;
end;
{ UNSIGNED_LESS }
function unsigned_less(a ,b : pointer ) : boolean;
begin
result:=unsigned_ptr(a )^ < unsigned_ptr(b )^;
end;
{ UNSIGNED_GREATER }
function unsigned_greater(a ,b : pointer ) : boolean;
begin
result:=unsigned_ptr(a )^ > unsigned_ptr(b )^;
end;
{ UNIT IMPLEMENTATION }
{ AT }
function array_base.at;
begin
at:=array_operator(i );
end;
{ CONSTRUCT }
constructor range_adaptor.Construct(array_ : array_base_ptr; start ,size_ : unsigned );
begin
m_array:=array_;
m_start:=start;
m_size :=size_;
end;
{ SIZE }
function range_adaptor.size : unsigned;
begin
result:=m_size;
end;
{ ENTRY }
function range_adaptor.entry : unsigned;
begin
result:=m_array.entry;
end;
{ ARRAY_OPERATOR }
function range_adaptor.array_operator(i : unsigned ) : pointer;
begin
result:=m_array.array_operator(m_start + i );
end;
{ CONSTRUCT }
constructor pod_array_adaptor.Construct;
begin
m_array:=array_;
m_size :=size_;
m_entry:=entry_;
end;
{ SIZE }
function pod_array_adaptor.size;
begin
result:=m_size;
end;
{ ENTRY }
function pod_array_adaptor.entry;
begin
result:=m_entry;
end;
{ ARRAY_OPERATOR }
function pod_array_adaptor.array_operator;
begin
result:=pointer(ptrcomp(m_array ) + i * sizeof(m_entry ) );
end;
{ AT }
function pod_array_adaptor.at;
begin
result:=pointer(ptrcomp(m_array ) + i * m_entry );
end;
{ CONSTRUCT }
constructor pod_auto_array.Construct;
begin
m_size :=size_;
m_entry_sz:=entry_sz;
agg_getmem(m_array ,m_size * m_entry_sz );
end;
{ DESTRUCT }
destructor pod_auto_array.Destruct;
begin
agg_freemem(m_array ,m_size * m_entry_sz );
end;
{ SIZE }
function pod_auto_array.size;
begin
result:=m_size;
end;
{ ENTRY }
function pod_auto_array.entry;
begin
result:=m_entry_sz;
end;
{ ARRAY_OPERATOR }
function pod_auto_array.array_operator;
begin
result:=pointer(ptrcomp(m_array ) + i * m_entry_sz );
end;
{ CONSTRUCT }
constructor pod_array.Construct(entry_sz : unsigned );
begin
m_entry_sz:=entry_sz;
m_size :=0;
m_capacity:=0;
m_array:=NIL;
end;
{ CONSTRUCT }
constructor pod_array.Construct(entry_sz ,size_ : unsigned );
begin
Construct(entry_sz );
allocate (size_ );
end;
{ CREATE }
constructor pod_array.Create(entry_sz ,size_ : unsigned );
begin
Construct(entry_sz );
capacity (size_ ,0 );
end;
{ DESTRUCT }
destructor pod_array.Destruct;
begin
if m_array <> NIL then
agg_freemem(m_array ,m_capacity * m_entry_sz );
end;
{ ALLOCATE }
// Allocate n elements. All data is lost,
// but elements can be accessed in range 0...size-1.
procedure pod_array.allocate;
begin
capacity(size_ ,extra_tail );
m_size:=size_;
end;
{ RESIZE }
// Resize keeping the content.
procedure pod_array.resize;
var
buff : pointer;
begin
if new_size > m_size then
if new_size > m_capacity then
begin
agg_getmem(buff ,new_size * m_entry_sz );
if m_array <> NIL then
begin
move(m_array^ ,buff^ ,m_size * m_entry_sz );
agg_freemem(m_array ,m_capacity * m_entry_sz );
end;
m_array :=buff;
m_capacity:=new_size;
end
else
else
m_size:=new_size;
end;
{ CAPACITY }
procedure pod_array.capacity;
begin
m_size:=0;
if cap > m_capacity then
begin
agg_freemem(m_array ,m_capacity * m_entry_sz );
m_capacity:=cap + extra_tail;
if m_capacity > 0 then
agg_getmem(m_array ,m_capacity * m_entry_sz )
else
m_array:=0;
end;
end;
{ ZERO }
procedure pod_array.zero;
begin
fillchar(m_array^ ,m_entry_sz * m_size ,0 );
end;
{ ADD }
procedure pod_array.add(v : pointer );
begin
move(v^ ,pointer(ptrcomp(m_array ) + m_size * m_entry_sz )^ ,m_entry_sz );
inc (m_size );
end;
{ DATA }
function pod_array.data;
begin
result:=m_array;
end;
{ SIZE }
function pod_array.size;
begin
result:=m_size;
end;
{ ENTRY }
function pod_array.entry;
begin
result:=m_entry_sz;
end;
{ ARRAY_OPERATOR }
function pod_array.array_operator(i : unsigned ) : pointer;
begin
result:=pointer(ptrcomp(m_array ) + i * m_entry_sz );
end;
{ CONSTRUCT }
constructor pod_deque.Construct(entry_sz : unsigned; s_ : unsigned = 6 );
begin
block_shift:=s_;
block_size :=1 shl block_shift;
block_mask :=block_size - 1;
m_size :=0;
m_num_blocks :=0;
m_max_blocks :=0;
m_blocks :=0;
m_block_ptr_inc:=block_size;
m_entry_sz:=entry_sz;
end;
{ CONSTRUCT }
constructor pod_deque.Construct(block_ptr_inc ,entry_sz : unsigned; s_ : unsigned );
begin
Construct(entry_sz ,s_ );
m_block_ptr_inc:=block_ptr_inc;
end;
{ DESTRUCT }
destructor pod_deque.Destruct;
var
blk : pointer;
begin
if m_num_blocks <> 0 then
begin
blk:=pointer(ptrcomp(m_blocks ) + (m_num_blocks - 1 ) * sizeof(pointer ) );
while m_num_blocks <> 0 do
begin
agg_freemem(p32(blk^ ).ptr ,block_size * m_entry_sz );
dec(ptrcomp(blk ) ,sizeof(pointer ) );
dec(m_num_blocks );
end;
agg_freemem(m_blocks ,m_max_blocks * sizeof(pointer ) );
end;
end;
{ REMOVE_ALL }
procedure pod_deque.remove_all;
begin
m_size:=0;
end;
{ REMOVE_LAST }
procedure pod_deque.remove_last;
begin
if m_size <> 0 then
dec(m_size );
end;
{ ADD }
procedure pod_deque.add;
var
p : pointer;
begin
p:=data_ptr;
move(val^ ,p^ ,m_entry_sz );
inc (m_size );
end;
{ MODIFY_LAST }
procedure pod_deque.modify_last;
begin
remove_last;
add(val );
end;
{ CUT_AT }
procedure pod_deque.cut_at(size_ : unsigned );
begin
if size_ < m_size then
m_size:=size_;
end;
{ SIZE }
function pod_deque.size;
begin
result:=m_size;
end;
{ ENTRY }
function pod_deque.entry;
begin
result:=m_entry_sz;
end;
{ ARRAY_OPERATOR }
function pod_deque.array_operator;
begin
result:=
pointer(
p32(pointer(ptrcomp(m_blocks ) + (i shr block_shift ) * sizeof(pointer ) )^ ).int
+ (i and block_mask ) * m_entry_sz );
end;
{ ASSIGN_OPERATOR }
procedure pod_deque.assign_operator;
var
i : unsigned;
src ,
dst : pointer;
begin
Destruct;
block_shift:=v.block_shift;
block_size :=v.block_size;
block_mask :=v.block_mask;
m_size :=v.m_size;
m_entry_sz:=v.m_entry_sz;
m_num_blocks:=v.m_num_blocks;
m_max_blocks:=v.m_max_blocks;
m_block_ptr_inc:=v.m_block_ptr_inc;
if m_max_blocks <> 0 then
agg_getmem(m_blocks ,m_max_blocks * sizeof(pointer ) )
else
m_blocks:=NIL;
src:=v.m_blocks;
dst:=m_blocks;
i :=0;
while i < m_num_blocks do
begin
agg_getmem(p32(dst^ ).ptr ,block_size * m_entry_sz );
move(
p32(src^ ).ptr^ ,
p32(dst^ ).ptr^ ,
block_size * m_entry_sz );
inc(ptrcomp(src ) ,sizeof(pointer ) );
inc(ptrcomp(dst ) ,sizeof(pointer ) );
inc(i );
end;
end;
{ CURR }
function pod_deque.curr;
begin
result:=array_operator(idx );
end;
{ PREV }
function pod_deque.prev;
begin
result:=array_operator((idx + m_size - 1 ) mod m_size );
end;
{ NEXT }
function pod_deque.next;
begin
result:=array_operator((idx + 1 ) mod m_size );
end;
{ LAST }
function pod_deque.last : pointer;
begin
result:=array_operator(m_size - 1 );
end;
{ ALLOCATE_CONTINUOUS_BLOCK }
function pod_deque.allocate_continuous_block;
var
rest ,index : unsigned;
begin
if num_elements < block_size then
begin
data_ptr; // Allocate initial block if necessary
rest:=block_size - (m_size and block_mask );
if num_elements <= rest then
begin
// The rest of the block is good, we can use it
index:=m_size;
inc(m_size ,num_elements );
result:=index;
exit;
end;
// New block
inc(m_size ,rest );
data_ptr;
index:=m_size;
inc(m_size ,num_elements );
result:=index;
exit;
end;
result:=-1; // Impossible to allocate
end;
{ ALLOCATE_BLOCK }
procedure pod_deque.allocate_block;
var
new_blocks : pointer;
begin
if nb >= m_max_blocks then
begin
agg_getmem(new_blocks ,(m_max_blocks + m_block_ptr_inc ) * sizeof(pointer ) );
if m_blocks <> NIL then
begin
move(
m_blocks^ ,
new_blocks^ ,
m_num_blocks * sizeof(pointer ) );
agg_freemem(m_blocks ,m_max_blocks * sizeof(pointer ) );
end;
m_blocks:=new_blocks;
inc(m_max_blocks ,m_block_ptr_inc );
end;
agg_getmem(
p32(pointer(ptrcomp(m_blocks ) + nb * sizeof(pointer ) )^ ).ptr ,
block_size * m_entry_sz );
inc(m_num_blocks );
end;
{ DATA_PTR }
function pod_deque.data_ptr;
var
nb : unsigned;
begin
nb:=m_size shr block_shift;
if nb >= m_num_blocks then
allocate_block(nb );
result:=
pointer(
p32(pointer(ptrcomp(m_blocks ) + nb * sizeof(pointer ) )^ ).int
+ (m_size and block_mask ) * m_entry_sz );
end;
{ CONSTRUCT }
constructor pod_allocator.Construct;
begin
m_block_size :=block_size;
m_block_ptr_inc:=block_ptr_inc;
m_num_blocks:=0;
m_max_blocks:=0;
m_blocks :=NIL;
m_buf_ptr:=NIL;
m_rest :=0;
end;
{ DESTRUCT }
destructor pod_allocator.Destruct;
begin
remove_all;
end;
{ REMOVE_ALL }
procedure pod_allocator.remove_all;
var
blk : pod_alloc_ptr;
begin
if m_num_blocks <> 0 then
begin
blk:=pod_alloc_ptr(ptrcomp(m_blocks ) + (m_num_blocks - 1 ) * sizeof(pod_alloc ) );
while m_num_blocks <> 0 do
begin
agg_freemem(pointer(blk.ptr ) ,blk.sz );
dec(ptrcomp(blk ) ,sizeof(pod_alloc ) );
dec(m_num_blocks );
end;
agg_freemem(pointer(m_blocks ) ,m_max_blocks * sizeof(pod_alloc ) );
end;
m_num_blocks:=0;
m_max_blocks:=0;
m_blocks :=NIL;
m_buf_ptr:=NIL;
m_rest :=0;
end;
{ ALLOCATE }
function pod_allocator.allocate;
var
ptr : int8u_ptr;
align : unsigned;
begin
if size = 0 then
begin
result:=0;
exit;
end;
if size <= m_rest then
begin
ptr:=m_buf_ptr;
if alignment > 1 then
begin
align:=(alignment - unsigned(int32u(ptr ) ) mod alignment ) mod alignment;
inc(size ,align );
inc(ptrcomp(ptr ) ,align );
if size <= m_rest then
begin
dec(m_rest ,size );
inc(ptrcomp(m_buf_ptr ) ,size );
result:=ptr;
exit;
end;
allocate_block(size );
result:=allocate(size - align ,alignment );
exit;
end;
dec(m_rest ,size );
inc(ptrcomp(m_buf_ptr ) ,size );
result:=ptr;
exit;
end;
allocate_block(size + alignment - 1 );
result:=allocate(size ,alignment );
end;
{ ALLOCATE_BLOCK }
procedure pod_allocator.allocate_block;
var
new_blocks : pod_alloc_ptr;
begin
if size < m_block_size then
size:=m_block_size;
if m_num_blocks >= m_max_blocks then
begin
agg_getmem(pointer(new_blocks ) ,(m_max_blocks + m_block_ptr_inc ) * sizeof(pod_alloc ) );
if m_blocks <> NIL then
begin
move(m_blocks^ ,new_blocks^ ,m_num_blocks * sizeof(pod_alloc ) );
agg_freemem(pointer(m_blocks ) ,m_max_blocks * sizeof(pod_alloc ) );
end;
m_blocks:=new_blocks;
inc(m_max_blocks ,m_block_ptr_inc );
end;
agg_getmem(pointer(m_buf_ptr ) ,size * sizeof(int8u ) );
pod_alloc_ptr(ptrcomp(m_blocks ) + m_num_blocks * sizeof(pod_alloc ) ).ptr:=m_buf_ptr;
pod_alloc_ptr(ptrcomp(m_blocks ) + m_num_blocks * sizeof(pod_alloc ) ).sz :=size;
inc(m_num_blocks );
m_rest:=size;
end;
END.