41     uint32_t rgbtoyuv[1<<24];
 
   49 #define OFFSET(x) offsetof(HQXContext, x) 
   50 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM 
   60     return r2y[c & 0xffffff];
 
   65 #define YMASK 0xff0000 
   66 #define UMASK 0x00ff00 
   67 #define VMASK 0x0000ff 
   68     return abs((yuv1 & 
YMASK) - (yuv2 & YMASK)) > (48 << 16) ||
 
   69            abs((yuv1 & 
UMASK) - (yuv2 & UMASK)) > ( 7 <<  8) ||
 
   70            abs((yuv1 & 
VMASK) - (yuv2 & VMASK)) > ( 6 <<  0);
 
   76     return (((((c1 & 0xff00ff00) >> 8) * w1 + ((c2 & 0xff00ff00) >> 8) * w2) << (8 - s)) & 0xff00ff00) |
 
   77            (((((c1 & 0x00ff00ff)     ) * w1 + ((c2 & 0x00ff00ff)     ) * w2) >>      s ) & 0x00ff00ff);
 
   83     return (((((c1 & 0xff00ff00) >> 8) * w1 + ((c2 & 0xff00ff00) >> 8) * w2 + ((c3 & 0xff00ff00) >> 8) * w3) << (8 - s)) & 0xff00ff00) |
 
   84            (((((c1 & 0x00ff00ff)     ) * w1 + ((c2 & 0x00ff00ff)     ) * w2 + ((c3 & 0x00ff00ff)     ) * w3) >>      s ) & 0x00ff00ff);
 
   90 #define P(m, r) ((k_shuffled & (m)) == (r)) 
   94 #define DROP4(z) ((z) > 4 ? (z)-1 : (z)) 
   97 #define SHF(x, rot, n) (((x) >> ((rot) ? 7-DROP4(n) : DROP4(n)) & 1) << DROP4(p##n)) 
  100 #define WDIFF(c1, c2) yuv_diff(rgb2yuv(r2y, c1), rgb2yuv(r2y, c2)) 
  105 #define INTERP_BOOTSTRAP(rot)                                           \ 
  106     const int k_shuffled = SHF(k,rot,0) | SHF(k,rot,1) | SHF(k,rot,2)   \ 
  107                          | SHF(k,rot,3) |       0      | SHF(k,rot,5)   \ 
  108                          | SHF(k,rot,6) | SHF(k,rot,7) | SHF(k,rot,8);  \ 
  110     const uint32_t w0 = w[p0], w1 = w[p1],                              \ 
  111                    w3 = w[p3], w4 = w[p4], w5 = w[p5],                  \ 
  119                                                  int p0, 
int p1, 
int p2,
 
  120                                                  int p3, 
int p4, 
int p5,
 
  121                                                  int p6, 
