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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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); }
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; }
void badBlock(bytesConstRef _block, string const& _err) { BlockHeader bi; DEV_IGNORE_EXCEPTIONS(bi = BlockHeader(_block)); badBlockInfo(bi, _err); }