/* This source file is a part of the GePhex Project. Copyright (C) 2001-2004 Georg Seidel Martin Bayer Phillip Promesberger This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/ #include "overlaymodule.h" #include static logT s_log; struct bgra_pixel_t { uint8_t colors[4]; // TODO endianes uint8_t& red() { return colors[0]; } uint8_t& green() { return colors[1]; } uint8_t& blue() { return colors[2]; } uint8_t& alpha() { return colors[3]; } uint8_t gray() { return (red() + 2*green() + blue()) / 4; } void alpha_mix(uint8_t a, bgra_pixel_t& color1, bgra_pixel_t& color2 ) { uint8_t ia = 255 - a; red() = (a * color1.red() + ia * color2.red() ) / 256; green() = (a * color1.green() + ia * color2.green()) / 256; blue() = (a * color1.blue() + ia * color2.blue() ) / 256; alpha() = (a * color1.blue() + ia * color2.blue() ) / 256; } }; typedef struct _MyInstance { FrameBufferType* temp_in_2; FrameBufferType* temp_in_control; } MyInstance, *MyInstancePtr; int init(logT log_function) { s_log = log_function; return 1; } void shutDown(void) { } MyInstance* construct() { MyInstance* my = (MyInstancePtr) malloc(sizeof(MyInstance)); my->temp_in_2=framebuffer_newInstance(); my->temp_in_control=framebuffer_newInstance(); return my; } void destruct(MyInstance* my) { framebuffer_deleteInstance(my->temp_in_2); framebuffer_deleteInstance(my->temp_in_control); free(my); } static __inline int framebuffer_compare_attributes(FrameBufferAttributes* attributes1, FrameBufferAttributes* attributes2) { return (attributes1->xsize == attributes2->xsize && attributes1->ysize == attributes2->ysize); } void update(void* instance) { InstancePtr inst = (InstancePtr) instance; MyInstancePtr my = inst->my; // Add your effect here! FrameBufferAttributes in_1_attr; FrameBufferAttributes in_2_attr; FrameBufferAttributes in_control_attr; framebuffer_getAttributes(inst->in_1,&in_1_attr); framebuffer_getAttributes(inst->in_2,&in_2_attr); framebuffer_getAttributes(inst->in_control,&in_control_attr); // default FrameBufferType* in_1=inst->in_1; FrameBufferType* in_2=inst->in_2; FrameBufferType* in_control=inst->in_control; if(!framebuffer_compare_attributes(&in_1_attr,&in_control_attr)) { // we need to convert th control image framebuffer_convertType(my->temp_in_control,inst->in_control , &in_1_attr); in_control=my->temp_in_control; } // check if all frame inputs have equal attributes if(!(framebuffer_compare_attributes(&in_1_attr,&in_2_attr))) { // scale the second input frame framebuffer_convertType(my->temp_in_2, inst->in_2, &in_1_attr); in_2=my->temp_in_2; } // change the output size framebuffer_changeAttributes(inst->out_r,&in_1_attr); int size=in_1_attr.xsize*in_1_attr.ysize; bgra_pixel_t* in_1_ptr=reinterpret_cast(in_1->data); bgra_pixel_t* in_1_ptr_end = reinterpret_cast(in_1->data) + size; bgra_pixel_t* in_2_ptr=reinterpret_cast(in_2->data); bgra_pixel_t* in_control_ptr=reinterpret_cast(in_control->data); bgra_pixel_t* out_r_ptr=reinterpret_cast(inst->out_r->data); int tolerance=trim_int(inst->in_tolerance->number*255 + .5 ,0,255); bool alpha_mode=trim_bool(inst->in_alpha_mode->number); // the three frames must have the same attributes { FrameBufferAttributes in_1_attr; FrameBufferAttributes in_2_attr; FrameBufferAttributes in_control_attr; framebuffer_getAttributes(in_1,&in_1_attr); framebuffer_getAttributes(in_2,&in_2_attr); framebuffer_getAttributes(in_control,&in_control_attr); assert(framebuffer_compare_attributes(&in_1_attr,&in_2_attr)&& framebuffer_compare_attributes(&in_2_attr,&in_control_attr)); } if (alpha_mode) while( in_1_ptr != in_1_ptr_end ) { *out_r_ptr = (in_control_ptr->gray() > tolerance) ? (*in_1_ptr) : (*in_2_ptr); ++in_1_ptr;++in_2_ptr;++in_control_ptr;++out_r_ptr; } else while( in_1_ptr != in_1_ptr_end ) { out_r_ptr->alpha_mix(in_control_ptr->gray(), *in_1_ptr, *in_2_ptr); ++in_1_ptr;++in_2_ptr;++in_control_ptr;++out_r_ptr; } } void strongDependencies(Instance* inst, int neededInputs[]) { // set the inputs to 0 that are not needed! }