From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 774CE10F92E5 for ; Tue, 31 Mar 2026 16:15:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To: Content-Transfer-Encoding:Content-Type:MIME-Version:References:Message-ID: Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=5CKY1ShayeyBKgTS9g5WXc+sjIt0plkwo3U2URkMkP8=; b=w/mzZ47iAUX+XIDa883YB9tLvD h6wjgCk02oEGDj5okHnI3/M1CgGAmhPTWkMlvgjr/x54jXg/1Hh5p42jBmM5mHtvnUtAHKULh0wr8 V//R+WI9kO+AmHSu1xyfej8lDkNLxpR3xx4szrb6ctpPlMFiXPg8eqUJAS75B4f/s7hVhICjRZLsv s0GpHUGVckX4BB2cPAoQ5JZkckH8ccHt+cOd4ixAvgeSM5If326LLZJWK/kkZGlH+ED65N3nAFols ziI9SNw/4pNFfWgSFmGbGFFCgMleTUC8aE4MZ0moUshE7SKjHyMUAvcD/oCoDjg3dFwKNQoZkCqpf EmSewTow==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1w7bkI-0000000DFIb-1k3T; Tue, 31 Mar 2026 16:15:14 +0000 Received: from perceval.ideasonboard.com ([213.167.242.64]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1w7bkG-0000000DFFq-0Bvb; Tue, 31 Mar 2026 16:15:13 +0000 Received: from killaraus.ideasonboard.com (2001-14ba-703d-e500--2a1.rev.dnainternet.fi [IPv6:2001:14ba:703d:e500::2a1]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 9A4D1316; Tue, 31 Mar 2026 18:13:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1774973625; bh=X9DLUqDirxP78ERBWuBb7M9vy72FmkWGBKCvgxS6PLc=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=gufU9QZwxiaCy/dKK6MO/NyomEBr4hZr+Pkcj8H7Opvpck0RB3FSgTO0pRcHzk4ya BnzveGIseVY7dND6ZjyPe9lrnsF8eOzNaTn3x2oK58K9awslOAgLdxZRr3LDPy33qB BtP+0B18lDJElX4eAVxP3diMFYylOtUrlpEp8PEI= Date: Tue, 31 Mar 2026 19:15:06 +0300 From: Laurent Pinchart To: =?utf-8?Q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi , Dafna Hirschfeld , Mauro Carvalho Chehab , Heiko Stuebner , linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v1] media: rkisp1: Add support for CAC Message-ID: <20260331161506.GD3357297@killaraus.ideasonboard.com> References: <20260323140216.1486161-1-barnabas.pocze@ideasonboard.com> <6c7ffd2d-94fa-4408-ac24-1e7adac95e5d@ideasonboard.com> <20260331133934.GC3357297@killaraus.ideasonboard.com> <5a7d1894-ee12-42b6-b40c-4d0e0b370974@ideasonboard.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <5a7d1894-ee12-42b6-b40c-4d0e0b370974@ideasonboard.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260331_091512_401103_4A021E32 X-CRM114-Status: GOOD ( 42.99 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Tue, Mar 31, 2026 at 05:24:38PM +0200, Barnabás Pőcze wrote: > 2026. 03. 31. 15:39 keltezéssel, Laurent Pinchart írta: > > On Tue, Mar 31, 2026 at 02:42:33PM +0200, Jacopo Mondi wrote: > >> On Mon, Mar 30, 2026 at 04:40:18PM +0200, Barnabás Pőcze wrote: > >>> 2026. 03. 25. 16:21 keltezéssel, Jacopo Mondi írta: > >>>> On Mon, Mar 23, 2026 at 03:02:16PM +0100, Barnabás Pőcze wrote: > >>>>> The CAC block implements chromatic aberration correction. Expose it to > >>>>> userspace using the extensible parameters format. This was tested on the > >>>>> i.MX8MP platform, but based on available documentation it is also present > >>>>> in the RK3399 variant (V10). Thus presumably also in later versions, > >>>>> so no feature flag is introduced. > >>>>> > >>>>> Signed-off-by: Barnabás Pőcze > >>>> > >>>> Only minors.. > >>>> > >>>>> --- > >>>>> .../platform/rockchip/rkisp1/rkisp1-params.c | 69 ++++++++++++ > >>>>> .../platform/rockchip/rkisp1/rkisp1-regs.h | 21 +++- > >>>>> include/uapi/linux/rkisp1-config.h | 106 +++++++++++++++++- > >>>>> 3 files changed, 193 insertions(+), 3 deletions(-) > >>>>> > >>>>> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c > >>>>> index 6442436a5e428..b889af9dcee45 100644 > >>>>> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c > >>>>> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c > >>>>> @@ -64,6 +64,7 @@ union rkisp1_ext_params_config { > >>>>> struct rkisp1_ext_params_compand_bls_config compand_bls; > >>>>> struct rkisp1_ext_params_compand_curve_config compand_curve; > >>>>> struct rkisp1_ext_params_wdr_config wdr; > >>>>> + struct rkisp1_ext_params_cac_config cac; > >>>>> }; > >>>>> > >>>>> enum rkisp1_params_formats { > >>>>> @@ -1413,6 +1414,48 @@ static void rkisp1_wdr_config(struct rkisp1_params *params, > >>>>> RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK); > >>>>> } > >>>>> > >>>>> +static void > >>>>> +rkisp1_cac_config(struct rkisp1_params *params, > >>>>> + const struct rkisp1_cif_isp_cac_config *arg) > >>>> > >>>> Fits in one line without going over 80 cols > >>> > >>> This is what the other functions looks like, so went this this. > >> > >> It seems to me not all of them are broken, but only the ones that go > >> over 80 cols > > I think I misunderstood initially. Adjusted now. > > >> in example: > >> > >> static void rkisp1_dpf_config(struct rkisp1_params *params, > >> const struct rkisp1_cif_isp_dpf_config *arg) > >> > >> A detail anyway, up to you > >> > >>>>> +{ > >>>>> + u32 regval; > > > > All other functions in this file name similar variables "val", "value" > > or "reg_val". Let's not introduce a fourth one. I have a small > > preference for "val", but that's not mandatory. > > Adjusted. > > >>>>> + > >>>>> + /* > >>>>> + * The enable bit is in the same register (RKISP1_CIF_ISP_CAC_CTRL), > >>>>> + * so only set the clipping mode, and do not modify the other bits. > >>>>> + */ > >>>>> + regval = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_CAC_CTRL); > >>>>> + regval &= ~(RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE | > >>>>> + RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE); > >>>>> + regval |= FIELD_PREP(RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE, arg->h_clip_mode) | > >>>>> + FIELD_PREP(RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE, arg->v_clip_mode); > >>>>> + rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_CTRL, regval); > >>>>> + > >>>>> + regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_COUNT_START_H_MASK, arg->h_count_start) | > >>>>> + FIELD_PREP(RKISP1_CIF_ISP_CAC_COUNT_START_V_MASK, arg->v_count_start); > >>>>> + rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_COUNT_START, regval); > >>>>> + > >>>>> + regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_A_RED_MASK, arg->red[0]) | > >>>>> + FIELD_PREP(RKISP1_CIF_ISP_CAC_A_BLUE_MASK, arg->blue[0]); > >>>>> + rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_A, regval); > >>>>> + > >>>>> + regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_B_RED_MASK, arg->red[1]) | > >>>>> + FIELD_PREP(RKISP1_CIF_ISP_CAC_B_BLUE_MASK, arg->blue[1]); > >>>>> + rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_B, regval); > >>>>> + > >>>>> + regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_C_RED_MASK, arg->red[2]) | > >>>>> + FIELD_PREP(RKISP1_CIF_ISP_CAC_C_BLUE_MASK, arg->blue[2]); > >>>>> + rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_C, regval); > >>>>> + > >>>>> + regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_X_NORM_NF_MASK, arg->x_nf) | > >>>>> + FIELD_PREP(RKISP1_CIF_ISP_CAC_X_NORM_NS_MASK, arg->x_ns); > >>>>> + rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_X_NORM, regval); > >>>>> + > >>>>> + regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_Y_NORM_NF_MASK, arg->y_nf) | > >>>>> + FIELD_PREP(RKISP1_CIF_ISP_CAC_Y_NORM_NS_MASK, arg->y_ns); > >>>>> + rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_Y_NORM, regval); > >>>>> +} > >>>>> + > >>>>> static void > >>>>> rkisp1_isp_isr_other_config(struct rkisp1_params *params, > >>>>> const struct rkisp1_params_cfg *new_params) > >>>>> @@ -2089,6 +2132,25 @@ static void rkisp1_ext_params_wdr(struct rkisp1_params *params, > >>>>> RKISP1_CIF_ISP_WDR_CTRL_ENABLE); > >>>>> } > >>>>> > >>>>> +static void rkisp1_ext_params_cac(struct rkisp1_params *params, > >>>>> + const union rkisp1_ext_params_config *block) > >>>>> +{ > >>>>> + const struct rkisp1_ext_params_cac_config *cac = &block->cac; > >>>>> + > >>>>> + if (cac->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { > >>>>> + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CAC_CTRL, > >>>>> + RKISP1_CIF_ISP_CAC_CTRL_ENABLE); > >>>>> + return; > >>>>> + } > >>>>> + > >>>>> + rkisp1_cac_config(params, &cac->config); > >>>>> + > >>>>> + if ((cac->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && > >>>>> + !(params->enabled_blocks & BIT(cac->header.type))) > >>>>> + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CAC_CTRL, > >>>>> + RKISP1_CIF_ISP_CAC_CTRL_ENABLE); > >>>>> +} > >>>>> + > >>>>> typedef void (*rkisp1_block_handler)(struct rkisp1_params *params, > >>>>> const union rkisp1_ext_params_config *config); > >>>>> > >>>>> @@ -2185,6 +2247,10 @@ static const struct rkisp1_ext_params_handler { > >>>>> .handler = rkisp1_ext_params_wdr, > >>>>> .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, > >>>>> }, > >>>>> + [RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC] = { > >>>>> + .handler = rkisp1_ext_params_cac, > >>>>> + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, > >>>>> + }, > >>>>> }; > >>>>> > >>>>> #define RKISP1_PARAMS_BLOCK_INFO(block, data) \ > >>>>> @@ -2215,6 +2281,7 @@ rkisp1_ext_params_block_types_info[] = { > >>>>> RKISP1_PARAMS_BLOCK_INFO(COMPAND_EXPAND, compand_curve), > >>>>> RKISP1_PARAMS_BLOCK_INFO(COMPAND_COMPRESS, compand_curve), > >>>>> RKISP1_PARAMS_BLOCK_INFO(WDR, wdr), > >>>>> + RKISP1_PARAMS_BLOCK_INFO(CAC, cac), > >>>>> }; > >>>>> > >>>>> static_assert(ARRAY_SIZE(rkisp1_ext_params_handlers) == > >>>>> @@ -2474,6 +2541,8 @@ void rkisp1_params_disable(struct rkisp1_params *params) > >>>>> rkisp1_ie_enable(params, false); > >>>>> rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE, > >>>>> RKISP1_CIF_ISP_DPF_MODE_EN); > >>>>> + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CAC_CTRL, > >>>>> + RKISP1_CIF_ISP_CAC_CTRL_ENABLE); > >>>>> } > >>>>> > >>>>> static const struct rkisp1_params_ops rkisp1_v10_params_ops = { > >>>>> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h > >>>>> index fbeb186cde0d5..8e25537459bbd 100644 > >>>>> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h > >>>>> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h > >>>>> @@ -724,6 +724,23 @@ > >>>>> #define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MASK GENMASK(20, 16) > >>>>> #define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX 16U > >>>>> > >>>>> +/* CAC */ > >>>>> +#define RKISP1_CIF_ISP_CAC_CTRL_ENABLE BIT(0) > >>>>> +#define RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE GENMASK(2, 1) > >>>>> +#define RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE GENMASK(3, 3) > > > > I'd go for BIT(3) as you use BIT(0) for the enable bit. > > Adjusted. > > >>>>> +#define RKISP1_CIF_ISP_CAC_COUNT_START_H_MASK GENMASK(12, 0) > >>>>> +#define RKISP1_CIF_ISP_CAC_COUNT_START_V_MASK GENMASK(28, 16) > >>>>> +#define RKISP1_CIF_ISP_CAC_A_RED_MASK GENMASK(8, 0) > >>>>> +#define RKISP1_CIF_ISP_CAC_A_BLUE_MASK GENMASK(24, 16) > >>>>> +#define RKISP1_CIF_ISP_CAC_B_RED_MASK GENMASK(8, 0) > >>>>> +#define RKISP1_CIF_ISP_CAC_B_BLUE_MASK GENMASK(24, 16) > >>>>> +#define RKISP1_CIF_ISP_CAC_C_RED_MASK GENMASK(8, 0) > >>>>> +#define RKISP1_CIF_ISP_CAC_C_BLUE_MASK GENMASK(24, 16) > >>>> > >>>> All these masks for coefficients 0, 1 and 2 are identical. Maybe > >>>> #define RKISP1_CIF_ISP_CAC_RED_MASK GENMASK(8, 0) > >>>> #define RKISP1_CIF_ISP_CAC_BLUE_MASK GENMASK(24, 16) > >>>> > >>>> is enough > >>> > >>> Adjusted. > >>> > >>>>> +#define RKISP1_CIF_ISP_CAC_X_NORM_NF_MASK GENMASK(4, 0) > >>>>> +#define RKISP1_CIF_ISP_CAC_X_NORM_NS_MASK GENMASK(19, 16) > >>>>> +#define RKISP1_CIF_ISP_CAC_Y_NORM_NF_MASK GENMASK(4, 0) > >>>>> +#define RKISP1_CIF_ISP_CAC_Y_NORM_NS_MASK GENMASK(19, 16) > >>> > >>> Did the same with these as well. > >> > >> Ah thanks! > >> > >>>>> + > >>>>> /* =================================================================== */ > >>>>> /* CIF Registers */ > >>>>> /* =================================================================== */ > >>>>> @@ -1196,8 +1213,8 @@ > >>>>> #define RKISP1_CIF_ISP_CAC_A (RKISP1_CIF_ISP_CAC_BASE + 0x00000008) > >>>>> #define RKISP1_CIF_ISP_CAC_B (RKISP1_CIF_ISP_CAC_BASE + 0x0000000c) > >>>>> #define RKISP1_CIF_ISP_CAC_C (RKISP1_CIF_ISP_CAC_BASE + 0x00000010) > >>>>> -#define RKISP1_CIF_ISP_X_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000014) > >>>>> -#define RKISP1_CIF_ISP_Y_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000018) > >>>>> +#define RKISP1_CIF_ISP_CAC_X_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000014) > >>>>> +#define RKISP1_CIF_ISP_CAC_Y_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000018) > >>>>> > >>>>> #define RKISP1_CIF_ISP_EXP_BASE 0x00002600 > >>>>> #define RKISP1_CIF_ISP_EXP_CTRL (RKISP1_CIF_ISP_EXP_BASE + 0x00000000) > >>>>> diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h > >>>>> index b2d2a71f7baff..d8acccaddd0e9 100644 > >>>>> --- a/include/uapi/linux/rkisp1-config.h > >>>>> +++ b/include/uapi/linux/rkisp1-config.h > >>>>> @@ -967,6 +967,92 @@ struct rkisp1_cif_isp_wdr_config { > >>>>> __u8 use_iref; > >>>>> }; > >>>>> > >>>>> +/* > >>>>> + * enum rkisp1_cif_isp_cac_h_clip_mode - horizontal clipping mode > >>>>> + * > >>>>> + * @RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4PX: +/- 4 pixels > >>>>> + * @RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4_5PX: +/- 4/5 pixels depending on bayer position > >>>>> + */ > >>>>> +enum rkisp1_cif_isp_cac_h_clip_mode { > >>>>> + RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4PX = 0, > >>>>> + RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4_5PX = 1, > >>>>> +}; > >>>>> + > >>>>> +/** > >>>>> + * enum rkisp1_cif_isp_cac_v_clip_mode - vertical clipping mode > >>>>> + * > >>>>> + * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_2PX: +/- 2 pixels > >>>>> + * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3PX: +/- 3 pixels > >>>>> + * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3_4PX: +/- 3/4 pixels depending on bayer position > >>>>> + */ > >>>>> +enum rkisp1_cif_isp_cac_v_clip_mode { > >>>>> + RKISP1_CIF_ISP_CAC_V_CLIP_MODE_2PX = 0, > >>>>> + RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3PX = 1, > >>>>> + RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3_4PX = 2, > >>>>> +}; > >>>>> + > >>>>> +/** > >>>>> + * struct rkisp1_cif_isp_cac_config - chromatic aberration correction configuration > >>>>> + * > >>>>> + * The correction is carried out by shifting the red and blue pixels relative > >>>>> + * to the green ones, depending on the distance from the optical center: > >>>> > >>>> Yes, the distance to the center is one parameter, but the shifting > >>>> amount depends on other things. I would drop the last part of the > >>>> sentence and move the description of the two below fields after the > >>>> text > >>> > >>> That's true, but within a specific image, the only varying quantity > >>> is the distance, so I think it is important to emphasize that. > >>> > >>> And I also quite like this structure of > >>> - description of step > >>> - parameters of step > >>> - description of step > >>> ... > >>> > >>> so I would love to keep it like this, if that's ok? > >> > >> Ok! > > > > Ack. > > > >>>>> + * > >>>>> + * @h_count_start: horizontal coordinate of the optical center (13-bit unsigned integer; [1,8191]) > >>>>> + * @v_count_start: vertical coordinate of the optical center (13-bit unsigned integer; [1,8191]) > >>>> > >>>> so these could go just before @x_nf > >>>> > >>>>> + * > >>>>> + * For each pixel, the x/y distances from the optical center are calculated and > >>>> > >>>> I forgot: did we establish that the correction is applied to the > >>>> euclidean distance or to x and y separately ? > >>> > >>> Given that there are two sets of "normalization" parameters, the assumption is that > >>> at least the x/y distances are transformed separately. I see two reasonable choices > >>> after that: (a) use the two distances separately, (b) use the radial distance. The > >>> documentation says (b). However, testing with sensor test patterns suggests that > >>> it is not the case (a horizontal/vertical boundary between appropriately colored > >>> regions should have a curvature after the transformation with appropriate parameters). > >> > >> I now recall that you have been able to shift just one plan when using > >> the sensor's test pattern > > > > I agree about the normalization, but it sounds really weird that the > > hardware would then shift separately in the X and Y directions. Below > > you document the radial correction formula, which looks correct to me. > > I think so, too. But if it uses the radial distance, I would expect the shifting to happen > along the radius. But that does not appear to be the case (e.g. y_nf=0 removes all vertical > correction). This could be explained by saying that the shifting actually happens along the > direction determined by the sum of the normalized distance vectors, but that seemed a bit > far fetched to me. It may not be that far fetched. The X and Y normalization factors are separate to support non-square pixels. Taking for example a pixel whose height is twice the width, the vertical distance in physical units is twice the vertical distance in pixels. The vertical normalization factor will be twice the horizontal factor to account for that and calculate a radius in physical units (as the displacement caused by the chromatic aberration depends on the physical distance to the image sensor). The pixel displacement then needs to be converted back to pixel units. Of course someone may point out that a normalization factor of 0 should result in an infinite vertical displacement when converting back. The above explanation may make no sense, or the hardware implementation may take some shortcuts that result in no vertical displacement when y_nf is 0. It could be interesting to vary y_nf and see how the vertical displacement evolves. > And even with that, I would expect to be able to turn a straight line > into a curve. Maybe I'm doing something wrong, but I can't recall ever being able to. > > >>>>> + * then transformed into the [0,255] range based on the following formula: > >>>> > >>>> s/transformed/normalized ? > >>> > >>> To be honest I vastly prefer "transform" / "map" over "normalize" here. > >> > >> You're right here, the below formula doesn't normalize the > >> distance in an interval but just re-scale it > >> > >>>>> + * > >>>>> + * (((d << 4) >> s) * f) >> 5 > >>>>> + * > >>>>> + * where `d` is the distance, `s` and `f` are the normalization parameters: > >>>> > >>>> Can you use 'ns' and 'nf' to match the below ? > >>> > >>> Adjusted. > >> > >> Thanks! > >> > >>>>> + * > >>>>> + * @x_nf: horizontal normalization scale parameter (5-bit unsigned integer; [0,31]) > >>>>> + * @x_ns: horizontal normalization shift parameter (4-bit unsigned integer; [0,15]) > >>>>> + * > >>>>> + * @y_nf: vertical normalization scale parameter (5-bit unsigned integer; [0,31]) > >>>>> + * @y_ns: vertical normalization shift parameter (4-bit unsigned integer; [0,15]) > >>>>> + * > >>>>> + * These parameters should be chosen based on the image resolution, the position > >>>>> + * of the optical center, and the shape of pixels: so that no normalized distance > >>>> > >>>> s/pixels:/pixels/ > >>> > >>> Replaced `:` with `,`. > >>> > >>>>> + * is larger than 255. If the pixels have square shape, the two sets of parameters > >>>>> + * should be equal. > > > > I wonder if we could have anisotropic lenses (from the point of view of > > chromatic aberrations) with square pixels. We can deal with it later. > > Right, this is what the documentation suggests, and I believe it is probably "correct enough" > most of the time. But should I remove it? > > >>>>> + * > >>>>> + * The actual amount of correction is calculated with a third degree polynomial: > >>>>> + * > >>>>> + * c[0] * r + c[1] * r^2 + c[2] * r^3 > >>>>> + * > >>>>> + * where `c` is the set of coefficients for the given color, and `r` is distance: > >>>>> + * > >>>>> + * @red: red coefficients (5.4 two's complement; [-16,15.9375]) > >>>>> + * @blue: blue coefficients (5.4 two's complement; [-16,15.9375]) > >>>>> + * > >>>>> + * Finally, the amount is clipped as requested: > >>>>> + * > >>>>> + * @h_clip_mode: maximum horizontal shift (from enum rkisp1_cif_isp_cac_h_clip_mode) > >>>>> + * @v_clip_mode: maximum vertical shift (from enum rkisp1_cif_isp_cac_v_clip_mode) > >>>>> + * > >>>>> + * A positive result will shift away from the optical center, while a negative > >>>>> + * one will shift towards the optical center. In the latter case, the pixel > >>>>> + * values at the edges are duplicated. > >>>>> + */ > >>>>> +struct rkisp1_cif_isp_cac_config { > >>>>> + __u8 h_clip_mode; > >>>>> + __u8 v_clip_mode; > >>>>> + > >>>>> + __u16 h_count_start; > >>>>> + __u16 v_count_start; > >>>>> + > >>>>> + __u16 red[3]; > >>>>> + __u16 blue[3]; > >>>>> + > >>>>> + __u8 x_nf; > >>>>> + __u8 x_ns; > >>>>> + > >>>>> + __u8 y_nf; > >>>>> + __u8 y_ns; > >>>>> +}; > >>>>> + > >>>>> /*---------- PART2: Measurement Statistics ------------*/ > >>>>> > >>>>> /** > >>>>> @@ -1161,6 +1247,7 @@ enum rkisp1_ext_params_block_type { > >>>>> RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND, > >>>>> RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS, > >>>>> RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR, > >>>>> + RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC, > >>>>> }; > >>>>> > >>>>> /* For backward compatibility */ > >>>>> @@ -1507,6 +1594,22 @@ struct rkisp1_ext_params_wdr_config { > >>>>> struct rkisp1_cif_isp_wdr_config config; > >>>>> } __attribute__((aligned(8))); > >>>>> > >>>>> +/** > >>>>> + * struct rkisp1_ext_params_cac_config - RkISP1 extensible params CAC config > >>>>> + * > >>>>> + * RkISP1 extensible parameters CAC block. > >>>>> + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC`. > >>>>> + * > >>>>> + * @header: The RkISP1 extensible parameters header, see > >>>>> + * :c:type:`rkisp1_ext_params_block_header` > >>>>> + * @config: CAC configuration, see > >>>>> + * :c:type:`rkisp1_cif_isp_cac_config` > >>>>> + */ > >>>>> +struct rkisp1_ext_params_cac_config { > >>>>> + struct rkisp1_ext_params_block_header header; > >>>>> + struct rkisp1_cif_isp_cac_config config; > >>>>> +} __attribute__((aligned(8))); > >>>>> + > >>>>> /* > >>>>> * The rkisp1_ext_params_compand_curve_config structure is counted twice as it > >>>>> * is used for both the COMPAND_EXPAND and COMPAND_COMPRESS block types. > >>>>> @@ -1532,7 +1635,8 @@ struct rkisp1_ext_params_wdr_config { > >>>>> sizeof(struct rkisp1_ext_params_compand_bls_config) +\ > >>>>> sizeof(struct rkisp1_ext_params_compand_curve_config) +\ > >>>>> sizeof(struct rkisp1_ext_params_compand_curve_config) +\ > >>>>> - sizeof(struct rkisp1_ext_params_wdr_config)) > >>>>> + sizeof(struct rkisp1_ext_params_wdr_config) +\ > >>>>> + sizeof(struct rkisp1_ext_params_cac_config)) > >>>> > >>>> All minors, please add > >>>> Reviewed-by: Jacopo Mondi > > > > and > > > > Reviewed-by: Laurent Pinchart > > > >>>>> > >>>>> /** > >>>>> * enum rksip1_ext_param_buffer_version - RkISP1 extensible parameters version -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 509A510F92E0 for ; Tue, 31 Mar 2026 16:15:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=WVRigOAOH5F1p2LkJxbgJI3CWqMOsLNaTai6t0fwN5M=; b=L/48UsAvQqr4hY C+0r+p/u/Mmnt8AZ2uT284pIEYaP5Qw742/l4Dfa8funBgbwM11/elAWwop//4mFGIVq4Jvf8y9a6 uUM72TBFbI4OyfC160LsEn9F9lUWJF+NqTq97md0tbYg/XGVRF7sGByErnssF3cWVD1U1n3hKj8bH 0IkurgRVKwGJuv5AYpdASs6C7eEtJ1AogqrqhZR338oYgvG7kTlFyhxM2aSuJuKu3mcznPB7rscE9 b7d4qFANP4MjPc8vuV940pJ30P+47wDtCgEhXBkGRbA61FRVw4PeISZ3bZ4CwBr04iBiQCGZN+eEG YWlJWdNobYcH63u0XN2Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1w7bkI-0000000DFIg-2wWU; Tue, 31 Mar 2026 16:15:14 +0000 Received: from perceval.ideasonboard.com ([213.167.242.64]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1w7bkG-0000000DFFq-0Bvb; Tue, 31 Mar 2026 16:15:13 +0000 Received: from killaraus.ideasonboard.com (2001-14ba-703d-e500--2a1.rev.dnainternet.fi [IPv6:2001:14ba:703d:e500::2a1]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 9A4D1316; Tue, 31 Mar 2026 18:13:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1774973625; bh=X9DLUqDirxP78ERBWuBb7M9vy72FmkWGBKCvgxS6PLc=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=gufU9QZwxiaCy/dKK6MO/NyomEBr4hZr+Pkcj8H7Opvpck0RB3FSgTO0pRcHzk4ya BnzveGIseVY7dND6ZjyPe9lrnsF8eOzNaTn3x2oK58K9awslOAgLdxZRr3LDPy33qB BtP+0B18lDJElX4eAVxP3diMFYylOtUrlpEp8PEI= Date: Tue, 31 Mar 2026 19:15:06 +0300 From: Laurent Pinchart To: =?utf-8?Q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi , Dafna Hirschfeld , Mauro Carvalho Chehab , Heiko Stuebner , linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v1] media: rkisp1: Add support for CAC Message-ID: <20260331161506.GD3357297@killaraus.ideasonboard.com> References: <20260323140216.1486161-1-barnabas.pocze@ideasonboard.com> <6c7ffd2d-94fa-4408-ac24-1e7adac95e5d@ideasonboard.com> <20260331133934.GC3357297@killaraus.ideasonboard.com> <5a7d1894-ee12-42b6-b40c-4d0e0b370974@ideasonboard.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <5a7d1894-ee12-42b6-b40c-4d0e0b370974@ideasonboard.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260331_091512_401103_4A021E32 X-CRM114-Status: GOOD ( 42.99 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org T24gVHVlLCBNYXIgMzEsIDIwMjYgYXQgMDU6MjQ6MzhQTSArMDIwMCwgQmFybmFiw6FzIFDFkWN6 ZSB3cm90ZToKPiAyMDI2LiAwMy4gMzEuIDE1OjM5IGtlbHRlesOpc3NlbCwgTGF1cmVudCBQaW5j aGFydCDDrXJ0YToKPiA+IE9uIFR1ZSwgTWFyIDMxLCAyMDI2IGF0IDAyOjQyOjMzUE0gKzAyMDAs IEphY29wbyBNb25kaSB3cm90ZToKPiA+PiBPbiBNb24sIE1hciAzMCwgMjAyNiBhdCAwNDo0MDox OFBNICswMjAwLCBCYXJuYWLDoXMgUMWRY3plIHdyb3RlOgo+ID4+PiAyMDI2LiAwMy4gMjUuIDE2 OjIxIGtlbHRlesOpc3NlbCwgSmFjb3BvIE1vbmRpIMOtcnRhOgo+ID4+Pj4gT24gTW9uLCBNYXIg MjMsIDIwMjYgYXQgMDM6MDI6MTZQTSArMDEwMCwgQmFybmFiw6FzIFDFkWN6ZSB3cm90ZToKPiA+ Pj4+PiBUaGUgQ0FDIGJsb2NrIGltcGxlbWVudHMgY2hyb21hdGljIGFiZXJyYXRpb24gY29ycmVj dGlvbi4gRXhwb3NlIGl0IHRvCj4gPj4+Pj4gdXNlcnNwYWNlIHVzaW5nIHRoZSBleHRlbnNpYmxl IHBhcmFtZXRlcnMgZm9ybWF0LiBUaGlzIHdhcyB0ZXN0ZWQgb24gdGhlCj4gPj4+Pj4gaS5NWDhN UCBwbGF0Zm9ybSwgYnV0IGJhc2VkIG9uIGF2YWlsYWJsZSBkb2N1bWVudGF0aW9uIGl0IGlzIGFs c28gcHJlc2VudAo+ID4+Pj4+IGluIHRoZSBSSzMzOTkgdmFyaWFudCAoVjEwKS4gVGh1cyBwcmVz dW1hYmx5IGFsc28gaW4gbGF0ZXIgdmVyc2lvbnMsCj4gPj4+Pj4gc28gbm8gZmVhdHVyZSBmbGFn IGlzIGludHJvZHVjZWQuCj4gPj4+Pj4KPiA+Pj4+PiBTaWduZWQtb2ZmLWJ5OiBCYXJuYWLDoXMg UMWRY3plIDxiYXJuYWJhcy5wb2N6ZUBpZGVhc29uYm9hcmQuY29tPgo+ID4+Pj4KPiA+Pj4+IE9u bHkgbWlub3JzLi4KPiA+Pj4+Cj4gPj4+Pj4gLS0tCj4gPj4+Pj4gICAgLi4uL3BsYXRmb3JtL3Jv Y2tjaGlwL3JraXNwMS9ya2lzcDEtcGFyYW1zLmMgIHwgIDY5ICsrKysrKysrKysrKwo+ID4+Pj4+ ICAgIC4uLi9wbGF0Zm9ybS9yb2NrY2hpcC9ya2lzcDEvcmtpc3AxLXJlZ3MuaCAgICB8ICAyMSAr KystCj4gPj4+Pj4gICAgaW5jbHVkZS91YXBpL2xpbnV4L3JraXNwMS1jb25maWcuaCAgICAgICAg ICAgIHwgMTA2ICsrKysrKysrKysrKysrKysrLQo+ID4+Pj4+ICAgIDMgZmlsZXMgY2hhbmdlZCwg MTkzIGluc2VydGlvbnMoKyksIDMgZGVsZXRpb25zKC0pCj4gPj4+Pj4KPiA+Pj4+PiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9yb2NrY2hpcC9ya2lzcDEvcmtpc3AxLXBhcmFt cy5jIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9yb2NrY2hpcC9ya2lzcDEvcmtpc3AxLXBhcmFt cy5jCj4gPj4+Pj4gaW5kZXggNjQ0MjQzNmE1ZTQyOC4uYjg4OWFmOWRjZWU0NSAxMDA2NDQKPiA+ Pj4+PiAtLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3JvY2tjaGlwL3JraXNwMS9ya2lzcDEt cGFyYW1zLmMKPiA+Pj4+PiArKysgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3JvY2tjaGlwL3Jr aXNwMS9ya2lzcDEtcGFyYW1zLmMKPiA+Pj4+PiBAQCAtNjQsNiArNjQsNyBAQCB1bmlvbiBya2lz cDFfZXh0X3BhcmFtc19jb25maWcgewo+ID4+Pj4+ICAgIAlzdHJ1Y3Qgcmtpc3AxX2V4dF9wYXJh bXNfY29tcGFuZF9ibHNfY29uZmlnIGNvbXBhbmRfYmxzOwo+ID4+Pj4+ICAgIAlzdHJ1Y3Qgcmtp c3AxX2V4dF9wYXJhbXNfY29tcGFuZF9jdXJ2ZV9jb25maWcgY29tcGFuZF9jdXJ2ZTsKPiA+Pj4+ PiAgICAJc3RydWN0IHJraXNwMV9leHRfcGFyYW1zX3dkcl9jb25maWcgd2RyOwo+ID4+Pj4+ICsJ c3RydWN0IHJraXNwMV9leHRfcGFyYW1zX2NhY19jb25maWcgY2FjOwo+ID4+Pj4+ICAgIH07Cj4g Pj4+Pj4KPiA+Pj4+PiAgICBlbnVtIHJraXNwMV9wYXJhbXNfZm9ybWF0cyB7Cj4gPj4+Pj4gQEAg LTE0MTMsNiArMTQxNCw0OCBAQCBzdGF0aWMgdm9pZCBya2lzcDFfd2RyX2NvbmZpZyhzdHJ1Y3Qg cmtpc3AxX3BhcmFtcyAqcGFyYW1zLAo+ID4+Pj4+ICAgIAkJCQkgICAgIFJLSVNQMV9DSUZfSVNQ X1dEUl9UT05FX0NVUlZFX1lNX01BU0spOwo+ID4+Pj4+ICAgIH0KPiA+Pj4+Pgo+ID4+Pj4+ICtz dGF0aWMgdm9pZAo+ID4+Pj4+ICtya2lzcDFfY2FjX2NvbmZpZyhzdHJ1Y3Qgcmtpc3AxX3BhcmFt cyAqcGFyYW1zLAo+ID4+Pj4+ICsJCSAgY29uc3Qgc3RydWN0IHJraXNwMV9jaWZfaXNwX2NhY19j b25maWcgKmFyZykKPiA+Pj4+Cj4gPj4+PiBGaXRzIGluIG9uZSBsaW5lIHdpdGhvdXQgZ29pbmcg b3ZlciA4MCBjb2xzCj4gPj4+Cj4gPj4+IFRoaXMgaXMgd2hhdCB0aGUgb3RoZXIgZnVuY3Rpb25z IGxvb2tzIGxpa2UsIHNvIHdlbnQgdGhpcyB0aGlzLgo+ID4+Cj4gPj4gSXQgc2VlbXMgdG8gbWUg bm90IGFsbCBvZiB0aGVtIGFyZSBicm9rZW4sIGJ1dCBvbmx5IHRoZSBvbmVzIHRoYXQgZ28KPiA+ PiBvdmVyIDgwIGNvbHMKPiAKPiBJIHRoaW5rIEkgbWlzdW5kZXJzdG9vZCBpbml0aWFsbHkuIEFk anVzdGVkIG5vdy4KPiAKPiA+PiBpbiBleGFtcGxlOgo+ID4+Cj4gPj4gc3RhdGljIHZvaWQgcmtp c3AxX2RwZl9jb25maWcoc3RydWN0IHJraXNwMV9wYXJhbXMgKnBhcmFtcywKPiA+PiAJCQkgICAg ICBjb25zdCBzdHJ1Y3Qgcmtpc3AxX2NpZl9pc3BfZHBmX2NvbmZpZyAqYXJnKQo+ID4+Cj4gPj4g QSBkZXRhaWwgYW55d2F5LCB1cCB0byB5b3UKPiA+Pgo+ID4+Pj4+ICt7Cj4gPj4+Pj4gKwl1MzIg cmVndmFsOwo+ID4gCj4gPiBBbGwgb3RoZXIgZnVuY3Rpb25zIGluIHRoaXMgZmlsZSBuYW1lIHNp bWlsYXIgdmFyaWFibGVzICJ2YWwiLCAidmFsdWUiCj4gPiBvciAicmVnX3ZhbCIuIExldCdzIG5v dCBpbnRyb2R1Y2UgYSBmb3VydGggb25lLiBJIGhhdmUgYSBzbWFsbAo+ID4gcHJlZmVyZW5jZSBm b3IgInZhbCIsIGJ1dCB0aGF0J3Mgbm90IG1hbmRhdG9yeS4KPiAKPiBBZGp1c3RlZC4KPiAKPiA+ Pj4+PiArCj4gPj4+Pj4gKwkvKgo+ID4+Pj4+ICsJICogVGhlIGVuYWJsZSBiaXQgaXMgaW4gdGhl IHNhbWUgcmVnaXN0ZXIgKFJLSVNQMV9DSUZfSVNQX0NBQ19DVFJMKSwKPiA+Pj4+PiArCSAqIHNv IG9ubHkgc2V0IHRoZSBjbGlwcGluZyBtb2RlLCBhbmQgZG8gbm90IG1vZGlmeSB0aGUgb3RoZXIg Yml0cy4KPiA+Pj4+PiArCSAqLwo+ID4+Pj4+ICsJcmVndmFsID0gcmtpc3AxX3JlYWQocGFyYW1z LT5ya2lzcDEsIFJLSVNQMV9DSUZfSVNQX0NBQ19DVFJMKTsKPiA+Pj4+PiArCXJlZ3ZhbCAmPSB+ KFJLSVNQMV9DSUZfSVNQX0NBQ19DVFJMX0hfQ0xJUF9NT0RFIHwKPiA+Pj4+PiArCQkgICAgUktJ U1AxX0NJRl9JU1BfQ0FDX0NUUkxfVl9DTElQX01PREUpOwo+ID4+Pj4+ICsJcmVndmFsIHw9IEZJ RUxEX1BSRVAoUktJU1AxX0NJRl9JU1BfQ0FDX0NUUkxfSF9DTElQX01PREUsIGFyZy0+aF9jbGlw X21vZGUpIHwKPiA+Pj4+PiArCQkgIEZJRUxEX1BSRVAoUktJU1AxX0NJRl9JU1BfQ0FDX0NUUkxf Vl9DTElQX01PREUsIGFyZy0+dl9jbGlwX21vZGUpOwo+ID4+Pj4+ICsJcmtpc3AxX3dyaXRlKHBh cmFtcy0+cmtpc3AxLCBSS0lTUDFfQ0lGX0lTUF9DQUNfQ1RSTCwgcmVndmFsKTsKPiA+Pj4+PiAr Cj4gPj4+Pj4gKwlyZWd2YWwgPSBGSUVMRF9QUkVQKFJLSVNQMV9DSUZfSVNQX0NBQ19DT1VOVF9T VEFSVF9IX01BU0ssIGFyZy0+aF9jb3VudF9zdGFydCkgfAo+ID4+Pj4+ICsJCSBGSUVMRF9QUkVQ KFJLSVNQMV9DSUZfSVNQX0NBQ19DT1VOVF9TVEFSVF9WX01BU0ssIGFyZy0+dl9jb3VudF9zdGFy dCk7Cj4gPj4+Pj4gKwlya2lzcDFfd3JpdGUocGFyYW1zLT5ya2lzcDEsIFJLSVNQMV9DSUZfSVNQ X0NBQ19DT1VOVF9TVEFSVCwgcmVndmFsKTsKPiA+Pj4+PiArCj4gPj4+Pj4gKwlyZWd2YWwgPSBG SUVMRF9QUkVQKFJLSVNQMV9DSUZfSVNQX0NBQ19BX1JFRF9NQVNLLCBhcmctPnJlZFswXSkgfAo+ ID4+Pj4+ICsJCSBGSUVMRF9QUkVQKFJLSVNQMV9DSUZfSVNQX0NBQ19BX0JMVUVfTUFTSywgYXJn LT5ibHVlWzBdKTsKPiA+Pj4+PiArCXJraXNwMV93cml0ZShwYXJhbXMtPnJraXNwMSwgUktJU1Ax X0NJRl9JU1BfQ0FDX0EsIHJlZ3ZhbCk7Cj4gPj4+Pj4gKwo+ID4+Pj4+ICsJcmVndmFsID0gRklF TERfUFJFUChSS0lTUDFfQ0lGX0lTUF9DQUNfQl9SRURfTUFTSywgYXJnLT5yZWRbMV0pIHwKPiA+ Pj4+PiArCQkgRklFTERfUFJFUChSS0lTUDFfQ0lGX0lTUF9DQUNfQl9CTFVFX01BU0ssIGFyZy0+ Ymx1ZVsxXSk7Cj4gPj4+Pj4gKwlya2lzcDFfd3JpdGUocGFyYW1zLT5ya2lzcDEsIFJLSVNQMV9D SUZfSVNQX0NBQ19CLCByZWd2YWwpOwo+ID4+Pj4+ICsKPiA+Pj4+PiArCXJlZ3ZhbCA9IEZJRUxE X1BSRVAoUktJU1AxX0NJRl9JU1BfQ0FDX0NfUkVEX01BU0ssIGFyZy0+cmVkWzJdKSB8Cj4gPj4+ Pj4gKwkJIEZJRUxEX1BSRVAoUktJU1AxX0NJRl9JU1BfQ0FDX0NfQkxVRV9NQVNLLCBhcmctPmJs dWVbMl0pOwo+ID4+Pj4+ICsJcmtpc3AxX3dyaXRlKHBhcmFtcy0+cmtpc3AxLCBSS0lTUDFfQ0lG X0lTUF9DQUNfQywgcmVndmFsKTsKPiA+Pj4+PiArCj4gPj4+Pj4gKwlyZWd2YWwgPSBGSUVMRF9Q UkVQKFJLSVNQMV9DSUZfSVNQX0NBQ19YX05PUk1fTkZfTUFTSywgYXJnLT54X25mKSB8Cj4gPj4+ Pj4gKwkJIEZJRUxEX1BSRVAoUktJU1AxX0NJRl9JU1BfQ0FDX1hfTk9STV9OU19NQVNLLCBhcmct PnhfbnMpOwo+ID4+Pj4+ICsJcmtpc3AxX3dyaXRlKHBhcmFtcy0+cmtpc3AxLCBSS0lTUDFfQ0lG X0lTUF9DQUNfWF9OT1JNLCByZWd2YWwpOwo+ID4+Pj4+ICsKPiA+Pj4+PiArCXJlZ3ZhbCA9IEZJ RUxEX1BSRVAoUktJU1AxX0NJRl9JU1BfQ0FDX1lfTk9STV9ORl9NQVNLLCBhcmctPnlfbmYpIHwK PiA+Pj4+PiArCQkgRklFTERfUFJFUChSS0lTUDFfQ0lGX0lTUF9DQUNfWV9OT1JNX05TX01BU0ss IGFyZy0+eV9ucyk7Cj4gPj4+Pj4gKwlya2lzcDFfd3JpdGUocGFyYW1zLT5ya2lzcDEsIFJLSVNQ MV9DSUZfSVNQX0NBQ19ZX05PUk0sIHJlZ3ZhbCk7Cj4gPj4+Pj4gK30KPiA+Pj4+PiArCj4gPj4+ Pj4gICAgc3RhdGljIHZvaWQKPiA+Pj4+PiAgICBya2lzcDFfaXNwX2lzcl9vdGhlcl9jb25maWco c3RydWN0IHJraXNwMV9wYXJhbXMgKnBhcmFtcywKPiA+Pj4+PiAgICAJCQkgICAgY29uc3Qgc3Ry dWN0IHJraXNwMV9wYXJhbXNfY2ZnICpuZXdfcGFyYW1zKQo+ID4+Pj4+IEBAIC0yMDg5LDYgKzIx MzIsMjUgQEAgc3RhdGljIHZvaWQgcmtpc3AxX2V4dF9wYXJhbXNfd2RyKHN0cnVjdCBya2lzcDFf cGFyYW1zICpwYXJhbXMsCj4gPj4+Pj4gICAgCQkJCSAgICAgIFJLSVNQMV9DSUZfSVNQX1dEUl9D VFJMX0VOQUJMRSk7Cj4gPj4+Pj4gICAgfQo+ID4+Pj4+Cj4gPj4+Pj4gK3N0YXRpYyB2b2lkIHJr aXNwMV9leHRfcGFyYW1zX2NhYyhzdHJ1Y3Qgcmtpc3AxX3BhcmFtcyAqcGFyYW1zLAo+ID4+Pj4+ ICsJCQkJICBjb25zdCB1bmlvbiBya2lzcDFfZXh0X3BhcmFtc19jb25maWcgKmJsb2NrKQo+ID4+ Pj4+ICt7Cj4gPj4+Pj4gKwljb25zdCBzdHJ1Y3Qgcmtpc3AxX2V4dF9wYXJhbXNfY2FjX2NvbmZp ZyAqY2FjID0gJmJsb2NrLT5jYWM7Cj4gPj4+Pj4gKwo+ID4+Pj4+ICsJaWYgKGNhYy0+aGVhZGVy LmZsYWdzICYgUktJU1AxX0VYVF9QQVJBTVNfRkxfQkxPQ0tfRElTQUJMRSkgewo+ID4+Pj4+ICsJ CXJraXNwMV9wYXJhbV9jbGVhcl9iaXRzKHBhcmFtcywgUktJU1AxX0NJRl9JU1BfQ0FDX0NUUkws Cj4gPj4+Pj4gKwkJCQkJUktJU1AxX0NJRl9JU1BfQ0FDX0NUUkxfRU5BQkxFKTsKPiA+Pj4+PiAr CQlyZXR1cm47Cj4gPj4+Pj4gKwl9Cj4gPj4+Pj4gKwo+ID4+Pj4+ICsJcmtpc3AxX2NhY19jb25m aWcocGFyYW1zLCAmY2FjLT5jb25maWcpOwo+ID4+Pj4+ICsKPiA+Pj4+PiArCWlmICgoY2FjLT5o ZWFkZXIuZmxhZ3MgJiBSS0lTUDFfRVhUX1BBUkFNU19GTF9CTE9DS19FTkFCTEUpICYmCj4gPj4+ Pj4gKwkgICAgIShwYXJhbXMtPmVuYWJsZWRfYmxvY2tzICYgQklUKGNhYy0+aGVhZGVyLnR5cGUp KSkKPiA+Pj4+PiArCQlya2lzcDFfcGFyYW1fc2V0X2JpdHMocGFyYW1zLCBSS0lTUDFfQ0lGX0lT UF9DQUNfQ1RSTCwKPiA+Pj4+PiArCQkJCSAgICAgIFJLSVNQMV9DSUZfSVNQX0NBQ19DVFJMX0VO QUJMRSk7Cj4gPj4+Pj4gK30KPiA+Pj4+PiArCj4gPj4+Pj4gICAgdHlwZWRlZiB2b2lkICgqcmtp c3AxX2Jsb2NrX2hhbmRsZXIpKHN0cnVjdCBya2lzcDFfcGFyYW1zICpwYXJhbXMsCj4gPj4+Pj4g ICAgCQkJICAgICBjb25zdCB1bmlvbiBya2lzcDFfZXh0X3BhcmFtc19jb25maWcgKmNvbmZpZyk7 Cj4gPj4+Pj4KPiA+Pj4+PiBAQCAtMjE4NSw2ICsyMjQ3LDEwIEBAIHN0YXRpYyBjb25zdCBzdHJ1 Y3Qgcmtpc3AxX2V4dF9wYXJhbXNfaGFuZGxlciB7Cj4gPj4+Pj4gICAgCQkuaGFuZGxlcgk9IHJr aXNwMV9leHRfcGFyYW1zX3dkciwKPiA+Pj4+PiAgICAJCS5ncm91cAkJPSBSS0lTUDFfRVhUX1BB UkFNU19CTE9DS19HUk9VUF9PVEhFUlMsCj4gPj4+Pj4gICAgCX0sCj4gPj4+Pj4gKwlbUktJU1Ax X0VYVF9QQVJBTVNfQkxPQ0tfVFlQRV9DQUNdID0gewo+ID4+Pj4+ICsJCS5oYW5kbGVyCT0gcmtp c3AxX2V4dF9wYXJhbXNfY2FjLAo+ID4+Pj4+ICsJCS5ncm91cAkJPSBSS0lTUDFfRVhUX1BBUkFN U19CTE9DS19HUk9VUF9PVEhFUlMsCj4gPj4+Pj4gKwl9LAo+ID4+Pj4+ICAgIH07Cj4gPj4+Pj4K PiA+Pj4+PiAgICAjZGVmaW5lIFJLSVNQMV9QQVJBTVNfQkxPQ0tfSU5GTyhibG9jaywgZGF0YSkg XAo+ID4+Pj4+IEBAIC0yMjE1LDYgKzIyODEsNyBAQCBya2lzcDFfZXh0X3BhcmFtc19ibG9ja190 eXBlc19pbmZvW10gPSB7Cj4gPj4+Pj4gICAgCVJLSVNQMV9QQVJBTVNfQkxPQ0tfSU5GTyhDT01Q QU5EX0VYUEFORCwgY29tcGFuZF9jdXJ2ZSksCj4gPj4+Pj4gICAgCVJLSVNQMV9QQVJBTVNfQkxP Q0tfSU5GTyhDT01QQU5EX0NPTVBSRVNTLCBjb21wYW5kX2N1cnZlKSwKPiA+Pj4+PiAgICAJUktJ U1AxX1BBUkFNU19CTE9DS19JTkZPKFdEUiwgd2RyKSwKPiA+Pj4+PiArCVJLSVNQMV9QQVJBTVNf QkxPQ0tfSU5GTyhDQUMsIGNhYyksCj4gPj4+Pj4gICAgfTsKPiA+Pj4+Pgo+ID4+Pj4+ICAgIHN0 YXRpY19hc3NlcnQoQVJSQVlfU0laRShya2lzcDFfZXh0X3BhcmFtc19oYW5kbGVycykgPT0KPiA+ Pj4+PiBAQCAtMjQ3NCw2ICsyNTQxLDggQEAgdm9pZCBya2lzcDFfcGFyYW1zX2Rpc2FibGUoc3Ry dWN0IHJraXNwMV9wYXJhbXMgKnBhcmFtcykKPiA+Pj4+PiAgICAJcmtpc3AxX2llX2VuYWJsZShw YXJhbXMsIGZhbHNlKTsKPiA+Pj4+PiAgICAJcmtpc3AxX3BhcmFtX2NsZWFyX2JpdHMocGFyYW1z LCBSS0lTUDFfQ0lGX0lTUF9EUEZfTU9ERSwKPiA+Pj4+PiAgICAJCQkJUktJU1AxX0NJRl9JU1Bf RFBGX01PREVfRU4pOwo+ID4+Pj4+ICsJcmtpc3AxX3BhcmFtX2NsZWFyX2JpdHMocGFyYW1zLCBS S0lTUDFfQ0lGX0lTUF9DQUNfQ1RSTCwKPiA+Pj4+PiArCQkJCVJLSVNQMV9DSUZfSVNQX0NBQ19D VFJMX0VOQUJMRSk7Cj4gPj4+Pj4gICAgfQo+ID4+Pj4+Cj4gPj4+Pj4gICAgc3RhdGljIGNvbnN0 IHN0cnVjdCBya2lzcDFfcGFyYW1zX29wcyBya2lzcDFfdjEwX3BhcmFtc19vcHMgPSB7Cj4gPj4+ Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vcm9ja2NoaXAvcmtpc3AxL3Jr aXNwMS1yZWdzLmggYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3JvY2tjaGlwL3JraXNwMS9ya2lz cDEtcmVncy5oCj4gPj4+Pj4gaW5kZXggZmJlYjE4NmNkZTBkNS4uOGUyNTUzNzQ1OWJiZCAxMDA2 NDQKPiA+Pj4+PiAtLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3JvY2tjaGlwL3JraXNwMS9y a2lzcDEtcmVncy5oCj4gPj4+Pj4gKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9yb2NrY2hp cC9ya2lzcDEvcmtpc3AxLXJlZ3MuaAo+ID4+Pj4+IEBAIC03MjQsNiArNzI0LDIzIEBACj4gPj4+ Pj4gICAgI2RlZmluZSBSS0lTUDFfQ0lGX0lTUF9XRFJfRE1JTl9TVFJFTkdUSF9NQVNLCQlHRU5N QVNLKDIwLCAxNikKPiA+Pj4+PiAgICAjZGVmaW5lIFJLSVNQMV9DSUZfSVNQX1dEUl9ETUlOX1NU UkVOR1RIX01BWAkJMTZVCj4gPj4+Pj4KPiA+Pj4+PiArLyogQ0FDICovCj4gPj4+Pj4gKyNkZWZp bmUgUktJU1AxX0NJRl9JU1BfQ0FDX0NUUkxfRU5BQkxFCQlCSVQoMCkKPiA+Pj4+PiArI2RlZmlu ZSBSS0lTUDFfQ0lGX0lTUF9DQUNfQ1RSTF9WX0NMSVBfTU9ERQlHRU5NQVNLKDIsIDEpCj4gPj4+ Pj4gKyNkZWZpbmUgUktJU1AxX0NJRl9JU1BfQ0FDX0NUUkxfSF9DTElQX01PREUJR0VOTUFTSygz LCAzKQo+ID4gCj4gPiBJJ2QgZ28gZm9yIEJJVCgzKSBhcyB5b3UgdXNlIEJJVCgwKSBmb3IgdGhl IGVuYWJsZSBiaXQuCj4gCj4gQWRqdXN0ZWQuCj4gCj4gPj4+Pj4gKyNkZWZpbmUgUktJU1AxX0NJ Rl9JU1BfQ0FDX0NPVU5UX1NUQVJUX0hfTUFTSwlHRU5NQVNLKDEyLCAwKQo+ID4+Pj4+ICsjZGVm aW5lIFJLSVNQMV9DSUZfSVNQX0NBQ19DT1VOVF9TVEFSVF9WX01BU0sJR0VOTUFTSygyOCwgMTYp Cj4gPj4+Pj4gKyNkZWZpbmUgUktJU1AxX0NJRl9JU1BfQ0FDX0FfUkVEX01BU0sJCUdFTk1BU0so OCwgMCkKPiA+Pj4+PiArI2RlZmluZSBSS0lTUDFfQ0lGX0lTUF9DQUNfQV9CTFVFX01BU0sJCUdF Tk1BU0soMjQsIDE2KQo+ID4+Pj4+ICsjZGVmaW5lIFJLSVNQMV9DSUZfSVNQX0NBQ19CX1JFRF9N QVNLCQlHRU5NQVNLKDgsIDApCj4gPj4+Pj4gKyNkZWZpbmUgUktJU1AxX0NJRl9JU1BfQ0FDX0Jf QkxVRV9NQVNLCQlHRU5NQVNLKDI0LCAxNikKPiA+Pj4+PiArI2RlZmluZSBSS0lTUDFfQ0lGX0lT UF9DQUNfQ19SRURfTUFTSwkJR0VOTUFTSyg4LCAwKQo+ID4+Pj4+ICsjZGVmaW5lIFJLSVNQMV9D SUZfSVNQX0NBQ19DX0JMVUVfTUFTSwkJR0VOTUFTSygyNCwgMTYpCj4gPj4+Pgo+ID4+Pj4gQWxs IHRoZXNlIG1hc2tzIGZvciBjb2VmZmljaWVudHMgMCwgMSBhbmQgMiBhcmUgaWRlbnRpY2FsLiBN YXliZQo+ID4+Pj4gI2RlZmluZSBSS0lTUDFfQ0lGX0lTUF9DQUNfUkVEX01BU0sJCUdFTk1BU0so OCwgMCkKPiA+Pj4+ICNkZWZpbmUgUktJU1AxX0NJRl9JU1BfQ0FDX0JMVUVfTUFTSwkJR0VOTUFT SygyNCwgMTYpCj4gPj4+Pgo+ID4+Pj4gaXMgZW5vdWdoCj4gPj4+Cj4gPj4+IEFkanVzdGVkLgo+ ID4+Pgo+ID4+Pj4+ICsjZGVmaW5lIFJLSVNQMV9DSUZfSVNQX0NBQ19YX05PUk1fTkZfTUFTSwlH RU5NQVNLKDQsIDApCj4gPj4+Pj4gKyNkZWZpbmUgUktJU1AxX0NJRl9JU1BfQ0FDX1hfTk9STV9O U19NQVNLCUdFTk1BU0soMTksIDE2KQo+ID4+Pj4+ICsjZGVmaW5lIFJLSVNQMV9DSUZfSVNQX0NB Q19ZX05PUk1fTkZfTUFTSwlHRU5NQVNLKDQsIDApCj4gPj4+Pj4gKyNkZWZpbmUgUktJU1AxX0NJ Rl9JU1BfQ0FDX1lfTk9STV9OU19NQVNLCUdFTk1BU0soMTksIDE2KQo+ID4+Pgo+ID4+PiBEaWQg dGhlIHNhbWUgd2l0aCB0aGVzZSBhcyB3ZWxsLgo+ID4+Cj4gPj4gQWggdGhhbmtzIQo+ID4+Cj4g Pj4+Pj4gKwo+ID4+Pj4+ICAgIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KPiA+Pj4+PiAgICAvKiAgICAgICAg ICAgICAgICAgICAgICAgICAgICBDSUYgUmVnaXN0ZXJzICAgICAgICAgICAgICAgICAgICAgICAg ICAgICovCj4gPj4+Pj4gICAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwo+ID4+Pj4+IEBAIC0xMTk2LDggKzEy MTMsOCBAQAo+ID4+Pj4+ICAgICNkZWZpbmUgUktJU1AxX0NJRl9JU1BfQ0FDX0EJCQkoUktJU1Ax X0NJRl9JU1BfQ0FDX0JBU0UgKyAweDAwMDAwMDA4KQo+ID4+Pj4+ICAgICNkZWZpbmUgUktJU1Ax X0NJRl9JU1BfQ0FDX0IJCQkoUktJU1AxX0NJRl9JU1BfQ0FDX0JBU0UgKyAweDAwMDAwMDBjKQo+ ID4+Pj4+ICAgICNkZWZpbmUgUktJU1AxX0NJRl9JU1BfQ0FDX0MJCQkoUktJU1AxX0NJRl9JU1Bf Q0FDX0JBU0UgKyAweDAwMDAwMDEwKQo+ID4+Pj4+IC0jZGVmaW5lIFJLSVNQMV9DSUZfSVNQX1hf Tk9STQkJCShSS0lTUDFfQ0lGX0lTUF9DQUNfQkFTRSArIDB4MDAwMDAwMTQpCj4gPj4+Pj4gLSNk ZWZpbmUgUktJU1AxX0NJRl9JU1BfWV9OT1JNCQkJKFJLSVNQMV9DSUZfSVNQX0NBQ19CQVNFICsg MHgwMDAwMDAxOCkKPiA+Pj4+PiArI2RlZmluZSBSS0lTUDFfQ0lGX0lTUF9DQUNfWF9OT1JNCQko UktJU1AxX0NJRl9JU1BfQ0FDX0JBU0UgKyAweDAwMDAwMDE0KQo+ID4+Pj4+ICsjZGVmaW5lIFJL SVNQMV9DSUZfSVNQX0NBQ19ZX05PUk0JCShSS0lTUDFfQ0lGX0lTUF9DQUNfQkFTRSArIDB4MDAw MDAwMTgpCj4gPj4+Pj4KPiA+Pj4+PiAgICAjZGVmaW5lIFJLSVNQMV9DSUZfSVNQX0VYUF9CQVNF CQkJMHgwMDAwMjYwMAo+ID4+Pj4+ICAgICNkZWZpbmUgUktJU1AxX0NJRl9JU1BfRVhQX0NUUkwJ CQkoUktJU1AxX0NJRl9JU1BfRVhQX0JBU0UgKyAweDAwMDAwMDAwKQo+ID4+Pj4+IGRpZmYgLS1n aXQgYS9pbmNsdWRlL3VhcGkvbGludXgvcmtpc3AxLWNvbmZpZy5oIGIvaW5jbHVkZS91YXBpL2xp bnV4L3JraXNwMS1jb25maWcuaAo+ID4+Pj4+IGluZGV4IGIyZDJhNzFmN2JhZmYuLmQ4YWNjY2Fk ZGQwZTkgMTAwNjQ0Cj4gPj4+Pj4gLS0tIGEvaW5jbHVkZS91YXBpL2xpbnV4L3JraXNwMS1jb25m aWcuaAo+ID4+Pj4+ICsrKyBiL2luY2x1ZGUvdWFwaS9saW51eC9ya2lzcDEtY29uZmlnLmgKPiA+ Pj4+PiBAQCAtOTY3LDYgKzk2Nyw5MiBAQCBzdHJ1Y3Qgcmtpc3AxX2NpZl9pc3Bfd2RyX2NvbmZp ZyB7Cj4gPj4+Pj4gICAgCV9fdTggdXNlX2lyZWY7Cj4gPj4+Pj4gICAgfTsKPiA+Pj4+Pgo+ID4+ Pj4+ICsvKgo+ID4+Pj4+ICsgKiBlbnVtIHJraXNwMV9jaWZfaXNwX2NhY19oX2NsaXBfbW9kZSAt IGhvcml6b250YWwgY2xpcHBpbmcgbW9kZQo+ID4+Pj4+ICsgKgo+ID4+Pj4+ICsgKiBAUktJU1Ax X0NJRl9JU1BfQ0FDX0hfQ0xJUF9NT0RFXzRQWDogKy8tIDQgcGl4ZWxzCj4gPj4+Pj4gKyAqIEBS S0lTUDFfQ0lGX0lTUF9DQUNfSF9DTElQX01PREVfNF81UFg6ICsvLSA0LzUgcGl4ZWxzIGRlcGVu ZGluZyBvbiBiYXllciBwb3NpdGlvbgo+ID4+Pj4+ICsgKi8KPiA+Pj4+PiArZW51bSBya2lzcDFf Y2lmX2lzcF9jYWNfaF9jbGlwX21vZGUgewo+ID4+Pj4+ICsJUktJU1AxX0NJRl9JU1BfQ0FDX0hf Q0xJUF9NT0RFXzRQWCA9IDAsCj4gPj4+Pj4gKwlSS0lTUDFfQ0lGX0lTUF9DQUNfSF9DTElQX01P REVfNF81UFggPSAxLAo+ID4+Pj4+ICt9Owo+ID4+Pj4+ICsKPiA+Pj4+PiArLyoqCj4gPj4+Pj4g KyAqIGVudW0gcmtpc3AxX2NpZl9pc3BfY2FjX3ZfY2xpcF9tb2RlIC0gdmVydGljYWwgY2xpcHBp bmcgbW9kZQo+ID4+Pj4+ICsgKgo+ID4+Pj4+ICsgKiBAUktJU1AxX0NJRl9JU1BfQ0FDX1ZfQ0xJ UF9NT0RFXzJQWDogKy8tIDIgcGl4ZWxzCj4gPj4+Pj4gKyAqIEBSS0lTUDFfQ0lGX0lTUF9DQUNf Vl9DTElQX01PREVfM1BYOiArLy0gMyBwaXhlbHMKPiA+Pj4+PiArICogQFJLSVNQMV9DSUZfSVNQ X0NBQ19WX0NMSVBfTU9ERV8zXzRQWDogKy8tIDMvNCBwaXhlbHMgZGVwZW5kaW5nIG9uIGJheWVy IHBvc2l0aW9uCj4gPj4+Pj4gKyAqLwo+ID4+Pj4+ICtlbnVtIHJraXNwMV9jaWZfaXNwX2NhY192 X2NsaXBfbW9kZSB7Cj4gPj4+Pj4gKwlSS0lTUDFfQ0lGX0lTUF9DQUNfVl9DTElQX01PREVfMlBY ID0gMCwKPiA+Pj4+PiArCVJLSVNQMV9DSUZfSVNQX0NBQ19WX0NMSVBfTU9ERV8zUFggPSAxLAo+ ID4+Pj4+ICsJUktJU1AxX0NJRl9JU1BfQ0FDX1ZfQ0xJUF9NT0RFXzNfNFBYID0gMiwKPiA+Pj4+ PiArfTsKPiA+Pj4+PiArCj4gPj4+Pj4gKy8qKgo+ID4+Pj4+ICsgKiBzdHJ1Y3Qgcmtpc3AxX2Np Zl9pc3BfY2FjX2NvbmZpZyAtIGNocm9tYXRpYyBhYmVycmF0aW9uIGNvcnJlY3Rpb24gY29uZmln dXJhdGlvbgo+ID4+Pj4+ICsgKgo+ID4+Pj4+ICsgKiBUaGUgY29ycmVjdGlvbiBpcyBjYXJyaWVk IG91dCBieSBzaGlmdGluZyB0aGUgcmVkIGFuZCBibHVlIHBpeGVscyByZWxhdGl2ZQo+ID4+Pj4+ ICsgKiB0byB0aGUgZ3JlZW4gb25lcywgZGVwZW5kaW5nIG9uIHRoZSBkaXN0YW5jZSBmcm9tIHRo ZSBvcHRpY2FsIGNlbnRlcjoKPiA+Pj4+Cj4gPj4+PiBZZXMsIHRoZSBkaXN0YW5jZSB0byB0aGUg Y2VudGVyIGlzIG9uZSBwYXJhbWV0ZXIsIGJ1dCB0aGUgc2hpZnRpbmcKPiA+Pj4+IGFtb3VudCBk ZXBlbmRzIG9uIG90aGVyIHRoaW5ncy4gSSB3b3VsZCBkcm9wIHRoZSBsYXN0IHBhcnQgb2YgdGhl Cj4gPj4+PiBzZW50ZW5jZSBhbmQgbW92ZSB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIHR3byBiZWxv dyBmaWVsZHMgYWZ0ZXIgdGhlCj4gPj4+PiB0ZXh0Cj4gPj4+Cj4gPj4+IFRoYXQncyB0cnVlLCBi dXQgd2l0aGluIGEgc3BlY2lmaWMgaW1hZ2UsIHRoZSBvbmx5IHZhcnlpbmcgcXVhbnRpdHkKPiA+ Pj4gaXMgdGhlIGRpc3RhbmNlLCBzbyBJIHRoaW5rIGl0IGlzIGltcG9ydGFudCB0byBlbXBoYXNp emUgdGhhdC4KPiA+Pj4KPiA+Pj4gQW5kIEkgYWxzbyBxdWl0ZSBsaWtlIHRoaXMgc3RydWN0dXJl IG9mCj4gPj4+ICAgIC0gZGVzY3JpcHRpb24gb2Ygc3RlcAo+ID4+PiAgICAtIHBhcmFtZXRlcnMg b2Ygc3RlcAo+ID4+PiAgICAtIGRlc2NyaXB0aW9uIG9mIHN0ZXAKPiA+Pj4gICAgLi4uCj4gPj4+ Cj4gPj4+IHNvIEkgd291bGQgbG92ZSB0byBrZWVwIGl0IGxpa2UgdGhpcywgaWYgdGhhdCdzIG9r Pwo+ID4+Cj4gPj4gT2shCj4gPiAKPiA+IEFjay4KPiA+IAo+ID4+Pj4+ICsgKgo+ID4+Pj4+ICsg KiBAaF9jb3VudF9zdGFydDogaG9yaXpvbnRhbCBjb29yZGluYXRlIG9mIHRoZSBvcHRpY2FsIGNl bnRlciAoMTMtYml0IHVuc2lnbmVkIGludGVnZXI7IFsxLDgxOTFdKQo+ID4+Pj4+ICsgKiBAdl9j b3VudF9zdGFydDogdmVydGljYWwgY29vcmRpbmF0ZSBvZiB0aGUgb3B0aWNhbCBjZW50ZXIgKDEz LWJpdCB1bnNpZ25lZCBpbnRlZ2VyOyBbMSw4MTkxXSkKPiA+Pj4+Cj4gPj4+PiBzbyB0aGVzZSBj b3VsZCBnbyBqdXN0IGJlZm9yZSBAeF9uZgo+ID4+Pj4KPiA+Pj4+PiArICoKPiA+Pj4+PiArICog Rm9yIGVhY2ggcGl4ZWwsIHRoZSB4L3kgZGlzdGFuY2VzIGZyb20gdGhlIG9wdGljYWwgY2VudGVy IGFyZSBjYWxjdWxhdGVkIGFuZAo+ID4+Pj4KPiA+Pj4+IEkgZm9yZ290OiBkaWQgd2UgZXN0YWJs aXNoIHRoYXQgdGhlIGNvcnJlY3Rpb24gaXMgYXBwbGllZCB0byB0aGUKPiA+Pj4+IGV1Y2xpZGVh biBkaXN0YW5jZSBvciB0byB4IGFuZCB5IHNlcGFyYXRlbHkgPwo+ID4+Pgo+ID4+PiBHaXZlbiB0 aGF0IHRoZXJlIGFyZSB0d28gc2V0cyBvZiAibm9ybWFsaXphdGlvbiIgcGFyYW1ldGVycywgdGhl IGFzc3VtcHRpb24gaXMgdGhhdAo+ID4+PiBhdCBsZWFzdCB0aGUgeC95IGRpc3RhbmNlcyBhcmUg dHJhbnNmb3JtZWQgc2VwYXJhdGVseS4gSSBzZWUgdHdvIHJlYXNvbmFibGUgY2hvaWNlcwo+ID4+ PiBhZnRlciB0aGF0OiAoYSkgdXNlIHRoZSB0d28gZGlzdGFuY2VzIHNlcGFyYXRlbHksIChiKSB1 c2UgdGhlIHJhZGlhbCBkaXN0YW5jZS4gVGhlCj4gPj4+IGRvY3VtZW50YXRpb24gc2F5cyAoYiku IEhvd2V2ZXIsIHRlc3Rpbmcgd2l0aCBzZW5zb3IgdGVzdCBwYXR0ZXJucyBzdWdnZXN0cyB0aGF0 Cj4gPj4+IGl0IGlzIG5vdCB0aGUgY2FzZSAoYSBob3Jpem9udGFsL3ZlcnRpY2FsIGJvdW5kYXJ5 IGJldHdlZW4gYXBwcm9wcmlhdGVseSBjb2xvcmVkCj4gPj4+IHJlZ2lvbnMgc2hvdWxkIGhhdmUg YSBjdXJ2YXR1cmUgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIHdpdGggYXBwcm9wcmlhdGUgcGFy YW1ldGVycykuCj4gPj4KPiA+PiBJIG5vdyByZWNhbGwgdGhhdCB5b3UgaGF2ZSBiZWVuIGFibGUg dG8gc2hpZnQganVzdCBvbmUgcGxhbiB3aGVuIHVzaW5nCj4gPj4gdGhlIHNlbnNvcidzIHRlc3Qg cGF0dGVybgo+ID4gCj4gPiBJIGFncmVlIGFib3V0IHRoZSBub3JtYWxpemF0aW9uLCBidXQgaXQg c291bmRzIHJlYWxseSB3ZWlyZCB0aGF0IHRoZQo+ID4gaGFyZHdhcmUgd291bGQgdGhlbiBzaGlm dCBzZXBhcmF0ZWx5IGluIHRoZSBYIGFuZCBZIGRpcmVjdGlvbnMuIEJlbG93Cj4gPiB5b3UgZG9j dW1lbnQgdGhlIHJhZGlhbCBjb3JyZWN0aW9uIGZvcm11bGEsIHdoaWNoIGxvb2tzIGNvcnJlY3Qg dG8gbWUuCj4gCj4gSSB0aGluayBzbywgdG9vLiBCdXQgaWYgaXQgdXNlcyB0aGUgcmFkaWFsIGRp c3RhbmNlLCBJIHdvdWxkIGV4cGVjdCB0aGUgc2hpZnRpbmcgdG8gaGFwcGVuCj4gYWxvbmcgdGhl IHJhZGl1cy4gQnV0IHRoYXQgZG9lcyBub3QgYXBwZWFyIHRvIGJlIHRoZSBjYXNlIChlLmcuIHlf bmY9MCByZW1vdmVzIGFsbCB2ZXJ0aWNhbAo+IGNvcnJlY3Rpb24pLiBUaGlzIGNvdWxkIGJlIGV4 cGxhaW5lZCBieSBzYXlpbmcgdGhhdCB0aGUgc2hpZnRpbmcgYWN0dWFsbHkgaGFwcGVucyBhbG9u ZyB0aGUKPiBkaXJlY3Rpb24gZGV0ZXJtaW5lZCBieSB0aGUgc3VtIG9mIHRoZSBub3JtYWxpemVk IGRpc3RhbmNlIHZlY3RvcnMsIGJ1dCB0aGF0IHNlZW1lZCBhIGJpdAo+IGZhciBmZXRjaGVkIHRv IG1lLgoKSXQgbWF5IG5vdCBiZSB0aGF0IGZhciBmZXRjaGVkLiBUaGUgWCBhbmQgWSBub3JtYWxp emF0aW9uIGZhY3RvcnMgYXJlCnNlcGFyYXRlIHRvIHN1cHBvcnQgbm9uLXNxdWFyZSBwaXhlbHMu IFRha2luZyBmb3IgZXhhbXBsZSBhIHBpeGVsIHdob3NlCmhlaWdodCBpcyB0d2ljZSB0aGUgd2lk dGgsIHRoZSB2ZXJ0aWNhbCBkaXN0YW5jZSBpbiBwaHlzaWNhbCB1bml0cyBpcwp0d2ljZSB0aGUg dmVydGljYWwgZGlzdGFuY2UgaW4gcGl4ZWxzLiBUaGUgdmVydGljYWwgbm9ybWFsaXphdGlvbiBm YWN0b3IKd2lsbCBiZSB0d2ljZSB0aGUgaG9yaXpvbnRhbCBmYWN0b3IgdG8gYWNjb3VudCBmb3Ig dGhhdCBhbmQgY2FsY3VsYXRlIGEKcmFkaXVzIGluIHBoeXNpY2FsIHVuaXRzIChhcyB0aGUgZGlz cGxhY2VtZW50IGNhdXNlZCBieSB0aGUgY2hyb21hdGljCmFiZXJyYXRpb24gZGVwZW5kcyBvbiB0 aGUgcGh5c2ljYWwgZGlzdGFuY2UgdG8gdGhlIGltYWdlIHNlbnNvcikuIFRoZQpwaXhlbCBkaXNw bGFjZW1lbnQgdGhlbiBuZWVkcyB0byBiZSBjb252ZXJ0ZWQgYmFjayB0byBwaXhlbCB1bml0cy4K Ck9mIGNvdXJzZSBzb21lb25lIG1heSBwb2ludCBvdXQgdGhhdCBhIG5vcm1hbGl6YXRpb24gZmFj dG9yIG9mIDAgc2hvdWxkCnJlc3VsdCBpbiBhbiBpbmZpbml0ZSB2ZXJ0aWNhbCBkaXNwbGFjZW1l bnQgd2hlbiBjb252ZXJ0aW5nIGJhY2suIFRoZQphYm92ZSBleHBsYW5hdGlvbiBtYXkgbWFrZSBu byBzZW5zZSwgb3IgdGhlIGhhcmR3YXJlIGltcGxlbWVudGF0aW9uIG1heQp0YWtlIHNvbWUgc2hv cnRjdXRzIHRoYXQgcmVzdWx0IGluIG5vIHZlcnRpY2FsIGRpc3BsYWNlbWVudCB3aGVuIHlfbmYg aXMKMC4gSXQgY291bGQgYmUgaW50ZXJlc3RpbmcgdG8gdmFyeSB5X25mIGFuZCBzZWUgaG93IHRo ZSB2ZXJ0aWNhbApkaXNwbGFjZW1lbnQgZXZvbHZlcy4KCj4gQW5kIGV2ZW4gd2l0aCB0aGF0LCBJ IHdvdWxkIGV4cGVjdCB0byBiZSBhYmxlIHRvIHR1cm4gYSBzdHJhaWdodCBsaW5lCj4gaW50byBh IGN1cnZlLiBNYXliZSBJJ20gZG9pbmcgc29tZXRoaW5nIHdyb25nLCBidXQgSSBjYW4ndCByZWNh bGwgZXZlciBiZWluZyBhYmxlIHRvLgo+IAo+ID4+Pj4+ICsgKiB0aGVuIHRyYW5zZm9ybWVkIGlu dG8gdGhlIFswLDI1NV0gcmFuZ2UgYmFzZWQgb24gdGhlIGZvbGxvd2luZyBmb3JtdWxhOgo+ID4+ Pj4KPiA+Pj4+IHMvdHJhbnNmb3JtZWQvbm9ybWFsaXplZCA/Cj4gPj4+Cj4gPj4+IFRvIGJlIGhv bmVzdCBJIHZhc3RseSBwcmVmZXIgInRyYW5zZm9ybSIgLyAibWFwIiBvdmVyICJub3JtYWxpemUi IGhlcmUuCj4gPj4KPiA+PiBZb3UncmUgcmlnaHQgaGVyZSwgdGhlIGJlbG93IGZvcm11bGEgZG9l c24ndCBub3JtYWxpemUgdGhlCj4gPj4gZGlzdGFuY2UgaW4gYW4gaW50ZXJ2YWwgYnV0IGp1c3Qg cmUtc2NhbGUgaXQKPiA+Pgo+ID4+Pj4+ICsgKgo+ID4+Pj4+ICsgKiAgICgoKGQgPDwgNCkgPj4g cykgKiBmKSA+PiA1Cj4gPj4+Pj4gKyAqCj4gPj4+Pj4gKyAqIHdoZXJlIGBkYCBpcyB0aGUgZGlz dGFuY2UsIGBzYCBhbmQgYGZgIGFyZSB0aGUgbm9ybWFsaXphdGlvbiBwYXJhbWV0ZXJzOgo+ID4+ Pj4KPiA+Pj4+IENhbiB5b3UgdXNlICducycgYW5kICduZicgdG8gbWF0Y2ggdGhlIGJlbG93ID8K PiA+Pj4KPiA+Pj4gQWRqdXN0ZWQuCj4gPj4KPiA+PiBUaGFua3MhCj4gPj4KPiA+Pj4+PiArICoK PiA+Pj4+PiArICogQHhfbmY6IGhvcml6b250YWwgbm9ybWFsaXphdGlvbiBzY2FsZSBwYXJhbWV0 ZXIgKDUtYml0IHVuc2lnbmVkIGludGVnZXI7IFswLDMxXSkKPiA+Pj4+PiArICogQHhfbnM6IGhv cml6b250YWwgbm9ybWFsaXphdGlvbiBzaGlmdCBwYXJhbWV0ZXIgKDQtYml0IHVuc2lnbmVkIGlu dGVnZXI7IFswLDE1XSkKPiA+Pj4+PiArICoKPiA+Pj4+PiArICogQHlfbmY6IHZlcnRpY2FsIG5v cm1hbGl6YXRpb24gc2NhbGUgcGFyYW1ldGVyICg1LWJpdCB1bnNpZ25lZCBpbnRlZ2VyOyBbMCwz MV0pCj4gPj4+Pj4gKyAqIEB5X25zOiB2ZXJ0aWNhbCBub3JtYWxpemF0aW9uIHNoaWZ0IHBhcmFt ZXRlciAoNC1iaXQgdW5zaWduZWQgaW50ZWdlcjsgWzAsMTVdKQo+ID4+Pj4+ICsgKgo+ID4+Pj4+ ICsgKiBUaGVzZSBwYXJhbWV0ZXJzIHNob3VsZCBiZSBjaG9zZW4gYmFzZWQgb24gdGhlIGltYWdl IHJlc29sdXRpb24sIHRoZSBwb3NpdGlvbgo+ID4+Pj4+ICsgKiBvZiB0aGUgb3B0aWNhbCBjZW50 ZXIsIGFuZCB0aGUgc2hhcGUgb2YgcGl4ZWxzOiBzbyB0aGF0IG5vIG5vcm1hbGl6ZWQgZGlzdGFu Y2UKPiA+Pj4+Cj4gPj4+PiBzL3BpeGVsczovcGl4ZWxzLwo+ID4+Pgo+ID4+PiBSZXBsYWNlZCBg OmAgd2l0aCBgLGAuCj4gPj4+Cj4gPj4+Pj4gKyAqIGlzIGxhcmdlciB0aGFuIDI1NS4gSWYgdGhl IHBpeGVscyBoYXZlIHNxdWFyZSBzaGFwZSwgdGhlIHR3byBzZXRzIG9mIHBhcmFtZXRlcnMKPiA+ Pj4+PiArICogc2hvdWxkIGJlIGVxdWFsLgo+ID4gCj4gPiBJIHdvbmRlciBpZiB3ZSBjb3VsZCBo YXZlIGFuaXNvdHJvcGljIGxlbnNlcyAoZnJvbSB0aGUgcG9pbnQgb2YgdmlldyBvZgo+ID4gY2hy b21hdGljIGFiZXJyYXRpb25zKSB3aXRoIHNxdWFyZSBwaXhlbHMuIFdlIGNhbiBkZWFsIHdpdGgg aXQgbGF0ZXIuCj4gCj4gUmlnaHQsIHRoaXMgaXMgd2hhdCB0aGUgZG9jdW1lbnRhdGlvbiBzdWdn ZXN0cywgYW5kIEkgYmVsaWV2ZSBpdCBpcyBwcm9iYWJseSAiY29ycmVjdCBlbm91Z2giCj4gbW9z dCBvZiB0aGUgdGltZS4gQnV0IHNob3VsZCBJIHJlbW92ZSBpdD8KPiAKPiA+Pj4+PiArICoKPiA+ Pj4+PiArICogVGhlIGFjdHVhbCBhbW91bnQgb2YgY29ycmVjdGlvbiBpcyBjYWxjdWxhdGVkIHdp dGggYSB0aGlyZCBkZWdyZWUgcG9seW5vbWlhbDoKPiA+Pj4+PiArICoKPiA+Pj4+PiArICogICBj WzBdICogciArIGNbMV0gKiByXjIgKyBjWzJdICogcl4zCj4gPj4+Pj4gKyAqCj4gPj4+Pj4gKyAq IHdoZXJlIGBjYCBpcyB0aGUgc2V0IG9mIGNvZWZmaWNpZW50cyBmb3IgdGhlIGdpdmVuIGNvbG9y LCBhbmQgYHJgIGlzIGRpc3RhbmNlOgo+ID4+Pj4+ICsgKgo+ID4+Pj4+ICsgKiBAcmVkOiByZWQg Y29lZmZpY2llbnRzICg1LjQgdHdvJ3MgY29tcGxlbWVudDsgWy0xNiwxNS45Mzc1XSkKPiA+Pj4+ PiArICogQGJsdWU6IGJsdWUgY29lZmZpY2llbnRzICg1LjQgdHdvJ3MgY29tcGxlbWVudDsgWy0x NiwxNS45Mzc1XSkKPiA+Pj4+PiArICoKPiA+Pj4+PiArICogRmluYWxseSwgdGhlIGFtb3VudCBp cyBjbGlwcGVkIGFzIHJlcXVlc3RlZDoKPiA+Pj4+PiArICoKPiA+Pj4+PiArICogQGhfY2xpcF9t b2RlOiBtYXhpbXVtIGhvcml6b250YWwgc2hpZnQgKGZyb20gZW51bSBya2lzcDFfY2lmX2lzcF9j YWNfaF9jbGlwX21vZGUpCj4gPj4+Pj4gKyAqIEB2X2NsaXBfbW9kZTogbWF4aW11bSB2ZXJ0aWNh bCBzaGlmdCAoZnJvbSBlbnVtIHJraXNwMV9jaWZfaXNwX2NhY192X2NsaXBfbW9kZSkKPiA+Pj4+ PiArICoKPiA+Pj4+PiArICogQSBwb3NpdGl2ZSByZXN1bHQgd2lsbCBzaGlmdCBhd2F5IGZyb20g dGhlIG9wdGljYWwgY2VudGVyLCB3aGlsZSBhIG5lZ2F0aXZlCj4gPj4+Pj4gKyAqIG9uZSB3aWxs IHNoaWZ0IHRvd2FyZHMgdGhlIG9wdGljYWwgY2VudGVyLiBJbiB0aGUgbGF0dGVyIGNhc2UsIHRo ZSBwaXhlbAo+ID4+Pj4+ICsgKiB2YWx1ZXMgYXQgdGhlIGVkZ2VzIGFyZSBkdXBsaWNhdGVkLgo+ ID4+Pj4+ICsgKi8KPiA+Pj4+PiArc3RydWN0IHJraXNwMV9jaWZfaXNwX2NhY19jb25maWcgewo+ ID4+Pj4+ICsJX191OCBoX2NsaXBfbW9kZTsKPiA+Pj4+PiArCV9fdTggdl9jbGlwX21vZGU7Cj4g Pj4+Pj4gKwo+ID4+Pj4+ICsJX191MTYgaF9jb3VudF9zdGFydDsKPiA+Pj4+PiArCV9fdTE2IHZf Y291bnRfc3RhcnQ7Cj4gPj4+Pj4gKwo+ID4+Pj4+ICsJX191MTYgcmVkWzNdOwo+ID4+Pj4+ICsJ X191MTYgYmx1ZVszXTsKPiA+Pj4+PiArCj4gPj4+Pj4gKwlfX3U4IHhfbmY7Cj4gPj4+Pj4gKwlf X3U4IHhfbnM7Cj4gPj4+Pj4gKwo+ID4+Pj4+ICsJX191OCB5X25mOwo+ID4+Pj4+ICsJX191OCB5 X25zOwo+ID4+Pj4+ICt9Owo+ID4+Pj4+ICsKPiA+Pj4+PiAgICAvKi0tLS0tLS0tLS0gUEFSVDI6 IE1lYXN1cmVtZW50IFN0YXRpc3RpY3MgLS0tLS0tLS0tLS0tKi8KPiA+Pj4+Pgo+ID4+Pj4+ICAg IC8qKgo+ID4+Pj4+IEBAIC0xMTYxLDYgKzEyNDcsNyBAQCBlbnVtIHJraXNwMV9leHRfcGFyYW1z X2Jsb2NrX3R5cGUgewo+ID4+Pj4+ICAgIAlSS0lTUDFfRVhUX1BBUkFNU19CTE9DS19UWVBFX0NP TVBBTkRfRVhQQU5ELAo+ID4+Pj4+ICAgIAlSS0lTUDFfRVhUX1BBUkFNU19CTE9DS19UWVBFX0NP TVBBTkRfQ09NUFJFU1MsCj4gPj4+Pj4gICAgCVJLSVNQMV9FWFRfUEFSQU1TX0JMT0NLX1RZUEVf V0RSLAo+ID4+Pj4+ICsJUktJU1AxX0VYVF9QQVJBTVNfQkxPQ0tfVFlQRV9DQUMsCj4gPj4+Pj4g ICAgfTsKPiA+Pj4+Pgo+ID4+Pj4+ICAgIC8qIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5ICov Cj4gPj4+Pj4gQEAgLTE1MDcsNiArMTU5NCwyMiBAQCBzdHJ1Y3Qgcmtpc3AxX2V4dF9wYXJhbXNf d2RyX2NvbmZpZyB7Cj4gPj4+Pj4gICAgCXN0cnVjdCBya2lzcDFfY2lmX2lzcF93ZHJfY29uZmln IGNvbmZpZzsKPiA+Pj4+PiAgICB9IF9fYXR0cmlidXRlX18oKGFsaWduZWQoOCkpKTsKPiA+Pj4+ Pgo+ID4+Pj4+ICsvKioKPiA+Pj4+PiArICogc3RydWN0IHJraXNwMV9leHRfcGFyYW1zX2NhY19j b25maWcgLSBSa0lTUDEgZXh0ZW5zaWJsZSBwYXJhbXMgQ0FDIGNvbmZpZwo+ID4+Pj4+ICsgKgo+ ID4+Pj4+ICsgKiBSa0lTUDEgZXh0ZW5zaWJsZSBwYXJhbWV0ZXJzIENBQyBibG9jay4KPiA+Pj4+ PiArICogSWRlbnRpZmllZCBieSA6Yzp0eXBlOmBSS0lTUDFfRVhUX1BBUkFNU19CTE9DS19UWVBF X0NBQ2AuCj4gPj4+Pj4gKyAqCj4gPj4+Pj4gKyAqIEBoZWFkZXI6IFRoZSBSa0lTUDEgZXh0ZW5z aWJsZSBwYXJhbWV0ZXJzIGhlYWRlciwgc2VlCj4gPj4+Pj4gKyAqCSAgICA6Yzp0eXBlOmBya2lz cDFfZXh0X3BhcmFtc19ibG9ja19oZWFkZXJgCj4gPj4+Pj4gKyAqIEBjb25maWc6IENBQyBjb25m aWd1cmF0aW9uLCBzZWUKPiA+Pj4+PiArICoJICAgIDpjOnR5cGU6YHJraXNwMV9jaWZfaXNwX2Nh Y19jb25maWdgCj4gPj4+Pj4gKyAqLwo+ID4+Pj4+ICtzdHJ1Y3Qgcmtpc3AxX2V4dF9wYXJhbXNf Y2FjX2NvbmZpZyB7Cj4gPj4+Pj4gKwlzdHJ1Y3Qgcmtpc3AxX2V4dF9wYXJhbXNfYmxvY2tfaGVh ZGVyIGhlYWRlcjsKPiA+Pj4+PiArCXN0cnVjdCBya2lzcDFfY2lmX2lzcF9jYWNfY29uZmlnIGNv bmZpZzsKPiA+Pj4+PiArfSBfX2F0dHJpYnV0ZV9fKChhbGlnbmVkKDgpKSk7Cj4gPj4+Pj4gKwo+ ID4+Pj4+ICAgIC8qCj4gPj4+Pj4gICAgICogVGhlIHJraXNwMV9leHRfcGFyYW1zX2NvbXBhbmRf Y3VydmVfY29uZmlnIHN0cnVjdHVyZSBpcyBjb3VudGVkIHR3aWNlIGFzIGl0Cj4gPj4+Pj4gICAg ICogaXMgdXNlZCBmb3IgYm90aCB0aGUgQ09NUEFORF9FWFBBTkQgYW5kIENPTVBBTkRfQ09NUFJF U1MgYmxvY2sgdHlwZXMuCj4gPj4+Pj4gQEAgLTE1MzIsNyArMTYzNSw4IEBAIHN0cnVjdCBya2lz cDFfZXh0X3BhcmFtc193ZHJfY29uZmlnIHsKPiA+Pj4+PiAgICAJc2l6ZW9mKHN0cnVjdCBya2lz cDFfZXh0X3BhcmFtc19jb21wYW5kX2Jsc19jb25maWcpCQkrXAo+ID4+Pj4+ICAgIAlzaXplb2Yo c3RydWN0IHJraXNwMV9leHRfcGFyYW1zX2NvbXBhbmRfY3VydmVfY29uZmlnKQkJK1wKPiA+Pj4+ PiAgICAJc2l6ZW9mKHN0cnVjdCBya2lzcDFfZXh0X3BhcmFtc19jb21wYW5kX2N1cnZlX2NvbmZp ZykJCStcCj4gPj4+Pj4gLQlzaXplb2Yoc3RydWN0IHJraXNwMV9leHRfcGFyYW1zX3dkcl9jb25m aWcpKQo+ID4+Pj4+ICsJc2l6ZW9mKHN0cnVjdCBya2lzcDFfZXh0X3BhcmFtc193ZHJfY29uZmln KQkJCStcCj4gPj4+Pj4gKwlzaXplb2Yoc3RydWN0IHJraXNwMV9leHRfcGFyYW1zX2NhY19jb25m aWcpKQo+ID4+Pj4KPiA+Pj4+IEFsbCBtaW5vcnMsIHBsZWFzZSBhZGQKPiA+Pj4+IFJldmlld2Vk LWJ5OiBKYWNvcG8gTW9uZGkgPGphY29wby5tb25kaUBpZGVhc29uYm9hcmQuY29tPgo+ID4gCj4g PiBhbmQKPiA+IAo+ID4gUmV2aWV3ZWQtYnk6IExhdXJlbnQgUGluY2hhcnQgPGxhdXJlbnQucGlu Y2hhcnRAaWRlYXNvbmJvYXJkLmNvbT4KPiA+IAo+ID4+Pj4+Cj4gPj4+Pj4gICAgLyoqCj4gPj4+ Pj4gICAgICogZW51bSBya3NpcDFfZXh0X3BhcmFtX2J1ZmZlcl92ZXJzaW9uIC0gUmtJU1AxIGV4 dGVuc2libGUgcGFyYW1ldGVycyB2ZXJzaW9uCgotLSAKUmVnYXJkcywKCkxhdXJlbnQgUGluY2hh cnQKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkxpbnV4 LXJvY2tjaGlwIG1haWxpbmcgbGlzdApMaW51eC1yb2NrY2hpcEBsaXN0cy5pbmZyYWRlYWQub3Jn Cmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtcm9ja2No aXAK