47 #define ZIMG_ALIGNMENT 64
48 #define MIN_TILESIZE 64
49 #define MAX_THREADS 64
139 zimg_image_format_default(&
s->src_format, ZIMG_API_VERSION);
140 zimg_image_format_default(&
s->dst_format, ZIMG_API_VERSION);
141 zimg_image_format_default(&
s->src_format_tmp, ZIMG_API_VERSION);
142 zimg_image_format_default(&
s->dst_format_tmp, ZIMG_API_VERSION);
144 zimg_graph_builder_params_default(&
s->params, ZIMG_API_VERSION);
145 zimg_graph_builder_params_default(&
s->params_tmp, ZIMG_API_VERSION);
147 if (
s->size_str && (
s->w_expr ||
s->h_expr)) {
149 "Size and width/height expressions cannot be set at the same time.\n");
153 if (
s->w_expr && !
s->h_expr)
154 FFSWAP(
char *,
s->w_expr,
s->size_str);
160 "Invalid size '%s'\n",
s->size_str);
163 snprintf(buf,
sizeof(buf)-1,
"%d",
s->w);
165 snprintf(buf,
sizeof(buf)-1,
"%d",
s->h);
222 formats =
s->colorspace != ZIMG_MATRIX_UNSPECIFIED &&
s->colorspace > 0
243 s->out_slice_start[0] = 0;
244 for (
int i = 1;
i <
s->nb_threads;
i++) {
248 s->out_slice_end[
s->nb_threads - 1] = out_h;
250 for (
int i = 0;
i <
s->nb_threads;
i++) {
251 s->in_slice_start[
i] =
s->out_slice_start[
i] * in_h / (
double)out_h;
252 s->in_slice_end[
i] =
s->out_slice_end[
i] * in_h / (
double)out_h;
264 double var_values[
VARS_NB], res;
267 int factor_w, factor_h;
275 (
double)
inlink->sample_aspect_ratio.num /
inlink->sample_aspect_ratio.den : 1;
331 if (
s->force_original_aspect_ratio) {
335 if (
s->force_original_aspect_ratio == 1) {
344 if (
w > INT_MAX ||
h > INT_MAX ||
354 if (
inlink->sample_aspect_ratio.num){
359 av_log(
ctx,
AV_LOG_DEBUG,
"w:%d h:%d fmt:%s csp:%s range:%s sar:%d/%d -> w:%d h:%d fmt:%s csp:%s range:%s sar:%d/%d\n",
362 inlink->sample_aspect_ratio.num,
inlink->sample_aspect_ratio.den,
370 "Error when evaluating the expression '%s'.\n"
371 "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
372 expr,
s->w_expr,
s->h_expr);
379 int err_code = zimg_get_last_error(err_msg,
sizeof(err_msg));
388 switch (chroma_location) {
391 return ZIMG_CHROMA_LEFT;
393 return ZIMG_CHROMA_CENTER;
395 return ZIMG_CHROMA_TOP_LEFT;
397 return ZIMG_CHROMA_TOP;
399 return ZIMG_CHROMA_BOTTOM_LEFT;
401 return ZIMG_CHROMA_BOTTOM;
403 return ZIMG_CHROMA_LEFT;
408 switch (colorspace) {
410 return ZIMG_MATRIX_RGB;
412 return ZIMG_MATRIX_709;
414 return ZIMG_MATRIX_UNSPECIFIED;
416 return ZIMG_MATRIX_FCC;
418 return ZIMG_MATRIX_470BG;
420 return ZIMG_MATRIX_170M;
422 return ZIMG_MATRIX_240M;
424 return ZIMG_MATRIX_YCGCO;
426 return ZIMG_MATRIX_2020_NCL;
428 return ZIMG_MATRIX_2020_CL;
430 return ZIMG_MATRIX_CHROMATICITY_DERIVED_NCL;
432 return ZIMG_MATRIX_CHROMATICITY_DERIVED_CL;
434 return ZIMG_MATRIX_ICTCP;
436 return ZIMG_MATRIX_UNSPECIFIED;
443 return ZIMG_TRANSFER_UNSPECIFIED;
445 return ZIMG_TRANSFER_709;
447 return ZIMG_TRANSFER_470_M;
449 return ZIMG_TRANSFER_470_BG;
451 return ZIMG_TRANSFER_601;
453 return ZIMG_TRANSFER_240M;
455 return ZIMG_TRANSFER_LINEAR;
457 return ZIMG_TRANSFER_LOG_100;
459 return ZIMG_TRANSFER_LOG_316;
461 return ZIMG_TRANSFER_IEC_61966_2_4;
463 return ZIMG_TRANSFER_2020_10;
465 return ZIMG_TRANSFER_2020_12;
467 return ZIMG_TRANSFER_ST2084;
469 return ZIMG_TRANSFER_ARIB_B67;
471 return ZIMG_TRANSFER_IEC_61966_2_1;
473 return ZIMG_TRANSFER_UNSPECIFIED;
480 return ZIMG_PRIMARIES_UNSPECIFIED;
482 return ZIMG_PRIMARIES_709;
484 return ZIMG_PRIMARIES_470_M;
486 return ZIMG_PRIMARIES_470_BG;
488 return ZIMG_PRIMARIES_170M;
490 return ZIMG_PRIMARIES_240M;
492 return ZIMG_PRIMARIES_FILM;
494 return ZIMG_PRIMARIES_2020;
496 return ZIMG_PRIMARIES_ST428;
498 return ZIMG_PRIMARIES_ST431_2;
500 return ZIMG_PRIMARIES_ST432_1;
502 return ZIMG_PRIMARIES_EBU3213_E;
504 return ZIMG_PRIMARIES_UNSPECIFIED;
512 return ZIMG_RANGE_LIMITED;
514 return ZIMG_RANGE_FULL;
516 return ZIMG_RANGE_LIMITED;
522 case ZIMG_RANGE_LIMITED:
524 case ZIMG_RANGE_FULL:
533 return ((img_fmt0->chroma_location != img_fmt1->chroma_location) ||
534 #
if ZIMG_API_VERSION >= 0x204
535 (img_fmt0->alpha != img_fmt1->alpha) ||
537 (img_fmt0->color_family != img_fmt1->color_family) ||
538 (img_fmt0->color_primaries != img_fmt1->color_primaries) ||
539 (img_fmt0->depth != img_fmt1->depth) ||
540 (img_fmt0->field_parity != img_fmt1->field_parity) ||
541 (img_fmt0->height != img_fmt1->height) ||
542 (img_fmt0->matrix_coefficients != img_fmt1->matrix_coefficients) ||
543 (img_fmt0->pixel_range != img_fmt1->pixel_range) ||
544 (img_fmt0->pixel_type != img_fmt1->pixel_type) ||
545 (img_fmt0->subsample_h != img_fmt1->subsample_h) ||
546 (img_fmt0->subsample_w != img_fmt1->subsample_w) ||
547 (img_fmt0->transfer_characteristics != img_fmt1->transfer_characteristics) ||
548 (img_fmt0->width != img_fmt1->width));
556 int ret = (parm0->allow_approximate_gamma != parm1->allow_approximate_gamma) ||
557 (parm0->dither_type != parm1->dither_type) ||
558 (parm0->resample_filter != parm1->resample_filter) ||
559 (parm0->resample_filter_uv != parm1->resample_filter_uv);
561 if ((
isnan(parm0->nominal_peak_luminance) == 0) || (
isnan(parm1->nominal_peak_luminance) == 0))
562 ret =
ret || (parm0->nominal_peak_luminance != parm1->nominal_peak_luminance);
563 if ((
isnan(parm0->filter_param_a) == 0) || (
isnan(parm1->filter_param_a) == 0))
564 ret =
ret || (parm0->filter_param_a != parm1->filter_param_a);
565 if ((
isnan(parm0->filter_param_a_uv) == 0) || (
isnan(parm1->filter_param_a_uv) == 0))
566 ret =
ret || (parm0->filter_param_a_uv != parm1->filter_param_a_uv);
567 if ((
isnan(parm0->filter_param_b) == 0) || (
isnan(parm1->filter_param_b) == 0))
568 ret =
ret || (parm0->filter_param_b != parm1->filter_param_b);
569 if ((
isnan(parm0->filter_param_b_uv) == 0) || (
isnan(parm1->filter_param_b_uv) == 0))
570 ret =
ret || (parm0->filter_param_b_uv != parm1->filter_param_b_uv);
584 : (
desc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE);
586 : (
desc->nb_components > 1 ? ZIMG_COLOR_YUV : ZIMG_COLOR_GREY);
602 zimg_image_format src_format;
603 zimg_image_format dst_format;
604 const double in_slice_start =
s->in_slice_start[job_nr];
605 const double in_slice_end =
s->in_slice_end[job_nr];
606 const int out_slice_start =
s->out_slice_start[job_nr];
607 const int out_slice_end =
s->out_slice_end[job_nr];
609 src_format =
s->src_format;
610 dst_format =
s->dst_format;
614 src_format.active_region.width = in->
width;
615 src_format.active_region.height = in_slice_end - in_slice_start;
616 src_format.active_region.left = 0;
617 src_format.active_region.top = in_slice_start;
619 dst_format.width =
out->width;
620 dst_format.height = out_slice_end - out_slice_start;
622 if (
s->graph[job_nr]) {
623 zimg_filter_graph_free(
s->graph[job_nr]);
625 s->graph[job_nr] = zimg_filter_graph_build(&src_format, &dst_format, &
s->params);
626 if (!
s->graph[job_nr])
629 ret = zimg_filter_graph_get_tmp_size(
s->graph[job_nr], &
size);
652 for (plane = 0; plane <
planes; plane++) {
653 int p =
desc->comp[plane].plane;
678 if (
s->primaries != -1)
679 frame->color_primaries = (int)
s->dst_format.color_primaries;
682 frame->color_trc = (int)
s->dst_format.transfer_characteristics;
684 if (
s->chromal != -1)
685 frame->chroma_location = (int)
s->dst_format.chroma_location + 1;
695 zimg_image_buffer_const src_buf = { ZIMG_API_VERSION };
696 zimg_image_buffer dst_buf = { ZIMG_API_VERSION };
697 const int out_slice_start =
s->out_slice_start[job_nr];
710 for (
int i = 0;
i < 4;
i++) {
715 if (i < td->
desc->nb_components) {
716 src_buf.plane[
i].data = td->
in->
data[p];
718 src_buf.plane[
i].mask = -1;
722 if (i < td->odesc->nb_components) {
723 dst_buf.plane[
i].data = td->
out->
data[p] + td->
out->
linesize[p] * (out_slice_start >> vsamp);
725 dst_buf.plane[
i].mask = -1;
728 if (!
s->graph[job_nr])
730 ret = zimg_filter_graph_process(
s->graph[job_nr], &src_buf, &dst_buf,
747 int ret = 0, changed = 0;
754 (
link->w != outlink->
w) ||
755 (
link->h != outlink->
h) ||
759 (
s->src_format.chroma_location !=
s->dst_format.chroma_location) ||
760 (
s->src_format.color_family !=
s->dst_format.color_family) ||
761 (
s->src_format.color_primaries !=
s->dst_format.color_primaries) ||
762 (
s->src_format.depth !=
s->dst_format.depth) ||
763 (
s->src_format.matrix_coefficients !=
s->dst_format.matrix_coefficients) ||
764 (
s->src_format.field_parity !=
s->dst_format.field_parity) ||
765 (
s->src_format.pixel_range !=
s->dst_format.pixel_range) ||
766 (
s->src_format.pixel_type !=
s->dst_format.pixel_type) ||
767 (
s->src_format.transfer_characteristics !=
s->dst_format.transfer_characteristics)
782 snprintf(buf,
sizeof(buf)-1,
"%d", outlink->
w);
784 snprintf(buf,
sizeof(buf)-1,
"%d", outlink->
h);
796 zimg_image_format_default(&
s->src_format, ZIMG_API_VERSION);
797 zimg_image_format_default(&
s->dst_format, ZIMG_API_VERSION);
798 zimg_graph_builder_params_default(&
s->params, ZIMG_API_VERSION);
801 s->primaries_in,
s->trc_in,
s->range_in,
s->chromal_in);
803 s->primaries,
s->trc,
s->range,
s->chromal);
806 s->params.dither_type =
s->dither;
807 s->params.cpu_type = ZIMG_CPU_AUTO_64B;
808 s->params.resample_filter =
s->filter;
809 s->params.resample_filter_uv =
s->filter;
810 s->params.nominal_peak_luminance =
s->nominal_peak_luminance;
811 s->params.allow_approximate_gamma =
s->approximate_gamma;
812 s->params.filter_param_a =
s->params.filter_param_a_uv =
s->param_a;
813 s->params.filter_param_b =
s->params.filter_param_b_uv =
s->param_b;
816 av_reduce(&
out->sample_aspect_ratio.num, &
out->sample_aspect_ratio.den,
832 memset(
s->jobs_ret, 0,
s->nb_threads *
sizeof(*
s->jobs_ret));
834 for (
int i = 0;
ret >= 0 &&
i <
s->nb_threads;
i++)
835 if (
s->jobs_ret[
i] < 0)
836 ret =
s->jobs_ret[
i];
843 s->src_format_tmp =
s->src_format;
844 s->dst_format_tmp =
s->dst_format;
845 s->params_tmp =
s->params;
850 const uint16_t h_one = 0x3C00;
851 for (y = 0; y <
out->height; y++) {
852 const ptrdiff_t row = y *
out->linesize[3];
854 for (x = 0; x <
out->width; x++) {
858 for (x = 0; x <
out->width; x++) {
863 }
else if (
s->dst_format.depth == 8) {
864 for (y = 0; y < outlink->
h; y++)
865 memset(
out->data[3] + y *
out->linesize[3], 0xff, outlink->
w);
867 const uint16_t
max = (1 <<
s->dst_format.depth) - 1;
868 for (y = 0; y < outlink->
h; y++) {
869 const ptrdiff_t row = y *
out->linesize[3];
870 for (x = 0; x <
out->width; x++)
893 for (
int i = 0;
i <
s->nb_threads;
i++) {
896 zimg_filter_graph_free(
s->graph[
i]);
903 char *res,
int res_len,
int flags)
908 if ( !strcmp(cmd,
"width") || !strcmp(cmd,
"w")
909 || !strcmp(cmd,
"height") || !strcmp(cmd,
"h")) {
926 #define OFFSET(x) offsetof(ZScaleContext, x)
927 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
928 #define TFLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
942 {
"error_diffusion", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_DITHER_ERROR_DIFFUSION}, 0, 0,
FLAGS, .unit =
"dither" },
964 {
"unspecified", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_PRIMARIES_UNSPECIFIED}, 0, 0,
FLAGS, .unit =
"primaries" },
968 {
"unknown", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_PRIMARIES_UNSPECIFIED}, 0, 0,
FLAGS, .unit =
"primaries" },
977 {
"smpte431", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_PRIMARIES_ST431_2}, 0, 0,
FLAGS, .unit =
"primaries" },
978 {
"smpte432", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_PRIMARIES_ST432_1}, 0, 0,
FLAGS, .unit =
"primaries" },
979 {
"jedec-p22", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_PRIMARIES_EBU3213_E}, 0, 0,
FLAGS, .unit =
"primaries" },
980 {
"ebu3213", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_PRIMARIES_EBU3213_E}, 0, 0,
FLAGS, .unit =
"primaries" },
981 {
"transfer",
"set transfer characteristic",
OFFSET(trc),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS, .unit =
"transfer" },
985 {
"unspecified", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_TRANSFER_UNSPECIFIED}, 0, 0,
FLAGS, .unit =
"transfer" },
990 {
"unknown", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_TRANSFER_UNSPECIFIED}, 0, 0,
FLAGS, .unit =
"transfer" },
999 {
"bt2020-10", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_TRANSFER_2020_10}, 0, 0,
FLAGS, .unit =
"transfer" },
1000 {
"bt2020-12", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_TRANSFER_2020_12}, 0, 0,
FLAGS, .unit =
"transfer" },
1001 {
"smpte2084", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_TRANSFER_ST2084}, 0, 0,
FLAGS, .unit =
"transfer" },
1002 {
"iec61966-2-4", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_TRANSFER_IEC_61966_2_4},0, 0,
FLAGS, .unit =
"transfer" },
1003 {
"iec61966-2-1", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_TRANSFER_IEC_61966_2_1},0, 0,
FLAGS, .unit =
"transfer" },
1004 {
"arib-std-b67", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_TRANSFER_ARIB_B67}, 0, 0,
FLAGS, .unit =
"transfer" },
1005 {
"matrix",
"set colorspace matrix",
OFFSET(colorspace),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS, .unit =
"matrix" },
1009 {
"unspecified", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_MATRIX_UNSPECIFIED}, 0, 0,
FLAGS, .unit =
"matrix" },
1024 {
"chroma-derived-nc",0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_MATRIX_CHROMATICITY_DERIVED_NCL}, 0, 0,
FLAGS, .unit =
"matrix" },
1025 {
"chroma-derived-c", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_MATRIX_CHROMATICITY_DERIVED_CL}, 0, 0,
FLAGS, .unit =
"matrix" },
1027 {
"in_range",
"set input color range",
OFFSET(range_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_RANGE_FULL,
FLAGS, .unit =
"range" },
1028 {
"rangein",
"set input color range",
OFFSET(range_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_RANGE_FULL,
FLAGS, .unit =
"range" },
1029 {
"rin",
"set input color range",
OFFSET(range_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_RANGE_FULL,
FLAGS, .unit =
"range" },
1030 {
"primariesin",
"set input color primaries",
OFFSET(primaries_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS, .unit =
"primaries" },
1031 {
"pin",
"set input color primaries",
OFFSET(primaries_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS, .unit =
"primaries" },
1032 {
"transferin",
"set input transfer characteristic",
OFFSET(trc_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS, .unit =
"transfer" },
1033 {
"tin",
"set input transfer characteristic",
OFFSET(trc_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS, .unit =
"transfer" },
1034 {
"matrixin",
"set input colorspace matrix",
OFFSET(colorspace_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS, .unit =
"matrix" },
1035 {
"min",
"set input colorspace matrix",
OFFSET(colorspace_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS, .unit =
"matrix" },
1036 {
"chromal",
"set output chroma location",
OFFSET(chromal),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM,
FLAGS, .unit =
"chroma" },
1037 {
"c",
"set output chroma location",
OFFSET(chromal),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM,
FLAGS, .unit =
"chroma" },
1043 {
"bottomleft",0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_CHROMA_BOTTOM_LEFT}, 0, 0,
FLAGS, .unit =
"chroma" },
1045 {
"chromalin",
"set input chroma location",
OFFSET(chromal_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM,
FLAGS, .unit =
"chroma" },
1046 {
"cin",
"set input chroma location",
OFFSET(chromal_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM,
FLAGS, .unit =
"chroma" },
1049 {
"param_a",
"parameter A, which is parameter \"b\" for bicubic, "
1076 .p.priv_class = &zscale_class,