1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * JPEG2000 image encoder 3cabdff1aSopenharmony_ci * Copyright (c) 2007 Kamil Nowosad 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci * 21cabdff1aSopenharmony_ci * ********************************************************************************************************************** 22cabdff1aSopenharmony_ci * 23cabdff1aSopenharmony_ci * 24cabdff1aSopenharmony_ci * 25cabdff1aSopenharmony_ci * This source code incorporates work covered by the following copyright and 26cabdff1aSopenharmony_ci * permission notice: 27cabdff1aSopenharmony_ci * 28cabdff1aSopenharmony_ci * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium 29cabdff1aSopenharmony_ci * Copyright (c) 2002-2007, Professor Benoit Macq 30cabdff1aSopenharmony_ci * Copyright (c) 2001-2003, David Janssens 31cabdff1aSopenharmony_ci * Copyright (c) 2002-2003, Yannick Verschueren 32cabdff1aSopenharmony_ci * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe 33cabdff1aSopenharmony_ci * Copyright (c) 2005, Herve Drolon, FreeImage Team 34cabdff1aSopenharmony_ci * Copyright (c) 2007, Callum Lerwick <seg@haxxed.com> 35cabdff1aSopenharmony_ci * Copyright (c) 2020, Gautam Ramakrishnan <gautamramk@gmail.com> 36cabdff1aSopenharmony_ci * All rights reserved. 37cabdff1aSopenharmony_ci * 38cabdff1aSopenharmony_ci * Redistribution and use in source and binary forms, with or without 39cabdff1aSopenharmony_ci * modification, are permitted provided that the following conditions 40cabdff1aSopenharmony_ci * are met: 41cabdff1aSopenharmony_ci * 1. Redistributions of source code must retain the above copyright 42cabdff1aSopenharmony_ci * notice, this list of conditions and the following disclaimer. 43cabdff1aSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 44cabdff1aSopenharmony_ci * notice, this list of conditions and the following disclaimer in the 45cabdff1aSopenharmony_ci * documentation and/or other materials provided with the distribution. 46cabdff1aSopenharmony_ci * 47cabdff1aSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' 48cabdff1aSopenharmony_ci * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49cabdff1aSopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50cabdff1aSopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 51cabdff1aSopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52cabdff1aSopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53cabdff1aSopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 54cabdff1aSopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 55cabdff1aSopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56cabdff1aSopenharmony_ci * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 57cabdff1aSopenharmony_ci * POSSIBILITY OF SUCH DAMAGE. 58cabdff1aSopenharmony_ci */ 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci/** 62cabdff1aSopenharmony_ci * JPEG2000 image encoder 63cabdff1aSopenharmony_ci * @file 64cabdff1aSopenharmony_ci * @author Kamil Nowosad 65cabdff1aSopenharmony_ci */ 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci#include <float.h> 68cabdff1aSopenharmony_ci#include "avcodec.h" 69cabdff1aSopenharmony_ci#include "codec_internal.h" 70cabdff1aSopenharmony_ci#include "encode.h" 71cabdff1aSopenharmony_ci#include "bytestream.h" 72cabdff1aSopenharmony_ci#include "jpeg2000.h" 73cabdff1aSopenharmony_ci#include "version.h" 74cabdff1aSopenharmony_ci#include "libavutil/common.h" 75cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h" 76cabdff1aSopenharmony_ci#include "libavutil/opt.h" 77cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 78cabdff1aSopenharmony_ci#include "libavutil/avstring.h" 79cabdff1aSopenharmony_ci#include "libavutil/thread.h" 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci#define NMSEDEC_BITS 7 82cabdff1aSopenharmony_ci#define NMSEDEC_FRACBITS (NMSEDEC_BITS-1) 83cabdff1aSopenharmony_ci#define WMSEDEC_SHIFT 13 ///< must be >= 13 84cabdff1aSopenharmony_ci#define LAMBDA_SCALE (100000000LL << (WMSEDEC_SHIFT - 13)) 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_ci#define CODEC_JP2 1 87cabdff1aSopenharmony_ci#define CODEC_J2K 0 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_cistatic int lut_nmsedec_ref [1<<NMSEDEC_BITS], 90cabdff1aSopenharmony_ci lut_nmsedec_ref0[1<<NMSEDEC_BITS], 91cabdff1aSopenharmony_ci lut_nmsedec_sig [1<<NMSEDEC_BITS], 92cabdff1aSopenharmony_ci lut_nmsedec_sig0[1<<NMSEDEC_BITS]; 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_cistatic const int dwt_norms[2][4][10] = { // [dwt_type][band][rlevel] (multiplied by 10000) 95cabdff1aSopenharmony_ci {{10000, 19650, 41770, 84030, 169000, 338400, 676900, 1353000, 2706000, 5409000}, 96cabdff1aSopenharmony_ci {20220, 39890, 83550, 170400, 342700, 686300, 1373000, 2746000, 5490000}, 97cabdff1aSopenharmony_ci {20220, 39890, 83550, 170400, 342700, 686300, 1373000, 2746000, 5490000}, 98cabdff1aSopenharmony_ci {20800, 38650, 83070, 171800, 347100, 695900, 1393000, 2786000, 5572000}}, 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_ci {{10000, 15000, 27500, 53750, 106800, 213400, 426700, 853300, 1707000, 3413000}, 101cabdff1aSopenharmony_ci {10380, 15920, 29190, 57030, 113300, 226400, 452500, 904800, 1809000}, 102cabdff1aSopenharmony_ci {10380, 15920, 29190, 57030, 113300, 226400, 452500, 904800, 1809000}, 103cabdff1aSopenharmony_ci { 7186, 9218, 15860, 30430, 60190, 120100, 240000, 479700, 959300}} 104cabdff1aSopenharmony_ci}; 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_citypedef struct { 107cabdff1aSopenharmony_ci Jpeg2000Component *comp; 108cabdff1aSopenharmony_ci double *layer_rates; 109cabdff1aSopenharmony_ci} Jpeg2000Tile; 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_citypedef struct { 112cabdff1aSopenharmony_ci AVClass *class; 113cabdff1aSopenharmony_ci AVCodecContext *avctx; 114cabdff1aSopenharmony_ci const AVFrame *picture; 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci int width, height; ///< image width and height 117cabdff1aSopenharmony_ci uint8_t cbps[4]; ///< bits per sample in particular components 118cabdff1aSopenharmony_ci int chroma_shift[2]; 119cabdff1aSopenharmony_ci uint8_t planar; 120cabdff1aSopenharmony_ci int ncomponents; 121cabdff1aSopenharmony_ci int tile_width, tile_height; ///< tile size 122cabdff1aSopenharmony_ci int numXtiles, numYtiles; 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci uint8_t *buf_start; 125cabdff1aSopenharmony_ci uint8_t *buf; 126cabdff1aSopenharmony_ci uint8_t *buf_end; 127cabdff1aSopenharmony_ci int bit_index; 128cabdff1aSopenharmony_ci 129cabdff1aSopenharmony_ci int64_t lambda; 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_ci Jpeg2000CodingStyle codsty; 132cabdff1aSopenharmony_ci Jpeg2000QuantStyle qntsty; 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ci Jpeg2000Tile *tile; 135cabdff1aSopenharmony_ci int layer_rates[100]; 136cabdff1aSopenharmony_ci uint8_t compression_rate_enc; ///< Is compression done using compression ratio? 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci int format; 139cabdff1aSopenharmony_ci int pred; 140cabdff1aSopenharmony_ci int sop; 141cabdff1aSopenharmony_ci int eph; 142cabdff1aSopenharmony_ci int prog; 143cabdff1aSopenharmony_ci int nlayers; 144cabdff1aSopenharmony_ci char *lr_str; 145cabdff1aSopenharmony_ci} Jpeg2000EncoderContext; 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci/* debug */ 149cabdff1aSopenharmony_ci#if 0 150cabdff1aSopenharmony_ci#undef ifprintf 151cabdff1aSopenharmony_ci#undef printf 152cabdff1aSopenharmony_ci 153cabdff1aSopenharmony_cistatic void nspaces(FILE *fd, int n) 154cabdff1aSopenharmony_ci{ 155cabdff1aSopenharmony_ci while(n--) putc(' ', fd); 156cabdff1aSopenharmony_ci} 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_cistatic void printcomp(Jpeg2000Component *comp) 159cabdff1aSopenharmony_ci{ 160cabdff1aSopenharmony_ci int i; 161cabdff1aSopenharmony_ci for (i = 0; i < comp->y1 - comp->y0; i++) 162cabdff1aSopenharmony_ci ff_jpeg2000_printv(comp->i_data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0); 163cabdff1aSopenharmony_ci} 164cabdff1aSopenharmony_ci 165cabdff1aSopenharmony_cistatic void dump(Jpeg2000EncoderContext *s, FILE *fd) 166cabdff1aSopenharmony_ci{ 167cabdff1aSopenharmony_ci int tileno, compno, reslevelno, bandno, precno; 168cabdff1aSopenharmony_ci fprintf(fd, "XSiz = %d, YSiz = %d, tile_width = %d, tile_height = %d\n" 169cabdff1aSopenharmony_ci "numXtiles = %d, numYtiles = %d, ncomponents = %d\n" 170cabdff1aSopenharmony_ci "tiles:\n", 171cabdff1aSopenharmony_ci s->width, s->height, s->tile_width, s->tile_height, 172cabdff1aSopenharmony_ci s->numXtiles, s->numYtiles, s->ncomponents); 173cabdff1aSopenharmony_ci for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ 174cabdff1aSopenharmony_ci Jpeg2000Tile *tile = s->tile + tileno; 175cabdff1aSopenharmony_ci nspaces(fd, 2); 176cabdff1aSopenharmony_ci fprintf(fd, "tile %d:\n", tileno); 177cabdff1aSopenharmony_ci for(compno = 0; compno < s->ncomponents; compno++){ 178cabdff1aSopenharmony_ci Jpeg2000Component *comp = tile->comp + compno; 179cabdff1aSopenharmony_ci nspaces(fd, 4); 180cabdff1aSopenharmony_ci fprintf(fd, "component %d:\n", compno); 181cabdff1aSopenharmony_ci nspaces(fd, 4); 182cabdff1aSopenharmony_ci fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d\n", 183cabdff1aSopenharmony_ci comp->x0, comp->x1, comp->y0, comp->y1); 184cabdff1aSopenharmony_ci for(reslevelno = 0; reslevelno < s->nreslevels; reslevelno++){ 185cabdff1aSopenharmony_ci Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; 186cabdff1aSopenharmony_ci nspaces(fd, 6); 187cabdff1aSopenharmony_ci fprintf(fd, "reslevel %d:\n", reslevelno); 188cabdff1aSopenharmony_ci nspaces(fd, 6); 189cabdff1aSopenharmony_ci fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d, nbands = %d\n", 190cabdff1aSopenharmony_ci reslevel->x0, reslevel->x1, reslevel->y0, 191cabdff1aSopenharmony_ci reslevel->y1, reslevel->nbands); 192cabdff1aSopenharmony_ci for(bandno = 0; bandno < reslevel->nbands; bandno++){ 193cabdff1aSopenharmony_ci Jpeg2000Band *band = reslevel->band + bandno; 194cabdff1aSopenharmony_ci nspaces(fd, 8); 195cabdff1aSopenharmony_ci fprintf(fd, "band %d:\n", bandno); 196cabdff1aSopenharmony_ci nspaces(fd, 8); 197cabdff1aSopenharmony_ci fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d," 198cabdff1aSopenharmony_ci "codeblock_width = %d, codeblock_height = %d cblknx = %d cblkny = %d\n", 199cabdff1aSopenharmony_ci band->x0, band->x1, 200cabdff1aSopenharmony_ci band->y0, band->y1, 201cabdff1aSopenharmony_ci band->codeblock_width, band->codeblock_height, 202cabdff1aSopenharmony_ci band->cblknx, band->cblkny); 203cabdff1aSopenharmony_ci for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ 204cabdff1aSopenharmony_ci Jpeg2000Prec *prec = band->prec + precno; 205cabdff1aSopenharmony_ci nspaces(fd, 10); 206cabdff1aSopenharmony_ci fprintf(fd, "prec %d:\n", precno); 207cabdff1aSopenharmony_ci nspaces(fd, 10); 208cabdff1aSopenharmony_ci fprintf(fd, "xi0 = %d, xi1 = %d, yi0 = %d, yi1 = %d\n", 209cabdff1aSopenharmony_ci prec->xi0, prec->xi1, prec->yi0, prec->yi1); 210cabdff1aSopenharmony_ci } 211cabdff1aSopenharmony_ci } 212cabdff1aSopenharmony_ci } 213cabdff1aSopenharmony_ci } 214cabdff1aSopenharmony_ci } 215cabdff1aSopenharmony_ci} 216cabdff1aSopenharmony_ci#endif 217cabdff1aSopenharmony_ci 218cabdff1aSopenharmony_ci/* bitstream routines */ 219cabdff1aSopenharmony_ci 220cabdff1aSopenharmony_ci/** put n times val bit */ 221cabdff1aSopenharmony_cistatic void put_bits(Jpeg2000EncoderContext *s, int val, int n) // TODO: optimize 222cabdff1aSopenharmony_ci{ 223cabdff1aSopenharmony_ci while (n-- > 0){ 224cabdff1aSopenharmony_ci if (s->bit_index == 8) 225cabdff1aSopenharmony_ci { 226cabdff1aSopenharmony_ci s->bit_index = *s->buf == 0xff; 227cabdff1aSopenharmony_ci *(++s->buf) = 0; 228cabdff1aSopenharmony_ci } 229cabdff1aSopenharmony_ci *s->buf |= val << (7 - s->bit_index++); 230cabdff1aSopenharmony_ci } 231cabdff1aSopenharmony_ci} 232cabdff1aSopenharmony_ci 233cabdff1aSopenharmony_ci/** put n least significant bits of a number num */ 234cabdff1aSopenharmony_cistatic void put_num(Jpeg2000EncoderContext *s, int num, int n) 235cabdff1aSopenharmony_ci{ 236cabdff1aSopenharmony_ci while(--n >= 0) 237cabdff1aSopenharmony_ci put_bits(s, (num >> n) & 1, 1); 238cabdff1aSopenharmony_ci} 239cabdff1aSopenharmony_ci 240cabdff1aSopenharmony_ci/** flush the bitstream */ 241cabdff1aSopenharmony_cistatic void j2k_flush(Jpeg2000EncoderContext *s) 242cabdff1aSopenharmony_ci{ 243cabdff1aSopenharmony_ci if (s->bit_index){ 244cabdff1aSopenharmony_ci s->bit_index = 0; 245cabdff1aSopenharmony_ci s->buf++; 246cabdff1aSopenharmony_ci } 247cabdff1aSopenharmony_ci} 248cabdff1aSopenharmony_ci 249cabdff1aSopenharmony_ci/* tag tree routines */ 250cabdff1aSopenharmony_ci 251cabdff1aSopenharmony_ci/** code the value stored in node */ 252cabdff1aSopenharmony_cistatic void tag_tree_code(Jpeg2000EncoderContext *s, Jpeg2000TgtNode *node, int threshold) 253cabdff1aSopenharmony_ci{ 254cabdff1aSopenharmony_ci Jpeg2000TgtNode *stack[30]; 255cabdff1aSopenharmony_ci int sp = -1, curval = 0; 256cabdff1aSopenharmony_ci 257cabdff1aSopenharmony_ci while(node->parent){ 258cabdff1aSopenharmony_ci stack[++sp] = node; 259cabdff1aSopenharmony_ci node = node->parent; 260cabdff1aSopenharmony_ci } 261cabdff1aSopenharmony_ci 262cabdff1aSopenharmony_ci while (1) { 263cabdff1aSopenharmony_ci if (curval > node->temp_val) 264cabdff1aSopenharmony_ci node->temp_val = curval; 265cabdff1aSopenharmony_ci else { 266cabdff1aSopenharmony_ci curval = node->temp_val; 267cabdff1aSopenharmony_ci } 268cabdff1aSopenharmony_ci 269cabdff1aSopenharmony_ci if (node->val >= threshold) { 270cabdff1aSopenharmony_ci put_bits(s, 0, threshold - curval); 271cabdff1aSopenharmony_ci curval = threshold; 272cabdff1aSopenharmony_ci } else { 273cabdff1aSopenharmony_ci put_bits(s, 0, node->val - curval); 274cabdff1aSopenharmony_ci curval = node->val; 275cabdff1aSopenharmony_ci if (!node->vis) { 276cabdff1aSopenharmony_ci put_bits(s, 1, 1); 277cabdff1aSopenharmony_ci node->vis = 1; 278cabdff1aSopenharmony_ci } 279cabdff1aSopenharmony_ci } 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci node->temp_val = curval; 282cabdff1aSopenharmony_ci if (sp < 0) 283cabdff1aSopenharmony_ci break; 284cabdff1aSopenharmony_ci node = stack[sp--]; 285cabdff1aSopenharmony_ci } 286cabdff1aSopenharmony_ci} 287cabdff1aSopenharmony_ci 288cabdff1aSopenharmony_ci/** update the value in node */ 289cabdff1aSopenharmony_cistatic void tag_tree_update(Jpeg2000TgtNode *node) 290cabdff1aSopenharmony_ci{ 291cabdff1aSopenharmony_ci while (node->parent){ 292cabdff1aSopenharmony_ci if (node->parent->val <= node->val) 293cabdff1aSopenharmony_ci break; 294cabdff1aSopenharmony_ci node->parent->val = node->val; 295cabdff1aSopenharmony_ci node = node->parent; 296cabdff1aSopenharmony_ci } 297cabdff1aSopenharmony_ci} 298cabdff1aSopenharmony_ci 299cabdff1aSopenharmony_cistatic int put_siz(Jpeg2000EncoderContext *s) 300cabdff1aSopenharmony_ci{ 301cabdff1aSopenharmony_ci int i; 302cabdff1aSopenharmony_ci 303cabdff1aSopenharmony_ci if (s->buf_end - s->buf < 40 + 3 * s->ncomponents) 304cabdff1aSopenharmony_ci return -1; 305cabdff1aSopenharmony_ci 306cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_SIZ); 307cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, 38 + 3 * s->ncomponents); // Lsiz 308cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, 0); // Rsiz 309cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, s->width); // width 310cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, s->height); // height 311cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); // X0Siz 312cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); // Y0Siz 313cabdff1aSopenharmony_ci 314cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, s->tile_width); // XTSiz 315cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, s->tile_height); // YTSiz 316cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); // XT0Siz 317cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); // YT0Siz 318cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, s->ncomponents); // CSiz 319cabdff1aSopenharmony_ci 320cabdff1aSopenharmony_ci for (i = 0; i < s->ncomponents; i++){ // Ssiz_i XRsiz_i, YRsiz_i 321cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, s->cbps[i] - 1); 322cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, i?1<<s->chroma_shift[0]:1); 323cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, i?1<<s->chroma_shift[1]:1); 324cabdff1aSopenharmony_ci } 325cabdff1aSopenharmony_ci return 0; 326cabdff1aSopenharmony_ci} 327cabdff1aSopenharmony_ci 328cabdff1aSopenharmony_cistatic int put_cod(Jpeg2000EncoderContext *s) 329cabdff1aSopenharmony_ci{ 330cabdff1aSopenharmony_ci Jpeg2000CodingStyle *codsty = &s->codsty; 331cabdff1aSopenharmony_ci uint8_t scod = 0; 332cabdff1aSopenharmony_ci 333cabdff1aSopenharmony_ci if (s->buf_end - s->buf < 14) 334cabdff1aSopenharmony_ci return -1; 335cabdff1aSopenharmony_ci 336cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_COD); 337cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, 12); // Lcod 338cabdff1aSopenharmony_ci if (s->sop) 339cabdff1aSopenharmony_ci scod |= JPEG2000_CSTY_SOP; 340cabdff1aSopenharmony_ci if (s->eph) 341cabdff1aSopenharmony_ci scod |= JPEG2000_CSTY_EPH; 342cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, scod); // Scod 343cabdff1aSopenharmony_ci // SGcod 344cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, s->prog); // progression level 345cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, s->nlayers); // num of layers 346cabdff1aSopenharmony_ci if(s->avctx->pix_fmt == AV_PIX_FMT_YUV444P){ 347cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 0); // unspecified 348cabdff1aSopenharmony_ci }else{ 349cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 0); // unspecified 350cabdff1aSopenharmony_ci } 351cabdff1aSopenharmony_ci // SPcod 352cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, codsty->nreslevels - 1); // num of decomp. levels 353cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, codsty->log2_cblk_width-2); // cblk width 354cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, codsty->log2_cblk_height-2); // cblk height 355cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 0); // cblk style 356cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, codsty->transform == FF_DWT53); // transformation 357cabdff1aSopenharmony_ci return 0; 358cabdff1aSopenharmony_ci} 359cabdff1aSopenharmony_ci 360cabdff1aSopenharmony_cistatic int put_qcd(Jpeg2000EncoderContext *s, int compno) 361cabdff1aSopenharmony_ci{ 362cabdff1aSopenharmony_ci int i, size; 363cabdff1aSopenharmony_ci Jpeg2000CodingStyle *codsty = &s->codsty; 364cabdff1aSopenharmony_ci Jpeg2000QuantStyle *qntsty = &s->qntsty; 365cabdff1aSopenharmony_ci 366cabdff1aSopenharmony_ci if (qntsty->quantsty == JPEG2000_QSTY_NONE) 367cabdff1aSopenharmony_ci size = 4 + 3 * (codsty->nreslevels-1); 368cabdff1aSopenharmony_ci else // QSTY_SE 369cabdff1aSopenharmony_ci size = 5 + 6 * (codsty->nreslevels-1); 370cabdff1aSopenharmony_ci 371cabdff1aSopenharmony_ci if (s->buf_end - s->buf < size + 2) 372cabdff1aSopenharmony_ci return -1; 373cabdff1aSopenharmony_ci 374cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_QCD); 375cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, size); // LQcd 376cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, (qntsty->nguardbits << 5) | qntsty->quantsty); // Sqcd 377cabdff1aSopenharmony_ci if (qntsty->quantsty == JPEG2000_QSTY_NONE) 378cabdff1aSopenharmony_ci for (i = 0; i < codsty->nreslevels * 3 - 2; i++) 379cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, qntsty->expn[i] << 3); 380cabdff1aSopenharmony_ci else // QSTY_SE 381cabdff1aSopenharmony_ci for (i = 0; i < codsty->nreslevels * 3 - 2; i++) 382cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, (qntsty->expn[i] << 11) | qntsty->mant[i]); 383cabdff1aSopenharmony_ci return 0; 384cabdff1aSopenharmony_ci} 385cabdff1aSopenharmony_ci 386cabdff1aSopenharmony_cistatic int put_com(Jpeg2000EncoderContext *s, int compno) 387cabdff1aSopenharmony_ci{ 388cabdff1aSopenharmony_ci int size = 4 + strlen(LIBAVCODEC_IDENT); 389cabdff1aSopenharmony_ci 390cabdff1aSopenharmony_ci if (s->avctx->flags & AV_CODEC_FLAG_BITEXACT) 391cabdff1aSopenharmony_ci return 0; 392cabdff1aSopenharmony_ci 393cabdff1aSopenharmony_ci if (s->buf_end - s->buf < size + 2) 394cabdff1aSopenharmony_ci return -1; 395cabdff1aSopenharmony_ci 396cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_COM); 397cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, size); 398cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, 1); // General use (ISO/IEC 8859-15 (Latin) values) 399cabdff1aSopenharmony_ci 400cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, LIBAVCODEC_IDENT, strlen(LIBAVCODEC_IDENT)); 401cabdff1aSopenharmony_ci 402cabdff1aSopenharmony_ci return 0; 403cabdff1aSopenharmony_ci} 404cabdff1aSopenharmony_ci 405cabdff1aSopenharmony_cistatic uint8_t *put_sot(Jpeg2000EncoderContext *s, int tileno) 406cabdff1aSopenharmony_ci{ 407cabdff1aSopenharmony_ci uint8_t *psotptr; 408cabdff1aSopenharmony_ci 409cabdff1aSopenharmony_ci if (s->buf_end - s->buf < 12) 410cabdff1aSopenharmony_ci return NULL; 411cabdff1aSopenharmony_ci 412cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_SOT); 413cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, 10); // Lsot 414cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, tileno); // Isot 415cabdff1aSopenharmony_ci 416cabdff1aSopenharmony_ci psotptr = s->buf; 417cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); // Psot (filled in later) 418cabdff1aSopenharmony_ci 419cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 0); // TPsot 420cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 1); // TNsot 421cabdff1aSopenharmony_ci return psotptr; 422cabdff1aSopenharmony_ci} 423cabdff1aSopenharmony_ci 424cabdff1aSopenharmony_cistatic void compute_rates(Jpeg2000EncoderContext* s) 425cabdff1aSopenharmony_ci{ 426cabdff1aSopenharmony_ci int i, j; 427cabdff1aSopenharmony_ci int layno, compno; 428cabdff1aSopenharmony_ci for (i = 0; i < s->numYtiles; i++) { 429cabdff1aSopenharmony_ci for (j = 0; j < s->numXtiles; j++) { 430cabdff1aSopenharmony_ci Jpeg2000Tile *tile = &s->tile[s->numXtiles * i + j]; 431cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++) { 432cabdff1aSopenharmony_ci int tilew = tile->comp[compno].coord[0][1] - tile->comp[compno].coord[0][0]; 433cabdff1aSopenharmony_ci int tileh = tile->comp[compno].coord[1][1] - tile->comp[compno].coord[1][0]; 434cabdff1aSopenharmony_ci int scale = (compno?1 << s->chroma_shift[0]:1) * (compno?1 << s->chroma_shift[1]:1); 435cabdff1aSopenharmony_ci for (layno = 0; layno < s->nlayers; layno++) { 436cabdff1aSopenharmony_ci if (s->layer_rates[layno] > 0) { 437cabdff1aSopenharmony_ci tile->layer_rates[layno] += (double)(tilew * tileh) * s->ncomponents * s->cbps[compno] / 438cabdff1aSopenharmony_ci (double)(s->layer_rates[layno] * 8 * scale); 439cabdff1aSopenharmony_ci } else { 440cabdff1aSopenharmony_ci tile->layer_rates[layno] = 0.0; 441cabdff1aSopenharmony_ci } 442cabdff1aSopenharmony_ci } 443cabdff1aSopenharmony_ci } 444cabdff1aSopenharmony_ci } 445cabdff1aSopenharmony_ci } 446cabdff1aSopenharmony_ci 447cabdff1aSopenharmony_ci} 448cabdff1aSopenharmony_ci 449cabdff1aSopenharmony_ci/** 450cabdff1aSopenharmony_ci * compute the sizes of tiles, resolution levels, bands, etc. 451cabdff1aSopenharmony_ci * allocate memory for them 452cabdff1aSopenharmony_ci * divide the input image into tile-components 453cabdff1aSopenharmony_ci */ 454cabdff1aSopenharmony_cistatic int init_tiles(Jpeg2000EncoderContext *s) 455cabdff1aSopenharmony_ci{ 456cabdff1aSopenharmony_ci int tileno, tilex, tiley, compno; 457cabdff1aSopenharmony_ci Jpeg2000CodingStyle *codsty = &s->codsty; 458cabdff1aSopenharmony_ci Jpeg2000QuantStyle *qntsty = &s->qntsty; 459cabdff1aSopenharmony_ci 460cabdff1aSopenharmony_ci s->numXtiles = ff_jpeg2000_ceildiv(s->width, s->tile_width); 461cabdff1aSopenharmony_ci s->numYtiles = ff_jpeg2000_ceildiv(s->height, s->tile_height); 462cabdff1aSopenharmony_ci 463cabdff1aSopenharmony_ci s->tile = av_calloc(s->numXtiles, s->numYtiles * sizeof(Jpeg2000Tile)); 464cabdff1aSopenharmony_ci if (!s->tile) 465cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 466cabdff1aSopenharmony_ci for (tileno = 0, tiley = 0; tiley < s->numYtiles; tiley++) 467cabdff1aSopenharmony_ci for (tilex = 0; tilex < s->numXtiles; tilex++, tileno++){ 468cabdff1aSopenharmony_ci Jpeg2000Tile *tile = s->tile + tileno; 469cabdff1aSopenharmony_ci 470cabdff1aSopenharmony_ci tile->comp = av_calloc(s->ncomponents, sizeof(*tile->comp)); 471cabdff1aSopenharmony_ci if (!tile->comp) 472cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 473cabdff1aSopenharmony_ci 474cabdff1aSopenharmony_ci tile->layer_rates = av_calloc(s->nlayers, sizeof(*tile->layer_rates)); 475cabdff1aSopenharmony_ci if (!tile->layer_rates) 476cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 477cabdff1aSopenharmony_ci 478cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++){ 479cabdff1aSopenharmony_ci Jpeg2000Component *comp = tile->comp + compno; 480cabdff1aSopenharmony_ci int ret, i, j; 481cabdff1aSopenharmony_ci 482cabdff1aSopenharmony_ci comp->coord[0][0] = comp->coord_o[0][0] = tilex * s->tile_width; 483cabdff1aSopenharmony_ci comp->coord[0][1] = comp->coord_o[0][1] = FFMIN((tilex+1)*s->tile_width, s->width); 484cabdff1aSopenharmony_ci comp->coord[1][0] = comp->coord_o[1][0] = tiley * s->tile_height; 485cabdff1aSopenharmony_ci comp->coord[1][1] = comp->coord_o[1][1] = FFMIN((tiley+1)*s->tile_height, s->height); 486cabdff1aSopenharmony_ci if (compno > 0) 487cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) 488cabdff1aSopenharmony_ci for (j = 0; j < 2; j++) 489cabdff1aSopenharmony_ci comp->coord[i][j] = comp->coord_o[i][j] = ff_jpeg2000_ceildivpow2(comp->coord[i][j], s->chroma_shift[i]); 490cabdff1aSopenharmony_ci 491cabdff1aSopenharmony_ci if ((ret = ff_jpeg2000_init_component(comp, 492cabdff1aSopenharmony_ci codsty, 493cabdff1aSopenharmony_ci qntsty, 494cabdff1aSopenharmony_ci s->cbps[compno], 495cabdff1aSopenharmony_ci compno?1<<s->chroma_shift[0]:1, 496cabdff1aSopenharmony_ci compno?1<<s->chroma_shift[1]:1, 497cabdff1aSopenharmony_ci s->avctx 498cabdff1aSopenharmony_ci )) < 0) 499cabdff1aSopenharmony_ci return ret; 500cabdff1aSopenharmony_ci } 501cabdff1aSopenharmony_ci } 502cabdff1aSopenharmony_ci compute_rates(s); 503cabdff1aSopenharmony_ci return 0; 504cabdff1aSopenharmony_ci} 505cabdff1aSopenharmony_ci 506cabdff1aSopenharmony_ci#define COPY_FRAME(D, PIXEL) \ 507cabdff1aSopenharmony_ci static void copy_frame_ ##D(Jpeg2000EncoderContext *s) \ 508cabdff1aSopenharmony_ci { \ 509cabdff1aSopenharmony_ci int tileno, compno, i, y, x; \ 510cabdff1aSopenharmony_ci PIXEL *line; \ 511cabdff1aSopenharmony_ci for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ \ 512cabdff1aSopenharmony_ci Jpeg2000Tile *tile = s->tile + tileno; \ 513cabdff1aSopenharmony_ci if (s->planar){ \ 514cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++){ \ 515cabdff1aSopenharmony_ci Jpeg2000Component *comp = tile->comp + compno; \ 516cabdff1aSopenharmony_ci int *dst = comp->i_data; \ 517cabdff1aSopenharmony_ci int cbps = s->cbps[compno]; \ 518cabdff1aSopenharmony_ci line = (PIXEL*)s->picture->data[compno] \ 519cabdff1aSopenharmony_ci + comp->coord[1][0] * (s->picture->linesize[compno] / sizeof(PIXEL)) \ 520cabdff1aSopenharmony_ci + comp->coord[0][0]; \ 521cabdff1aSopenharmony_ci for (y = comp->coord[1][0]; y < comp->coord[1][1]; y++){ \ 522cabdff1aSopenharmony_ci PIXEL *ptr = line; \ 523cabdff1aSopenharmony_ci for (x = comp->coord[0][0]; x < comp->coord[0][1]; x++) \ 524cabdff1aSopenharmony_ci *dst++ = *ptr++ - (1 << (cbps - 1)); \ 525cabdff1aSopenharmony_ci line += s->picture->linesize[compno] / sizeof(PIXEL); \ 526cabdff1aSopenharmony_ci } \ 527cabdff1aSopenharmony_ci } \ 528cabdff1aSopenharmony_ci } else{ \ 529cabdff1aSopenharmony_ci line = (PIXEL*)s->picture->data[0] + tile->comp[0].coord[1][0] * (s->picture->linesize[0] / sizeof(PIXEL)) \ 530cabdff1aSopenharmony_ci + tile->comp[0].coord[0][0] * s->ncomponents; \ 531cabdff1aSopenharmony_ci \ 532cabdff1aSopenharmony_ci i = 0; \ 533cabdff1aSopenharmony_ci for (y = tile->comp[0].coord[1][0]; y < tile->comp[0].coord[1][1]; y++){ \ 534cabdff1aSopenharmony_ci PIXEL *ptr = line; \ 535cabdff1aSopenharmony_ci for (x = tile->comp[0].coord[0][0]; x < tile->comp[0].coord[0][1]; x++, i++){ \ 536cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++){ \ 537cabdff1aSopenharmony_ci int cbps = s->cbps[compno]; \ 538cabdff1aSopenharmony_ci tile->comp[compno].i_data[i] = *ptr++ - (1 << (cbps - 1)); \ 539cabdff1aSopenharmony_ci } \ 540cabdff1aSopenharmony_ci } \ 541cabdff1aSopenharmony_ci line += s->picture->linesize[0] / sizeof(PIXEL); \ 542cabdff1aSopenharmony_ci } \ 543cabdff1aSopenharmony_ci } \ 544cabdff1aSopenharmony_ci } \ 545cabdff1aSopenharmony_ci } 546cabdff1aSopenharmony_ci 547cabdff1aSopenharmony_ciCOPY_FRAME(8, uint8_t) 548cabdff1aSopenharmony_ciCOPY_FRAME(16, uint16_t) 549cabdff1aSopenharmony_ci 550cabdff1aSopenharmony_cistatic void init_quantization(Jpeg2000EncoderContext *s) 551cabdff1aSopenharmony_ci{ 552cabdff1aSopenharmony_ci int compno, reslevelno, bandno; 553cabdff1aSopenharmony_ci Jpeg2000QuantStyle *qntsty = &s->qntsty; 554cabdff1aSopenharmony_ci Jpeg2000CodingStyle *codsty = &s->codsty; 555cabdff1aSopenharmony_ci 556cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++){ 557cabdff1aSopenharmony_ci int gbandno = 0; 558cabdff1aSopenharmony_ci for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ 559cabdff1aSopenharmony_ci int nbands, lev = codsty->nreslevels - reslevelno - 1; 560cabdff1aSopenharmony_ci nbands = reslevelno ? 3 : 1; 561cabdff1aSopenharmony_ci for (bandno = 0; bandno < nbands; bandno++, gbandno++){ 562cabdff1aSopenharmony_ci int expn, mant = 0; 563cabdff1aSopenharmony_ci 564cabdff1aSopenharmony_ci if (codsty->transform == FF_DWT97_INT){ 565cabdff1aSopenharmony_ci int bandpos = bandno + (reslevelno>0), 566cabdff1aSopenharmony_ci ss = 81920000 / dwt_norms[0][bandpos][lev], 567cabdff1aSopenharmony_ci log = av_log2(ss); 568cabdff1aSopenharmony_ci mant = (11 - log < 0 ? ss >> log - 11 : ss << 11 - log) & 0x7ff; 569cabdff1aSopenharmony_ci expn = s->cbps[compno] - log + 13; 570cabdff1aSopenharmony_ci } else 571cabdff1aSopenharmony_ci expn = ((bandno&2)>>1) + (reslevelno>0) + s->cbps[compno]; 572cabdff1aSopenharmony_ci 573cabdff1aSopenharmony_ci qntsty->expn[gbandno] = expn; 574cabdff1aSopenharmony_ci qntsty->mant[gbandno] = mant; 575cabdff1aSopenharmony_ci } 576cabdff1aSopenharmony_ci } 577cabdff1aSopenharmony_ci } 578cabdff1aSopenharmony_ci} 579cabdff1aSopenharmony_ci 580cabdff1aSopenharmony_cistatic void init_luts(void) 581cabdff1aSopenharmony_ci{ 582cabdff1aSopenharmony_ci int i, a, 583cabdff1aSopenharmony_ci mask = ~((1<<NMSEDEC_FRACBITS)-1); 584cabdff1aSopenharmony_ci 585cabdff1aSopenharmony_ci for (i = 0; i < (1 << NMSEDEC_BITS); i++){ 586cabdff1aSopenharmony_ci lut_nmsedec_sig[i] = FFMAX((3 * i << (13 - NMSEDEC_FRACBITS)) - (9 << 11), 0); 587cabdff1aSopenharmony_ci lut_nmsedec_sig0[i] = FFMAX((i*i + (1<<NMSEDEC_FRACBITS-1) & mask) << 1, 0); 588cabdff1aSopenharmony_ci 589cabdff1aSopenharmony_ci a = (i >> (NMSEDEC_BITS-2)&2) + 1; 590cabdff1aSopenharmony_ci lut_nmsedec_ref[i] = FFMAX((a - 2) * (i << (13 - NMSEDEC_FRACBITS)) + 591cabdff1aSopenharmony_ci (1 << 13) - (a * a << 11), 0); 592cabdff1aSopenharmony_ci lut_nmsedec_ref0[i] = FFMAX(((i * i - (i << NMSEDEC_BITS) + (1 << 2 * NMSEDEC_FRACBITS) + (1 << (NMSEDEC_FRACBITS - 1))) & mask) 593cabdff1aSopenharmony_ci << 1, 0); 594cabdff1aSopenharmony_ci } 595cabdff1aSopenharmony_ci ff_jpeg2000_init_tier1_luts(); 596cabdff1aSopenharmony_ci} 597cabdff1aSopenharmony_ci 598cabdff1aSopenharmony_ci/* tier-1 routines */ 599cabdff1aSopenharmony_cistatic int getnmsedec_sig(int x, int bpno) 600cabdff1aSopenharmony_ci{ 601cabdff1aSopenharmony_ci if (bpno > NMSEDEC_FRACBITS) 602cabdff1aSopenharmony_ci return lut_nmsedec_sig[(x >> (bpno - NMSEDEC_FRACBITS)) & ((1 << NMSEDEC_BITS) - 1)]; 603cabdff1aSopenharmony_ci return lut_nmsedec_sig0[x & ((1 << NMSEDEC_BITS) - 1)]; 604cabdff1aSopenharmony_ci} 605cabdff1aSopenharmony_ci 606cabdff1aSopenharmony_cistatic int getnmsedec_ref(int x, int bpno) 607cabdff1aSopenharmony_ci{ 608cabdff1aSopenharmony_ci if (bpno > NMSEDEC_FRACBITS) 609cabdff1aSopenharmony_ci return lut_nmsedec_ref[(x >> (bpno - NMSEDEC_FRACBITS)) & ((1 << NMSEDEC_BITS) - 1)]; 610cabdff1aSopenharmony_ci return lut_nmsedec_ref0[x & ((1 << NMSEDEC_BITS) - 1)]; 611cabdff1aSopenharmony_ci} 612cabdff1aSopenharmony_ci 613cabdff1aSopenharmony_cistatic void encode_sigpass(Jpeg2000T1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno) 614cabdff1aSopenharmony_ci{ 615cabdff1aSopenharmony_ci int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS); 616cabdff1aSopenharmony_ci for (y0 = 0; y0 < height; y0 += 4) 617cabdff1aSopenharmony_ci for (x = 0; x < width; x++) 618cabdff1aSopenharmony_ci for (y = y0; y < height && y < y0+4; y++){ 619cabdff1aSopenharmony_ci if (!(t1->flags[(y+1) * t1->stride + x+1] & JPEG2000_T1_SIG) && (t1->flags[(y+1) * t1->stride + x+1] & JPEG2000_T1_SIG_NB)){ 620cabdff1aSopenharmony_ci int ctxno = ff_jpeg2000_getsigctxno(t1->flags[(y+1) * t1->stride + x+1], bandno), 621cabdff1aSopenharmony_ci bit = t1->data[(y) * t1->stride + x] & mask ? 1 : 0; 622cabdff1aSopenharmony_ci ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, bit); 623cabdff1aSopenharmony_ci if (bit){ 624cabdff1aSopenharmony_ci int xorbit; 625cabdff1aSopenharmony_ci int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[(y+1) * t1->stride + x+1], &xorbit); 626cabdff1aSopenharmony_ci ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[(y+1) * t1->stride + x+1] >> 15) ^ xorbit); 627cabdff1aSopenharmony_ci *nmsedec += getnmsedec_sig(t1->data[(y) * t1->stride + x], bpno + NMSEDEC_FRACBITS); 628cabdff1aSopenharmony_ci ff_jpeg2000_set_significance(t1, x, y, t1->flags[(y+1) * t1->stride + x+1] >> 15); 629cabdff1aSopenharmony_ci } 630cabdff1aSopenharmony_ci t1->flags[(y+1) * t1->stride + x+1] |= JPEG2000_T1_VIS; 631cabdff1aSopenharmony_ci } 632cabdff1aSopenharmony_ci } 633cabdff1aSopenharmony_ci} 634cabdff1aSopenharmony_ci 635cabdff1aSopenharmony_cistatic void encode_refpass(Jpeg2000T1Context *t1, int width, int height, int *nmsedec, int bpno) 636cabdff1aSopenharmony_ci{ 637cabdff1aSopenharmony_ci int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS); 638cabdff1aSopenharmony_ci for (y0 = 0; y0 < height; y0 += 4) 639cabdff1aSopenharmony_ci for (x = 0; x < width; x++) 640cabdff1aSopenharmony_ci for (y = y0; y < height && y < y0+4; y++) 641cabdff1aSopenharmony_ci if ((t1->flags[(y+1) * t1->stride + x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS)) == JPEG2000_T1_SIG){ 642cabdff1aSopenharmony_ci int ctxno = ff_jpeg2000_getrefctxno(t1->flags[(y+1) * t1->stride + x+1]); 643cabdff1aSopenharmony_ci *nmsedec += getnmsedec_ref(t1->data[(y) * t1->stride + x], bpno + NMSEDEC_FRACBITS); 644cabdff1aSopenharmony_ci ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[(y) * t1->stride + x] & mask ? 1:0); 645cabdff1aSopenharmony_ci t1->flags[(y+1) * t1->stride + x+1] |= JPEG2000_T1_REF; 646cabdff1aSopenharmony_ci } 647cabdff1aSopenharmony_ci} 648cabdff1aSopenharmony_ci 649cabdff1aSopenharmony_cistatic void encode_clnpass(Jpeg2000T1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno) 650cabdff1aSopenharmony_ci{ 651cabdff1aSopenharmony_ci int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS); 652cabdff1aSopenharmony_ci for (y0 = 0; y0 < height; y0 += 4) 653cabdff1aSopenharmony_ci for (x = 0; x < width; x++){ 654cabdff1aSopenharmony_ci if (y0 + 3 < height && !( 655cabdff1aSopenharmony_ci (t1->flags[(y0+1) * t1->stride + x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) || 656cabdff1aSopenharmony_ci (t1->flags[(y0+2) * t1->stride + x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) || 657cabdff1aSopenharmony_ci (t1->flags[(y0+3) * t1->stride + x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) || 658cabdff1aSopenharmony_ci (t1->flags[(y0+4) * t1->stride + x+1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)))) 659cabdff1aSopenharmony_ci { 660cabdff1aSopenharmony_ci // aggregation mode 661cabdff1aSopenharmony_ci int rlen; 662cabdff1aSopenharmony_ci for (rlen = 0; rlen < 4; rlen++) 663cabdff1aSopenharmony_ci if (t1->data[(y0+rlen) * t1->stride + x] & mask) 664cabdff1aSopenharmony_ci break; 665cabdff1aSopenharmony_ci ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL, rlen != 4); 666cabdff1aSopenharmony_ci if (rlen == 4) 667cabdff1aSopenharmony_ci continue; 668cabdff1aSopenharmony_ci ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI, rlen >> 1); 669cabdff1aSopenharmony_ci ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI, rlen & 1); 670cabdff1aSopenharmony_ci for (y = y0 + rlen; y < y0 + 4; y++){ 671cabdff1aSopenharmony_ci if (!(t1->flags[(y+1) * t1->stride + x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))){ 672cabdff1aSopenharmony_ci int ctxno = ff_jpeg2000_getsigctxno(t1->flags[(y+1) * t1->stride + x+1], bandno); 673cabdff1aSopenharmony_ci if (y > y0 + rlen) 674cabdff1aSopenharmony_ci ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[(y) * t1->stride + x] & mask ? 1:0); 675cabdff1aSopenharmony_ci if (t1->data[(y) * t1->stride + x] & mask){ // newly significant 676cabdff1aSopenharmony_ci int xorbit; 677cabdff1aSopenharmony_ci int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[(y+1) * t1->stride + x+1], &xorbit); 678cabdff1aSopenharmony_ci *nmsedec += getnmsedec_sig(t1->data[(y) * t1->stride + x], bpno + NMSEDEC_FRACBITS); 679cabdff1aSopenharmony_ci ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[(y+1) * t1->stride + x+1] >> 15) ^ xorbit); 680cabdff1aSopenharmony_ci ff_jpeg2000_set_significance(t1, x, y, t1->flags[(y+1) * t1->stride + x+1] >> 15); 681cabdff1aSopenharmony_ci } 682cabdff1aSopenharmony_ci } 683cabdff1aSopenharmony_ci t1->flags[(y+1) * t1->stride + x+1] &= ~JPEG2000_T1_VIS; 684cabdff1aSopenharmony_ci } 685cabdff1aSopenharmony_ci } else{ 686cabdff1aSopenharmony_ci for (y = y0; y < y0 + 4 && y < height; y++){ 687cabdff1aSopenharmony_ci if (!(t1->flags[(y+1) * t1->stride + x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))){ 688cabdff1aSopenharmony_ci int ctxno = ff_jpeg2000_getsigctxno(t1->flags[(y+1) * t1->stride + x+1], bandno); 689cabdff1aSopenharmony_ci ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[(y) * t1->stride + x] & mask ? 1:0); 690cabdff1aSopenharmony_ci if (t1->data[(y) * t1->stride + x] & mask){ // newly significant 691cabdff1aSopenharmony_ci int xorbit; 692cabdff1aSopenharmony_ci int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[(y+1) * t1->stride + x+1], &xorbit); 693cabdff1aSopenharmony_ci *nmsedec += getnmsedec_sig(t1->data[(y) * t1->stride + x], bpno + NMSEDEC_FRACBITS); 694cabdff1aSopenharmony_ci ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[(y+1) * t1->stride + x+1] >> 15) ^ xorbit); 695cabdff1aSopenharmony_ci ff_jpeg2000_set_significance(t1, x, y, t1->flags[(y+1) * t1->stride + x+1] >> 15); 696cabdff1aSopenharmony_ci } 697cabdff1aSopenharmony_ci } 698cabdff1aSopenharmony_ci t1->flags[(y+1) * t1->stride + x+1] &= ~JPEG2000_T1_VIS; 699cabdff1aSopenharmony_ci } 700cabdff1aSopenharmony_ci } 701cabdff1aSopenharmony_ci } 702cabdff1aSopenharmony_ci} 703cabdff1aSopenharmony_ci 704cabdff1aSopenharmony_cistatic void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk, Jpeg2000Tile *tile, 705cabdff1aSopenharmony_ci int width, int height, int bandpos, int lev) 706cabdff1aSopenharmony_ci{ 707cabdff1aSopenharmony_ci int pass_t = 2, passno, x, y, max=0, nmsedec, bpno; 708cabdff1aSopenharmony_ci int64_t wmsedec = 0; 709cabdff1aSopenharmony_ci 710cabdff1aSopenharmony_ci memset(t1->flags, 0, t1->stride * (height + 2) * sizeof(*t1->flags)); 711cabdff1aSopenharmony_ci 712cabdff1aSopenharmony_ci for (y = 0; y < height; y++){ 713cabdff1aSopenharmony_ci for (x = 0; x < width; x++){ 714cabdff1aSopenharmony_ci if (t1->data[(y) * t1->stride + x] < 0){ 715cabdff1aSopenharmony_ci t1->flags[(y+1) * t1->stride + x+1] |= JPEG2000_T1_SGN; 716cabdff1aSopenharmony_ci t1->data[(y) * t1->stride + x] = -t1->data[(y) * t1->stride + x]; 717cabdff1aSopenharmony_ci } 718cabdff1aSopenharmony_ci max = FFMAX(max, t1->data[(y) * t1->stride + x]); 719cabdff1aSopenharmony_ci } 720cabdff1aSopenharmony_ci } 721cabdff1aSopenharmony_ci 722cabdff1aSopenharmony_ci if (max == 0){ 723cabdff1aSopenharmony_ci cblk->nonzerobits = 0; 724cabdff1aSopenharmony_ci } else{ 725cabdff1aSopenharmony_ci cblk->nonzerobits = av_log2(max) + 1 - NMSEDEC_FRACBITS; 726cabdff1aSopenharmony_ci } 727cabdff1aSopenharmony_ci bpno = cblk->nonzerobits - 1; 728cabdff1aSopenharmony_ci 729cabdff1aSopenharmony_ci cblk->data[0] = 0; 730cabdff1aSopenharmony_ci ff_mqc_initenc(&t1->mqc, cblk->data + 1); 731cabdff1aSopenharmony_ci 732cabdff1aSopenharmony_ci for (passno = 0; bpno >= 0; passno++){ 733cabdff1aSopenharmony_ci nmsedec=0; 734cabdff1aSopenharmony_ci 735cabdff1aSopenharmony_ci switch(pass_t){ 736cabdff1aSopenharmony_ci case 0: encode_sigpass(t1, width, height, bandpos, &nmsedec, bpno); 737cabdff1aSopenharmony_ci break; 738cabdff1aSopenharmony_ci case 1: encode_refpass(t1, width, height, &nmsedec, bpno); 739cabdff1aSopenharmony_ci break; 740cabdff1aSopenharmony_ci case 2: encode_clnpass(t1, width, height, bandpos, &nmsedec, bpno); 741cabdff1aSopenharmony_ci break; 742cabdff1aSopenharmony_ci } 743cabdff1aSopenharmony_ci 744cabdff1aSopenharmony_ci cblk->passes[passno].rate = ff_mqc_flush_to(&t1->mqc, cblk->passes[passno].flushed, &cblk->passes[passno].flushed_len); 745cabdff1aSopenharmony_ci cblk->passes[passno].rate -= cblk->passes[passno].flushed_len; 746cabdff1aSopenharmony_ci 747cabdff1aSopenharmony_ci wmsedec += (int64_t)nmsedec << (2*bpno); 748cabdff1aSopenharmony_ci cblk->passes[passno].disto = wmsedec; 749cabdff1aSopenharmony_ci 750cabdff1aSopenharmony_ci if (++pass_t == 3){ 751cabdff1aSopenharmony_ci pass_t = 0; 752cabdff1aSopenharmony_ci bpno--; 753cabdff1aSopenharmony_ci } 754cabdff1aSopenharmony_ci } 755cabdff1aSopenharmony_ci cblk->npasses = passno; 756cabdff1aSopenharmony_ci cblk->ninclpasses = passno; 757cabdff1aSopenharmony_ci 758cabdff1aSopenharmony_ci if (passno) { 759cabdff1aSopenharmony_ci cblk->passes[passno-1].rate = ff_mqc_flush_to(&t1->mqc, cblk->passes[passno-1].flushed, &cblk->passes[passno-1].flushed_len); 760cabdff1aSopenharmony_ci cblk->passes[passno-1].rate -= cblk->passes[passno-1].flushed_len; 761cabdff1aSopenharmony_ci } 762cabdff1aSopenharmony_ci} 763cabdff1aSopenharmony_ci 764cabdff1aSopenharmony_ci/* tier-2 routines: */ 765cabdff1aSopenharmony_ci 766cabdff1aSopenharmony_cistatic void putnumpasses(Jpeg2000EncoderContext *s, int n) 767cabdff1aSopenharmony_ci{ 768cabdff1aSopenharmony_ci if (n == 1) 769cabdff1aSopenharmony_ci put_num(s, 0, 1); 770cabdff1aSopenharmony_ci else if (n == 2) 771cabdff1aSopenharmony_ci put_num(s, 2, 2); 772cabdff1aSopenharmony_ci else if (n <= 5) 773cabdff1aSopenharmony_ci put_num(s, 0xc | (n-3), 4); 774cabdff1aSopenharmony_ci else if (n <= 36) 775cabdff1aSopenharmony_ci put_num(s, 0x1e0 | (n-6), 9); 776cabdff1aSopenharmony_ci else 777cabdff1aSopenharmony_ci put_num(s, 0xff80 | (n-37), 16); 778cabdff1aSopenharmony_ci} 779cabdff1aSopenharmony_ci 780cabdff1aSopenharmony_ci 781cabdff1aSopenharmony_cistatic int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, int layno, 782cabdff1aSopenharmony_ci int precno, uint8_t *expn, int numgbits, int packetno, 783cabdff1aSopenharmony_ci int nlayers) 784cabdff1aSopenharmony_ci{ 785cabdff1aSopenharmony_ci int bandno, empty = 1; 786cabdff1aSopenharmony_ci int i; 787cabdff1aSopenharmony_ci // init bitstream 788cabdff1aSopenharmony_ci *s->buf = 0; 789cabdff1aSopenharmony_ci s->bit_index = 0; 790cabdff1aSopenharmony_ci 791cabdff1aSopenharmony_ci if (s->sop) { 792cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_SOP); 793cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, 4); 794cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, packetno); 795cabdff1aSopenharmony_ci } 796cabdff1aSopenharmony_ci // header 797cabdff1aSopenharmony_ci 798cabdff1aSopenharmony_ci if (!layno) { 799cabdff1aSopenharmony_ci for (bandno = 0; bandno < rlevel->nbands; bandno++) { 800cabdff1aSopenharmony_ci Jpeg2000Band *band = rlevel->band + bandno; 801cabdff1aSopenharmony_ci if (band->coord[0][0] < band->coord[0][1] 802cabdff1aSopenharmony_ci && band->coord[1][0] < band->coord[1][1]) { 803cabdff1aSopenharmony_ci Jpeg2000Prec *prec = band->prec + precno; 804cabdff1aSopenharmony_ci int nb_cblks = prec->nb_codeblocks_height * prec->nb_codeblocks_width; 805cabdff1aSopenharmony_ci int pos; 806cabdff1aSopenharmony_ci ff_tag_tree_zero(prec->zerobits, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 99); 807cabdff1aSopenharmony_ci ff_tag_tree_zero(prec->cblkincl, prec->nb_codeblocks_width, prec->nb_codeblocks_height, 99); 808cabdff1aSopenharmony_ci for (pos = 0; pos < nb_cblks; pos++) { 809cabdff1aSopenharmony_ci Jpeg2000Cblk *cblk = &prec->cblk[pos]; 810cabdff1aSopenharmony_ci prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - cblk->nonzerobits; 811cabdff1aSopenharmony_ci cblk->incl = 0; 812cabdff1aSopenharmony_ci cblk->lblock = 3; 813cabdff1aSopenharmony_ci tag_tree_update(prec->zerobits + pos); 814cabdff1aSopenharmony_ci for (i = 0; i < nlayers; i++) { 815cabdff1aSopenharmony_ci if (cblk->layers[i].npasses > 0) { 816cabdff1aSopenharmony_ci prec->cblkincl[pos].val = i; 817cabdff1aSopenharmony_ci break; 818cabdff1aSopenharmony_ci } 819cabdff1aSopenharmony_ci } 820cabdff1aSopenharmony_ci if (i == nlayers) 821cabdff1aSopenharmony_ci prec->cblkincl[pos].val = i; 822cabdff1aSopenharmony_ci tag_tree_update(prec->cblkincl + pos); 823cabdff1aSopenharmony_ci } 824cabdff1aSopenharmony_ci } 825cabdff1aSopenharmony_ci } 826cabdff1aSopenharmony_ci } 827cabdff1aSopenharmony_ci 828cabdff1aSopenharmony_ci // is the packet empty? 829cabdff1aSopenharmony_ci for (bandno = 0; bandno < rlevel->nbands; bandno++){ 830cabdff1aSopenharmony_ci Jpeg2000Band *band = rlevel->band + bandno; 831cabdff1aSopenharmony_ci if (band->coord[0][0] < band->coord[0][1] 832cabdff1aSopenharmony_ci && band->coord[1][0] < band->coord[1][1]) { 833cabdff1aSopenharmony_ci Jpeg2000Prec *prec = band->prec + precno; 834cabdff1aSopenharmony_ci int nb_cblks = prec->nb_codeblocks_height * prec->nb_codeblocks_width; 835cabdff1aSopenharmony_ci int pos; 836cabdff1aSopenharmony_ci for (pos = 0; pos < nb_cblks; pos++) { 837cabdff1aSopenharmony_ci Jpeg2000Cblk *cblk = &prec->cblk[pos]; 838cabdff1aSopenharmony_ci if (cblk->layers[layno].npasses) { 839cabdff1aSopenharmony_ci empty = 0; 840cabdff1aSopenharmony_ci break; 841cabdff1aSopenharmony_ci } 842cabdff1aSopenharmony_ci } 843cabdff1aSopenharmony_ci if (!empty) 844cabdff1aSopenharmony_ci break; 845cabdff1aSopenharmony_ci } 846cabdff1aSopenharmony_ci } 847cabdff1aSopenharmony_ci 848cabdff1aSopenharmony_ci put_bits(s, !empty, 1); 849cabdff1aSopenharmony_ci if (empty){ 850cabdff1aSopenharmony_ci j2k_flush(s); 851cabdff1aSopenharmony_ci if (s->eph) 852cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_EPH); 853cabdff1aSopenharmony_ci return 0; 854cabdff1aSopenharmony_ci } 855cabdff1aSopenharmony_ci 856cabdff1aSopenharmony_ci for (bandno = 0; bandno < rlevel->nbands; bandno++) { 857cabdff1aSopenharmony_ci Jpeg2000Band *band = rlevel->band + bandno; 858cabdff1aSopenharmony_ci Jpeg2000Prec *prec = band->prec + precno; 859cabdff1aSopenharmony_ci int yi, xi, pos; 860cabdff1aSopenharmony_ci int cblknw = prec->nb_codeblocks_width; 861cabdff1aSopenharmony_ci 862cabdff1aSopenharmony_ci if (band->coord[0][0] == band->coord[0][1] 863cabdff1aSopenharmony_ci || band->coord[1][0] == band->coord[1][1]) 864cabdff1aSopenharmony_ci continue; 865cabdff1aSopenharmony_ci 866cabdff1aSopenharmony_ci for (pos=0, yi = 0; yi < prec->nb_codeblocks_height; yi++) { 867cabdff1aSopenharmony_ci for (xi = 0; xi < cblknw; xi++, pos++){ 868cabdff1aSopenharmony_ci int llen = 0, length; 869cabdff1aSopenharmony_ci Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi; 870cabdff1aSopenharmony_ci 871cabdff1aSopenharmony_ci if (s->buf_end - s->buf < 20) // approximately 872cabdff1aSopenharmony_ci return -1; 873cabdff1aSopenharmony_ci 874cabdff1aSopenharmony_ci // inclusion information 875cabdff1aSopenharmony_ci if (!cblk->incl) 876cabdff1aSopenharmony_ci tag_tree_code(s, prec->cblkincl + pos, layno + 1); 877cabdff1aSopenharmony_ci else { 878cabdff1aSopenharmony_ci put_bits(s, cblk->layers[layno].npasses > 0, 1); 879cabdff1aSopenharmony_ci } 880cabdff1aSopenharmony_ci 881cabdff1aSopenharmony_ci if (!cblk->layers[layno].npasses) 882cabdff1aSopenharmony_ci continue; 883cabdff1aSopenharmony_ci 884cabdff1aSopenharmony_ci // zerobits information 885cabdff1aSopenharmony_ci if (!cblk->incl) { 886cabdff1aSopenharmony_ci tag_tree_code(s, prec->zerobits + pos, 100); 887cabdff1aSopenharmony_ci cblk->incl = 1; 888cabdff1aSopenharmony_ci } 889cabdff1aSopenharmony_ci 890cabdff1aSopenharmony_ci // number of passes 891cabdff1aSopenharmony_ci putnumpasses(s, cblk->layers[layno].npasses); 892cabdff1aSopenharmony_ci 893cabdff1aSopenharmony_ci length = cblk->layers[layno].data_len; 894cabdff1aSopenharmony_ci if (layno == nlayers - 1 && cblk->layers[layno].cum_passes){ 895cabdff1aSopenharmony_ci length += cblk->passes[cblk->layers[layno].cum_passes-1].flushed_len; 896cabdff1aSopenharmony_ci } 897cabdff1aSopenharmony_ci if (cblk->lblock + av_log2(cblk->layers[layno].npasses) < av_log2(length) + 1) { 898cabdff1aSopenharmony_ci llen = av_log2(length) + 1 - cblk->lblock - av_log2(cblk->layers[layno].npasses); 899cabdff1aSopenharmony_ci } 900cabdff1aSopenharmony_ci 901cabdff1aSopenharmony_ci // length of code block 902cabdff1aSopenharmony_ci cblk->lblock += llen; 903cabdff1aSopenharmony_ci put_bits(s, 1, llen); 904cabdff1aSopenharmony_ci put_bits(s, 0, 1); 905cabdff1aSopenharmony_ci put_num(s, length, cblk->lblock + av_log2(cblk->layers[layno].npasses)); 906cabdff1aSopenharmony_ci } 907cabdff1aSopenharmony_ci } 908cabdff1aSopenharmony_ci } 909cabdff1aSopenharmony_ci j2k_flush(s); 910cabdff1aSopenharmony_ci if (s->eph) { 911cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_EPH); 912cabdff1aSopenharmony_ci } 913cabdff1aSopenharmony_ci 914cabdff1aSopenharmony_ci for (bandno = 0; bandno < rlevel->nbands; bandno++) { 915cabdff1aSopenharmony_ci Jpeg2000Band *band = rlevel->band + bandno; 916cabdff1aSopenharmony_ci Jpeg2000Prec *prec = band->prec + precno; 917cabdff1aSopenharmony_ci int yi, cblknw = prec->nb_codeblocks_width; 918cabdff1aSopenharmony_ci for (yi =0; yi < prec->nb_codeblocks_height; yi++) { 919cabdff1aSopenharmony_ci int xi; 920cabdff1aSopenharmony_ci for (xi = 0; xi < cblknw; xi++){ 921cabdff1aSopenharmony_ci Jpeg2000Cblk *cblk = prec->cblk + yi * cblknw + xi; 922cabdff1aSopenharmony_ci if (cblk->layers[layno].npasses) { 923cabdff1aSopenharmony_ci if (s->buf_end - s->buf < cblk->layers[layno].data_len + 2) 924cabdff1aSopenharmony_ci return -1; 925cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, cblk->layers[layno].data_start + 1, cblk->layers[layno].data_len); 926cabdff1aSopenharmony_ci if (layno == nlayers - 1 && cblk->layers[layno].cum_passes) { 927cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, cblk->passes[cblk->layers[layno].cum_passes-1].flushed, 928cabdff1aSopenharmony_ci cblk->passes[cblk->layers[layno].cum_passes-1].flushed_len); 929cabdff1aSopenharmony_ci } 930cabdff1aSopenharmony_ci } 931cabdff1aSopenharmony_ci } 932cabdff1aSopenharmony_ci } 933cabdff1aSopenharmony_ci } 934cabdff1aSopenharmony_ci return 0; 935cabdff1aSopenharmony_ci} 936cabdff1aSopenharmony_ci 937cabdff1aSopenharmony_cistatic int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno, int nlayers) 938cabdff1aSopenharmony_ci{ 939cabdff1aSopenharmony_ci int compno, reslevelno, layno, ret; 940cabdff1aSopenharmony_ci Jpeg2000CodingStyle *codsty = &s->codsty; 941cabdff1aSopenharmony_ci Jpeg2000QuantStyle *qntsty = &s->qntsty; 942cabdff1aSopenharmony_ci int packetno = 0; 943cabdff1aSopenharmony_ci int step_x, step_y; 944cabdff1aSopenharmony_ci int x, y; 945cabdff1aSopenharmony_ci int tile_coord[2][2]; 946cabdff1aSopenharmony_ci int col = tileno % s->numXtiles; 947cabdff1aSopenharmony_ci int row = tileno / s->numXtiles; 948cabdff1aSopenharmony_ci 949cabdff1aSopenharmony_ci tile_coord[0][0] = col * s->tile_width; 950cabdff1aSopenharmony_ci tile_coord[0][1] = FFMIN(tile_coord[0][0] + s->tile_width, s->width); 951cabdff1aSopenharmony_ci tile_coord[1][0] = row * s->tile_height; 952cabdff1aSopenharmony_ci tile_coord[1][1] = FFMIN(tile_coord[1][0] + s->tile_height, s->height); 953cabdff1aSopenharmony_ci 954cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG, "tier2\n"); 955cabdff1aSopenharmony_ci // lay-rlevel-comp-pos progression 956cabdff1aSopenharmony_ci switch (s->prog) { 957cabdff1aSopenharmony_ci case JPEG2000_PGOD_LRCP: 958cabdff1aSopenharmony_ci for (layno = 0; layno < nlayers; layno++) { 959cabdff1aSopenharmony_ci for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ 960cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++){ 961cabdff1aSopenharmony_ci int precno; 962cabdff1aSopenharmony_ci Jpeg2000ResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno; 963cabdff1aSopenharmony_ci for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ 964cabdff1aSopenharmony_ci if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), 965cabdff1aSopenharmony_ci qntsty->nguardbits, packetno++, nlayers)) < 0) 966cabdff1aSopenharmony_ci return ret; 967cabdff1aSopenharmony_ci } 968cabdff1aSopenharmony_ci } 969cabdff1aSopenharmony_ci } 970cabdff1aSopenharmony_ci } 971cabdff1aSopenharmony_ci break; 972cabdff1aSopenharmony_ci case JPEG2000_PGOD_RLCP: 973cabdff1aSopenharmony_ci for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ 974cabdff1aSopenharmony_ci for (layno = 0; layno < nlayers; layno++) { 975cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++){ 976cabdff1aSopenharmony_ci int precno; 977cabdff1aSopenharmony_ci Jpeg2000ResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno; 978cabdff1aSopenharmony_ci for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ 979cabdff1aSopenharmony_ci if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), 980cabdff1aSopenharmony_ci qntsty->nguardbits, packetno++, nlayers)) < 0) 981cabdff1aSopenharmony_ci return ret; 982cabdff1aSopenharmony_ci } 983cabdff1aSopenharmony_ci } 984cabdff1aSopenharmony_ci } 985cabdff1aSopenharmony_ci } 986cabdff1aSopenharmony_ci break; 987cabdff1aSopenharmony_ci case JPEG2000_PGOD_RPCL: 988cabdff1aSopenharmony_ci for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { 989cabdff1aSopenharmony_ci int precno; 990cabdff1aSopenharmony_ci step_x = 30; 991cabdff1aSopenharmony_ci step_y = 30; 992cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++) { 993cabdff1aSopenharmony_ci Jpeg2000Component *comp = tile->comp + compno; 994cabdff1aSopenharmony_ci if (reslevelno < codsty->nreslevels) { 995cabdff1aSopenharmony_ci uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r 996cabdff1aSopenharmony_ci Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; 997cabdff1aSopenharmony_ci step_x = FFMIN(step_x, rlevel->log2_prec_width + reducedresno); 998cabdff1aSopenharmony_ci step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno); 999cabdff1aSopenharmony_ci } 1000cabdff1aSopenharmony_ci } 1001cabdff1aSopenharmony_ci 1002cabdff1aSopenharmony_ci step_x = 1<<step_x; 1003cabdff1aSopenharmony_ci step_y = 1<<step_y; 1004cabdff1aSopenharmony_ci for (y = tile_coord[1][0]; y < tile_coord[1][1]; y = (y/step_y + 1)*step_y) { 1005cabdff1aSopenharmony_ci for (x = tile_coord[0][0]; x < tile_coord[0][1]; x = (x/step_x + 1)*step_x) { 1006cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++) { 1007cabdff1aSopenharmony_ci Jpeg2000Component *comp = tile->comp + compno; 1008cabdff1aSopenharmony_ci uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r 1009cabdff1aSopenharmony_ci Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; 1010cabdff1aSopenharmony_ci int log_subsampling[2] = { compno?s->chroma_shift[0]:0, compno?s->chroma_shift[1]:0}; 1011cabdff1aSopenharmony_ci unsigned prcx, prcy; 1012cabdff1aSopenharmony_ci int trx0, try0; 1013cabdff1aSopenharmony_ci 1014cabdff1aSopenharmony_ci trx0 = ff_jpeg2000_ceildivpow2(tile_coord[0][0], log_subsampling[0] + reducedresno); 1015cabdff1aSopenharmony_ci try0 = ff_jpeg2000_ceildivpow2(tile_coord[1][0], log_subsampling[1] + reducedresno); 1016cabdff1aSopenharmony_ci 1017cabdff1aSopenharmony_ci if (!(y % ((uint64_t)1 << (reslevel->log2_prec_height + reducedresno + log_subsampling[1])) == 0 || 1018cabdff1aSopenharmony_ci (y == tile_coord[1][0] && (try0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_height))))) 1019cabdff1aSopenharmony_ci continue; 1020cabdff1aSopenharmony_ci 1021cabdff1aSopenharmony_ci if (!(x % ((uint64_t)1 << (reslevel->log2_prec_width + reducedresno + log_subsampling[0])) == 0 || 1022cabdff1aSopenharmony_ci (x == tile_coord[0][0] && (trx0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_width))))) 1023cabdff1aSopenharmony_ci continue; 1024cabdff1aSopenharmony_ci 1025cabdff1aSopenharmony_ci // check if a precinct exists 1026cabdff1aSopenharmony_ci prcx = ff_jpeg2000_ceildivpow2(x, log_subsampling[0] + reducedresno) >> reslevel->log2_prec_width; 1027cabdff1aSopenharmony_ci prcy = ff_jpeg2000_ceildivpow2(y, log_subsampling[1] + reducedresno) >> reslevel->log2_prec_height; 1028cabdff1aSopenharmony_ci prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> reslevel->log2_prec_width; 1029cabdff1aSopenharmony_ci prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> reslevel->log2_prec_height; 1030cabdff1aSopenharmony_ci precno = prcx + reslevel->num_precincts_x * prcy; 1031cabdff1aSopenharmony_ci 1032cabdff1aSopenharmony_ci if (prcx >= reslevel->num_precincts_x || prcy >= reslevel->num_precincts_y) { 1033cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n", 1034cabdff1aSopenharmony_ci prcx, prcy, reslevel->num_precincts_x, reslevel->num_precincts_y); 1035cabdff1aSopenharmony_ci continue; 1036cabdff1aSopenharmony_ci } 1037cabdff1aSopenharmony_ci for (layno = 0; layno < nlayers; layno++) { 1038cabdff1aSopenharmony_ci if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), 1039cabdff1aSopenharmony_ci qntsty->nguardbits, packetno++, nlayers)) < 0) 1040cabdff1aSopenharmony_ci return ret; 1041cabdff1aSopenharmony_ci } 1042cabdff1aSopenharmony_ci } 1043cabdff1aSopenharmony_ci } 1044cabdff1aSopenharmony_ci } 1045cabdff1aSopenharmony_ci } 1046cabdff1aSopenharmony_ci break; 1047cabdff1aSopenharmony_ci case JPEG2000_PGOD_PCRL: 1048cabdff1aSopenharmony_ci step_x = 32; 1049cabdff1aSopenharmony_ci step_y = 32; 1050cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++) { 1051cabdff1aSopenharmony_ci Jpeg2000Component *comp = tile->comp + compno; 1052cabdff1aSopenharmony_ci 1053cabdff1aSopenharmony_ci for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { 1054cabdff1aSopenharmony_ci uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r 1055cabdff1aSopenharmony_ci Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; 1056cabdff1aSopenharmony_ci step_x = FFMIN(step_x, rlevel->log2_prec_width + reducedresno); 1057cabdff1aSopenharmony_ci step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno); 1058cabdff1aSopenharmony_ci } 1059cabdff1aSopenharmony_ci } 1060cabdff1aSopenharmony_ci if (step_x >= 31 || step_y >= 31){ 1061cabdff1aSopenharmony_ci avpriv_request_sample(s->avctx, "PCRL with large step"); 1062cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 1063cabdff1aSopenharmony_ci } 1064cabdff1aSopenharmony_ci step_x = 1<<step_x; 1065cabdff1aSopenharmony_ci step_y = 1<<step_y; 1066cabdff1aSopenharmony_ci 1067cabdff1aSopenharmony_ci for (y = tile_coord[1][0]; y < tile_coord[1][1]; y = (y/step_y + 1)*step_y) { 1068cabdff1aSopenharmony_ci for (x = tile_coord[0][0]; x < tile_coord[0][1]; x = (x/step_x + 1)*step_x) { 1069cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++) { 1070cabdff1aSopenharmony_ci Jpeg2000Component *comp = tile->comp + compno; 1071cabdff1aSopenharmony_ci int log_subsampling[2] = { compno?s->chroma_shift[0]:0, compno?s->chroma_shift[1]:0}; 1072cabdff1aSopenharmony_ci 1073cabdff1aSopenharmony_ci for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { 1074cabdff1aSopenharmony_ci unsigned prcx, prcy; 1075cabdff1aSopenharmony_ci int precno; 1076cabdff1aSopenharmony_ci uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r 1077cabdff1aSopenharmony_ci Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; 1078cabdff1aSopenharmony_ci int trx0, try0; 1079cabdff1aSopenharmony_ci 1080cabdff1aSopenharmony_ci trx0 = ff_jpeg2000_ceildivpow2(tile_coord[0][0], log_subsampling[0] + reducedresno); 1081cabdff1aSopenharmony_ci try0 = ff_jpeg2000_ceildivpow2(tile_coord[1][0], log_subsampling[1] + reducedresno); 1082cabdff1aSopenharmony_ci 1083cabdff1aSopenharmony_ci if (!(y % ((uint64_t)1 << (reslevel->log2_prec_height + reducedresno + log_subsampling[1])) == 0 || 1084cabdff1aSopenharmony_ci (y == tile_coord[1][0] && (try0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_height))))) 1085cabdff1aSopenharmony_ci continue; 1086cabdff1aSopenharmony_ci 1087cabdff1aSopenharmony_ci if (!(x % ((uint64_t)1 << (reslevel->log2_prec_width + reducedresno + log_subsampling[0])) == 0 || 1088cabdff1aSopenharmony_ci (x == tile_coord[0][0] && (trx0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_width))))) 1089cabdff1aSopenharmony_ci continue; 1090cabdff1aSopenharmony_ci 1091cabdff1aSopenharmony_ci // check if a precinct exists 1092cabdff1aSopenharmony_ci prcx = ff_jpeg2000_ceildivpow2(x, log_subsampling[0] + reducedresno) >> reslevel->log2_prec_width; 1093cabdff1aSopenharmony_ci prcy = ff_jpeg2000_ceildivpow2(y, log_subsampling[1] + reducedresno) >> reslevel->log2_prec_height; 1094cabdff1aSopenharmony_ci prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> reslevel->log2_prec_width; 1095cabdff1aSopenharmony_ci prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> reslevel->log2_prec_height; 1096cabdff1aSopenharmony_ci 1097cabdff1aSopenharmony_ci precno = prcx + reslevel->num_precincts_x * prcy; 1098cabdff1aSopenharmony_ci 1099cabdff1aSopenharmony_ci if (prcx >= reslevel->num_precincts_x || prcy >= reslevel->num_precincts_y) { 1100cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n", 1101cabdff1aSopenharmony_ci prcx, prcy, reslevel->num_precincts_x, reslevel->num_precincts_y); 1102cabdff1aSopenharmony_ci continue; 1103cabdff1aSopenharmony_ci } 1104cabdff1aSopenharmony_ci for (layno = 0; layno < nlayers; layno++) { 1105cabdff1aSopenharmony_ci if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), 1106cabdff1aSopenharmony_ci qntsty->nguardbits, packetno++, nlayers)) < 0) 1107cabdff1aSopenharmony_ci return ret; 1108cabdff1aSopenharmony_ci } 1109cabdff1aSopenharmony_ci } 1110cabdff1aSopenharmony_ci } 1111cabdff1aSopenharmony_ci } 1112cabdff1aSopenharmony_ci } 1113cabdff1aSopenharmony_ci break; 1114cabdff1aSopenharmony_ci case JPEG2000_PGOD_CPRL: 1115cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++) { 1116cabdff1aSopenharmony_ci Jpeg2000Component *comp = tile->comp + compno; 1117cabdff1aSopenharmony_ci int log_subsampling[2] = { compno?s->chroma_shift[0]:0, compno?s->chroma_shift[1]:0}; 1118cabdff1aSopenharmony_ci step_x = 32; 1119cabdff1aSopenharmony_ci step_y = 32; 1120cabdff1aSopenharmony_ci 1121cabdff1aSopenharmony_ci for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { 1122cabdff1aSopenharmony_ci uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r 1123cabdff1aSopenharmony_ci Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; 1124cabdff1aSopenharmony_ci step_x = FFMIN(step_x, rlevel->log2_prec_width + reducedresno); 1125cabdff1aSopenharmony_ci step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno); 1126cabdff1aSopenharmony_ci } 1127cabdff1aSopenharmony_ci if (step_x >= 31 || step_y >= 31){ 1128cabdff1aSopenharmony_ci avpriv_request_sample(s->avctx, "CPRL with large step"); 1129cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 1130cabdff1aSopenharmony_ci } 1131cabdff1aSopenharmony_ci step_x = 1<<step_x; 1132cabdff1aSopenharmony_ci step_y = 1<<step_y; 1133cabdff1aSopenharmony_ci 1134cabdff1aSopenharmony_ci for (y = tile_coord[1][0]; y < tile_coord[1][1]; y = (y/step_y + 1)*step_y) { 1135cabdff1aSopenharmony_ci for (x = tile_coord[0][0]; x < tile_coord[0][1]; x = (x/step_x + 1)*step_x) { 1136cabdff1aSopenharmony_ci for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { 1137cabdff1aSopenharmony_ci unsigned prcx, prcy; 1138cabdff1aSopenharmony_ci int precno; 1139cabdff1aSopenharmony_ci int trx0, try0; 1140cabdff1aSopenharmony_ci uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r 1141cabdff1aSopenharmony_ci Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; 1142cabdff1aSopenharmony_ci 1143cabdff1aSopenharmony_ci trx0 = ff_jpeg2000_ceildivpow2(tile_coord[0][0], log_subsampling[0] + reducedresno); 1144cabdff1aSopenharmony_ci try0 = ff_jpeg2000_ceildivpow2(tile_coord[1][0], log_subsampling[1] + reducedresno); 1145cabdff1aSopenharmony_ci 1146cabdff1aSopenharmony_ci if (!(y % ((uint64_t)1 << (reslevel->log2_prec_height + reducedresno + log_subsampling[1])) == 0 || 1147cabdff1aSopenharmony_ci (y == tile_coord[1][0] && (try0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_height))))) 1148cabdff1aSopenharmony_ci continue; 1149cabdff1aSopenharmony_ci 1150cabdff1aSopenharmony_ci if (!(x % ((uint64_t)1 << (reslevel->log2_prec_width + reducedresno + log_subsampling[0])) == 0 || 1151cabdff1aSopenharmony_ci (x == tile_coord[0][0] && (trx0 << reducedresno) % (1U << (reducedresno + reslevel->log2_prec_width))))) 1152cabdff1aSopenharmony_ci continue; 1153cabdff1aSopenharmony_ci 1154cabdff1aSopenharmony_ci // check if a precinct exists 1155cabdff1aSopenharmony_ci prcx = ff_jpeg2000_ceildivpow2(x, log_subsampling[0] + reducedresno) >> reslevel->log2_prec_width; 1156cabdff1aSopenharmony_ci prcy = ff_jpeg2000_ceildivpow2(y, log_subsampling[1] + reducedresno) >> reslevel->log2_prec_height; 1157cabdff1aSopenharmony_ci prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> reslevel->log2_prec_width; 1158cabdff1aSopenharmony_ci prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> reslevel->log2_prec_height; 1159cabdff1aSopenharmony_ci 1160cabdff1aSopenharmony_ci precno = prcx + reslevel->num_precincts_x * prcy; 1161cabdff1aSopenharmony_ci 1162cabdff1aSopenharmony_ci if (prcx >= reslevel->num_precincts_x || prcy >= reslevel->num_precincts_y) { 1163cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n", 1164cabdff1aSopenharmony_ci prcx, prcy, reslevel->num_precincts_x, reslevel->num_precincts_y); 1165cabdff1aSopenharmony_ci continue; 1166cabdff1aSopenharmony_ci } 1167cabdff1aSopenharmony_ci for (layno = 0; layno < nlayers; layno++) { 1168cabdff1aSopenharmony_ci if ((ret = encode_packet(s, reslevel, layno, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), 1169cabdff1aSopenharmony_ci qntsty->nguardbits, packetno++, nlayers)) < 0) 1170cabdff1aSopenharmony_ci return ret; 1171cabdff1aSopenharmony_ci } 1172cabdff1aSopenharmony_ci } 1173cabdff1aSopenharmony_ci } 1174cabdff1aSopenharmony_ci } 1175cabdff1aSopenharmony_ci } 1176cabdff1aSopenharmony_ci 1177cabdff1aSopenharmony_ci } 1178cabdff1aSopenharmony_ci 1179cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG, "after tier2\n"); 1180cabdff1aSopenharmony_ci return 0; 1181cabdff1aSopenharmony_ci} 1182cabdff1aSopenharmony_ci 1183cabdff1aSopenharmony_cistatic void makelayer(Jpeg2000EncoderContext *s, int layno, double thresh, Jpeg2000Tile* tile, int final) 1184cabdff1aSopenharmony_ci{ 1185cabdff1aSopenharmony_ci int compno, resno, bandno, precno, cblkno; 1186cabdff1aSopenharmony_ci int passno; 1187cabdff1aSopenharmony_ci 1188cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++) { 1189cabdff1aSopenharmony_ci Jpeg2000Component *comp = &tile->comp[compno]; 1190cabdff1aSopenharmony_ci 1191cabdff1aSopenharmony_ci for (resno = 0; resno < s->codsty.nreslevels; resno++) { 1192cabdff1aSopenharmony_ci Jpeg2000ResLevel *reslevel = comp->reslevel + resno; 1193cabdff1aSopenharmony_ci 1194cabdff1aSopenharmony_ci for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ 1195cabdff1aSopenharmony_ci for (bandno = 0; bandno < reslevel->nbands ; bandno++){ 1196cabdff1aSopenharmony_ci Jpeg2000Band *band = reslevel->band + bandno; 1197cabdff1aSopenharmony_ci Jpeg2000Prec *prec = band->prec + precno; 1198cabdff1aSopenharmony_ci 1199cabdff1aSopenharmony_ci for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ 1200cabdff1aSopenharmony_ci Jpeg2000Cblk *cblk = prec->cblk + cblkno; 1201cabdff1aSopenharmony_ci Jpeg2000Layer *layer = &cblk->layers[layno]; 1202cabdff1aSopenharmony_ci int n; 1203cabdff1aSopenharmony_ci 1204cabdff1aSopenharmony_ci if (layno == 0) { 1205cabdff1aSopenharmony_ci cblk->ninclpasses = 0; 1206cabdff1aSopenharmony_ci } 1207cabdff1aSopenharmony_ci 1208cabdff1aSopenharmony_ci n = cblk->ninclpasses; 1209cabdff1aSopenharmony_ci 1210cabdff1aSopenharmony_ci if (thresh < 0) { 1211cabdff1aSopenharmony_ci n = cblk->npasses; 1212cabdff1aSopenharmony_ci } else { 1213cabdff1aSopenharmony_ci for (passno = cblk->ninclpasses; passno < cblk->npasses; passno++) { 1214cabdff1aSopenharmony_ci int32_t dr; 1215cabdff1aSopenharmony_ci double dd; 1216cabdff1aSopenharmony_ci Jpeg2000Pass *pass = &cblk->passes[passno]; 1217cabdff1aSopenharmony_ci 1218cabdff1aSopenharmony_ci if (n == 0) { 1219cabdff1aSopenharmony_ci dr = pass->rate; 1220cabdff1aSopenharmony_ci dd = pass->disto; 1221cabdff1aSopenharmony_ci } else { 1222cabdff1aSopenharmony_ci dr = pass->rate - cblk->passes[n - 1].rate; 1223cabdff1aSopenharmony_ci dd = pass->disto - cblk->passes[n-1].disto; 1224cabdff1aSopenharmony_ci } 1225cabdff1aSopenharmony_ci 1226cabdff1aSopenharmony_ci if (!dr) { 1227cabdff1aSopenharmony_ci if (dd != 0.0) { 1228cabdff1aSopenharmony_ci n = passno + 1; 1229cabdff1aSopenharmony_ci } 1230cabdff1aSopenharmony_ci continue; 1231cabdff1aSopenharmony_ci } 1232cabdff1aSopenharmony_ci 1233cabdff1aSopenharmony_ci if (thresh - (dd / dr) < DBL_EPSILON) 1234cabdff1aSopenharmony_ci n = passno + 1; 1235cabdff1aSopenharmony_ci } 1236cabdff1aSopenharmony_ci } 1237cabdff1aSopenharmony_ci layer->npasses = n - cblk->ninclpasses; 1238cabdff1aSopenharmony_ci layer->cum_passes = n; 1239cabdff1aSopenharmony_ci 1240cabdff1aSopenharmony_ci if (layer->npasses == 0) { 1241cabdff1aSopenharmony_ci layer->disto = 0; 1242cabdff1aSopenharmony_ci layer->data_len = 0; 1243cabdff1aSopenharmony_ci continue; 1244cabdff1aSopenharmony_ci } 1245cabdff1aSopenharmony_ci 1246cabdff1aSopenharmony_ci if (cblk->ninclpasses == 0) { 1247cabdff1aSopenharmony_ci layer->data_len = cblk->passes[n - 1].rate; 1248cabdff1aSopenharmony_ci layer->data_start = cblk->data; 1249cabdff1aSopenharmony_ci layer->disto = cblk->passes[n - 1].disto; 1250cabdff1aSopenharmony_ci } else { 1251cabdff1aSopenharmony_ci layer->data_len = cblk->passes[n - 1].rate - cblk->passes[cblk->ninclpasses - 1].rate; 1252cabdff1aSopenharmony_ci layer->data_start = cblk->data + cblk->passes[cblk->ninclpasses - 1].rate; 1253cabdff1aSopenharmony_ci layer->disto = cblk->passes[n - 1].disto - 1254cabdff1aSopenharmony_ci cblk->passes[cblk->ninclpasses - 1].disto; 1255cabdff1aSopenharmony_ci } 1256cabdff1aSopenharmony_ci if (final) { 1257cabdff1aSopenharmony_ci cblk->ninclpasses = n; 1258cabdff1aSopenharmony_ci } 1259cabdff1aSopenharmony_ci } 1260cabdff1aSopenharmony_ci } 1261cabdff1aSopenharmony_ci } 1262cabdff1aSopenharmony_ci } 1263cabdff1aSopenharmony_ci } 1264cabdff1aSopenharmony_ci} 1265cabdff1aSopenharmony_ci 1266cabdff1aSopenharmony_cistatic void makelayers(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) 1267cabdff1aSopenharmony_ci{ 1268cabdff1aSopenharmony_ci int precno, compno, reslevelno, bandno, cblkno, lev, passno, layno; 1269cabdff1aSopenharmony_ci int i; 1270cabdff1aSopenharmony_ci double min = DBL_MAX; 1271cabdff1aSopenharmony_ci double max = 0; 1272cabdff1aSopenharmony_ci double thresh; 1273cabdff1aSopenharmony_ci 1274cabdff1aSopenharmony_ci Jpeg2000CodingStyle *codsty = &s->codsty; 1275cabdff1aSopenharmony_ci 1276cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++){ 1277cabdff1aSopenharmony_ci Jpeg2000Component *comp = tile->comp + compno; 1278cabdff1aSopenharmony_ci 1279cabdff1aSopenharmony_ci for (reslevelno = 0, lev = codsty->nreslevels-1; reslevelno < codsty->nreslevels; reslevelno++, lev--){ 1280cabdff1aSopenharmony_ci Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; 1281cabdff1aSopenharmony_ci 1282cabdff1aSopenharmony_ci for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ 1283cabdff1aSopenharmony_ci for (bandno = 0; bandno < reslevel->nbands ; bandno++){ 1284cabdff1aSopenharmony_ci Jpeg2000Band *band = reslevel->band + bandno; 1285cabdff1aSopenharmony_ci Jpeg2000Prec *prec = band->prec + precno; 1286cabdff1aSopenharmony_ci 1287cabdff1aSopenharmony_ci for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ 1288cabdff1aSopenharmony_ci Jpeg2000Cblk *cblk = prec->cblk + cblkno; 1289cabdff1aSopenharmony_ci for (passno = 0; passno < cblk->npasses; passno++) { 1290cabdff1aSopenharmony_ci Jpeg2000Pass *pass = &cblk->passes[passno]; 1291cabdff1aSopenharmony_ci int dr; 1292cabdff1aSopenharmony_ci double dd, drslope; 1293cabdff1aSopenharmony_ci 1294cabdff1aSopenharmony_ci if (passno == 0) { 1295cabdff1aSopenharmony_ci dr = (int32_t)pass->rate; 1296cabdff1aSopenharmony_ci dd = pass->disto; 1297cabdff1aSopenharmony_ci } else { 1298cabdff1aSopenharmony_ci dr = (int32_t)(pass->rate - cblk->passes[passno - 1].rate); 1299cabdff1aSopenharmony_ci dd = pass->disto - cblk->passes[passno - 1].disto; 1300cabdff1aSopenharmony_ci } 1301cabdff1aSopenharmony_ci 1302cabdff1aSopenharmony_ci if (dr <= 0) 1303cabdff1aSopenharmony_ci continue; 1304cabdff1aSopenharmony_ci 1305cabdff1aSopenharmony_ci drslope = dd / dr; 1306cabdff1aSopenharmony_ci if (drslope < min) 1307cabdff1aSopenharmony_ci min = drslope; 1308cabdff1aSopenharmony_ci 1309cabdff1aSopenharmony_ci if (drslope > max) 1310cabdff1aSopenharmony_ci max = drslope; 1311cabdff1aSopenharmony_ci } 1312cabdff1aSopenharmony_ci } 1313cabdff1aSopenharmony_ci } 1314cabdff1aSopenharmony_ci } 1315cabdff1aSopenharmony_ci } 1316cabdff1aSopenharmony_ci } 1317cabdff1aSopenharmony_ci 1318cabdff1aSopenharmony_ci for (layno = 0; layno < s->nlayers; layno++) { 1319cabdff1aSopenharmony_ci double lo = min; 1320cabdff1aSopenharmony_ci double hi = max; 1321cabdff1aSopenharmony_ci double stable_thresh = 0.0; 1322cabdff1aSopenharmony_ci double good_thresh = 0.0; 1323cabdff1aSopenharmony_ci if (!s->layer_rates[layno]) { 1324cabdff1aSopenharmony_ci good_thresh = -1.0; 1325cabdff1aSopenharmony_ci } else { 1326cabdff1aSopenharmony_ci for (i = 0; i < 128; i++) { 1327cabdff1aSopenharmony_ci uint8_t *stream_pos = s->buf; 1328cabdff1aSopenharmony_ci int ret; 1329cabdff1aSopenharmony_ci thresh = (lo + hi) / 2; 1330cabdff1aSopenharmony_ci makelayer(s, layno, thresh, tile, 0); 1331cabdff1aSopenharmony_ci ret = encode_packets(s, tile, (int)(tile - s->tile), layno + 1); 1332cabdff1aSopenharmony_ci memset(stream_pos, 0, s->buf - stream_pos); 1333cabdff1aSopenharmony_ci if ((s->buf - stream_pos > ceil(tile->layer_rates[layno])) || ret < 0) { 1334cabdff1aSopenharmony_ci lo = thresh; 1335cabdff1aSopenharmony_ci s->buf = stream_pos; 1336cabdff1aSopenharmony_ci continue; 1337cabdff1aSopenharmony_ci } 1338cabdff1aSopenharmony_ci hi = thresh; 1339cabdff1aSopenharmony_ci stable_thresh = thresh; 1340cabdff1aSopenharmony_ci s->buf = stream_pos; 1341cabdff1aSopenharmony_ci } 1342cabdff1aSopenharmony_ci } 1343cabdff1aSopenharmony_ci if (good_thresh >= 0.0) 1344cabdff1aSopenharmony_ci good_thresh = stable_thresh == 0.0 ? thresh : stable_thresh; 1345cabdff1aSopenharmony_ci makelayer(s, layno, good_thresh, tile, 1); 1346cabdff1aSopenharmony_ci } 1347cabdff1aSopenharmony_ci} 1348cabdff1aSopenharmony_ci 1349cabdff1aSopenharmony_cistatic int getcut(Jpeg2000Cblk *cblk, int64_t lambda, int dwt_norm) 1350cabdff1aSopenharmony_ci{ 1351cabdff1aSopenharmony_ci int passno, res = 0; 1352cabdff1aSopenharmony_ci for (passno = 0; passno < cblk->npasses; passno++){ 1353cabdff1aSopenharmony_ci int dr; 1354cabdff1aSopenharmony_ci int64_t dd; 1355cabdff1aSopenharmony_ci 1356cabdff1aSopenharmony_ci dr = cblk->passes[passno].rate 1357cabdff1aSopenharmony_ci - (res ? cblk->passes[res-1].rate : 0); 1358cabdff1aSopenharmony_ci dd = cblk->passes[passno].disto 1359cabdff1aSopenharmony_ci - (res ? cblk->passes[res-1].disto : 0); 1360cabdff1aSopenharmony_ci 1361cabdff1aSopenharmony_ci if (((dd * dwt_norm) >> WMSEDEC_SHIFT) * dwt_norm >= dr * lambda) 1362cabdff1aSopenharmony_ci res = passno+1; 1363cabdff1aSopenharmony_ci } 1364cabdff1aSopenharmony_ci return res; 1365cabdff1aSopenharmony_ci} 1366cabdff1aSopenharmony_ci 1367cabdff1aSopenharmony_cistatic void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) 1368cabdff1aSopenharmony_ci{ 1369cabdff1aSopenharmony_ci int precno, compno, reslevelno, bandno, cblkno, lev; 1370cabdff1aSopenharmony_ci Jpeg2000CodingStyle *codsty = &s->codsty; 1371cabdff1aSopenharmony_ci 1372cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++){ 1373cabdff1aSopenharmony_ci Jpeg2000Component *comp = tile->comp + compno; 1374cabdff1aSopenharmony_ci 1375cabdff1aSopenharmony_ci for (reslevelno = 0, lev = codsty->nreslevels-1; reslevelno < codsty->nreslevels; reslevelno++, lev--){ 1376cabdff1aSopenharmony_ci Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; 1377cabdff1aSopenharmony_ci 1378cabdff1aSopenharmony_ci for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ 1379cabdff1aSopenharmony_ci for (bandno = 0; bandno < reslevel->nbands ; bandno++){ 1380cabdff1aSopenharmony_ci int bandpos = bandno + (reslevelno > 0); 1381cabdff1aSopenharmony_ci Jpeg2000Band *band = reslevel->band + bandno; 1382cabdff1aSopenharmony_ci Jpeg2000Prec *prec = band->prec + precno; 1383cabdff1aSopenharmony_ci 1384cabdff1aSopenharmony_ci for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ 1385cabdff1aSopenharmony_ci Jpeg2000Cblk *cblk = prec->cblk + cblkno; 1386cabdff1aSopenharmony_ci 1387cabdff1aSopenharmony_ci cblk->ninclpasses = getcut(cblk, s->lambda, 1388cabdff1aSopenharmony_ci (int64_t)dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 15); 1389cabdff1aSopenharmony_ci cblk->layers[0].data_start = cblk->data; 1390cabdff1aSopenharmony_ci cblk->layers[0].cum_passes = cblk->ninclpasses; 1391cabdff1aSopenharmony_ci cblk->layers[0].npasses = cblk->ninclpasses; 1392cabdff1aSopenharmony_ci if (cblk->ninclpasses) 1393cabdff1aSopenharmony_ci cblk->layers[0].data_len = cblk->passes[cblk->ninclpasses - 1].rate; 1394cabdff1aSopenharmony_ci } 1395cabdff1aSopenharmony_ci } 1396cabdff1aSopenharmony_ci } 1397cabdff1aSopenharmony_ci } 1398cabdff1aSopenharmony_ci } 1399cabdff1aSopenharmony_ci} 1400cabdff1aSopenharmony_ci 1401cabdff1aSopenharmony_cistatic int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno) 1402cabdff1aSopenharmony_ci{ 1403cabdff1aSopenharmony_ci int compno, reslevelno, bandno, ret; 1404cabdff1aSopenharmony_ci Jpeg2000T1Context t1; 1405cabdff1aSopenharmony_ci Jpeg2000CodingStyle *codsty = &s->codsty; 1406cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++){ 1407cabdff1aSopenharmony_ci Jpeg2000Component *comp = s->tile[tileno].comp + compno; 1408cabdff1aSopenharmony_ci 1409cabdff1aSopenharmony_ci t1.stride = (1<<codsty->log2_cblk_width) + 2; 1410cabdff1aSopenharmony_ci 1411cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG,"dwt\n"); 1412cabdff1aSopenharmony_ci if ((ret = ff_dwt_encode(&comp->dwt, comp->i_data)) < 0) 1413cabdff1aSopenharmony_ci return ret; 1414cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG,"after dwt -> tier1\n"); 1415cabdff1aSopenharmony_ci 1416cabdff1aSopenharmony_ci for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ 1417cabdff1aSopenharmony_ci Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno; 1418cabdff1aSopenharmony_ci 1419cabdff1aSopenharmony_ci for (bandno = 0; bandno < reslevel->nbands ; bandno++){ 1420cabdff1aSopenharmony_ci Jpeg2000Band *band = reslevel->band + bandno; 1421cabdff1aSopenharmony_ci Jpeg2000Prec *prec = band->prec; // we support only 1 precinct per band ATM in the encoder 1422cabdff1aSopenharmony_ci int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos; 1423cabdff1aSopenharmony_ci yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0]; 1424cabdff1aSopenharmony_ci y0 = yy0; 1425cabdff1aSopenharmony_ci yy1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[1][0] + 1, band->log2_cblk_height) << band->log2_cblk_height, 1426cabdff1aSopenharmony_ci band->coord[1][1]) - band->coord[1][0] + yy0; 1427cabdff1aSopenharmony_ci 1428cabdff1aSopenharmony_ci if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1]) 1429cabdff1aSopenharmony_ci continue; 1430cabdff1aSopenharmony_ci 1431cabdff1aSopenharmony_ci bandpos = bandno + (reslevelno > 0); 1432cabdff1aSopenharmony_ci 1433cabdff1aSopenharmony_ci for (cblky = 0; cblky < prec->nb_codeblocks_height; cblky++){ 1434cabdff1aSopenharmony_ci if (reslevelno == 0 || bandno == 1) 1435cabdff1aSopenharmony_ci xx0 = 0; 1436cabdff1aSopenharmony_ci else 1437cabdff1aSopenharmony_ci xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0]; 1438cabdff1aSopenharmony_ci x0 = xx0; 1439cabdff1aSopenharmony_ci xx1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[0][0] + 1, band->log2_cblk_width) << band->log2_cblk_width, 1440cabdff1aSopenharmony_ci band->coord[0][1]) - band->coord[0][0] + xx0; 1441cabdff1aSopenharmony_ci 1442cabdff1aSopenharmony_ci for (cblkx = 0; cblkx < prec->nb_codeblocks_width; cblkx++, cblkno++){ 1443cabdff1aSopenharmony_ci int y, x; 1444cabdff1aSopenharmony_ci if (codsty->transform == FF_DWT53){ 1445cabdff1aSopenharmony_ci for (y = yy0; y < yy1; y++){ 1446cabdff1aSopenharmony_ci int *ptr = t1.data + (y-yy0)*t1.stride; 1447cabdff1aSopenharmony_ci for (x = xx0; x < xx1; x++){ 1448cabdff1aSopenharmony_ci *ptr++ = comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] * (1 << NMSEDEC_FRACBITS); 1449cabdff1aSopenharmony_ci } 1450cabdff1aSopenharmony_ci } 1451cabdff1aSopenharmony_ci } else{ 1452cabdff1aSopenharmony_ci for (y = yy0; y < yy1; y++){ 1453cabdff1aSopenharmony_ci int *ptr = t1.data + (y-yy0)*t1.stride; 1454cabdff1aSopenharmony_ci for (x = xx0; x < xx1; x++){ 1455cabdff1aSopenharmony_ci *ptr = (comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]); 1456cabdff1aSopenharmony_ci *ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 15 - NMSEDEC_FRACBITS; 1457cabdff1aSopenharmony_ci ptr++; 1458cabdff1aSopenharmony_ci } 1459cabdff1aSopenharmony_ci } 1460cabdff1aSopenharmony_ci } 1461cabdff1aSopenharmony_ci if (!prec->cblk[cblkno].data) 1462cabdff1aSopenharmony_ci prec->cblk[cblkno].data = av_malloc(1 + 8192); 1463cabdff1aSopenharmony_ci if (!prec->cblk[cblkno].passes) 1464cabdff1aSopenharmony_ci prec->cblk[cblkno].passes = av_malloc_array(JPEG2000_MAX_PASSES, sizeof (*prec->cblk[cblkno].passes)); 1465cabdff1aSopenharmony_ci if (!prec->cblk[cblkno].data || !prec->cblk[cblkno].passes) 1466cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1467cabdff1aSopenharmony_ci encode_cblk(s, &t1, prec->cblk + cblkno, tile, xx1 - xx0, yy1 - yy0, 1468cabdff1aSopenharmony_ci bandpos, codsty->nreslevels - reslevelno - 1); 1469cabdff1aSopenharmony_ci xx0 = xx1; 1470cabdff1aSopenharmony_ci xx1 = FFMIN(xx1 + (1 << band->log2_cblk_width), band->coord[0][1] - band->coord[0][0] + x0); 1471cabdff1aSopenharmony_ci } 1472cabdff1aSopenharmony_ci yy0 = yy1; 1473cabdff1aSopenharmony_ci yy1 = FFMIN(yy1 + (1 << band->log2_cblk_height), band->coord[1][1] - band->coord[1][0] + y0); 1474cabdff1aSopenharmony_ci } 1475cabdff1aSopenharmony_ci } 1476cabdff1aSopenharmony_ci } 1477cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG, "after tier1\n"); 1478cabdff1aSopenharmony_ci } 1479cabdff1aSopenharmony_ci 1480cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG, "rate control\n"); 1481cabdff1aSopenharmony_ci if (s->compression_rate_enc) 1482cabdff1aSopenharmony_ci makelayers(s, tile); 1483cabdff1aSopenharmony_ci else 1484cabdff1aSopenharmony_ci truncpasses(s, tile); 1485cabdff1aSopenharmony_ci 1486cabdff1aSopenharmony_ci if ((ret = encode_packets(s, tile, tileno, s->nlayers)) < 0) 1487cabdff1aSopenharmony_ci return ret; 1488cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG, "after rate control\n"); 1489cabdff1aSopenharmony_ci return 0; 1490cabdff1aSopenharmony_ci} 1491cabdff1aSopenharmony_ci 1492cabdff1aSopenharmony_cistatic void cleanup(Jpeg2000EncoderContext *s) 1493cabdff1aSopenharmony_ci{ 1494cabdff1aSopenharmony_ci int tileno, compno; 1495cabdff1aSopenharmony_ci Jpeg2000CodingStyle *codsty = &s->codsty; 1496cabdff1aSopenharmony_ci 1497cabdff1aSopenharmony_ci if (!s->tile) 1498cabdff1aSopenharmony_ci return; 1499cabdff1aSopenharmony_ci for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ 1500cabdff1aSopenharmony_ci if (s->tile[tileno].comp) { 1501cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++){ 1502cabdff1aSopenharmony_ci Jpeg2000Component *comp = s->tile[tileno].comp + compno; 1503cabdff1aSopenharmony_ci ff_jpeg2000_cleanup(comp, codsty); 1504cabdff1aSopenharmony_ci } 1505cabdff1aSopenharmony_ci av_freep(&s->tile[tileno].comp); 1506cabdff1aSopenharmony_ci } 1507cabdff1aSopenharmony_ci av_freep(&s->tile[tileno].layer_rates); 1508cabdff1aSopenharmony_ci } 1509cabdff1aSopenharmony_ci av_freep(&s->tile); 1510cabdff1aSopenharmony_ci} 1511cabdff1aSopenharmony_ci 1512cabdff1aSopenharmony_cistatic void reinit(Jpeg2000EncoderContext *s) 1513cabdff1aSopenharmony_ci{ 1514cabdff1aSopenharmony_ci int tileno, compno; 1515cabdff1aSopenharmony_ci for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ 1516cabdff1aSopenharmony_ci Jpeg2000Tile *tile = s->tile + tileno; 1517cabdff1aSopenharmony_ci for (compno = 0; compno < s->ncomponents; compno++) 1518cabdff1aSopenharmony_ci ff_jpeg2000_reinit(tile->comp + compno, &s->codsty); 1519cabdff1aSopenharmony_ci } 1520cabdff1aSopenharmony_ci} 1521cabdff1aSopenharmony_ci 1522cabdff1aSopenharmony_cistatic void update_size(uint8_t *size, const uint8_t *end) 1523cabdff1aSopenharmony_ci{ 1524cabdff1aSopenharmony_ci AV_WB32(size, end-size); 1525cabdff1aSopenharmony_ci} 1526cabdff1aSopenharmony_ci 1527cabdff1aSopenharmony_cistatic int encode_frame(AVCodecContext *avctx, AVPacket *pkt, 1528cabdff1aSopenharmony_ci const AVFrame *pict, int *got_packet) 1529cabdff1aSopenharmony_ci{ 1530cabdff1aSopenharmony_ci int tileno, ret; 1531cabdff1aSopenharmony_ci Jpeg2000EncoderContext *s = avctx->priv_data; 1532cabdff1aSopenharmony_ci uint8_t *chunkstart, *jp2cstart, *jp2hstart; 1533cabdff1aSopenharmony_ci const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); 1534cabdff1aSopenharmony_ci 1535cabdff1aSopenharmony_ci if ((ret = ff_alloc_packet(avctx, pkt, avctx->width*avctx->height*9 + AV_INPUT_BUFFER_MIN_SIZE)) < 0) 1536cabdff1aSopenharmony_ci return ret; 1537cabdff1aSopenharmony_ci 1538cabdff1aSopenharmony_ci // init: 1539cabdff1aSopenharmony_ci s->buf = s->buf_start = pkt->data; 1540cabdff1aSopenharmony_ci s->buf_end = pkt->data + pkt->size; 1541cabdff1aSopenharmony_ci 1542cabdff1aSopenharmony_ci s->picture = pict; 1543cabdff1aSopenharmony_ci 1544cabdff1aSopenharmony_ci s->lambda = s->picture->quality * LAMBDA_SCALE; 1545cabdff1aSopenharmony_ci 1546cabdff1aSopenharmony_ci if (s->cbps[0] > 8) 1547cabdff1aSopenharmony_ci copy_frame_16(s); 1548cabdff1aSopenharmony_ci else 1549cabdff1aSopenharmony_ci copy_frame_8(s); 1550cabdff1aSopenharmony_ci 1551cabdff1aSopenharmony_ci reinit(s); 1552cabdff1aSopenharmony_ci 1553cabdff1aSopenharmony_ci if (s->format == CODEC_JP2) { 1554cabdff1aSopenharmony_ci av_assert0(s->buf == pkt->data); 1555cabdff1aSopenharmony_ci 1556cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0x0000000C); 1557cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0x6A502020); 1558cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0x0D0A870A); 1559cabdff1aSopenharmony_ci 1560cabdff1aSopenharmony_ci chunkstart = s->buf; 1561cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); 1562cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, "ftyp", 4); 1563cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, "jp2\040\040", 4); 1564cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); 1565cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, "jp2\040", 4); 1566cabdff1aSopenharmony_ci update_size(chunkstart, s->buf); 1567cabdff1aSopenharmony_ci 1568cabdff1aSopenharmony_ci jp2hstart = s->buf; 1569cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); 1570cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, "jp2h", 4); 1571cabdff1aSopenharmony_ci 1572cabdff1aSopenharmony_ci chunkstart = s->buf; 1573cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); 1574cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, "ihdr", 4); 1575cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, avctx->height); 1576cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, avctx->width); 1577cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, s->ncomponents); 1578cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, s->cbps[0]); 1579cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 7); 1580cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 0); 1581cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 0); 1582cabdff1aSopenharmony_ci update_size(chunkstart, s->buf); 1583cabdff1aSopenharmony_ci 1584cabdff1aSopenharmony_ci chunkstart = s->buf; 1585cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); 1586cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, "colr", 4); 1587cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 1); 1588cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 0); 1589cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 0); 1590cabdff1aSopenharmony_ci if ((desc->flags & AV_PIX_FMT_FLAG_RGB) || avctx->pix_fmt == AV_PIX_FMT_PAL8) { 1591cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 16); 1592cabdff1aSopenharmony_ci } else if (s->ncomponents == 1) { 1593cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 17); 1594cabdff1aSopenharmony_ci } else { 1595cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 18); 1596cabdff1aSopenharmony_ci } 1597cabdff1aSopenharmony_ci update_size(chunkstart, s->buf); 1598cabdff1aSopenharmony_ci if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { 1599cabdff1aSopenharmony_ci int i; 1600cabdff1aSopenharmony_ci uint8_t *palette = pict->data[1]; 1601cabdff1aSopenharmony_ci chunkstart = s->buf; 1602cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); 1603cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, "pclr", 4); 1604cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, AVPALETTE_COUNT); 1605cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 3); // colour channels 1606cabdff1aSopenharmony_ci bytestream_put_be24(&s->buf, 0x070707); //colour depths 1607cabdff1aSopenharmony_ci for (i = 0; i < AVPALETTE_COUNT; i++) { 1608cabdff1aSopenharmony_ci bytestream_put_be24(&s->buf, HAVE_BIGENDIAN ? AV_RB24(palette + 1) : AV_RL24(palette)); 1609cabdff1aSopenharmony_ci palette += 4; 1610cabdff1aSopenharmony_ci } 1611cabdff1aSopenharmony_ci update_size(chunkstart, s->buf); 1612cabdff1aSopenharmony_ci chunkstart = s->buf; 1613cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); 1614cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, "cmap", 4); 1615cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { 1616cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, 0); // component 1617cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, 1); // palette mapping 1618cabdff1aSopenharmony_ci bytestream_put_byte(&s->buf, i); // index 1619cabdff1aSopenharmony_ci } 1620cabdff1aSopenharmony_ci update_size(chunkstart, s->buf); 1621cabdff1aSopenharmony_ci } 1622cabdff1aSopenharmony_ci update_size(jp2hstart, s->buf); 1623cabdff1aSopenharmony_ci 1624cabdff1aSopenharmony_ci jp2cstart = s->buf; 1625cabdff1aSopenharmony_ci bytestream_put_be32(&s->buf, 0); 1626cabdff1aSopenharmony_ci bytestream_put_buffer(&s->buf, "jp2c", 4); 1627cabdff1aSopenharmony_ci } 1628cabdff1aSopenharmony_ci 1629cabdff1aSopenharmony_ci if (s->buf_end - s->buf < 2) 1630cabdff1aSopenharmony_ci return -1; 1631cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_SOC); 1632cabdff1aSopenharmony_ci if ((ret = put_siz(s)) < 0) 1633cabdff1aSopenharmony_ci return ret; 1634cabdff1aSopenharmony_ci if ((ret = put_cod(s)) < 0) 1635cabdff1aSopenharmony_ci return ret; 1636cabdff1aSopenharmony_ci if ((ret = put_qcd(s, 0)) < 0) 1637cabdff1aSopenharmony_ci return ret; 1638cabdff1aSopenharmony_ci if ((ret = put_com(s, 0)) < 0) 1639cabdff1aSopenharmony_ci return ret; 1640cabdff1aSopenharmony_ci 1641cabdff1aSopenharmony_ci for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ 1642cabdff1aSopenharmony_ci uint8_t *psotptr; 1643cabdff1aSopenharmony_ci if (!(psotptr = put_sot(s, tileno))) 1644cabdff1aSopenharmony_ci return -1; 1645cabdff1aSopenharmony_ci if (s->buf_end - s->buf < 2) 1646cabdff1aSopenharmony_ci return -1; 1647cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_SOD); 1648cabdff1aSopenharmony_ci if ((ret = encode_tile(s, s->tile + tileno, tileno)) < 0) 1649cabdff1aSopenharmony_ci return ret; 1650cabdff1aSopenharmony_ci bytestream_put_be32(&psotptr, s->buf - psotptr + 6); 1651cabdff1aSopenharmony_ci } 1652cabdff1aSopenharmony_ci if (s->buf_end - s->buf < 2) 1653cabdff1aSopenharmony_ci return -1; 1654cabdff1aSopenharmony_ci bytestream_put_be16(&s->buf, JPEG2000_EOC); 1655cabdff1aSopenharmony_ci 1656cabdff1aSopenharmony_ci if (s->format == CODEC_JP2) 1657cabdff1aSopenharmony_ci update_size(jp2cstart, s->buf); 1658cabdff1aSopenharmony_ci 1659cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG, "end\n"); 1660cabdff1aSopenharmony_ci pkt->size = s->buf - s->buf_start; 1661cabdff1aSopenharmony_ci *got_packet = 1; 1662cabdff1aSopenharmony_ci 1663cabdff1aSopenharmony_ci return 0; 1664cabdff1aSopenharmony_ci} 1665cabdff1aSopenharmony_ci 1666cabdff1aSopenharmony_cistatic int parse_layer_rates(Jpeg2000EncoderContext *s) 1667cabdff1aSopenharmony_ci{ 1668cabdff1aSopenharmony_ci int i; 1669cabdff1aSopenharmony_ci char *token; 1670cabdff1aSopenharmony_ci char *saveptr = NULL; 1671cabdff1aSopenharmony_ci int rate; 1672cabdff1aSopenharmony_ci int nlayers = 0; 1673cabdff1aSopenharmony_ci if (!s->lr_str) { 1674cabdff1aSopenharmony_ci s->nlayers = 1; 1675cabdff1aSopenharmony_ci s->layer_rates[0] = 0; 1676cabdff1aSopenharmony_ci s->compression_rate_enc = 0; 1677cabdff1aSopenharmony_ci return 0; 1678cabdff1aSopenharmony_ci } 1679cabdff1aSopenharmony_ci 1680cabdff1aSopenharmony_ci token = av_strtok(s->lr_str, ",", &saveptr); 1681cabdff1aSopenharmony_ci if (token && (rate = strtol(token, NULL, 10))) { 1682cabdff1aSopenharmony_ci s->layer_rates[0] = rate <= 1 ? 0:rate; 1683cabdff1aSopenharmony_ci nlayers++; 1684cabdff1aSopenharmony_ci } else { 1685cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1686cabdff1aSopenharmony_ci } 1687cabdff1aSopenharmony_ci 1688cabdff1aSopenharmony_ci while (1) { 1689cabdff1aSopenharmony_ci token = av_strtok(NULL, ",", &saveptr); 1690cabdff1aSopenharmony_ci if (!token) 1691cabdff1aSopenharmony_ci break; 1692cabdff1aSopenharmony_ci if (rate = strtol(token, NULL, 10)) { 1693cabdff1aSopenharmony_ci if (nlayers >= 100) { 1694cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1695cabdff1aSopenharmony_ci } 1696cabdff1aSopenharmony_ci s->layer_rates[nlayers] = rate <= 1 ? 0:rate; 1697cabdff1aSopenharmony_ci nlayers++; 1698cabdff1aSopenharmony_ci } else { 1699cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1700cabdff1aSopenharmony_ci } 1701cabdff1aSopenharmony_ci } 1702cabdff1aSopenharmony_ci 1703cabdff1aSopenharmony_ci for (i = 1; i < nlayers; i++) { 1704cabdff1aSopenharmony_ci if (s->layer_rates[i] >= s->layer_rates[i-1]) { 1705cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1706cabdff1aSopenharmony_ci } 1707cabdff1aSopenharmony_ci } 1708cabdff1aSopenharmony_ci s->nlayers = nlayers; 1709cabdff1aSopenharmony_ci s->compression_rate_enc = 1; 1710cabdff1aSopenharmony_ci return 0; 1711cabdff1aSopenharmony_ci} 1712cabdff1aSopenharmony_ci 1713cabdff1aSopenharmony_cistatic av_cold int j2kenc_init(AVCodecContext *avctx) 1714cabdff1aSopenharmony_ci{ 1715cabdff1aSopenharmony_ci static AVOnce init_static_once = AV_ONCE_INIT; 1716cabdff1aSopenharmony_ci int i, ret; 1717cabdff1aSopenharmony_ci Jpeg2000EncoderContext *s = avctx->priv_data; 1718cabdff1aSopenharmony_ci Jpeg2000CodingStyle *codsty = &s->codsty; 1719cabdff1aSopenharmony_ci Jpeg2000QuantStyle *qntsty = &s->qntsty; 1720cabdff1aSopenharmony_ci const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); 1721cabdff1aSopenharmony_ci 1722cabdff1aSopenharmony_ci s->avctx = avctx; 1723cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG, "init\n"); 1724cabdff1aSopenharmony_ci if (parse_layer_rates(s)) { 1725cabdff1aSopenharmony_ci av_log(s, AV_LOG_WARNING, "Layer rates invalid. Encoding with 1 layer based on quality metric.\n"); 1726cabdff1aSopenharmony_ci s->nlayers = 1; 1727cabdff1aSopenharmony_ci s->layer_rates[0] = 0; 1728cabdff1aSopenharmony_ci s->compression_rate_enc = 0; 1729cabdff1aSopenharmony_ci } 1730cabdff1aSopenharmony_ci 1731cabdff1aSopenharmony_ci if (avctx->pix_fmt == AV_PIX_FMT_PAL8 && (s->pred != FF_DWT97_INT || s->format != CODEC_JP2)) { 1732cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_WARNING, "Forcing lossless jp2 for pal8\n"); 1733cabdff1aSopenharmony_ci s->pred = 1; 1734cabdff1aSopenharmony_ci s->format = CODEC_JP2; 1735cabdff1aSopenharmony_ci } 1736cabdff1aSopenharmony_ci 1737cabdff1aSopenharmony_ci // defaults: 1738cabdff1aSopenharmony_ci // TODO: implement setting non-standard precinct size 1739cabdff1aSopenharmony_ci memset(codsty->log2_prec_widths , 15, sizeof(codsty->log2_prec_widths )); 1740cabdff1aSopenharmony_ci memset(codsty->log2_prec_heights, 15, sizeof(codsty->log2_prec_heights)); 1741cabdff1aSopenharmony_ci codsty->nreslevels2decode= 1742cabdff1aSopenharmony_ci codsty->nreslevels = 7; 1743cabdff1aSopenharmony_ci codsty->nlayers = s->nlayers; 1744cabdff1aSopenharmony_ci codsty->log2_cblk_width = 4; 1745cabdff1aSopenharmony_ci codsty->log2_cblk_height = 4; 1746cabdff1aSopenharmony_ci codsty->transform = s->pred ? FF_DWT53 : FF_DWT97_INT; 1747cabdff1aSopenharmony_ci 1748cabdff1aSopenharmony_ci qntsty->nguardbits = 1; 1749cabdff1aSopenharmony_ci 1750cabdff1aSopenharmony_ci if ((s->tile_width & (s->tile_width -1)) || 1751cabdff1aSopenharmony_ci (s->tile_height & (s->tile_height-1))) { 1752cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "Tile dimension not a power of 2\n"); 1753cabdff1aSopenharmony_ci } 1754cabdff1aSopenharmony_ci 1755cabdff1aSopenharmony_ci if (codsty->transform == FF_DWT53) 1756cabdff1aSopenharmony_ci qntsty->quantsty = JPEG2000_QSTY_NONE; 1757cabdff1aSopenharmony_ci else 1758cabdff1aSopenharmony_ci qntsty->quantsty = JPEG2000_QSTY_SE; 1759cabdff1aSopenharmony_ci 1760cabdff1aSopenharmony_ci s->width = avctx->width; 1761cabdff1aSopenharmony_ci s->height = avctx->height; 1762cabdff1aSopenharmony_ci 1763cabdff1aSopenharmony_ci s->ncomponents = desc->nb_components; 1764cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { 1765cabdff1aSopenharmony_ci s->cbps[i] = desc->comp[i].depth; 1766cabdff1aSopenharmony_ci } 1767cabdff1aSopenharmony_ci 1768cabdff1aSopenharmony_ci if ((desc->flags & AV_PIX_FMT_FLAG_PLANAR) && s->ncomponents > 1) { 1769cabdff1aSopenharmony_ci s->planar = 1; 1770cabdff1aSopenharmony_ci ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, 1771cabdff1aSopenharmony_ci s->chroma_shift, s->chroma_shift + 1); 1772cabdff1aSopenharmony_ci if (ret) 1773cabdff1aSopenharmony_ci return ret; 1774cabdff1aSopenharmony_ci } 1775cabdff1aSopenharmony_ci 1776cabdff1aSopenharmony_ci ff_thread_once(&init_static_once, init_luts); 1777cabdff1aSopenharmony_ci 1778cabdff1aSopenharmony_ci init_quantization(s); 1779cabdff1aSopenharmony_ci if ((ret=init_tiles(s)) < 0) 1780cabdff1aSopenharmony_ci return ret; 1781cabdff1aSopenharmony_ci 1782cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG, "after init\n"); 1783cabdff1aSopenharmony_ci 1784cabdff1aSopenharmony_ci return 0; 1785cabdff1aSopenharmony_ci} 1786cabdff1aSopenharmony_ci 1787cabdff1aSopenharmony_cistatic int j2kenc_destroy(AVCodecContext *avctx) 1788cabdff1aSopenharmony_ci{ 1789cabdff1aSopenharmony_ci Jpeg2000EncoderContext *s = avctx->priv_data; 1790cabdff1aSopenharmony_ci 1791cabdff1aSopenharmony_ci cleanup(s); 1792cabdff1aSopenharmony_ci return 0; 1793cabdff1aSopenharmony_ci} 1794cabdff1aSopenharmony_ci 1795cabdff1aSopenharmony_ci// taken from the libopenjpeg wraper so it matches 1796cabdff1aSopenharmony_ci 1797cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(Jpeg2000EncoderContext, x) 1798cabdff1aSopenharmony_ci#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 1799cabdff1aSopenharmony_cistatic const AVOption options[] = { 1800cabdff1aSopenharmony_ci { "format", "Codec Format", OFFSET(format), AV_OPT_TYPE_INT, { .i64 = CODEC_JP2 }, CODEC_J2K, CODEC_JP2, VE, "format" }, 1801cabdff1aSopenharmony_ci { "j2k", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CODEC_J2K }, 0, 0, VE, "format" }, 1802cabdff1aSopenharmony_ci { "jp2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CODEC_JP2 }, 0, 0, VE, "format" }, 1803cabdff1aSopenharmony_ci { "tile_width", "Tile Width", OFFSET(tile_width), AV_OPT_TYPE_INT, { .i64 = 256 }, 1, 1<<30, VE, }, 1804cabdff1aSopenharmony_ci { "tile_height", "Tile Height", OFFSET(tile_height), AV_OPT_TYPE_INT, { .i64 = 256 }, 1, 1<<30, VE, }, 1805cabdff1aSopenharmony_ci { "pred", "DWT Type", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, "pred" }, 1806cabdff1aSopenharmony_ci { "dwt97int", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" }, 1807cabdff1aSopenharmony_ci { "dwt53", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" }, 1808cabdff1aSopenharmony_ci { "sop", "SOP marker", OFFSET(sop), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, }, 1809cabdff1aSopenharmony_ci { "eph", "EPH marker", OFFSET(eph), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, }, 1810cabdff1aSopenharmony_ci { "prog", "Progression Order", OFFSET(prog), AV_OPT_TYPE_INT, { .i64 = 0 }, JPEG2000_PGOD_LRCP, JPEG2000_PGOD_CPRL, VE, "prog" }, 1811cabdff1aSopenharmony_ci { "lrcp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_LRCP }, 0, 0, VE, "prog" }, 1812cabdff1aSopenharmony_ci { "rlcp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_RLCP }, 0, 0, VE, "prog" }, 1813cabdff1aSopenharmony_ci { "rpcl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_RPCL }, 0, 0, VE, "prog" }, 1814cabdff1aSopenharmony_ci { "pcrl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_PCRL }, 0, 0, VE, "prog" }, 1815cabdff1aSopenharmony_ci { "cprl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = JPEG2000_PGOD_CPRL }, 0, 0, VE, "prog" }, 1816cabdff1aSopenharmony_ci { "layer_rates", "Layer Rates", OFFSET(lr_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE }, 1817cabdff1aSopenharmony_ci { NULL } 1818cabdff1aSopenharmony_ci}; 1819cabdff1aSopenharmony_ci 1820cabdff1aSopenharmony_cistatic const AVClass j2k_class = { 1821cabdff1aSopenharmony_ci .class_name = "jpeg 2000 encoder", 1822cabdff1aSopenharmony_ci .item_name = av_default_item_name, 1823cabdff1aSopenharmony_ci .option = options, 1824cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 1825cabdff1aSopenharmony_ci}; 1826cabdff1aSopenharmony_ci 1827cabdff1aSopenharmony_ciconst FFCodec ff_jpeg2000_encoder = { 1828cabdff1aSopenharmony_ci .p.name = "jpeg2000", 1829cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"), 1830cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1831cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_JPEG2000, 1832cabdff1aSopenharmony_ci .priv_data_size = sizeof(Jpeg2000EncoderContext), 1833cabdff1aSopenharmony_ci .init = j2kenc_init, 1834cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(encode_frame), 1835cabdff1aSopenharmony_ci .close = j2kenc_destroy, 1836cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]) { 1837cabdff1aSopenharmony_ci AV_PIX_FMT_RGB24, AV_PIX_FMT_YUV444P, AV_PIX_FMT_GRAY8, 1838cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, 1839cabdff1aSopenharmony_ci AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, 1840cabdff1aSopenharmony_ci AV_PIX_FMT_PAL8, 1841cabdff1aSopenharmony_ci AV_PIX_FMT_RGB48, AV_PIX_FMT_GRAY16, 1842cabdff1aSopenharmony_ci AV_PIX_FMT_NONE 1843cabdff1aSopenharmony_ci }, 1844cabdff1aSopenharmony_ci .p.priv_class = &j2k_class, 1845cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 1846cabdff1aSopenharmony_ci}; 1847