From patchwork Thu Sep 5 01:54:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Osamu Watanabe X-Patchwork-Id: 51352 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:612c:f31:b0:48e:c0f8:d0de with SMTP id kb17csp103746vqb; Wed, 4 Sep 2024 18:54:59 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUgD1iW6PitzJzQPaMsNeCKM7VPj2Or9CvFdrLmH5edRSXsy1JNZ7rzRZX6MVlgS2POMSKZ7hgMnpenLHFrgjrU@gmail.com X-Google-Smtp-Source: AGHT+IGrAtBspevKvK+oPHeAPf7MvVLO996+AQErVJu6MaFQrf2mTZLyENZDP2y1hDDvhaZxWG6a X-Received: by 2002:a17:907:3e92:b0:a80:a37f:c303 with SMTP id a640c23a62f3a-a89a357825bmr702297866b.4.1725501299338; Wed, 04 Sep 2024 18:54:59 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id a640c23a62f3a-a8a62469dc0si69526266b.1053.2024.09.04.18.54.58; Wed, 04 Sep 2024 18:54:59 -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=@takushoku.onmicrosoft.com header.s=selector2-takushoku-onmicrosoft-com header.b=Cb5Ykv2M; arc=fail (body hash mismatch); 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 51C7A68DCA9; Thu, 5 Sep 2024 04:54:55 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from TY3P286CU002.outbound.protection.outlook.com (mail-japaneastazon11020073.outbound.protection.outlook.com [52.101.229.73]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B3A3E68DC13 for ; Thu, 5 Sep 2024 04:54:46 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=X5v4zx/4CbmkQO5WQZz0KbtApifOy4XdIRnSiAW1tQG7Ct8tZr2zduKgK6OmHba4Gsz3HLdyDaj8d4nMQpI/aXhxO5jOHxAqfN1JkOE4Pjm9izYerufROXKqkS/zb8/nFXrAjUh2FcXhmyYYH8Y+ocoi5swolRJPx6uqPWwFk0/tDFTjCPbjCCDkxi/NszmAr/TJdadKN3i3eWPF9lu4jqtZ4hJZ55JcLvt8F2Ai0OGCFFy3hvDHcZL78auaDuKdqt9Pz/HQ/i7Eed+PUFBlhZk6Mc7HEx56aZ1ywCmzLaBuUF9nQ0Pwa06+pmHFmy58+TizusrJN4fgpDTmKQywWg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ILsyuVhyqNtoBWUzJedQwUFGoAQ0U0D6pjRmPCuNBZk=; b=dK+Evic1t5KOjQswhQTsDo8n4eNXp4itwdDE+I3UonjNXmwrRKEqUWE/CfC9cemoA2yzeOVLITocXQ5BZp1e10Mbw4MvGgyQ+Y1PzAjSpeMfPuqT4pos9t4xOkmAUaeTEW63kNpqkSLcIFcMeJkO0v+V5S6zu21Pcuq7S85mO6tJUWuNDwlGzyWvymwvbp9j6rQ2sOC7nvU0/okncPMGHpnttXjJXA7ERRlyKq7CP02ucp7Hsg06nTkrAGRooijpvfvSZsrZSDdhx60CnlNr4IQvmEI1l5pkImONl/I2BAisrzjhXERLOIXfJ4UsS47Hos9v8/FQIFAoRLTmAj56yA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=es.takushoku-u.ac.jp; dmarc=pass action=none header.from=es.takushoku-u.ac.jp; dkim=pass header.d=es.takushoku-u.ac.jp; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=takushoku.onmicrosoft.com; s=selector2-takushoku-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ILsyuVhyqNtoBWUzJedQwUFGoAQ0U0D6pjRmPCuNBZk=; b=Cb5Ykv2MqDHVR88zCilHZTd429E7oBEoadMhEZ4GSBkS+Tmr+BoKpcziewV50N96EjN9voh2dE/PJnXCGOl5/mMXPvRFrbNKERjtZszq9E81GTMLBT8uz+FHAqz2ofIfDhLgXAa1siLBXPjrqUVQwc3lNFBn3YoRkFbSKgi5V5w= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=es.takushoku-u.ac.jp; Received: from OS0PR01MB6001.jpnprd01.prod.outlook.com (2603:1096:604:b7::12) by TYRPR01MB12319.jpnprd01.prod.outlook.com (2603:1096:405:100::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7918.27; Thu, 5 Sep 2024 01:54:41 +0000 Received: from OS0PR01MB6001.jpnprd01.prod.outlook.com ([fe80::181c:c1f4:9b58:f6cc]) by OS0PR01MB6001.jpnprd01.prod.outlook.com ([fe80::181c:c1f4:9b58:f6cc%3]) with mapi id 15.20.7918.024; Thu, 5 Sep 2024 01:54:41 +0000 From: Osamu Watanabe To: ffmpeg-devel@ffmpeg.org Date: Thu, 5 Sep 2024 10:54:35 +0900 Message-ID: <20240905015436.78024-1-owatanab@es.takushoku-u.ac.jp> X-Mailer: git-send-email 2.43.0 X-ClientProxiedBy: TYCP301CA0042.JPNP301.PROD.OUTLOOK.COM (2603:1096:400:380::10) To OS0PR01MB6001.jpnprd01.prod.outlook.com (2603:1096:604:b7::12) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: OS0PR01MB6001:EE_|TYRPR01MB12319:EE_ X-MS-Office365-Filtering-Correlation-Id: cddfb74f-262f-4b9e-3a47-08dccd4db497 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|52116014|366016|41320700013|1800799024|38350700014; X-Microsoft-Antispam-Message-Info: 05Ji43xR708jhLsYoKsiJYHkZO0hNN1iAuuNzbVkG5iWA9grvErgD8nsQMpD36jdwpjHj2D7X3Y6aN4JHlj4JmEQkLTzK2aXB8MuZpexOkQ4UpUBZ3Zqx+WVIwVuV4/XkPX+pxyXp8NmcCNMdm0AnG+9eHhq+v/yLgtWA3sJ5RKnN3hruUc4YZKeICFeVThJZ/QG5p432pRKlee8h1RalYYZsiNYZZWXpbv9yD/CJbkx9g0vNQixtcfonqaYnZJIGmReVReYVp/6M8QL5h75o/QCr+l4IS+C7Ee/dd0y+NEy0pXw5JoP0zbehZaplFx8ZwUdnsNBTRERGAPXpkQPWzRhBXsSFy/knzfTakUL8PH+tHgxSvMvnWo6FGWPFPrasQFAOe4Dl1NyKCNqS6UNY+/DY+UO5Jqv8BaZArOwF52/B9yxyi1SHkG54mBbQ326tGT+kSF6aeHyx/aME2dYxF0BmtQ4RvLgIh3xP6Z++Ya+mEg+yiYk3bjbv/OsB+WQEEQx2GF3hN17HuTf/BPu4w0hPwdG9Y7o/0IuNBSap309XsFnFBHCGL6qBIy5iqhTqvFkAQFC6GIHin+HEZbtjWHav2hJfdfCyxzW1Hy5GpgZEpEg+bP4JIU4NwKPnCn4rkfCQsqN/5F0YSAx4izsmKs17sFB3zQtJCIoNEEXeRfrJ3ES/H7yd9vNxbYvgWKlFOPfMwv44TRX0Cb5kVY77x6kTPsjMTGxnWaPA3un1qU41vneh3GJJMe3GavnAwxJqHRl1lSxjyJKxpt44/yBpQGoeRSHvP/J3nQjQag4N14LqKw1bC2NaAoB9QnhtK8FGQhKRoKM97jj/5dNd1Tjnf6dtlFcNuI4Tj8LdM9QYUFm8bt04Swxz56ik35fJKtjFSxDmnThkWRyKUu9m38pNDSSdNfzytQsKK1U2+2PHW/z4E/LD0oQyEcrJ0PyZ18d1fkP9jpRodMpkHW+FTKrw0fO14dunslu8CfHtiMuP2TbyvVPkiVgaMmNt4PAF3hBZLIme25u/cjiyBYcDlNUjx0ixIvJceZBYya/LbtGMYRhHHRf4CVdtOmhM7GPQNKxBN9A8LmrgEpqCdU1gyVI6I5PTj58jMkSkR/rODDRTN60KvYQ5aJQmhRehFkwzi8c2AF5z32Vqt0IluCFNJG9lqTYQDPEE7Z5BTUYTlM70I0lKrp+rrJ7+omOxV8wkbjUsvVbUWqKL4COOZ3KiKN3vO/a0cpfT2PY/JYQ1i6Wt9UAQTDqX45wKyOdE1hguREXcJAaLc2om3ej8mL4L4Hl2o8H6mbVQjqM+Wjfzwd8365M35oIJcTgb2vPh3BMqTLnbO6oQniz3xYud6p0E8I+iDghjVgIbETiAtTPX4970tA= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:OS0PR01MB6001.jpnprd01.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(376014)(52116014)(366016)(41320700013)(1800799024)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: E5VeRvEFvmn8ZhFp/wb1D1gk1o1Qi0M5L3Z/ZNaMQMDcUE/UdTKtZXQTUt+7BvPauOBZrLX4eQiIjrU0JLbolkmBS5485/maS2EPmA1zwDw4BFN4QTbFfotiaPfWiGyVZfSttd6iW5KTUSuxgMPiDIX3vQvWyt74faPgP6f+Q+0pXrNsqa20xDT4QCX2WuT1Mz3r2B/2LrBzMcuvZgHlIvfDgHBfJcPjnzUwQ/vtXc2csU8CKL3hltgLOZAkZETq2nBkcrv4LS3LLDZU2czljZAGoinQxiO9BL8kZ1lHrKuk0rflqAvlg9xuZ8G3SD2eoFmgmjB3SFvdMfl9g0uvbMZ/6YdwylItj+2GALnemjiRYno/4DDdaWYPUg8o7LiJN7oHFAgk71smqrciFU9mtJbFPB4an2VP4bNVI49xak2NhSPm8NUTZ6xlJLhy+itftAUvjXHHWs9o0evBPo4nKTMAnm/EuspCo+6bUwqplHp0Gi9PWc4fst1qpIQftFRmbj+kChvqNP0h7GhFhSfCsrUnOVl3L7cAUhAqRzi2fOpXIBAY4tYgNNl5xCK7S1JHku15tX+y+5zw8jyn3ZizADw9eQLvsQmF+gtcRSG4CE0B9sLFHVVxlYZ8nfZ4WLTqyyrtBIaZkRV3Vd6oX/kU5RNtVpe52XEbDiVdy5IcdXWJzcr7h/0KqEFvTnkMYcvPY3dXohGKnhjbSlC4Lp6QVymIJtzs/TxYOAPAXMoZjIb9tgZhrDeKRAhh3zShqUcTX2DM8kL25Ni42VanBD2yiENOzzrNEiakkjJt5+BjGT0/ylv006+C1eRTGRxNpc/L6tznc9HqdmX7lu1K2/QMKgIyB6vItBWgBfOhdF9jGmdP75T/fYuL8SNZU37KMaky3tqyDQbTdtgDH3o7cPolhVjBHoKatDGV/Wd9+YhpeKl50ehfqH5+/kXS5AJYqA7Rn0BwvRaR/GbTRfo3axsO2kZrvTLgLLMGEz5I+IRu3auOQmovnTogTrE8Blb6dmtYMW6F0w7ff3D20o2xHt+Q2YVDXrkgcYqDtVHSbp5p/ESvm4pUI0oQ+ySijmWgf/F5qX92GT7ai0FDlyTHlSp8PcupCWa70aeIAxEj7n3Dw/Bk8g7wQerRGYqdj6RLYIaTCfGhtUXi1G7LdDjBFx0em82Xcj1EPHGzoK8CQLCk5MAAlSVr5Nyh7lU9/IdGiYlL6mRx1JGZqRIq8K6Uq7M6brUAtOd1BnnZVFzOBjTGyzgCa9TNbvec1ckn6w42JI+FVUx2X5jeTvWbWhqi/AcpjZrgHPu/6V9w6UyXAaDHT+ViAZrlgPhfyOoasYspGrKkhRGZn7y99OaVqXzwsbpabyYcots38bWRxz40US2517/aMY6TKdTnqOqHlN8OpBOpRIFHnP2j8jyS8g6fM3u+e6i2rz+5zaILzSOBFMJCTO241/3+Xax4hG21ZhmEIdnOyv+7leV5CU9QG8oM57Q9vlGqsa8s02THBF0YzSTsbL2puu84FBSy5tREBhCWc0rDzNBpwwIpR5BCbQEhhWJ3cEVDMX83p5qQws0sVtL8K6qgy/Oh4q5c0XMcjSbouYEm0P0g6d5ppZHdT4OMOGSDxw== X-OriginatorOrg: es.takushoku-u.ac.jp X-MS-Exchange-CrossTenant-Network-Message-Id: cddfb74f-262f-4b9e-3a47-08dccd4db497 X-MS-Exchange-CrossTenant-AuthSource: OS0PR01MB6001.jpnprd01.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2024 01:54:41.7037 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 853333e5-13b1-4738-ae04-bfb589cf2665 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: +8Ii7cutdEsFoBss6bet3quH4vQbLuOLpMs80YMk8cO4tSrCxQseQLYe/1ucQnzEHfaeAkEeiU3oPJA6Z9+FtlUbDbwlVZ8dgeHfSeFrno8= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYRPR01MB12319 Subject: [FFmpeg-devel] [PATCH v3 1/2] avcodec/jpeg2000dec: Fix FF_DWT97_INT to pass the conformance testing defined in ISO/IEC 15444-4. 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: Osamu Watanabe , pal@sandflow.com Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: S50cdYNX82JM This commit fixes the problem described below on the integer version of the inverse DWT processing (FF_DWT97_INT, https://trac.ffmpeg.org/ticket/10123), which is activated with `-flags +bitexact`. - Problem - The tests for the following codestreams were failed with `-flags +bitexact`. - p0_04.j2k, p0_05.j2k, p0_09.j2k, p1_02.j2k, p1_03.j2k, p1_06.j2k. - ds0_ht_04_b11.j2k, ds0_ht_04_b12.j2k, ds0_ht_05_b11.j2k, ds0_ht_05_b12.j2k, ds0_ht_09_b11.j2k, ds1_ht_02_b11.j2k, ds1_ht_02_b12.j2k, ds1_ht_03_b11.j2k, ds1_ht_03_b12.j2k, ds1_ht_06_b11.j2k. Signed-off-by: Osamu Watanabe --- libavcodec/j2kenc.c | 9 +++++++-- libavcodec/jpeg2000.c | 7 +++---- libavcodec/jpeg2000dec.c | 4 +++- libavcodec/jpeg2000dwt.c | 38 +++++++++++++++++++++++++------------- 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index 91e66d8104..ecd9f42401 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -1384,7 +1384,9 @@ static void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) Jpeg2000Band *band = reslevel->band + bandno; Jpeg2000Prec *prec = band->prec + precno; - int64_t dwt_norm = dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 15; + // Shifting down to 1 bit above from the bi/nary point. + // This is mandatory for FF_DWT97_INT to maintain its precision. + int64_t dwt_norm = dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 14; int64_t lambda_prime = av_rescale(s->lambda, 1 << WMSEDEC_SHIFT, dwt_norm * dwt_norm); for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ Jpeg2000Cblk *cblk = prec->cblk + cblkno; @@ -1457,7 +1459,10 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno int *ptr = t1.data + (y-yy0)*t1.stride; for (x = xx0; x < xx1; x++){ *ptr = (comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]); - *ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 15 - NMSEDEC_FRACBITS; + + // Shifting down to 1 bit above from the bi/nary point. + // This is mandatory for FF_DWT97_INT to maintain its precision. + *ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 14 - NMSEDEC_FRACBITS; ptr++; } } diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index d6ffb02319..2d093e4705 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -260,9 +260,8 @@ static void init_band_stepsize(AVCodecContext *avctx, band->f_stepsize *= F_LFTG_X * F_LFTG_X * 4; break; } - if (codsty->transform == FF_DWT97) { - band->f_stepsize *= pow(F_LFTG_K, 2*(codsty->nreslevels2decode - reslevelno) + lband - 2); - } + // scaling + band->f_stepsize *= pow(F_LFTG_K, 2*(codsty->nreslevels2decode - reslevelno) + lband - 2); } if (band->f_stepsize > (INT_MAX >> 15)) { @@ -270,7 +269,7 @@ static void init_band_stepsize(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "stepsize out of range\n"); } - band->i_stepsize = band->f_stepsize * (1 << 15); + band->i_stepsize = lrint(band->f_stepsize * (1 << 15) + 0.5f); /* FIXME: In OpenJPEG code stepsize = stepsize * 0.5. Why? * If not set output of entropic decoder is not correct. */ diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 2e09b279dc..6af8c764d0 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -2136,7 +2136,9 @@ static void dequantization_int_97(int x, int y, Jpeg2000Cblk *cblk, int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x]; int *src = t1->data + j*t1->stride; for (i = 0; i < w; ++i) - datap[i] = (src[i] * (int64_t)band->i_stepsize + (1<<15)) >> 16; + // Shifting down to 1 bit above from the binary point. + // This is mandatory for FF_DWT97_INT to pass the conformance testing. + datap[i] = (int32_t)(src[i] * (int64_t)band->i_stepsize + (1 << 14)) >> 15; } } diff --git a/libavcodec/jpeg2000dwt.c b/libavcodec/jpeg2000dwt.c index 34e33553f7..6994809ac0 100644 --- a/libavcodec/jpeg2000dwt.c +++ b/libavcodec/jpeg2000dwt.c @@ -39,7 +39,7 @@ /* Lifting parameters in integer format. * Computed as param = (float param) * (1 << 16) */ -#define I_LFTG_ALPHA 103949ll +#define I_LFTG_ALPHA 38413ll // = 103949 - 65536, (= 1.586 - 1.0) #define I_LFTG_BETA 3472ll #define I_LFTG_GAMMA 57862ll #define I_LFTG_DELTA 29066ll @@ -234,8 +234,11 @@ static void sd_1d97_int(int *p, int i0, int i1) extend97_int(p, i0, i1); i0++; i1++; - for (i = (i0>>1) - 2; i < (i1>>1) + 1; i++) - p[2 * i + 1] -= (I_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16; + for (i = (i0>>1) - 2; i < (i1>>1) + 1; i++) { + int64_t sum = p[2 * i] + p[2 * i + 2]; + p[2 * i + 1] -= sum; + p[2 * i + 1] -= (I_LFTG_ALPHA * sum + (1 << 15)) >> 16; + } for (i = (i0>>1) - 1; i < (i1>>1) + 1; i++) p[2 * i] -= (I_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16; for (i = (i0>>1) - 1; i < (i1>>1); i++) @@ -276,7 +279,7 @@ static void dwt_encode97_int(DWTContext *s, int *t) // copy back and deinterleave for (i = mv; i < lv; i+=2, j++) - t[w*j + lp] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; + t[w*j + lp] = l[i]; // ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; for (i = 1-mv; i < lv; i+=2, j++) t[w*j + lp] = l[i]; } @@ -293,7 +296,7 @@ static void dwt_encode97_int(DWTContext *s, int *t) // copy back and deinterleave for (i = mh; i < lh; i+=2, j++) - t[w*lp + j] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; + t[w*lp + j] = l[i]; // ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; for (i = 1-mh; i < lh; i+=2, j++) t[w*lp + j] = l[i]; } @@ -301,7 +304,10 @@ static void dwt_encode97_int(DWTContext *s, int *t) } for (i = 0; i < w * h; i++) - t[i] = (t[i] + ((1<>1)) >> I_PRESHIFT; + // Shifting down to the binary point. + // In FF_DWT97_INT, the binary point of the input coefficients is 1 bit above from the LSB. + // So, we need `>> (I_PRESHIFT + 1)` here. + t[i] = (t[i] + ((1<<(I_PRESHIFT + 1))>>1)) >> (I_PRESHIFT + 1); } static void sr_1d53(unsigned *p, int i0, int i1) @@ -471,8 +477,11 @@ static void sr_1d97_int(int32_t *p, int i0, int i1) for (i = (i0 >> 1); i < (i1 >> 1) + 1; i++) p[2 * i] += (I_LFTG_BETA * (p[2 * i - 1] + (int64_t)p[2 * i + 1]) + (1 << 15)) >> 16; /* step 6 */ - for (i = (i0 >> 1); i < (i1 >> 1); i++) - p[2 * i + 1] += (I_LFTG_ALPHA * (p[2 * i] + (int64_t)p[2 * i + 2]) + (1 << 15)) >> 16; + for (i = (i0 >> 1); i < (i1 >> 1); i++) { + int64_t sum = p[2 * i] + (int64_t) p[2 * i + 2]; + p[2 * i + 1] += sum; + p[2 * i + 1] += (I_LFTG_ALPHA * sum + (1 << 15)) >> 16; + } } static void dwt_decode97_int(DWTContext *s, int32_t *t) @@ -500,9 +509,9 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t) l = line + mh; for (lp = 0; lp < lv; lp++) { int i, j = 0; - // rescale with interleaving + // interleaving for (i = mh; i < lh; i += 2, j++) - l[i] = ((data[w * lp + j] * I_LFTG_K) + (1 << 15)) >> 16; + l[i] = data[w * lp + j]; for (i = 1 - mh; i < lh; i += 2, j++) l[i] = data[w * lp + j]; @@ -516,9 +525,9 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t) l = line + mv; for (lp = 0; lp < lh; lp++) { int i, j = 0; - // rescale with interleaving + // interleaving for (i = mv; i < lv; i += 2, j++) - l[i] = ((data[w * j + lp] * I_LFTG_K) + (1 << 15)) >> 16; + l[i] = data[w * j + lp]; for (i = 1 - mv; i < lv; i += 2, j++) l[i] = data[w * j + lp]; @@ -530,7 +539,10 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t) } for (i = 0; i < w * h; i++) - data[i] = (data[i] + ((1LL<>1)) >> I_PRESHIFT; + // Shifting down to the binary point. + // In FF_DWT97_INT, the binary point of the input coefficients is 1 bit above from the LSB. + // So, we need `>> (I_PRESHIFT + 1)` here. + data[i] = (int32_t)(data[i] + ((1LL<<(I_PRESHIFT + 1))>>1)) >> (I_PRESHIFT + 1); } int ff_jpeg2000_dwt_init(DWTContext *s, int border[2][2],