Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

Diff Revisions 167 vs 168 for /trunk/Source Code/Utility/ImageTools.cpp

Diff revisions: vs.
  @@ -1,4 +1,5 @@
1 1 #include "Headers/ImageTools.h"
2 + #include "Hardware/Video/Headers/RenderAPIEnums.h"
2 3
3 4 #define IL_STATIC_LIB
4 5 #undef _UNICODE
  @@ -6,240 +7,218 @@
6 7 #include <IL/ilu.h>
7 8
8 9 namespace ImageTools {
9 - U8* OpenImagePPM(const std::string& filename, U16& w, U16& h, U8& d, U32& t, U32& ilTexture,const bool flip) {
10 - char head[70];
11 - I8 i;
12 - U8 * img = NULL;
13 - FILE* f;
14 - f = fopen(filename.c_str(),"rb");
10 + inline GFXImageFormat textureFormatDevIL(ILint format)
11 + {
12 + switch(format) {
13 + case IL_RGB : return RGB;
14 + case IL_ALPHA : return ALPHA;
15 + case IL_RGBA : return RGBA;
16 + case IL_BGR : return BGR;
17 + case IL_BGRA : return BGRA;
18 + case IL_LUMINANCE : return LUMINANCE;
19 + case IL_LUMINANCE_ALPHA : return LUMINANCE_ALPHA;
20 + };
21 +
22 + return RGB;
23 + }
24 +
25 + void initialize() {
26 + // used to play nice with DevIL (DevIL acts like OpenGL - a state machine)
27 + static bool first = true;
28 + if(!first)
29 + return;
15 30
16 - if(f==NULL){
17 - return 0;
18 - }
19 - fgets(head,70,f);
20 -
21 - if(!strncmp(head, "P6", 2)){
22 - i=0;
23 - while(i<3){
24 - fgets(head,70,f);
25 -
26 - if(head[0] == '#'){
27 - continue;
28 - }
29 -
30 - if(i==0)
31 - i += sscanf_s(head, "%d %d %d", &w, &h, &d);
32 - else if(i==1)
33 - i += sscanf_s(head, "%d %d", &h, &d);
34 - else if(i==2)
35 - i += sscanf_s(head, "%d", &d);
36 - }
37 -
38 - img = New U8[(size_t)(w) * (size_t)(h) * 3];
39 - if(img==NULL) {
40 - fclose(f);
41 - return 0;
42 - }
43 -
44 - fread(img, sizeof(U8), (size_t)w*(size_t)h*3,f);
45 - fclose(f);
46 - }
47 - else{
48 - fclose(f);
49 - }
50 - t = 0;
51 - ilTexture = 0;
52 - return img;
53 - }
54 -
55 - U8* OpenImageDevIL(const std::string& filename, U16& w, U16& h, U8& d, U32& t,U32& ilTexture, bool& alpha,const bool flip) {
56 - static bool first = true;
57 - WriteLock w_lock(_loadingMutex);
58 - if(first) {
59 31 first = false;
60 32 ilInit();
61 33 ilEnable(IL_TYPE_SET);
62 34 ilTypeFunc(IL_UNSIGNED_BYTE);
35 +
36 + }
37 +
38 + void ImageData::throwLoadError(const std::string& fileName){
39 + ERROR_FN(Locale::get("ERROR_IMAGETOOLS_INVALID_IMAGE_FILE"),fileName.c_str());
40 + ILenum error;
41 + while((error = ilGetError()) != IL_NO_ERROR) {
42 + ERROR_FN(Locale::get("ERROR_IMAGETOOLS_DEVIL"), iluErrorString(error));
43 + }
44 +
45 + ilDeleteImages(1, &_ilTexture);
46 + _ilTexture = 0;
47 + }
48 +
49 + bool ImageData::prepareInternalData() {
50 +
51 + initialize();
52 +
53 + ilOriginFunc(_flip ? IL_ORIGIN_LOWER_LEFT : IL_ORIGIN_UPPER_LEFT);
54 + ilEnable(IL_ORIGIN_SET);
55 + ilGenImages(1, &_ilTexture);
56 + ilBindImage(_ilTexture);
57 + return true;
58 + }
59 +
60 + bool ImageData::setInternalData() {
61 + assert(ilGetInteger(IL_CUR_IMAGE) != 0);
62 + _dimensions.set(ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT));
63 + _bpp = ilGetInteger(IL_IMAGE_BPP);
64 + ILint format = ilGetInteger(IL_IMAGE_FORMAT);
65 +
66 + // we determine the target format and use a flag to determine if we should convert or not
67 + ILint targetFormat = format;
68 +
69 + switch(format){
70 + //palette types
71 + case IL_COLOR_INDEX: {
72 + switch(ilGetInteger(IL_PALETTE_TYPE)) {
73 + default:
74 + case IL_PAL_NONE: {
75 + throwLoadError(_name);
76 + return false;
77 + }
78 + case IL_PAL_RGB24:
79 + case IL_PAL_RGB32:
80 + case IL_PAL_BGR24:
81 + case IL_PAL_BGR32: targetFormat = IL_RGB; break;
82 + case IL_PAL_BGRA32:
83 + case IL_PAL_RGBA32: targetFormat = IL_RGBA; break;
84 + }
85 + } break;
86 + case IL_BGRA: targetFormat = IL_RGBA; break;
87 + case IL_BGR: targetFormat = IL_RGB; break;
88 + }
89 +
90 + // if the image's format is not desired or the image's data type is not in unsigned byte format, we should convert it
91 + if(format != targetFormat || (ilGetInteger(IL_IMAGE_TYPE) != IL_UNSIGNED_BYTE)){
92 + if(ilConvertImage(targetFormat, IL_UNSIGNED_BYTE) != IL_TRUE){
93 + throwLoadError(_name);
94 + return false;
95 + }
96 + format = targetFormat;
97 + }
98 +
99 + // most formats do not have an alpha channel
100 + _alpha = (format == IL_RGBA || format == IL_LUMINANCE_ALPHA || format == IL_ALPHA);
101 + _format = textureFormatDevIL(format);
102 + size_t imageSize = (size_t)(_dimensions.width) * (size_t)(_dimensions.height) * (size_t)(_bpp);
103 +
104 + _data = New U8[imageSize];
105 + memcpy(_data, ilGetData(), imageSize);
106 +
107 + ilBindImage(0);
108 + return true;
109 + }
110 +
111 + bool ImageData::create(const void* ptr, U32 size) {
112 + WriteLock w_lock(_loadingMutex);
113 + prepareInternalData();
114 + _name = "[buffer offset file]";
115 + if (ilLoadL(IL_TYPE_UNKNOWN, ptr, size) == IL_FALSE) {
116 + throwLoadError(_name);
117 + return false;
118 + }
119 +
120 + return setInternalData();
121 + }
122 +
123 + bool ImageData::create(const std::string& filename) {
124 + WriteLock w_lock(_loadingMutex);
125 + prepareInternalData();
126 + _name = filename;
127 + if (ilLoadImage(filename.c_str()) == IL_FALSE) {
128 + throwLoadError(_name);
129 + return false;
130 + }
131 +
132 + return setInternalData();
133 +
63 134 }
64 135
65 - ilOriginFunc(flip ? IL_ORIGIN_LOWER_LEFT : IL_ORIGIN_UPPER_LEFT);
66 - ilEnable(IL_ORIGIN_SET);
136 + void ImageData::destroy(){
137 + ilDeleteImages(1, &_ilTexture);
138 + SAFE_DELETE_ARRAY(_data);
139 + }
140 +
141 + vec3<I32> ImageData::getColor(U16 x, U16 y) const {
142 + I32 idx = (y * _dimensions.width + x) * _bpp;
143 + return vec3<I32>( _data[idx+0], _data[idx+1], _data[idx+2]);
144 + }
145 +
146 + void ImageData::resize(U16 width, U16 height) {
147 + ilBindImage(_ilTexture);
148 + iluImageParameter(ILU_FILTER,ILU_SCALE_BELL);
149 + iluScale(width,height,_bpp);
150 + _dimensions.set(width,height);
151 + ilBindImage(0);
152 + }
67 153
68 - ilGenImages(1, &ilTexture);
69 - ilBindImage(ilTexture);
154 + I8 SaveToTGA(char *filename, const vec2<U16>& dimensions, U8 pixelDepth, U8 *imageData) {
155 +
156 + U8 cGarbage = 0, type,mode,aux;
157 + I16 iGarbage = 0;
158 + U16 width = dimensions.width;
159 + U16 height = dimensions.height;
160 +
161 + // open file and check for errors
162 + FILE *file = fopen(filename, "wb");
163 + if (file == NULL) {
164 + return(-1);
165 + }
166 +
167 + // compute image type: 2 for RGB(A), 3 for greyscale
168 + mode = pixelDepth / 8;
169 + type = ((pixelDepth == 24) || (pixelDepth == 32)) ? 2 : 3;
170 +
171 + // write the header
172 + fwrite(&cGarbage, sizeof(U8), 1, file);
173 + fwrite(&cGarbage, sizeof(U8), 1, file);
174 + fwrite(&type, sizeof(U8), 1, file);
175 +
176 + fwrite(&iGarbage, sizeof(I16), 1, file);
177 + fwrite(&iGarbage, sizeof(I16), 1, file);
178 + fwrite(&cGarbage, sizeof(U8), 1, file);
179 + fwrite(&iGarbage, sizeof(I16), 1, file);
180 + fwrite(&iGarbage, sizeof(I16), 1, file);
181 +
182 + fwrite(&width, sizeof(U16), 1, file);
183 + fwrite(&height, sizeof(U16), 1, file);
184 + fwrite(&pixelDepth, sizeof(U8), 1, file);
185 + fwrite(&cGarbage, sizeof(U8), 1, file);
186 +
187 + // convert the image data from RGB(a) to BGR(A)
188 + if (mode >= 3)
189 + for (I32 i=0; i < width * height * mode ; i+= mode) {
190 + aux = imageData[i];
191 + imageData[i] = imageData[i+2];
192 + imageData[i+2] = aux;
193 + }
70 194
71 - if (!ilLoadImage(filename.c_str())) return false;
195 + // save the image data
196 + fwrite(imageData, sizeof(U8), width * height * mode, file);
197 + fclose(file);
198 + /// release the memory
199 + SAFE_DELETE(imageData);
200 + return 0;
201 + }
202 +
203 + /// saves a series of files with names "filenameX.tga"
204 + I8 SaveSeries(char *filename, const vec2<U16>& dimensions, U8 pixelDepth, U8 *imageData) {
205 +
206 + static I8 savedImages=0;
207 + char *newFilename;
208 + // compute the new filename by adding the
209 + // series number and the extension
210 + newFilename = new char[strlen(filename)+8];
211 +
212 + sprintf_s(newFilename,strlen(filename)+8,"%s%d.tga",filename,savedImages);
213 +
214 + // save the image
215 + I8 status = SaveToTGA(newFilename,dimensions,pixelDepth,imageData);
216 +
217 + //increase the counter
218 + if (status == 0) savedImages++;
219 + SAFE_DELETE_ARRAY(newFilename);
220 +
221 + return status;
222 + }
72 223
73 - w = ilGetInteger(IL_IMAGE_WIDTH);
74 - h = ilGetInteger(IL_IMAGE_HEIGHT);
75 - d = ilGetInteger(IL_IMAGE_BPP);
76 - t = ilGetInteger(IL_IMAGE_TYPE);
77 - I32 format = ilGetInteger(IL_IMAGE_FORMAT);
78 -
79 - switch(format) {
80 - case IL_COLOR_INDEX:
81 - switch(ilGetInteger(IL_PALETTE_TYPE)) {
82 - case IL_PAL_NONE:
83 - ilDeleteImages(1, &ilTexture);
84 - break;
85 -
86 - case IL_PAL_BGRA32:
87 - ilConvertPal(IL_PAL_RGBA32);
88 -
89 - case IL_PAL_RGBA32:
90 - alpha = true;
91 - break;
92 -
93 - case IL_PAL_BGR24:
94 - case IL_PAL_RGB32:
95 - case IL_PAL_BGR32:
96 - ilConvertPal(IL_PAL_RGB24);
97 -
98 - case IL_PAL_RGB24:
99 - alpha = false;
100 - break;
101 - }
102 - break;
103 -
104 - case IL_LUMINANCE:
105 - case IL_BGR:
106 - case IL_RGB:
107 - if(format != IL_RGB || ilGetInteger(IL_IMAGE_TYPE) != IL_UNSIGNED_BYTE)
108 - ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
109 - alpha = false;
110 - break;
111 -
112 - case IL_LUMINANCE_ALPHA:
113 - case IL_BGRA:
114 - case IL_RGBA:
115 - if(format != IL_RGBA || ilGetInteger(IL_IMAGE_TYPE) != IL_UNSIGNED_BYTE)
116 - ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
117 - alpha = true;
118 - break;
119 - }
120 -
121 - const U8* Pixels = ilGetData();
122 -
123 - U8* img = New U8[(size_t)(w) * (size_t)(h) * (size_t)(d)];
124 - memcpy(img, Pixels, (size_t)(w) * (size_t)(h) * (size_t)(d));
125 -
126 - ilBindImage(0);
127 - ilDeleteImages(1, &ilTexture);
128 -
129 - return img;
130 - }
131 -
132 - U8* OpenImage(const std::string& filename, U16& w, U16& h, U8& d, U32& t,U32& ilTexture,bool& alpha,const bool flip) {
133 - if(filename.find(".ppm") != std::string::npos){
134 - alpha = false;
135 - return OpenImagePPM(filename, w, h, d,t,ilTexture,flip);
136 - }
137 -
138 - return OpenImageDevIL(filename,w,h,d,t,ilTexture,alpha,flip);
139 - }
140 -
141 - void OpenImage(const std::string& filename, ImageData& img, bool& alpha){
142 - img.name = filename;
143 - img.data = OpenImage(filename, img.w, img.h, img.d, img.type,img.ilTexture,alpha,img._flip);
144 - }
145 -
146 - void ImageData::Destroy(){
147 - SAFE_DELETE_ARRAY(data);
148 - }
149 -
150 - vec3<I32> ImageData::getColor(U16 x, U16 y) const {
151 - I32 idx = (y * w + x) * d;
152 - return vec3<I32>( data[idx+0], data[idx+1], data[idx+2]);
153 - }
154 -
155 - void ImageData::resize(U16 width, U16 height){
156 - ilBindImage(ilTexture);
157 - iluImageParameter(ILU_FILTER,ILU_SCALE_BELL);
158 - iluScale(width,height,d);
159 - ilBindImage(0);
160 - }
161 -
162 - I8 saveToTGA(char *filename,
163 - U16 width,
164 - U16 height,
165 - U8 pixelDepth,
166 - U8 *imageData) {
167 - U8 cGarbage = 0, type,mode,aux;
168 - I16 iGarbage = 0;
169 - I32 i;
170 - FILE *file;
171 -
172 - // open file and check for errors
173 - file = fopen(filename, "wb");
174 - if (file == NULL) {
175 - return(-1);
176 - }
177 -
178 - // compute image type: 2 for RGB(A), 3 for greyscale
179 - mode = pixelDepth / 8;
180 - if ((pixelDepth == 24) || (pixelDepth == 32))
181 - type = 2;
182 - else
183 - type = 3;
184 -
185 - // write the header
186 - fwrite(&cGarbage, sizeof(U8), 1, file);
187 - fwrite(&cGarbage, sizeof(U8), 1, file);
188 -
189 - fwrite(&type, sizeof(U8), 1, file);
190 -
191 - fwrite(&iGarbage, sizeof(I16), 1, file);
192 - fwrite(&iGarbage, sizeof(I16), 1, file);
193 - fwrite(&cGarbage, sizeof(U8), 1, file);
194 - fwrite(&iGarbage, sizeof(I16), 1, file);
195 - fwrite(&iGarbage, sizeof(I16), 1, file);
196 -
197 - fwrite(&width, sizeof(I16), 1, file);
198 - fwrite(&height, sizeof(I16), 1, file);
199 - fwrite(&pixelDepth, sizeof(U8), 1, file);
200 -
201 - fwrite(&cGarbage, sizeof(U8), 1, file);
202 -
203 - // convert the image data from RGB(a) to BGR(A)
204 - if (mode >= 3)
205 - for (i=0; i < width * height * mode ; i+= mode) {
206 - aux = imageData[i];
207 - imageData[i] = imageData[i+2];
208 - imageData[i+2] = aux;
209 - }
210 -
211 - // save the image data
212 - fwrite(imageData, sizeof(U8),
213 - width * height * mode, file);
214 - fclose(file);
215 - /// release the memory
216 - SAFE_DELETE(imageData);
217 - return(0);
218 - }
219 -
220 - /// saves a series of files with names "filenameX.tga"
221 - I8 SaveSeries(char *filename,
222 - U16 width,
223 - U16 height,
224 - U8 pixelDepth,
225 - U8 *imageData) {
226 - static I8 savedImages=0;
227 - char *newFilename;
228 - I8 status;
229 -
230 - // compute the new filename by adding the
231 - // series number and the extension
232 - newFilename = new char[strlen(filename)+8];
233 -
234 - sprintf_s(newFilename,strlen(filename)+8,"%s%d.tga",filename,savedImages);
235 -
236 - // save the image
237 - status = saveToTGA(newFilename,width,height,pixelDepth,imageData);
238 -
239 - //increase the counter
240 - if (status == 0)
241 - savedImages++;
242 - SAFE_DELETE_ARRAY(newFilename);
243 - return(status);
244 - }
245 - }
224 + } ///namespace ImageTools