diff options
Diffstat (limited to 'source/blender/imbuf/intern/dds/dds_api.cpp')
-rw-r--r-- | source/blender/imbuf/intern/dds/dds_api.cpp | 258 |
1 files changed, 134 insertions, 124 deletions
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp index fa88f81b55a..6a76e231e37 100644 --- a/source/blender/imbuf/intern/dds/dds_api.cpp +++ b/source/blender/imbuf/intern/dds/dds_api.cpp @@ -18,7 +18,6 @@ * \ingroup imbdds */ - extern "C" { #include "BLI_utildefines.h" } @@ -28,11 +27,11 @@ extern "C" { #include <Stream.h> #include <DirectDrawSurface.h> #include <FlipDXT.h> -#include <stdio.h> // printf +#include <stdio.h> // printf #include <fstream> -#if defined (WIN32) -#include "utfconv.h" +#if defined(WIN32) +# include "utfconv.h" #endif extern "C" { @@ -47,138 +46,149 @@ extern "C" { int imb_save_dds(struct ImBuf *ibuf, const char *name, int /*flags*/) { - return(0); /* todo: finish this function */ + return (0); /* todo: finish this function */ - /* check image buffer */ - if (ibuf == 0) return (0); - if (ibuf->rect == 0) return (0); + /* check image buffer */ + if (ibuf == 0) + return (0); + if (ibuf->rect == 0) + return (0); - /* open file for writing */ - std::ofstream fildes; + /* open file for writing */ + std::ofstream fildes; -#if defined (WIN32) - wchar_t *wname = alloc_utf16_from_8(name, 0); - fildes.open(wname); - free(wname); +#if defined(WIN32) + wchar_t *wname = alloc_utf16_from_8(name, 0); + fildes.open(wname); + free(wname); #else - fildes.open(name); + fildes.open(name); #endif - /* write header */ - fildes << "DDS "; - fildes.close(); + /* write header */ + fildes << "DDS "; + fildes.close(); - return(1); + return (1); } -int imb_is_a_dds(const unsigned char *mem) // note: use at most first 32 bytes +int imb_is_a_dds(const unsigned char *mem) // note: use at most first 32 bytes { - /* heuristic check to see if mem contains a DDS file */ - /* header.fourcc == FOURCC_DDS */ - if ((mem[0] != 'D') || (mem[1] != 'D') || (mem[2] != 'S') || (mem[3] != ' ')) return(0); - /* header.size == 124 */ - if ((mem[4] != 124) || mem[5] || mem[6] || mem[7]) return(0); - return(1); + /* heuristic check to see if mem contains a DDS file */ + /* header.fourcc == FOURCC_DDS */ + if ((mem[0] != 'D') || (mem[1] != 'D') || (mem[2] != 'S') || (mem[3] != ' ')) + return (0); + /* header.size == 124 */ + if ((mem[4] != 124) || mem[5] || mem[6] || mem[7]) + return (0); + return (1); } -struct ImBuf *imb_load_dds(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +struct ImBuf *imb_load_dds(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]) { - struct ImBuf *ibuf = NULL; - DirectDrawSurface dds((unsigned char *)mem, size); /* reads header */ - unsigned char bits_per_pixel; - unsigned int *rect; - Image img; - unsigned int numpixels = 0; - int col; - unsigned char *cp = (unsigned char *) &col; - Color32 pixel; - Color32 *pixels = 0; - - /* OCIO_TODO: never was able to save DDS, so can't test loading - * but profile used to be set to sRGB and can't see rect_float here, so - * default byte space should work fine - */ - colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); - - if (!imb_is_a_dds(mem)) - return (0); - - /* check if DDS is valid and supported */ - if (!dds.isValid()) { - /* no need to print error here, just testing if it is a DDS */ - if (flags & IB_test) - return (0); - - printf("DDS: not valid; header follows\n"); - dds.printInfo(); - return(0); - } - if (!dds.isSupported()) { - printf("DDS: format not supported\n"); - return(0); - } - if ((dds.width() > 65535) || (dds.height() > 65535)) { - printf("DDS: dimensions too large\n"); - return(0); - } - - /* convert DDS into ImBuf */ - dds.mipmap(&img, 0, 0); /* load first face, first mipmap */ - pixels = img.pixels(); - numpixels = dds.width() * dds.height(); - bits_per_pixel = 24; - if (img.format() == Image::Format_ARGB) { - /* check that there is effectively an alpha channel */ - for (unsigned int i = 0; i < numpixels; i++) { - pixel = pixels[i]; - if (pixel.a != 255) { - bits_per_pixel = 32; - break; - } - } - } - ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0); - if (ibuf == 0) return(0); /* memory allocation failed */ - - ibuf->ftype = IMB_FTYPE_DDS; - ibuf->dds_data.fourcc = dds.fourCC(); - ibuf->dds_data.nummipmaps = dds.mipmapCount(); - - if ((flags & IB_test) == 0) { - if (!imb_addrectImBuf(ibuf)) return(ibuf); - if (ibuf->rect == 0) return(ibuf); - - rect = ibuf->rect; - cp[3] = 0xff; /* default alpha if alpha channel is not present */ - - for (unsigned int i = 0; i < numpixels; i++) { - pixel = pixels[i]; - 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 (dds.hasAlpha()) - cp[3] = pixel.a; /* set A component of col */ - rect[i] = col; - } - - if (ibuf->dds_data.fourcc != FOURCC_DDS) { - ibuf->dds_data.data = (unsigned char *)dds.readData(ibuf->dds_data.size); - - /* flip compressed texture */ - if (ibuf->dds_data.data) { - FlipDXTCImage(dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data); - } - } - else { - ibuf->dds_data.data = NULL; - ibuf->dds_data.size = 0; - } - - /* flip uncompressed texture */ - IMB_flipy(ibuf); - } - - return(ibuf); + struct ImBuf *ibuf = NULL; + DirectDrawSurface dds((unsigned char *)mem, size); /* reads header */ + unsigned char bits_per_pixel; + unsigned int *rect; + Image img; + unsigned int numpixels = 0; + int col; + unsigned char *cp = (unsigned char *)&col; + Color32 pixel; + Color32 *pixels = 0; + + /* OCIO_TODO: never was able to save DDS, so can't test loading + * but profile used to be set to sRGB and can't see rect_float here, so + * default byte space should work fine + */ + colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); + + if (!imb_is_a_dds(mem)) + return (0); + + /* check if DDS is valid and supported */ + if (!dds.isValid()) { + /* no need to print error here, just testing if it is a DDS */ + if (flags & IB_test) + return (0); + + printf("DDS: not valid; header follows\n"); + dds.printInfo(); + return (0); + } + if (!dds.isSupported()) { + printf("DDS: format not supported\n"); + return (0); + } + if ((dds.width() > 65535) || (dds.height() > 65535)) { + printf("DDS: dimensions too large\n"); + return (0); + } + + /* convert DDS into ImBuf */ + dds.mipmap(&img, 0, 0); /* load first face, first mipmap */ + pixels = img.pixels(); + numpixels = dds.width() * dds.height(); + bits_per_pixel = 24; + if (img.format() == Image::Format_ARGB) { + /* check that there is effectively an alpha channel */ + for (unsigned int i = 0; i < numpixels; i++) { + pixel = pixels[i]; + if (pixel.a != 255) { + bits_per_pixel = 32; + break; + } + } + } + ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0); + if (ibuf == 0) + return (0); /* memory allocation failed */ + + ibuf->ftype = IMB_FTYPE_DDS; + ibuf->dds_data.fourcc = dds.fourCC(); + ibuf->dds_data.nummipmaps = dds.mipmapCount(); + + if ((flags & IB_test) == 0) { + if (!imb_addrectImBuf(ibuf)) + return (ibuf); + if (ibuf->rect == 0) + return (ibuf); + + rect = ibuf->rect; + cp[3] = 0xff; /* default alpha if alpha channel is not present */ + + for (unsigned int i = 0; i < numpixels; i++) { + pixel = pixels[i]; + 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 (dds.hasAlpha()) + cp[3] = pixel.a; /* set A component of col */ + rect[i] = col; + } + + if (ibuf->dds_data.fourcc != FOURCC_DDS) { + ibuf->dds_data.data = (unsigned char *)dds.readData(ibuf->dds_data.size); + + /* flip compressed texture */ + if (ibuf->dds_data.data) { + FlipDXTCImage( + dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data); + } + } + else { + ibuf->dds_data.data = NULL; + ibuf->dds_data.size = 0; + } + + /* flip uncompressed texture */ + IMB_flipy(ibuf); + } + + return (ibuf); } -} // extern "C" +} // extern "C" |