Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Mundt <tmundt75@gmail.com>2017-04-21 00:33:39 +0300
committerJames Almer <jamrial@gmail.com>2017-05-02 20:09:50 +0300
commit2da5bf4c2f4cb878bad794be2b76108afbbd899d (patch)
tree509008cb5a54e60151674017dae6c88bdcd9d6a7
parent20da4135020fdf66f6060bb14926befbcc42a7dd (diff)
avfilter/interlace: add complex vertical low-pass filter
This complex (-1 2 6 2 -1) filter slightly less reduces interlace 'twitter' but better retain detail and subjective sharpness impression compared to the linear (1 2 1) filter. Signed-off-by: Thomas Mundt <tmundt75@gmail.com> Signed-off-by: James Almer <jamrial@gmail.com>
-rw-r--r--doc/filters.texi27
-rw-r--r--libavfilter/interlace.h6
-rw-r--r--libavfilter/tinterlace.h4
-rw-r--r--libavfilter/vf_interlace.c49
-rw-r--r--libavfilter/vf_tinterlace.c61
-rw-r--r--libavfilter/x86/vf_interlace.asm60
-rw-r--r--libavfilter/x86/vf_interlace_init.c15
-rw-r--r--libavfilter/x86/vf_tinterlace_init.c15
-rw-r--r--tests/fate/filter-video.mak3
-rw-r--r--tests/ref/fate/filter-interlace-complex30
10 files changed, 246 insertions, 24 deletions
diff --git a/doc/filters.texi b/doc/filters.texi
index 119e7474a5..f431274f0f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -9158,8 +9158,21 @@ This determines whether the interlaced frame is taken from the even
(tff - default) or odd (bff) lines of the progressive frame.
@item lowpass
-Enable (default) or disable the vertical lowpass filter to avoid twitter
-interlacing and reduce moire patterns.
+Vertical lowpass filter to avoid twitter interlacing and
+reduce moire patterns.
+
+@table @samp
+@item 0, off
+Disable vertical lowpass filter
+
+@item 1, linear
+Enable linear filter (default)
+
+@item 2, complex
+Enable complex filter. This will slightly less reduce twitter and moire
+but better retain detail and subjective sharpness impression.
+
+@end table
@end table
@section kerndeint
@@ -13857,17 +13870,23 @@ Available value for @var{flags} is:
@table @option
@item low_pass_filter, vlfp
-Enable vertical low-pass filtering in the filter.
+Enable linear vertical low-pass filtering in the filter.
Vertical low-pass filtering is required when creating an interlaced
destination from a progressive source which contains high-frequency
vertical detail. Filtering will reduce interlace 'twitter' and Moire
patterning.
+@item complex_filter, cvlfp
+Enable complex vertical low-pass filtering.
+This will slightly less reduce interlace 'twitter' and Moire
+patterning but better retain detail and subjective sharpness impression.
+
+@end table
+
Vertical low-pass filtering can only be enabled for @option{mode}
@var{interleave_top} and @var{interleave_bottom}.
@end table
-@end table
@section transpose
diff --git a/libavfilter/interlace.h b/libavfilter/interlace.h
index 107c94fdb1..2101b79939 100644
--- a/libavfilter/interlace.h
+++ b/libavfilter/interlace.h
@@ -44,6 +44,12 @@ enum FieldType {
FIELD_LOWER = 1,
};
+enum VLPFilter {
+ VLPF_OFF = 0,
+ VLPF_LIN = 1,
+ VLPF_CMP = 2,
+};
+
typedef struct InterlaceContext {
const AVClass *class;
enum ScanMode scan; // top or bottom field first scanning
diff --git a/libavfilter/tinterlace.h b/libavfilter/tinterlace.h
index f52af13c9a..e01050cba7 100644
--- a/libavfilter/tinterlace.h
+++ b/libavfilter/tinterlace.h
@@ -30,6 +30,10 @@
#include "libavutil/opt.h"
#include "avfilter.h"
+#define TINTERLACE_FLAG_VLPF 01
+#define TINTERLACE_FLAG_EXACT_TB 2
+#define TINTERLACE_FLAG_CVLPF 4
+
enum TInterlaceMode {
MODE_MERGE = 0,
MODE_DROP_EVEN,
diff --git a/libavfilter/vf_interlace.c b/libavfilter/vf_interlace.c
index 8da8326709..d72cb43401 100644
--- a/libavfilter/vf_interlace.c
+++ b/libavfilter/vf_interlace.c
@@ -3,6 +3,7 @@
* Copyright (c) 2010 Baptiste Coudurier
* Copyright (c) 2011 Stefano Sabatini
* Copyright (c) 2013 Vittorio Giovara <vittorio.giovara@gmail.com>
+ * Copyright (c) 2017 Thomas Mundt <tmundt75@gmail.com>
*
* This file is part of FFmpeg.
*
@@ -47,7 +48,13 @@ static const AVOption interlace_options[] = {
{ "bff", "bottom field first", 0,
AV_OPT_TYPE_CONST, {.i64 = MODE_BFF }, INT_MIN, INT_MAX, .flags = FLAGS, .unit = "scan" },
{ "lowpass", "set vertical low-pass filter", OFFSET(lowpass),
- AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, .flags = FLAGS },
+ AV_OPT_TYPE_INT, {.i64 = VLPF_LIN }, 0, 2, .flags = FLAGS, .unit = "lowpass" },
+ { "off", "disable vertical low-pass filter", 0,
+ AV_OPT_TYPE_CONST, {.i64 = VLPF_OFF }, INT_MIN, INT_MAX, .flags = FLAGS, .unit = "lowpass" },
+ { "linear", "linear vertical low-pass filter", 0,
+ AV_OPT_TYPE_CONST, {.i64 = VLPF_LIN }, INT_MIN, INT_MAX, .flags = FLAGS, .unit = "lowpass" },
+ { "complex", "complex vertical low-pass filter", 0,
+ AV_OPT_TYPE_CONST, {.i64 = VLPF_CMP }, INT_MIN, INT_MAX, .flags = FLAGS, .unit = "lowpass" },
{ NULL }
};
@@ -68,6 +75,25 @@ static void lowpass_line_c(uint8_t *dstp, ptrdiff_t linesize,
}
}
+static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t linesize,
+ const uint8_t *srcp,
+ ptrdiff_t mref, ptrdiff_t pref)
+{
+ const uint8_t *srcp_above = srcp + mref;
+ const uint8_t *srcp_below = srcp + pref;
+ const uint8_t *srcp_above2 = srcp + mref * 2;
+ const uint8_t *srcp_below2 = srcp + pref * 2;
+ int i;
+ for (i = 0; i < linesize; i++) {
+ // this calculation is an integer representation of
+ // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2'
+ // '4 +' is for rounding.
+ dstp[i] = av_clip_uint8((4 + (srcp[i] << 2)
+ + ((srcp[i] + srcp_above[i] + srcp_below[i]) << 1)
+ - srcp_above2[i] - srcp_below2[i]) >> 3);
+ }
+}
+
static const enum AVPixelFormat formats_supported[] = {
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P,
@@ -117,7 +143,10 @@ static int config_out_props(AVFilterLink *outlink)
if (s->lowpass) {
- s->lowpass_line = lowpass_line_c;
+ if (s->lowpass == VLPF_LIN)
+ s->lowpass_line = lowpass_line_c;
+ else if (s->lowpass == VLPF_CMP)
+ s->lowpass_line = lowpass_line_complex_c;
if (ARCH_X86)
ff_interlace_init_x86(s);
}
@@ -151,7 +180,7 @@ static void copy_picture_field(InterlaceContext *s,
srcp += src_frame->linesize[plane];
dstp += dst_frame->linesize[plane];
}
- if (lowpass) {
+ if (lowpass == VLPF_LIN) {
int srcp_linesize = src_frame->linesize[plane] * 2;
int dstp_linesize = dst_frame->linesize[plane] * 2;
for (j = lines; j > 0; j--) {
@@ -165,6 +194,20 @@ static void copy_picture_field(InterlaceContext *s,
dstp += dstp_linesize;
srcp += srcp_linesize;
}
+ } else if (lowpass == VLPF_CMP) {
+ int srcp_linesize = src_frame->linesize[plane] * 2;
+ int dstp_linesize = dst_frame->linesize[plane] * 2;
+ for (j = lines; j > 0; j--) {
+ ptrdiff_t pref = src_frame->linesize[plane];
+ ptrdiff_t mref = -pref;
+ if (j >= (lines - 1))
+ mref = 0;
+ else if (j <= 2)
+ pref = 0;
+ s->lowpass_line(dstp, cols, srcp, mref, pref);
+ dstp += dstp_linesize;
+ srcp += srcp_linesize;
+ }
} else {
av_image_copy_plane(dstp, dst_frame->linesize[plane] * 2,
srcp, src_frame->linesize[plane] * 2,
diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
index 09ca4d30ee..65997076ad 100644
--- a/libavfilter/vf_tinterlace.c
+++ b/libavfilter/vf_tinterlace.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2017 Thomas Mundt <tmundt75@gmail.com>
* Copyright (c) 2011 Stefano Sabatini
* Copyright (c) 2010 Baptiste Coudurier
* Copyright (c) 2003 Michael Zucchi <notzed@ximian.com>
@@ -34,8 +35,6 @@
#define OFFSET(x) offsetof(TInterlaceContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
-#define TINTERLACE_FLAG_VLPF 01
-#define TINTERLACE_FLAG_EXACT_TB 2
static const AVOption tinterlace_options[] = {
{"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_MERGE}, 0, MODE_NB-1, FLAGS, "mode"},
@@ -51,6 +50,8 @@ static const AVOption tinterlace_options[] = {
{"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
{"low_pass_filter", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
{"vlpf", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
+ {"complex_filter", "enable complex vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_CVLPF},INT_MIN, INT_MAX, FLAGS, "flags" },
+ {"cvlpf", "enable complex vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_CVLPF},INT_MIN, INT_MAX, FLAGS, "flags" },
{"exact_tb", "force a timebase which can represent timestamps exactly", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_EXACT_TB}, INT_MIN, INT_MAX, FLAGS, "flags" },
{NULL}
@@ -102,6 +103,24 @@ static void lowpass_line_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp,
}
}
+static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp,
+ ptrdiff_t mref, ptrdiff_t pref)
+{
+ const uint8_t *srcp_above = srcp + mref;
+ const uint8_t *srcp_below = srcp + pref;
+ const uint8_t *srcp_above2 = srcp + mref * 2;
+ const uint8_t *srcp_below2 = srcp + pref * 2;
+ int i;
+ for (i = 0; i < width; i++) {
+ // this calculation is an integer representation of
+ // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2'
+ // '4 +' is for rounding.
+ dstp[i] = av_clip_uint8((4 + (srcp[i] << 2)
+ + ((srcp[i] + srcp_above[i] + srcp_below[i]) << 1)
+ - srcp_above2[i] - srcp_below2[i]) >> 3);
+ }
+}
+
static av_cold void uninit(AVFilterContext *ctx)
{
TInterlaceContext *tinterlace = ctx->priv;
@@ -144,12 +163,14 @@ static int config_out_props(AVFilterLink *outlink)
tinterlace->black_linesize[i] * h);
}
}
- if ((tinterlace->flags & TINTERLACE_FLAG_VLPF)
+ if ((tinterlace->flags & TINTERLACE_FLAG_VLPF
+ || tinterlace->flags & TINTERLACE_FLAG_CVLPF)
&& !(tinterlace->mode == MODE_INTERLEAVE_TOP
|| tinterlace->mode == MODE_INTERLEAVE_BOTTOM)) {
- av_log(ctx, AV_LOG_WARNING, "low_pass_filter flag ignored with mode %d\n",
+ av_log(ctx, AV_LOG_WARNING, "low_pass_filter flags ignored with mode %d\n",
tinterlace->mode);
tinterlace->flags &= ~TINTERLACE_FLAG_VLPF;
+ tinterlace->flags &= ~TINTERLACE_FLAG_CVLPF;
}
tinterlace->preout_time_base = inlink->time_base;
if (tinterlace->mode == MODE_INTERLACEX2) {
@@ -172,14 +193,19 @@ static int config_out_props(AVFilterLink *outlink)
(tinterlace->flags & TINTERLACE_FLAG_EXACT_TB))
outlink->time_base = tinterlace->preout_time_base;
- if (tinterlace->flags & TINTERLACE_FLAG_VLPF) {
+ if (tinterlace->flags & TINTERLACE_FLAG_CVLPF) {
+ tinterlace->lowpass_line = lowpass_line_complex_c;
+ if (ARCH_X86)
+ ff_tinterlace_init_x86(tinterlace);
+ } else if (tinterlace->flags & TINTERLACE_FLAG_VLPF) {
tinterlace->lowpass_line = lowpass_line_c;
if (ARCH_X86)
ff_tinterlace_init_x86(tinterlace);
}
- av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n",
- tinterlace->mode, (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "on" : "off",
+ av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n", tinterlace->mode,
+ (tinterlace->flags & TINTERLACE_FLAG_CVLPF) ? "complex" :
+ (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "linear" : "off",
inlink->h, outlink->h);
return 0;
@@ -223,10 +249,23 @@ void copy_picture_field(TInterlaceContext *tinterlace,
srcp += src_linesize[plane];
if (interleave && dst_field == FIELD_LOWER)
dstp += dst_linesize[plane];
- if (flags & TINTERLACE_FLAG_VLPF) {
- // Low-pass filtering is required when creating an interlaced destination from
- // a progressive source which contains high-frequency vertical detail.
- // Filtering will reduce interlace 'twitter' and Moire patterning.
+ // Low-pass filtering is required when creating an interlaced destination from
+ // a progressive source which contains high-frequency vertical detail.
+ // Filtering will reduce interlace 'twitter' and Moire patterning.
+ if (flags & TINTERLACE_FLAG_CVLPF) {
+ int srcp_linesize = src_linesize[plane] * k;
+ int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1);
+ for (h = lines; h > 0; h--) {
+ ptrdiff_t pref = src_linesize[plane];
+ ptrdiff_t mref = -pref;
+ if (h >= (lines - 1)) mref = 0;
+ else if (h <= 2) pref = 0;
+
+ tinterlace->lowpass_line(dstp, cols, srcp, mref, pref);
+ dstp += dstp_linesize;
+ srcp += srcp_linesize;
+ }
+ } else if (flags & TINTERLACE_FLAG_VLPF) {
int srcp_linesize = src_linesize[plane] * k;
int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1);
for (h = lines; h > 0; h--) {
diff --git a/libavfilter/x86/vf_interlace.asm b/libavfilter/x86/vf_interlace.asm
index 8a0dd3bdea..c601fd7bf4 100644
--- a/libavfilter/x86/vf_interlace.asm
+++ b/libavfilter/x86/vf_interlace.asm
@@ -3,6 +3,7 @@
;*
;* Copyright (C) 2014 Kieran Kunhya <kierank@obe.tv>
;* Copyright (c) 2014 Michael Niedermayer <michaelni@gmx.at>
+;* Copyright (c) 2017 Thomas Mundt <tmundt75@gmail.com>
;*
;* This file is part of FFmpeg.
;*
@@ -25,6 +26,8 @@
SECTION_RODATA
+pw_4: times 8 dw 4
+
SECTION .text
%macro LOWPASS_LINE 0
@@ -56,6 +59,60 @@ cglobal lowpass_line, 5, 5, 7, dst, h, src, mref, pref
add hq, 2*mmsize
jl .loop
REP_RET
+
+%endmacro
+
+%macro LOWPASS_LINE_COMPLEX 0
+cglobal lowpass_line_complex, 5, 5, 7, dst, h, src, mref, pref
+ pxor m6, m6
+.loop:
+ mova m0, [srcq+mrefq]
+ mova m2, [srcq+prefq]
+ mova m1, m0
+ mova m3, m2
+ punpcklbw m0, m6
+ punpcklbw m2, m6
+ punpckhbw m1, m6
+ punpckhbw m3, m6
+ paddw m0, m2
+ paddw m1, m3
+ mova m2, [srcq+mrefq*2]
+ mova m4, [srcq+prefq*2]
+ mova m3, m2
+ mova m5, m4
+ punpcklbw m2, m6
+ punpcklbw m4, m6
+ punpckhbw m3, m6
+ punpckhbw m5, m6
+ paddw m2, m4
+ paddw m3, m5
+ mova m4, [srcq]
+ mova m5, m4
+ punpcklbw m4, m6
+ punpckhbw m5, m6
+ paddw m0, m4
+ paddw m1, m5
+ psllw m0, 1
+ psllw m1, 1
+ psllw m4, 2
+ psllw m5, 2
+ paddw m0, m4
+ paddw m1, m5
+ paddw m0, [pw_4]
+ paddw m1, [pw_4]
+ psubusw m0, m2
+ psubusw m1, m3
+ psrlw m0, 3
+ psrlw m1, 3
+ packuswb m0, m1
+ mova [dstq], m0
+
+ add dstq, mmsize
+ add srcq, mmsize
+ sub hd, mmsize
+ jg .loop
+REP_RET
+
%endmacro
INIT_XMM sse2
@@ -63,3 +120,6 @@ LOWPASS_LINE
INIT_XMM avx
LOWPASS_LINE
+
+INIT_XMM sse2
+LOWPASS_LINE_COMPLEX
diff --git a/libavfilter/x86/vf_interlace_init.c b/libavfilter/x86/vf_interlace_init.c
index 7d8acd6143..c0f04dcd97 100644
--- a/libavfilter/x86/vf_interlace_init.c
+++ b/libavfilter/x86/vf_interlace_init.c
@@ -33,12 +33,21 @@ void ff_lowpass_line_avx (uint8_t *dstp, ptrdiff_t linesize,
const uint8_t *srcp,
ptrdiff_t mref, ptrdiff_t pref);
+void ff_lowpass_line_complex_sse2(uint8_t *dstp, ptrdiff_t linesize,
+ const uint8_t *srcp,
+ ptrdiff_t mref, ptrdiff_t pref);
+
av_cold void ff_interlace_init_x86(InterlaceContext *s)
{
int cpu_flags = av_get_cpu_flags();
- if (EXTERNAL_SSE2(cpu_flags))
- s->lowpass_line = ff_lowpass_line_sse2;
+ if (EXTERNAL_SSE2(cpu_flags)) {
+ if (s->lowpass == VLPF_LIN)
+ s->lowpass_line = ff_lowpass_line_sse2;
+ else if (s->lowpass == VLPF_CMP)
+ s->lowpass_line = ff_lowpass_line_complex_sse2;
+ }
if (EXTERNAL_AVX(cpu_flags))
- s->lowpass_line = ff_lowpass_line_avx;
+ if (s->lowpass == VLPF_LIN)
+ s->lowpass_line = ff_lowpass_line_avx;
}
diff --git a/libavfilter/x86/vf_tinterlace_init.c b/libavfilter/x86/vf_tinterlace_init.c
index 175b5cff01..2b10e1b74c 100644
--- a/libavfilter/x86/vf_tinterlace_init.c
+++ b/libavfilter/x86/vf_tinterlace_init.c
@@ -34,12 +34,21 @@ void ff_lowpass_line_avx (uint8_t *dstp, ptrdiff_t linesize,
const uint8_t *srcp,
ptrdiff_t mref, ptrdiff_t pref);
+void ff_lowpass_line_complex_sse2(uint8_t *dstp, ptrdiff_t linesize,
+ const uint8_t *srcp,
+ ptrdiff_t mref, ptrdiff_t pref);
+
av_cold void ff_tinterlace_init_x86(TInterlaceContext *s)
{
int cpu_flags = av_get_cpu_flags();
- if (EXTERNAL_SSE2(cpu_flags))
- s->lowpass_line = ff_lowpass_line_sse2;
+ if (EXTERNAL_SSE2(cpu_flags)) {
+ if (!(s->flags & TINTERLACE_FLAG_CVLPF))
+ s->lowpass_line = ff_lowpass_line_sse2;
+ else
+ s->lowpass_line = ff_lowpass_line_complex_sse2;
+ }
if (EXTERNAL_AVX(cpu_flags))
- s->lowpass_line = ff_lowpass_line_avx;
+ if (!(s->flags & TINTERLACE_FLAG_CVLPF))
+ s->lowpass_line = ff_lowpass_line_avx;
}
diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index f185897361..1ca29e8d32 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -123,6 +123,9 @@ fate-filter-hqdn3d: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf hqdn3d
FATE_FILTER_VSYNTH-$(CONFIG_INTERLACE_FILTER) += fate-filter-interlace
fate-filter-interlace: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf interlace
+FATE_FILTER_VSYNTH-$(CONFIG_INTERLACE_FILTER) += fate-filter-interlace-complex
+fate-filter-interlace-complex: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf interlace=lowpass=complex
+
FATE_FILTER_VSYNTH-$(call ALLYES, NEGATE_FILTER PERMS_FILTER) += fate-filter-negate
fate-filter-negate: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf perms=random,negate
diff --git a/tests/ref/fate/filter-interlace-complex b/tests/ref/fate/filter-interlace-complex
new file mode 100644
index 0000000000..3b7812581f
--- /dev/null
+++ b/tests/ref/fate/filter-interlace-complex
@@ -0,0 +1,30 @@
+#tb 0: 2/25
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 352x288
+#sar 0: 0/1
+0, 0, 0, 1, 152064, 0x91290ae6
+0, 1, 1, 1, 152064, 0x24f34baf
+0, 2, 2, 1, 152064, 0x799fc436
+0, 3, 3, 1, 152064, 0xfe42c0a9
+0, 4, 4, 1, 152064, 0xb496f879
+0, 5, 5, 1, 152064, 0xc43b36c9
+0, 6, 6, 1, 152064, 0xb65abbf4
+0, 7, 7, 1, 152064, 0xd1806312
+0, 8, 8, 1, 152064, 0x0faf56c1
+0, 9, 9, 1, 152064, 0x4de73b75
+0, 10, 10, 1, 152064, 0xf90f24ce
+0, 11, 11, 1, 152064, 0xc1efd6e0
+0, 12, 12, 1, 152064, 0xeb8e5894
+0, 13, 13, 1, 152064, 0xe8aacabc
+0, 14, 14, 1, 152064, 0x8bd2163c
+0, 15, 15, 1, 152064, 0xbfc72ac2
+0, 16, 16, 1, 152064, 0x1e8f6f56
+0, 17, 17, 1, 152064, 0xe3d19450
+0, 18, 18, 1, 152064, 0x3872af32
+0, 19, 19, 1, 152064, 0xf23be72a
+0, 20, 20, 1, 152064, 0x024f8f2b
+0, 21, 21, 1, 152064, 0xb49301ea
+0, 22, 22, 1, 152064, 0x84f5d056
+0, 23, 23, 1, 152064, 0xd2c09ca5
+0, 24, 24, 1, 152064, 0xe9b5ddfd