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 * Contributor(s): Matt Ebb, Campbell Barton, Shuvro Sarker 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00028 #include <math.h> 00029 #include <stdlib.h> 00030 00031 #include "BKE_image.h" 00032 #include "BLI_math_color.h" 00033 #include "BLI_math_base.h" 00034 #include "BLF_api.h" 00035 00036 void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, float color[4]) 00037 { 00038 int x, y; 00039 00040 /* blank image */ 00041 if(rect_float) { 00042 for(y= 0; y<height; y++) { 00043 for(x= 0; x<width; x++) { 00044 rect_float[0]= color[0]; 00045 rect_float[1]= color[1]; 00046 rect_float[2]= color[2]; 00047 rect_float[3]= color[3]; 00048 rect_float+= 4; 00049 } 00050 } 00051 } 00052 00053 if(rect) { 00054 char ccol[4]; 00055 00056 ccol[0]= (char)(color[0]*255.0f); 00057 ccol[1]= (char)(color[1]*255.0f); 00058 ccol[2]= (char)(color[2]*255.0f); 00059 ccol[3]= (char)(color[3]*255.0f); 00060 for(y= 0; y<height; y++) { 00061 for(x= 0; x<width; x++) { 00062 00063 rect[0]= ccol[0]; 00064 rect[1]= ccol[1]; 00065 rect[2]= ccol[2]; 00066 rect[3]= ccol[3]; 00067 rect+= 4; 00068 } 00069 } 00070 } 00071 } 00072 00073 00074 void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int width, int height) 00075 { 00076 /* these two passes could be combined into one, but it's more readable and 00077 * easy to tweak like this, speed isn't really that much of an issue in this situation... */ 00078 00079 int checkerwidth= 32, dark= 1; 00080 int x, y; 00081 00082 unsigned char *rect_orig= rect; 00083 float *rect_float_orig= rect_float; 00084 00085 00086 float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b; 00087 00088 /* checkers */ 00089 for(y= 0; y<height; y++) { 00090 dark= powf(-1.0f, floorf(y / checkerwidth)); 00091 00092 for(x= 0; x<width; x++) { 00093 if (x % checkerwidth == 0) dark= -dark; 00094 00095 if (rect_float) { 00096 if (dark > 0) { 00097 rect_float[0]= rect_float[1]= rect_float[2]= 0.25f; 00098 rect_float[3]= 1.0f; 00099 } else { 00100 rect_float[0]= rect_float[1]= rect_float[2]= 0.58f; 00101 rect_float[3]= 1.0f; 00102 } 00103 rect_float+= 4; 00104 } 00105 else { 00106 if (dark > 0) { 00107 rect[0]= rect[1]= rect[2]= 64; 00108 rect[3]= 255; 00109 } else { 00110 rect[0]= rect[1]= rect[2]= 150; 00111 rect[3]= 255; 00112 } 00113 rect+= 4; 00114 } 00115 } 00116 } 00117 00118 rect= rect_orig; 00119 rect_float= rect_float_orig; 00120 00121 /* 2nd pass, colored + */ 00122 for(y= 0; y<height; y++) { 00123 hoffs= 0.125f * floorf(y / checkerwidth); 00124 00125 for(x= 0; x<width; x++) { 00126 h= 0.125f * floorf(x / checkerwidth); 00127 00128 if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) && 00129 (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4)) { 00130 00131 if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) || 00132 (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1)) { 00133 00134 hue= fmodf(fabs(h-hoffs), 1.0f); 00135 hsv_to_rgb(hue, s, v, &r, &g, &b); 00136 00137 if (rect) { 00138 rect[0]= (char)(r * 255.0f); 00139 rect[1]= (char)(g * 255.0f); 00140 rect[2]= (char)(b * 255.0f); 00141 rect[3]= 255; 00142 } 00143 00144 if (rect_float) { 00145 rect_float[0]= r; 00146 rect_float[1]= g; 00147 rect_float[2]= b; 00148 rect_float[3]= 1.0f; 00149 } 00150 } 00151 } 00152 00153 if (rect_float) rect_float+= 4; 00154 if (rect) rect+= 4; 00155 } 00156 } 00157 } 00158 00159 00160 /* Utility functions for BKE_image_buf_fill_checker_color */ 00161 00162 #define BLEND_FLOAT(real, add) (real+add <= 1.0f) ? (real+add) : 1.0f 00163 #define BLEND_CHAR(real, add) ((real + (char)(add * 255.0f)) <= 255) ? (real + (char)(add * 255.0f)) : 255 00164 00165 static void checker_board_color_fill(unsigned char *rect, float *rect_float, int width, int height) 00166 { 00167 int hue_step, y, x; 00168 float hue, val, sat, r, g, b; 00169 00170 sat= 1.0; 00171 00172 hue_step= power_of_2_max_i(width / 8); 00173 if(hue_step < 8) hue_step= 8; 00174 00175 for(y= 0; y < height; y++) 00176 { 00177 00178 val= 0.1 + (y * (0.4 / height)); /* use a number lower then 1.0 else its too bright */ 00179 for(x= 0; x < width; x++) 00180 { 00181 hue= (float)((double)(x/hue_step) * 1.0 / width * hue_step); 00182 hsv_to_rgb(hue, sat, val, &r, &g, &b); 00183 00184 if (rect) { 00185 rect[0]= (char)(r * 255.0f); 00186 rect[1]= (char)(g * 255.0f); 00187 rect[2]= (char)(b * 255.0f); 00188 rect[3]= 255; 00189 00190 rect += 4; 00191 } 00192 00193 if (rect_float) { 00194 rect_float[0]= r; 00195 rect_float[1]= g; 00196 rect_float[2]= b; 00197 rect_float[3]= 1.0f; 00198 00199 rect_float += 4; 00200 } 00201 } 00202 } 00203 } 00204 00205 static void checker_board_color_tint(unsigned char *rect, float *rect_float, int width, int height, int size, float blend) 00206 { 00207 int x, y; 00208 float blend_half= blend * 0.5f; 00209 00210 for(y= 0; y < height; y++) 00211 { 00212 for(x= 0; x < width; x++) 00213 { 00214 if( ( (y/size)%2 == 1 && (x/size)%2 == 1 ) || ( (y/size)%2 == 0 && (x/size)%2 == 0 ) ) 00215 { 00216 if (rect) { 00217 rect[0]= (char)BLEND_CHAR(rect[0], blend); 00218 rect[1]= (char)BLEND_CHAR(rect[1], blend); 00219 rect[2]= (char)BLEND_CHAR(rect[2], blend); 00220 rect[3]= 255; 00221 00222 rect += 4; 00223 } 00224 if (rect_float) { 00225 rect_float[0]= BLEND_FLOAT(rect_float[0], blend); 00226 rect_float[1]= BLEND_FLOAT(rect_float[1], blend); 00227 rect_float[2]= BLEND_FLOAT(rect_float[2], blend); 00228 rect_float[3]= 1.0f; 00229 00230 rect_float += 4; 00231 } 00232 } 00233 else { 00234 if (rect) { 00235 rect[0]= (char)BLEND_CHAR(rect[0], blend_half); 00236 rect[1]= (char)BLEND_CHAR(rect[1], blend_half); 00237 rect[2]= (char)BLEND_CHAR(rect[2], blend_half); 00238 rect[3]= 255; 00239 00240 rect += 4; 00241 } 00242 if (rect_float) { 00243 rect_float[0]= BLEND_FLOAT(rect_float[0], blend_half); 00244 rect_float[1]= BLEND_FLOAT(rect_float[1], blend_half); 00245 rect_float[2]= BLEND_FLOAT(rect_float[2], blend_half); 00246 rect_float[3]= 1.0f; 00247 00248 rect_float += 4; 00249 } 00250 } 00251 00252 } 00253 } 00254 } 00255 00256 static void checker_board_grid_fill(unsigned char *rect, float *rect_float, int width, int height, float blend) 00257 { 00258 int x, y; 00259 for(y= 0; y < height; y++) 00260 { 00261 for(x= 0; x < width; x++) 00262 { 00263 if( ((y % 32) == 0) || ((x % 32) == 0) || x == 0 ) 00264 { 00265 if (rect) { 00266 rect[0]= BLEND_CHAR(rect[0], blend); 00267 rect[1]= BLEND_CHAR(rect[1], blend); 00268 rect[2]= BLEND_CHAR(rect[2], blend); 00269 rect[3]= 255; 00270 00271 rect += 4; 00272 } 00273 if (rect_float) { 00274 rect_float[0]= BLEND_FLOAT(rect_float[0], blend); 00275 rect_float[1]= BLEND_FLOAT(rect_float[1], blend); 00276 rect_float[2]= BLEND_FLOAT(rect_float[2], blend); 00277 rect_float[3]= 1.0f; 00278 00279 rect_float += 4; 00280 } 00281 } 00282 else { 00283 if(rect_float) rect_float += 4; 00284 if(rect) rect += 4; 00285 } 00286 } 00287 } 00288 } 00289 00290 /* defined in image.c */ 00291 00292 static void checker_board_text(unsigned char *rect, float *rect_float, int width, int height, int step, int outline) 00293 { 00294 int x, y; 00295 int pen_x, pen_y; 00296 char text[3]= {'A', '1', '\0'}; 00297 const int mono= blf_mono_font; 00298 00299 BLF_size(mono, 54, 72); /* hard coded size! */ 00300 00301 BLF_buffer(mono, rect_float, rect, width, height, 4); 00302 00303 for(y= 0; y < height; y+=step) 00304 { 00305 text[1]= '1'; 00306 00307 for(x= 0; x < width; x+=step) 00308 { 00309 /* hard coded offset */ 00310 pen_x = x + 33; 00311 pen_y = y + 44; 00312 00313 /* terribly crappy outline font! */ 00314 BLF_buffer_col(mono, 1.0, 1.0, 1.0, 1.0); 00315 00316 BLF_position(mono, pen_x-outline, pen_y, 0.0); 00317 BLF_draw_buffer(mono, text); 00318 BLF_position(mono, pen_x+outline, pen_y, 0.0); 00319 BLF_draw_buffer(mono, text); 00320 BLF_position(mono, pen_x, pen_y-outline, 0.0); 00321 BLF_draw_buffer(mono, text); 00322 BLF_position(mono, pen_x, pen_y+outline, 0.0); 00323 BLF_draw_buffer(mono, text); 00324 00325 BLF_position(mono, pen_x-outline, pen_y-outline, 0.0); 00326 BLF_draw_buffer(mono, text); 00327 BLF_position(mono, pen_x+outline, pen_y+outline, 0.0); 00328 BLF_draw_buffer(mono, text); 00329 BLF_position(mono, pen_x-outline, pen_y+outline, 0.0); 00330 BLF_draw_buffer(mono, text); 00331 BLF_position(mono, pen_x+outline, pen_y-outline, 0.0); 00332 BLF_draw_buffer(mono, text); 00333 00334 BLF_buffer_col(mono, 0.0, 0.0, 0.0, 1.0); 00335 BLF_position(mono, pen_x, pen_y, 0.0); 00336 BLF_draw_buffer(mono, text); 00337 00338 text[1]++; 00339 } 00340 text[0]++; 00341 } 00342 00343 /* cleanup the buffer. */ 00344 BLF_buffer(mono, NULL, NULL, 0, 0, 0); 00345 } 00346 00347 void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int width, int height) 00348 { 00349 checker_board_color_fill(rect, rect_float, width, height); 00350 checker_board_color_tint(rect, rect_float, width, height, 1, 0.03f); 00351 checker_board_color_tint(rect, rect_float, width, height, 4, 0.05f); 00352 checker_board_color_tint(rect, rect_float, width, height, 32, 0.07f); 00353 checker_board_color_tint(rect, rect_float, width, height, 128, 0.15f); 00354 checker_board_grid_fill(rect, rect_float, width, height, 1.0f/4.0f); 00355 00356 checker_board_text(rect, rect_float, width, height, 128, 2); 00357 }