Blender V2.61 - r43446

dds_api.cpp

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * Contributors: Amorilia (amorilia@users.sourceforge.net)
00019  *
00020  * ***** END GPL LICENSE BLOCK *****
00021  */
00022 
00028 #include <stddef.h>
00029 #include <dds_api.h>
00030 #include <Stream.h>
00031 #include <DirectDrawSurface.h>
00032 #include <stdio.h> // printf
00033 #include <fstream>
00034 
00035 extern "C" {
00036 
00037 #include "imbuf.h"
00038 #include "IMB_imbuf_types.h"
00039 #include "IMB_imbuf.h"
00040 #include "IMB_allocimbuf.h"
00041 
00042 
00043 int imb_save_dds(struct ImBuf * ibuf, const char *name, int flags)
00044 {
00045     return(0); /* todo: finish this function */
00046 
00047     /* check image buffer */
00048     if (ibuf == 0) return (0);
00049     if (ibuf->rect == 0) return (0);
00050 
00051     /* open file for writing */
00052     std::ofstream fildes(name);
00053 
00054     /* write header */
00055     fildes << "DDS ";
00056     fildes.close();
00057 
00058     return(1);
00059 }
00060 
00061 int imb_is_a_dds(unsigned char *mem) // note: use at most first 32 bytes
00062 {
00063     /* heuristic check to see if mem contains a DDS file */
00064     /* header.fourcc == FOURCC_DDS */
00065     if ((mem[0] != 'D') || (mem[1] != 'D') || (mem[2] != 'S') || (mem[3] != ' ')) return(0);
00066     /* header.size == 124 */
00067     if ((mem[4] != 124) || mem[5] || mem[6] || mem[7]) return(0);
00068     return(1);
00069 }
00070 
00071 struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags)
00072 {
00073     struct ImBuf * ibuf = 0;
00074     DirectDrawSurface dds(mem, size); /* reads header */
00075     unsigned char bits_per_pixel;
00076     unsigned int *rect;
00077     Image img;
00078     unsigned int numpixels = 0;
00079     int col;
00080     unsigned char *cp = (unsigned char *) &col;
00081     Color32 pixel;
00082     Color32 *pixels = 0;
00083 
00084     if(!imb_is_a_dds(mem))
00085         return (0);
00086 
00087     /* check if DDS is valid and supported */
00088     if (!dds.isValid()) {
00089         /* no need to print error here, just testing if it is a DDS */
00090         if(flags & IB_test)
00091             return (0);
00092 
00093         printf("DDS: not valid; header follows\n");
00094         dds.printInfo();
00095         return(0);
00096     }
00097     if (!dds.isSupported()) {
00098         printf("DDS: format not supported\n");
00099         return(0);
00100     }
00101     if ((dds.width() > 65535) || (dds.height() > 65535)) {
00102         printf("DDS: dimensions too large\n");
00103         return(0);
00104     }
00105 
00106     /* convert DDS into ImBuf */
00107     dds.mipmap(&img, 0, 0); /* load first face, first mipmap */
00108     pixels = img.pixels();
00109     numpixels = dds.width() * dds.height();
00110     bits_per_pixel = 24;
00111     if (img.format() == Image::Format_ARGB) {
00112         /* check that there is effectively an alpha channel */
00113         for (unsigned int i = 0; i < numpixels; i++) {
00114             pixel = pixels[i];
00115             if (pixel.a != 255) {
00116                 bits_per_pixel = 32;
00117                 break;
00118             };
00119         };
00120     };
00121     ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0); 
00122     if (ibuf == 0) return(0); /* memory allocation failed */
00123 
00124     ibuf->ftype = DDS;
00125     ibuf->profile = IB_PROFILE_SRGB;
00126 
00127     if ((flags & IB_test) == 0) {
00128         if (!imb_addrectImBuf(ibuf)) return(ibuf);
00129         if (ibuf->rect == 0) return(ibuf);
00130 
00131         rect = ibuf->rect;
00132         cp[3] = 0xff; /* default alpha if alpha channel is not present */
00133 
00134         for (unsigned int i = 0; i < numpixels; i++) {
00135             pixel = pixels[i];
00136             cp[0] = pixel.r; /* set R component of col */
00137             cp[1] = pixel.g; /* set G component of col */
00138             cp[2] = pixel.b; /* set B component of col */
00139             if (bits_per_pixel == 32)
00140                 cp[3] = pixel.a; /* set A component of col */
00141             rect[i] = col;
00142         }
00143         IMB_flipy(ibuf);
00144     }
00145 
00146     return(ibuf);
00147 }
00148 
00149 } // extern "C"