Sfoglia il codice sorgente

In Collada: added support for exporting uncompressed embeded textures as bitmap

Léo Terziman 12 anni fa
parent
commit
94f156f809
4 ha cambiato i file con 288 aggiunte e 1 eliminazioni
  1. 145 0
      code/Bitmap.cpp
  2. 139 0
      code/Bitmap.h
  3. 2 0
      code/CMakeLists.txt
  4. 2 1
      code/ColladaExporter.cpp

+ 145 - 0
code/Bitmap.cpp

@@ -0,0 +1,145 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2012, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file Bitmap.cpp
+ *  @brief Defines bitmap format helper for textures
+ *
+ * Used for file formats which embed their textures into the model file.
+ */
+
+#include "AssimpPCH.h"
+
+#include "Bitmap.h"
+
+namespace Assimp {
+
+	void Bitmap::Save(aiTexture* texture, IOStream* file) {
+		if(file != NULL) {
+			Header header;
+			DIB dib;
+
+			dib.size = DIB::dib_size;
+			dib.width = texture->mWidth;
+			dib.height = texture->mHeight;
+			dib.planes = 1;
+			dib.bits_per_pixel = 8 * mBytesPerPixel;
+			dib.compression = 0;
+			dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height;
+			dib.x_resolution = 0;
+			dib.y_resolution = 0;
+			dib.nb_colors = 0;
+			dib.nb_important_colors = 0;
+
+			header.type = 0x4D42; // 'BM'
+			header.offset = Header::header_size + DIB::dib_size;
+			header.size = header.offset + dib.image_size;
+			header.reserved1 = 0;
+			header.reserved2 = 0;
+
+			WriteHeader(header, file);
+			WriteDIB(dib, file);
+			WriteData(texture, file);
+		}
+	}
+
+	template<typename T>
+	inline std::size_t Copy(uint8_t* data, T& field) {
+		std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field);
+	}
+
+	void Bitmap::WriteHeader(Header& header, IOStream* file) {
+		uint8_t data[Header::header_size];
+
+		std::size_t offset = 0;
+
+		offset += Copy(&data[offset], header.type);
+		offset += Copy(&data[offset], header.size);
+		offset += Copy(&data[offset], header.reserved1);
+		offset += Copy(&data[offset], header.reserved2);
+		offset += Copy(&data[offset], header.offset);
+
+		file->Write(data, Header::header_size, 1);
+	}
+
+	void Bitmap::WriteDIB(DIB& dib, IOStream* file) {
+		uint8_t data[DIB::dib_size];
+
+		std::size_t offset = 0;
+
+		offset += Copy(&data[offset], dib.size);
+		offset += Copy(&data[offset], dib.width);
+		offset += Copy(&data[offset], dib.height);
+		offset += Copy(&data[offset], dib.planes);
+		offset += Copy(&data[offset], dib.bits_per_pixel);
+		offset += Copy(&data[offset], dib.compression);
+		offset += Copy(&data[offset], dib.image_size);
+		offset += Copy(&data[offset], dib.x_resolution);
+		offset += Copy(&data[offset], dib.y_resolution);
+		offset += Copy(&data[offset], dib.nb_colors);
+		offset += Copy(&data[offset], dib.nb_important_colors);
+
+		file->Write(data, DIB::dib_size, 1);
+	}
+
+	void Bitmap::WriteData(aiTexture* texture, IOStream* file) {
+		static const std::size_t padding_offset = 4;
+		static const uint8_t padding_data[padding_offset] = {0x0, 0x0, 0x0, 0x0};
+
+		unsigned int padding = (padding_offset - ((mBytesPerPixel * texture->mWidth) % padding_offset)) % padding_offset;
+		uint8_t pixel[mBytesPerPixel];
+
+		for(std::size_t i = 0; i < texture->mHeight; ++i) {
+			for(std::size_t j = 0; j < texture->mWidth; ++j) {
+				const aiTexel& texel = texture->pcData[(texture->mHeight - i - 1) * texture->mWidth + j]; // Bitmap files are stored in bottom-up format
+
+				pixel[0] = texel.r;
+				pixel[1] = texel.g;
+				pixel[2] = texel.b;
+				pixel[3] = texel.a;
+
+				file->Write(pixel, mBytesPerPixel, 1);
+			}
+
+			file->Write(padding_data, padding, 1);
+		}
+	}
+
+}

