/src/libvips/libvips/create/point.c
Line | Count | Source |
1 | | /* base class for point-wise creators |
2 | | * |
3 | | * 13/6/13 |
4 | | */ |
5 | | |
6 | | /* |
7 | | |
8 | | This file is part of VIPS. |
9 | | |
10 | | VIPS is free software; you can redistribute it and/or modify |
11 | | it under the terms of the GNU Lesser General Public License as published by |
12 | | the Free Software Foundation; either version 2 of the License, or |
13 | | (at your option) any later version. |
14 | | |
15 | | This program is distributed in the hope that it will be useful, |
16 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | | GNU Lesser General Public License for more details. |
19 | | |
20 | | You should have received a copy of the GNU Lesser General Public License |
21 | | along with this program; if not, write to the Free Software |
22 | | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
23 | | 02110-1301 USA |
24 | | |
25 | | */ |
26 | | |
27 | | /* |
28 | | |
29 | | These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk |
30 | | |
31 | | */ |
32 | | |
33 | | /* |
34 | | #define VIPS_DEBUG |
35 | | */ |
36 | | |
37 | | #ifdef HAVE_CONFIG_H |
38 | | #include <config.h> |
39 | | #endif /*HAVE_CONFIG_H*/ |
40 | | #include <glib/gi18n-lib.h> |
41 | | |
42 | | #include <stdio.h> |
43 | | #include <string.h> |
44 | | #include <stdlib.h> |
45 | | #include <math.h> |
46 | | |
47 | | #include <vips/vips.h> |
48 | | |
49 | | #include "pcreate.h" |
50 | | #include "point.h" |
51 | | |
52 | 190 | G_DEFINE_ABSTRACT_TYPE(VipsPoint, vips_point, VIPS_TYPE_CREATE); |
53 | 190 | |
54 | 190 | static int |
55 | 190 | vips_point_gen(VipsRegion *out_region, |
56 | 190 | void *seq, void *a, void *b, gboolean *stop) |
57 | 1.46k | { |
58 | 1.46k | VipsPoint *point = (VipsPoint *) a; |
59 | 1.46k | VipsPointClass *class = VIPS_POINT_GET_CLASS(point); |
60 | 1.46k | VipsRect *r = &out_region->valid; |
61 | | |
62 | 1.46k | int x, y; |
63 | | |
64 | 23.8k | for (y = 0; y < r->height; y++) { |
65 | 22.3k | int ay = r->top + y; |
66 | 22.3k | float *q = (float *) VIPS_REGION_ADDR(out_region, r->left, ay); |
67 | | |
68 | 168k | for (x = 0; x < r->width; x++) |
69 | 146k | q[x] = class->point(point, r->left + x, ay); |
70 | 22.3k | } |
71 | | |
72 | 1.46k | return 0; |
73 | 1.46k | } |
74 | | |
75 | | static int |
76 | | vips_point_build(VipsObject *object) |
77 | 109 | { |
78 | 109 | VipsCreate *create = VIPS_CREATE(object); |
79 | 109 | VipsPoint *point = VIPS_POINT(object); |
80 | 109 | VipsPointClass *class = VIPS_POINT_GET_CLASS(point); |
81 | 109 | VipsImage **t = (VipsImage **) vips_object_local_array(object, 4); |
82 | | |
83 | 109 | VipsImage *in; |
84 | | |
85 | 109 | if (VIPS_OBJECT_CLASS(vips_point_parent_class)->build(object)) |
86 | 7 | return -1; |
87 | | |
88 | 102 | t[0] = vips_image_new(); |
89 | 102 | vips_image_init_fields(t[0], |
90 | 102 | point->width, point->height, 1, |
91 | 102 | VIPS_FORMAT_FLOAT, VIPS_CODING_NONE, class->interpretation, |
92 | 102 | 1.0, 1.0); |
93 | 102 | if (vips_image_pipelinev(t[0], VIPS_DEMAND_STYLE_ANY, NULL) || |
94 | 102 | vips_image_generate(t[0], |
95 | 102 | NULL, vips_point_gen, NULL, point, NULL)) |
96 | 0 | return -1; |
97 | 102 | in = t[0]; |
98 | | |
99 | 102 | if (point->uchar) { |
100 | 0 | float min = class->min; |
101 | 0 | float max = class->max; |
102 | 0 | float range = max - min; |
103 | |
|
104 | 0 | if (vips_linear1(in, &t[2], |
105 | 0 | 255.0 / range, -min * 255.0 / range, |
106 | 0 | "uchar", TRUE, |
107 | 0 | NULL)) |
108 | 0 | return -1; |
109 | 0 | in = t[2]; |
110 | | |
111 | | /* We don't want FOURIER or whatever in this case. |
112 | | */ |
113 | 0 | in->Type = VIPS_INTERPRETATION_MULTIBAND; |
114 | 0 | } |
115 | | |
116 | 102 | if (vips_image_write(in, create->out)) |
117 | 0 | return -1; |
118 | | |
119 | 102 | return 0; |
120 | 102 | } |
121 | | |
122 | | static void |
123 | | vips_point_class_init(VipsPointClass *class) |
124 | 19 | { |
125 | 19 | GObjectClass *gobject_class = G_OBJECT_CLASS(class); |
126 | 19 | VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS(class); |
127 | | |
128 | 19 | gobject_class->set_property = vips_object_set_property; |
129 | 19 | gobject_class->get_property = vips_object_get_property; |
130 | | |
131 | 19 | vobject_class->nickname = "point"; |
132 | 19 | vobject_class->description = _("make a point image"); |
133 | 19 | vobject_class->build = vips_point_build; |
134 | | |
135 | 19 | class->point = NULL; |
136 | 19 | class->min = -1.0F; |
137 | 19 | class->max = 1.0F; |
138 | 19 | class->interpretation = VIPS_INTERPRETATION_MULTIBAND; |
139 | | |
140 | 19 | VIPS_ARG_INT(class, "width", 2, |
141 | 19 | _("Width"), |
142 | 19 | _("Image width in pixels"), |
143 | 19 | VIPS_ARGUMENT_REQUIRED_INPUT, |
144 | 19 | G_STRUCT_OFFSET(VipsPoint, width), |
145 | 19 | 1, VIPS_MAX_COORD, 1); |
146 | | |
147 | 19 | VIPS_ARG_INT(class, "height", 3, |
148 | 19 | _("Height"), |
149 | 19 | _("Image height in pixels"), |
150 | 19 | VIPS_ARGUMENT_REQUIRED_INPUT, |
151 | 19 | G_STRUCT_OFFSET(VipsPoint, height), |
152 | 19 | 1, VIPS_MAX_COORD, 1); |
153 | | |
154 | 19 | VIPS_ARG_BOOL(class, "uchar", 4, |
155 | 19 | _("Uchar"), |
156 | 19 | _("Output an unsigned char image"), |
157 | 19 | VIPS_ARGUMENT_OPTIONAL_INPUT, |
158 | 19 | G_STRUCT_OFFSET(VipsPoint, uchar), |
159 | 19 | FALSE); |
160 | 19 | } |
161 | | |
162 | | static void |
163 | | vips_point_init(VipsPoint *point) |
164 | 121 | { |
165 | 121 | } |