@@ -40,6 +40,7 @@ typedef std::map<std::string, gradient_cache> gradientmap_cache;
4040struct slice_desc
4141{
4242 mlt_image_s image;
43+ mlt_image_format format;
4344 const std::vector<mlt_color> *colors;
4445};
4546
@@ -164,10 +165,10 @@ static void compute_colors(const std::vector<stop> &gradient, std::vector<mlt_co
164165}
165166
166167static mlt_color gradient_map (
167- const std::vector<mlt_color> &colors, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
168+ const std::vector<mlt_color> &colors, float r, float g, float b, float a)
168169{
169170 // This is what Krita does, although other methods could be explored.
170- float intensity = ( r * 0.30 + g * 0.59 + b * 0.11 ) / 255 ;
171+ float intensity = r * 0.30 + g * 0.59 + b * 0.11 ;
171172 uint32_t t = intensity * colors.size () + 0.5 ;
172173 if (colors.size () > t) {
173174 mlt_color c = colors[t];
@@ -187,15 +188,37 @@ static int sliced_proc(int id, int index, int jobs, void *data)
187188 int slice_line_start,
188189 slice_height = mlt_slices_size_slice (jobs, index, desc->image .height , &slice_line_start);
189190 int slice_line_end = slice_line_start + slice_height;
190- int line_size = desc->image .strides [0 ];
191- for (int j = slice_line_start; j < slice_line_end; ++j) {
192- uint8_t *p = desc->image .planes [0 ] + j * line_size;
193- for (int i = 0 ; i < line_size; i += 4 ) {
194- mlt_color c = gradient_map (*desc->colors , p[i], p[i + 1 ], p[i + 2 ], p[i + 3 ]);
195- p[i] = c.r ;
196- p[i + 1 ] = c.g ;
197- p[i + 2 ] = c.b ;
198- p[i + 3 ] = c.a ;
191+ if (desc->format == mlt_image_rgba) {
192+ int line_size = desc->image .strides [0 ];
193+ for (int j = slice_line_start; j < slice_line_end; ++j) {
194+ uint8_t *p = desc->image .planes [0 ] + j * line_size;
195+ for (int i = 0 ; i < line_size; i += 4 ) {
196+ float r = (float ) p[i] / 255.0 ;
197+ float g = (float ) p[i + 1 ] / 255.0 ;
198+ float b = (float ) p[i + 2 ] / 255.0 ;
199+ float a = (float ) p[i + 3 ] / 255.0 ;
200+ mlt_color c = gradient_map (*desc->colors , r, g, b, a);
201+ p[i] = c.r ;
202+ p[i + 1 ] = c.g ;
203+ p[i + 2 ] = c.b ;
204+ p[i + 3 ] = c.a ;
205+ }
206+ }
207+ } else if (desc->format == mlt_image_rgba64) {
208+ int line_size = desc->image .strides [0 ] / 2 ; // two bytes per word
209+ for (int j = slice_line_start; j < slice_line_end; ++j) {
210+ uint16_t *p = (uint16_t *) desc->image .planes [0 ] + j * line_size;
211+ for (int i = 0 ; i < line_size; i += 4 ) {
212+ float r = (float ) p[i] / 65535.0 ;
213+ float g = (float ) p[i + 1 ] / 65535.0 ;
214+ float b = (float ) p[i + 2 ] / 65535.0 ;
215+ float a = (float ) p[i + 3 ] / 65535.0 ;
216+ mlt_color c = gradient_map (*desc->colors , r, g, b, a);
217+ p[i] = (uint16_t ) c.r * 257 ;
218+ p[i + 1 ] = (uint16_t ) c.g * 257 ;
219+ p[i + 2 ] = (uint16_t ) c.b * 257 ;
220+ p[i + 3 ] = (uint16_t ) c.a * 257 ;
221+ }
199222 }
200223 }
201224 return 0 ;
@@ -211,7 +234,8 @@ static int filter_get_image(mlt_frame frame,
211234 mlt_filter filter = reinterpret_cast <mlt_filter>(mlt_frame_pop_service (frame));
212235 gradientmap_cache *cache = reinterpret_cast <gradientmap_cache *>(filter->child );
213236
214- *format = mlt_image_rgba;
237+ if (*format != mlt_image_rgba64)
238+ *format = mlt_image_rgba;
215239 int error = mlt_frame_get_image (frame, image, format, width, height, 1 );
216240
217241 if (error == 0 ) {
@@ -235,6 +259,7 @@ static int filter_get_image(mlt_frame frame,
235259
236260 slice_desc desc;
237261 desc.colors = &colors;
262+ desc.format = *format;
238263 mlt_image_set_values (&desc.image , *image, *format, *width, *height);
239264 mlt_slices_run_normal (0 , sliced_proc, &desc);
240265 }
0 commit comments