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