Пример #1
0
static void *AcquireBlock(size_t size)
{
  register size_t
    i;

  register void
    *block;

  /*
    Find free block.
  */
  size=(size_t) (size+sizeof(size_t)+6*sizeof(size_t)-1) & -(4U*sizeof(size_t));
  i=AllocationPolicy(size);
  block=memory_pool.blocks[i];
  while ((block != (void *) NULL) && (SizeOfBlock(block) < size))
    block=NextBlockInList(block);
  if (block == (void *) NULL)
    {
      i++;
      while (memory_pool.blocks[i] == (void *) NULL)
        i++;
      block=memory_pool.blocks[i];
      if (i >= MaxBlocks)
        return((void *) NULL);
    }
  assert((*BlockHeader(NextBlock(block)) & PreviousBlockBit) == 0);
  assert(SizeOfBlock(block) >= size);
  RemoveFreeBlock(block,AllocationPolicy(SizeOfBlock(block)));
  if (SizeOfBlock(block) > size)
    {
      size_t
        blocksize;

      void
        *next;

      /*
        Split block.
      */
      next=(char *) block+size;
      blocksize=SizeOfBlock(block)-size;
      *BlockHeader(next)=blocksize;
      *BlockFooter(next,blocksize)=blocksize;
      InsertFreeBlock(next,AllocationPolicy(blocksize));
      *BlockHeader(block)=size | (*BlockHeader(block) & ~SizeMask);
    }
  assert(size == SizeOfBlock(block));
  *BlockHeader(NextBlock(block))|=PreviousBlockBit;
  memory_pool.allocation+=size;
  return(block);
}
Пример #2
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   E x p a n d H e a p                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ExpandHeap() get more memory from the system.  It returns MagickTrue on
%  success otherwise MagickFalse.
%
%  The format of the ExpandHeap method is:
%
%      MagickBooleanType ExpandHeap(size_t size)
%
%  A description of each parameter follows:
%
%    o size: the size of the memory in bytes we require.
%
*/
static MagickBooleanType ExpandHeap(size_t size)
{
  DataSegmentInfo
    *segment_info;

  MagickBooleanType
    mapped;

  register ssize_t
    i;

  register void
    *block;

  size_t
    blocksize;

  void
    *segment;

  blocksize=((size+12*sizeof(size_t))+SegmentSize-1) & -SegmentSize;
  assert(memory_pool.number_segments < MaxSegments);
  segment=MapBlob(-1,IOMode,0,blocksize);
  mapped=segment != (void *) NULL ? MagickTrue : MagickFalse;
  if (segment == (void *) NULL)
    segment=(void *) memory_methods.acquire_memory_handler(blocksize);
  if (segment == (void *) NULL)
    return(MagickFalse);
  segment_info=(DataSegmentInfo *) free_segments;
  free_segments=segment_info->next;
  segment_info->mapped=mapped;
  segment_info->length=blocksize;
  segment_info->allocation=segment;
  segment_info->bound=(char *) segment+blocksize;
  i=(ssize_t) memory_pool.number_segments-1;
  for ( ; (i >= 0) && (memory_pool.segments[i]->allocation > segment); i--)
    memory_pool.segments[i+1]=memory_pool.segments[i];
  memory_pool.segments[i+1]=segment_info;
  memory_pool.number_segments++;
  size=blocksize-12*sizeof(size_t);
  block=(char *) segment_info->allocation+4*sizeof(size_t);
  *BlockHeader(block)=size | PreviousBlockBit;
  *BlockFooter(block,size)=size;
  InsertFreeBlock(block,AllocationPolicy(size));
  block=NextBlock(block);
  assert(block < segment_info->bound);
  *BlockHeader(block)=2*sizeof(size_t);
  *BlockHeader(NextBlock(block))=PreviousBlockBit;
  return(MagickTrue);
}
Пример #3
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e l i n q u i s h M a g i c k M e m o r y                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RelinquishMagickMemory() frees memory acquired with AcquireMagickMemory()
%  or AcquireQuantumMemory() for reuse.
%
%  The format of the RelinquishMagickMemory method is:
%
%      void *RelinquishMagickMemory(void *memory)
%
%  A description of each parameter follows:
%
%    o memory: A pointer to a block of memory to free for reuse.
%
*/
MagickExport void *RelinquishMagickMemory(void *memory)
{
  if (memory == (void *) NULL)
    return((void *) NULL);
#if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
  memory_methods.destroy_memory_handler(memory);
#else
  LockSemaphoreInfo(memory_semaphore);
  assert((SizeOfBlock(memory) % (4*sizeof(size_t))) == 0);
  assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0);
  if ((*BlockHeader(memory) & PreviousBlockBit) == 0)
    {
      void
        *previous;

      /*
        Coalesce with previous adjacent block.
      */
      previous=PreviousBlock(memory);
      RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
      *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
        (*BlockHeader(previous) & ~SizeMask);
      memory=previous;
    }
  if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
    {
      void
        *next;

      /*
        Coalesce with next adjacent block.
      */
      next=NextBlock(memory);
      RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
      *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
        (*BlockHeader(memory) & ~SizeMask);
    }
  *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
  *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
  InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
  UnlockSemaphoreInfo(memory_semaphore);
