|
Blender
V2.59
|
00001 /* image_gen.c 00002 * 00003 * $Id: image_gen.c 36271 2011-04-21 13:11:51Z campbellbarton $ 00004 * 00005 * ***** BEGIN GPL LICENSE BLOCK ***** 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License 00009 * as published by the Free Software Foundation; either version 2 00010 * of the License, or (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software Foundation, 00019 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00020 * 00021 * Contributor(s): Matt Ebb, Campbell Barton, Shuvro Sarker 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include <math.h> 00032 #include <stdlib.h> 00033 00034 #include "BKE_image.h" 00035 #include "BLI_math_color.h" 00036 #include "BLF_api.h" 00037 00038 void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, float color[4]) 00039 { 00040 int x, y; 00041 00042 /* blank image */ 00043 if(rect_float) { 00044 for(y= 0; y<height; y++) { 00045 for(x= 0; x<width; x++) { 00046 rect_float[0]= color[0]; 00047 rect_float[1]= color[1]; 00048 rect_float[2]= color[2]; 00049 rect_float[3]= color[3]; 00050 rect_float+= 4; 00051 } 00052 } 00053 } 00054 00055 if(rect) { 00056 char ccol[4]; 00057 00058 ccol[0]= (char)(color[0]*255.0f); 00059 ccol[1]= (char)(color[1]*255.0f); 00060 ccol[2]= (char)(color[2]*255.0f); 00061 ccol[3]= (char)(color[3]*255.0f); 00062 for(y= 0; y<height; y++) { 00063 for(x= 0; x<width; x++) { 00064 00065 rect[0]= ccol[0]; 00066 rect[1]= ccol[1]; 00067 rect[2]= ccol[2]; 00068 rect[3]= ccol[3]; 00069 rect+= 4; 00070 } 00071 } 00072 } 00073 } 00074 00075 00076 void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int width, int height) 00077 { 00078 /* these two passes could be combined into one, but it's more readable and 00079 * easy to tweak like this, speed isn't really that much of an issue in this situation... */ 00080 00081 int checkerwidth= 32, dark= 1; 00082 int x, y; 00083 00084 unsigned char *rect_orig= rect; 00085 float *rect_float_orig= rect_float; 00086 00087 00088 float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b; 00089 00090 /* checkers */ 00091 for(y= 0; y<height; y++) { 00092 dark= powf(-1.0f, floorf(y / checkerwidth)); 00093 00094 for(x= 0; x<width; x++) { 00095 if (x % checkerwidth == 0) dark= -dark; 00096 00097 if (rect_float) { 00098 if (dark > 0) { 00099 rect_float[0]= rect_float[1]= rect_float[2]= 0.25f; 00100 rect_float[3]= 1.0f; 00101 } else { 00102 rect_float[0]= rect_float[1]= rect_float[2]= 0.58f; 00103 rect_float[3]= 1.0f; 00104 } 00105 rect_float+= 4; 00106 } 00107 else { 00108 if (dark > 0) { 00109 rect[0]= rect[1]= rect[2]= 64; 00110 rect[3]= 255; 00111 } else { 00112 rect[0]= rect[1]= rect[2]= 150; 00113 rect[3]= 255; 00114 } 00115 rect+= 4; 00116 } 00117 } 00118 } 00119 00120 rect= rect_orig; 00121 rect_float= rect_float_orig; 00122 00123 /* 2nd pass, colored + */ 00124 for(y= 0; y<height; y++) { 00125 hoffs= 0.125f * floorf(y / checkerwidth); 00126 00127 for(x= 0; x<width; x++) { 00128 h= 0.125f * floorf(x / checkerwidth); 00129 00130 if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) && 00131 (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4)) { 00132 00133 if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) || 00134 (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1)) { 00135 00136 hue= fmodf(fabs(h-hoffs), 1.0f); 00137 hsv_to_rgb(hue, s, v, &r, &g, &b); 00138 00139 if (rect) { 00140 rect[0]= (char)(r * 255.0f); 00141 rect[1]= (char)(g * 255.0f); 00142 rect[2]= (char)(b * 255.0f); 00143 rect[3]= 255; 00144 } 00145 00146 if (rect_float) { 00147 rect_float[0]= r; 00148 rect_float[1]= g; 00149 rect_float[2]= b; 00150 rect_float[3]= 1.0f; 00151 } 00152 } 00153 } 00154 00155 if (rect_float) rect_float+= 4; 00156 if (rect) rect+= 4; 00157 } 00158 } 00159 } 00160 00161 00162 /* Utility functions for BKE_image_buf_fill_checker_color */ 00163 00164 #define BLEND_FLOAT(real, add) (real+add <= 1.0f) ? (real+add) : 1.0f 00165 #define BLEND_CHAR(real, add) ((real + (char)(add * 255.0f)) <= 255) ? (real + (char)(add * 255.0f)) : 255 00166 00167 static int is_pow2(int n) 00168 { 00169 return ((n)&(n-1))==0; 00170 } 00171 static int larger_pow2(int n) 00172 { 00173 if (is_pow2(n)) 00174 return n; 00175 00176 while(!is_pow2(n)) 00177 n= n&(n-1); 00178 00179 return n*2; 00180 } 00181 00182 static void checker_board_color_fill(unsigned char *rect, float *rect_float, int width, int height) 00183 { 00184 int hue_step, y, x; 00185 float hue, val, sat, r, g, b; 00186 00187 sat= 1.0; 00188 00189 hue_step= larger_pow2(width / 8); 00190 if(hue_step < 8) hue_step= 8; 00191 00192 for(y= 0; y < height; y++) 00193 { 00194 00195 val= 0.1 + (y * (0.4 / height)); /* use a number lower then 1.0 else its too bright */ 00196 for(x= 0; x < width; x++) 00197 { 00198 hue= (float)((double)(x/hue_step) * 1.0 / width * hue_step); 00199 hsv_to_rgb(hue, sat, val, &r, &g, &b); 00200 00201 if (rect) { 00202 rect[0]= (char)(r * 255.0f); 00203 rect[1]= (char)(g * 255.0f); 00204 rect[2]= (char)(b * 255.0f); 00205 rect[3]= 255; 00206 00207 rect += 4; 00208 } 00209 00210 if (rect_float) { 00211 rect_float[0]= r; 00212 rect_float[1]= g; 00213 rect_float[2]= b; 00214 rect_float[3]= 1.0f; 00215 00216 rect_float += 4; 00217 } 00218 } 00219 } 00220 } 00221 00222 static void checker_board_color_tint(unsigned char *rect, float *rect_float, int width, int height, int size, float blend) 00223 { 00224 int x, y; 00225 float blend_half= blend * 0.5f; 00226 00227 for(y= 0; y < height; y++) 00228 { 00229 for(x= 0; x < width; x++) 00230 { 00231 if( ( (y/size)%2 == 1 && (x/size)%2 == 1 ) || ( (y/size)%2 == 0 && (x/size)%2 == 0 ) ) 00232 { 00233 if (rect) { 00234 rect[0]= (char)BLEND_CHAR(rect[0], blend); 00235 rect[1]= (char)BLEND_CHAR(rect[1], blend); 00236 rect[2]= (char)BLEND_CHAR(rect[2], blend); 00237 rect[3]= 255; 00238 00239 rect += 4; 00240 } 00241 if (rect_float) { 00242 rect_float[0]= BLEND_FLOAT(rect_float[0], blend); 00243 rect_float[1]= BLEND_FLOAT(rect_float[1], blend); 00244 rect_float[2]= BLEND_FLOAT(rect_float[2], blend); 00245 rect_float[3]= 1.0f; 00246 00247 rect_float += 4; 00248 } 00249 } 00250 else { 00251 if (rect) { 00252 rect[0]= (char)BLEND_CHAR(rect[0], blend_half); 00253 rect[1]= (char)BLEND_CHAR(rect[1], blend_half); 00254 rect[2]= (char)BLEND_CHAR(rect[2], blend_half); 00255 rect[3]= 255; 00256 00257 rect += 4; 00258 } 00259 if (rect_float) { 00260 rect_float[0]= BLEND_FLOAT(rect_float[0], blend_half); 00261 rect_float[1]= BLEND_FLOAT(rect_float[1], blend_half); 00262 rect_float[2]= BLEND_FLOAT(rect_float[2], blend_half); 00263 rect_float[3]= 1.0f; 00264 00265 rect_float += 4; 00266 } 00267 } 00268 00269 } 00270 } 00271 } 00272 00273 static void checker_board_grid_fill(unsigned char *rect, float *rect_float, int width, int height, float blend) 00274 { 00275 int x, y; 00276 for(y= 0; y < height; y++) 00277 { 00278 for(x= 0; x < width; x++) 00279 { 00280 if( ((y % 32) == 0) || ((x % 32) == 0) || x == 0 ) 00281 { 00282 if (rect) { 00283 rect[0]= BLEND_CHAR(rect[0], blend); 00284 rect[1]= BLEND_CHAR(rect[1], blend); 00285 rect[2]= BLEND_CHAR(rect[2], blend); 00286 rect[3]= 255; 00287 00288 rect += 4; 00289 } 00290 if (rect_float) { 00291 rect_float[0]= BLEND_FLOAT(rect_float[0], blend); 00292 rect_float[1]= BLEND_FLOAT(rect_float[1], blend); 00293 rect_float[2]= BLEND_FLOAT(rect_float[2], blend); 00294 rect_float[3]= 1.0f; 00295 00296 rect_float += 4; 00297 } 00298 } 00299 else { 00300 if(rect_float) rect_float += 4; 00301 if(rect) rect += 4; 00302 } 00303 } 00304 } 00305 } 00306 00307 /* defined in image.c */ 00308 00309 static void checker_board_text(unsigned char *rect, float *rect_float, int width, int height, int step, int outline) 00310 { 00311 int x, y; 00312 int pen_x, pen_y; 00313 char text[3]= {'A', '1', '\0'}; 00314 const int mono= blf_mono_font; 00315 00316 BLF_size(mono, 54, 72); /* hard coded size! */ 00317 00318 BLF_buffer(mono, rect_float, rect, width, height, 4); 00319 00320 for(y= 0; y < height; y+=step) 00321 { 00322 text[1]= '1'; 00323 00324 for(x= 0; x < width; x+=step) 00325 { 00326 /* hard coded offset */ 00327 pen_x = x + 33; 00328 pen_y = y + 44; 00329 00330 /* terribly crappy outline font! */ 00331 BLF_buffer_col(mono, 1.0, 1.0, 1.0, 1.0); 00332 00333 BLF_position(mono, pen_x-outline, pen_y, 0.0); 00334 BLF_draw_buffer(mono, text); 00335 BLF_position(mono, pen_x+outline, pen_y, 0.0); 00336 BLF_draw_buffer(mono, text); 00337 BLF_position(mono, pen_x, pen_y-outline, 0.0); 00338 BLF_draw_buffer(mono, text); 00339 BLF_position(mono, pen_x, pen_y+outline, 0.0); 00340 BLF_draw_buffer(mono, text); 00341 00342 BLF_position(mono, pen_x-outline, pen_y-outline, 0.0); 00343 BLF_draw_buffer(mono, text); 00344 BLF_position(mono, pen_x+outline, pen_y+outline, 0.0); 00345 BLF_draw_buffer(mono, text); 00346 BLF_position(mono, pen_x-outline, pen_y+outline, 0.0); 00347 BLF_draw_buffer(mono, text); 00348 BLF_position(mono, pen_x+outline, pen_y-outline, 0.0); 00349 BLF_draw_buffer(mono, text); 00350 00351 BLF_buffer_col(mono, 0.0, 0.0, 0.0, 1.0); 00352 BLF_position(mono, pen_x, pen_y, 0.0); 00353 BLF_draw_buffer(mono, text); 00354 00355 text[1]++; 00356 } 00357 text[0]++; 00358 } 00359 00360 /* cleanup the buffer. */ 00361 BLF_buffer(mono, NULL, NULL, 0, 0, 0); 00362 } 00363 00364 void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int width, int height) 00365 { 00366 checker_board_color_fill(rect, rect_float, width, height); 00367 checker_board_color_tint(rect, rect_float, width, height, 1, 0.03f); 00368 checker_board_color_tint(rect, rect_float, width, height, 4, 0.05f); 00369 checker_board_color_tint(rect, rect_float, width, height, 32, 0.07f); 00370 checker_board_color_tint(rect, rect_float, width, height, 128, 0.15f); 00371 checker_board_grid_fill(rect, rect_float, width, height, 1.0f/4.0f); 00372 00373 checker_board_text(rect, rect_float, width, height, 128, 2); 00374 }