[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12256] trunk/blender/source/blender/imbuf /intern/dds: This is patch [#7483] imbuf support for uncompressed DDS images

Kent Mein mein at cs.umn.edu
Fri Oct 12 18:10:00 CEST 2007


Revision: 12256
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12256
Author:   sirdude
Date:     2007-10-12 18:09:59 +0200 (Fri, 12 Oct 2007)

Log Message:
-----------
This is patch [#7483] imbuf support for uncompressed DDS images
provided by Amorilia

NVIDIA updated the dds stuff so we get a nice new patch.

Kent

Modified Paths:
--------------
    trunk/blender/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
    trunk/blender/source/blender/imbuf/intern/dds/Stream.cpp
    trunk/blender/source/blender/imbuf/intern/dds/Stream.h
    trunk/blender/source/blender/imbuf/intern/dds/dds_api.cpp

Modified: trunk/blender/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
===================================================================
--- trunk/blender/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp	2007-10-12 07:29:38 UTC (rev 12255)
+++ trunk/blender/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp	2007-10-12 16:09:59 UTC (rev 12256)
@@ -434,16 +434,15 @@
 			return false;
 		}
 	}
-	/*
 	else if (header.pf.flags & DDPF_RGB)
 	{
 		if (header.pf.bitcount == 24)
 		{
-			return false;
+			return true;
 		}
 		else if (header.pf.bitcount == 32)
 		{
-			return false;
+			return true;
 		}
 		else
 		{
@@ -451,7 +450,6 @@
 			return false;
 		}
 	}
-	*/
 	else
 	{
 		return false;
@@ -500,8 +498,18 @@
 
 bool DirectDrawSurface::hasAlpha() const
 {
-	if (header.pf.fourcc == FOURCC_DXT1) return false;
-	else return true;
+	if ((header.pf.flags & DDPF_RGB) && (header.pf.amask == 0))
+	{
+		return false;
+	}
+	else if (header.pf.fourcc == FOURCC_DXT1)
+	{
+		return false;
+	}
+	else
+	{
+		return true;
+	}
 }
 
 bool DirectDrawSurface::isTexture2D() const
@@ -545,10 +553,98 @@
 	}
 }
 
+/* helper function for readLinearImage */
+void maskShiftAndSize(unsigned int mask, unsigned int * shift, unsigned int * size)
+{
+	if (!mask)
+	{
+		*shift = 0;
+		*size = 0;
+		return;
+	}
+
+	*shift = 0;
+	while((mask & 1) == 0) {
+		++(*shift);
+		mask >>= 1;
+	}
+	
+	*size = 0;
+	while((mask & 1) == 1) {
+		++(*size);
+		mask >>= 1;
+	}
+}
+
+/* helper function for readLinearImage */
+unsigned int convert(unsigned int c, unsigned int inbits, unsigned int outbits)
+{
+	if (inbits == 0) {
+		return 0;
+	}
+	else if (inbits == outbits)
+	{
+		return c;
+	}
+	else if (inbits > outbits) 
+	{
+		// truncate
+		return c >> (inbits - outbits);
+	}
+	else
+	{
+		// bitexpand
+		return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
+	}
+}
+
 void DirectDrawSurface::readLinearImage(Image * img)
 {
-	// @@ Read linear RGB images.
-	printf("DDS: linear RGB images not supported\n");
+	const unsigned int w = img->width();
+	const unsigned int h = img->height();
+
+	unsigned int rshift, rsize;
+	maskShiftAndSize(header.pf.rmask, &rshift, &rsize);
+	
+	unsigned int gshift, gsize;
+	maskShiftAndSize(header.pf.gmask, &gshift, &gsize);
+	
+	unsigned int bshift, bsize;
+	maskShiftAndSize(header.pf.bmask, &bshift, &bsize);
+	
+	unsigned int ashift, asize;
+	maskShiftAndSize(header.pf.amask, &ashift, &asize);
+
+	unsigned int byteCount = (header.pf.bitcount + 7) / 8;
+	if (byteCount > 4)
+	{
+		/* just in case... we could have segfaults later on if byteCount > 4 */
+		printf("DDS: bitcount too large (file corrupt?)");
+		return;
+	}
+
+	if (header.pf.amask != 0)
+	{
+		img->setFormat(Image::Format_ARGB);
+	}
+
+	// Read linear RGB images.
+	for (unsigned int y = 0; y < h; y++)
+	{
+		for (unsigned int x = 0; x < w; x++)
+		{
+			unsigned int c = 0;
+			mem_read(stream, (unsigned char *)(&c), byteCount);
+
+			Color32 pixel(0, 0, 0, 0xFF);
+			pixel.r = convert(c >> rshift, rsize, 8);
+			pixel.g = convert(c >> gshift, gsize, 8);
+			pixel.b = convert(c >> bshift, bsize, 8);
+			pixel.a = convert(c >> ashift, asize, 8);
+
+			img->pixel(x, y) = pixel;
+		}
+	}
 }
 
 void DirectDrawSurface::readBlockImage(Image * img)

