- Timestamp:
- 03/21/12 18:36:20 (14 months ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osgPlugins/pvr/ReaderWriterPVR.cpp
r12597 r13041 73 73 int testWord; 74 74 char testByte[sizeof(int)]; 75 }endianTest; 75 }endianTest; 76 76 endianTest.testWord = 1; 77 77 if( endianTest.testByte[0] == 1 ) … … 80 80 return true; 81 81 } 82 82 83 83 template <class T> 84 84 inline void swapBytes( T &s ) 85 85 { 86 if( sizeof( T ) == 1 ) 86 if( sizeof( T ) == 1 ) 87 87 return; 88 88 89 89 T d = s; 90 90 BytePtr sptr = (BytePtr)&s; 91 91 BytePtr dptr = &(((BytePtr)&d)[sizeof(T)-1]); 92 92 93 93 for( unsigned int i = 0; i < sizeof(T); i++ ) 94 94 *(sptr++) = *(dptr--); … … 118 118 { 119 119 public: 120 120 121 121 ReaderWriterPVR() 122 122 { 123 123 supportsExtension("pvr","PVR image format"); 124 124 } 125 125 126 126 virtual const char* className() const { return "PVR Image Reader/Writer"; } 127 127 128 128 129 129 ReadResult readPVRStream(std::istream& fin) const 130 130 { 131 131 PVRTexHeader header; 132 132 133 133 fin.read((char*)&header, sizeof(PVRTexHeader)); 134 134 if(!fin.good()){ … … 136 136 return ReadResult::ERROR_IN_READING_FILE; 137 137 } 138 138 139 139 if(header.needsBytesSwapped()) 140 140 header.swapBytes(); 141 141 142 142 if(gPVRTexIdentifier[0] != static_cast<char>((header.pvrTag >> 0) & 0xff) || 143 143 gPVRTexIdentifier[1] != static_cast<char>((header.pvrTag >> 8) & 0xff) || … … 148 148 return ReadResult::FILE_NOT_HANDLED; 149 149 } 150 151 150 151 152 152 uint32_t formatFlags = header.flags & PVR_TEXTURE_FLAG_TYPE_MASK; 153 153 GLenum internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; 154 154 uint32_t width, height; 155 155 156 156 if(formatFlags == kPVRTextureFlagTypePVRTC_4 || formatFlags == kPVRTextureFlagTypePVRTC_2 || 157 157 formatFlags == kPVRTextureFlagTypeOGLPVRTC_4 || formatFlags == kPVRTextureFlagTypeOGLPVRTC_2 || … … 163 163 else if(formatFlags == kPVRTextureFlagTypeETC) 164 164 internalFormat = GL_ETC1_RGB8_OES; 165 165 166 166 width = header.width; 167 167 height = header.height; … … 169 169 osg::ref_ptr<osg::Image> image = new osg::Image; 170 170 if (!image) return ReadResult::INSUFFICIENT_MEMORY_TO_LOAD; 171 171 172 172 unsigned char *imageData = new unsigned char[header.dataLength]; 173 173 if (!imageData) return ReadResult::INSUFFICIENT_MEMORY_TO_LOAD; 174 174 175 175 fin.read((char*)imageData, header.dataLength); 176 176 if(!fin.good()) … … 179 179 return ReadResult::ERROR_IN_READING_FILE; 180 180 } 181 181 182 182 image->setImage(header.width, header.height, 1, 183 183 internalFormat, internalFormat, … … 185 185 imageData, 186 186 osg::Image::USE_NEW_DELETE); 187 187 188 188 uint32_t dataOffset = 0; 189 189 uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0; 190 190 uint32_t bpp = 4; 191 191 192 192 osg::Image::MipmapDataType mipmapdata; 193 193 194 194 // Calculate the data size for each texture level and respect the minimum number of blocks 195 195 while(dataOffset < header.dataLength){ … … 210 210 bpp = 2; 211 211 } 212 212 213 213 // Clamp to minimum number of blocks 214 214 if(widthBlocks < 2) … … 216 216 if(heightBlocks < 2) 217 217 heightBlocks = 2; 218 218 219 219 if(dataOffset > 0) 220 220 mipmapdata.push_back(dataOffset); 221 221 222 222 dataOffset += widthBlocks * heightBlocks * ((blockSize * bpp) / 8); 223 223 224 224 width = osg::maximum(width >> 1, (uint32_t)1); 225 225 height = osg::maximum(height >> 1, (uint32_t)1); 226 226 } 227 227 228 228 if(!mipmapdata.empty()) 229 229 image->setMipmapLevels(mipmapdata); 230 230 231 231 return image.get(); 232 232 } 233 233 234 234 osg::notify(osg::WARN) << "Failed to read pvr data." << std::endl; 235 return ReadResult::FILE_NOT_HANDLED; 236 } 237 235 return ReadResult::FILE_NOT_HANDLED; 236 } 237 238 238 virtual ReadResult readObject(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const 239 239 { … … 250 250 return readPVRStream(fin); 251 251 } 252 252 253 253 virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const 254 254 { … … 256 256 if(!acceptsExtension(ext)) 257 257 return ReadResult::FILE_NOT_HANDLED; 258 258 259 259 std::string fileName = osgDB::findDataFile(file, options); 260 260 if(fileName.empty()) 261 261 return ReadResult::FILE_NOT_FOUND; 262 262 263 263 std::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); 264 264 if(!istream) return ReadResult::FILE_NOT_HANDLED;
