Skip to content

Commit e129bda

Browse files
committed
Add rgb64 support for spot remover filter
1 parent 5a88171 commit e129bda

2 files changed

Lines changed: 65 additions & 23 deletions

File tree

src/modules/plus/filter_spot_remover.c

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* filter_remover.c -- filter to interpolate pixels to cover an area
3-
* Copyright (c) 2018-2020 Meltytech, LLC
3+
* Copyright (c) 2018-2025 Meltytech, LLC
44
*
55
* This library is free software; you can redistribute it and/or
66
* modify it under the terms of the GNU Lesser General Public
@@ -73,9 +73,10 @@ static mlt_rect constrain_rect(mlt_rect rect, int max_x, int max_y)
7373

7474
typedef struct
7575
{
76-
uint8_t *chan[4]; // pointer to the first value in the channel
76+
void *chan[4]; // pointer to the first value in the channel
7777
int rowCount[4]; // the number of values in each line (row)
7878
int step[4]; // the space between values in each line
79+
int word[4]; // the number of bits in a word (8 or 16)
7980
mlt_rect rect[4]; // rect the area to be removed
8081
} slice_desc;
8182

@@ -90,31 +91,52 @@ static int remove_spot_channel_proc(int id, int index, int jobs, void *data)
9091
(void) id; // unused
9192
(void) jobs; // unused
9293
slice_desc *desc = ((slice_desc *) data);
93-
uint8_t *chan = desc->chan[index];
9494
int rowCount = desc->rowCount[index];
9595
int step = desc->step[index];
96+
int word = desc->word[index];
9697
mlt_rect rect = desc->rect[index];
9798
int yStop = rect.y + rect.h;
9899
int xStop = rect.x + rect.w;
99100
int rowSize = rowCount * step;
100-
int y;
101-
for (y = rect.y; y < yStop; y++) {
102-
uint8_t *xValueL = chan + (y * rowSize) + (((int) rect.x - 1) * step);
103-
uint8_t *xValueR = xValueL + ((int) rect.w * step);
104-
uint8_t *p = chan + (y * rowSize) + ((int) rect.x * step);
105-
double yRatio = 1.0 - ((y - rect.y) / rect.h);
106-
int x;
107-
for (x = rect.x; x < xStop; x++) {
108-
uint8_t *yValueT = chan + (((int) rect.y - 1) * rowSize) + (x * step);
109-
uint8_t *yValueB = yValueT + (int) rect.h * rowSize;
110-
double xRatio = 1.0 - ((x - rect.x) / rect.w);
111-
unsigned int xValueInterp = (*xValueL * xRatio) + (*xValueR * (1.0 - xRatio));
112-
unsigned int yValueInterp = (*yValueT * yRatio) + (*yValueB * (1.0 - yRatio));
113-
unsigned int value = (xValueInterp + yValueInterp) / 2;
114-
if (value > 255)
115-
value = 255;
116-
*p = value;
117-
p += step;
101+
if (word == 8) {
102+
uint8_t *chan = desc->chan[index];
103+
for (int y = rect.y; y < yStop; y++) {
104+
uint8_t *xValueL = chan + (y * rowSize) + (((int) rect.x - 1) * step);
105+
uint8_t *xValueR = xValueL + ((int) rect.w * step);
106+
uint8_t *p = chan + (y * rowSize) + ((int) rect.x * step);
107+
double yRatio = 1.0 - ((y - rect.y) / rect.h);
108+
for (int x = rect.x; x < xStop; x++) {
109+
uint8_t *yValueT = chan + (((int) rect.y - 1) * rowSize) + (x * step);
110+
uint8_t *yValueB = yValueT + (int) rect.h * rowSize;
111+
double xRatio = 1.0 - ((x - rect.x) / rect.w);
112+
unsigned int xValueInterp = (*xValueL * xRatio) + (*xValueR * (1.0 - xRatio));
113+
unsigned int yValueInterp = (*yValueT * yRatio) + (*yValueB * (1.0 - yRatio));
114+
unsigned int value = (xValueInterp + yValueInterp) / 2;
115+
if (value > 255)
116+
value = 255;
117+
*p = value;
118+
p += step;
119+
}
120+
}
121+
} else if (word == 16) {
122+
uint16_t *chan = desc->chan[index];
123+
for (int y = rect.y; y < yStop; y++) {
124+
uint16_t *xValueL = chan + (y * rowSize) + (((int) rect.x - 1) * step);
125+
uint16_t *xValueR = xValueL + ((int) rect.w * step);
126+
uint16_t *p = chan + (y * rowSize) + ((int) rect.x * step);
127+
double yRatio = 1.0 - ((y - rect.y) / rect.h);
128+
for (int x = rect.x; x < xStop; x++) {
129+
uint16_t *yValueT = chan + (((int) rect.y - 1) * rowSize) + (x * step);
130+
uint16_t *yValueB = yValueT + (int) rect.h * rowSize;
131+
double xRatio = 1.0 - ((x - rect.x) / rect.w);
132+
unsigned int xValueInterp = (*xValueL * xRatio) + (*xValueR * (1.0 - xRatio));
133+
unsigned int yValueInterp = (*yValueT * yRatio) + (*yValueB * (1.0 - yRatio));
134+
unsigned int value = (xValueInterp + yValueInterp) / 2;
135+
if (value > 65535)
136+
value = 65535;
137+
*p = value;
138+
p += step;
139+
}
118140
}
119141
}
120142
return 0;
@@ -162,6 +184,7 @@ static int filter_get_image(mlt_frame frame,
162184
case mlt_image_rgb:
163185
case mlt_image_yuv422:
164186
case mlt_image_yuv420p:
187+
case mlt_image_rgba64:
165188
// These formats are all supported
166189
break;
167190
default:
@@ -186,6 +209,7 @@ static int filter_get_image(mlt_frame frame,
186209
desc.chan[i] = img.planes[0] + i;
187210
desc.rowCount[i] = img.width;
188211
desc.step[i] = 4;
212+
desc.word[i] = 8;
189213
desc.rect[i] = rect;
190214
}
191215
break;
@@ -195,6 +219,7 @@ static int filter_get_image(mlt_frame frame,
195219
desc.chan[i] = img.planes[0] + i;
196220
desc.rowCount[i] = img.width;
197221
desc.step[i] = 4;
222+
desc.word[i] = 8;
198223
desc.rect[i] = rect;
199224
}
200225
break;
@@ -204,16 +229,19 @@ static int filter_get_image(mlt_frame frame,
204229
desc.chan[0] = img.planes[0];
205230
desc.rowCount[0] = img.width;
206231
desc.step[0] = 2;
232+
desc.word[0] = 8;
207233
desc.rect[0] = rect;
208234
// U
209235
desc.chan[1] = img.planes[0] + 1;
210236
desc.rowCount[1] = img.width / 2;
211237
desc.step[1] = 4;
238+
desc.word[1] = 8;
212239
desc.rect[1] = constrain_rect(scale_rect(rect, 2, 1), img.width / 2, img.height);
213240
// V
214241
desc.chan[2] = img.planes[0] + 3;
215242
desc.rowCount[2] = img.width / 2;
216243
desc.step[2] = 4;
244+
desc.word[2] = 8;
217245
desc.rect[2] = constrain_rect(scale_rect(rect, 2, 1), img.width / 2, img.height);
218246
break;
219247
case mlt_image_yuv420p:
@@ -222,28 +250,42 @@ static int filter_get_image(mlt_frame frame,
222250
desc.chan[0] = img.planes[0];
223251
desc.rowCount[0] = img.width;
224252
desc.step[0] = 1;
253+
desc.word[0] = 8;
225254
desc.rect[0] = rect;
226255
// U
227256
desc.chan[1] = img.planes[1];
228257
desc.rowCount[1] = img.width / 2;
229258
desc.step[1] = 1;
259+
desc.word[1] = 8;
230260
desc.rect[1] = constrain_rect(scale_rect(rect, 2, 2), img.width / 2, img.height / 2);
231261
// V
232262
desc.chan[2] = img.planes[2];
233263
desc.rowCount[2] = img.width / 2;
234264
desc.step[2] = 1;
265+
desc.word[2] = 8;
235266
desc.rect[2] = constrain_rect(scale_rect(rect, 2, 2), img.width / 2, img.height / 2);
236267
break;
268+
case mlt_image_rgba64:
269+
jobs = 4;
270+
for (i = 0; i < 4; i++) {
271+
desc.chan[i] = ((uint16_t *) img.planes[0]) + i;
272+
desc.rowCount[i] = img.width;
273+
desc.step[i] = 4;
274+
desc.word[i] = 16;
275+
desc.rect[i] = rect;
276+
}
277+
break;
237278
default:
238279
return 1;
239280
}
240281

241282
uint8_t *alpha = mlt_frame_get_alpha(frame);
242-
if (alpha && *format != mlt_image_rgba) {
283+
if (alpha && *format != mlt_image_rgba && *format != mlt_image_rgba64) {
243284
jobs++;
244285
desc.chan[3] = alpha;
245286
desc.rowCount[3] = img.width;
246287
desc.step[3] = 1;
288+
desc.word[3] = 8;
247289
desc.rect[3] = rect;
248290
}
249291

src/modules/plus/filter_spot_remover.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ schema_version: 7.0
22
type: filter
33
identifier: spot_remover
44
title: Spot Remover
5-
version: 1
5+
version: 2
66
copyright: Meltytech, LLC
77
license: LGPLv2.1
88
language: en

0 commit comments

Comments
 (0)