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 
31 #include <iostream>
32 #include "image_hierarchy.hh"
33 #include "photoflow.hh"
34 
35 
image_hierarchy_free(PF::IHArray * array)36 void PF::image_hierarchy_free(PF::IHArray* array)
37 {
38   if( !array ) return;
39   if( array->vec ) g_free(array->vec);
40   g_free(array);
41 }
42 
43 
image_hierarchy_new()44 PF::IHArray* PF::image_hierarchy_new()
45 {
46   PF::IHArray* result = (PF::IHArray*)g_malloc( sizeof(PF::IHArray) );
47   if( result ) {
48     result->size = 0;
49     result->vec = NULL;
50   }
51   return result;
52 }
53 
54 
image_hierarchy_add_element(PF::IHArray * array,VipsImage * el,int padding)55 void PF::image_hierarchy_add_element(PF::IHArray* array, VipsImage* el, int padding)
56 {
57   if( !array ) return;
58   //std::cout<<"image_hierarchy_add_element(): padding="<<padding<<std::endl;
59   for(unsigned int i = 0; i < array->size; i++) {
60     if( array->vec[i].image == el ) {
61       //std::cout<<"image_hierarchy_add_element():   found image in array, old padding="<<array->vec[i].padding<<std::endl;
62       if( array->vec[i].padding < padding ) {
63         array->vec[i].padding = padding;
64       }
65       return;
66     }
67   }
68 
69   array->vec = (PF::IHElement*)g_realloc( array->vec, sizeof(PF::IHElement)*(array->size+1) );
70   if( array->vec == NULL ) {
71     array->size = 0;
72     return;
73   }
74   array->vec[array->size].image = el;
75   array->vec[array->size].padding = padding;
76   array->size += 1;
77   //std::cout<<"image_hierarchy_add_element():   added element, new size="<<array->size<<std::endl;
78 }
79 
80 
image_hierarchy_fill(VipsImage * dest,int padding,std::vector<VipsImage * > & parents)81 void PF::image_hierarchy_fill(VipsImage* dest, int padding, std::vector<VipsImage*>& parents)
82 {
83   if( !dest ) return;
84 
85   PF::IHArray* array = PF::image_hierarchy_new();
86   //std::cout<<"image_hierarchy_fill(): array="<<(void*)array<<" size="<<array->size<<std::endl;
87 
88   for( unsigned int i = 0; i < parents.size(); i++ ) {
89     PF::IHArray* parray;
90     size_t length;
91 
92     //std::cout<<"image_hierarchy_fill(): i="<<i<<" array="<<array<<" parents[i]="<<parents[i]<<std::endl;
93     if( !parents[i] ) continue;
94     if( PF_VIPS_IMAGE_GET_BLOB( parents[i], "pf-image-hierarchy", &parray, &length) ) {
95       std::cout<<"image_hierarchy_fill(): parent image "<<i<<" does not have hierarchy information"<<std::endl;
96       std::cout<<"image_hierarchy_fill(): i="<<i<<" array="<<array<<std::endl;
97     } else {
98       if( parray == NULL ) {
99         std::cout<<"image_hierarchy_fill(): parent image "<<i<<" NULL hierarchy information"<<std::endl;
100         std::cout<<"image_hierarchy_fill(): i="<<i<<" array="<<array<<std::endl;
101       } else {
102         if( length != sizeof(PF::IHArray) ) {
103           std::cout<<"image_hierarchy_fill(): parent image "<<i<<" wrong size of hierarchy information"<<std::endl;
104           std::cout<<"image_hierarchy_fill(): i="<<i<<" array="<<array<<std::endl;
105         } else {
106           //std::cout<<"image_hierarchy_fill(): adding array from parent image "<<i<<std::endl;
107 
108           for( unsigned int ei = 0; ei < parray->size; ei++ ) {
109             PF::image_hierarchy_add_element( array, parray->vec[ei].image,
110                 parray->vec[ei].padding+padding );
111             //std::cout<<"image_hierarchy_fill(): i="<<i<<" ei="<<ei<<" array="<<array<<std::endl;
112           }
113         }
114       }
115     }
116 
117     // add the parent image itself
118     PF::image_hierarchy_add_element( array, parents[i], padding );
119     //std::cout<<"image_hierarchy_fill(): i="<<i<<" array="<<array<<std::endl;
120   }
121 
122   //std::cout<<"image_hierarchy_fill(): adding array to image="<<array<<std::endl;
123   vips_image_set_blob( dest, "pf-image-hierarchy",
124       (VipsCallbackFn) PF::image_hierarchy_free, array, sizeof(PF::IHArray) );
125   //std::cout<<"image_hierarchy_fill(): array added"<<std::endl;
126 }
127 
128 
129 
image_hierarchy_compare_images(VipsImage * i0,VipsImage * i1)130 int PF::image_hierarchy_compare_images(VipsImage* i0, VipsImage* i1)
131 {
132   PF::IHArray* parray0;
133   PF::IHArray* parray1;
134   size_t length;
135 
136   if( PF_VIPS_IMAGE_GET_BLOB( i0, "pf-image-hierarchy", &parray0, &length) ) {
137     return 1;
138   }
139   if( parray0 == NULL ) return 1;
140   if( length != sizeof(PF::IHArray) ) return 1;
141 
142   if( PF_VIPS_IMAGE_GET_BLOB( i1, "pf-image-hierarchy", &parray1, &length) ) {
143     return 0;
144   }
145   if( parray1 == NULL ) return 0;
146   if( length != sizeof(PF::IHArray) ) return 0;
147 
148   //std::cout<<"image_hierarchy_compare_images(): parray0->size="<<parray0->size
149   //    <<"  parray1->size="<<parray1->size<<std::endl;
150 
151   if( parray0->size==0 && parray1->size!=0 ) return 1;
152   if( parray1->size==0 && parray0->size!=0 ) return 0;
153 
154   int padding_tot0 = 0;
155   int padding_tot1 = 0;
156 
157   for( unsigned int i = 0; i < parray0->size; i++ ) {
158     for( unsigned int j = 0; j < parray1->size; j++ ) {
159       //std::cout<<"image_hierarchy_compare_images(): i="<<i<<" j="<<j
160       //    <<"  parray0->vec[i].image="<<parray0->vec[i].image
161       //    <<"  parray1->vec[j].image="<<parray1->vec[j].image<<std::endl;
162       if( parray0->vec[i].image != parray1->vec[j].image )
163         continue;
164       //std::cout<<"image_hierarchy_compare_images(): i="<<i<<" j="<<j
165       //    <<"  parray0->vec[i].padding="<<parray0->vec[i].padding
166       //    <<"  parray1->vec[j].padding="<<parray1->vec[j].padding<<std::endl;
167       if( parray0->vec[i].padding > parray1->vec[j].padding )
168         padding_tot0 += parray0->vec[i].padding - parray1->vec[j].padding;
169       else
170         padding_tot1 += parray1->vec[j].padding - parray0->vec[i].padding;
171     }
172   }
173   if( padding_tot0 >= padding_tot1 ) return 0;
174   else return 1;
175 }
176