47
47
48
48
#include "pcolour.h"
49
49
50
- typedef VipsColourTransform VipsXYZ2scRGB ;
51
- typedef VipsColourTransformClass VipsXYZ2scRGBClass ;
50
+ /* We can't use VipsColourCode as our parent class. We want to handle
51
+ * alpha ourselves.
52
+ */
53
+
54
+ typedef struct _VipsXYZ2scRGB {
55
+ VipsOperation parent_instance ;
56
+
57
+ VipsImage * in ;
58
+ VipsImage * out ;
59
+ } VipsXYZ2scRGB ;
52
60
53
- G_DEFINE_TYPE (VipsXYZ2scRGB , vips_XYZ2scRGB , VIPS_TYPE_COLOUR_TRANSFORM );
61
+ typedef VipsOperationClass VipsXYZ2scRGBClass ;
62
+
63
+ G_DEFINE_TYPE (VipsXYZ2scRGB , vips_XYZ2scRGB , VIPS_TYPE_OPERATION );
54
64
55
65
/* We used to have the comment:
56
66
@@ -69,17 +79,15 @@ G_DEFINE_TYPE(VipsXYZ2scRGB, vips_XYZ2scRGB, VIPS_TYPE_COLOUR_TRANSFORM);
69
79
*/
70
80
71
81
static void
72
- vips_XYZ2scRGB_line (VipsColour * colour , VipsPel * out , VipsPel * * in , int width )
82
+ vips_XYZ2scRGB_line (float * restrict q , float * restrict p ,
83
+ int extra_bands , int width )
73
84
{
74
- float * restrict p = (float * ) in [0 ];
75
- float * restrict q = (float * ) out ;
76
-
77
- int i ;
85
+ int i , j ;
78
86
79
87
for (i = 0 ; i < width ; i ++ ) {
80
- float X = p [0 ];
81
- float Y = p [1 ];
82
- float Z = p [2 ];
88
+ const float X = p [0 ];
89
+ const float Y = p [1 ];
90
+ const float Z = p [2 ];
83
91
84
92
float R , G , B ;
85
93
@@ -92,27 +100,118 @@ vips_XYZ2scRGB_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width)
92
100
q [2 ] = B ;
93
101
94
102
q += 3 ;
103
+
104
+ for (j = 0 ; j < extra_bands ; j ++ )
105
+ q [j ] = VIPS_CLIP (0 , p [j ] / 255.0 , 1.0 );
106
+ p += extra_bands ;
107
+ q += extra_bands ;
108
+ }
109
+ }
110
+
111
+ static int
112
+ vips_XYZ2scRGB_gen (VipsRegion * out_region ,
113
+ void * seq , void * a , void * b , gboolean * stop )
114
+ {
115
+ VipsRegion * ir = (VipsRegion * ) seq ;
116
+ VipsRect * r = & out_region -> valid ;
117
+ VipsImage * in = ir -> im ;
118
+
119
+ int y ;
120
+
121
+ if (vips_region_prepare (ir , r ))
122
+ return -1 ;
123
+
124
+ VIPS_GATE_START ("vips_XYZ2scRGB: work" );
125
+
126
+ for (y = 0 ; y < r -> height ; y ++ ) {
127
+ float * p = (float * )
128
+ VIPS_REGION_ADDR (ir , r -> left , r -> top + y );
129
+ float * q = (float * )
130
+ VIPS_REGION_ADDR (out_region , r -> left , r -> top + y );
131
+
132
+ vips_XYZ2scRGB_line (q , p , in -> Bands - 3 , r -> width );
133
+ }
134
+
135
+ VIPS_GATE_STOP ("vips_XYZ2scRGB: work" );
136
+
137
+ return 0 ;
138
+ }
139
+
140
+ static int
141
+ vips_XYZ2scRGB_build (VipsObject * object )
142
+ {
143
+ VipsObjectClass * class = VIPS_OBJECT_GET_CLASS (object );
144
+ VipsXYZ2scRGB * XYZ2scRGB = (VipsXYZ2scRGB * ) object ;
145
+
146
+ VipsImage * * t = (VipsImage * * ) vips_object_local_array (object , 2 );
147
+
148
+ VipsImage * in ;
149
+ VipsImage * out ;
150
+
151
+ if (VIPS_OBJECT_CLASS (vips_XYZ2scRGB_parent_class )-> build (object ))
152
+ return -1 ;
153
+
154
+ in = XYZ2scRGB -> in ;
155
+ if (vips_check_bands_atleast (class -> nickname , in , 3 ))
156
+ return -1 ;
157
+
158
+ if (vips_cast_float (in , & t [0 ], NULL ))
159
+ return -1 ;
160
+ in = t [0 ];
161
+
162
+ out = vips_image_new ();
163
+ if (vips_image_pipelinev (out ,
164
+ VIPS_DEMAND_STYLE_THINSTRIP , in , NULL )) {
165
+ g_object_unref (out );
166
+ return -1 ;
167
+ }
168
+ out -> Type = VIPS_INTERPRETATION_scRGB ;
169
+ out -> BandFmt = VIPS_FORMAT_FLOAT ;
170
+
171
+ if (vips_image_generate (out ,
172
+ vips_start_one , vips_XYZ2scRGB_gen , vips_stop_one ,
173
+ in , XYZ2scRGB )) {
174
+ g_object_unref (out );
175
+ return -1 ;
95
176
}
177
+
178
+ g_object_set (object , "out" , out , NULL );
179
+
180
+ return 0 ;
96
181
}
97
182
98
183
static void
99
184
vips_XYZ2scRGB_class_init (VipsXYZ2scRGBClass * class )
100
185
{
186
+ GObjectClass * gobject_class = G_OBJECT_CLASS (class );
101
187
VipsObjectClass * object_class = (VipsObjectClass * ) class ;
102
- VipsColourClass * colour_class = VIPS_COLOUR_CLASS (class );
188
+ VipsOperationClass * operation_class = VIPS_OPERATION_CLASS (class );
189
+
190
+ gobject_class -> set_property = vips_object_set_property ;
191
+ gobject_class -> get_property = vips_object_get_property ;
103
192
104
193
object_class -> nickname = "XYZ2scRGB" ;
105
194
object_class -> description = _ ("transform XYZ to scRGB" );
195
+ object_class -> build = vips_XYZ2scRGB_build ;
196
+
197
+ operation_class -> flags = VIPS_OPERATION_SEQUENTIAL ;
106
198
107
- colour_class -> process_line = vips_XYZ2scRGB_line ;
199
+ VIPS_ARG_IMAGE (class , "in" , 1 ,
200
+ _ ("Input" ),
201
+ _ ("Input image" ),
202
+ VIPS_ARGUMENT_REQUIRED_INPUT ,
203
+ G_STRUCT_OFFSET (VipsXYZ2scRGB , in ));
204
+
205
+ VIPS_ARG_IMAGE (class , "out" , 100 ,
206
+ _ ("Output" ),
207
+ _ ("Output image" ),
208
+ VIPS_ARGUMENT_REQUIRED_OUTPUT ,
209
+ G_STRUCT_OFFSET (VipsXYZ2scRGB , out ));
108
210
}
109
211
110
212
static void
111
213
vips_XYZ2scRGB_init (VipsXYZ2scRGB * XYZ2scRGB )
112
214
{
113
- VipsColour * colour = VIPS_COLOUR (XYZ2scRGB );
114
-
115
- colour -> interpretation = VIPS_INTERPRETATION_scRGB ;
116
215
}
117
216
118
217
/**
0 commit comments