void CMemoryBuffer::CopyTo(const CMemoryBuffer & buffer, size_t size, size_t off) const { if(buffer.GetBufferSize() < size) NOVA_EXP("CMemoryBuffer::CopyTo: unput buffer too small...", MEM_ERROR); if((off + size) > mbSize) NOVA_EXP("CMemoryBuffer::CopyTo: offset param too large", MEM_ERROR); nova::nByte *p = (nova::nByte *)mBegin + off; memcpy(buffer.GetBegin(), p, size); }
CMemoryBuffer CHardwarePixelBuffer::LockSource(size_t offset, size_t length, THardwareBufferLock opt) { if(mSize == 0) throw NOVA_EXP("CHardwarePixelBuffer::LockSource - \ mSize == 0, null pixel box..", BAD_OPERATION); CMemoryBuffer data; GLuint face_target = 0; data.AllocBuffer(mSize); COpenGLFormats informat; informat.SetExFormat(mPixelFormat); glPixelStorei(GL_PACK_ALIGNMENT, 1); GLenum type = TextureTarget(mTarget); if(mTarget == USE_CUBEMAP_TEXTURE) face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace; else face_target = type; glBindTexture(type, mTargetId); glGetTexImage(face_target, mLevel, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin()); glPixelStorei(GL_PACK_ALIGNMENT, 4); int error = glGetError(); if(error != GL_NO_ERROR) { nstringstream str; str << "CHardwarePixelBuffer::LockSource - \ detecting OpenGL error with code " << error; throw NOVA_EXP(str.str().c_str(), BAD_OPERATION); } CMemoryBuffer result; result.AllocBuffer(mLockActSize); size_t line = mLockWidth * informat.GetInternalChannels(); nova::byte * source = (nova::byte *)data.GetBegin() + offset; nova::byte * dest = (nova::byte *)result.GetBegin(); for(nova::uint i = 0; i < mLockDepth; ++i) { for(nova::uint j = 0; j < mLockHeight; ++j) { memcpy(dest, source, line); source += mRowPitch * informat.GetInternalChannels(); dest += line; } source += mSlicePitch * informat.GetInternalChannels(); } data.FreeBuffer(); return result; }
void CFilesPackage::PutFile(const CMemoryBuffer &buf , const nstring & name, const nstring & ext, const nstring &grs) { TFileHeader fheader; memset(&fheader, 0, sizeof(TFileHeader)); strcpy(fheader.file_name, name.c_str()); strcpy(fheader.ext, ext.c_str()); strcpy(fheader.resource_group, grs.c_str()); if(!mIsOpened) throw NOVA_EXP("CFilesPackage::PutFile: package not opened, open package file first!", BAD_OPERATION); if(!mWritePackage) throw NOVA_EXP("CFilesPackage::PutFile: package opened for reading!", BAD_OPERATION); if(InFileList(name)) throw NOVA_EXP("CFilesPackage::PutFile: package already contains this name!", BAD_OPERATION); fheader.pos = mFile->Tell() + sizeof(TFileHeader); fheader.number = mPackageMap.size() + 1; fheader.size = buf.GetBufferSize(); mFile->Write(&fheader, sizeof(TFileHeader)); mFile->Write(buf); std::pair<nstring, TFileHeader> pf; pf.first = name; pf.second = fheader; mPackageMap.insert(pf); mFile->Flush(); }
CMemoryBuffer CFilesPackage::GetFile(const nstring & name) const { stl<nstring, FileHeader>::map::const_iterator it; TFileHeader header; if(!mIsOpened) throw NOVA_EXP("CFilesPackage::GetFile: package not opened, open package file first!", BAD_OPERATION); if(mWritePackage) throw NOVA_EXP("CFilesPackage::GetFile: package opened for writing!", BAD_OPERATION); if((it = mPackageMap.find(name)) != mPackageMap.end()) header = (*it).second; else return CMemoryBuffer(); CMemoryBuffer result; mFile->Seek(header.pos); result.AllocBuffer(header.size); mFile->Read(result); return result; }
void COFF_PutNameInSectionHeader(SCOFF_SectionHeader & sec, const char * name, CMemoryBuffer & StringTable) { // Function to put a name into SCOFF_SectionHeader. // Put name in string table if longer than 8 characters int len = (int)strlen(name); // Length of name if (len <= 8) { // Short name. store in section header memcpy(sec.Name, name, len); // Pad with zeroes for (; len < 8; len++) sec.Name[len] = 0; } else { // Long name. store in string table sprintf(sec.Name, "/%i", StringTable.PushString(name)); } }
uint32 COFF_PutNameInSymbolTable(SCOFF_SymTableEntry & sym, const char * name, CMemoryBuffer & StringTable) { // Function to put a name into SCOFF_SymTableEntry. // Put name in string table if longer than 8 characters. // Returns index into StringTable if StringTable used int len = (int)strlen(name); // Length of name if (len <= 8) { // Short name. store in section header memcpy(sym.s.Name, name, len); // Pad with zeroes for (; len < 8; len++) sym.s.Name[len] = 0; } else { // Long name. store in string table sym.stringindex.zeroes = 0; sym.stringindex.offset = StringTable.PushString(name); // Second integer = entry into string table return sym.stringindex.offset; } return 0; }
void CTextureSurfaceList::BuildSurfaceList(const CMemoryBuffer & data, size_t width, size_t height, size_t depth) { if(!width || !height || !depth) throw NOVA_EXP("CTextureSurfaceList::BuildSurfaseList - incorrect input size param.", BAD_OPERATION); GLenum type = CHardwarePixelBuffer::TextureTarget(mType); bool mipmap_hardware_gen = CRenderSystem::GetSingelton().CheckCapabilities(TEXTURE_CATEGORY, CAP_AUTOMIPMAP); COpenGLFormats informat; informat.SetExFormat(mPixelFormat); mMaxMipmaps = GetMaxMipmaps(width, height, depth); glEnable(type); if(mType == CHardwarePixelBuffer::USE_CUBEMAP_TEXTURE && mFace > 0) {} else glGenTextures(1, &mTargetId); glBindTexture(type, mTargetId); if(mMipState == USE_HARDWARE_MIPMAPS) { if(!mipmap_hardware_gen) mMipState = USE_SOFTWARE_MIPMAPS; } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if(mMipState == DO_NOT_USE_MIPMAPS) { glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); mMaxMipmaps = 1; switch(mType) { case CHardwarePixelBuffer::USE_TEXTURE_1D: glTexImage1D(GL_TEXTURE_1D, 0, informat.GetInternalChannels(), width, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin()); break; case CHardwarePixelBuffer::USE_TEXTURE_2D: glTexImage2D(GL_TEXTURE_2D, 0, informat.GetInternalChannels(), width, height, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin()); break; case CHardwarePixelBuffer::USE_TEXTURE_3D: glTexImage3D(GL_TEXTURE_3D, 0, informat.GetInternalChannels(), width, height, depth, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin()); break; case CHardwarePixelBuffer::USE_CUBEMAP_TEXTURE: glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace, 0, informat.GetInternalChannels(), width, height, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin()); break; } } else if(mMipState == USE_SOFTWARE_MIPMAPS) { glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); switch(mType) { case CHardwarePixelBuffer::USE_TEXTURE_1D: gluBuild1DMipmaps(GL_TEXTURE_1D, informat.GetInternalChannels(), width, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin()); break; case CHardwarePixelBuffer::USE_TEXTURE_2D: gluBuild2DMipmaps(GL_TEXTURE_2D, informat.GetInternalChannels(), width, height, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin()); break; case CHardwarePixelBuffer::USE_CUBEMAP_TEXTURE: gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace, informat.GetInternalChannels(), width, height, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin()); break; case CHardwarePixelBuffer::USE_TEXTURE_3D: throw NOVA_EXP("CTextureSurfaceList::BuildSurfaseList - \ OpenGL can not support software 3D mipmaps", BAD_OPERATION); break; } }
void CHardwarePixelBuffer::UnlockSource(CMemoryBuffer & buf) { if(mSize == 0) throw NOVA_EXP("CHardwarePixelBuffer::UnlockSource - \ mSize == 0, null pixel box..", BAD_OPERATION); GLuint face_target = 0; void *ptr = buf.GetBegin(); if(!ptr) throw NOVA_EXP("CHardwarePixelBuffer::LockSource - \ ptr == NULL, bad ptr..", BAD_OPERATION); COpenGLFormats informat; informat.SetExFormat(mPixelFormat); glPixelStorei(GL_PACK_ALIGNMENT, 1); GLenum type = TextureTarget(mTarget); if(mTarget == USE_CUBEMAP_TEXTURE) face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace; else face_target = type; glBindTexture(type, mTargetId); size_t xoff, yoff, zoff; SizeToWHD(&xoff, &yoff, &zoff, mLockStart); nova::uint _width; nova::uint _height; nova::uint _depth; SizeToWHD(&_width, &_height, &_depth, mLockStart + mLockSize); _width -= (xoff-1); _height -= (yoff-1); _depth -= (zoff-1); switch(mTarget) { case USE_TEXTURE_1D: { glTexSubImage1D(GL_TEXTURE_1D, mLevel, xoff, _width, informat.GetFormat(), GL_UNSIGNED_BYTE, ptr); } break; case USE_TEXTURE_2D: case USE_CUBEMAP_TEXTURE: { glTexSubImage2D(face_target, mLevel, xoff, yoff, _width, _height, informat.GetFormat(), GL_UNSIGNED_BYTE, ptr); } break; case USE_TEXTURE_3D: { glTexSubImage3D(GL_TEXTURE_3D, mLevel, xoff, yoff, zoff, _width, _height, _depth, informat.GetFormat(), GL_UNSIGNED_BYTE, ptr); } break; } mLockWidth = 0; mLockHeight = 0; mLockDepth = 0; mLockActSize = 0; glPixelStorei(GL_PACK_ALIGNMENT, 4); buf.FreeBuffer(); }
// MakeSegmentList void COMF2ASM::MakeSegmentList() { // Make Sections list in Disasm int32 SegNum; // Segment number int32 Segment; // Segment number in OMF record uint32 RecNum; // OMF record number uint32 LastDataRecord; // OMF record number of last LEDATA record uint32 RecOffset; // Segment offset of LEDATA, LIDATA record uint32 RecSize; // Data size of LEDATA, LIDATA record uint32 LastDataRecordSize; // Last RecSize uint32 LastOffset; // Last RecOffset int8 * LastDataRecordPointer; // Point to last raw data uint32 BufOffset; // Offset of segment into SegmentData buffer CMemoryBuffer TempBuf; // Temporary buffer for building raw data // Loop through segments for (SegNum = 1; SegNum <= NumSegments; SegNum++) { // Get size uint32 SegmentSize = Segments[SegNum].Size; if (SegmentSize == 0) continue; // Empty segment // Allocate temporary data buffer and reset it TempBuf.SetSize(SegmentSize + 16); int FillByte = 0; // Byte to fill memory with if (Segments[SegNum].Type == 1) { // Code segment. Fill any unused bytes with NOP opcode = 0x90 FillByte = 0x90; } memset(TempBuf.Buf(), FillByte, SegmentSize + 16);// Reset to all 0 or NOP LastDataRecord = 0; LastDataRecordSize = 0; LastDataRecordPointer = 0; LastOffset = 0; int comdatsSoFar = 0; // Search for LEDATA, LIDATA and FIXUPP records for this segment for (RecNum = 0; RecNum < NumRecords; RecNum++) { if (Records[RecNum].Type2 == OMF_LEDATA) { // LEDATA record Records[RecNum].Index = 3; // Initialize record reading Segment = Records[RecNum].GetIndex();// Read segment number if ((Segment & 0xC000) == 0x4000) { // Refers to Borland communal section Segment = (Segment & ~0x4000) + FirstComDatSection - 1; } if (Segment != SegNum) continue; // Does not refer to this segment RecOffset = Records[RecNum].GetNumeric();// Read offset of this record RecSize = Records[RecNum].End - Records[RecNum].Index; // Calculate size of data LastDataRecord = RecNum; // Save for later FIXUPP that refers to this record if (RecOffset < LastOffset + LastDataRecordSize && LastOffset < RecOffset + RecSize) { // Overlapping data records if (RecOffset + 8 < LastOffset + LastDataRecordSize || Segments[SegNum].Type != 1) { // Overlapping data by more than 7 bytes or not executable code err.submit(1207); } else { // Possibly backpatched code err.submit(1208); // Warning err.ClearError(1208); // Report only once } } LastDataRecordSize = RecSize; LastDataRecordPointer = Records[RecNum].buffer + Records[RecNum].FileOffset + Records[RecNum].Index; LastOffset = RecOffset; // Save offset for subsequent FIXUPP records // Check if data within segment if (RecOffset + RecSize > SegmentSize) { err.submit(2309, GetSegmentName(Segment)); continue; } // Put raw data into temporary buffer memcpy(TempBuf.Buf() + RecOffset, LastDataRecordPointer, RecSize); } // Finished with LEDATA record if (Records[RecNum].Type2 == OMF_LIDATA) { // LIDATA record Records[RecNum].Index = 3; // Initialize record reading Segment = Records[RecNum].GetIndex(); if (Segment != SegNum) continue; // Does not refer to this segment LastDataRecord = RecNum; // Save for later FIXUPP that refers to this record RecOffset = Records[RecNum].GetNumeric();// Read offset if (RecOffset > SegmentSize) { err.submit(2310); continue; // Error: outside bounds } // Unpack LIDATA blocks recursively RecSize = Records[RecNum].UnpackLIDATABlock(TempBuf.Buf() + RecOffset, SegmentSize - RecOffset); if (RecOffset < LastOffset + LastDataRecordSize && LastOffset < RecOffset + RecSize) { // Overlapping data records err.submit(1207); // Warning } LastDataRecordSize = RecSize; // Save data size LastOffset = RecOffset; // Save offset for subsequent FIXUPP records } // Finished with LIDATA record if (Records[RecNum].Type2 == OMF_COMDAT) { // COMDAT record. Records[RecNum].Index = 3; // Initialize record reading uint16 flags = Records[RecNum].GetByte(); if ((flags&1)==0) { // not a continuation ++comdatsSoFar; LastDataRecord = RecNum; // Save for later FIXUPP that refers to this record } Segment = FirstComDatSection + comdatsSoFar-1; if (SegNum != Segment) continue; uint16 attribs = Records[RecNum].GetByte(); Records[RecNum].GetByte(); // align (ignore) RecOffset = Records[RecNum].GetNumeric(); Records[RecNum].GetIndex(); // type (ignore) if ((attribs&0xF)==0) { Records[RecNum].GetIndex(); // public base uint16 publicSegment = Records[RecNum].GetIndex(); if (publicSegment==0) Records[RecNum].GetIndex(); // public frame (ignore) } Records[RecNum].GetIndex(); // public name (ignore) RecSize = Records[RecNum].End - Records[RecNum].Index; // Calculate size of data LastDataRecord = RecNum; // Save for later FIXUPP that refers to this record LastDataRecordSize = RecSize; LastDataRecordPointer = Records[RecNum].buffer + Records[RecNum].Index+Records[RecNum].FileOffset; LastOffset = RecOffset; // Put raw data into temporary buffer memcpy(TempBuf.Buf() + RecOffset, LastDataRecordPointer, RecSize); } // Finished with COMDAT record if (Records[RecNum].Type2 == OMF_FIXUPP) { // FIXUPP record if (Segment != SegNum) continue; // Does not refer to this segment Records[RecNum].Index = 3; if (Records[LastDataRecord].Type2 == OMF_LEDATA) { // FIXUPP for last LEDATA record // Make relocation records MakeRelocations(Segment, RecNum, LastOffset, LastDataRecordSize, (uint8*)TempBuf.Buf()); } else if (Records[RecNum].Index < Records[RecNum].End) { // Non-empty FIXUPP record does not refer to LEDATA record if (Records[LastDataRecord].Type2 == OMF_COMDAT) { // FIXUPP for last COMDAT record // Make relocation records MakeRelocations(Segment, RecNum, LastOffset, LastDataRecordSize, (uint8*)TempBuf.Buf()); } else if (Records[LastDataRecord].Type2 == OMF_LIDATA) { err.submit(2311); // Error: Relocation of iterated data not supported } else { err.submit(2312); // Does not refer to data record } } } } // End of loop to search for LEDATA, LIDATA and FIXUPP records for this segment // Transfer raw data from TempBuf to SegmentData buffer BufOffset = SegmentData.Push(TempBuf.Buf(), SegmentSize); // Remember offset into SegmentData Segments[SegNum].BufOffset = BufOffset; } // End of first loop through segments // We must put all segments into SegmentData buffer before we assign pointers to // the raw data because otherwise the SegmentData buffer might me reallocated // when it grows and the pointers become invalid. This is the reasons why we // have two loops through the segments here. // Second loop through segments int totalcodesize=0; for (SegNum = 1; SegNum <= NumSegments; SegNum++) { // Pointer to merged raw data uint8 * RawDatap = (uint8*)SegmentData.Buf() + Segments[SegNum].BufOffset; // Size of raw data uint32 InitSize = (Segments[SegNum].Type == 3) ? 0 : Segments[SegNum].Size; // Define segment const char * SegmentName = NameBuffer.Buf() + Segments[SegNum].NameO; Disasm.AddSection(RawDatap, InitSize, Segments[SegNum].Size, Segments[SegNum].Offset, Segments[SegNum].Type, Segments[SegNum].Align, Segments[SegNum].WordSize, SegmentName); if (Segments[SegNum].Type == 1 || Segments[SegNum].Type == 0x1001) { totalcodesize += Segments[SegNum].Size; } } }
void CELF2ELF<ELFSTRUCTURES>::MakeSymbolTable() { uint32 SectionNumber; // Section number char * SectionName; // Section name uint32 SecNamei; // Section name index uint32 OldSymi; // Old symbol index uint32 NewSymi; // New symbol index int isymt; // 0 = symtab, 1 = dynsym const char * name1; // Old name of symbol const char * name2; // Changed name of symbol int SymbolType; // Symbol type for cmd.SymbolChange int action; // Symbol change action int binding; // Symbol binding TELF_Symbol sym; // Symbol table entry TELF_Symbol AliasEntry; // Symbol table alias entry uint32 symnamei; // New symbol name index CMemoryBuffer TempGlobalSymbolTable; // Temporary storage of public and external symbols // Find symbol table and string tables for (SectionNumber = 0; SectionNumber < this->NSections; SectionNumber++) { // Get copy of 32-bit header or converted 64-bit header TELF_SectionHeader sheader = this->SectionHeaders[SectionNumber]; switch (sheader.sh_type) { case SHT_SYMTAB: isymtab[0] = SectionNumber; // Symbol table found istrtab[0] = this->SectionHeaders[SectionNumber].sh_link; // Associated string table break; case SHT_DYNSYM: isymtab[1] = SectionNumber; // Dynamic symbol table found istrtab[1] = this->SectionHeaders[SectionNumber].sh_link; // Associated string table break; case SHT_STRTAB: SecNamei = sheader.sh_name; if (SecNamei >= this->SecStringTableLen) err.submit(2112); SectionName = this->SecStringTable + SecNamei; if (SectionNumber == this->FileHeader.e_shstrndx || !strcmp(SectionName,".shstrtab")) { istrtab[2] = SectionNumber; // Section header string table found } else if (!strcmp(SectionName,".strtab") && !istrtab[0]) { istrtab[0] = SectionNumber; // Symbol string table found } else if (!strcmp(SectionName,".stabstr")) { istrtab[3] = SectionNumber; // Debug string table found } break; } } // Make new symbol tables and string tables // Loop through possibly two symbol tables for (isymt = 0; isymt < 2; isymt++) { if (isymtab[isymt] && isymtab[isymt] < this->NSections && istrtab[isymt] && istrtab[isymt] < this->NSections) { // Symbol table header uint32 SymTabHeaderOffset = uint32(this->FileHeader.e_shoff + isymtab[isymt] * this->SectionHeaderSize); //TELF_SectionHeader SymTabHeader = this->Get<TELF_SectionHeader>(SymTabHeaderOffset); // Some compilers fail with the double template here. Avoid the template: TELF_SectionHeader SymTabHeader = *(TELF_SectionHeader*)(this->Buf() + SymTabHeaderOffset); // Find symbol table uint32 symtabsize = (uint32)(SymTabHeader.sh_size); int8 * symtab = this->Buf() + SymTabHeader.sh_offset; int8 * symtabend = symtab + symtabsize; int entrysize = (int)(SymTabHeader.sh_entsize); if (entrysize <= 0) entrysize = sizeof(TELF_Symbol); // Find string table char * StringTable = this->Buf() + this->SectionHeaders[istrtab[isymt]].sh_offset; uint32 StringTableLen = uint32(this->SectionHeaders[istrtab[isymt]].sh_size); NewStringTable[isymt].Push(0, 1); // Initialize new string table, first entry 0 if (isymt == 0) { // Allocate NewSymbolIndex NumOldSymbols = (symtabsize + entrysize - 1) / entrysize; // round up to nearest integer to be safe NewSymbolIndex.SetNum(NumOldSymbols); // Allocate array NewSymbolIndex.SetZero(); // Initialize } // Loop through old symbol table for (OldSymi = 0; symtab < symtabend; symtab += entrysize, OldSymi++) { // Symbol table entry sym = *(TELF_Symbol*)symtab; // Symbol name if (sym.st_name < StringTableLen) { name1 = StringTable + sym.st_name;} else { err.submit(2035); name1 = 0; } name2 = 0; // Symbol type int type = sym.st_type; binding = sym.st_bind; if (binding == STB_LOCAL) { SymbolType = SYMT_LOCAL; // Symbol is local } else if (type == STT_OBJECT || type == STT_FUNC || type == STT_NOTYPE) { if (int16(sym.st_shndx) > 0) { // Check section number SymbolType = SYMT_PUBLIC; // Symbol is public } else { SymbolType = SYMT_EXTERNAL; // Symbol is external } } else { SymbolType = SYMT_OTHER; // Symbol is section or filename or debug } // Check if any change required for this symbol action = cmd.SymbolChange(name1, &name2, SymbolType); switch (action) { case SYMA_NOCHANGE: // No change break; case SYMA_MAKE_WEAK: // Make symbol weak if (cmd.OutputType == FILETYPE_COFF) { // PE/COFF format does not support weak publics. Use this only when converting to ELF err.submit(2200); } // Make weak binding = STB_WEAK; sym.st_bind = binding; sym.st_type = type ; break; case SYMA_MAKE_LOCAL: // Make public symbol local, make external symbol ignored binding = STB_LOCAL; SymbolType = SYMT_LOCAL; sym.st_bind = binding; sym.st_type = type ; break; case SYMA_CHANGE_NAME: // Change name of symbol name1 = name2; name2 = 0; break; case SYMA_CHANGE_ALIAS: // Make alias and keep old name if (isymt != 0) err.submit(1033, name1); // alias in dynsym not supported yet AliasEntry = sym; break; default: err.submit(9000); // unknown error } // Add entry to new string table if (name1 && *name1) { symnamei = NewStringTable[isymt].PushString(name1); } else { symnamei = 0; } sym.st_name = symnamei; if (isymt == 0) { // The symtab symbol table must be ordered with local symbols first. // Therefore the public and external symbols are temporarily stored // in TempGlobalSymbolTable and the high bit of NewSymi is set. // The two tables are joined together when the number of local symbols // is known and the indexes into TempGlobalSymbolTable are adjusted // to indexes into the joined table. if (SymbolType == SYMT_LOCAL) { NewSymbolTable[isymt].Push(&sym, entrysize); NewSymi = NewSymbolTable[isymt].GetLastIndex(); } else { TempGlobalSymbolTable.Push(&sym, entrysize); NewSymi = TempGlobalSymbolTable.GetLastIndex() | 0x80000000; } // Insert into symbol index translation table NewSymbolIndex[OldSymi] = NewSymi; if (action == SYMA_CHANGE_ALIAS && name2 && *name2) { // Make one more entry for new alias symnamei = NewStringTable[isymt].PushString(name2); AliasEntry.st_name = symnamei; TempGlobalSymbolTable.Push(&AliasEntry, entrysize); } } else { // dynsym table has no local symbols // no index translation table is currently needed NewSymbolTable[isymt].Push(&sym, entrysize); } } // End of loop through old symbol table if (isymt == 0) { // The symbol table has been temporarily split into local and non-local // Save index to first nonlocal symbol FirstGlobalSymbol = NewSymbolTable[isymt].GetNumEntries(); // Adjust symbol index translation table for (OldSymi = 0; OldSymi < NumOldSymbols; OldSymi++) { if (NewSymbolIndex[OldSymi] & 0x80000000) { // Translate index into TempGlobalSymbolTable to index into joined table NewSymbolIndex[OldSymi] = (NewSymbolIndex[OldSymi] & ~0x80000000) + FirstGlobalSymbol; } } // Join the two tables NewSymbolTable[isymt].Push(TempGlobalSymbolTable.Buf(), TempGlobalSymbolTable.GetDataSize()); } } } // End of isymt loop through possibly two symbol tables }
void CELF2ELF<ELFSTRUCTURES>::MakeBinaryFile() { uint32 SectionNumber; // Section number CMemoryBuffer NewSectionHeaders; // Temporary storage of section headers // Copy file header ToFile.Push(this->Buf(), sizeof(TELF_Header)); // Copy program header if any if (this->FileHeader.e_phnum) { ToFile.Push(this->Buf() + this->FileHeader.e_phoff, this->FileHeader.e_phentsize * this->FileHeader.e_phnum); ((TELF_Header*)ToFile.Buf())->e_phoff = sizeof(TELF_Header); } // Copy section data uint32 SectionHeaderOffset = uint32(this->FileHeader.e_shoff); TELF_SectionHeader sheader; // Section header // Loop through sections for (SectionNumber = 0; SectionNumber < this->NSections; SectionNumber++, SectionHeaderOffset += this->FileHeader.e_shentsize) { // Get section header //sheader = this->Get<TELF_SectionHeader>(SectionHeaderOffset); // Some compilers fail with the double template here. Avoid the template: sheader = *(TELF_SectionHeader*)(this->Buf() + SectionHeaderOffset); // Check for null section if (SectionNumber == 0 && sheader.sh_type != 0) { // First section must be null err.submit(2036, 0); } // Align ToFile.Align(16); // Check for sections that have been modified if (SectionNumber == isymtab[0]) { // Static symbol table .symtab sheader.sh_offset = ToFile.Push(NewSymbolTable[0].Buf(), NewSymbolTable[0].GetDataSize()); sheader.sh_size = NewSymbolTable[0].GetDataSize(); sheader.sh_info = FirstGlobalSymbol; } else if (SectionNumber == isymtab[1]) { // Dynamic symbol table .dynsym sheader.sh_offset = ToFile.Push(NewSymbolTable[1].Buf(), NewSymbolTable[1].GetDataSize()); sheader.sh_size = NewSymbolTable[1].GetDataSize(); } else if (SectionNumber == istrtab[0]) { // Symbol string table .strtab sheader.sh_offset = ToFile.Push(NewStringTable[0].Buf(), NewStringTable[0].GetDataSize()); sheader.sh_size = NewStringTable[0].GetDataSize(); } else if (SectionNumber == istrtab[1] && SectionNumber != istrtab[0]) { // Dynamic symbol string table if different from .strtab sheader.sh_offset = ToFile.Push(NewStringTable[1].Buf(), NewStringTable[1].GetDataSize()); sheader.sh_size = NewStringTable[1].GetDataSize(); } else if (SectionNumber == istrtab[2]) { // Section name string table .shstrtab sheader.sh_offset = ToFile.Push(NewStringTable[2].Buf(), NewStringTable[2].GetDataSize()); sheader.sh_size = NewStringTable[2].GetDataSize(); } else { // Any other section (including istrtab[3] = .stabstr) sheader.sh_offset = ToFile.Push(this->Buf() + (uint32)sheader.sh_offset, (uint32)sheader.sh_size); } // Store section header NewSectionHeaders.Push(&sheader, sizeof(sheader)); } // End of section loop // Align ToFile.Align(16); // Store section headers uint32 SectionHeadersOffset = ToFile.Push(NewSectionHeaders.Buf(), NewSectionHeaders.GetDataSize()); // Update file header ((TELF_Header*)ToFile.Buf())->e_shoff = SectionHeadersOffset; ((TELF_Header*)ToFile.Buf())->e_shentsize = sizeof(TELF_SectionHeader); ((TELF_Header*)ToFile.Buf())->e_shnum = NewSectionHeaders.GetNumEntries(); ((TELF_Header*)ToFile.Buf())->e_shstrndx = istrtab[2]; }
void CFreeFont::MakeLetter(wchar_t code) { // Первая вещь, которую нам надо сделать, это вывести наш символ // в растр. Это делается набором команд FreeType // Загрузить глифы для каждого символа. if(FT_Load_Glyph(face, FT_Get_Char_Index(face, code), FT_LOAD_DEFAULT)) throw NOVA_EXP("CFreeFont::MakeLetter - FT_Load_Glyph failed", BAD_OPERATION); // Поместить глиф в объект. FT_Glyph glyph; if(FT_Get_Glyph(face->glyph, &glyph)) throw NOVA_EXP("CFreeFont::MakeLetter - FT_Get_Glyph failed", BAD_OPERATION); // Конвертировать глиф в растр. FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1); FT_BitmapGlyph bitmap_glyph = reinterpret_cast<FT_BitmapGlyph>(glyph); // С помощью этой ссылки, получаем легкий доступ до растра. FT_Bitmap & bitmap = bitmap_glyph->bitmap; // Используем нашу вспомогательную функцию для вычисления ширины и высоты // текстуры для нашего растра. nInt32 bwidth = NextP2(bitmap.width); nInt32 bheight = NextP2(bitmap.rows); // Выделим память для данных текстуры. //nByte * expanded_data = NULL; //expanded_data = getmem<nByte>(expanded_data, 2 * bwidth * bheight); CMemoryBuffer mem; mem.AllocBuffer(2 * bwidth * bheight); nByte * expanded_data = (nova::nByte *)mem.GetBegin(); // Поместим данные в расширенный растр. // Отмечу, что использован двухканальный растр (Один для // канала яркости и один для альфа), но мы будем назначать // обоим каналам одно и тоже значение, которое мы // получим из растра FreeType. // Мы используем оператор ?: для того чтобы поместить 0 в зону вне растра FreeType. for(nInt32 j = 0; j < bheight; ++j) for(nInt32 i = 0; i < bwidth; ++i) expanded_data[2*(i + j * bwidth)] = expanded_data[2*(i + j * bwidth)+1] = (i >= bitmap.width || j >= bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j]; /* GLuint texture; glGenTextures(1, &texture); glBindTexture( GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Здесь мы создаем текстуру // Помните, что используем GL_LUMINANCE_ALPHA, чтобы было два альфа канала данных glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bwidth, bheight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data); */ //nInt32 tid = CTextureManager::GetSingeltonPtr()->AddTexture(GL_TEXTURE_2D, // expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA); /* CTexturePtr ptex = CTextureManager::GetSingeltonPtr()->AddTexture(new CTexture(fname.c_str(), GL_TEXTURE_2D)); ptex->SetEnvType(GL_MODULATE); ptex->CreateTexture(expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA, GL_CLAMP); // После создания текстуры, мы больше не нуждаемся в промежуточных данных. freemems(expanded_data); CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6, slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows, code, ptex); */ nstring resnamet; nstring resnamei("TempFontImage"); resnamet = mName + "_" + CStringUtils::IntTo16xString(static_cast<nInt32>(code)); // Создаем промежуточное изображение в памяти CImagePtr pImage = CImageManager::GetSingelton().CreateNewImage(resnamei, mName, mem, bwidth, bheight, 1, CImageFormats::NF_LUMINANCE_ALPHA, CResource::NV_FREE); // На базе изображения создаем текстуру CTexturePtr texp = CTextureManager::GetSingelton().CreateNewTexture(resnamet, mName, pImage); // После создания текстуры, мы больше не нуждаемся в промежуточных данных. mem.FreeBuffer(); CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6, slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows, code, texp); mSize += texp->GetSize(); /// Создаем дисплейный список на букву /////////////////////////////////////////////// letter.GetDispList().CreateList(); letter.GetDispList().BeginList(); /// ////////////////////////////////////////////////////////////////////////////////// if(!texp.IsNull()) texp->ApplyTexture(); // Вычислим какая часть нашей текстуры будет заполнена пустым пространством. // Мы рисуем только ту часть текстуры, в которой находится символ, и сохраняем // информацию в переменных x и y, затем, когда мы рисуем четырехугольник, // мы будем только ссылаться на ту часть текстуры, в которой непосредственно // содержится символ. nReal x = static_cast<nReal>(letter.GetBitmapw()) / static_cast<nReal>(letter.GetWidth()), y = static_cast<nReal>(letter.GetBitmapr()) / static_cast<nReal>(letter.GetHeight()); //glBindTexture(GL_TEXTURE_2D, let.GetTex()); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2i(0,0); glTexCoord2f(0,y); glVertex2i(0,letter.GetBitmapr()); glTexCoord2f(x,y); glVertex2i(letter.GetBitmapw(), letter.GetBitmapr()); glTexCoord2f(x,0); glVertex2i(letter.GetBitmapw(), 0); glEnd(); /// Завершаем дисплейный список ////////////////////////////////////////////////// letter.GetDispList().EndList(); /// ////////////////////////////////////////////////////////////////////////////// letters_map[code] = letter; }
void CDevILCodec::DecodeFromBuffer(const CMemoryBuffer & input, CImage *image, CImageFormats::NovaPixelFormats format, ESaveFormats ext) { ILuint image_id; // Generate the main image name to use. ilGenImages(1, &image_id); // Bind this image name. ilBindImage(image_id); ILenum type = 0; switch(ext) { case SF_BMP: type = IL_BMP; break; case SF_ICO: type = IL_ICO; break; case SF_JPG: type = IL_JPG; break; case SF_PCX: type = IL_PCX; break; case SF_PIC: type = IL_PIC; break; case SF_PNG: type = IL_PNG; break; case SF_TGA: type = IL_TGA; break; case SF_TIF: type = IL_TIF; break; case SF_GIF: type = IL_GIF; break; case SF_DDS: type = IL_DDS; break; case SF_PIX: type = IL_PIX; break; case SF_HDR: type = IL_HDR; break; default: return; } if(!ilLoadL(type, input.GetBegin(), input.GetBufferSize())) { ILenum Error = 0; if((Error = ilGetError()) != NULL) { nstring str("CDevILCodec::DecodeFormStream: Can not load image lump - "); str.append(iluErrorString(Error)); throw NOVA_EXP(str.c_str(), BAD_OPERATION); } } image->GetImageSource().mHeight = ilGetInteger(IL_IMAGE_HEIGHT); image->GetImageSource().mWidth = ilGetInteger(IL_IMAGE_WIDTH); image->GetImageSource().mDepth = ilGetInteger(IL_IMAGE_DEPTH); //if (ilGetInteger(IL_IMAGE_ORIGIN) == IL_ORIGIN_UPPER_LEFT) // iluFlipImage(); if(format == CImageFormats::NF_DEFAULT) { CDevILFormats inf; inf.SetFormat(ilGetInteger(IL_IMAGE_FORMAT)); format = inf.GetExFormat(); } CDevILFormats informat; informat.SetExFormat(format); image->GetImageSource().mPixelFormat = format; size_t _size = image->GetWidth() * image->GetHeight() * image->GetDepth() * ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL); image->GetBits().FreeBuffer(); image->GetBits().AllocBuffer(_size); ilCopyPixels(0, 0, 0, image->GetWidth(), image->GetHeight(), image->GetDepth(), informat.GetFormat(), IL_UNSIGNED_BYTE, image->GetBits().GetBegin()); ilDeleteImages(1, &image_id); ILenum Error = 0; if((Error = ilGetError()) != NULL) { nstring str("CDevILCodec::DecodeFormStream(): Can not load image file - "); str.append(iluErrorString(Error)); throw NOVA_EXP(str.c_str(), BAD_OPERATION); } }
void CDevILCodec::CodeToBuffer(CMemoryBuffer & out, const CImage &image, ESaveFormats ext) { ILuint imageid; CDevILFormats informat; informat.SetExFormat(image.GetPixelFormat()); // Generate the main image name to use. ilGenImages(1, &imageid); // Bind this image name. ilBindImage(imageid); ilTexImage(image.GetWidth(), image.GetHeight(), image.GetDepth(), informat.GetInternalChannels(), informat.GetFormat(), IL_UNSIGNED_BYTE, image.GetBitsPtr()); ILenum type = 0; switch(ext) { case SF_BMP: type = IL_BMP; break; case SF_ICO: type = IL_ICO; break; case SF_JPG: type = IL_JPG; break; case SF_PCX: type = IL_PCX; break; case SF_PIC: type = IL_PIC; break; case SF_PNG: type = IL_PNG; break; case SF_TGA: type = IL_TGA; break; case SF_TIF: type = IL_TIF; break; case SF_GIF: type = IL_GIF; break; case SF_DDS: type = IL_DDS; break; case SF_PIX: type = IL_PIX; break; case SF_HDR: type = IL_HDR; break; default: return; } out.AllocBuffer(image.GetSize()+0xff); ilSaveL(type, out.GetBegin(), out.GetBufferSize()); ilDeleteImages(1, &imageid); ILenum Error = 0; if((Error = ilGetError()) != NULL) { nstring str("CDevILCodec::CodeToStream: "); str.append(iluErrorString(Error)); throw NOVA_EXP(str.c_str(), BAD_OPERATION); } }