static size_t s_read(int fd, void* buf, size_t count) { std::map<int, FileInfo>::iterator iter; iter = s_fileInfos.find(fd); if (iter == s_fileInfos.end()) /* sanity check */ { errno = EBADF; return -1; } size_t size; char *key=NULL; switch (iter->second.encrypt) { case 0: key = NULL; break; case 1: key = s_codeKey; break; case 2: key = s_assetsKey; break; } if (key) { off_t curr = s_lseek(fd, 0, SEEK_CUR); size = readHelper(fd, buf, count); if (curr != (off_t)-1 && size != (size_t)-1) for (size_t i = (curr<32)?(32-curr):0; i < size; ++i) ((char*)buf)[i] ^= key[(((curr+i)*13)+(((curr+i)/256)*31))%256]; } else { size = readHelper(fd, buf, count); } return size; }
TriMesh::TriMesh(Stream *_stream, int index) : Shape(Properties()), m_tangents(NULL) { ref<Stream> stream = _stream; if (index != 0) { /* Determine the position of the requested substream. This is stored at the end of the file */ stream->setPos(stream->getSize() - sizeof(uint32_t)); uint32_t count = stream->readUInt(); if (index < 0 || index > (int) count) { Log(EError, "Unable to unserialize mesh, " "shape index is out of range! (requested %i out of 0..%i)", index, count-1); } stream->setPos(stream->getSize() - sizeof(uint32_t) * (1+count-index)); // Seek to the correct position stream->setPos(stream->readUInt()); } if (stream->getByteOrder() != Stream::ELittleEndian) Log(EError, "Tried to unserialize a shape from a stream, " "which was not previously set to little endian byte order!"); short format = stream->readShort(); if (format == 0x1C04) Log(EError, "Encountered a geometry file generated by an old " "version of Mitsuba. Please re-import the scene to update this file " "to the current format."); if (format != MTS_FILEFORMAT_HEADER) Log(EError, "Encountered an invalid file format!"); short version = stream->readShort(); if (version != MTS_FILEFORMAT_VERSION_V3) Log(EError, "Encountered an incompatible file version!"); stream = new ZStream(stream); uint32_t flags = stream->readUInt(); m_vertexCount = stream->readSize(); m_triangleCount = stream->readSize(); bool fileDoublePrecision = flags & EDoublePrecision; m_faceNormals = flags & EFaceNormals; m_positions = new Point[m_vertexCount]; readHelper(stream, fileDoublePrecision, reinterpret_cast<Float *>(m_positions), m_vertexCount, sizeof(Point)/sizeof(Float)); if (flags & EHasNormals) { m_normals = new Normal[m_vertexCount]; readHelper(stream, fileDoublePrecision, reinterpret_cast<Float *>(m_normals), m_vertexCount, sizeof(Normal)/sizeof(Float)); } else { m_normals = NULL; } if (flags & EHasTexcoords) { m_texcoords = new Point2[m_vertexCount]; readHelper(stream, fileDoublePrecision, reinterpret_cast<Float *>(m_texcoords), m_vertexCount, sizeof(Point2)/sizeof(Float)); } else { m_texcoords = NULL; } if (flags & EHasColors) { m_colors = new Spectrum[m_vertexCount]; readHelper(stream, fileDoublePrecision, reinterpret_cast<Float *>(m_colors), m_vertexCount, sizeof(Spectrum)/sizeof(Float)); } else { m_colors = NULL; } m_triangles = new Triangle[m_triangleCount]; stream->readUIntArray(reinterpret_cast<uint32_t *>(m_triangles), m_triangleCount * sizeof(Triangle)/sizeof(uint32_t)); m_flipNormals = false; }