Blender V2.61 - r43446
|
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"