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