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_DESATURATE_LUMINANCE_H
31 #define VIPS_DESATURATE_LUMINANCE_H
32 
33 namespace PF
34 {
35   class DesaturateLuminancePar: public OpParBase
36   {
37     ICCProfile* profile;
38     ProcessorBase* proc_average;
39     ProcessorBase* convert2lab;
40     ProcessorBase* convert_cs;
41 
42   public:
43     DesaturateLuminancePar();
44 
has_intensity()45     bool has_intensity() { return false; }
get_profile()46     ICCProfile* get_profile() { return profile; }
47 
48     VipsImage* build(std::vector<VipsImage*>& in, int first,
49                      VipsImage* imap, VipsImage* omap,
50                      unsigned int& level);
51   };
52 
53 
54   template < OP_TEMPLATE_DEF >
55   class DesaturateLuminanceProc
56   {
57   public:
render(VipsRegion ** ireg,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * oreg,DesaturateLuminancePar * par)58     void render(VipsRegion** ireg, int n, int in_first,
59                 VipsRegion* imap, VipsRegion* omap,
60                 VipsRegion* oreg, DesaturateLuminancePar* par)
61     {
62     }
63   };
64 
65 
66   template < class BLENDER, int CHMIN, int CHMAX, bool has_imap, bool has_omap, bool PREVIEW >
67   class DesaturateLuminanceProc< float, BLENDER, PF_COLORSPACE_RGB, CHMIN, CHMAX, has_imap, has_omap, PREVIEW >
68   {
69   public:
render(VipsRegion ** ireg,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * oreg,DesaturateLuminancePar * par)70     void render(VipsRegion** ireg, int n, int in_first,
71         VipsRegion* imap, VipsRegion* omap,
72         VipsRegion* oreg, DesaturateLuminancePar* par)
73     {
74       ICCProfile* profile = par->get_profile();
75       if( !profile ) return;
76 
77       VipsRect *r = &oreg->valid;
78       //int x, y, xomap, y0, dx1=CHMIN, dx2=PF::ColorspaceInfo<colorspace>::NCH-CHMIN, ch, CHMAXplus1=CHMAX+1;
79       int x, y, y0;
80       int width = r->width;
81       int line_size = width * oreg->im->Bands;
82       float* pin;
83       float* pin2;
84       float* pout;
85       float* line = NULL;
86       float val;
87       //if( profile->get_trc_type()!=PF_TRC_LINEAR ) line = new float[line_size];
88       //if( false && r->left==0 && r->top==0 ) {
89       //  std::cout<<"DesaturateLuminanceProc::render(): profile="<<profile<<std::endl;
90       //  std::cout<<"DesaturateLuminanceProc::render(): profile->has_colorants="<<profile->has_colorants<<std::endl;
91       //}
92       for( y = 0; y < r->height; y++ ) {
93         y0 = r->top + y;
94         pin = (float*)VIPS_REGION_ADDR( ireg[in_first], r->left, y0 );
95         pout = (float*)VIPS_REGION_ADDR( oreg, r->left, y0 );
96         //if( line ) {
97         //  for( x = 0; x < line_size; x++ ) {
98         //    line[x] = profile->perceptual2linear( pin[x] );
99         //  }
100         //  pin2 = line;
101         //} else {
102         //  pin2 = pin;
103         //}
104 
105         for( x = 0; x < line_size; x += 3 ) {
106           val = profile->get_lightness( pin[x], pin[x+1], pin[x+2] );
107           //if( profile->get_trc_type()!=PF_TRC_LINEAR )
108           //  val = profile->linear2perceptual( val );
109           pout[x] = val;
110           pout[x+1] = val;
111           pout[x+2] = val;
112         }
113       }
114       //if( line ) delete line;
115     }
116   };
117 
118 
119   template < class BLENDER, int CHMIN, int CHMAX, bool has_imap, bool has_omap, bool PREVIEW >
120   class DesaturateLuminanceProc< float, BLENDER, PF_COLORSPACE_LAB, CHMIN, CHMAX, has_imap, has_omap, PREVIEW >
121   {
122   public:
render(VipsRegion ** ireg,int n,int in_first,VipsRegion * imap,VipsRegion * omap,VipsRegion * oreg,DesaturateLuminancePar * par)123     void render(VipsRegion** ireg, int n, int in_first,
124         VipsRegion* imap, VipsRegion* omap,
125         VipsRegion* oreg, DesaturateLuminancePar* par)
126     {
127       VipsRect *r = &oreg->valid;
128       //int x, y, xomap, y0, dx1=CHMIN, dx2=PF::ColorspaceInfo<colorspace>::NCH-CHMIN, ch, CHMAXplus1=CHMAX+1;
129       int x, y, y0;
130       int width = r->width;
131       int line_size = width * oreg->im->Bands;
132       float* pin;
133       float* pout;
134       for( y = 0; y < r->height; y++ ) {
135         y0 = r->top + y;
136         pin = (float*)VIPS_REGION_ADDR( ireg[in_first], r->left, y0 );
137         pout = (float*)VIPS_REGION_ADDR( oreg, r->left, y0 );
138         for( x = 0; x < line_size; x += 3 ) {
139           pout[x] = pin[x];
140           pout[x+1] = pout[x+2] = FormatInfo<float>::HALF;
141         }
142       }
143     }
144   };
145 
146 
147   ProcessorBase* new_desaturate_luminance();
148 }
149 
150 #endif
151 
152 
153