|
Blender
V2.59
|
00001 /* 00002 * $Id: CMP_huecorrect.c 36201 2011-04-17 22:11:23Z broken $ 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): Matt Ebb 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include "../CMP_util.h" 00036 00037 static bNodeSocketType cmp_node_huecorrect_in[]= { 00038 { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 00039 { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, 00040 { -1, 0, "" } 00041 }; 00042 00043 static bNodeSocketType cmp_node_huecorrect_out[]= { 00044 { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, 00045 { -1, 0, "" } 00046 }; 00047 00048 static void do_huecorrect(bNode *node, float *out, float *in) 00049 { 00050 float hsv[3], f; 00051 00052 rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2); 00053 00054 /* adjust hue, scaling returned default 0.5 up to 1 */ 00055 f = curvemapping_evaluateF(node->storage, 0, hsv[0]); 00056 hsv[0] += f-0.5f; 00057 00058 /* adjust saturation, scaling returned default 0.5 up to 1 */ 00059 f = curvemapping_evaluateF(node->storage, 1, hsv[0]); 00060 hsv[1] *= (f * 2.f); 00061 00062 /* adjust value, scaling returned default 0.5 up to 1 */ 00063 f = curvemapping_evaluateF(node->storage, 2, hsv[0]); 00064 hsv[2] *= (f * 2.f); 00065 00066 hsv[0] = hsv[0] - floor(hsv[0]); /* mod 1.0 */ 00067 CLAMP(hsv[1], 0.f, 1.f); 00068 00069 /* convert back to rgb */ 00070 hsv_to_rgb(hsv[0], hsv[1], hsv[2], out, out+1, out+2); 00071 00072 out[3]= in[3]; 00073 } 00074 00075 static void do_huecorrect_fac(bNode *node, float *out, float *in, float *fac) 00076 { 00077 float hsv[3], rgb[3], f; 00078 const float mfac = 1.f-*fac; 00079 00080 rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2); 00081 00082 /* adjust hue, scaling returned default 0.5 up to 1 */ 00083 f = curvemapping_evaluateF(node->storage, 0, hsv[0]); 00084 hsv[0] += f-0.5f; 00085 00086 /* adjust saturation, scaling returned default 0.5 up to 1 */ 00087 f = curvemapping_evaluateF(node->storage, 1, hsv[0]); 00088 hsv[1] *= (f * 2.f); 00089 00090 /* adjust value, scaling returned default 0.5 up to 1 */ 00091 f = curvemapping_evaluateF(node->storage, 2, hsv[0]); 00092 hsv[2] *= (f * 2.f); 00093 00094 hsv[0] = hsv[0] - floor(hsv[0]); /* mod 1.0 */ 00095 CLAMP(hsv[1], 0.f, 1.f); 00096 00097 /* convert back to rgb */ 00098 hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); 00099 00100 out[0]= mfac*in[0] + *fac*rgb[0]; 00101 out[1]= mfac*in[1] + *fac*rgb[1]; 00102 out[2]= mfac*in[2] + *fac*rgb[2]; 00103 out[3]= in[3]; 00104 } 00105 00106 static void node_composit_exec_huecorrect(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) 00107 { 00108 CompBuf *cbuf= in[1]->data; 00109 CompBuf *stackbuf; 00110 00111 /* stack order input: fac, image, black level, white level */ 00112 /* stack order output: image */ 00113 00114 if(out[0]->hasoutput==0) 00115 return; 00116 00117 if(in[0]->vec[0] == 0.f && in[0]->data == NULL) { 00118 out[0]->data = pass_on_compbuf(cbuf); 00119 return; 00120 } 00121 00122 /* input no image? then only color operation */ 00123 if(in[1]->data==NULL) { 00124 do_huecorrect_fac(node, out[0]->vec, in[1]->vec, in[0]->vec); 00125 } 00126 00127 if (cbuf) { 00128 stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* make output size of input image */ 00129 00130 if ((in[0]->data==NULL) && (in[0]->vec[0] >= 1.f)) 00131 composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_huecorrect, CB_RGBA); 00132 else 00133 composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_huecorrect_fac, CB_RGBA, CB_VAL); 00134 00135 out[0]->data= stackbuf; 00136 } 00137 00138 } 00139 00140 static void node_composit_init_huecorrect(bNode* node) 00141 { 00142 CurveMapping *cumapping = node->storage= curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); 00143 int c; 00144 00145 cumapping->preset = CURVE_PRESET_MID9; 00146 00147 for (c=0; c<3; c++) { 00148 CurveMap *cuma = &cumapping->cm[c]; 00149 curvemap_reset(cuma, &cumapping->clipr, cumapping->preset, CURVEMAP_SLOPE_POSITIVE); 00150 } 00151 00152 /* default to showing Saturation */ 00153 cumapping->cur = 1; 00154 } 00155 00156 void register_node_type_cmp_huecorrect(ListBase *lb) 00157 { 00158 static bNodeType ntype; 00159 00160 node_type_base(&ntype, CMP_NODE_HUECORRECT, "Hue Correct", NODE_CLASS_OP_COLOR, NODE_OPTIONS, 00161 cmp_node_huecorrect_in, cmp_node_huecorrect_out); 00162 node_type_size(&ntype, 320, 140, 400); 00163 node_type_init(&ntype, node_composit_init_huecorrect); 00164 node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); 00165 node_type_exec(&ntype, node_composit_exec_huecorrect); 00166 00167 nodeRegisterType(lb, &ntype); 00168 } 00169 00170