Modified: trunk/blender/source/blender/imbuf/intern/dds/Stream.cpp
===================================================================
--- trunk/blender/source/blender/imbuf/intern/dds/Stream.cpp	2007-10-12 07:29:38 UTC (rev 12255)
+++ trunk/blender/source/blender/imbuf/intern/dds/Stream.cpp	2007-10-12 16:09:59 UTC (rev 12256)
@@ -86,3 +86,14 @@
 	return(1);
 }
 
+unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt)
+{
+	if (mem.pos + cnt > mem.size) {
+		printf("DDS: trying to read beyond end of stream (corrupt file?)");
+		return(0);
+	};
+	memcpy(i, mem.mem + mem.pos, cnt);
+	mem.pos += cnt;
+	return(cnt);
+}
+

Modified: trunk/blender/source/blender/imbuf/intern/dds/Stream.h
===================================================================
--- trunk/blender/source/blender/imbuf/intern/dds/Stream.h	2007-10-12 07:29:38 UTC (rev 12255)
+++ trunk/blender/source/blender/imbuf/intern/dds/Stream.h	2007-10-12 16:09:59 UTC (rev 12256)
@@ -43,6 +43,7 @@
 unsigned int mem_read(Stream & mem, unsigned int & i);
 unsigned int mem_read(Stream & mem, unsigned short & i);
 unsigned int mem_read(Stream & mem, unsigned char & i);
+unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt);
 
 #endif // _STREAM_H
 

Modified: trunk/blender/source/blender/imbuf/intern/dds/dds_api.cpp
===================================================================
--- trunk/blender/source/blender/imbuf/intern/dds/dds_api.cpp	2007-10-12 07:29:38 UTC (rev 12255)
+++ trunk/blender/source/blender/imbuf/intern/dds/dds_api.cpp	2007-10-12 16:09:59 UTC (rev 12256)
@@ -28,8 +28,8 @@
 #include <dds_api.h>
 #include <Stream.h>
 #include <DirectDrawSurface.h>
-
 #include <stdio.h> // printf
+#include <fstream>
 
 extern "C" {
 
@@ -39,12 +39,24 @@
 #include "IMB_imbuf.h"
 #include "IMB_allocimbuf.h"
 
-/* not supported yet
+
 short imb_save_dds(struct ImBuf * ibuf, char *name, int flags)
 {
-	return(0);
+	return(0); /* todo: finish this function */
+
+	/* check image buffer */
+	if (ibuf == 0) return (0);
+	if (ibuf->rect == 0) return (0);
+
+	/* open file for writing */
+	std::ofstream fildes(name);
+
+	/* write header */
+	fildes << "DDS ";
+	fildes.close();
+
+	return(1);
 }
-*/
 
 int imb_is_a_dds(unsigned char *mem) // note: use at most first 32 bytes
 {
@@ -60,7 +72,7 @@
 {
 	struct ImBuf * ibuf = 0;
 	DirectDrawSurface dds(mem, size); /* reads header */
-	unsigned char bytes_per_pixel;
+	unsigned char bits_per_pixel;
 	unsigned int *rect;
 	Image img;
 	unsigned int numpixels = 0;
@@ -85,9 +97,9 @@
 	}
 
 	/* convert DDS into ImBuf */
-	if (dds.hasAlpha()) bytes_per_pixel = 32;
-	else bytes_per_pixel = 24;
-	ibuf = IMB_allocImBuf(dds.width(), dds.height(), bytes_per_pixel, 0, 0); 
+	if (dds.hasAlpha()) bits_per_pixel = 32;
+	else bits_per_pixel = 24;
+	ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0, 0); 
 	if (ibuf == 0) return(0); /* memory allocation failed */
 
 	ibuf->ftype = DDS;
@@ -107,7 +119,7 @@
 			cp[0] = pixel.r; /* set R component of col */
 			cp[1] = pixel.g; /* set G component of col */
 			cp[2] = pixel.b; /* set B component of col */
-			if (bytes_per_pixel == 32)
+			if (bits_per_pixel == 32)
 				cp[3] = pixel.a; /* set A component of col */
 			rect[i] = col;
 		}





More information about the Bf-blender-cvs mailing list