|
Blender
V2.59
|
00001 /* 00002 * $Id: CMP_levels.c 36276 2011-04-21 15:53:30Z campbellbarton $ 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 * The Original Code is Copyright (C) 2006 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): Bob Holcomb. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include "../CMP_util.h" 00036 00037 00038 /* **************** LEVELS ******************** */ 00039 static bNodeSocketType cmp_node_view_levels_in[]= { 00040 { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 00041 { -1, 0, "" } 00042 }; 00043 00044 static bNodeSocketType cmp_node_view_levels_out[]={ 00045 {SOCK_VALUE, 0,"Mean",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 00046 {SOCK_VALUE, 0,"Std Dev",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 00047 {-1,0,""} 00048 }; 00049 00050 static void rgb_tobw(float r, float g, float b, float* out) 00051 { 00052 *out= r*0.35f + g*0.45f + b*0.2f; 00053 } 00054 00055 static void fill_bins(bNode* node, CompBuf* in, int* bins, int colorcor) 00056 { 00057 float value[4]; 00058 int ivalue=0; 00059 int x,y; 00060 00061 /*fill bins */ 00062 for(y=0; y<in->y; y++) { 00063 for(x=0; x<in->x; x++) { 00064 00065 /* get the pixel */ 00066 qd_getPixel(in, x, y, value); 00067 00068 if(value[3] > 0.0) { /* don't count transparent pixels */ 00069 switch(node->custom1) { 00070 case 1: { /* all colors */ 00071 if(colorcor) 00072 linearrgb_to_srgb_v3_v3(&value[0],&value[0]); 00073 rgb_tobw(value[0],value[1],value[2], &value[0]); 00074 value[0]=value[0]*255; /* scale to 0-255 range */ 00075 ivalue=(int)value[0]; 00076 break; 00077 } 00078 case 2: { /* red channel */ 00079 if(colorcor) 00080 value[0]=linearrgb_to_srgb(value[0]); 00081 value[0]=value[0]*255; /* scale to 0-255 range */ 00082 ivalue=(int)value[0]; 00083 break; 00084 } 00085 case 3: { /* green channel */ 00086 if(colorcor) 00087 value[1]=linearrgb_to_srgb(value[1]); 00088 value[1]=value[1]*255; /* scale to 0-255 range */ 00089 ivalue=(int)value[1]; 00090 break; 00091 } 00092 case 4: /*blue channel */ 00093 { 00094 if(colorcor) 00095 value[2]=linearrgb_to_srgb(value[2]); 00096 value[2]=value[2]*255; /* scale to 0-255 range */ 00097 ivalue=(int)value[2]; 00098 break; 00099 } 00100 case 5: /* luminence */ 00101 { 00102 if(colorcor) 00103 linearrgb_to_srgb_v3_v3(&value[0],&value[0]); 00104 rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]); 00105 value[0]=value[0]*255; /* scale to 0-255 range */ 00106 ivalue=(int)value[0]; 00107 break; 00108 } 00109 } /*end switch */ 00110 00111 /*clip*/ 00112 if(ivalue<0) ivalue=0; 00113 if(ivalue>255) ivalue=255; 00114 00115 /*put in the correct bin*/ 00116 bins[ivalue]+=1; 00117 } /*end if alpha */ 00118 } 00119 } 00120 } 00121 00122 static float brightness_mean(bNode* node, CompBuf* in) 00123 { 00124 float sum=0.0; 00125 int numPixels=0.0; 00126 int x,y; 00127 float value[4]; 00128 00129 for(x=0; x< in->x; x++) { 00130 for(y=0; y < in->y; y++) { 00131 00132 /* get the pixel */ 00133 qd_getPixel(in, x, y, value); 00134 00135 if(value[3] > 0.0) { /* don't count transparent pixels */ 00136 numPixels++; 00137 switch(node->custom1) 00138 { 00139 case 1: 00140 { 00141 rgb_tobw(value[0],value[1],value[2], &value[0]); 00142 sum+=value[0]; 00143 break; 00144 } 00145 case 2: 00146 { 00147 sum+=value[0]; 00148 break; 00149 } 00150 case 3: 00151 { 00152 sum+=value[1]; 00153 break; 00154 } 00155 case 4: 00156 { 00157 sum+=value[2]; 00158 break; 00159 } 00160 case 5: 00161 { 00162 rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]); 00163 sum+=value[0]; 00164 break; 00165 } 00166 } 00167 } 00168 } 00169 } 00170 00171 return sum/numPixels; 00172 } 00173 00174 static float brightness_standard_deviation(bNode* node, CompBuf* in, float mean) 00175 { 00176 float sum=0.0; 00177 int numPixels=0.0; 00178 int x,y; 00179 float value[4]; 00180 00181 for(x=0; x< in->x; x++) { 00182 for(y=0; y < in->y; y++) { 00183 00184 /* get the pixel */ 00185 qd_getPixel(in, x, y, value); 00186 00187 if(value[3] > 0.0) { /* don't count transparent pixels */ 00188 numPixels++; 00189 switch(node->custom1) 00190 { 00191 case 1: 00192 { 00193 rgb_tobw(value[0],value[1],value[2], &value[0]); 00194 sum+=(value[0]-mean)*(value[0]-mean); 00195 break; 00196 } 00197 case 2: 00198 { 00199 sum+=value[0]; 00200 sum+=(value[0]-mean)*(value[0]-mean); 00201 break; 00202 } 00203 case 3: 00204 { 00205 sum+=value[1]; 00206 sum+=(value[1]-mean)*(value[1]-mean); 00207 break; 00208 } 00209 case 4: 00210 { 00211 sum+=value[2]; 00212 sum+=(value[2]-mean)*(value[2]-mean); 00213 break; 00214 } 00215 case 5: 00216 { 00217 rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]); 00218 sum+=(value[0]-mean)*(value[0]-mean); 00219 break; 00220 } 00221 } 00222 } 00223 } 00224 } 00225 00226 00227 return sqrt(sum/(float)(numPixels-1)); 00228 } 00229 00230 static void draw_histogram(bNode *node, CompBuf *out, int* bins) 00231 { 00232 int x,y; 00233 float color[4]; 00234 float value; 00235 int max; 00236 00237 /* find max value */ 00238 max=0; 00239 for(x=0; x<256; x++) { 00240 if(bins[x]>max) max=bins[x]; 00241 } 00242 00243 /*draw histogram in buffer */ 00244 for(x=0; x<out->x; x++) { 00245 for(y=0;y<out->y; y++) { 00246 00247 /* get normalized value (0..255) */ 00248 value=((float)bins[x]/(float)max)*255.0; 00249 00250 if(y < (int)value) { /*if the y value is below the height of the bar for this line then draw with the color */ 00251 switch (node->custom1) { 00252 case 1: { /* draw in black */ 00253 color[0]=0.0; color[1]=0.0; color[2]=0.0; color[3]=1.0; 00254 break; 00255 } 00256 case 2: { /* draw in red */ 00257 color[0]=1.0; color[1]=0.0; color[2]=0.0; color[3]=1.0; 00258 break; 00259 } 00260 case 3: { /* draw in green */ 00261 color[0]=0.0; color[1]=1.0; color[2]=0.0; color[3]=1.0; 00262 break; 00263 } 00264 case 4: { /* draw in blue */ 00265 color[0]=0.0; color[1]=0.0; color[2]=1.0; color[3]=1.0; 00266 break; 00267 } 00268 case 5: { /* draw in white */ 00269 color[0]=1.0; color[1]=1.0; color[2]=1.0; color[3]=1.0; 00270 break; 00271 } 00272 } 00273 } 00274 else{ 00275 color[0]=0.8; color[1]=0.8; color[2]=0.8; color[3]=1.0; 00276 } 00277 00278 /* set the color */ 00279 qd_setPixel(out, x, y, color); 00280 } 00281 } 00282 } 00283 00284 static void node_composit_exec_view_levels(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 00285 { 00286 CompBuf* cbuf; 00287 CompBuf* histogram; 00288 RenderData *rd=data; 00289 float mean, std_dev; 00290 int bins[256]; 00291 int x; 00292 00293 if(in[0]->hasinput==0) return; 00294 if(in[0]->data==NULL) return; 00295 00296 histogram=alloc_compbuf(256, 256, CB_RGBA, 1); 00297 cbuf=typecheck_compbuf(in[0]->data, CB_RGBA); 00298 00299 /*initalize bins*/ 00300 for(x=0; x<256; x++) { 00301 bins[x]=0; 00302 } 00303 00304 /*fill bins */ 00305 fill_bins(node, in[0]->data, bins, rd->color_mgt_flag & R_COLOR_MANAGEMENT); 00306 00307 /* draw the histogram chart */ 00308 draw_histogram(node, histogram, bins); 00309 00310 /* calculate the average brightness and contrast */ 00311 mean=brightness_mean(node, in[0]->data); 00312 std_dev=brightness_standard_deviation(node, in[0]->data, mean); 00313 00314 /* Printf debuging ;) 00315 printf("Mean: %f\n", mean); 00316 printf("Std Dev: %f\n", std_dev); 00317 */ 00318 00319 if(out[0]->hasoutput) 00320 out[0]->vec[0]= mean; 00321 if(out[1]->hasoutput) 00322 out[1]->vec[0]= std_dev; 00323 00324 generate_preview(data, node, histogram); 00325 00326 if(cbuf!=in[0]->data) 00327 free_compbuf(cbuf); 00328 free_compbuf(histogram); 00329 } 00330 00331 static void node_composit_init_view_levels(bNode* node) 00332 { 00333 node->custom1=1; /*All channels*/ 00334 } 00335 00336 void register_node_type_cmp_view_levels(ListBase *lb) 00337 { 00338 static bNodeType ntype; 00339 00340 node_type_base(&ntype, CMP_NODE_VIEW_LEVELS, "Levels", NODE_CLASS_OUTPUT, NODE_OPTIONS|NODE_PREVIEW, 00341 cmp_node_view_levels_in, cmp_node_view_levels_out); 00342 node_type_size(&ntype, 140, 100, 320); 00343 node_type_init(&ntype, node_composit_init_view_levels); 00344 node_type_storage(&ntype, "ImageUser", NULL, NULL); 00345 node_type_exec(&ntype, node_composit_exec_view_levels); 00346 00347 nodeRegisterType(lb, &ntype); 00348 } 00349 00350