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
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user