From patchwork Thu Oct 24 10:25:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niklas Haas X-Patchwork-Id: 52464 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:612c:1c41:b0:48e:c0f8:d0de with SMTP id im1csp230960vqb; Thu, 24 Oct 2024 03:28:17 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUTY3m+yV/9oVUAzFGetGcFe/cAY8tMy/4/kVxYS/XvSgVYJqYrHEnss7/5mWYVOMxyfw+Tw2ZCnGW9qJGL4eDK@gmail.com X-Google-Smtp-Source: AGHT+IFKe2jHW005vkugHzkpI+NQxb7pAR6EtsMRdQ0nIO0TvUcNo2spYZBEsaUidWbiyygbVNew X-Received: by 2002:a05:651c:550:b0:2fb:4603:da13 with SMTP id 38308e7fff4ca-2fca8265e94mr8125181fa.39.1729765697526; Thu, 24 Oct 2024 03:28:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1729765697; cv=none; d=google.com; s=arc-20240605; b=LOc0UgylCmiIiJSqPnwq0PQ8oxEuDBvtLiGe04vHbrOR2keNHaiwAOUBd6/Po/WQiY HT15KGJYgqE3IVWCqDJCWHHiJJ6xsKD9vZCzWXYUVgrrzcr2MdoRm5IlG6e6Ng92pjpQ awt8vHoYxbqBs6oUcYLHZPKLkjEn2Z7HVcP9+XMceYlje8IDcz/dXkl9DbW57NU6AmiS UqEEJVsAm99wAMBaCRjzr8CMFxJFPcriTlme98vmSCDI4pashErHA8XUiYJc9/FFSAH8 yQpTBibBc2vw7rQXf2lmbb0IKVzDy/9hWfoil8ueFkKOrQgKyOyZfzvw7vu6a2WUab/7 Q1Hw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=BtlX/TbUn090N4vjaTMgRB75TeCUfx/iPRGkcyqQrH4=; fh=xmAeKtysnShNOmkhiJmYkS30uw4Fu2hvBJ7qlIwukxQ=; b=A/8ASgs6eM8j8tM16bxYP9pM22EIpnVxJ9LMVPquYhTATktqoaSGwAXBCxWiIjIxcU tyPbgn5zRrI6icXpptThHDiz58URG+SAKaciDbcbu9emNim+EEuPADMjGmeZOBWThsPB GswUp+rAyK/MeAs4U4pUZ9Y8duwSjk+1V1TDxsoyiDEKEgreCuYCDn4o+45IF66iEQ3h 7jdrTPFNmRYUvcow1Gr1yOJBilk3jraLQRMcbIqysdmx7lhw/esTk6Oz1nN4DgFTf7rI BspGkGWmRUV4UGpKdrxHBTYnbz6BZGihKGoeyOQAfU6uKi9QKfkTsdtU3twJi1fCu+K4 FxMQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@haasn.xyz header.s=mail header.b="F/rF6z/J"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 38308e7fff4ca-2fb9aecb3b1si30181211fa.649.2024.10.24.03.28.17; Thu, 24 Oct 2024 03:28:17 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@haasn.xyz header.s=mail header.b="F/rF6z/J"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 95C6868DCE1; Thu, 24 Oct 2024 13:27:52 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from haasn.dev (haasn.dev [78.46.187.166]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D6BDD68DBC1 for ; Thu, 24 Oct 2024 13:27:42 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=haasn.xyz; s=mail; t=1729765662; bh=v0o9PLYlpcbgjZcNCudik2TKUMsGZ/amgqvwXjoHUfc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F/rF6z/JTNYtGhZ8QSL1WbOR3fouNG1dfQ/0WdGRRhRHWp8fGuoIxPDDMdHRBFCjH EYF26yLcWwRzsfCv5Oi36YOc+zfF33t4mGHaZjMMef65kOTNKgRv774dNws3TkeMle VQ8hfc+2QTwU+gNxRJUmLlTwzHp7nAfWqlBM28xI= Received: from haasn.dev (unknown [10.30.0.2]) by haasn.dev (Postfix) with ESMTP id 9AA8B4327A; Thu, 24 Oct 2024 12:27:42 +0200 (CEST) From: Niklas Haas To: ffmpeg-devel@ffmpeg.org Date: Thu, 24 Oct 2024 12:25:12 +0200 Message-ID: <20241024102737.792421-3-ffmpeg@haasn.xyz> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241024102737.792421-1-ffmpeg@haasn.xyz> References: <20241024102737.792421-1-ffmpeg@haasn.xyz> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v4 02/13] swscale/options: cosmetic changes X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Niklas Haas Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: tHu0OgkRvzcj From: Niklas Haas Reorganize the list, fix whitespace, make indentation consistent, and rename some descriptions for clarity, consistency or informativeness. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas --- libswscale/options.c | 86 ++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/libswscale/options.c b/libswscale/options.c index 56b1d2235d..e64e289cf3 100644 --- a/libswscale/options.c +++ b/libswscale/options.c @@ -32,55 +32,57 @@ static const char *sws_context_to_name(void *ptr) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption swscale_options[] = { - { "sws_flags", "scaler flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, { .i64 = SWS_BICUBIC }, 0, UINT_MAX, VE, .unit = "sws_flags" }, - { "fast_bilinear", "fast bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_FAST_BILINEAR }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "bilinear", "bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BILINEAR }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "bicubic", "bicubic", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BICUBIC }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "experimental", "experimental", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_X }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "neighbor", "nearest neighbor", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_POINT }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "area", "averaging area", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_AREA }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "bicublin", "luma bicubic, chroma bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BICUBLIN }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "gauss", "Gaussian", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_GAUSS }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "sinc", "sinc", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_SINC }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "lanczos", "Lanczos", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_LANCZOS }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "spline", "natural bicubic spline", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_SPLINE }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "print_info", "print info", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_PRINT_INFO }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "accurate_rnd", "accurate rounding", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ACCURATE_RND }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "full_chroma_int", "full chroma interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_FULL_CHR_H_INT }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "full_chroma_inp", "full chroma input", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_FULL_CHR_H_INP }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "bitexact", "", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BITEXACT }, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, - { "error_diffusion", "error diffusion dither", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ERROR_DIFFUSION}, INT_MIN, INT_MAX, VE, .unit = "sws_flags" }, + { "sws_flags", "swscale flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, { .i64 = SWS_BICUBIC }, .flags = VE, .unit = "sws_flags", .max = UINT_MAX }, + { "fast_bilinear", "fast bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_FAST_BILINEAR }, .flags = VE, .unit = "sws_flags" }, + { "bilinear", "bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BILINEAR }, .flags = VE, .unit = "sws_flags" }, + { "bicubic", "bicubic", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BICUBIC }, .flags = VE, .unit = "sws_flags" }, + { "experimental", "experimental", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_X }, .flags = VE, .unit = "sws_flags" }, + { "neighbor", "nearest neighbor", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_POINT }, .flags = VE, .unit = "sws_flags" }, + { "area", "averaging area", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_AREA }, .flags = VE, .unit = "sws_flags" }, + { "bicublin", "luma bicubic, chroma bilinear", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BICUBLIN }, .flags = VE, .unit = "sws_flags" }, + { "gauss", "gaussian approximation", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_GAUSS }, .flags = VE, .unit = "sws_flags" }, + { "sinc", "sinc", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_SINC }, .flags = VE, .unit = "sws_flags" }, + { "lanczos", "lanczos (sinc/sinc)", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_LANCZOS }, .flags = VE, .unit = "sws_flags" }, + { "spline", "natural bicubic spline", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_SPLINE }, .flags = VE, .unit = "sws_flags" }, + { "print_info", "print info", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_PRINT_INFO }, .flags = VE, .unit = "sws_flags" }, + { "accurate_rnd", "accurate rounding", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ACCURATE_RND }, .flags = VE, .unit = "sws_flags" }, + { "full_chroma_int", "full chroma interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_FULL_CHR_H_INT }, .flags = VE, .unit = "sws_flags" }, + { "full_chroma_inp", "full chroma input", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_FULL_CHR_H_INP }, .flags = VE, .unit = "sws_flags" }, + { "bitexact", "bit-exact mode", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_BITEXACT }, .flags = VE, .unit = "sws_flags" }, + { "error_diffusion", "error diffusion dither", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ERROR_DIFFUSION}, .flags = VE, .unit = "sws_flags" }, - { "srcw", "source width", OFFSET(srcW), AV_OPT_TYPE_INT, { .i64 = 16 }, 1, INT_MAX, VE }, - { "srch", "source height", OFFSET(srcH), AV_OPT_TYPE_INT, { .i64 = 16 }, 1, INT_MAX, VE }, - { "dstw", "destination width", OFFSET(dstW), AV_OPT_TYPE_INT, { .i64 = 16 }, 1, INT_MAX, VE }, - { "dsth", "destination height", OFFSET(dstH), AV_OPT_TYPE_INT, { .i64 = 16 }, 1, INT_MAX, VE }, + { "param0", "scaler param 0", OFFSET(param[0]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, VE }, + { "param1", "scaler param 1", OFFSET(param[1]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, VE }, + + { "srcw", "source width", OFFSET(srcW), AV_OPT_TYPE_INT, { .i64 = 16 }, 1, INT_MAX, VE }, + { "srch", "source height", OFFSET(srcH), AV_OPT_TYPE_INT, { .i64 = 16 }, 1, INT_MAX, VE }, + { "dstw", "destination width", OFFSET(dstW), AV_OPT_TYPE_INT, { .i64 = 16 }, 1, INT_MAX, VE }, + { "dsth", "destination height", OFFSET(dstH), AV_OPT_TYPE_INT, { .i64 = 16 }, 1, INT_MAX, VE }, { "src_format", "source format", OFFSET(srcFormat), AV_OPT_TYPE_PIXEL_FMT,{ .i64 = DEFAULT }, 0, INT_MAX, VE }, { "dst_format", "destination format", OFFSET(dstFormat), AV_OPT_TYPE_PIXEL_FMT,{ .i64 = DEFAULT }, 0, INT_MAX, VE }, - { "src_range", "source is full range", OFFSET(srcRange), AV_OPT_TYPE_BOOL, { .i64 = DEFAULT }, 0, 1, VE }, - { "dst_range", "destination is full range", OFFSET(dstRange), AV_OPT_TYPE_BOOL, { .i64 = DEFAULT }, 0, 1, VE }, - { "param0", "scaler param 0", OFFSET(param[0]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, VE }, - { "param1", "scaler param 1", OFFSET(param[1]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, VE }, + { "src_range", "source is full range", OFFSET(srcRange), AV_OPT_TYPE_BOOL, { .i64 = DEFAULT }, 0, 1, VE }, + { "dst_range", "destination is full range", OFFSET(dstRange), AV_OPT_TYPE_BOOL, { .i64 = DEFAULT }, 0, 1, VE }, + { "gamma", "gamma correct scaling", OFFSET(gamma_flag),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, + + { "src_v_chr_pos", "source vertical chroma position in luma grid/256" , OFFSET(src_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513 }, -513, 1024, VE }, + { "src_h_chr_pos", "source horizontal chroma position in luma grid/256", OFFSET(src_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513 }, -513, 1024, VE }, + { "dst_v_chr_pos", "destination vertical chroma position in luma grid/256" , OFFSET(dst_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513 }, -513, 1024, VE }, + { "dst_h_chr_pos", "destination horizontal chroma position in luma grid/256", OFFSET(dst_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513 }, -513, 1024, VE }, - { "src_v_chr_pos", "source vertical chroma position in luma grid/256" , OFFSET(src_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513 }, -513, 1024, VE }, - { "src_h_chr_pos", "source horizontal chroma position in luma grid/256", OFFSET(src_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513 }, -513, 1024, VE }, - { "dst_v_chr_pos", "destination vertical chroma position in luma grid/256" , OFFSET(dst_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513 }, -513, 1024, VE }, - { "dst_h_chr_pos", "destination horizontal chroma position in luma grid/256", OFFSET(dst_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513 }, -513, 1024, VE }, + { "sws_dither", "set dithering algorithm", OFFSET(dither), AV_OPT_TYPE_INT, { .i64 = SWS_DITHER_AUTO }, .flags = VE, .unit = "sws_dither", .max = SWS_DITHER_NB - 1 }, + { "auto", "automatic selection", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_AUTO }, .flags = VE, .unit = "sws_dither" }, + { "bayer", "ordered matrix dither", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_BAYER }, .flags = VE, .unit = "sws_dither" }, + { "ed", "full error diffusion", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_ED }, .flags = VE, .unit = "sws_dither" }, + { "a_dither", "arithmetic addition dither", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_A_DITHER }, .flags = VE, .unit = "sws_dither" }, + { "x_dither", "arithmetic xor dither", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_X_DITHER }, .flags = VE, .unit = "sws_dither" }, - { "sws_dither", "set dithering algorithm", OFFSET(dither), AV_OPT_TYPE_INT, { .i64 = SWS_DITHER_AUTO }, 0, SWS_DITHER_NB, VE, .unit = "sws_dither" }, - { "auto", "leave choice to sws", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_AUTO }, INT_MIN, INT_MAX, VE, .unit = "sws_dither" }, - { "bayer", "bayer dither", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_BAYER }, INT_MIN, INT_MAX, VE, .unit = "sws_dither" }, - { "ed", "error diffusion", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_ED }, INT_MIN, INT_MAX, VE, .unit = "sws_dither" }, - { "a_dither", "arithmetic addition dither", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_A_DITHER}, INT_MIN, INT_MAX, VE, .unit = "sws_dither" }, - { "x_dither", "arithmetic xor dither", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_X_DITHER}, INT_MIN, INT_MAX, VE, .unit = "sws_dither" }, - { "gamma", "gamma correct scaling", OFFSET(gamma_flag),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, - { "alphablend", "mode for alpha -> non alpha", OFFSET(alphablend),AV_OPT_TYPE_INT, { .i64 = SWS_ALPHA_BLEND_NONE}, 0, SWS_ALPHA_BLEND_NB-1, VE, .unit = "alphablend" }, - { "none", "ignore alpha", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ALPHA_BLEND_NONE}, INT_MIN, INT_MAX, VE, .unit = "alphablend" }, - { "uniform_color", "blend onto a uniform color", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ALPHA_BLEND_UNIFORM},INT_MIN, INT_MAX, VE, .unit = "alphablend" }, - { "checkerboard", "blend onto a checkerboard", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ALPHA_BLEND_CHECKERBOARD},INT_MIN, INT_MAX, VE, .unit = "alphablend" }, + { "alphablend", "mode for alpha -> non alpha", OFFSET(alphablend), AV_OPT_TYPE_INT, { .i64 = SWS_ALPHA_BLEND_NONE}, .flags = VE, .unit = "alphablend", .max = SWS_ALPHA_BLEND_NB - 1 }, + { "none", "ignore alpha", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ALPHA_BLEND_NONE}, .flags = VE, .unit = "alphablend" }, + { "uniform_color", "blend onto a uniform color", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ALPHA_BLEND_UNIFORM}, .flags = VE, .unit = "alphablend" }, + { "checkerboard", "blend onto a checkerboard", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_ALPHA_BLEND_CHECKERBOARD}, .flags = VE, .unit = "alphablend" }, { "threads", "number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, VE, .unit = "threads" }, - { "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = VE, .unit = "threads" }, + { "auto", "automatic selection", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = VE, .unit = "threads" }, { NULL } };