1 /*
2  */
3 
4 /*
5 
6     Copyright (C) 2014 Ferrero Andrea
7 
8     This program is free software: you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21 
22  */
23 
24 /*
25 
26     These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/
27 
28  */
29 
30 #ifndef VIPS_PROCESSOR_IMP_H
31 #define VIPS_PROCESSOR_IMP_H
32 
33 
34 #include "processor.hh"
35 #include "operation.hh"
36 
37 
38 namespace PF
39 {
40   template< class OPPAR, template < OP_TEMPLATE_DEF > class OP >
41   class Processor: public ProcessorBase
42   {
43     OPPAR op_par;
44 
45   public:
Processor()46     Processor(): ProcessorBase(&op_par) { op_par.set_processor(this); }
get_par()47     OPPAR* get_par() { return &op_par; }
48     //virtual OpParBase* get_params() { return &op_params; };
49     virtual void process(VipsRegion** in, int n, int in_first,
50 			 VipsRegion* imap, VipsRegion* omap,
51 			 VipsRegion* out);
52   };
53 
54 
55 
56 #define MAPFLAG_SWITCH( TYPE, CS, CHMIN, CHMAX ) {	\
57         switch(mapflag) { \
58         case 0:								\
59 					if(get_par()->get_render_mode() == PF_RENDER_NORMAL) {					\
60 						OP< TYPE, Blender< TYPE, CS, CHMIN, CHMAX, false >, CS, CHMIN, CHMAX, false, false, false > op; \
61 	    op.render(in,n,in_first,imap,omap,out,&op_par);		\
62 	  } else {							\
63 	    OP< TYPE, Blender< TYPE, CS, CHMIN, CHMAX, false >, CS, CHMIN, CHMAX, false, false, true > op; \
64 	    op.render(in,n,in_first,imap,omap,out,&op_par);		\
65 	  }								\
66 	  break; \
67         case 1:								\
68 					if(get_par()->get_render_mode() == PF_RENDER_NORMAL) {					\
69 	    OP< TYPE, Blender< TYPE, CS, CHMIN, CHMAX, false >, CS, CHMIN, CHMAX, true, false, false > op; \
70 	    op.render(in,n,in_first,imap,omap,out,&op_par);		\
71 	  } else {							\
72 	    OP< TYPE, Blender< TYPE, CS, CHMIN, CHMAX, false >, CS, CHMIN, CHMAX, true, false, true > op; \
73 	    op.render(in,n,in_first,imap,omap,out,&op_par);		\
74 	  }								\
75 	  break; \
76         case 2:								\
77 					if(get_par()->get_render_mode() == PF_RENDER_NORMAL) {					\
78 	    OP< TYPE, Blender< TYPE, CS, CHMIN, CHMAX, true >, CS, CHMIN, CHMAX, false, true, false > op; \
79 	    op.render(in,n,in_first,imap,omap,out,&op_par);		\
80 	  } else {							\
81 	    OP< TYPE, Blender< TYPE, CS, CHMIN, CHMAX, true >, CS, CHMIN, CHMAX, false, true, true > op; \
82 	    op.render(in,n,in_first,imap,omap,out,&op_par);		\
83 	  }								\
84 	  break; \
85         case 3:								\
86 					if(get_par()->get_render_mode() == PF_RENDER_NORMAL) {					\
87 	    OP< TYPE, Blender< TYPE, CS, CHMIN, CHMAX, true >, CS, CHMIN, CHMAX, true, true, false > op; \
88 	    op.render(in,n,in_first,imap,omap,out,&op_par);		\
89 	  } else {							\
90 	    OP< TYPE, Blender< TYPE, CS, CHMIN, CHMAX, true >, CS, CHMIN, CHMAX, true, true, true > op; \
91 	    op.render(in,n,in_first,imap,omap,out,&op_par);		\
92 	  }								\
93 	  break; \
94         }						\
95 }
96 
97 
98 #define CS_SWITCH( TYPE ) {			\
99   switch(colorspace) {							\
100   case PF_COLORSPACE_RAW:						\
101   case PF_COLORSPACE_GRAYSCALE:						\
102     MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_GRAYSCALE, 0, 0 );	\
103     break;								\
104   case PF_COLORSPACE_MULTIBAND:            \
105     MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_MULTIBAND, 0, 0 ); \
106     break;                \
107   case PF_COLORSPACE_RGB:						\
108     switch( op_par.get_rgb_target_channel() ) {				\
109     case 0:								\
110       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_RGB, 0, 0 );	\
111       break;								\
112     case 1:								\
113       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_RGB, 1, 1 );	\
114       break;								\
115     case 2:								\
116       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_RGB, 2, 2 );	\
117       break;								\
118     default:								\
119       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_RGB, 0, 2 );	\
120       break;								\
121     }									\
122     break;								\
123   case PF_COLORSPACE_LAB:						\
124     switch( op_par.get_lab_target_channel() ) {				\
125     case 0:								\
126       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_LAB, 0, 0 );	\
127       break;								\
128     case 1:								\
129       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_LAB, 1, 1 );	\
130       break;								\
131     case 2:								\
132       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_LAB, 2, 2 );	\
133       break;								\
134     default:								\
135       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_LAB, 0, 2 );	\
136       break;								\
137     }									\
138     break;								\
139   case PF_COLORSPACE_CMYK:						\
140     switch( op_par.get_cmyk_target_channel() ) {			\
141     case 0:								\
142       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_CMYK, 0, 0 );	\
143       break;								\
144     case 1:								\
145       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_CMYK, 1, 1 );	\
146       break;								\
147     case 2:								\
148       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_CMYK, 2, 2 );	\
149       break;								\
150     case 3:								\
151       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_CMYK, 3, 3 );	\
152       break;								\
153     default:								\
154       MAPFLAG_SWITCH( TYPE, PF_COLORSPACE_CMYK, 0, 3 );	\
155       break;								\
156     }									\
157     break;								\
158   case PF_COLORSPACE_UNKNOWN:						\
159     break;								\
160   }									\
161 }
162 
163 
164   template< class OPPAR, template < OP_TEMPLATE_DEF > class OP >
process(VipsRegion ** in,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * out)165   void Processor<OPPAR,OP>::process(VipsRegion** in, int n, int in_first,
166 				    VipsRegion* imap, VipsRegion* omap,
167 				    VipsRegion* out)
168   {
169     BandFormat fmt = PF_BANDFMT_UNKNOWN;
170     colorspace_t colorspace = PF_COLORSPACE_UNKNOWN;
171 
172     fmt = (PF::BandFormat)op_par.get_format();
173     //std::cout<<"Processor<OPPAR,OP>::process(): format = "<<fmt<<std::endl;
174     colorspace = PF::convert_colorspace( op_par.get_interpretation() );
175 
176     /*
177     if(out) {
178       fmt = (BandFormat)out->im->BandFmt;
179       colorspace = PF::convert_colorspace(out->im->Type);
180     } else {
181       if(n > 0) {
182 	fmt = (BandFormat)in[0]->im->BandFmt;
183 	colorspace = PF::convert_colorspace(in[0]->im->Type);
184 	//interpret = in[0]->image->Type;
185       }
186     }
187     */
188 
189     int mapflag = 0;
190     if(imap) mapflag += 1;
191     if(omap) mapflag += 2;
192 
193     /*
194     std::cout<<"Processor::process(): "<<std::endl
195 	     <<"  fmt = "<<fmt<<std::endl
196 	     <<"  colorspace = "<<colorspace<<std::endl
197 	     //<<"  blend mode = "<<op_params.get_blend_mode()<<std::endl
198 	     <<"  imap = "<<imap<<"  omap = "<<omap<<std::endl
199 	     <<"  mapflag = "<<mapflag<<std::endl;
200     */
201 
202     switch(fmt) {
203     /*case PF_BANDFMT_UCHAR:
204       CS_SWITCH( uint8_t );
205       break;
206     case PF_BANDFMT_USHORT:
207       CS_SWITCH( unsigned short int );
208       break;*/
209     case PF_BANDFMT_FLOAT:
210       CS_SWITCH( float );
211       break;
212     case PF_BANDFMT_UCHAR:
213     case PF_BANDFMT_USHORT:
214     case PF_BANDFMT_CHAR:
215     case PF_BANDFMT_SHORT:
216     case PF_BANDFMT_UINT:
217     case PF_BANDFMT_INT:
218     case PF_BANDFMT_DOUBLE:
219     case PF_BANDFMT_UNKNOWN:
220       std::cout<<"Processor::process(): unhandled band format"<<std::endl;
221       break;
222     }
223   }
224 
225 }
226 
227 
228 #endif /*VIPS_PARITHMETIC_H*/
229 
230 
231