+ 139 - 0
code/Bitmap.h

@@ -0,0 +1,139 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2012, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file Bitmap.h
+ *  @brief Defines bitmap format helper for textures
+ *
+ * Used for file formats which embed their textures into the model file.
+ */
+
+#ifndef AI_BITMAP_H_INC
+#define AI_BITMAP_H_INC
+
+namespace Assimp {
+
+class Bitmap {
+
+	protected:
+
+		struct Header {
+
+			uint16_t type;
+
+			uint32_t size;
+
+			uint16_t reserved1;
+
+			uint16_t reserved2;
+
+			uint32_t offset;
+
+			// We define the struct size because sizeof(Header) might return a wrong result because of structure padding.
+			// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
+			static const std::size_t header_size =
+				sizeof(uint16_t) + // type
+				sizeof(uint32_t) + // size
+				sizeof(uint16_t) + // reserved1
+				sizeof(uint16_t) + // reserved2
+				sizeof(uint32_t);  // offset
+
+		};
+
+		struct DIB {
+
+			uint32_t size;
+
+			int32_t width;
+
+			int32_t height;
+
+			uint16_t planes;
+
+			uint16_t bits_per_pixel;
+
+			uint32_t compression;
+
+			uint32_t image_size;
+
+			int32_t x_resolution;
+
+			int32_t y_resolution;
+
+			uint32_t nb_colors;
+
+			uint32_t nb_important_colors;
+
+			// We define the struct size because sizeof(DIB) might return a wrong result because of structure padding.
+			// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
+			static const std::size_t dib_size =
+				sizeof(uint32_t) + // size
+				sizeof(int32_t) +  // width
+				sizeof(int32_t) +  // height
+				sizeof(uint16_t) + // planes
+				sizeof(uint16_t) + // bits_per_pixel
+				sizeof(uint32_t) + // compression
+				sizeof(uint32_t) + // image_size
+				sizeof(int32_t) +  // x_resolution
+				sizeof(int32_t) +  // y_resolution
+				sizeof(uint32_t) + // nb_colors
+				sizeof(uint32_t);  // nb_important_colors
+
+		};
+
+		static const std::size_t mBytesPerPixel = 4;
+
+	public:
+
+		static void Save(aiTexture* texture, IOStream* file);
+
+	protected:
+
+		static void WriteHeader(Header& header, IOStream* file);
+
+		static void WriteDIB(DIB& dib, IOStream* file);
+
+		static void WriteData(aiTexture* texture, IOStream* file);
+
+};
+
+}
+
+#endif // AI_BITMAP_H_INC

+ 2 - 0
code/CMakeLists.txt

@@ -140,6 +140,8 @@ SET( Common_SRCS
 	TinyFormatter.h
 	Profiler.h
 	LogAux.h
+	Bitmap.cpp
+	Bitmap.h
 )
 SOURCE_GROUP(Common FILES ${Common_SRCS})
 

+ 2 - 1
code/ColladaExporter.cpp

@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
 #include "ColladaExporter.h"
 
+#include "Bitmap.h"
 #include "fast_atof.h"
 #include "SceneCombiner.h" 
 
@@ -258,7 +259,7 @@ void ColladaExporter::WriteTextures() {
 			if(texture->mHeight == 0) {
 				outfile->Write((void*) texture->pcData, texture->mWidth, 1);
 			} else {
-				//TODO
+				Bitmap::Save(texture, outfile.get());
 			}
 
 			outfile->Flush();