#endif
  return((void *) NULL);
}
Пример #4
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e l i n q u i s h M a g i c k M e m o r y                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RelinquishMagickMemory() zeros memory that has been allocated, frees it for
%  reuse.
%
%  The format of the RelinquishMagickMemory method is:
%
%      void *RelinquishMagickMemory(void *memory)
%
%  A description of each parameter follows:
%
%    o memory: A pointer to a block of memory to free for reuse.
%
*/
MagickExport void *RelinquishMagickMemory(void *memory)
{
  if (memory == (void *) NULL)
    return((void *) NULL);
#if !defined(UseEmbeddableMagick)
  free(memory);
#else
  assert((SizeOfBlock(memory) % (4*sizeof(size_t))) == 0);
  assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0);
  AcquireSemaphoreInfo(&memory_semaphore);
  if ((*BlockHeader(memory) & PreviousBlockBit) == 0)
    {
      void
        *previous;

      /*
        Coalesce with previous adjacent block.
      */
      previous=PreviousBlock(memory);
      RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
      *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
        (*BlockHeader(previous) & ~SizeMask);
      memory=previous;
    }
  if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
    {
      void
        *next;

      /*
        Coalesce with next adjacent block.
      */
      next=NextBlock(memory);
      RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
      *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
        (*BlockHeader(memory) & ~SizeMask);
    }
  *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
  *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
  InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
  RelinquishSemaphoreInfo(memory_semaphore);
