Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorKent Mein <mein@cs.umn.edu>2007-10-12 20:09:59 +0400
committerKent Mein <mein@cs.umn.edu>2007-10-12 20:09:59 +0400
commit6fe98f19a95117633684b85073b4d90654e159fd (patch)
tree50d54508e6e4395442fb486d96cb7202a871ee5e /source
parent3697e0852467a29223a59d2ad6a31a00cfbde529 (diff)
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
Diffstat (limited to 'source')
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp112
-rw-r--r--source/blender/imbuf/intern/dds/Stream.cpp11
-rw-r--r--source/blender/imbuf/intern/dds/Stream.h1
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.cpp30
4 files changed, 137 insertions, 17 deletions
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index 6937840334d..c28f8b5b72d 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -434,16 +434,15 @@ bool DirectDrawSurface::isSupported() const
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 @@ bool DirectDrawSurface::isSupported() const
return false;
}
}
- */
else
{
return false;
@@ -500,8 +498,18 @@ unsigned int DirectDrawSurface::depth() const
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 @@ void DirectDrawSurface::mipmap(Image * img, unsigned int face, unsigned int mipm
}
}
+/* 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)
diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp
index a181ec74476..2340598b4fa 100644
--- a/source/blender/imbuf/intern/dds/Stream.cpp
+++ b/source/blender/imbuf/intern/dds/Stream.cpp
@@ -86,3 +86,14 @@ unsigned int mem_read(Stream & mem, unsigned char & i)
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);
+}
+
diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h
index 1e7d3c6b536..373e68db44e 100644
--- a/source/blender/imbuf/intern/dds/Stream.h
+++ b/source/blender/imbuf/intern/dds/Stream.h
@@ -43,6 +43,7 @@ unsigned int mem_read(Stream & mem, unsigned long long & i);
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
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
index 0e06fd3e50b..3de30b9f183 100644
--- a/source/blender/imbuf/intern/dds/dds_api.cpp
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -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 @@ extern "C" {
#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 *imb_load_dds(unsigned char *mem, int size, int flags)
{
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 @@ struct ImBuf *imb_load_dds(unsigned char *mem, int size, int flags)
}
/* 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 @@ struct ImBuf *imb_load_dds(unsigned char *mem, int size, int flags)
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;
}