+static int filter_slice_packed(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+ int x, y;
+ const CurvesContext *curves = ctx->priv;
+ const ThreadData *td = arg;
+ const AVFrame *in = td->in;
+ const AVFrame *out = td->out;
+ const int direct = out == in;
+ const int step = curves->step;
+ const uint8_t r = curves->rgba_map[R];
+ const uint8_t g = curves->rgba_map[G];
+ const uint8_t b = curves->rgba_map[B];
+ const uint8_t a = curves->rgba_map[A];
+ const int slice_start = (in->height * jobnr ) / nb_jobs;
+ const int slice_end = (in->height * (jobnr+1)) / nb_jobs;
+
+ if (curves->is_16bit) {
+ for (y = slice_start; y < slice_end; y++) {
+ uint16_t *dstp = ( uint16_t *)(out->data[0] + y * out->linesize[0]);
+ const uint16_t *srcp = (const uint16_t *)(in ->data[0] + y * in->linesize[0]);
+
+ for (x = 0; x < in->width * step; x += step) {
+ dstp[x + r] = curves->graph[R][srcp[x + r]];
+ dstp[x + g] = curves->graph[G][srcp[x + g]];
+ dstp[x + b] = curves->graph[B][srcp[x + b]];
+ if (!direct && step == 4)
+ dstp[x + a] = srcp[x + a];
+ }
+ }
+ } else {
+ uint8_t *dst = out->data[0] + slice_start * out->linesize[0];
+ const uint8_t *src = in->data[0] + slice_start * in->linesize[0];
+
+ for (y = slice_start; y < slice_end; y++) {
+ for (x = 0; x < in->width * step; x += step) {
+ dst[x + r] = curves->graph[R][src[x + r]];
+ dst[x + g] = curves->graph[G][src[x + g]];
+ dst[x + b] = curves->graph[B][src[x + b]];
+ if (!direct && step == 4)
+ dst[x + a] = src[x + a];
+ }
+ dst += out->linesize[0];
+ src += in ->linesize[0];
+ }
+ }
+ return 0;
+}
+
+static int filter_slice_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+ int x, y;
+ const CurvesContext *curves = ctx->priv;
+ const ThreadData *td = arg;
+ const AVFrame *in = td->in;
+ const AVFrame *out = td->out;
+ const int direct = out == in;
+ const int step = curves->step;
+ const uint8_t r = curves->rgba_map[R];
+ const uint8_t g = curves->rgba_map[G];
+ const uint8_t b = curves->rgba_map[B];
+ const uint8_t a = curves->rgba_map[A];
+ const int slice_start = (in->height * jobnr ) / nb_jobs;
+ const int slice_end = (in->height * (jobnr+1)) / nb_jobs;
+
+ if (curves->is_16bit) {
+ for (y = slice_start; y < slice_end; y++) {
+ uint16_t *dstrp = ( uint16_t *)(out->data[r] + y * out->linesize[r]);
+ uint16_t *dstgp = ( uint16_t *)(out->data[g] + y * out->linesize[g]);
+ uint16_t *dstbp = ( uint16_t *)(out->data[b] + y * out->linesize[b]);
+ uint16_t *dstap = ( uint16_t *)(out->data[a] + y * out->linesize[a]);
+ const uint16_t *srcrp = (const uint16_t *)(in ->data[r] + y * in->linesize[r]);
+ const uint16_t *srcgp = (const uint16_t *)(in ->data[g] + y * in->linesize[g]);
+ const uint16_t *srcbp = (const uint16_t *)(in ->data[b] + y * in->linesize[b]);
+ const uint16_t *srcap = (const uint16_t *)(in ->data[a] + y * in->linesize[a]);
+
+ for (x = 0; x < in->width; x++) {
+ dstrp[x] = curves->graph[R][srcrp[x]];
+ dstgp[x] = curves->graph[G][srcgp[x]];
+ dstbp[x] = curves->graph[B][srcbp[x]];
+ if (!direct && step == 4)
+ dstap[x] = srcap[x];
+ }
+ }
+ } else {
+ uint8_t *dstr = out->data[r] + slice_start * out->linesize[r];
+ uint8_t *dstg = out->data[g] + slice_start * out->linesize[g];
+ uint8_t *dstb = out->data[b] + slice_start * out->linesize[b];
+ uint8_t *dsta = out->data[a] + slice_start * out->linesize[a];
+ const uint8_t *srcr = in->data[r] + slice_start * in->linesize[r];
+ const uint8_t *srcg = in->data[g] + slice_start * in->linesize[g];
+ const uint8_t *srcb = in->data[b] + slice_start * in->linesize[b];
+ const uint8_t *srca = in->data[a] + slice_start * in->linesize[a];
+
+ for (y = slice_start; y < slice_end; y++) {
+ for (x = 0; x < in->width; x++) {
+ dstr[x] = curves->graph[R][srcr[x]];
+ dstg[x] = curves->graph[G][srcg[x]];
+ dstb[x] = curves->graph[B][srcb[x]];
+ if (!direct && step == 4)
+ dsta[x] = srca[x];
+ }
+ dstr += out->linesize[r];
+ dstg += out->linesize[g];
+ dstb += out->linesize[b];
+ dsta += out->linesize[a];
+ srcr += in ->linesize[r];
+ srcg += in ->linesize[g];
+ srcb += in ->linesize[b];
+ srca += in ->linesize[a];
+ }
+ }
+ return 0;
+}
+