47 #define ZIMG_ALIGNMENT 64
48 #define MIN_TILESIZE 64
49 #define MAX_THREADS 64
152 zimg_image_format_default(&
s->src_format, ZIMG_API_VERSION);
153 zimg_image_format_default(&
s->dst_format, ZIMG_API_VERSION);
154 zimg_image_format_default(&
s->src_format_tmp, ZIMG_API_VERSION);
155 zimg_image_format_default(&
s->dst_format_tmp, ZIMG_API_VERSION);
157 zimg_image_format_default(&
s->alpha_src_format, ZIMG_API_VERSION);
158 zimg_image_format_default(&
s->alpha_dst_format, ZIMG_API_VERSION);
159 zimg_image_format_default(&
s->alpha_src_format_tmp, ZIMG_API_VERSION);
160 zimg_image_format_default(&
s->alpha_dst_format_tmp, ZIMG_API_VERSION);
162 zimg_graph_builder_params_default(&
s->params, ZIMG_API_VERSION);
163 zimg_graph_builder_params_default(&
s->params_tmp, ZIMG_API_VERSION);
164 zimg_graph_builder_params_default(&
s->alpha_params, ZIMG_API_VERSION);
165 zimg_graph_builder_params_default(&
s->alpha_params_tmp, ZIMG_API_VERSION);
167 if (
s->size_str && (
s->w_expr ||
s->h_expr)) {
169 "Size and width/height expressions cannot be set at the same time.\n");
173 if (
s->w_expr && !
s->h_expr)
174 FFSWAP(
char *,
s->w_expr,
s->size_str);
180 "Invalid size '%s'\n",
s->size_str);
183 snprintf(buf,
sizeof(buf)-1,
"%d",
s->w);
185 snprintf(buf,
sizeof(buf)-1,
"%d",
s->h);
230 s->out_slice_start[0] = 0;
231 for (
int i = 1;
i <
s->nb_threads;
i++) {
235 s->out_slice_end[
s->nb_threads - 1] = out_h;
237 for (
int i = 0;
i <
s->nb_threads;
i++) {
238 s->in_slice_start[
i] =
s->out_slice_start[
i] * in_h / (
double)out_h;
239 s->in_slice_end[
i] =
s->out_slice_end[
i] * in_h / (
double)out_h;
251 double var_values[
VARS_NB], res;
254 int factor_w, factor_h;
262 (
double)
inlink->sample_aspect_ratio.num /
inlink->sample_aspect_ratio.den : 1;
318 if (
s->force_original_aspect_ratio) {
322 if (
s->force_original_aspect_ratio == 1) {
331 if (
w > INT_MAX ||
h > INT_MAX ||
341 if (
inlink->sample_aspect_ratio.num){
348 inlink->sample_aspect_ratio.num,
inlink->sample_aspect_ratio.den,
355 "Error when evaluating the expression '%s'.\n"
356 "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
357 expr,
s->w_expr,
s->h_expr);
364 int err_code = zimg_get_last_error(err_msg,
sizeof(err_msg));
373 switch (chroma_location) {
376 return ZIMG_CHROMA_LEFT;
378 return ZIMG_CHROMA_CENTER;
380 return ZIMG_CHROMA_TOP_LEFT;
382 return ZIMG_CHROMA_TOP;
384 return ZIMG_CHROMA_BOTTOM_LEFT;
386 return ZIMG_CHROMA_BOTTOM;
388 return ZIMG_CHROMA_LEFT;
393 switch (colorspace) {
395 return ZIMG_MATRIX_RGB;
397 return ZIMG_MATRIX_709;
399 return ZIMG_MATRIX_UNSPECIFIED;
401 return ZIMG_MATRIX_FCC;
403 return ZIMG_MATRIX_470BG;
405 return ZIMG_MATRIX_170M;
407 return ZIMG_MATRIX_240M;
409 return ZIMG_MATRIX_YCGCO;
411 return ZIMG_MATRIX_2020_NCL;
413 return ZIMG_MATRIX_2020_CL;
415 return ZIMG_MATRIX_CHROMATICITY_DERIVED_NCL;
417 return ZIMG_MATRIX_CHROMATICITY_DERIVED_CL;
419 return ZIMG_MATRIX_ICTCP;
421 return ZIMG_MATRIX_UNSPECIFIED;
428 return ZIMG_TRANSFER_UNSPECIFIED;
430 return ZIMG_TRANSFER_709;
432 return ZIMG_TRANSFER_470_M;
434 return ZIMG_TRANSFER_470_BG;
436 return ZIMG_TRANSFER_601;
438 return ZIMG_TRANSFER_240M;
440 return ZIMG_TRANSFER_LINEAR;
442 return ZIMG_TRANSFER_LOG_100;
444 return ZIMG_TRANSFER_LOG_316;
446 return ZIMG_TRANSFER_IEC_61966_2_4;
448 return ZIMG_TRANSFER_2020_10;
450 return ZIMG_TRANSFER_2020_12;
452 return ZIMG_TRANSFER_ST2084;
454 return ZIMG_TRANSFER_ARIB_B67;
456 return ZIMG_TRANSFER_IEC_61966_2_1;
458 return ZIMG_TRANSFER_UNSPECIFIED;
465 return ZIMG_PRIMARIES_UNSPECIFIED;
467 return ZIMG_PRIMARIES_709;
469 return ZIMG_PRIMARIES_470_M;
471 return ZIMG_PRIMARIES_470_BG;
473 return ZIMG_PRIMARIES_170M;
475 return ZIMG_PRIMARIES_240M;
477 return ZIMG_PRIMARIES_FILM;
479 return ZIMG_PRIMARIES_2020;
481 return ZIMG_PRIMARIES_ST428;
483 return ZIMG_PRIMARIES_ST431_2;
485 return ZIMG_PRIMARIES_ST432_1;
487 return ZIMG_PRIMARIES_EBU3213_E;
489 return ZIMG_PRIMARIES_UNSPECIFIED;
497 return ZIMG_RANGE_LIMITED;
499 return ZIMG_RANGE_FULL;
501 return ZIMG_RANGE_LIMITED;
507 case ZIMG_RANGE_LIMITED:
509 case ZIMG_RANGE_FULL:
518 return ((img_fmt0->chroma_location != img_fmt1->chroma_location) ||
519 #
if ZIMG_API_VERSION >= 0x204
520 (img_fmt0->alpha != img_fmt1->alpha) ||
522 (img_fmt0->color_family != img_fmt1->color_family) ||
523 (img_fmt0->color_primaries != img_fmt1->color_primaries) ||
524 (img_fmt0->depth != img_fmt1->depth) ||
525 (img_fmt0->field_parity != img_fmt1->field_parity) ||
526 (img_fmt0->height != img_fmt1->height) ||
527 (img_fmt0->matrix_coefficients != img_fmt1->matrix_coefficients) ||
528 (img_fmt0->pixel_range != img_fmt1->pixel_range) ||
529 (img_fmt0->pixel_type != img_fmt1->pixel_type) ||
530 (img_fmt0->subsample_h != img_fmt1->subsample_h) ||
531 (img_fmt0->subsample_w != img_fmt1->subsample_w) ||
532 (img_fmt0->transfer_characteristics != img_fmt1->transfer_characteristics) ||
533 (img_fmt0->width != img_fmt1->width));
541 int ret = (parm0->allow_approximate_gamma != parm1->allow_approximate_gamma) ||
542 (parm0->dither_type != parm1->dither_type) ||
543 (parm0->resample_filter != parm1->resample_filter) ||
544 (parm0->resample_filter_uv != parm1->resample_filter_uv);
546 if ((
isnan(parm0->nominal_peak_luminance) == 0) || (
isnan(parm1->nominal_peak_luminance) == 0))
547 ret =
ret || (parm0->nominal_peak_luminance != parm1->nominal_peak_luminance);
548 if ((
isnan(parm0->filter_param_a) == 0) || (
isnan(parm1->filter_param_a) == 0))
549 ret =
ret || (parm0->filter_param_a != parm1->filter_param_a);
550 if ((
isnan(parm0->filter_param_a_uv) == 0) || (
isnan(parm1->filter_param_a_uv) == 0))
551 ret =
ret || (parm0->filter_param_a_uv != parm1->filter_param_a_uv);
552 if ((
isnan(parm0->filter_param_b) == 0) || (
isnan(parm1->filter_param_b) == 0))
553 ret =
ret || (parm0->filter_param_b != parm1->filter_param_b);
554 if ((
isnan(parm0->filter_param_b_uv) == 0) || (
isnan(parm1->filter_param_b_uv) == 0))
555 ret =
ret || (parm0->filter_param_b_uv != parm1->filter_param_b_uv);
561 int colorspace,
int primaries,
int transfer,
int range,
int location)
583 zimg_image_format src_format;
584 zimg_image_format dst_format;
585 zimg_image_format alpha_src_format;
586 zimg_image_format alpha_dst_format;
587 const double in_slice_start =
s->in_slice_start[job_nr];
588 const double in_slice_end =
s->in_slice_end[job_nr];
589 const int out_slice_start =
s->out_slice_start[job_nr];
590 const int out_slice_end =
s->out_slice_end[job_nr];
592 src_format =
s->src_format;
593 dst_format =
s->dst_format;
597 src_format.active_region.width = in->
width;
598 src_format.active_region.height = in_slice_end - in_slice_start;
599 src_format.active_region.left = 0;
600 src_format.active_region.top = in_slice_start;
602 dst_format.width =
out->width;
603 dst_format.height = out_slice_end - out_slice_start;
605 if (
s->graph[job_nr]) {
606 zimg_filter_graph_free(
s->graph[job_nr]);
608 s->graph[job_nr] = zimg_filter_graph_build(&src_format, &dst_format, &
s->params);
609 if (!
s->graph[job_nr])
612 ret = zimg_filter_graph_get_tmp_size(
s->graph[job_nr], &
size);
623 alpha_src_format =
s->alpha_src_format;
624 alpha_dst_format =
s->alpha_dst_format;
627 alpha_src_format.active_region.width = in->
width;
628 alpha_src_format.active_region.height = in_slice_end - in_slice_start;
629 alpha_src_format.active_region.left = 0;
630 alpha_src_format.active_region.top = in_slice_start;
632 alpha_dst_format.width =
out->width;
633 alpha_dst_format.height = out_slice_end - out_slice_start;
635 if (
s->alpha_graph[job_nr]) {
636 zimg_filter_graph_free(
s->alpha_graph[job_nr]);
638 s->alpha_graph[job_nr] = zimg_filter_graph_build(&alpha_src_format, &alpha_dst_format, &
s->alpha_params);
639 if (!
s->alpha_graph[job_nr])
652 for (plane = 0; plane <
planes; plane++) {
653 int p =
desc->comp[plane].plane;
660 aligned->format = (*frame)->format;
661 aligned->width = (*frame)->width;
662 aligned->height = (*frame)->height;
686 if (
s->colorspace != -1)
687 frame->colorspace = (
int)
s->dst_format.matrix_coefficients;
689 if (
s->primaries != -1)
690 frame->color_primaries = (
int)
s->dst_format.color_primaries;
696 frame->color_trc = (
int)
s->dst_format.transfer_characteristics;
698 if (
s->chromal != -1)
699 frame->chroma_location = (
int)
s->dst_format.chroma_location + 1;
709 zimg_image_buffer_const src_buf = { ZIMG_API_VERSION };
710 zimg_image_buffer dst_buf = { ZIMG_API_VERSION };
711 const int out_slice_start =
s->out_slice_start[job_nr];
728 for (
int i = 0;
i < 3;
i++) {
729 const int vsamp =
i >= 1 ?
td->odesc->log2_chroma_h : 0;
731 p =
td->desc->comp[
i].plane;
733 src_buf.plane[
i].data =
td->in->data[p];
734 src_buf.plane[
i].stride =
td->in->linesize[p];
735 src_buf.plane[
i].mask = -1;
737 p =
td->odesc->comp[
i].plane;
738 dst_buf.plane[
i].data =
td->out->data[p] +
td->out->linesize[p] * (out_slice_start >> vsamp);
739 dst_buf.plane[
i].stride =
td->out->linesize[p];
740 dst_buf.plane[
i].mask = -1;
742 if (!
s->graph[job_nr])
744 ret = zimg_filter_graph_process(
s->graph[job_nr], &src_buf, &dst_buf,
s->tmp[job_nr], 0, 0, 0, 0);
749 src_buf.plane[0].data =
td->in->data[3];
750 src_buf.plane[0].stride =
td->in->linesize[3];
751 src_buf.plane[0].mask = -1;
753 dst_buf.plane[0].data =
td->out->data[3] +
td->out->linesize[3] * out_slice_start;
754 dst_buf.plane[0].stride =
td->out->linesize[3];
755 dst_buf.plane[0].mask = -1;
757 if (!
s->alpha_graph[job_nr])
759 ret = zimg_filter_graph_process(
s->alpha_graph[job_nr], &src_buf, &dst_buf,
s->tmp[job_nr], 0, 0, 0, 0);
781 (
link->w != outlink->
w) ||
782 (
link->h != outlink->
h) ||
784 (
s->src_format.chroma_location !=
s->dst_format.chroma_location) ||
785 (
s->src_format.color_family !=
s->dst_format.color_family) ||
786 (
s->src_format.color_primaries !=
s->dst_format.color_primaries) ||
787 (
s->src_format.depth !=
s->dst_format.depth) ||
788 (
s->src_format.matrix_coefficients !=
s->dst_format.matrix_coefficients) ||
789 (
s->src_format.field_parity !=
s->dst_format.field_parity) ||
790 (
s->src_format.pixel_range !=
s->dst_format.pixel_range) ||
791 (
s->src_format.pixel_type !=
s->dst_format.pixel_type) ||
792 (
s->src_format.transfer_characteristics !=
s->dst_format.transfer_characteristics)
808 snprintf(buf,
sizeof(buf)-1,
"%d", outlink->
w);
810 snprintf(buf,
sizeof(buf)-1,
"%d", outlink->
h);
822 s->out_colorspace =
out->colorspace;
823 s->out_trc =
out->color_trc;
824 s->out_primaries =
out->color_primaries;
825 s->out_range =
out->color_range;
829 zimg_image_format_default(&
s->src_format, ZIMG_API_VERSION);
830 zimg_image_format_default(&
s->dst_format, ZIMG_API_VERSION);
831 zimg_graph_builder_params_default(&
s->params, ZIMG_API_VERSION);
834 s->primaries_in,
s->trc_in,
s->range_in,
s->chromal_in);
836 s->primaries,
s->trc,
s->range,
s->chromal);
839 s->params.dither_type =
s->dither;
840 s->params.cpu_type = ZIMG_CPU_AUTO_64B;
841 s->params.resample_filter =
s->filter;
842 s->params.resample_filter_uv =
s->filter;
843 s->params.nominal_peak_luminance =
s->nominal_peak_luminance;
844 s->params.allow_approximate_gamma =
s->approximate_gamma;
845 s->params.filter_param_a =
s->params.filter_param_a_uv =
s->param_a;
846 s->params.filter_param_b =
s->params.filter_param_b_uv =
s->param_b;
849 zimg_image_format_default(&
s->alpha_src_format, ZIMG_API_VERSION);
850 zimg_image_format_default(&
s->alpha_dst_format, ZIMG_API_VERSION);
851 zimg_graph_builder_params_default(&
s->alpha_params, ZIMG_API_VERSION);
853 s->alpha_params.dither_type =
s->dither;
854 s->alpha_params.cpu_type = ZIMG_CPU_AUTO_64B;
855 s->alpha_params.resample_filter =
s->filter;
857 s->alpha_src_format.width = in->
width;
858 s->alpha_src_format.height = in->
height;
859 s->alpha_src_format.depth =
desc->comp[0].depth;
860 s->alpha_src_format.pixel_type = (
desc->flags &
AV_PIX_FMT_FLAG_FLOAT) ? ZIMG_PIXEL_FLOAT :
desc->comp[0].depth > 8 ? ZIMG_PIXEL_WORD : ZIMG_PIXEL_BYTE;
861 s->alpha_src_format.color_family = ZIMG_COLOR_GREY;
863 s->alpha_dst_format.depth = odesc->
comp[0].
depth;
865 s->alpha_dst_format.color_family = ZIMG_COLOR_GREY;
869 av_reduce(&
out->sample_aspect_ratio.num, &
out->sample_aspect_ratio.den,
879 memset(
s->jobs_ret, 0,
s->nb_threads *
sizeof(*
s->jobs_ret));
881 for (
int i = 0;
ret >= 0 &&
i <
s->nb_threads;
i++)
882 if (
s->jobs_ret[
i] < 0)
883 ret =
s->jobs_ret[
i];
890 s->src_format_tmp =
s->src_format;
891 s->dst_format_tmp =
s->dst_format;
892 s->params_tmp =
s->params;
894 s->alpha_src_format_tmp =
s->alpha_src_format;
895 s->alpha_dst_format_tmp =
s->alpha_dst_format;
896 s->alpha_params_tmp =
s->alpha_params;
902 for (y = 0; y <
out->height; y++) {
903 for (x = 0; x <
out->width; x++) {
909 for (y = 0; y < outlink->
h; y++)
910 memset(
out->data[3] + y *
out->linesize[3], 0xff, outlink->
w);
931 for (
int i = 0;
i <
s->nb_threads;
i++) {
934 zimg_filter_graph_free(
s->graph[
i]);
937 if (
s->alpha_graph[
i]) {
938 zimg_filter_graph_free(
s->alpha_graph[
i]);
945 char *res,
int res_len,
int flags)
950 if ( !strcmp(cmd,
"width") || !strcmp(cmd,
"w")
951 || !strcmp(cmd,
"height") || !strcmp(cmd,
"h")) {
968 #define OFFSET(x) offsetof(ZScaleContext, x)
969 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
970 #define TFLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
984 {
"error_diffusion", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_DITHER_ERROR_DIFFUSION}, 0, 0,
FLAGS,
"dither" },
1006 {
"unspecified", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_PRIMARIES_UNSPECIFIED}, 0, 0,
FLAGS,
"primaries" },
1043 {
"iec61966-2-4", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_TRANSFER_IEC_61966_2_4},0, 0,
FLAGS,
"transfer" },
1044 {
"iec61966-2-1", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_TRANSFER_IEC_61966_2_1},0, 0,
FLAGS,
"transfer" },
1065 {
"chroma-derived-nc",0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_MATRIX_CHROMATICITY_DERIVED_NCL}, 0, 0,
FLAGS,
"matrix" },
1066 {
"chroma-derived-c", 0, 0,
AV_OPT_TYPE_CONST, {.i64 = ZIMG_MATRIX_CHROMATICITY_DERIVED_CL}, 0, 0,
FLAGS,
"matrix" },
1068 {
"in_range",
"set input color range",
OFFSET(range_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_RANGE_FULL,
FLAGS,
"range" },
1071 {
"primariesin",
"set input color primaries",
OFFSET(primaries_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS,
"primaries" },
1073 {
"transferin",
"set input transfer characteristic",
OFFSET(trc_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS,
"transfer" },
1074 {
"tin",
"set input transfer characteristic",
OFFSET(trc_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS,
"transfer" },
1075 {
"matrixin",
"set input colorspace matrix",
OFFSET(colorspace_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
FLAGS,
"matrix" },
1077 {
"chromal",
"set output chroma location",
OFFSET(chromal),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM,
FLAGS,
"chroma" },
1078 {
"c",
"set output chroma location",
OFFSET(chromal),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM,
FLAGS,
"chroma" },
1086 {
"chromalin",
"set input chroma location",
OFFSET(chromal_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM,
FLAGS,
"chroma" },
1087 {
"cin",
"set input chroma location",
OFFSET(chromal_in),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM,
FLAGS,
"chroma" },
1090 {
"param_a",
"parameter A, which is parameter \"b\" for bicubic, "
1119 .priv_class = &zscale_class,