#endif
  return((void *) NULL);
}
Пример #5
0
uint32_t TIGER::decodeCDRM(iostream *dataStream, uint32_t &size, string &path, string &name)
{
	bool changes = false;
	CDRM_Header table;
	dataStream->read((char*)&table, sizeof(CDRM_Header));
	if (table.magic != 0x4D524443)
		exit(-1);
	vector<CDRM_BlockHeader> BlockHeader(table.count);
	dataStream->read((char*)BlockHeader.data(), table.count*sizeof(CDRM_BlockHeader));

	size = 0;
	uint32_t total_size = 0;
	uint32_t offset = 0;
	for (uint32_t i = 0; i < BlockHeader.size(); i++)	//Calculate total size.
	{
		size += BlockHeader[i].uncompressedSize;
	}
	total_size = size;
	auto_ptr<char> uncompressedData(new char[size]);
	for (uint32_t i = 0; i < BlockHeader.size(); i++)
	{
		uint32_t pos = dataStream->tellg();
		pos = ((pos + 15) / 16) * 16;
		dataStream->seekg(pos);	//Data is 16byte aligned.
		dataStream->seekp(pos);	//Data is 16byte aligned.
		if (BlockHeader[i].blockType == 1)
		{
			dataStream->read(uncompressedData.get() + offset, BlockHeader[i].uncompressedSize);
			offset += BlockHeader[i].uncompressedSize;
		}
		else if (BlockHeader[i].blockType == 2)
		{
			auto_ptr<char> compressedData(new char[BlockHeader[i].compressedSize]);
			dataStream->read(compressedData.get(), BlockHeader[i].compressedSize);
			int ret = Z_OK;
			uLong uncompressSize = size - offset;
			uint8_t *dataPtr = (uint8_t*)uncompressedData.get() + offset;
			ret = uncompress(dataPtr, &uncompressSize, (Bytef*)compressedData.get(), BlockHeader[i].compressedSize);
			offset += BlockHeader[i].uncompressedSize;
			if ((ret != Z_OK) && (ret != Z_STREAM_END))
			{
				exit(ret);
			}
		}
	}
	CDRM_BlockFooter footer;
	dataStream->seekg(((((uint64_t)dataStream->tellg()) + 15) / 16) * 16);	//Data is 16byte aligned.
	dataStream->read((char*)&footer, sizeof(footer));
	switch (((uint32_t*)(uncompressedData.get()))[0])
	{
	case '9DCP':	//PCD9
	{
		uncompressedData = decodePCD9(uncompressedData, size, path, name);
		changes = true;
	}
	break;
	case 0x00000006:
	{
		if ((currentMode == UNPACK))
		{
			try
			{
				string fullpath = path + "\\" + name + ".mesh";
				cout << "Writing \"" << fullpath << "\"\n";
				//Scene scene(uncompressedData.get() , size);
				fstream output(fullpath, ios_base::binary | ios_base::out);
				if (!output.is_open())
					exit(errno);
				output.write(uncompressedData.get(), size);
				output.close();
			}
			catch (exception e)
			{
				cout << e.what();
			}
		}
		//return -1;
	}
	default:
	{
		if (writeDRM && (currentMode == UNPACK))
		{
			string fullpath = path + "\\" + name + ".drm";
			cout << "Writing \"" << fullpath << "\"\n";
			fstream output(fullpath, ios_base::binary | ios_base::out);
			if (!output.is_open())
				exit(errno);
			output.write(uncompressedData.get(), size);
			output.close();
		}
	}
	}
	if (currentMode == PACK /*&& changes*/)
	{
		if (total_size != size)
		{
			cout << "Incorrect size\n";
			exit(-1);
		}

		/*Find next free CDRM*/
		tigerFiles[4]->seekg(0);
		tigerFiles[4]->seekp(0);
		uint32_t blockheaderpos = 0;
		CDRM_Header i;
		while (true)
		{
			uint32_t size = 0;
			i.load(tigerFiles[4]);
			if (i.magic == 0)
				break;
			size += i.count*sizeof(CDRM_BlockHeader);
			size = ((size + 15) / 16) * 16;
			CDRM_BlockHeader j;
			for (int k = 0;k < i.count;k++)
			{
				j.load(tigerFiles[4]);
				size += j.compressedSize;
			}
			size = (((size + 0x800 - 1) / 0x800) * 0x800);
			blockheaderpos += size;
			size -= sizeof(CDRM_Header);
			tigerFiles[4]->seekg(size, ios_base::cur);
			tigerFiles[4]->seekp(size, ios_base::cur);
		}

		tigerFiles[4]->seekg(blockheaderpos);
		tigerFiles[4]->seekp(blockheaderpos);
		tigerFiles[4]->write((char*)&table, sizeof(CDRM_Header));
		blockheaderpos = tigerFiles[4]->tellp();
		tigerFiles[4]->write((char*)BlockHeader.data(), sizeof(CDRM_BlockHeader)*BlockHeader.size());
		tigerFiles[4]->seekp(((((uint64_t)tigerFiles[4]->tellp()) + 15) / 16) * 16);	//Data is 16byte aligned.
		for (uint32_t i = 0; i < BlockHeader.size(); i++)
		{
			BlockHeader[i].uncompressedSize = size;
			if (BlockHeader[i].blockType == 1)
			{
				BlockHeader[i].compressedSize = BlockHeader[i].uncompressedSize;
				tigerFiles[4]->write(uncompressedData.get(), BlockHeader[i].uncompressedSize);
			}
			else if (BlockHeader[i].blockType == 2)
			{
				auto_ptr<char> compressedData(new char[BlockHeader[i].uncompressedSize]);
				int ret = Z_OK;
				BlockHeader[i].compressedSize = BlockHeader[i].uncompressedSize;
				ret = compress2((Bytef*)compressedData.get(), (uLongf*)(&BlockHeader[i].compressedSize), (Bytef*)uncompressedData.get(), BlockHeader[i].uncompressedSize, 4);
				if ((ret != Z_OK) && (ret != Z_STREAM_END))
				{
					cout << "Error Compressing\n";
					exit(ret);
				}
				tigerFiles[4]->write(compressedData.get(), BlockHeader[i].compressedSize);
			}
		}

		uint32_t cdrm_footer = tigerFiles[4]->tellp();
		cdrm_footer = ((cdrm_footer + 15) / 16) * 16;

		footer.relative_offset = 0x800 - (cdrm_footer % 0x800);
		tigerFiles[4]->seekp(cdrm_footer);	//Data is 16byte aligned.
		tigerFiles[4]->write((char*)&footer, sizeof(CDRM_BlockFooter));
		tigerFiles[4]->seekp(blockheaderpos);
		tigerFiles[4]->write((char*)BlockHeader.data(), sizeof(CDRM_BlockHeader)*BlockHeader.size());
		tigerFiles[4]->flush();
		return (blockheaderpos & 0xFFFFFF00) | 4;
	}

	return -1;
}
Пример #6
0
void badBlock(bytesConstRef _block, string const& _err)
{
	BlockHeader bi;
	DEV_IGNORE_EXCEPTIONS(bi = BlockHeader(_block));
	badBlockInfo(bi, _err);
}