int p7, 
int p8)
 
  125     if ((
P(0xbf,0x37) || 
P(0xdb,0x13)) && 
WDIFF(w1, w5))
 
  127     if ((
P(0xdb,0x49) || 
P(0xef,0x6d)) && 
WDIFF(w7, w3))
 
  129     if ((
P(0x0b,0x0b) || 
P(0xfe,0x4a) || 
P(0xfe,0x1a)) && 
WDIFF(w3, w1))
 
  131     if ((
P(0x6f,0x2a) || 
P(0x5b,0x0a) || 
P(0xbf,0x3a) || 
P(0xdf,0x5a) ||
 
  132          P(0x9f,0x8a) || 
P(0xcf,0x8a) || 
P(0xef,0x4e) || 
P(0x3f,0x0e) ||
 
  133          P(0xfb,0x5a) || 
P(0xbb,0x8a) || 
P(0x7f,0x5a) || 
P(0xaf,0x8a) ||
 
  134          P(0xeb,0x8a)) && 
WDIFF(w3, w1))
 
  142     if (
P(0xbf,0x37) || 
P(0xdb,0x13))
 
  144     if (
P(0xdb,0x49) || 
P(0xef,0x6d))
 
  146     if (
P(0x1b,0x03) || 
P(0x4f,0x43) || 
P(0x8b,0x83) || 
P(0x6b,0x43))
 
  148     if (
P(0x4b,0x09) || 
P(0x8b,0x89) || 
P(0x1f,0x19) || 
P(0x3b,0x19))
 
  150     if (
P(0x7e,0x2a) || 
P(0xef,0xab) || 
P(0xbf,0x8f) || 
P(0x7e,0x0e))
 
  152     if (
P(0xfb,0x6a) || 
P(0x6f,0x6e) || 
P(0x3f,0x3e) || 
P(0xfb,0xfa) ||
 
  153         P(0xdf,0xde) || 
P(0xdf,0x1e))
 
  155     if (
P(0x0a,0x00) || 
P(0x4f,0x4b) || 
P(0x9f,0x1b) || 
P(0x2f,0x0b) ||
 
  156         P(0xbe,0x0a) || 
P(0xee,0x0a) || 
P(0x7e,0x0a) || 
P(0xeb,0x4b) ||
 
  168                                              const uint32_t *r2y, 
int k,
 
  170                                              int pos00, 
int pos01,
 
  171                                              int p0, 
int p1, 
int p2,
 
  172                                              int p3, 
int p4, 
int p5,
 
  173                                              int p6, 
int p7, 
int p8,
 
  178     uint32_t *dst00 = &dst[dst_linesize*(pos00>>1) + (pos00&1)];
 
  179     uint32_t *dst01 = &dst[dst_linesize*(pos01>>1) + (pos01&1)];
 
  181     if ((
P(0xdb,0x49) || 
P(0xef,0x6d)) && 
WDIFF(w7, w3))
 
  183     else if ((
P(0xbf,0x37) || 
P(0xdb,0x13)) && 
WDIFF(w1, w5))
 
  185     else if ((
P(0x0b,0x0b) || 
P(0xfe,0x4a) || 
P(0xfe,0x1a)) && 
WDIFF(w3, w1))
 
  187     else if ((
P(0x6f,0x2a) || 
P(0x5b,0x0a) || 
P(0xbf,0x3a) || 
P(0xdf,0x5a) ||
 
  188               P(0x9f,0x8a) || 
P(0xcf,0x8a) || 
P(0xef,0x4e) || 
P(0x3f,0x0e) ||
 
  189               P(0xfb,0x5a) || 
P(0xbb,0x8a) || 
P(0x7f,0x5a) || 
P(0xaf,0x8a) ||
 
  190               P(0xeb,0x8a)) && 
WDIFF(w3, w1))
 
  192     else if (
P(0x4b,0x09) || 
P(0x8b,0x89) || 
P(0x1f,0x19) || 
P(0x3b,0x19))
 
  194     else if (
P(0x1b,0x03) || 
P(0x4f,0x43) || 
P(0x8b,0x83) || 
P(0x6b,0x43))
 
  196     else if (
P(0x7e,0x2a) || 
P(0xef,0xab) || 
P(0xbf,0x8f) || 
P(0x7e,0x0e))
 
  198     else if (
P(0x4f,0x4b) || 
P(0x9f,0x1b) || 
P(0x2f,0x0b) || 
P(0xbe,0x0a) ||
 
  199              P(0xee,0x0a) || 
P(0x7e,0x0a) || 
P(0xeb,0x4b) || 
P(0x3b,0x1b))
 
  201     else if (
P(0x0b,0x08) || 
P(0xf9,0x68) || 
P(0xf3,0x62) || 
P(0x6d,0x6c) ||
 
  202              P(0x67,0x66) || 
P(0x3d,0x3c) || 
P(0x37,0x36) || 
P(0xf9,0xf8) ||
 
  203              P(0xdd,0xdc) || 
P(0xf3,0xf2) || 
P(0xd7,0xd6) || 
P(0xdd,0x1c) ||
 
  204              P(0xd7,0x16) || 
P(0x0b,0x02))
 
  209     if ((
P(0xfe,0xde) || 
P(0x9e,0x16) || 
P(0xda,0x12) || 
P(0x17,0x16) ||
 
  210          P(0x5b,0x12) || 
P(0xbb,0x12)) && 
WDIFF(w1, w5))
 
  212     else if ((
P(0x0f,0x0b) || 
P(0x5e,0x0a) || 
P(0xfb,0x7b) || 
P(0x3b,0x0b) ||
 
  213               P(0xbe,0x0a) || 
P(0x7a,0x0a)) && 
WDIFF(w3, w1))
 
  215     else if (
P(0xbf,0x8f) || 
P(0x7e,0x0e) || 
P(0xbf,0x37) || 
P(0xdb,0x13))
 
  217     else if (
P(0x02,0x00) || 
P(0x7c,0x28) || 
P(0xed,0xa9) || 
P(0xf5,0xb4) ||
 
  220     else if (
P(0x4f,0x4b) || 
P(0xfb,0x7b) || 
P(0xfe,0x7e) || 
P(0x9f,0x1b) ||
 
  221              P(0x2f,0x0b) || 
P(0xbe,0x0a) || 
P(0x7e,0x0a) || 
P(0xfb,0x4b) ||
 
  222              P(0xfb,0xdb) || 
P(0xfe,0xde) || 
P(0xfe,0x56) || 
P(0x57,0x56) ||
 
  223              P(0x97,0x16) || 
P(0x3f,0x1e) || 
P(0xdb,0x12) || 
P(0xbb,0x12))
 
  234                                              const uint32_t *r2y, 
int k,
 
  236                                              int pos00, 
int pos01,
 
  237                                              int pos10, 
int pos11,
 
  238                                              int p0, 
int p1, 
int p2,
 
  239                                              int p3, 
int p4, 
int p5,
 
  240                                              int p6, 
int p7, 
int p8)
 
  244     uint32_t *dst00 = &dst[dst_linesize*(pos00>>1) + (pos00&1)];
 
  245     uint32_t *dst01 = &dst[dst_linesize*(pos01>>1) + (pos01&1)];
 
  246     uint32_t *dst10 = &dst[dst_linesize*(pos10>>1) + (pos10&1)];
 
  247     uint32_t *dst11 = &dst[dst_linesize*(pos11>>1) + (pos11&1)];
 
  249     const int cond00 = (
P(0xbf,0x37) || 
P(0xdb,0x13)) && 
WDIFF(w1, w5);
 
  250     const int cond01 = (
P(0xdb,0x49) || 
P(0xef,0x6d)) && 
WDIFF(w7, w3);
 
  251     const int cond02 = (
P(0x6f,0x2a) || 
P(0x5b,0x0a) || 
P(0xbf,0x3a) ||
 
  252                         P(0xdf,0x5a) || 
P(0x9f,0x8a) || 
P(0xcf,0x8a) ||
 
  253                         P(0xef,0x4e) || 
P(0x3f,0x0e) || 
P(0xfb,0x5a) ||
 
  254                         P(0xbb,0x8a) || 
P(0x7f,0x5a) || 
P(0xaf,0x8a) ||
 
  255                         P(0xeb,0x8a)) && 
WDIFF(w3, w1);
 
  256     const int cond03 = 
P(0xdb,0x49) || 
P(0xef,0x6d);
 
  257     const int cond04 = 
P(0xbf,0x37) || 
P(0xdb,0x13);
 
  258     const int cond05 = 
P(0x1b,0x03) || 
P(0x4f,0x43) || 
P(0x8b,0x83) ||
 
  260     const int cond06 = 
P(0x4b,0x09) || 
P(0x8b,0x89) || 
P(0x1f,0x19) ||
 
  262     const int cond07 = 
P(0x0b,0x08) || 
P(0xf9,0x68) || 
P(0xf3,0x62) ||
 
  263                        P(0x6d,0x6c) || 
P(0x67,0x66) || 
P(0x3d,0x3c) ||
 
  264                        P(0x37,0x36) || 
P(0xf9,0xf8) || 
P(0xdd,0xdc) ||
 
  265                        P(0xf3,0xf2) || 
P(0xd7,0xd6) || 
P(0xdd,0x1c) ||
 
  266                        P(0xd7,0x16) || 
P(0x0b,0x02);
 
  267     const int cond08 = (
P(0x0f,0x0b) || 
P(0x2b,0x0b) || 
P(0xfe,0x4a) ||
 
  268                         P(0xfe,0x1a)) && 
WDIFF(w3, w1);
 
  269     const int cond09 = 
P(0x2f,0x2f);
 
  270     const int cond10 = 
P(0x0a,0x00);
 
  271     const int cond11 = 
P(0x0b,0x09);
 
  272     const int cond12 = 
P(0x7e,0x2a) || 
P(0xef,0xab);
 
  273     const int cond13 = 
P(0xbf,0x8f) || 
P(0x7e,0x0e);
 
  274     const int cond14 = 
P(0x4f,0x4b) || 
P(0x9f,0x1b) || 
P(0x2f,0x0b) ||
 
  275                        P(0xbe,0x0a) || 
P(0xee,0x0a) || 
P(0x7e,0x0a) ||
 
  276                        P(0xeb,0x4b) || 
P(0x3b,0x1b);
 
  277     const int cond15 = 
P(0x0b,0x03);
 
  283     else if ((
P(0x0b,0x0b) || 
P(0xfe,0x4a) || 
P(0xfe,0x1a)) && 
WDIFF(w3, w1))
 
  295     else if (
P(0x0f,0x0b) || 
P(0x5e,0x0a) || 
P(0x2b,0x0b) || 
P(0xbe,0x0a) ||
 
  296              P(0x7a,0x0a) || 
P(0xee,0x0a))
 
  313     else if (
P(0x0b,0x08))
 
  325     else if (
P(0xf3,0x62) || 
P(0x67,0x66) || 
P(0x37,0x36) || 
P(0xf3,0xf2) ||
 
  326              P(0xd7,0xd6) || 
P(0xd7,0x16) || 
P(0x0b,0x02))
 
  343     else if (
P(0x0b,0x02))
 
  355     else if (
P(0x0b,0x08) || 
P(0xf9,0x68) || 
P(0x6d,0x6c) || 
P(0x3d,0x3c) ||
 
  356              P(0xf9,0xf8) || 
P(0xdd,0xdc) || 
P(0xdd,0x1c))
 
  363     if ((
P(0x7f,0x2b) || 
P(0xef,0xab) || 
P(0xbf,0x8f) || 
P(0x7f,0x0f)) &&
 
  372     else if (
P(0x0a,0x00) || 
P(0x7e,0x2a) || 
P(0xef,0xab) || 
P(0xbf,0x8f) ||
 
  388     const int slice_start = (height *  jobnr   ) / nb_jobs;
 
  389     const int slice_end   = (height * (jobnr+1)) / nb_jobs;
 
  390     const int dst_linesize = 
out->linesize[0];
 
  391     const int src_linesize =  in->
linesize[0];
 
  392     uint8_t       *dst = 
out->data[0] + slice_start * dst_linesize * 
n;
 
  395     const int dst32_linesize = dst_linesize >> 2;
 
  396     const int src32_linesize = src_linesize >> 2;
 
  398     for (y = slice_start; y < 
slice_end; y++) {
 
  399         const uint32_t *src32 = (
const uint32_t *)src;
 
  400         uint32_t       *dst32 = (uint32_t *)dst;
 
  401         const int prevline = y > 0          ? -src32_linesize : 0;
 
  402         const int nextline = y < height - 1 ?  src32_linesize : 0;
 
  404         for (x = 0; x < 
width; x++) {
 
  405             const int prevcol = x > 0        ? -1 : 0;
 
  406             const int nextcol = x < width -1 ?  1 : 0;
 
  407             const uint32_t w[3*3] = {
 
  408                 src32[prevcol + prevline], src32[prevline], src32[prevline + nextcol],
 
  409                 src32[prevcol           ], src32[       0], src32[           nextcol],
 
  410                 src32[prevcol + nextline], src32[nextline], src32[nextline + nextcol]
 
  412             const uint32_t yuv1 = 
rgb2yuv(r2y, w[4]);
 
  413             const int pattern = (w[4] != w[0] ? (
yuv_diff(yuv1, 
rgb2yuv(r2y, w[0]))) : 0)
 
  423                 dst32[dst32_linesize*0 + 0] = 
hq2x_interp_1x1(r2y, pattern, w, 0,1,2,3,4,5,6,7,8);  
 
  424                 dst32[dst32_linesize*0 + 1] = 
hq2x_interp_1x1(r2y, pattern, w, 2,1,0,5,4,3,8,7,6);  
 
  425                 dst32[dst32_linesize*1 + 0] = 
hq2x_interp_1x1(r2y, pattern, w, 6,7,8,3,4,5,0,1,2);  
 
  426                 dst32[dst32_linesize*1 + 1] = 
hq2x_interp_1x1(r2y, pattern, w, 8,7,6,5,4,3,2,1,0);  
 
  428                 hq3x_interp_2x1(dst32,                        dst32_linesize, r2y, pattern, w, 0,1, 0,1,2,3,4,5,6,7,8, 0);  
 
  429                 hq3x_interp_2x1(dst32 + 1,                    dst32_linesize, r2y, pattern, w, 1,3, 2,5,8,1,4,7,0,3,6, 1);  
 
  430                 hq3x_interp_2x1(dst32 + 1*dst32_linesize,     dst32_linesize, r2y, pattern, w, 2,0, 6,3,0,7,4,1,8,5,2, 1);  
 
  431                 hq3x_interp_2x1(dst32 + 1*dst32_linesize + 1, dst32_linesize, r2y, pattern, w, 3,2, 8,7,6,5,4,3,2,1,0, 0);  
 
  432                 dst32[dst32_linesize + 1] = w[4];                                                                           
 
  434                 hq4x_interp_2x2(dst32,                        dst32_linesize, r2y, pattern, w, 0,1,2,3, 0,1,2,3,4,5,6,7,8); 
 
  435                 hq4x_interp_2x2(dst32 + 2,                    dst32_linesize, r2y, pattern, w, 1,0,3,2, 2,1,0,5,4,3,8,7,6); 
 
  436                 hq4x_interp_2x2(dst32 + 2*dst32_linesize,     dst32_linesize, r2y, pattern, w, 2,3,0,1, 6,7,8,3,4,5,0,1,2); 
 
  437                 hq4x_interp_2x2(dst32 + 2*dst32_linesize + 2, dst32_linesize, r2y, pattern, w, 3,2,1,0, 8,7,6,5,4,3,2,1,0); 
 
  447         dst += dst_linesize * 
n;
 
  451 #define HQX_FUNC(size) \ 
  452 static int hq##size##x(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ 
  454     hqx_filter(arg, jobnr, nb_jobs, size); \ 
  475     outlink->
w = inlink->
w * hqx->
n;
 
  476     outlink->
h = inlink->
h * hqx->
n;
 
  479            inlink->
w, inlink->
h, outlink->
w, outlink->
h);
 
  510     static const hqxfunc_t hqxfuncs[] = {hq2x, hq3x, hq4x};
 
  515     for (bg=-255; bg<256; bg++) {
 
  516         for (rg=-255; rg<256; rg++) {
 
  517             const uint32_t 
u = (uint32_t)((-169*rg + 500*bg)/1000) + 128;
 
  518             const uint32_t 
v = (uint32_t)(( 500*rg -  81*bg)/1000) + 128;
 
  519             int startg = 
FFMAX3(-bg, -rg, 0);
 
  520             int endg = 
FFMIN3(255-bg, 255-rg, 255);
 
  521             uint32_t 
y = (uint32_t)(( 299*rg + 1000*startg + 114*bg)/1000);
 
  522             c = bg + (rg<<16) + 0x010101 * startg;
 
  523             for (g = startg; g <= endg; g++) {
 
  524                 hqx->
rgbtoyuv[
c] = ((y++) << 16) + (u << 8) + v;
 
  530     hqx->
func = hqxfuncs[hqx->
n - 2];
 
  554     .description   = 
NULL_IF_CONFIG_SMALL(
"Scale the input by 2, 3 or 4 using the hq*x magnification algorithm."),
 
  560     .priv_class    = &hqx_class,