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,