1 /* Definitions for partial image regions.
2  *
3  * J.Cupitt, 8/4/93
4  *
5  * 2/3/11
6  * 	- move to GObject
7  */
8 
9 /*
10 
11     This file is part of VIPS.
12 
13     VIPS is free software; you can redistribute it and/or modify
14     it under the terms of the GNU Lesser General Public License as published by
15     the Free Software Foundation; either version 2 of the License, or
16     (at your option) any later version.
17 
18     This program is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21     GNU Lesser General Public License for more details.
22 
23     You should have received a copy of the GNU Lesser General Public License
24     along with this program; if not, write to the Free Software
25     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26     02110-1301  USA
27 
28  */
29 
30 /*
31 
32     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
33 
34  */
35 
36 #ifndef VIPS_REGION_H
37 #define VIPS_REGION_H
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif /*__cplusplus*/
42 
43 #define VIPS_TYPE_REGION (vips_region_get_type())
44 #define VIPS_REGION( obj ) \
45 	(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
46 	VIPS_TYPE_REGION, VipsRegion ))
47 #define VIPS_REGION_CLASS( klass ) \
48 	(G_TYPE_CHECK_CLASS_CAST( (klass), \
49 	VIPS_TYPE_REGION, VipsRegionClass))
50 #define VIPS_IS_REGION( obj ) \
51 	(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_REGION ))
52 #define VIPS_IS_REGION_CLASS( klass ) \
53 	(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_REGION ))
54 #define VIPS_REGION_GET_CLASS( obj ) \
55 	(G_TYPE_INSTANCE_GET_CLASS( (obj), \
56 	VIPS_TYPE_REGION, VipsRegionClass ))
57 
58 /**
59  * VipsRegionShrink:
60  * @VIPS_REGION_SHRINK_MEAN: use the average
61  * @VIPS_REGION_SHRINK_MEDIAN: use the median
62  * @VIPS_REGION_SHRINK_MODE: use the mode
63  * @VIPS_REGION_SHRINK_MAX: use the maximum
64  * @VIPS_REGION_SHRINK_MIN: use the minimum
65  * @VIPS_REGION_SHRINK_NEAREST: use the top-left pixel
66  *
67  * How to calculate the output pixels when shrinking a 2x2 region.
68  */
69 typedef enum {
70 	VIPS_REGION_SHRINK_MEAN,
71 	VIPS_REGION_SHRINK_MEDIAN,
72 	VIPS_REGION_SHRINK_MODE,
73 	VIPS_REGION_SHRINK_MAX,
74 	VIPS_REGION_SHRINK_MIN,
75 	VIPS_REGION_SHRINK_NEAREST,
76 	VIPS_REGION_SHRINK_LAST
77 } VipsRegionShrink;
78 
79 /* Sub-area of image.
80  *
81  * Matching typedef in basic.h.
82  */
83 struct _VipsRegion {
84 	VipsObject parent_object;
85 
86 	/*< public >*/
87 	/* Users may read these two fields.
88 	 */
89 	VipsImage *im;		/* Link back to parent image */
90 	VipsRect valid;		/* Area of parent we can see */
91 
92 	/* The rest of VipsRegion is private.
93 	 */
94 	/*< private >*/
95 	RegionType type;	/* What kind of attachment */
96 	VipsPel *data;		/* Off here to get data */
97 	int bpl;		/* Bytes-per-line for data */
98 	void *seq;		/* Sequence we are using to fill region */
99 
100 	/* The thread that made this region. Used to assert() test that
101 	 * regions are not being shared between threads.
102 	 */
103 	GThread *thread;
104 
105 	/* Ref to the window we use for this region, if any.
106 	 */
107 	VipsWindow *window;
108 
109 	/* Ref to the buffer we use for this region, if any.
110 	 */
111 	VipsBuffer *buffer;
112 
113 	/* The image this region is on has changed and caches need to be
114 	 * dropped.
115 	 */
116 	gboolean invalid;
117 };
118 
119 typedef struct _VipsRegionClass {
120 	VipsObjectClass parent_class;
121 
122 } VipsRegionClass;
123 
124 /* Don't put spaces around void here, it breaks gtk-doc.
125  */
126 GType vips_region_get_type(void);
127 
128 VipsRegion *vips_region_new( VipsImage *image );
129 
130 int vips_region_buffer( VipsRegion *reg, const VipsRect *r );
131 int vips_region_image( VipsRegion *reg, const VipsRect *r );
132 int vips_region_region( VipsRegion *reg, VipsRegion *dest,
133 	const VipsRect *r, int x, int y );
134 int vips_region_equalsregion( VipsRegion *reg1, VipsRegion *reg2 );
135 int vips_region_position( VipsRegion *reg, int x, int y );
136 
137 void vips_region_paint( VipsRegion *reg, const VipsRect *r, int value );
138 void vips_region_paint_pel( VipsRegion *reg,
139 	const VipsRect *r, const VipsPel *ink );
140 void vips_region_black( VipsRegion *reg );
141 void vips_region_copy( VipsRegion *reg, VipsRegion *dest,
142 	const VipsRect *r, int x, int y );
143 int vips_region_shrink_method( VipsRegion *from, VipsRegion *to,
144 	const VipsRect *target, VipsRegionShrink method );
145 int vips_region_shrink( VipsRegion *from, VipsRegion *to,
146 	const VipsRect *target );
147 
148 int vips_region_prepare( VipsRegion *reg, const VipsRect *r );
149 int vips_region_prepare_to( VipsRegion *reg,
150 	VipsRegion *dest, const VipsRect *r, int x, int y );
151 
152 VipsPel *vips_region_fetch( VipsRegion *region,
153 	int left, int top, int width, int height, size_t *len );
154 int vips_region_width( VipsRegion *region );
155 int vips_region_height( VipsRegion *region );
156 
157 void vips_region_invalidate( VipsRegion *reg );
158 
159 /* Use this to count pixels passing through key points. Handy for spotting bad
160  * overcomputation.
161  */
162 #ifdef DEBUG_LEAK
163 #define VIPS_COUNT_PIXELS( R, N ) vips__region_count_pixels( R, N )
164 #else /*!DEBUG_LEAK*/
165 #define VIPS_COUNT_PIXELS( R, N )
166 #endif /*DEBUG_LEAK*/
167 
168 #define VIPS_REGION_LSKIP( R ) \
169 	((size_t)((R)->bpl))
170 #define VIPS_REGION_N_ELEMENTS( R ) \
171 	((size_t)((R)->valid.width * (R)->im->Bands))
172 #define VIPS_REGION_SIZEOF_ELEMENT( R ) \
173 	(VIPS_IMAGE_SIZEOF_ELEMENT( (R)->im ))
174 #define VIPS_REGION_SIZEOF_PEL( R ) \
175 	(VIPS_IMAGE_SIZEOF_PEL( (R)->im ))
176 #define VIPS_REGION_SIZEOF_LINE( R ) \
177 	((size_t)((R)->valid.width * VIPS_REGION_SIZEOF_PEL( R )))
178 
179 /* If DEBUG is defined, add bounds checking.
180  */
181 #ifdef DEBUG
182 #define VIPS_REGION_ADDR( R, X, Y ) \
183 	( (vips_rect_includespoint( &(R)->valid, (X), (Y) ))? \
184 	  ((R)->data + ((Y) - (R)->valid.top) * VIPS_REGION_LSKIP(R) + \
185 	  ((X) - (R)->valid.left) * VIPS_REGION_SIZEOF_PEL( R )): \
186 	  (fprintf( stderr, \
187 		"VIPS_REGION_ADDR: point out of bounds, " \
188 		"file \"%s\", line %d\n" \
189 		"(point x=%d, y=%d\n" \
190 		" should have been within VipsRect left=%d, top=%d, " \
191 		"width=%d, height=%d)\n", \
192 		__FILE__, __LINE__, \
193 		(X), (Y), \
194 		(R)->valid.left, \
195 		(R)->valid.top, \
196 		(R)->valid.width, \
197 		(R)->valid.height ), abort(), (VipsPel *) NULL) \
198 	)
199 #else /*DEBUG*/
200 #define VIPS_REGION_ADDR( R, X, Y ) \
201 	((R)->data + \
202 	((Y)-(R)->valid.top) * VIPS_REGION_LSKIP( R ) + \
203 	((X)-(R)->valid.left) * VIPS_REGION_SIZEOF_PEL( R ))
204 #endif /*DEBUG*/
205 
206 #define VIPS_REGION_ADDR_TOPLEFT( R ) ((R)->data)
207 
208 #ifdef __cplusplus
209 }
210 #endif /*__cplusplus*/
211 
212 #endif /*VIPS_REGION_H*/
213