xref: /aosp_15_r20/external/pdfium/third_party/libopenjpeg/tcd.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker /*
2*3ac0a46fSAndroid Build Coastguard Worker  * The copyright in this software is being made available under the 2-clauses
3*3ac0a46fSAndroid Build Coastguard Worker  * BSD License, included below. This software may be subject to other third
4*3ac0a46fSAndroid Build Coastguard Worker  * party and contributor rights, including patent rights, and no such rights
5*3ac0a46fSAndroid Build Coastguard Worker  * are granted under this license.
6*3ac0a46fSAndroid Build Coastguard Worker  *
7*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2002-2014, Professor Benoit Macq
9*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2001-2003, David Janssens
10*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2002-2003, Yannick Verschueren
11*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2003-2007, Francois-Olivier Devaux
12*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2003-2014, Antonin Descampe
13*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2005, Herve Drolon, FreeImage Team
14*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2006-2007, Parvatha Elangovan
15*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
16*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2012, CS Systemes d'Information, France
17*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2017, IntoPIX SA <[email protected]>
18*3ac0a46fSAndroid Build Coastguard Worker  * All rights reserved.
19*3ac0a46fSAndroid Build Coastguard Worker  *
20*3ac0a46fSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
21*3ac0a46fSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
22*3ac0a46fSAndroid Build Coastguard Worker  * are met:
23*3ac0a46fSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
24*3ac0a46fSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
25*3ac0a46fSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
26*3ac0a46fSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
27*3ac0a46fSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
28*3ac0a46fSAndroid Build Coastguard Worker  *
29*3ac0a46fSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
30*3ac0a46fSAndroid Build Coastguard Worker  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31*3ac0a46fSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32*3ac0a46fSAndroid Build Coastguard Worker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33*3ac0a46fSAndroid Build Coastguard Worker  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34*3ac0a46fSAndroid Build Coastguard Worker  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35*3ac0a46fSAndroid Build Coastguard Worker  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36*3ac0a46fSAndroid Build Coastguard Worker  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37*3ac0a46fSAndroid Build Coastguard Worker  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38*3ac0a46fSAndroid Build Coastguard Worker  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39*3ac0a46fSAndroid Build Coastguard Worker  * POSSIBILITY OF SUCH DAMAGE.
40*3ac0a46fSAndroid Build Coastguard Worker  */
41*3ac0a46fSAndroid Build Coastguard Worker 
42*3ac0a46fSAndroid Build Coastguard Worker #include "opj_includes.h"
43*3ac0a46fSAndroid Build Coastguard Worker #include "opj_common.h"
44*3ac0a46fSAndroid Build Coastguard Worker 
45*3ac0a46fSAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
46*3ac0a46fSAndroid Build Coastguard Worker 
47*3ac0a46fSAndroid Build Coastguard Worker /* TODO MSD: */
48*3ac0a46fSAndroid Build Coastguard Worker #ifdef TODO_MSD
tcd_dump(FILE * fd,opj_tcd_t * tcd,opj_tcd_image_t * img)49*3ac0a46fSAndroid Build Coastguard Worker void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img)
50*3ac0a46fSAndroid Build Coastguard Worker {
51*3ac0a46fSAndroid Build Coastguard Worker     int tileno, compno, resno, bandno, precno;/*, cblkno;*/
52*3ac0a46fSAndroid Build Coastguard Worker 
53*3ac0a46fSAndroid Build Coastguard Worker     fprintf(fd, "image {\n");
54*3ac0a46fSAndroid Build Coastguard Worker     fprintf(fd, "  tw=%d, th=%d x0=%d x1=%d y0=%d y1=%d\n",
55*3ac0a46fSAndroid Build Coastguard Worker             img->tw, img->th, tcd->image->x0, tcd->image->x1, tcd->image->y0,
56*3ac0a46fSAndroid Build Coastguard Worker             tcd->image->y1);
57*3ac0a46fSAndroid Build Coastguard Worker 
58*3ac0a46fSAndroid Build Coastguard Worker     for (tileno = 0; tileno < img->th * img->tw; tileno++) {
59*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_tile_t *tile = &tcd->tcd_image->tiles[tileno];
60*3ac0a46fSAndroid Build Coastguard Worker         fprintf(fd, "  tile {\n");
61*3ac0a46fSAndroid Build Coastguard Worker         fprintf(fd, "    x0=%d, y0=%d, x1=%d, y1=%d, numcomps=%d\n",
62*3ac0a46fSAndroid Build Coastguard Worker                 tile->x0, tile->y0, tile->x1, tile->y1, tile->numcomps);
63*3ac0a46fSAndroid Build Coastguard Worker         for (compno = 0; compno < tile->numcomps; compno++) {
64*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
65*3ac0a46fSAndroid Build Coastguard Worker             fprintf(fd, "    tilec {\n");
66*3ac0a46fSAndroid Build Coastguard Worker             fprintf(fd,
67*3ac0a46fSAndroid Build Coastguard Worker                     "      x0=%d, y0=%d, x1=%d, y1=%d, numresolutions=%d\n",
68*3ac0a46fSAndroid Build Coastguard Worker                     tilec->x0, tilec->y0, tilec->x1, tilec->y1, tilec->numresolutions);
69*3ac0a46fSAndroid Build Coastguard Worker             for (resno = 0; resno < tilec->numresolutions; resno++) {
70*3ac0a46fSAndroid Build Coastguard Worker                 opj_tcd_resolution_t *res = &tilec->resolutions[resno];
71*3ac0a46fSAndroid Build Coastguard Worker                 fprintf(fd, "\n   res {\n");
72*3ac0a46fSAndroid Build Coastguard Worker                 fprintf(fd,
73*3ac0a46fSAndroid Build Coastguard Worker                         "          x0=%d, y0=%d, x1=%d, y1=%d, pw=%d, ph=%d, numbands=%d\n",
74*3ac0a46fSAndroid Build Coastguard Worker                         res->x0, res->y0, res->x1, res->y1, res->pw, res->ph, res->numbands);
75*3ac0a46fSAndroid Build Coastguard Worker                 for (bandno = 0; bandno < res->numbands; bandno++) {
76*3ac0a46fSAndroid Build Coastguard Worker                     opj_tcd_band_t *band = &res->bands[bandno];
77*3ac0a46fSAndroid Build Coastguard Worker                     fprintf(fd, "        band {\n");
78*3ac0a46fSAndroid Build Coastguard Worker                     fprintf(fd,
79*3ac0a46fSAndroid Build Coastguard Worker                             "          x0=%d, y0=%d, x1=%d, y1=%d, stepsize=%f, numbps=%d\n",
80*3ac0a46fSAndroid Build Coastguard Worker                             band->x0, band->y0, band->x1, band->y1, band->stepsize, band->numbps);
81*3ac0a46fSAndroid Build Coastguard Worker                     for (precno = 0; precno < res->pw * res->ph; precno++) {
82*3ac0a46fSAndroid Build Coastguard Worker                         opj_tcd_precinct_t *prec = &band->precincts[precno];
83*3ac0a46fSAndroid Build Coastguard Worker                         fprintf(fd, "          prec {\n");
84*3ac0a46fSAndroid Build Coastguard Worker                         fprintf(fd,
85*3ac0a46fSAndroid Build Coastguard Worker                                 "            x0=%d, y0=%d, x1=%d, y1=%d, cw=%d, ch=%d\n",
86*3ac0a46fSAndroid Build Coastguard Worker                                 prec->x0, prec->y0, prec->x1, prec->y1, prec->cw, prec->ch);
87*3ac0a46fSAndroid Build Coastguard Worker                         /*
88*3ac0a46fSAndroid Build Coastguard Worker                         for (cblkno = 0; cblkno < prec->cw * prec->ch; cblkno++) {
89*3ac0a46fSAndroid Build Coastguard Worker                                 opj_tcd_cblk_t *cblk = &prec->cblks[cblkno];
90*3ac0a46fSAndroid Build Coastguard Worker                                 fprintf(fd, "            cblk {\n");
91*3ac0a46fSAndroid Build Coastguard Worker                                 fprintf(fd,
92*3ac0a46fSAndroid Build Coastguard Worker                                         "              x0=%d, y0=%d, x1=%d, y1=%d\n",
93*3ac0a46fSAndroid Build Coastguard Worker                                         cblk->x0, cblk->y0, cblk->x1, cblk->y1);
94*3ac0a46fSAndroid Build Coastguard Worker                                 fprintf(fd, "            }\n");
95*3ac0a46fSAndroid Build Coastguard Worker                         }
96*3ac0a46fSAndroid Build Coastguard Worker                         */
97*3ac0a46fSAndroid Build Coastguard Worker                         fprintf(fd, "          }\n");
98*3ac0a46fSAndroid Build Coastguard Worker                     }
99*3ac0a46fSAndroid Build Coastguard Worker                     fprintf(fd, "        }\n");
100*3ac0a46fSAndroid Build Coastguard Worker                 }
101*3ac0a46fSAndroid Build Coastguard Worker                 fprintf(fd, "      }\n");
102*3ac0a46fSAndroid Build Coastguard Worker             }
103*3ac0a46fSAndroid Build Coastguard Worker             fprintf(fd, "    }\n");
104*3ac0a46fSAndroid Build Coastguard Worker         }
105*3ac0a46fSAndroid Build Coastguard Worker         fprintf(fd, "  }\n");
106*3ac0a46fSAndroid Build Coastguard Worker     }
107*3ac0a46fSAndroid Build Coastguard Worker     fprintf(fd, "}\n");
108*3ac0a46fSAndroid Build Coastguard Worker }
109*3ac0a46fSAndroid Build Coastguard Worker #endif
110*3ac0a46fSAndroid Build Coastguard Worker 
111*3ac0a46fSAndroid Build Coastguard Worker /**
112*3ac0a46fSAndroid Build Coastguard Worker  * Initializes tile coding/decoding
113*3ac0a46fSAndroid Build Coastguard Worker  */
114*3ac0a46fSAndroid Build Coastguard Worker static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
115*3ac0a46fSAndroid Build Coastguard Worker         OPJ_BOOL isEncoder, OPJ_SIZE_T sizeof_block,
116*3ac0a46fSAndroid Build Coastguard Worker         opj_event_mgr_t* manager);
117*3ac0a46fSAndroid Build Coastguard Worker 
118*3ac0a46fSAndroid Build Coastguard Worker /**
119*3ac0a46fSAndroid Build Coastguard Worker * Allocates memory for a decoding code block.
120*3ac0a46fSAndroid Build Coastguard Worker */
121*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_code_block_dec_allocate(opj_tcd_cblk_dec_t *
122*3ac0a46fSAndroid Build Coastguard Worker         p_code_block);
123*3ac0a46fSAndroid Build Coastguard Worker 
124*3ac0a46fSAndroid Build Coastguard Worker /**
125*3ac0a46fSAndroid Build Coastguard Worker  * Deallocates the decoding data of the given precinct.
126*3ac0a46fSAndroid Build Coastguard Worker  */
127*3ac0a46fSAndroid Build Coastguard Worker static void opj_tcd_code_block_dec_deallocate(opj_tcd_precinct_t * p_precinct);
128*3ac0a46fSAndroid Build Coastguard Worker 
129*3ac0a46fSAndroid Build Coastguard Worker /**
130*3ac0a46fSAndroid Build Coastguard Worker  * Allocates memory for an encoding code block (but not data).
131*3ac0a46fSAndroid Build Coastguard Worker  */
132*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_code_block_enc_allocate(opj_tcd_cblk_enc_t *
133*3ac0a46fSAndroid Build Coastguard Worker         p_code_block);
134*3ac0a46fSAndroid Build Coastguard Worker 
135*3ac0a46fSAndroid Build Coastguard Worker /**
136*3ac0a46fSAndroid Build Coastguard Worker  * Allocates data for an encoding code block
137*3ac0a46fSAndroid Build Coastguard Worker  */
138*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_code_block_enc_allocate_data(opj_tcd_cblk_enc_t *
139*3ac0a46fSAndroid Build Coastguard Worker         p_code_block);
140*3ac0a46fSAndroid Build Coastguard Worker 
141*3ac0a46fSAndroid Build Coastguard Worker /**
142*3ac0a46fSAndroid Build Coastguard Worker  * Deallocates the encoding data of the given precinct.
143*3ac0a46fSAndroid Build Coastguard Worker  */
144*3ac0a46fSAndroid Build Coastguard Worker static void opj_tcd_code_block_enc_deallocate(opj_tcd_precinct_t * p_precinct);
145*3ac0a46fSAndroid Build Coastguard Worker 
146*3ac0a46fSAndroid Build Coastguard Worker 
147*3ac0a46fSAndroid Build Coastguard Worker /**
148*3ac0a46fSAndroid Build Coastguard Worker Free the memory allocated for encoding
149*3ac0a46fSAndroid Build Coastguard Worker @param tcd TCD handle
150*3ac0a46fSAndroid Build Coastguard Worker */
151*3ac0a46fSAndroid Build Coastguard Worker static void opj_tcd_free_tile(opj_tcd_t *tcd);
152*3ac0a46fSAndroid Build Coastguard Worker 
153*3ac0a46fSAndroid Build Coastguard Worker 
154*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_t2_decode(opj_tcd_t *p_tcd,
155*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_BYTE * p_src_data,
156*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_UINT32 * p_data_read,
157*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_UINT32 p_max_src_size,
158*3ac0a46fSAndroid Build Coastguard Worker                                   opj_codestream_index_t *p_cstr_index,
159*3ac0a46fSAndroid Build Coastguard Worker                                   opj_event_mgr_t *p_manager);
160*3ac0a46fSAndroid Build Coastguard Worker 
161*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_t1_decode(opj_tcd_t *p_tcd,
162*3ac0a46fSAndroid Build Coastguard Worker                                   opj_event_mgr_t *p_manager);
163*3ac0a46fSAndroid Build Coastguard Worker 
164*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_dwt_decode(opj_tcd_t *p_tcd);
165*3ac0a46fSAndroid Build Coastguard Worker 
166*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_mct_decode(opj_tcd_t *p_tcd,
167*3ac0a46fSAndroid Build Coastguard Worker                                    opj_event_mgr_t *p_manager);
168*3ac0a46fSAndroid Build Coastguard Worker 
169*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_dc_level_shift_decode(opj_tcd_t *p_tcd);
170*3ac0a46fSAndroid Build Coastguard Worker 
171*3ac0a46fSAndroid Build Coastguard Worker 
172*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_dc_level_shift_encode(opj_tcd_t *p_tcd);
173*3ac0a46fSAndroid Build Coastguard Worker 
174*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_mct_encode(opj_tcd_t *p_tcd);
175*3ac0a46fSAndroid Build Coastguard Worker 
176*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_dwt_encode(opj_tcd_t *p_tcd);
177*3ac0a46fSAndroid Build Coastguard Worker 
178*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_t1_encode(opj_tcd_t *p_tcd);
179*3ac0a46fSAndroid Build Coastguard Worker 
180*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd,
181*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_BYTE * p_dest_data,
182*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_UINT32 * p_data_written,
183*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_UINT32 p_max_dest_size,
184*3ac0a46fSAndroid Build Coastguard Worker                                   opj_codestream_info_t *p_cstr_info,
185*3ac0a46fSAndroid Build Coastguard Worker                                   opj_tcd_marker_info_t* p_marker_info,
186*3ac0a46fSAndroid Build Coastguard Worker                                   opj_event_mgr_t *p_manager);
187*3ac0a46fSAndroid Build Coastguard Worker 
188*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_rate_allocate_encode(opj_tcd_t *p_tcd,
189*3ac0a46fSAndroid Build Coastguard Worker         OPJ_BYTE * p_dest_data,
190*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 p_max_dest_size,
191*3ac0a46fSAndroid Build Coastguard Worker         opj_codestream_info_t *p_cstr_info,
192*3ac0a46fSAndroid Build Coastguard Worker         opj_event_mgr_t *p_manager);
193*3ac0a46fSAndroid Build Coastguard Worker 
194*3ac0a46fSAndroid Build Coastguard Worker 
195*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_is_whole_tilecomp_decoding(opj_tcd_t *tcd,
196*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 compno);
197*3ac0a46fSAndroid Build Coastguard Worker 
198*3ac0a46fSAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
199*3ac0a46fSAndroid Build Coastguard Worker 
200*3ac0a46fSAndroid Build Coastguard Worker /**
201*3ac0a46fSAndroid Build Coastguard Worker Create a new TCD handle
202*3ac0a46fSAndroid Build Coastguard Worker */
opj_tcd_create(OPJ_BOOL p_is_decoder)203*3ac0a46fSAndroid Build Coastguard Worker opj_tcd_t* opj_tcd_create(OPJ_BOOL p_is_decoder)
204*3ac0a46fSAndroid Build Coastguard Worker {
205*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_t *l_tcd = 00;
206*3ac0a46fSAndroid Build Coastguard Worker 
207*3ac0a46fSAndroid Build Coastguard Worker     /* create the tcd structure */
208*3ac0a46fSAndroid Build Coastguard Worker     l_tcd = (opj_tcd_t*) opj_calloc(1, sizeof(opj_tcd_t));
209*3ac0a46fSAndroid Build Coastguard Worker     if (!l_tcd) {
210*3ac0a46fSAndroid Build Coastguard Worker         return 00;
211*3ac0a46fSAndroid Build Coastguard Worker     }
212*3ac0a46fSAndroid Build Coastguard Worker 
213*3ac0a46fSAndroid Build Coastguard Worker     l_tcd->m_is_decoder = p_is_decoder ? 1 : 0;
214*3ac0a46fSAndroid Build Coastguard Worker 
215*3ac0a46fSAndroid Build Coastguard Worker     l_tcd->tcd_image = (opj_tcd_image_t*)opj_calloc(1, sizeof(opj_tcd_image_t));
216*3ac0a46fSAndroid Build Coastguard Worker     if (!l_tcd->tcd_image) {
217*3ac0a46fSAndroid Build Coastguard Worker         opj_free(l_tcd);
218*3ac0a46fSAndroid Build Coastguard Worker         return 00;
219*3ac0a46fSAndroid Build Coastguard Worker     }
220*3ac0a46fSAndroid Build Coastguard Worker 
221*3ac0a46fSAndroid Build Coastguard Worker     return l_tcd;
222*3ac0a46fSAndroid Build Coastguard Worker }
223*3ac0a46fSAndroid Build Coastguard Worker 
224*3ac0a46fSAndroid Build Coastguard Worker 
225*3ac0a46fSAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
226*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_rateallocate_fixed(opj_tcd_t * tcd)227*3ac0a46fSAndroid Build Coastguard Worker void opj_tcd_rateallocate_fixed(opj_tcd_t *tcd)
228*3ac0a46fSAndroid Build Coastguard Worker {
229*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 layno;
230*3ac0a46fSAndroid Build Coastguard Worker 
231*3ac0a46fSAndroid Build Coastguard Worker     for (layno = 0; layno < tcd->tcp->numlayers; layno++) {
232*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_makelayer_fixed(tcd, layno, 1);
233*3ac0a46fSAndroid Build Coastguard Worker     }
234*3ac0a46fSAndroid Build Coastguard Worker }
235*3ac0a46fSAndroid Build Coastguard Worker 
236*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_makelayer(opj_tcd_t * tcd,OPJ_UINT32 layno,OPJ_FLOAT64 thresh,OPJ_UINT32 final)237*3ac0a46fSAndroid Build Coastguard Worker void opj_tcd_makelayer(opj_tcd_t *tcd,
238*3ac0a46fSAndroid Build Coastguard Worker                        OPJ_UINT32 layno,
239*3ac0a46fSAndroid Build Coastguard Worker                        OPJ_FLOAT64 thresh,
240*3ac0a46fSAndroid Build Coastguard Worker                        OPJ_UINT32 final)
241*3ac0a46fSAndroid Build Coastguard Worker {
242*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno, resno, bandno, precno, cblkno;
243*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 passno;
244*3ac0a46fSAndroid Build Coastguard Worker 
245*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t *tcd_tile = tcd->tcd_image->tiles;
246*3ac0a46fSAndroid Build Coastguard Worker 
247*3ac0a46fSAndroid Build Coastguard Worker     tcd_tile->distolayer[layno] = 0;        /* fixed_quality */
248*3ac0a46fSAndroid Build Coastguard Worker 
249*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < tcd_tile->numcomps; compno++) {
250*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
251*3ac0a46fSAndroid Build Coastguard Worker 
252*3ac0a46fSAndroid Build Coastguard Worker         for (resno = 0; resno < tilec->numresolutions; resno++) {
253*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_resolution_t *res = &tilec->resolutions[resno];
254*3ac0a46fSAndroid Build Coastguard Worker 
255*3ac0a46fSAndroid Build Coastguard Worker             for (bandno = 0; bandno < res->numbands; bandno++) {
256*3ac0a46fSAndroid Build Coastguard Worker                 opj_tcd_band_t *band = &res->bands[bandno];
257*3ac0a46fSAndroid Build Coastguard Worker 
258*3ac0a46fSAndroid Build Coastguard Worker                 /* Skip empty bands */
259*3ac0a46fSAndroid Build Coastguard Worker                 if (opj_tcd_is_band_empty(band)) {
260*3ac0a46fSAndroid Build Coastguard Worker                     continue;
261*3ac0a46fSAndroid Build Coastguard Worker                 }
262*3ac0a46fSAndroid Build Coastguard Worker 
263*3ac0a46fSAndroid Build Coastguard Worker                 for (precno = 0; precno < res->pw * res->ph; precno++) {
264*3ac0a46fSAndroid Build Coastguard Worker                     opj_tcd_precinct_t *prc = &band->precincts[precno];
265*3ac0a46fSAndroid Build Coastguard Worker 
266*3ac0a46fSAndroid Build Coastguard Worker                     for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
267*3ac0a46fSAndroid Build Coastguard Worker                         opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
268*3ac0a46fSAndroid Build Coastguard Worker                         opj_tcd_layer_t *layer = &cblk->layers[layno];
269*3ac0a46fSAndroid Build Coastguard Worker                         OPJ_UINT32 n;
270*3ac0a46fSAndroid Build Coastguard Worker 
271*3ac0a46fSAndroid Build Coastguard Worker                         if (layno == 0) {
272*3ac0a46fSAndroid Build Coastguard Worker                             cblk->numpassesinlayers = 0;
273*3ac0a46fSAndroid Build Coastguard Worker                         }
274*3ac0a46fSAndroid Build Coastguard Worker 
275*3ac0a46fSAndroid Build Coastguard Worker                         n = cblk->numpassesinlayers;
276*3ac0a46fSAndroid Build Coastguard Worker 
277*3ac0a46fSAndroid Build Coastguard Worker                         if (thresh < 0) {
278*3ac0a46fSAndroid Build Coastguard Worker                             /* Special value to indicate to use all passes */
279*3ac0a46fSAndroid Build Coastguard Worker                             n = cblk->totalpasses;
280*3ac0a46fSAndroid Build Coastguard Worker                         } else {
281*3ac0a46fSAndroid Build Coastguard Worker                             for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) {
282*3ac0a46fSAndroid Build Coastguard Worker                                 OPJ_UINT32 dr;
283*3ac0a46fSAndroid Build Coastguard Worker                                 OPJ_FLOAT64 dd;
284*3ac0a46fSAndroid Build Coastguard Worker                                 opj_tcd_pass_t *pass = &cblk->passes[passno];
285*3ac0a46fSAndroid Build Coastguard Worker 
286*3ac0a46fSAndroid Build Coastguard Worker                                 if (n == 0) {
287*3ac0a46fSAndroid Build Coastguard Worker                                     dr = pass->rate;
288*3ac0a46fSAndroid Build Coastguard Worker                                     dd = pass->distortiondec;
289*3ac0a46fSAndroid Build Coastguard Worker                                 } else {
290*3ac0a46fSAndroid Build Coastguard Worker                                     dr = pass->rate - cblk->passes[n - 1].rate;
291*3ac0a46fSAndroid Build Coastguard Worker                                     dd = pass->distortiondec - cblk->passes[n - 1].distortiondec;
292*3ac0a46fSAndroid Build Coastguard Worker                                 }
293*3ac0a46fSAndroid Build Coastguard Worker 
294*3ac0a46fSAndroid Build Coastguard Worker                                 if (!dr) {
295*3ac0a46fSAndroid Build Coastguard Worker                                     if (dd != 0) {
296*3ac0a46fSAndroid Build Coastguard Worker                                         n = passno + 1;
297*3ac0a46fSAndroid Build Coastguard Worker                                     }
298*3ac0a46fSAndroid Build Coastguard Worker                                     continue;
299*3ac0a46fSAndroid Build Coastguard Worker                                 }
300*3ac0a46fSAndroid Build Coastguard Worker                                 if (thresh - (dd / dr) <
301*3ac0a46fSAndroid Build Coastguard Worker                                         DBL_EPSILON) { /* do not rely on float equality, check with DBL_EPSILON margin */
302*3ac0a46fSAndroid Build Coastguard Worker                                     n = passno + 1;
303*3ac0a46fSAndroid Build Coastguard Worker                                 }
304*3ac0a46fSAndroid Build Coastguard Worker                             }
305*3ac0a46fSAndroid Build Coastguard Worker                         }
306*3ac0a46fSAndroid Build Coastguard Worker 
307*3ac0a46fSAndroid Build Coastguard Worker                         layer->numpasses = n - cblk->numpassesinlayers;
308*3ac0a46fSAndroid Build Coastguard Worker 
309*3ac0a46fSAndroid Build Coastguard Worker                         if (!layer->numpasses) {
310*3ac0a46fSAndroid Build Coastguard Worker                             layer->disto = 0;
311*3ac0a46fSAndroid Build Coastguard Worker                             continue;
312*3ac0a46fSAndroid Build Coastguard Worker                         }
313*3ac0a46fSAndroid Build Coastguard Worker 
314*3ac0a46fSAndroid Build Coastguard Worker                         if (cblk->numpassesinlayers == 0) {
315*3ac0a46fSAndroid Build Coastguard Worker                             layer->len = cblk->passes[n - 1].rate;
316*3ac0a46fSAndroid Build Coastguard Worker                             layer->data = cblk->data;
317*3ac0a46fSAndroid Build Coastguard Worker                             layer->disto = cblk->passes[n - 1].distortiondec;
318*3ac0a46fSAndroid Build Coastguard Worker                         } else {
319*3ac0a46fSAndroid Build Coastguard Worker                             layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers -
320*3ac0a46fSAndroid Build Coastguard Worker                                          1].rate;
321*3ac0a46fSAndroid Build Coastguard Worker                             layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
322*3ac0a46fSAndroid Build Coastguard Worker                             layer->disto = cblk->passes[n - 1].distortiondec -
323*3ac0a46fSAndroid Build Coastguard Worker                                            cblk->passes[cblk->numpassesinlayers - 1].distortiondec;
324*3ac0a46fSAndroid Build Coastguard Worker                         }
325*3ac0a46fSAndroid Build Coastguard Worker 
326*3ac0a46fSAndroid Build Coastguard Worker                         tcd_tile->distolayer[layno] += layer->disto;    /* fixed_quality */
327*3ac0a46fSAndroid Build Coastguard Worker 
328*3ac0a46fSAndroid Build Coastguard Worker                         if (final) {
329*3ac0a46fSAndroid Build Coastguard Worker                             cblk->numpassesinlayers = n;
330*3ac0a46fSAndroid Build Coastguard Worker                         }
331*3ac0a46fSAndroid Build Coastguard Worker                     }
332*3ac0a46fSAndroid Build Coastguard Worker                 }
333*3ac0a46fSAndroid Build Coastguard Worker             }
334*3ac0a46fSAndroid Build Coastguard Worker         }
335*3ac0a46fSAndroid Build Coastguard Worker     }
336*3ac0a46fSAndroid Build Coastguard Worker }
337*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_makelayer_fixed(opj_tcd_t * tcd,OPJ_UINT32 layno,OPJ_UINT32 final)338*3ac0a46fSAndroid Build Coastguard Worker void opj_tcd_makelayer_fixed(opj_tcd_t *tcd, OPJ_UINT32 layno,
339*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 final)
340*3ac0a46fSAndroid Build Coastguard Worker {
341*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno, resno, bandno, precno, cblkno;
342*3ac0a46fSAndroid Build Coastguard Worker     OPJ_INT32 value;                        /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolutions][3]; */
343*3ac0a46fSAndroid Build Coastguard Worker     OPJ_INT32 matrice[10][10][3];
344*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 i, j, k;
345*3ac0a46fSAndroid Build Coastguard Worker 
346*3ac0a46fSAndroid Build Coastguard Worker     opj_cp_t *cp = tcd->cp;
347*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t *tcd_tile = tcd->tcd_image->tiles;
348*3ac0a46fSAndroid Build Coastguard Worker     opj_tcp_t *tcd_tcp = tcd->tcp;
349*3ac0a46fSAndroid Build Coastguard Worker 
350*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < tcd_tile->numcomps; compno++) {
351*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
352*3ac0a46fSAndroid Build Coastguard Worker 
353*3ac0a46fSAndroid Build Coastguard Worker         for (i = 0; i < tcd_tcp->numlayers; i++) {
354*3ac0a46fSAndroid Build Coastguard Worker             for (j = 0; j < tilec->numresolutions; j++) {
355*3ac0a46fSAndroid Build Coastguard Worker                 for (k = 0; k < 3; k++) {
356*3ac0a46fSAndroid Build Coastguard Worker                     matrice[i][j][k] =
357*3ac0a46fSAndroid Build Coastguard Worker                         (OPJ_INT32)((OPJ_FLOAT32)cp->m_specific_param.m_enc.m_matrice[i *
358*3ac0a46fSAndroid Build Coastguard Worker                                       tilec->numresolutions * 3 + j * 3 + k]
359*3ac0a46fSAndroid Build Coastguard Worker                                     * (OPJ_FLOAT32)(tcd->image->comps[compno].prec / 16.0));
360*3ac0a46fSAndroid Build Coastguard Worker                 }
361*3ac0a46fSAndroid Build Coastguard Worker             }
362*3ac0a46fSAndroid Build Coastguard Worker         }
363*3ac0a46fSAndroid Build Coastguard Worker 
364*3ac0a46fSAndroid Build Coastguard Worker         for (resno = 0; resno < tilec->numresolutions; resno++) {
365*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_resolution_t *res = &tilec->resolutions[resno];
366*3ac0a46fSAndroid Build Coastguard Worker 
367*3ac0a46fSAndroid Build Coastguard Worker             for (bandno = 0; bandno < res->numbands; bandno++) {
368*3ac0a46fSAndroid Build Coastguard Worker                 opj_tcd_band_t *band = &res->bands[bandno];
369*3ac0a46fSAndroid Build Coastguard Worker 
370*3ac0a46fSAndroid Build Coastguard Worker                 /* Skip empty bands */
371*3ac0a46fSAndroid Build Coastguard Worker                 if (opj_tcd_is_band_empty(band)) {
372*3ac0a46fSAndroid Build Coastguard Worker                     continue;
373*3ac0a46fSAndroid Build Coastguard Worker                 }
374*3ac0a46fSAndroid Build Coastguard Worker 
375*3ac0a46fSAndroid Build Coastguard Worker                 for (precno = 0; precno < res->pw * res->ph; precno++) {
376*3ac0a46fSAndroid Build Coastguard Worker                     opj_tcd_precinct_t *prc = &band->precincts[precno];
377*3ac0a46fSAndroid Build Coastguard Worker 
378*3ac0a46fSAndroid Build Coastguard Worker                     for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
379*3ac0a46fSAndroid Build Coastguard Worker                         opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
380*3ac0a46fSAndroid Build Coastguard Worker                         opj_tcd_layer_t *layer = &cblk->layers[layno];
381*3ac0a46fSAndroid Build Coastguard Worker                         OPJ_UINT32 n;
382*3ac0a46fSAndroid Build Coastguard Worker                         OPJ_INT32 imsb = (OPJ_INT32)(tcd->image->comps[compno].prec -
383*3ac0a46fSAndroid Build Coastguard Worker                                                      cblk->numbps); /* number of bit-plan equal to zero */
384*3ac0a46fSAndroid Build Coastguard Worker 
385*3ac0a46fSAndroid Build Coastguard Worker                         /* Correction of the matrix of coefficient to include the IMSB information */
386*3ac0a46fSAndroid Build Coastguard Worker                         if (layno == 0) {
387*3ac0a46fSAndroid Build Coastguard Worker                             value = matrice[layno][resno][bandno];
388*3ac0a46fSAndroid Build Coastguard Worker                             if (imsb >= value) {
389*3ac0a46fSAndroid Build Coastguard Worker                                 value = 0;
390*3ac0a46fSAndroid Build Coastguard Worker                             } else {
391*3ac0a46fSAndroid Build Coastguard Worker                                 value -= imsb;
392*3ac0a46fSAndroid Build Coastguard Worker                             }
393*3ac0a46fSAndroid Build Coastguard Worker                         } else {
394*3ac0a46fSAndroid Build Coastguard Worker                             value = matrice[layno][resno][bandno] - matrice[layno - 1][resno][bandno];
395*3ac0a46fSAndroid Build Coastguard Worker                             if (imsb >= matrice[layno - 1][resno][bandno]) {
396*3ac0a46fSAndroid Build Coastguard Worker                                 value -= (imsb - matrice[layno - 1][resno][bandno]);
397*3ac0a46fSAndroid Build Coastguard Worker                                 if (value < 0) {
398*3ac0a46fSAndroid Build Coastguard Worker                                     value = 0;
399*3ac0a46fSAndroid Build Coastguard Worker                                 }
400*3ac0a46fSAndroid Build Coastguard Worker                             }
401*3ac0a46fSAndroid Build Coastguard Worker                         }
402*3ac0a46fSAndroid Build Coastguard Worker 
403*3ac0a46fSAndroid Build Coastguard Worker                         if (layno == 0) {
404*3ac0a46fSAndroid Build Coastguard Worker                             cblk->numpassesinlayers = 0;
405*3ac0a46fSAndroid Build Coastguard Worker                         }
406*3ac0a46fSAndroid Build Coastguard Worker 
407*3ac0a46fSAndroid Build Coastguard Worker                         n = cblk->numpassesinlayers;
408*3ac0a46fSAndroid Build Coastguard Worker                         if (cblk->numpassesinlayers == 0) {
409*3ac0a46fSAndroid Build Coastguard Worker                             if (value != 0) {
410*3ac0a46fSAndroid Build Coastguard Worker                                 n = 3 * (OPJ_UINT32)value - 2 + cblk->numpassesinlayers;
411*3ac0a46fSAndroid Build Coastguard Worker                             } else {
412*3ac0a46fSAndroid Build Coastguard Worker                                 n = cblk->numpassesinlayers;
413*3ac0a46fSAndroid Build Coastguard Worker                             }
414*3ac0a46fSAndroid Build Coastguard Worker                         } else {
415*3ac0a46fSAndroid Build Coastguard Worker                             n = 3 * (OPJ_UINT32)value + cblk->numpassesinlayers;
416*3ac0a46fSAndroid Build Coastguard Worker                         }
417*3ac0a46fSAndroid Build Coastguard Worker 
418*3ac0a46fSAndroid Build Coastguard Worker                         layer->numpasses = n - cblk->numpassesinlayers;
419*3ac0a46fSAndroid Build Coastguard Worker 
420*3ac0a46fSAndroid Build Coastguard Worker                         if (!layer->numpasses) {
421*3ac0a46fSAndroid Build Coastguard Worker                             continue;
422*3ac0a46fSAndroid Build Coastguard Worker                         }
423*3ac0a46fSAndroid Build Coastguard Worker 
424*3ac0a46fSAndroid Build Coastguard Worker                         if (cblk->numpassesinlayers == 0) {
425*3ac0a46fSAndroid Build Coastguard Worker                             layer->len = cblk->passes[n - 1].rate;
426*3ac0a46fSAndroid Build Coastguard Worker                             layer->data = cblk->data;
427*3ac0a46fSAndroid Build Coastguard Worker                         } else {
428*3ac0a46fSAndroid Build Coastguard Worker                             layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers -
429*3ac0a46fSAndroid Build Coastguard Worker                                          1].rate;
430*3ac0a46fSAndroid Build Coastguard Worker                             layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
431*3ac0a46fSAndroid Build Coastguard Worker                         }
432*3ac0a46fSAndroid Build Coastguard Worker 
433*3ac0a46fSAndroid Build Coastguard Worker                         if (final) {
434*3ac0a46fSAndroid Build Coastguard Worker                             cblk->numpassesinlayers = n;
435*3ac0a46fSAndroid Build Coastguard Worker                         }
436*3ac0a46fSAndroid Build Coastguard Worker                     }
437*3ac0a46fSAndroid Build Coastguard Worker                 }
438*3ac0a46fSAndroid Build Coastguard Worker             }
439*3ac0a46fSAndroid Build Coastguard Worker         }
440*3ac0a46fSAndroid Build Coastguard Worker     }
441*3ac0a46fSAndroid Build Coastguard Worker }
442*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_rateallocate(opj_tcd_t * tcd,OPJ_BYTE * dest,OPJ_UINT32 * p_data_written,OPJ_UINT32 len,opj_codestream_info_t * cstr_info,opj_event_mgr_t * p_manager)443*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_tcd_rateallocate(opj_tcd_t *tcd,
444*3ac0a46fSAndroid Build Coastguard Worker                               OPJ_BYTE *dest,
445*3ac0a46fSAndroid Build Coastguard Worker                               OPJ_UINT32 * p_data_written,
446*3ac0a46fSAndroid Build Coastguard Worker                               OPJ_UINT32 len,
447*3ac0a46fSAndroid Build Coastguard Worker                               opj_codestream_info_t *cstr_info,
448*3ac0a46fSAndroid Build Coastguard Worker                               opj_event_mgr_t *p_manager)
449*3ac0a46fSAndroid Build Coastguard Worker {
450*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno, resno, bandno, precno, cblkno, layno;
451*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 passno;
452*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT64 min, max;
453*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT64 cumdisto[100];      /* fixed_quality */
454*3ac0a46fSAndroid Build Coastguard Worker     const OPJ_FLOAT64 K = 1;                /* 1.1; fixed_quality */
455*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT64 maxSE = 0;
456*3ac0a46fSAndroid Build Coastguard Worker 
457*3ac0a46fSAndroid Build Coastguard Worker     opj_cp_t *cp = tcd->cp;
458*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t *tcd_tile = tcd->tcd_image->tiles;
459*3ac0a46fSAndroid Build Coastguard Worker     opj_tcp_t *tcd_tcp = tcd->tcp;
460*3ac0a46fSAndroid Build Coastguard Worker 
461*3ac0a46fSAndroid Build Coastguard Worker     min = DBL_MAX;
462*3ac0a46fSAndroid Build Coastguard Worker     max = 0;
463*3ac0a46fSAndroid Build Coastguard Worker 
464*3ac0a46fSAndroid Build Coastguard Worker     tcd_tile->numpix = 0;           /* fixed_quality */
465*3ac0a46fSAndroid Build Coastguard Worker 
466*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < tcd_tile->numcomps; compno++) {
467*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
468*3ac0a46fSAndroid Build Coastguard Worker         tilec->numpix = 0;
469*3ac0a46fSAndroid Build Coastguard Worker 
470*3ac0a46fSAndroid Build Coastguard Worker         for (resno = 0; resno < tilec->numresolutions; resno++) {
471*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_resolution_t *res = &tilec->resolutions[resno];
472*3ac0a46fSAndroid Build Coastguard Worker 
473*3ac0a46fSAndroid Build Coastguard Worker             for (bandno = 0; bandno < res->numbands; bandno++) {
474*3ac0a46fSAndroid Build Coastguard Worker                 opj_tcd_band_t *band = &res->bands[bandno];
475*3ac0a46fSAndroid Build Coastguard Worker 
476*3ac0a46fSAndroid Build Coastguard Worker                 /* Skip empty bands */
477*3ac0a46fSAndroid Build Coastguard Worker                 if (opj_tcd_is_band_empty(band)) {
478*3ac0a46fSAndroid Build Coastguard Worker                     continue;
479*3ac0a46fSAndroid Build Coastguard Worker                 }
480*3ac0a46fSAndroid Build Coastguard Worker 
481*3ac0a46fSAndroid Build Coastguard Worker                 for (precno = 0; precno < res->pw * res->ph; precno++) {
482*3ac0a46fSAndroid Build Coastguard Worker                     opj_tcd_precinct_t *prc = &band->precincts[precno];
483*3ac0a46fSAndroid Build Coastguard Worker 
484*3ac0a46fSAndroid Build Coastguard Worker                     for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
485*3ac0a46fSAndroid Build Coastguard Worker                         opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
486*3ac0a46fSAndroid Build Coastguard Worker 
487*3ac0a46fSAndroid Build Coastguard Worker                         for (passno = 0; passno < cblk->totalpasses; passno++) {
488*3ac0a46fSAndroid Build Coastguard Worker                             opj_tcd_pass_t *pass = &cblk->passes[passno];
489*3ac0a46fSAndroid Build Coastguard Worker                             OPJ_INT32 dr;
490*3ac0a46fSAndroid Build Coastguard Worker                             OPJ_FLOAT64 dd, rdslope;
491*3ac0a46fSAndroid Build Coastguard Worker 
492*3ac0a46fSAndroid Build Coastguard Worker                             if (passno == 0) {
493*3ac0a46fSAndroid Build Coastguard Worker                                 dr = (OPJ_INT32)pass->rate;
494*3ac0a46fSAndroid Build Coastguard Worker                                 dd = pass->distortiondec;
495*3ac0a46fSAndroid Build Coastguard Worker                             } else {
496*3ac0a46fSAndroid Build Coastguard Worker                                 dr = (OPJ_INT32)(pass->rate - cblk->passes[passno - 1].rate);
497*3ac0a46fSAndroid Build Coastguard Worker                                 dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec;
498*3ac0a46fSAndroid Build Coastguard Worker                             }
499*3ac0a46fSAndroid Build Coastguard Worker 
500*3ac0a46fSAndroid Build Coastguard Worker                             if (dr == 0) {
501*3ac0a46fSAndroid Build Coastguard Worker                                 continue;
502*3ac0a46fSAndroid Build Coastguard Worker                             }
503*3ac0a46fSAndroid Build Coastguard Worker 
504*3ac0a46fSAndroid Build Coastguard Worker                             rdslope = dd / dr;
505*3ac0a46fSAndroid Build Coastguard Worker                             if (rdslope < min) {
506*3ac0a46fSAndroid Build Coastguard Worker                                 min = rdslope;
507*3ac0a46fSAndroid Build Coastguard Worker                             }
508*3ac0a46fSAndroid Build Coastguard Worker 
509*3ac0a46fSAndroid Build Coastguard Worker                             if (rdslope > max) {
510*3ac0a46fSAndroid Build Coastguard Worker                                 max = rdslope;
511*3ac0a46fSAndroid Build Coastguard Worker                             }
512*3ac0a46fSAndroid Build Coastguard Worker                         } /* passno */
513*3ac0a46fSAndroid Build Coastguard Worker 
514*3ac0a46fSAndroid Build Coastguard Worker                         /* fixed_quality */
515*3ac0a46fSAndroid Build Coastguard Worker                         tcd_tile->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
516*3ac0a46fSAndroid Build Coastguard Worker                         tilec->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
517*3ac0a46fSAndroid Build Coastguard Worker                     } /* cbklno */
518*3ac0a46fSAndroid Build Coastguard Worker                 } /* precno */
519*3ac0a46fSAndroid Build Coastguard Worker             } /* bandno */
520*3ac0a46fSAndroid Build Coastguard Worker         } /* resno */
521*3ac0a46fSAndroid Build Coastguard Worker 
522*3ac0a46fSAndroid Build Coastguard Worker         maxSE += (((OPJ_FLOAT64)(1 << tcd->image->comps[compno].prec) - 1.0)
523*3ac0a46fSAndroid Build Coastguard Worker                   * ((OPJ_FLOAT64)(1 << tcd->image->comps[compno].prec) - 1.0))
524*3ac0a46fSAndroid Build Coastguard Worker                  * ((OPJ_FLOAT64)(tilec->numpix));
525*3ac0a46fSAndroid Build Coastguard Worker     } /* compno */
526*3ac0a46fSAndroid Build Coastguard Worker 
527*3ac0a46fSAndroid Build Coastguard Worker     /* index file */
528*3ac0a46fSAndroid Build Coastguard Worker     if (cstr_info) {
529*3ac0a46fSAndroid Build Coastguard Worker         opj_tile_info_t *tile_info = &cstr_info->tile[tcd->tcd_tileno];
530*3ac0a46fSAndroid Build Coastguard Worker         tile_info->numpix = tcd_tile->numpix;
531*3ac0a46fSAndroid Build Coastguard Worker         tile_info->distotile = tcd_tile->distotile;
532*3ac0a46fSAndroid Build Coastguard Worker         tile_info->thresh = (OPJ_FLOAT64 *) opj_malloc(tcd_tcp->numlayers * sizeof(
533*3ac0a46fSAndroid Build Coastguard Worker                                 OPJ_FLOAT64));
534*3ac0a46fSAndroid Build Coastguard Worker         if (!tile_info->thresh) {
535*3ac0a46fSAndroid Build Coastguard Worker             /* FIXME event manager error callback */
536*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
537*3ac0a46fSAndroid Build Coastguard Worker         }
538*3ac0a46fSAndroid Build Coastguard Worker     }
539*3ac0a46fSAndroid Build Coastguard Worker 
540*3ac0a46fSAndroid Build Coastguard Worker     for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
541*3ac0a46fSAndroid Build Coastguard Worker         OPJ_FLOAT64 lo = min;
542*3ac0a46fSAndroid Build Coastguard Worker         OPJ_FLOAT64 hi = max;
543*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 maxlen = tcd_tcp->rates[layno] > 0.0f ? opj_uint_min(((
544*3ac0a46fSAndroid Build Coastguard Worker                                 OPJ_UINT32) ceil(tcd_tcp->rates[layno])), len) : len;
545*3ac0a46fSAndroid Build Coastguard Worker         OPJ_FLOAT64 goodthresh = 0;
546*3ac0a46fSAndroid Build Coastguard Worker         OPJ_FLOAT64 stable_thresh = 0;
547*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 i;
548*3ac0a46fSAndroid Build Coastguard Worker         OPJ_FLOAT64 distotarget;                /* fixed_quality */
549*3ac0a46fSAndroid Build Coastguard Worker 
550*3ac0a46fSAndroid Build Coastguard Worker         /* fixed_quality */
551*3ac0a46fSAndroid Build Coastguard Worker         distotarget = tcd_tile->distotile - ((K * maxSE) / pow((OPJ_FLOAT32)10,
552*3ac0a46fSAndroid Build Coastguard Worker                                              tcd_tcp->distoratio[layno] / 10));
553*3ac0a46fSAndroid Build Coastguard Worker 
554*3ac0a46fSAndroid Build Coastguard Worker         /* Don't try to find an optimal threshold but rather take everything not included yet, if
555*3ac0a46fSAndroid Build Coastguard Worker           -r xx,yy,zz,0   (disto_alloc == 1 and rates == 0)
556*3ac0a46fSAndroid Build Coastguard Worker           -q xx,yy,zz,0   (fixed_quality == 1 and distoratio == 0)
557*3ac0a46fSAndroid Build Coastguard Worker           ==> possible to have some lossy layers and the last layer for sure lossless */
558*3ac0a46fSAndroid Build Coastguard Worker         if (((cp->m_specific_param.m_enc.m_disto_alloc == 1) &&
559*3ac0a46fSAndroid Build Coastguard Worker                 (tcd_tcp->rates[layno] > 0.0f)) ||
560*3ac0a46fSAndroid Build Coastguard Worker                 ((cp->m_specific_param.m_enc.m_fixed_quality == 1) &&
561*3ac0a46fSAndroid Build Coastguard Worker                  (tcd_tcp->distoratio[layno] > 0.0))) {
562*3ac0a46fSAndroid Build Coastguard Worker             opj_t2_t*t2 = opj_t2_create(tcd->image, cp);
563*3ac0a46fSAndroid Build Coastguard Worker             OPJ_FLOAT64 thresh = 0;
564*3ac0a46fSAndroid Build Coastguard Worker 
565*3ac0a46fSAndroid Build Coastguard Worker             if (t2 == 00) {
566*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
567*3ac0a46fSAndroid Build Coastguard Worker             }
568*3ac0a46fSAndroid Build Coastguard Worker 
569*3ac0a46fSAndroid Build Coastguard Worker             for (i = 0; i < 128; ++i) {
570*3ac0a46fSAndroid Build Coastguard Worker                 OPJ_FLOAT64 distoachieved = 0;  /* fixed_quality */
571*3ac0a46fSAndroid Build Coastguard Worker 
572*3ac0a46fSAndroid Build Coastguard Worker                 thresh = (lo + hi) / 2;
573*3ac0a46fSAndroid Build Coastguard Worker 
574*3ac0a46fSAndroid Build Coastguard Worker                 opj_tcd_makelayer(tcd, layno, thresh, 0);
575*3ac0a46fSAndroid Build Coastguard Worker 
576*3ac0a46fSAndroid Build Coastguard Worker                 if (cp->m_specific_param.m_enc.m_fixed_quality) {       /* fixed_quality */
577*3ac0a46fSAndroid Build Coastguard Worker                     if (OPJ_IS_CINEMA(cp->rsiz) || OPJ_IS_IMF(cp->rsiz)) {
578*3ac0a46fSAndroid Build Coastguard Worker                         if (! opj_t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest,
579*3ac0a46fSAndroid Build Coastguard Worker                                                     p_data_written, maxlen, cstr_info, NULL, tcd->cur_tp_num, tcd->tp_pos,
580*3ac0a46fSAndroid Build Coastguard Worker                                                     tcd->cur_pino,
581*3ac0a46fSAndroid Build Coastguard Worker                                                     THRESH_CALC, p_manager)) {
582*3ac0a46fSAndroid Build Coastguard Worker 
583*3ac0a46fSAndroid Build Coastguard Worker                             lo = thresh;
584*3ac0a46fSAndroid Build Coastguard Worker                             continue;
585*3ac0a46fSAndroid Build Coastguard Worker                         } else {
586*3ac0a46fSAndroid Build Coastguard Worker                             distoachieved = layno == 0 ?
587*3ac0a46fSAndroid Build Coastguard Worker                                             tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];
588*3ac0a46fSAndroid Build Coastguard Worker 
589*3ac0a46fSAndroid Build Coastguard Worker                             if (distoachieved < distotarget) {
590*3ac0a46fSAndroid Build Coastguard Worker                                 hi = thresh;
591*3ac0a46fSAndroid Build Coastguard Worker                                 stable_thresh = thresh;
592*3ac0a46fSAndroid Build Coastguard Worker                                 continue;
593*3ac0a46fSAndroid Build Coastguard Worker                             } else {
594*3ac0a46fSAndroid Build Coastguard Worker                                 lo = thresh;
595*3ac0a46fSAndroid Build Coastguard Worker                             }
596*3ac0a46fSAndroid Build Coastguard Worker                         }
597*3ac0a46fSAndroid Build Coastguard Worker                     } else {
598*3ac0a46fSAndroid Build Coastguard Worker                         distoachieved = (layno == 0) ?
599*3ac0a46fSAndroid Build Coastguard Worker                                         tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
600*3ac0a46fSAndroid Build Coastguard Worker 
601*3ac0a46fSAndroid Build Coastguard Worker                         if (distoachieved < distotarget) {
602*3ac0a46fSAndroid Build Coastguard Worker                             hi = thresh;
603*3ac0a46fSAndroid Build Coastguard Worker                             stable_thresh = thresh;
604*3ac0a46fSAndroid Build Coastguard Worker                             continue;
605*3ac0a46fSAndroid Build Coastguard Worker                         }
606*3ac0a46fSAndroid Build Coastguard Worker                         lo = thresh;
607*3ac0a46fSAndroid Build Coastguard Worker                     }
608*3ac0a46fSAndroid Build Coastguard Worker                 } else {
609*3ac0a46fSAndroid Build Coastguard Worker                     if (! opj_t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest,
610*3ac0a46fSAndroid Build Coastguard Worker                                                 p_data_written, maxlen, cstr_info, NULL, tcd->cur_tp_num, tcd->tp_pos,
611*3ac0a46fSAndroid Build Coastguard Worker                                                 tcd->cur_pino,
612*3ac0a46fSAndroid Build Coastguard Worker                                                 THRESH_CALC, p_manager)) {
613*3ac0a46fSAndroid Build Coastguard Worker                         /* TODO: what to do with l ??? seek / tell ??? */
614*3ac0a46fSAndroid Build Coastguard Worker                         /* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */
615*3ac0a46fSAndroid Build Coastguard Worker                         lo = thresh;
616*3ac0a46fSAndroid Build Coastguard Worker                         continue;
617*3ac0a46fSAndroid Build Coastguard Worker                     }
618*3ac0a46fSAndroid Build Coastguard Worker 
619*3ac0a46fSAndroid Build Coastguard Worker                     hi = thresh;
620*3ac0a46fSAndroid Build Coastguard Worker                     stable_thresh = thresh;
621*3ac0a46fSAndroid Build Coastguard Worker                 }
622*3ac0a46fSAndroid Build Coastguard Worker             }
623*3ac0a46fSAndroid Build Coastguard Worker 
624*3ac0a46fSAndroid Build Coastguard Worker             goodthresh = stable_thresh == 0 ? thresh : stable_thresh;
625*3ac0a46fSAndroid Build Coastguard Worker 
626*3ac0a46fSAndroid Build Coastguard Worker             opj_t2_destroy(t2);
627*3ac0a46fSAndroid Build Coastguard Worker         } else {
628*3ac0a46fSAndroid Build Coastguard Worker             /* Special value to indicate to use all passes */
629*3ac0a46fSAndroid Build Coastguard Worker             goodthresh = -1;
630*3ac0a46fSAndroid Build Coastguard Worker         }
631*3ac0a46fSAndroid Build Coastguard Worker 
632*3ac0a46fSAndroid Build Coastguard Worker         if (cstr_info) { /* Threshold for Marcela Index */
633*3ac0a46fSAndroid Build Coastguard Worker             cstr_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh;
634*3ac0a46fSAndroid Build Coastguard Worker         }
635*3ac0a46fSAndroid Build Coastguard Worker 
636*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_makelayer(tcd, layno, goodthresh, 1);
637*3ac0a46fSAndroid Build Coastguard Worker 
638*3ac0a46fSAndroid Build Coastguard Worker         /* fixed_quality */
639*3ac0a46fSAndroid Build Coastguard Worker         cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] :
640*3ac0a46fSAndroid Build Coastguard Worker                           (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
641*3ac0a46fSAndroid Build Coastguard Worker     }
642*3ac0a46fSAndroid Build Coastguard Worker 
643*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
644*3ac0a46fSAndroid Build Coastguard Worker }
645*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_init(opj_tcd_t * p_tcd,opj_image_t * p_image,opj_cp_t * p_cp,opj_thread_pool_t * p_tp)646*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_tcd_init(opj_tcd_t *p_tcd,
647*3ac0a46fSAndroid Build Coastguard Worker                       opj_image_t * p_image,
648*3ac0a46fSAndroid Build Coastguard Worker                       opj_cp_t * p_cp,
649*3ac0a46fSAndroid Build Coastguard Worker                       opj_thread_pool_t* p_tp)
650*3ac0a46fSAndroid Build Coastguard Worker {
651*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->image = p_image;
652*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->cp = p_cp;
653*3ac0a46fSAndroid Build Coastguard Worker 
654*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_calloc(1,
655*3ac0a46fSAndroid Build Coastguard Worker                               sizeof(opj_tcd_tile_t));
656*3ac0a46fSAndroid Build Coastguard Worker     if (! p_tcd->tcd_image->tiles) {
657*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
658*3ac0a46fSAndroid Build Coastguard Worker     }
659*3ac0a46fSAndroid Build Coastguard Worker 
660*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->tcd_image->tiles->comps = (opj_tcd_tilecomp_t *) opj_calloc(
661*3ac0a46fSAndroid Build Coastguard Worker                                          p_image->numcomps, sizeof(opj_tcd_tilecomp_t));
662*3ac0a46fSAndroid Build Coastguard Worker     if (! p_tcd->tcd_image->tiles->comps) {
663*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
664*3ac0a46fSAndroid Build Coastguard Worker     }
665*3ac0a46fSAndroid Build Coastguard Worker 
666*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->tcd_image->tiles->numcomps = p_image->numcomps;
667*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->tp_pos = p_cp->m_specific_param.m_enc.m_tp_pos;
668*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->thread_pool = p_tp;
669*3ac0a46fSAndroid Build Coastguard Worker 
670*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
671*3ac0a46fSAndroid Build Coastguard Worker }
672*3ac0a46fSAndroid Build Coastguard Worker 
673*3ac0a46fSAndroid Build Coastguard Worker /**
674*3ac0a46fSAndroid Build Coastguard Worker Destroy a previously created TCD handle
675*3ac0a46fSAndroid Build Coastguard Worker */
opj_tcd_destroy(opj_tcd_t * tcd)676*3ac0a46fSAndroid Build Coastguard Worker void opj_tcd_destroy(opj_tcd_t *tcd)
677*3ac0a46fSAndroid Build Coastguard Worker {
678*3ac0a46fSAndroid Build Coastguard Worker     if (tcd) {
679*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_free_tile(tcd);
680*3ac0a46fSAndroid Build Coastguard Worker 
681*3ac0a46fSAndroid Build Coastguard Worker         if (tcd->tcd_image) {
682*3ac0a46fSAndroid Build Coastguard Worker             opj_free(tcd->tcd_image);
683*3ac0a46fSAndroid Build Coastguard Worker             tcd->tcd_image = 00;
684*3ac0a46fSAndroid Build Coastguard Worker         }
685*3ac0a46fSAndroid Build Coastguard Worker 
686*3ac0a46fSAndroid Build Coastguard Worker         opj_free(tcd->used_component);
687*3ac0a46fSAndroid Build Coastguard Worker 
688*3ac0a46fSAndroid Build Coastguard Worker         opj_free(tcd);
689*3ac0a46fSAndroid Build Coastguard Worker     }
690*3ac0a46fSAndroid Build Coastguard Worker }
691*3ac0a46fSAndroid Build Coastguard Worker 
opj_alloc_tile_component_data(opj_tcd_tilecomp_t * l_tilec)692*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec)
693*3ac0a46fSAndroid Build Coastguard Worker {
694*3ac0a46fSAndroid Build Coastguard Worker     if ((l_tilec->data == 00) ||
695*3ac0a46fSAndroid Build Coastguard Worker             ((l_tilec->data_size_needed > l_tilec->data_size) &&
696*3ac0a46fSAndroid Build Coastguard Worker              (l_tilec->ownsData == OPJ_FALSE))) {
697*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->data = (OPJ_INT32 *) opj_image_data_alloc(l_tilec->data_size_needed);
698*3ac0a46fSAndroid Build Coastguard Worker         if (!l_tilec->data && l_tilec->data_size_needed != 0) {
699*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
700*3ac0a46fSAndroid Build Coastguard Worker         }
701*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr, "tAllocate data of tilec (int): %d x OPJ_UINT32n",l_data_size);*/
702*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->data_size = l_tilec->data_size_needed;
703*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->ownsData = OPJ_TRUE;
704*3ac0a46fSAndroid Build Coastguard Worker     } else if (l_tilec->data_size_needed > l_tilec->data_size) {
705*3ac0a46fSAndroid Build Coastguard Worker         /* We don't need to keep old data */
706*3ac0a46fSAndroid Build Coastguard Worker         opj_image_data_free(l_tilec->data);
707*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->data = (OPJ_INT32 *) opj_image_data_alloc(l_tilec->data_size_needed);
708*3ac0a46fSAndroid Build Coastguard Worker         if (! l_tilec->data) {
709*3ac0a46fSAndroid Build Coastguard Worker             l_tilec->data_size = 0;
710*3ac0a46fSAndroid Build Coastguard Worker             l_tilec->data_size_needed = 0;
711*3ac0a46fSAndroid Build Coastguard Worker             l_tilec->ownsData = OPJ_FALSE;
712*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
713*3ac0a46fSAndroid Build Coastguard Worker         }
714*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr, "tReallocate data of tilec (int): from %d to %d x OPJ_UINT32n", l_tilec->data_size, l_data_size);*/
715*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->data_size = l_tilec->data_size_needed;
716*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->ownsData = OPJ_TRUE;
717*3ac0a46fSAndroid Build Coastguard Worker     }
718*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
719*3ac0a46fSAndroid Build Coastguard Worker }
720*3ac0a46fSAndroid Build Coastguard Worker 
721*3ac0a46fSAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
722*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_init_tile(opj_tcd_t * p_tcd,OPJ_UINT32 p_tile_no,OPJ_BOOL isEncoder,OPJ_SIZE_T sizeof_block,opj_event_mgr_t * manager)723*3ac0a46fSAndroid Build Coastguard Worker static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
724*3ac0a46fSAndroid Build Coastguard Worker         OPJ_BOOL isEncoder, OPJ_SIZE_T sizeof_block,
725*3ac0a46fSAndroid Build Coastguard Worker         opj_event_mgr_t* manager)
726*3ac0a46fSAndroid Build Coastguard Worker {
727*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno, resno, bandno, precno, cblkno;
728*3ac0a46fSAndroid Build Coastguard Worker     opj_tcp_t * l_tcp = 00;
729*3ac0a46fSAndroid Build Coastguard Worker     opj_cp_t * l_cp = 00;
730*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t * l_tile = 00;
731*3ac0a46fSAndroid Build Coastguard Worker     opj_tccp_t *l_tccp = 00;
732*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t *l_tilec = 00;
733*3ac0a46fSAndroid Build Coastguard Worker     opj_image_comp_t * l_image_comp = 00;
734*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_resolution_t *l_res = 00;
735*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_band_t *l_band = 00;
736*3ac0a46fSAndroid Build Coastguard Worker     opj_stepsize_t * l_step_size = 00;
737*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_precinct_t *l_current_precinct = 00;
738*3ac0a46fSAndroid Build Coastguard Worker     opj_image_t *l_image = 00;
739*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 p, q;
740*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_level_no;
741*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_pdx, l_pdy;
742*3ac0a46fSAndroid Build Coastguard Worker     OPJ_INT32 l_x0b, l_y0b;
743*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_tx0, l_ty0;
744*3ac0a46fSAndroid Build Coastguard Worker     /* extent of precincts , top left, bottom right**/
745*3ac0a46fSAndroid Build Coastguard Worker     OPJ_INT32 l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end, l_br_prc_y_end;
746*3ac0a46fSAndroid Build Coastguard Worker     /* number of precinct for a resolution */
747*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_nb_precincts;
748*3ac0a46fSAndroid Build Coastguard Worker     /* room needed to store l_nb_precinct precinct for a resolution */
749*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_nb_precinct_size;
750*3ac0a46fSAndroid Build Coastguard Worker     /* number of code blocks for a precinct*/
751*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_nb_code_blocks;
752*3ac0a46fSAndroid Build Coastguard Worker     /* room needed to store l_nb_code_blocks code blocks for a precinct*/
753*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_nb_code_blocks_size;
754*3ac0a46fSAndroid Build Coastguard Worker     /* size of data for a tile */
755*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_data_size;
756*3ac0a46fSAndroid Build Coastguard Worker 
757*3ac0a46fSAndroid Build Coastguard Worker     l_cp = p_tcd->cp;
758*3ac0a46fSAndroid Build Coastguard Worker     l_tcp = &(l_cp->tcps[p_tile_no]);
759*3ac0a46fSAndroid Build Coastguard Worker     l_tile = p_tcd->tcd_image->tiles;
760*3ac0a46fSAndroid Build Coastguard Worker     l_tccp = l_tcp->tccps;
761*3ac0a46fSAndroid Build Coastguard Worker     l_tilec = l_tile->comps;
762*3ac0a46fSAndroid Build Coastguard Worker     l_image = p_tcd->image;
763*3ac0a46fSAndroid Build Coastguard Worker     l_image_comp = p_tcd->image->comps;
764*3ac0a46fSAndroid Build Coastguard Worker 
765*3ac0a46fSAndroid Build Coastguard Worker     p = p_tile_no % l_cp->tw;       /* tile coordinates */
766*3ac0a46fSAndroid Build Coastguard Worker     q = p_tile_no / l_cp->tw;
767*3ac0a46fSAndroid Build Coastguard Worker     /*fprintf(stderr, "Tile coordinate = %d,%d\n", p, q);*/
768*3ac0a46fSAndroid Build Coastguard Worker 
769*3ac0a46fSAndroid Build Coastguard Worker     /* 4 borders of the tile rescale on the image if necessary */
770*3ac0a46fSAndroid Build Coastguard Worker     l_tx0 = l_cp->tx0 + p *
771*3ac0a46fSAndroid Build Coastguard Worker             l_cp->tdx; /* can't be greater than l_image->x1 so won't overflow */
772*3ac0a46fSAndroid Build Coastguard Worker     l_tile->x0 = (OPJ_INT32)opj_uint_max(l_tx0, l_image->x0);
773*3ac0a46fSAndroid Build Coastguard Worker     l_tile->x1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_tx0, l_cp->tdx),
774*3ac0a46fSAndroid Build Coastguard Worker                                          l_image->x1);
775*3ac0a46fSAndroid Build Coastguard Worker     /* all those OPJ_UINT32 are casted to OPJ_INT32, let's do some sanity check */
776*3ac0a46fSAndroid Build Coastguard Worker     if ((l_tile->x0 < 0) || (l_tile->x1 <= l_tile->x0)) {
777*3ac0a46fSAndroid Build Coastguard Worker         opj_event_msg(manager, EVT_ERROR, "Tile X coordinates are not supported\n");
778*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
779*3ac0a46fSAndroid Build Coastguard Worker     }
780*3ac0a46fSAndroid Build Coastguard Worker     l_ty0 = l_cp->ty0 + q *
781*3ac0a46fSAndroid Build Coastguard Worker             l_cp->tdy; /* can't be greater than l_image->y1 so won't overflow */
782*3ac0a46fSAndroid Build Coastguard Worker     l_tile->y0 = (OPJ_INT32)opj_uint_max(l_ty0, l_image->y0);
783*3ac0a46fSAndroid Build Coastguard Worker     l_tile->y1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_ty0, l_cp->tdy),
784*3ac0a46fSAndroid Build Coastguard Worker                                          l_image->y1);
785*3ac0a46fSAndroid Build Coastguard Worker     /* all those OPJ_UINT32 are casted to OPJ_INT32, let's do some sanity check */
786*3ac0a46fSAndroid Build Coastguard Worker     if ((l_tile->y0 < 0) || (l_tile->y1 <= l_tile->y0)) {
787*3ac0a46fSAndroid Build Coastguard Worker         opj_event_msg(manager, EVT_ERROR, "Tile Y coordinates are not supported\n");
788*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
789*3ac0a46fSAndroid Build Coastguard Worker     }
790*3ac0a46fSAndroid Build Coastguard Worker 
791*3ac0a46fSAndroid Build Coastguard Worker 
792*3ac0a46fSAndroid Build Coastguard Worker     /* testcase 1888.pdf.asan.35.988 */
793*3ac0a46fSAndroid Build Coastguard Worker     if (l_tccp->numresolutions == 0) {
794*3ac0a46fSAndroid Build Coastguard Worker         opj_event_msg(manager, EVT_ERROR, "tiles require at least one resolution\n");
795*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
796*3ac0a46fSAndroid Build Coastguard Worker     }
797*3ac0a46fSAndroid Build Coastguard Worker     /*fprintf(stderr, "Tile border = %d,%d,%d,%d\n", l_tile->x0, l_tile->y0,l_tile->x1,l_tile->y1);*/
798*3ac0a46fSAndroid Build Coastguard Worker 
799*3ac0a46fSAndroid Build Coastguard Worker     /*tile->numcomps = image->numcomps; */
800*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < l_tile->numcomps; ++compno) {
801*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr, "compno = %d/%d\n", compno, l_tile->numcomps);*/
802*3ac0a46fSAndroid Build Coastguard Worker         l_image_comp->resno_decoded = 0;
803*3ac0a46fSAndroid Build Coastguard Worker         /* border of each l_tile component (global) */
804*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->x0 = opj_int_ceildiv(l_tile->x0, (OPJ_INT32)l_image_comp->dx);
805*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->y0 = opj_int_ceildiv(l_tile->y0, (OPJ_INT32)l_image_comp->dy);
806*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->x1 = opj_int_ceildiv(l_tile->x1, (OPJ_INT32)l_image_comp->dx);
807*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->y1 = opj_int_ceildiv(l_tile->y1, (OPJ_INT32)l_image_comp->dy);
808*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->compno = compno;
809*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr, "\tTile compo border = %d,%d,%d,%d\n", l_tilec->x0, l_tilec->y0,l_tilec->x1,l_tilec->y1);*/
810*3ac0a46fSAndroid Build Coastguard Worker 
811*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->numresolutions = l_tccp->numresolutions;
812*3ac0a46fSAndroid Build Coastguard Worker         if (l_tccp->numresolutions < l_cp->m_specific_param.m_dec.m_reduce) {
813*3ac0a46fSAndroid Build Coastguard Worker             l_tilec->minimum_num_resolutions = 1;
814*3ac0a46fSAndroid Build Coastguard Worker         } else {
815*3ac0a46fSAndroid Build Coastguard Worker             l_tilec->minimum_num_resolutions = l_tccp->numresolutions -
816*3ac0a46fSAndroid Build Coastguard Worker                                                l_cp->m_specific_param.m_dec.m_reduce;
817*3ac0a46fSAndroid Build Coastguard Worker         }
818*3ac0a46fSAndroid Build Coastguard Worker 
819*3ac0a46fSAndroid Build Coastguard Worker         if (isEncoder) {
820*3ac0a46fSAndroid Build Coastguard Worker             OPJ_SIZE_T l_tile_data_size;
821*3ac0a46fSAndroid Build Coastguard Worker 
822*3ac0a46fSAndroid Build Coastguard Worker             if (l_tilec->x0 >= l_tilec->x1 || l_tilec->y0 >= l_tilec->y1) {
823*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(manager, EVT_ERROR, "Invalid tile data\n");
824*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
825*3ac0a46fSAndroid Build Coastguard Worker             }
826*3ac0a46fSAndroid Build Coastguard Worker 
827*3ac0a46fSAndroid Build Coastguard Worker             /* compute l_data_size with overflow check */
828*3ac0a46fSAndroid Build Coastguard Worker             OPJ_SIZE_T w = (OPJ_SIZE_T)(l_tilec->x1 - l_tilec->x0);
829*3ac0a46fSAndroid Build Coastguard Worker             OPJ_SIZE_T h = (OPJ_SIZE_T)(l_tilec->y1 - l_tilec->y0);
830*3ac0a46fSAndroid Build Coastguard Worker 
831*3ac0a46fSAndroid Build Coastguard Worker             /* issue 733, l_data_size == 0U, probably something wrong should be checked before getting here */
832*3ac0a46fSAndroid Build Coastguard Worker             if (h > 0 && w > SIZE_MAX / h) {
833*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(manager, EVT_ERROR, "Size of tile data exceeds system limits\n");
834*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
835*3ac0a46fSAndroid Build Coastguard Worker             }
836*3ac0a46fSAndroid Build Coastguard Worker             l_tile_data_size = w * h;
837*3ac0a46fSAndroid Build Coastguard Worker 
838*3ac0a46fSAndroid Build Coastguard Worker             if (SIZE_MAX / sizeof(OPJ_UINT32) < l_tile_data_size) {
839*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(manager, EVT_ERROR, "Size of tile data exceeds system limits\n");
840*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
841*3ac0a46fSAndroid Build Coastguard Worker             }
842*3ac0a46fSAndroid Build Coastguard Worker             l_tile_data_size = l_tile_data_size * sizeof(OPJ_UINT32);
843*3ac0a46fSAndroid Build Coastguard Worker 
844*3ac0a46fSAndroid Build Coastguard Worker             l_tilec->data_size_needed = l_tile_data_size;
845*3ac0a46fSAndroid Build Coastguard Worker         }
846*3ac0a46fSAndroid Build Coastguard Worker 
847*3ac0a46fSAndroid Build Coastguard Worker         l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(
848*3ac0a46fSAndroid Build Coastguard Worker                           opj_tcd_resolution_t);
849*3ac0a46fSAndroid Build Coastguard Worker 
850*3ac0a46fSAndroid Build Coastguard Worker         opj_image_data_free(l_tilec->data_win);
851*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->data_win = NULL;
852*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->win_x0 = 0;
853*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->win_y0 = 0;
854*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->win_x1 = 0;
855*3ac0a46fSAndroid Build Coastguard Worker         l_tilec->win_y1 = 0;
856*3ac0a46fSAndroid Build Coastguard Worker 
857*3ac0a46fSAndroid Build Coastguard Worker         if (l_tilec->resolutions == 00) {
858*3ac0a46fSAndroid Build Coastguard Worker             l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size);
859*3ac0a46fSAndroid Build Coastguard Worker             if (! l_tilec->resolutions) {
860*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
861*3ac0a46fSAndroid Build Coastguard Worker             }
862*3ac0a46fSAndroid Build Coastguard Worker             /*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %d\n",l_data_size);*/
863*3ac0a46fSAndroid Build Coastguard Worker             l_tilec->resolutions_size = l_data_size;
864*3ac0a46fSAndroid Build Coastguard Worker             memset(l_tilec->resolutions, 0, l_data_size);
865*3ac0a46fSAndroid Build Coastguard Worker         } else if (l_data_size > l_tilec->resolutions_size) {
866*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_resolution_t* new_resolutions = (opj_tcd_resolution_t *) opj_realloc(
867*3ac0a46fSAndroid Build Coastguard Worker                     l_tilec->resolutions, l_data_size);
868*3ac0a46fSAndroid Build Coastguard Worker             if (! new_resolutions) {
869*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile resolutions\n");
870*3ac0a46fSAndroid Build Coastguard Worker                 opj_free(l_tilec->resolutions);
871*3ac0a46fSAndroid Build Coastguard Worker                 l_tilec->resolutions = NULL;
872*3ac0a46fSAndroid Build Coastguard Worker                 l_tilec->resolutions_size = 0;
873*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
874*3ac0a46fSAndroid Build Coastguard Worker             }
875*3ac0a46fSAndroid Build Coastguard Worker             l_tilec->resolutions = new_resolutions;
876*3ac0a46fSAndroid Build Coastguard Worker             /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/
877*3ac0a46fSAndroid Build Coastguard Worker             memset(((OPJ_BYTE*) l_tilec->resolutions) + l_tilec->resolutions_size, 0,
878*3ac0a46fSAndroid Build Coastguard Worker                    l_data_size - l_tilec->resolutions_size);
879*3ac0a46fSAndroid Build Coastguard Worker             l_tilec->resolutions_size = l_data_size;
880*3ac0a46fSAndroid Build Coastguard Worker         }
881*3ac0a46fSAndroid Build Coastguard Worker 
882*3ac0a46fSAndroid Build Coastguard Worker         l_level_no = l_tilec->numresolutions;
883*3ac0a46fSAndroid Build Coastguard Worker         l_res = l_tilec->resolutions;
884*3ac0a46fSAndroid Build Coastguard Worker         l_step_size = l_tccp->stepsizes;
885*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr, "\tlevel_no=%d\n",l_level_no);*/
886*3ac0a46fSAndroid Build Coastguard Worker 
887*3ac0a46fSAndroid Build Coastguard Worker         for (resno = 0; resno < l_tilec->numresolutions; ++resno) {
888*3ac0a46fSAndroid Build Coastguard Worker             /*fprintf(stderr, "\t\tresno = %d/%d\n", resno, l_tilec->numresolutions);*/
889*3ac0a46fSAndroid Build Coastguard Worker             OPJ_INT32 tlcbgxstart, tlcbgystart /*, brcbgxend, brcbgyend*/;
890*3ac0a46fSAndroid Build Coastguard Worker             OPJ_UINT32 cbgwidthexpn, cbgheightexpn;
891*3ac0a46fSAndroid Build Coastguard Worker             OPJ_UINT32 cblkwidthexpn, cblkheightexpn;
892*3ac0a46fSAndroid Build Coastguard Worker 
893*3ac0a46fSAndroid Build Coastguard Worker             --l_level_no;
894*3ac0a46fSAndroid Build Coastguard Worker 
895*3ac0a46fSAndroid Build Coastguard Worker             /* border for each resolution level (global) */
896*3ac0a46fSAndroid Build Coastguard Worker             l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no);
897*3ac0a46fSAndroid Build Coastguard Worker             l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no);
898*3ac0a46fSAndroid Build Coastguard Worker             l_res->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no);
899*3ac0a46fSAndroid Build Coastguard Worker             l_res->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no);
900*3ac0a46fSAndroid Build Coastguard Worker 
901*3ac0a46fSAndroid Build Coastguard Worker             /*fprintf(stderr, "\t\t\tres_x0= %d, res_y0 =%d, res_x1=%d, res_y1=%d\n", l_res->x0, l_res->y0, l_res->x1, l_res->y1);*/
902*3ac0a46fSAndroid Build Coastguard Worker             /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */
903*3ac0a46fSAndroid Build Coastguard Worker             l_pdx = l_tccp->prcw[resno];
904*3ac0a46fSAndroid Build Coastguard Worker             l_pdy = l_tccp->prch[resno];
905*3ac0a46fSAndroid Build Coastguard Worker             /*fprintf(stderr, "\t\t\tpdx=%d, pdy=%d\n", l_pdx, l_pdy);*/
906*3ac0a46fSAndroid Build Coastguard Worker             /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)  */
907*3ac0a46fSAndroid Build Coastguard Worker             l_tl_prc_x_start = opj_int_floordivpow2(l_res->x0, (OPJ_INT32)l_pdx) << l_pdx;
908*3ac0a46fSAndroid Build Coastguard Worker             l_tl_prc_y_start = opj_int_floordivpow2(l_res->y0, (OPJ_INT32)l_pdy) << l_pdy;
909*3ac0a46fSAndroid Build Coastguard Worker             {
910*3ac0a46fSAndroid Build Coastguard Worker                 OPJ_UINT32 tmp = ((OPJ_UINT32)opj_int_ceildivpow2(l_res->x1,
911*3ac0a46fSAndroid Build Coastguard Worker                                   (OPJ_INT32)l_pdx)) << l_pdx;
912*3ac0a46fSAndroid Build Coastguard Worker                 if (tmp > (OPJ_UINT32)INT_MAX) {
913*3ac0a46fSAndroid Build Coastguard Worker                     opj_event_msg(manager, EVT_ERROR, "Integer overflow\n");
914*3ac0a46fSAndroid Build Coastguard Worker                     return OPJ_FALSE;
915*3ac0a46fSAndroid Build Coastguard Worker                 }
916*3ac0a46fSAndroid Build Coastguard Worker                 l_br_prc_x_end = (OPJ_INT32)tmp;
917*3ac0a46fSAndroid Build Coastguard Worker             }
918*3ac0a46fSAndroid Build Coastguard Worker             {
919*3ac0a46fSAndroid Build Coastguard Worker                 OPJ_UINT32 tmp = ((OPJ_UINT32)opj_int_ceildivpow2(l_res->y1,
920*3ac0a46fSAndroid Build Coastguard Worker                                   (OPJ_INT32)l_pdy)) << l_pdy;
921*3ac0a46fSAndroid Build Coastguard Worker                 if (tmp > (OPJ_UINT32)INT_MAX) {
922*3ac0a46fSAndroid Build Coastguard Worker                     opj_event_msg(manager, EVT_ERROR, "Integer overflow\n");
923*3ac0a46fSAndroid Build Coastguard Worker                     return OPJ_FALSE;
924*3ac0a46fSAndroid Build Coastguard Worker                 }
925*3ac0a46fSAndroid Build Coastguard Worker                 l_br_prc_y_end = (OPJ_INT32)tmp;
926*3ac0a46fSAndroid Build Coastguard Worker             }
927*3ac0a46fSAndroid Build Coastguard Worker             /*fprintf(stderr, "\t\t\tprc_x_start=%d, prc_y_start=%d, br_prc_x_end=%d, br_prc_y_end=%d \n", l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end ,l_br_prc_y_end );*/
928*3ac0a46fSAndroid Build Coastguard Worker 
929*3ac0a46fSAndroid Build Coastguard Worker             l_res->pw = (l_res->x0 == l_res->x1) ? 0U : (OPJ_UINT32)((
930*3ac0a46fSAndroid Build Coastguard Worker                             l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx);
931*3ac0a46fSAndroid Build Coastguard Worker             l_res->ph = (l_res->y0 == l_res->y1) ? 0U : (OPJ_UINT32)((
932*3ac0a46fSAndroid Build Coastguard Worker                             l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy);
933*3ac0a46fSAndroid Build Coastguard Worker             /*fprintf(stderr, "\t\t\tres_pw=%d, res_ph=%d\n", l_res->pw, l_res->ph );*/
934*3ac0a46fSAndroid Build Coastguard Worker 
935*3ac0a46fSAndroid Build Coastguard Worker             if ((l_res->pw != 0U) && ((((OPJ_UINT32) - 1) / l_res->pw) < l_res->ph)) {
936*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(manager, EVT_ERROR, "Size of tile data exceeds system limits\n");
937*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
938*3ac0a46fSAndroid Build Coastguard Worker             }
939*3ac0a46fSAndroid Build Coastguard Worker             l_nb_precincts = l_res->pw * l_res->ph;
940*3ac0a46fSAndroid Build Coastguard Worker 
941*3ac0a46fSAndroid Build Coastguard Worker             if ((((OPJ_UINT32) - 1) / (OPJ_UINT32)sizeof(opj_tcd_precinct_t)) <
942*3ac0a46fSAndroid Build Coastguard Worker                     l_nb_precincts) {
943*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(manager, EVT_ERROR, "Size of tile data exceeds system limits\n");
944*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
945*3ac0a46fSAndroid Build Coastguard Worker             }
946*3ac0a46fSAndroid Build Coastguard Worker             l_nb_precinct_size = l_nb_precincts * (OPJ_UINT32)sizeof(opj_tcd_precinct_t);
947*3ac0a46fSAndroid Build Coastguard Worker 
948*3ac0a46fSAndroid Build Coastguard Worker             if (resno == 0) {
949*3ac0a46fSAndroid Build Coastguard Worker                 tlcbgxstart = l_tl_prc_x_start;
950*3ac0a46fSAndroid Build Coastguard Worker                 tlcbgystart = l_tl_prc_y_start;
951*3ac0a46fSAndroid Build Coastguard Worker                 /*brcbgxend = l_br_prc_x_end;*/
952*3ac0a46fSAndroid Build Coastguard Worker                 /* brcbgyend = l_br_prc_y_end;*/
953*3ac0a46fSAndroid Build Coastguard Worker                 cbgwidthexpn = l_pdx;
954*3ac0a46fSAndroid Build Coastguard Worker                 cbgheightexpn = l_pdy;
955*3ac0a46fSAndroid Build Coastguard Worker                 l_res->numbands = 1;
956*3ac0a46fSAndroid Build Coastguard Worker             } else {
957*3ac0a46fSAndroid Build Coastguard Worker                 tlcbgxstart = opj_int_ceildivpow2(l_tl_prc_x_start, 1);
958*3ac0a46fSAndroid Build Coastguard Worker                 tlcbgystart = opj_int_ceildivpow2(l_tl_prc_y_start, 1);
959*3ac0a46fSAndroid Build Coastguard Worker                 /*brcbgxend = opj_int_ceildivpow2(l_br_prc_x_end, 1);*/
960*3ac0a46fSAndroid Build Coastguard Worker                 /*brcbgyend = opj_int_ceildivpow2(l_br_prc_y_end, 1);*/
961*3ac0a46fSAndroid Build Coastguard Worker                 cbgwidthexpn = l_pdx - 1;
962*3ac0a46fSAndroid Build Coastguard Worker                 cbgheightexpn = l_pdy - 1;
963*3ac0a46fSAndroid Build Coastguard Worker                 l_res->numbands = 3;
964*3ac0a46fSAndroid Build Coastguard Worker             }
965*3ac0a46fSAndroid Build Coastguard Worker 
966*3ac0a46fSAndroid Build Coastguard Worker             cblkwidthexpn = opj_uint_min(l_tccp->cblkw, cbgwidthexpn);
967*3ac0a46fSAndroid Build Coastguard Worker             cblkheightexpn = opj_uint_min(l_tccp->cblkh, cbgheightexpn);
968*3ac0a46fSAndroid Build Coastguard Worker             l_band = l_res->bands;
969*3ac0a46fSAndroid Build Coastguard Worker 
970*3ac0a46fSAndroid Build Coastguard Worker             for (bandno = 0; bandno < l_res->numbands; ++bandno, ++l_band, ++l_step_size) {
971*3ac0a46fSAndroid Build Coastguard Worker                 /*fprintf(stderr, "\t\t\tband_no=%d/%d\n", bandno, l_res->numbands );*/
972*3ac0a46fSAndroid Build Coastguard Worker 
973*3ac0a46fSAndroid Build Coastguard Worker                 if (resno == 0) {
974*3ac0a46fSAndroid Build Coastguard Worker                     l_band->bandno = 0 ;
975*3ac0a46fSAndroid Build Coastguard Worker                     l_band->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no);
976*3ac0a46fSAndroid Build Coastguard Worker                     l_band->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no);
977*3ac0a46fSAndroid Build Coastguard Worker                     l_band->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no);
978*3ac0a46fSAndroid Build Coastguard Worker                     l_band->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no);
979*3ac0a46fSAndroid Build Coastguard Worker                 } else {
980*3ac0a46fSAndroid Build Coastguard Worker                     l_band->bandno = bandno + 1;
981*3ac0a46fSAndroid Build Coastguard Worker                     /* x0b = 1 if bandno = 1 or 3 */
982*3ac0a46fSAndroid Build Coastguard Worker                     l_x0b = l_band->bandno & 1;
983*3ac0a46fSAndroid Build Coastguard Worker                     /* y0b = 1 if bandno = 2 or 3 */
984*3ac0a46fSAndroid Build Coastguard Worker                     l_y0b = (OPJ_INT32)((l_band->bandno) >> 1);
985*3ac0a46fSAndroid Build Coastguard Worker                     /* l_band border (global) */
986*3ac0a46fSAndroid Build Coastguard Worker                     l_band->x0 = opj_int64_ceildivpow2(l_tilec->x0 - ((OPJ_INT64)l_x0b <<
987*3ac0a46fSAndroid Build Coastguard Worker                                                        l_level_no), (OPJ_INT32)(l_level_no + 1));
988*3ac0a46fSAndroid Build Coastguard Worker                     l_band->y0 = opj_int64_ceildivpow2(l_tilec->y0 - ((OPJ_INT64)l_y0b <<
989*3ac0a46fSAndroid Build Coastguard Worker                                                        l_level_no), (OPJ_INT32)(l_level_no + 1));
990*3ac0a46fSAndroid Build Coastguard Worker                     l_band->x1 = opj_int64_ceildivpow2(l_tilec->x1 - ((OPJ_INT64)l_x0b <<
991*3ac0a46fSAndroid Build Coastguard Worker                                                        l_level_no), (OPJ_INT32)(l_level_no + 1));
992*3ac0a46fSAndroid Build Coastguard Worker                     l_band->y1 = opj_int64_ceildivpow2(l_tilec->y1 - ((OPJ_INT64)l_y0b <<
993*3ac0a46fSAndroid Build Coastguard Worker                                                        l_level_no), (OPJ_INT32)(l_level_no + 1));
994*3ac0a46fSAndroid Build Coastguard Worker                 }
995*3ac0a46fSAndroid Build Coastguard Worker 
996*3ac0a46fSAndroid Build Coastguard Worker                 if (isEncoder) {
997*3ac0a46fSAndroid Build Coastguard Worker                     /* Skip empty bands */
998*3ac0a46fSAndroid Build Coastguard Worker                     if (opj_tcd_is_band_empty(l_band)) {
999*3ac0a46fSAndroid Build Coastguard Worker                         /* Do not zero l_band->precints to avoid leaks */
1000*3ac0a46fSAndroid Build Coastguard Worker                         /* but make sure we don't use it later, since */
1001*3ac0a46fSAndroid Build Coastguard Worker                         /* it will point to precincts of previous bands... */
1002*3ac0a46fSAndroid Build Coastguard Worker                         continue;
1003*3ac0a46fSAndroid Build Coastguard Worker                     }
1004*3ac0a46fSAndroid Build Coastguard Worker                 }
1005*3ac0a46fSAndroid Build Coastguard Worker 
1006*3ac0a46fSAndroid Build Coastguard Worker                 {
1007*3ac0a46fSAndroid Build Coastguard Worker                     /* Table E-1 - Sub-band gains */
1008*3ac0a46fSAndroid Build Coastguard Worker                     /* BUG_WEIRD_TWO_INVK (look for this identifier in dwt.c): */
1009*3ac0a46fSAndroid Build Coastguard Worker                     /* the test (!isEncoder && l_tccp->qmfbid == 0) is strongly */
1010*3ac0a46fSAndroid Build Coastguard Worker                     /* linked to the use of two_invK instead of invK */
1011*3ac0a46fSAndroid Build Coastguard Worker                     const OPJ_INT32 log2_gain = (!isEncoder &&
1012*3ac0a46fSAndroid Build Coastguard Worker                                                  l_tccp->qmfbid == 0) ? 0 : (l_band->bandno == 0) ? 0 :
1013*3ac0a46fSAndroid Build Coastguard Worker                                                 (l_band->bandno == 3) ? 2 : 1;
1014*3ac0a46fSAndroid Build Coastguard Worker 
1015*3ac0a46fSAndroid Build Coastguard Worker                     /* Nominal dynamic range. Equation E-4 */
1016*3ac0a46fSAndroid Build Coastguard Worker                     const OPJ_INT32 Rb = (OPJ_INT32)l_image_comp->prec + log2_gain;
1017*3ac0a46fSAndroid Build Coastguard Worker 
1018*3ac0a46fSAndroid Build Coastguard Worker                     /* Delta_b value of Equation E-3 in "E.1 Inverse quantization
1019*3ac0a46fSAndroid Build Coastguard Worker                     * procedure" of the standard */
1020*3ac0a46fSAndroid Build Coastguard Worker                     l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0,
1021*3ac0a46fSAndroid Build Coastguard Worker                                                       (OPJ_INT32)(Rb - l_step_size->expn))));
1022*3ac0a46fSAndroid Build Coastguard Worker                 }
1023*3ac0a46fSAndroid Build Coastguard Worker 
1024*3ac0a46fSAndroid Build Coastguard Worker                 /* Mb value of Equation E-2 in "E.1 Inverse quantization
1025*3ac0a46fSAndroid Build Coastguard Worker                  * procedure" of the standard */
1026*3ac0a46fSAndroid Build Coastguard Worker                 l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits -
1027*3ac0a46fSAndroid Build Coastguard Worker                                  1;
1028*3ac0a46fSAndroid Build Coastguard Worker 
1029*3ac0a46fSAndroid Build Coastguard Worker                 if (!l_band->precincts && (l_nb_precincts > 0U)) {
1030*3ac0a46fSAndroid Build Coastguard Worker                     l_band->precincts = (opj_tcd_precinct_t *) opj_malloc(/*3 * */
1031*3ac0a46fSAndroid Build Coastguard Worker                                             l_nb_precinct_size);
1032*3ac0a46fSAndroid Build Coastguard Worker                     if (! l_band->precincts) {
1033*3ac0a46fSAndroid Build Coastguard Worker                         opj_event_msg(manager, EVT_ERROR,
1034*3ac0a46fSAndroid Build Coastguard Worker                                       "Not enough memory to handle band precints\n");
1035*3ac0a46fSAndroid Build Coastguard Worker                         return OPJ_FALSE;
1036*3ac0a46fSAndroid Build Coastguard Worker                     }
1037*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t\t\t\tAllocate precincts of a band (opj_tcd_precinct_t): %d\n",l_nb_precinct_size);     */
1038*3ac0a46fSAndroid Build Coastguard Worker                     memset(l_band->precincts, 0, l_nb_precinct_size);
1039*3ac0a46fSAndroid Build Coastguard Worker                     l_band->precincts_data_size = l_nb_precinct_size;
1040*3ac0a46fSAndroid Build Coastguard Worker                 } else if (l_band->precincts_data_size < l_nb_precinct_size) {
1041*3ac0a46fSAndroid Build Coastguard Worker 
1042*3ac0a46fSAndroid Build Coastguard Worker                     opj_tcd_precinct_t * new_precincts = (opj_tcd_precinct_t *) opj_realloc(
1043*3ac0a46fSAndroid Build Coastguard Worker                             l_band->precincts,/*3 * */ l_nb_precinct_size);
1044*3ac0a46fSAndroid Build Coastguard Worker                     if (! new_precincts) {
1045*3ac0a46fSAndroid Build Coastguard Worker                         opj_event_msg(manager, EVT_ERROR,
1046*3ac0a46fSAndroid Build Coastguard Worker                                       "Not enough memory to handle band precints\n");
1047*3ac0a46fSAndroid Build Coastguard Worker                         opj_free(l_band->precincts);
1048*3ac0a46fSAndroid Build Coastguard Worker                         l_band->precincts = NULL;
1049*3ac0a46fSAndroid Build Coastguard Worker                         l_band->precincts_data_size = 0;
1050*3ac0a46fSAndroid Build Coastguard Worker                         return OPJ_FALSE;
1051*3ac0a46fSAndroid Build Coastguard Worker                     }
1052*3ac0a46fSAndroid Build Coastguard Worker                     l_band->precincts = new_precincts;
1053*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t\t\t\tReallocate precincts of a band (opj_tcd_precinct_t): from %d to %d\n",l_band->precincts_data_size, l_nb_precinct_size);*/
1054*3ac0a46fSAndroid Build Coastguard Worker                     memset(((OPJ_BYTE *) l_band->precincts) + l_band->precincts_data_size, 0,
1055*3ac0a46fSAndroid Build Coastguard Worker                            l_nb_precinct_size - l_band->precincts_data_size);
1056*3ac0a46fSAndroid Build Coastguard Worker                     l_band->precincts_data_size = l_nb_precinct_size;
1057*3ac0a46fSAndroid Build Coastguard Worker                 }
1058*3ac0a46fSAndroid Build Coastguard Worker 
1059*3ac0a46fSAndroid Build Coastguard Worker                 l_current_precinct = l_band->precincts;
1060*3ac0a46fSAndroid Build Coastguard Worker                 for (precno = 0; precno < l_nb_precincts; ++precno) {
1061*3ac0a46fSAndroid Build Coastguard Worker                     OPJ_INT32 tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
1062*3ac0a46fSAndroid Build Coastguard Worker                     OPJ_INT32 cbgxstart = tlcbgxstart + (OPJ_INT32)(precno % l_res->pw) *
1063*3ac0a46fSAndroid Build Coastguard Worker                                           (1 << cbgwidthexpn);
1064*3ac0a46fSAndroid Build Coastguard Worker                     OPJ_INT32 cbgystart = tlcbgystart + (OPJ_INT32)(precno / l_res->pw) *
1065*3ac0a46fSAndroid Build Coastguard Worker                                           (1 << cbgheightexpn);
1066*3ac0a46fSAndroid Build Coastguard Worker                     OPJ_INT32 cbgxend = cbgxstart + (1 << cbgwidthexpn);
1067*3ac0a46fSAndroid Build Coastguard Worker                     OPJ_INT32 cbgyend = cbgystart + (1 << cbgheightexpn);
1068*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t precno=%d; bandno=%d, resno=%d; compno=%d\n", precno, bandno , resno, compno);*/
1069*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t tlcbgxstart(=%d) + (precno(=%d) percent res->pw(=%d)) * (1 << cbgwidthexpn(=%d)) \n",tlcbgxstart,precno,l_res->pw,cbgwidthexpn);*/
1070*3ac0a46fSAndroid Build Coastguard Worker 
1071*3ac0a46fSAndroid Build Coastguard Worker                     /* precinct size (global) */
1072*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t cbgxstart=%d, l_band->x0 = %d \n",cbgxstart, l_band->x0);*/
1073*3ac0a46fSAndroid Build Coastguard Worker 
1074*3ac0a46fSAndroid Build Coastguard Worker                     l_current_precinct->x0 = opj_int_max(cbgxstart, l_band->x0);
1075*3ac0a46fSAndroid Build Coastguard Worker                     l_current_precinct->y0 = opj_int_max(cbgystart, l_band->y0);
1076*3ac0a46fSAndroid Build Coastguard Worker                     l_current_precinct->x1 = opj_int_min(cbgxend, l_band->x1);
1077*3ac0a46fSAndroid Build Coastguard Worker                     l_current_precinct->y1 = opj_int_min(cbgyend, l_band->y1);
1078*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t prc_x0=%d; prc_y0=%d, prc_x1=%d; prc_y1=%d\n",l_current_precinct->x0, l_current_precinct->y0 ,l_current_precinct->x1, l_current_precinct->y1);*/
1079*3ac0a46fSAndroid Build Coastguard Worker 
1080*3ac0a46fSAndroid Build Coastguard Worker                     tlcblkxstart = opj_int_floordivpow2(l_current_precinct->x0,
1081*3ac0a46fSAndroid Build Coastguard Worker                                                         (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn;
1082*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t tlcblkxstart =%d\n",tlcblkxstart );*/
1083*3ac0a46fSAndroid Build Coastguard Worker                     tlcblkystart = opj_int_floordivpow2(l_current_precinct->y0,
1084*3ac0a46fSAndroid Build Coastguard Worker                                                         (OPJ_INT32)cblkheightexpn) << cblkheightexpn;
1085*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t tlcblkystart =%d\n",tlcblkystart );*/
1086*3ac0a46fSAndroid Build Coastguard Worker                     brcblkxend = opj_int_ceildivpow2(l_current_precinct->x1,
1087*3ac0a46fSAndroid Build Coastguard Worker                                                      (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn;
1088*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t brcblkxend =%d\n",brcblkxend );*/
1089*3ac0a46fSAndroid Build Coastguard Worker                     brcblkyend = opj_int_ceildivpow2(l_current_precinct->y1,
1090*3ac0a46fSAndroid Build Coastguard Worker                                                      (OPJ_INT32)cblkheightexpn) << cblkheightexpn;
1091*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t brcblkyend =%d\n",brcblkyend );*/
1092*3ac0a46fSAndroid Build Coastguard Worker                     l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >>
1093*3ac0a46fSAndroid Build Coastguard Worker                                                           cblkwidthexpn);
1094*3ac0a46fSAndroid Build Coastguard Worker                     l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >>
1095*3ac0a46fSAndroid Build Coastguard Worker                                                           cblkheightexpn);
1096*3ac0a46fSAndroid Build Coastguard Worker 
1097*3ac0a46fSAndroid Build Coastguard Worker                     if (l_current_precinct->cw && ((OPJ_UINT32)-1) / l_current_precinct->cw < l_current_precinct->ch) {
1098*3ac0a46fSAndroid Build Coastguard Worker                         return OPJ_FALSE;
1099*3ac0a46fSAndroid Build Coastguard Worker                     }
1100*3ac0a46fSAndroid Build Coastguard Worker                     l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch;
1101*3ac0a46fSAndroid Build Coastguard Worker                     /*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch);      */
1102*3ac0a46fSAndroid Build Coastguard Worker                     if ((((OPJ_UINT32) - 1) / (OPJ_UINT32)sizeof_block) <
1103*3ac0a46fSAndroid Build Coastguard Worker                             l_nb_code_blocks) {
1104*3ac0a46fSAndroid Build Coastguard Worker                         opj_event_msg(manager, EVT_ERROR,
1105*3ac0a46fSAndroid Build Coastguard Worker                                       "Size of code block data exceeds system limits\n");
1106*3ac0a46fSAndroid Build Coastguard Worker                         return OPJ_FALSE;
1107*3ac0a46fSAndroid Build Coastguard Worker                     }
1108*3ac0a46fSAndroid Build Coastguard Worker                     l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof_block;
1109*3ac0a46fSAndroid Build Coastguard Worker 
1110*3ac0a46fSAndroid Build Coastguard Worker                     if (!l_current_precinct->cblks.blocks && (l_nb_code_blocks > 0U)) {
1111*3ac0a46fSAndroid Build Coastguard Worker                         l_current_precinct->cblks.blocks = opj_malloc(l_nb_code_blocks_size);
1112*3ac0a46fSAndroid Build Coastguard Worker                         if (! l_current_precinct->cblks.blocks) {
1113*3ac0a46fSAndroid Build Coastguard Worker                             return OPJ_FALSE;
1114*3ac0a46fSAndroid Build Coastguard Worker                         }
1115*3ac0a46fSAndroid Build Coastguard Worker                         /*fprintf(stderr, "\t\t\t\tAllocate cblks of a precinct (opj_tcd_cblk_dec_t): %d\n",l_nb_code_blocks_size);*/
1116*3ac0a46fSAndroid Build Coastguard Worker 
1117*3ac0a46fSAndroid Build Coastguard Worker                         memset(l_current_precinct->cblks.blocks, 0, l_nb_code_blocks_size);
1118*3ac0a46fSAndroid Build Coastguard Worker 
1119*3ac0a46fSAndroid Build Coastguard Worker                         l_current_precinct->block_size = l_nb_code_blocks_size;
1120*3ac0a46fSAndroid Build Coastguard Worker                     } else if (l_nb_code_blocks_size > l_current_precinct->block_size) {
1121*3ac0a46fSAndroid Build Coastguard Worker                         void *new_blocks = opj_realloc(l_current_precinct->cblks.blocks,
1122*3ac0a46fSAndroid Build Coastguard Worker                                                        l_nb_code_blocks_size);
1123*3ac0a46fSAndroid Build Coastguard Worker                         if (! new_blocks) {
1124*3ac0a46fSAndroid Build Coastguard Worker                             opj_free(l_current_precinct->cblks.blocks);
1125*3ac0a46fSAndroid Build Coastguard Worker                             l_current_precinct->cblks.blocks = NULL;
1126*3ac0a46fSAndroid Build Coastguard Worker                             l_current_precinct->block_size = 0;
1127*3ac0a46fSAndroid Build Coastguard Worker                             opj_event_msg(manager, EVT_ERROR,
1128*3ac0a46fSAndroid Build Coastguard Worker                                           "Not enough memory for current precinct codeblock element\n");
1129*3ac0a46fSAndroid Build Coastguard Worker                             return OPJ_FALSE;
1130*3ac0a46fSAndroid Build Coastguard Worker                         }
1131*3ac0a46fSAndroid Build Coastguard Worker                         l_current_precinct->cblks.blocks = new_blocks;
1132*3ac0a46fSAndroid Build Coastguard Worker                         /*fprintf(stderr, "\t\t\t\tReallocate cblks of a precinct (opj_tcd_cblk_dec_t): from %d to %d\n",l_current_precinct->block_size, l_nb_code_blocks_size);     */
1133*3ac0a46fSAndroid Build Coastguard Worker 
1134*3ac0a46fSAndroid Build Coastguard Worker                         memset(((OPJ_BYTE *) l_current_precinct->cblks.blocks) +
1135*3ac0a46fSAndroid Build Coastguard Worker                                l_current_precinct->block_size
1136*3ac0a46fSAndroid Build Coastguard Worker                                , 0
1137*3ac0a46fSAndroid Build Coastguard Worker                                , l_nb_code_blocks_size - l_current_precinct->block_size);
1138*3ac0a46fSAndroid Build Coastguard Worker 
1139*3ac0a46fSAndroid Build Coastguard Worker                         l_current_precinct->block_size = l_nb_code_blocks_size;
1140*3ac0a46fSAndroid Build Coastguard Worker                     }
1141*3ac0a46fSAndroid Build Coastguard Worker 
1142*3ac0a46fSAndroid Build Coastguard Worker                     if (! l_current_precinct->incltree) {
1143*3ac0a46fSAndroid Build Coastguard Worker                         l_current_precinct->incltree = opj_tgt_create(l_current_precinct->cw,
1144*3ac0a46fSAndroid Build Coastguard Worker                                                        l_current_precinct->ch, manager);
1145*3ac0a46fSAndroid Build Coastguard Worker                     } else {
1146*3ac0a46fSAndroid Build Coastguard Worker                         l_current_precinct->incltree = opj_tgt_init(l_current_precinct->incltree,
1147*3ac0a46fSAndroid Build Coastguard Worker                                                        l_current_precinct->cw, l_current_precinct->ch, manager);
1148*3ac0a46fSAndroid Build Coastguard Worker                     }
1149*3ac0a46fSAndroid Build Coastguard Worker 
1150*3ac0a46fSAndroid Build Coastguard Worker                     if (! l_current_precinct->imsbtree) {
1151*3ac0a46fSAndroid Build Coastguard Worker                         l_current_precinct->imsbtree = opj_tgt_create(l_current_precinct->cw,
1152*3ac0a46fSAndroid Build Coastguard Worker                                                        l_current_precinct->ch, manager);
1153*3ac0a46fSAndroid Build Coastguard Worker                     } else {
1154*3ac0a46fSAndroid Build Coastguard Worker                         l_current_precinct->imsbtree = opj_tgt_init(l_current_precinct->imsbtree,
1155*3ac0a46fSAndroid Build Coastguard Worker                                                        l_current_precinct->cw, l_current_precinct->ch, manager);
1156*3ac0a46fSAndroid Build Coastguard Worker                     }
1157*3ac0a46fSAndroid Build Coastguard Worker 
1158*3ac0a46fSAndroid Build Coastguard Worker                     for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
1159*3ac0a46fSAndroid Build Coastguard Worker                         OPJ_INT32 cblkxstart = tlcblkxstart + (OPJ_INT32)(cblkno %
1160*3ac0a46fSAndroid Build Coastguard Worker                                                l_current_precinct->cw) * (1 << cblkwidthexpn);
1161*3ac0a46fSAndroid Build Coastguard Worker                         OPJ_INT32 cblkystart = tlcblkystart + (OPJ_INT32)(cblkno /
1162*3ac0a46fSAndroid Build Coastguard Worker                                                l_current_precinct->cw) * (1 << cblkheightexpn);
1163*3ac0a46fSAndroid Build Coastguard Worker                         OPJ_INT32 cblkxend = cblkxstart + (1 << cblkwidthexpn);
1164*3ac0a46fSAndroid Build Coastguard Worker                         OPJ_INT32 cblkyend = cblkystart + (1 << cblkheightexpn);
1165*3ac0a46fSAndroid Build Coastguard Worker 
1166*3ac0a46fSAndroid Build Coastguard Worker                         if (isEncoder) {
1167*3ac0a46fSAndroid Build Coastguard Worker                             opj_tcd_cblk_enc_t* l_code_block = l_current_precinct->cblks.enc + cblkno;
1168*3ac0a46fSAndroid Build Coastguard Worker 
1169*3ac0a46fSAndroid Build Coastguard Worker                             if (! opj_tcd_code_block_enc_allocate(l_code_block)) {
1170*3ac0a46fSAndroid Build Coastguard Worker                                 return OPJ_FALSE;
1171*3ac0a46fSAndroid Build Coastguard Worker                             }
1172*3ac0a46fSAndroid Build Coastguard Worker                             /* code-block size (global) */
1173*3ac0a46fSAndroid Build Coastguard Worker                             l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0);
1174*3ac0a46fSAndroid Build Coastguard Worker                             l_code_block->y0 = opj_int_max(cblkystart, l_current_precinct->y0);
1175*3ac0a46fSAndroid Build Coastguard Worker                             l_code_block->x1 = opj_int_min(cblkxend, l_current_precinct->x1);
1176*3ac0a46fSAndroid Build Coastguard Worker                             l_code_block->y1 = opj_int_min(cblkyend, l_current_precinct->y1);
1177*3ac0a46fSAndroid Build Coastguard Worker 
1178*3ac0a46fSAndroid Build Coastguard Worker                             if (! opj_tcd_code_block_enc_allocate_data(l_code_block)) {
1179*3ac0a46fSAndroid Build Coastguard Worker                                 return OPJ_FALSE;
1180*3ac0a46fSAndroid Build Coastguard Worker                             }
1181*3ac0a46fSAndroid Build Coastguard Worker                         } else {
1182*3ac0a46fSAndroid Build Coastguard Worker                             opj_tcd_cblk_dec_t* l_code_block = l_current_precinct->cblks.dec + cblkno;
1183*3ac0a46fSAndroid Build Coastguard Worker 
1184*3ac0a46fSAndroid Build Coastguard Worker                             if (! opj_tcd_code_block_dec_allocate(l_code_block)) {
1185*3ac0a46fSAndroid Build Coastguard Worker                                 return OPJ_FALSE;
1186*3ac0a46fSAndroid Build Coastguard Worker                             }
1187*3ac0a46fSAndroid Build Coastguard Worker                             /* code-block size (global) */
1188*3ac0a46fSAndroid Build Coastguard Worker                             l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0);
1189*3ac0a46fSAndroid Build Coastguard Worker                             l_code_block->y0 = opj_int_max(cblkystart, l_current_precinct->y0);
1190*3ac0a46fSAndroid Build Coastguard Worker                             l_code_block->x1 = opj_int_min(cblkxend, l_current_precinct->x1);
1191*3ac0a46fSAndroid Build Coastguard Worker                             l_code_block->y1 = opj_int_min(cblkyend, l_current_precinct->y1);
1192*3ac0a46fSAndroid Build Coastguard Worker                         }
1193*3ac0a46fSAndroid Build Coastguard Worker                     }
1194*3ac0a46fSAndroid Build Coastguard Worker                     ++l_current_precinct;
1195*3ac0a46fSAndroid Build Coastguard Worker                 } /* precno */
1196*3ac0a46fSAndroid Build Coastguard Worker             } /* bandno */
1197*3ac0a46fSAndroid Build Coastguard Worker             ++l_res;
1198*3ac0a46fSAndroid Build Coastguard Worker         } /* resno */
1199*3ac0a46fSAndroid Build Coastguard Worker         ++l_tccp;
1200*3ac0a46fSAndroid Build Coastguard Worker         ++l_tilec;
1201*3ac0a46fSAndroid Build Coastguard Worker         ++l_image_comp;
1202*3ac0a46fSAndroid Build Coastguard Worker     } /* compno */
1203*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
1204*3ac0a46fSAndroid Build Coastguard Worker }
1205*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_init_encode_tile(opj_tcd_t * p_tcd,OPJ_UINT32 p_tile_no,opj_event_mgr_t * p_manager)1206*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_tcd_init_encode_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
1207*3ac0a46fSAndroid Build Coastguard Worker                                   opj_event_mgr_t* p_manager)
1208*3ac0a46fSAndroid Build Coastguard Worker {
1209*3ac0a46fSAndroid Build Coastguard Worker     return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_TRUE,
1210*3ac0a46fSAndroid Build Coastguard Worker                              sizeof(opj_tcd_cblk_enc_t), p_manager);
1211*3ac0a46fSAndroid Build Coastguard Worker }
1212*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_init_decode_tile(opj_tcd_t * p_tcd,OPJ_UINT32 p_tile_no,opj_event_mgr_t * p_manager)1213*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_tcd_init_decode_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
1214*3ac0a46fSAndroid Build Coastguard Worker                                   opj_event_mgr_t* p_manager)
1215*3ac0a46fSAndroid Build Coastguard Worker {
1216*3ac0a46fSAndroid Build Coastguard Worker     return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_FALSE,
1217*3ac0a46fSAndroid Build Coastguard Worker                              sizeof(opj_tcd_cblk_dec_t), p_manager);
1218*3ac0a46fSAndroid Build Coastguard Worker }
1219*3ac0a46fSAndroid Build Coastguard Worker 
1220*3ac0a46fSAndroid Build Coastguard Worker /**
1221*3ac0a46fSAndroid Build Coastguard Worker  * Allocates memory for an encoding code block (but not data memory).
1222*3ac0a46fSAndroid Build Coastguard Worker  */
opj_tcd_code_block_enc_allocate(opj_tcd_cblk_enc_t * p_code_block)1223*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_code_block_enc_allocate(opj_tcd_cblk_enc_t *
1224*3ac0a46fSAndroid Build Coastguard Worker         p_code_block)
1225*3ac0a46fSAndroid Build Coastguard Worker {
1226*3ac0a46fSAndroid Build Coastguard Worker     if (! p_code_block->layers) {
1227*3ac0a46fSAndroid Build Coastguard Worker         /* no memset since data */
1228*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->layers = (opj_tcd_layer_t*) opj_calloc(100,
1229*3ac0a46fSAndroid Build Coastguard Worker                                sizeof(opj_tcd_layer_t));
1230*3ac0a46fSAndroid Build Coastguard Worker         if (! p_code_block->layers) {
1231*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
1232*3ac0a46fSAndroid Build Coastguard Worker         }
1233*3ac0a46fSAndroid Build Coastguard Worker     }
1234*3ac0a46fSAndroid Build Coastguard Worker     if (! p_code_block->passes) {
1235*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->passes = (opj_tcd_pass_t*) opj_calloc(100,
1236*3ac0a46fSAndroid Build Coastguard Worker                                sizeof(opj_tcd_pass_t));
1237*3ac0a46fSAndroid Build Coastguard Worker         if (! p_code_block->passes) {
1238*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
1239*3ac0a46fSAndroid Build Coastguard Worker         }
1240*3ac0a46fSAndroid Build Coastguard Worker     }
1241*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
1242*3ac0a46fSAndroid Build Coastguard Worker }
1243*3ac0a46fSAndroid Build Coastguard Worker 
1244*3ac0a46fSAndroid Build Coastguard Worker /**
1245*3ac0a46fSAndroid Build Coastguard Worker  * Allocates data memory for an encoding code block.
1246*3ac0a46fSAndroid Build Coastguard Worker  */
opj_tcd_code_block_enc_allocate_data(opj_tcd_cblk_enc_t * p_code_block)1247*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_code_block_enc_allocate_data(opj_tcd_cblk_enc_t *
1248*3ac0a46fSAndroid Build Coastguard Worker         p_code_block)
1249*3ac0a46fSAndroid Build Coastguard Worker {
1250*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_data_size;
1251*3ac0a46fSAndroid Build Coastguard Worker 
1252*3ac0a46fSAndroid Build Coastguard Worker     /* +1 is needed for https://github.com/uclouvain/openjpeg/issues/835 */
1253*3ac0a46fSAndroid Build Coastguard Worker     /* and actually +2 required for https://github.com/uclouvain/openjpeg/issues/982 */
1254*3ac0a46fSAndroid Build Coastguard Worker     /* and +7 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 3) */
1255*3ac0a46fSAndroid Build Coastguard Worker     /* and +26 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 7) */
1256*3ac0a46fSAndroid Build Coastguard Worker     /* and +28 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 44) */
1257*3ac0a46fSAndroid Build Coastguard Worker     /* and +33 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 4) */
1258*3ac0a46fSAndroid Build Coastguard Worker     /* and +63 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 4 -IMF 2K) */
1259*3ac0a46fSAndroid Build Coastguard Worker     /* and +74 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 4 -n 8 -s 7,7 -I) */
1260*3ac0a46fSAndroid Build Coastguard Worker     /* TODO: is there a theoretical upper-bound for the compressed code */
1261*3ac0a46fSAndroid Build Coastguard Worker     /* block size ? */
1262*3ac0a46fSAndroid Build Coastguard Worker     l_data_size = 74 + (OPJ_UINT32)((p_code_block->x1 - p_code_block->x0) *
1263*3ac0a46fSAndroid Build Coastguard Worker                                     (p_code_block->y1 - p_code_block->y0) * (OPJ_INT32)sizeof(OPJ_UINT32));
1264*3ac0a46fSAndroid Build Coastguard Worker 
1265*3ac0a46fSAndroid Build Coastguard Worker     if (l_data_size > p_code_block->data_size) {
1266*3ac0a46fSAndroid Build Coastguard Worker         if (p_code_block->data) {
1267*3ac0a46fSAndroid Build Coastguard Worker             /* We refer to data - 1 since below we incremented it */
1268*3ac0a46fSAndroid Build Coastguard Worker             opj_free(p_code_block->data - 1);
1269*3ac0a46fSAndroid Build Coastguard Worker         }
1270*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->data = (OPJ_BYTE*) opj_malloc(l_data_size + 1);
1271*3ac0a46fSAndroid Build Coastguard Worker         if (! p_code_block->data) {
1272*3ac0a46fSAndroid Build Coastguard Worker             p_code_block->data_size = 0U;
1273*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
1274*3ac0a46fSAndroid Build Coastguard Worker         }
1275*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->data_size = l_data_size;
1276*3ac0a46fSAndroid Build Coastguard Worker 
1277*3ac0a46fSAndroid Build Coastguard Worker         /* We reserve the initial byte as a fake byte to a non-FF value */
1278*3ac0a46fSAndroid Build Coastguard Worker         /* and increment the data pointer, so that opj_mqc_init_enc() */
1279*3ac0a46fSAndroid Build Coastguard Worker         /* can do bp = data - 1, and opj_mqc_byteout() can safely dereference */
1280*3ac0a46fSAndroid Build Coastguard Worker         /* it. */
1281*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->data[0] = 0;
1282*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->data += 1; /*why +1 ?*/
1283*3ac0a46fSAndroid Build Coastguard Worker     }
1284*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
1285*3ac0a46fSAndroid Build Coastguard Worker }
1286*3ac0a46fSAndroid Build Coastguard Worker 
1287*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_reinit_segment(opj_tcd_seg_t * seg)1288*3ac0a46fSAndroid Build Coastguard Worker void opj_tcd_reinit_segment(opj_tcd_seg_t* seg)
1289*3ac0a46fSAndroid Build Coastguard Worker {
1290*3ac0a46fSAndroid Build Coastguard Worker     memset(seg, 0, sizeof(opj_tcd_seg_t));
1291*3ac0a46fSAndroid Build Coastguard Worker }
1292*3ac0a46fSAndroid Build Coastguard Worker 
1293*3ac0a46fSAndroid Build Coastguard Worker /**
1294*3ac0a46fSAndroid Build Coastguard Worker  * Allocates memory for a decoding code block.
1295*3ac0a46fSAndroid Build Coastguard Worker  */
opj_tcd_code_block_dec_allocate(opj_tcd_cblk_dec_t * p_code_block)1296*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_code_block_dec_allocate(opj_tcd_cblk_dec_t *
1297*3ac0a46fSAndroid Build Coastguard Worker         p_code_block)
1298*3ac0a46fSAndroid Build Coastguard Worker {
1299*3ac0a46fSAndroid Build Coastguard Worker     if (! p_code_block->segs) {
1300*3ac0a46fSAndroid Build Coastguard Worker 
1301*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->segs = (opj_tcd_seg_t *) opj_calloc(OPJ_J2K_DEFAULT_NB_SEGS,
1302*3ac0a46fSAndroid Build Coastguard Worker                              sizeof(opj_tcd_seg_t));
1303*3ac0a46fSAndroid Build Coastguard Worker         if (! p_code_block->segs) {
1304*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
1305*3ac0a46fSAndroid Build Coastguard Worker         }
1306*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr, "Allocate %d elements of code_block->data\n", OPJ_J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t));*/
1307*3ac0a46fSAndroid Build Coastguard Worker 
1308*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->m_current_max_segs = OPJ_J2K_DEFAULT_NB_SEGS;
1309*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr, "m_current_max_segs of code_block->data = %d\n", p_code_block->m_current_max_segs);*/
1310*3ac0a46fSAndroid Build Coastguard Worker     } else {
1311*3ac0a46fSAndroid Build Coastguard Worker         /* sanitize */
1312*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_seg_t * l_segs = p_code_block->segs;
1313*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 l_current_max_segs = p_code_block->m_current_max_segs;
1314*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_seg_data_chunk_t* l_chunks = p_code_block->chunks;
1315*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 l_numchunksalloc = p_code_block->numchunksalloc;
1316*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 i;
1317*3ac0a46fSAndroid Build Coastguard Worker 
1318*3ac0a46fSAndroid Build Coastguard Worker         opj_aligned_free(p_code_block->decoded_data);
1319*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->decoded_data = 00;
1320*3ac0a46fSAndroid Build Coastguard Worker 
1321*3ac0a46fSAndroid Build Coastguard Worker         memset(p_code_block, 0, sizeof(opj_tcd_cblk_dec_t));
1322*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->segs = l_segs;
1323*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->m_current_max_segs = l_current_max_segs;
1324*3ac0a46fSAndroid Build Coastguard Worker         for (i = 0; i < l_current_max_segs; ++i) {
1325*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_reinit_segment(&l_segs[i]);
1326*3ac0a46fSAndroid Build Coastguard Worker         }
1327*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->chunks = l_chunks;
1328*3ac0a46fSAndroid Build Coastguard Worker         p_code_block->numchunksalloc = l_numchunksalloc;
1329*3ac0a46fSAndroid Build Coastguard Worker     }
1330*3ac0a46fSAndroid Build Coastguard Worker 
1331*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
1332*3ac0a46fSAndroid Build Coastguard Worker }
1333*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_get_decoded_tile_size(opj_tcd_t * p_tcd,OPJ_BOOL take_into_account_partial_decoding)1334*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 opj_tcd_get_decoded_tile_size(opj_tcd_t *p_tcd,
1335*3ac0a46fSAndroid Build Coastguard Worker         OPJ_BOOL take_into_account_partial_decoding)
1336*3ac0a46fSAndroid Build Coastguard Worker {
1337*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 i;
1338*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_data_size = 0;
1339*3ac0a46fSAndroid Build Coastguard Worker     opj_image_comp_t * l_img_comp = 00;
1340*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t * l_tile_comp = 00;
1341*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_resolution_t * l_res = 00;
1342*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_size_comp, l_remaining;
1343*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_temp;
1344*3ac0a46fSAndroid Build Coastguard Worker 
1345*3ac0a46fSAndroid Build Coastguard Worker     l_tile_comp = p_tcd->tcd_image->tiles->comps;
1346*3ac0a46fSAndroid Build Coastguard Worker     l_img_comp = p_tcd->image->comps;
1347*3ac0a46fSAndroid Build Coastguard Worker 
1348*3ac0a46fSAndroid Build Coastguard Worker     for (i = 0; i < p_tcd->image->numcomps; ++i) {
1349*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 w, h;
1350*3ac0a46fSAndroid Build Coastguard Worker         l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
1351*3ac0a46fSAndroid Build Coastguard Worker         l_remaining = l_img_comp->prec & 7;  /* (%8) */
1352*3ac0a46fSAndroid Build Coastguard Worker 
1353*3ac0a46fSAndroid Build Coastguard Worker         if (l_remaining) {
1354*3ac0a46fSAndroid Build Coastguard Worker             ++l_size_comp;
1355*3ac0a46fSAndroid Build Coastguard Worker         }
1356*3ac0a46fSAndroid Build Coastguard Worker 
1357*3ac0a46fSAndroid Build Coastguard Worker         if (l_size_comp == 3) {
1358*3ac0a46fSAndroid Build Coastguard Worker             l_size_comp = 4;
1359*3ac0a46fSAndroid Build Coastguard Worker         }
1360*3ac0a46fSAndroid Build Coastguard Worker 
1361*3ac0a46fSAndroid Build Coastguard Worker         l_res = l_tile_comp->resolutions + l_tile_comp->minimum_num_resolutions - 1;
1362*3ac0a46fSAndroid Build Coastguard Worker         if (take_into_account_partial_decoding && !p_tcd->whole_tile_decoding) {
1363*3ac0a46fSAndroid Build Coastguard Worker             w = l_res->win_x1 - l_res->win_x0;
1364*3ac0a46fSAndroid Build Coastguard Worker             h = l_res->win_y1 - l_res->win_y0;
1365*3ac0a46fSAndroid Build Coastguard Worker         } else {
1366*3ac0a46fSAndroid Build Coastguard Worker             w = (OPJ_UINT32)(l_res->x1 - l_res->x0);
1367*3ac0a46fSAndroid Build Coastguard Worker             h = (OPJ_UINT32)(l_res->y1 - l_res->y0);
1368*3ac0a46fSAndroid Build Coastguard Worker         }
1369*3ac0a46fSAndroid Build Coastguard Worker         if (h > 0 && UINT_MAX / w < h) {
1370*3ac0a46fSAndroid Build Coastguard Worker             return UINT_MAX;
1371*3ac0a46fSAndroid Build Coastguard Worker         }
1372*3ac0a46fSAndroid Build Coastguard Worker         l_temp = w * h;
1373*3ac0a46fSAndroid Build Coastguard Worker         if (l_size_comp && UINT_MAX / l_size_comp < l_temp) {
1374*3ac0a46fSAndroid Build Coastguard Worker             return UINT_MAX;
1375*3ac0a46fSAndroid Build Coastguard Worker         }
1376*3ac0a46fSAndroid Build Coastguard Worker         l_temp *= l_size_comp;
1377*3ac0a46fSAndroid Build Coastguard Worker 
1378*3ac0a46fSAndroid Build Coastguard Worker         if (l_temp > UINT_MAX - l_data_size) {
1379*3ac0a46fSAndroid Build Coastguard Worker             return UINT_MAX;
1380*3ac0a46fSAndroid Build Coastguard Worker         }
1381*3ac0a46fSAndroid Build Coastguard Worker         l_data_size += l_temp;
1382*3ac0a46fSAndroid Build Coastguard Worker         ++l_img_comp;
1383*3ac0a46fSAndroid Build Coastguard Worker         ++l_tile_comp;
1384*3ac0a46fSAndroid Build Coastguard Worker     }
1385*3ac0a46fSAndroid Build Coastguard Worker 
1386*3ac0a46fSAndroid Build Coastguard Worker     return l_data_size;
1387*3ac0a46fSAndroid Build Coastguard Worker }
1388*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_encode_tile(opj_tcd_t * p_tcd,OPJ_UINT32 p_tile_no,OPJ_BYTE * p_dest,OPJ_UINT32 * p_data_written,OPJ_UINT32 p_max_length,opj_codestream_info_t * p_cstr_info,opj_tcd_marker_info_t * p_marker_info,opj_event_mgr_t * p_manager)1389*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd,
1390*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 p_tile_no,
1391*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_BYTE *p_dest,
1392*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 * p_data_written,
1393*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 p_max_length,
1394*3ac0a46fSAndroid Build Coastguard Worker                              opj_codestream_info_t *p_cstr_info,
1395*3ac0a46fSAndroid Build Coastguard Worker                              opj_tcd_marker_info_t* p_marker_info,
1396*3ac0a46fSAndroid Build Coastguard Worker                              opj_event_mgr_t *p_manager)
1397*3ac0a46fSAndroid Build Coastguard Worker {
1398*3ac0a46fSAndroid Build Coastguard Worker 
1399*3ac0a46fSAndroid Build Coastguard Worker     if (p_tcd->cur_tp_num == 0) {
1400*3ac0a46fSAndroid Build Coastguard Worker 
1401*3ac0a46fSAndroid Build Coastguard Worker         p_tcd->tcd_tileno = p_tile_no;
1402*3ac0a46fSAndroid Build Coastguard Worker         p_tcd->tcp = &p_tcd->cp->tcps[p_tile_no];
1403*3ac0a46fSAndroid Build Coastguard Worker 
1404*3ac0a46fSAndroid Build Coastguard Worker         /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */
1405*3ac0a46fSAndroid Build Coastguard Worker         if (p_cstr_info)  {
1406*3ac0a46fSAndroid Build Coastguard Worker             OPJ_UINT32 l_num_packs = 0;
1407*3ac0a46fSAndroid Build Coastguard Worker             OPJ_UINT32 i;
1408*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_tilecomp_t *l_tilec_idx =
1409*3ac0a46fSAndroid Build Coastguard Worker                 &p_tcd->tcd_image->tiles->comps[0];        /* based on component 0 */
1410*3ac0a46fSAndroid Build Coastguard Worker             opj_tccp_t *l_tccp = p_tcd->tcp->tccps; /* based on component 0 */
1411*3ac0a46fSAndroid Build Coastguard Worker 
1412*3ac0a46fSAndroid Build Coastguard Worker             for (i = 0; i < l_tilec_idx->numresolutions; i++) {
1413*3ac0a46fSAndroid Build Coastguard Worker                 opj_tcd_resolution_t *l_res_idx = &l_tilec_idx->resolutions[i];
1414*3ac0a46fSAndroid Build Coastguard Worker 
1415*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_info->tile[p_tile_no].pw[i] = (int)l_res_idx->pw;
1416*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_info->tile[p_tile_no].ph[i] = (int)l_res_idx->ph;
1417*3ac0a46fSAndroid Build Coastguard Worker 
1418*3ac0a46fSAndroid Build Coastguard Worker                 l_num_packs += l_res_idx->pw * l_res_idx->ph;
1419*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_info->tile[p_tile_no].pdx[i] = (int)l_tccp->prcw[i];
1420*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_info->tile[p_tile_no].pdy[i] = (int)l_tccp->prch[i];
1421*3ac0a46fSAndroid Build Coastguard Worker             }
1422*3ac0a46fSAndroid Build Coastguard Worker             p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t*) opj_calloc((
1423*3ac0a46fSAndroid Build Coastguard Worker                     OPJ_SIZE_T)p_cstr_info->numcomps * (OPJ_SIZE_T)p_cstr_info->numlayers *
1424*3ac0a46fSAndroid Build Coastguard Worker                                                   l_num_packs,
1425*3ac0a46fSAndroid Build Coastguard Worker                                                   sizeof(opj_packet_info_t));
1426*3ac0a46fSAndroid Build Coastguard Worker             if (!p_cstr_info->tile[p_tile_no].packet) {
1427*3ac0a46fSAndroid Build Coastguard Worker                 /* FIXME event manager error callback */
1428*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
1429*3ac0a46fSAndroid Build Coastguard Worker             }
1430*3ac0a46fSAndroid Build Coastguard Worker         }
1431*3ac0a46fSAndroid Build Coastguard Worker         /* << INDEX */
1432*3ac0a46fSAndroid Build Coastguard Worker 
1433*3ac0a46fSAndroid Build Coastguard Worker         /* FIXME _ProfStart(PGROUP_DC_SHIFT); */
1434*3ac0a46fSAndroid Build Coastguard Worker         /*---------------TILE-------------------*/
1435*3ac0a46fSAndroid Build Coastguard Worker         if (! opj_tcd_dc_level_shift_encode(p_tcd)) {
1436*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
1437*3ac0a46fSAndroid Build Coastguard Worker         }
1438*3ac0a46fSAndroid Build Coastguard Worker         /* FIXME _ProfStop(PGROUP_DC_SHIFT); */
1439*3ac0a46fSAndroid Build Coastguard Worker 
1440*3ac0a46fSAndroid Build Coastguard Worker         /* FIXME _ProfStart(PGROUP_MCT); */
1441*3ac0a46fSAndroid Build Coastguard Worker         if (! opj_tcd_mct_encode(p_tcd)) {
1442*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
1443*3ac0a46fSAndroid Build Coastguard Worker         }
1444*3ac0a46fSAndroid Build Coastguard Worker         /* FIXME _ProfStop(PGROUP_MCT); */
1445*3ac0a46fSAndroid Build Coastguard Worker 
1446*3ac0a46fSAndroid Build Coastguard Worker         /* FIXME _ProfStart(PGROUP_DWT); */
1447*3ac0a46fSAndroid Build Coastguard Worker         if (! opj_tcd_dwt_encode(p_tcd)) {
1448*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
1449*3ac0a46fSAndroid Build Coastguard Worker         }
1450*3ac0a46fSAndroid Build Coastguard Worker         /* FIXME  _ProfStop(PGROUP_DWT); */
1451*3ac0a46fSAndroid Build Coastguard Worker 
1452*3ac0a46fSAndroid Build Coastguard Worker         /* FIXME  _ProfStart(PGROUP_T1); */
1453*3ac0a46fSAndroid Build Coastguard Worker         if (! opj_tcd_t1_encode(p_tcd)) {
1454*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
1455*3ac0a46fSAndroid Build Coastguard Worker         }
1456*3ac0a46fSAndroid Build Coastguard Worker         /* FIXME _ProfStop(PGROUP_T1); */
1457*3ac0a46fSAndroid Build Coastguard Worker 
1458*3ac0a46fSAndroid Build Coastguard Worker         /* FIXME _ProfStart(PGROUP_RATE); */
1459*3ac0a46fSAndroid Build Coastguard Worker         if (! opj_tcd_rate_allocate_encode(p_tcd, p_dest, p_max_length,
1460*3ac0a46fSAndroid Build Coastguard Worker                                            p_cstr_info, p_manager)) {
1461*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
1462*3ac0a46fSAndroid Build Coastguard Worker         }
1463*3ac0a46fSAndroid Build Coastguard Worker         /* FIXME _ProfStop(PGROUP_RATE); */
1464*3ac0a46fSAndroid Build Coastguard Worker 
1465*3ac0a46fSAndroid Build Coastguard Worker     }
1466*3ac0a46fSAndroid Build Coastguard Worker     /*--------------TIER2------------------*/
1467*3ac0a46fSAndroid Build Coastguard Worker 
1468*3ac0a46fSAndroid Build Coastguard Worker     /* INDEX */
1469*3ac0a46fSAndroid Build Coastguard Worker     if (p_cstr_info) {
1470*3ac0a46fSAndroid Build Coastguard Worker         p_cstr_info->index_write = 1;
1471*3ac0a46fSAndroid Build Coastguard Worker     }
1472*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStart(PGROUP_T2); */
1473*3ac0a46fSAndroid Build Coastguard Worker 
1474*3ac0a46fSAndroid Build Coastguard Worker     if (! opj_tcd_t2_encode(p_tcd, p_dest, p_data_written, p_max_length,
1475*3ac0a46fSAndroid Build Coastguard Worker                             p_cstr_info, p_marker_info, p_manager)) {
1476*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
1477*3ac0a46fSAndroid Build Coastguard Worker     }
1478*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStop(PGROUP_T2); */
1479*3ac0a46fSAndroid Build Coastguard Worker 
1480*3ac0a46fSAndroid Build Coastguard Worker     /*---------------CLEAN-------------------*/
1481*3ac0a46fSAndroid Build Coastguard Worker 
1482*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
1483*3ac0a46fSAndroid Build Coastguard Worker }
1484*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_decode_tile(opj_tcd_t * p_tcd,OPJ_UINT32 win_x0,OPJ_UINT32 win_y0,OPJ_UINT32 win_x1,OPJ_UINT32 win_y1,OPJ_UINT32 numcomps_to_decode,const OPJ_UINT32 * comps_indices,OPJ_BYTE * p_src,OPJ_UINT32 p_max_length,OPJ_UINT32 p_tile_no,opj_codestream_index_t * p_cstr_index,opj_event_mgr_t * p_manager)1485*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *p_tcd,
1486*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 win_x0,
1487*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 win_y0,
1488*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 win_x1,
1489*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 win_y1,
1490*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 numcomps_to_decode,
1491*3ac0a46fSAndroid Build Coastguard Worker                              const OPJ_UINT32 *comps_indices,
1492*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_BYTE *p_src,
1493*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 p_max_length,
1494*3ac0a46fSAndroid Build Coastguard Worker                              OPJ_UINT32 p_tile_no,
1495*3ac0a46fSAndroid Build Coastguard Worker                              opj_codestream_index_t *p_cstr_index,
1496*3ac0a46fSAndroid Build Coastguard Worker                              opj_event_mgr_t *p_manager
1497*3ac0a46fSAndroid Build Coastguard Worker                             )
1498*3ac0a46fSAndroid Build Coastguard Worker {
1499*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_data_read;
1500*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno;
1501*3ac0a46fSAndroid Build Coastguard Worker 
1502*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->tcd_tileno = p_tile_no;
1503*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->tcp = &(p_tcd->cp->tcps[p_tile_no]);
1504*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->win_x0 = win_x0;
1505*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->win_y0 = win_y0;
1506*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->win_x1 = win_x1;
1507*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->win_y1 = win_y1;
1508*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->whole_tile_decoding = OPJ_TRUE;
1509*3ac0a46fSAndroid Build Coastguard Worker 
1510*3ac0a46fSAndroid Build Coastguard Worker     opj_free(p_tcd->used_component);
1511*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->used_component = NULL;
1512*3ac0a46fSAndroid Build Coastguard Worker 
1513*3ac0a46fSAndroid Build Coastguard Worker     if (numcomps_to_decode) {
1514*3ac0a46fSAndroid Build Coastguard Worker         OPJ_BOOL* used_component = (OPJ_BOOL*) opj_calloc(sizeof(OPJ_BOOL),
1515*3ac0a46fSAndroid Build Coastguard Worker                                    p_tcd->image->numcomps);
1516*3ac0a46fSAndroid Build Coastguard Worker         if (used_component == NULL) {
1517*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
1518*3ac0a46fSAndroid Build Coastguard Worker         }
1519*3ac0a46fSAndroid Build Coastguard Worker         for (compno = 0; compno < numcomps_to_decode; compno++) {
1520*3ac0a46fSAndroid Build Coastguard Worker             used_component[ comps_indices[compno] ] = OPJ_TRUE;
1521*3ac0a46fSAndroid Build Coastguard Worker         }
1522*3ac0a46fSAndroid Build Coastguard Worker 
1523*3ac0a46fSAndroid Build Coastguard Worker         p_tcd->used_component = used_component;
1524*3ac0a46fSAndroid Build Coastguard Worker     }
1525*3ac0a46fSAndroid Build Coastguard Worker 
1526*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < p_tcd->image->numcomps; compno++) {
1527*3ac0a46fSAndroid Build Coastguard Worker         if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) {
1528*3ac0a46fSAndroid Build Coastguard Worker             continue;
1529*3ac0a46fSAndroid Build Coastguard Worker         }
1530*3ac0a46fSAndroid Build Coastguard Worker 
1531*3ac0a46fSAndroid Build Coastguard Worker         if (!opj_tcd_is_whole_tilecomp_decoding(p_tcd, compno)) {
1532*3ac0a46fSAndroid Build Coastguard Worker             p_tcd->whole_tile_decoding = OPJ_FALSE;
1533*3ac0a46fSAndroid Build Coastguard Worker             break;
1534*3ac0a46fSAndroid Build Coastguard Worker         }
1535*3ac0a46fSAndroid Build Coastguard Worker     }
1536*3ac0a46fSAndroid Build Coastguard Worker 
1537*3ac0a46fSAndroid Build Coastguard Worker     if (p_tcd->whole_tile_decoding) {
1538*3ac0a46fSAndroid Build Coastguard Worker         for (compno = 0; compno < p_tcd->image->numcomps; compno++) {
1539*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_tilecomp_t* tilec = &(p_tcd->tcd_image->tiles->comps[compno]);
1540*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_resolution_t *l_res = &
1541*3ac0a46fSAndroid Build Coastguard Worker                                           (tilec->resolutions[tilec->minimum_num_resolutions - 1]);
1542*3ac0a46fSAndroid Build Coastguard Worker             OPJ_SIZE_T l_data_size;
1543*3ac0a46fSAndroid Build Coastguard Worker 
1544*3ac0a46fSAndroid Build Coastguard Worker             /* compute l_data_size with overflow check */
1545*3ac0a46fSAndroid Build Coastguard Worker             OPJ_SIZE_T res_w = (OPJ_SIZE_T)(l_res->x1 - l_res->x0);
1546*3ac0a46fSAndroid Build Coastguard Worker             OPJ_SIZE_T res_h = (OPJ_SIZE_T)(l_res->y1 - l_res->y0);
1547*3ac0a46fSAndroid Build Coastguard Worker 
1548*3ac0a46fSAndroid Build Coastguard Worker             if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) {
1549*3ac0a46fSAndroid Build Coastguard Worker                 continue;
1550*3ac0a46fSAndroid Build Coastguard Worker             }
1551*3ac0a46fSAndroid Build Coastguard Worker 
1552*3ac0a46fSAndroid Build Coastguard Worker             /* issue 733, l_data_size == 0U, probably something wrong should be checked before getting here */
1553*3ac0a46fSAndroid Build Coastguard Worker             if (res_h > 0 && res_w > SIZE_MAX / res_h) {
1554*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(p_manager, EVT_ERROR,
1555*3ac0a46fSAndroid Build Coastguard Worker                               "Size of tile data exceeds system limits\n");
1556*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
1557*3ac0a46fSAndroid Build Coastguard Worker             }
1558*3ac0a46fSAndroid Build Coastguard Worker             l_data_size = res_w * res_h;
1559*3ac0a46fSAndroid Build Coastguard Worker 
1560*3ac0a46fSAndroid Build Coastguard Worker             if (SIZE_MAX / sizeof(OPJ_UINT32) < l_data_size) {
1561*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(p_manager, EVT_ERROR,
1562*3ac0a46fSAndroid Build Coastguard Worker                               "Size of tile data exceeds system limits\n");
1563*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
1564*3ac0a46fSAndroid Build Coastguard Worker             }
1565*3ac0a46fSAndroid Build Coastguard Worker             l_data_size *= sizeof(OPJ_UINT32);
1566*3ac0a46fSAndroid Build Coastguard Worker 
1567*3ac0a46fSAndroid Build Coastguard Worker             tilec->data_size_needed = l_data_size;
1568*3ac0a46fSAndroid Build Coastguard Worker 
1569*3ac0a46fSAndroid Build Coastguard Worker             if (!opj_alloc_tile_component_data(tilec)) {
1570*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(p_manager, EVT_ERROR,
1571*3ac0a46fSAndroid Build Coastguard Worker                               "Size of tile data exceeds system limits\n");
1572*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
1573*3ac0a46fSAndroid Build Coastguard Worker             }
1574*3ac0a46fSAndroid Build Coastguard Worker         }
1575*3ac0a46fSAndroid Build Coastguard Worker     } else {
1576*3ac0a46fSAndroid Build Coastguard Worker         /* Compute restricted tile-component and tile-resolution coordinates */
1577*3ac0a46fSAndroid Build Coastguard Worker         /* of the window of interest, but defer the memory allocation until */
1578*3ac0a46fSAndroid Build Coastguard Worker         /* we know the resno_decoded */
1579*3ac0a46fSAndroid Build Coastguard Worker         for (compno = 0; compno < p_tcd->image->numcomps; compno++) {
1580*3ac0a46fSAndroid Build Coastguard Worker             OPJ_UINT32 resno;
1581*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_tilecomp_t* tilec = &(p_tcd->tcd_image->tiles->comps[compno]);
1582*3ac0a46fSAndroid Build Coastguard Worker             opj_image_comp_t* image_comp = &(p_tcd->image->comps[compno]);
1583*3ac0a46fSAndroid Build Coastguard Worker 
1584*3ac0a46fSAndroid Build Coastguard Worker             if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) {
1585*3ac0a46fSAndroid Build Coastguard Worker                 continue;
1586*3ac0a46fSAndroid Build Coastguard Worker             }
1587*3ac0a46fSAndroid Build Coastguard Worker 
1588*3ac0a46fSAndroid Build Coastguard Worker             /* Compute the intersection of the area of interest, expressed in tile coordinates */
1589*3ac0a46fSAndroid Build Coastguard Worker             /* with the tile coordinates */
1590*3ac0a46fSAndroid Build Coastguard Worker             tilec->win_x0 = opj_uint_max(
1591*3ac0a46fSAndroid Build Coastguard Worker                                 (OPJ_UINT32)tilec->x0,
1592*3ac0a46fSAndroid Build Coastguard Worker                                 opj_uint_ceildiv(p_tcd->win_x0, image_comp->dx));
1593*3ac0a46fSAndroid Build Coastguard Worker             tilec->win_y0 = opj_uint_max(
1594*3ac0a46fSAndroid Build Coastguard Worker                                 (OPJ_UINT32)tilec->y0,
1595*3ac0a46fSAndroid Build Coastguard Worker                                 opj_uint_ceildiv(p_tcd->win_y0, image_comp->dy));
1596*3ac0a46fSAndroid Build Coastguard Worker             tilec->win_x1 = opj_uint_min(
1597*3ac0a46fSAndroid Build Coastguard Worker                                 (OPJ_UINT32)tilec->x1,
1598*3ac0a46fSAndroid Build Coastguard Worker                                 opj_uint_ceildiv(p_tcd->win_x1, image_comp->dx));
1599*3ac0a46fSAndroid Build Coastguard Worker             tilec->win_y1 = opj_uint_min(
1600*3ac0a46fSAndroid Build Coastguard Worker                                 (OPJ_UINT32)tilec->y1,
1601*3ac0a46fSAndroid Build Coastguard Worker                                 opj_uint_ceildiv(p_tcd->win_y1, image_comp->dy));
1602*3ac0a46fSAndroid Build Coastguard Worker             if (tilec->win_x1 < tilec->win_x0 ||
1603*3ac0a46fSAndroid Build Coastguard Worker                     tilec->win_y1 < tilec->win_y0) {
1604*3ac0a46fSAndroid Build Coastguard Worker                 /* We should not normally go there. The circumstance is when */
1605*3ac0a46fSAndroid Build Coastguard Worker                 /* the tile coordinates do not intersect the area of interest */
1606*3ac0a46fSAndroid Build Coastguard Worker                 /* Upper level logic should not even try to decode that tile */
1607*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(p_manager, EVT_ERROR,
1608*3ac0a46fSAndroid Build Coastguard Worker                               "Invalid tilec->win_xxx values\n");
1609*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
1610*3ac0a46fSAndroid Build Coastguard Worker             }
1611*3ac0a46fSAndroid Build Coastguard Worker 
1612*3ac0a46fSAndroid Build Coastguard Worker             for (resno = 0; resno < tilec->numresolutions; ++resno) {
1613*3ac0a46fSAndroid Build Coastguard Worker                 opj_tcd_resolution_t *res = tilec->resolutions + resno;
1614*3ac0a46fSAndroid Build Coastguard Worker                 res->win_x0 = opj_uint_ceildivpow2(tilec->win_x0,
1615*3ac0a46fSAndroid Build Coastguard Worker                                                    tilec->numresolutions - 1 - resno);
1616*3ac0a46fSAndroid Build Coastguard Worker                 res->win_y0 = opj_uint_ceildivpow2(tilec->win_y0,
1617*3ac0a46fSAndroid Build Coastguard Worker                                                    tilec->numresolutions - 1 - resno);
1618*3ac0a46fSAndroid Build Coastguard Worker                 res->win_x1 = opj_uint_ceildivpow2(tilec->win_x1,
1619*3ac0a46fSAndroid Build Coastguard Worker                                                    tilec->numresolutions - 1 - resno);
1620*3ac0a46fSAndroid Build Coastguard Worker                 res->win_y1 = opj_uint_ceildivpow2(tilec->win_y1,
1621*3ac0a46fSAndroid Build Coastguard Worker                                                    tilec->numresolutions - 1 - resno);
1622*3ac0a46fSAndroid Build Coastguard Worker             }
1623*3ac0a46fSAndroid Build Coastguard Worker         }
1624*3ac0a46fSAndroid Build Coastguard Worker     }
1625*3ac0a46fSAndroid Build Coastguard Worker 
1626*3ac0a46fSAndroid Build Coastguard Worker #ifdef TODO_MSD /* FIXME */
1627*3ac0a46fSAndroid Build Coastguard Worker     /* INDEX >>  */
1628*3ac0a46fSAndroid Build Coastguard Worker     if (p_cstr_info) {
1629*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 resno, compno, numprec = 0;
1630*3ac0a46fSAndroid Build Coastguard Worker         for (compno = 0; compno < (OPJ_UINT32) p_cstr_info->numcomps; compno++) {
1631*3ac0a46fSAndroid Build Coastguard Worker             opj_tcp_t *tcp = &p_tcd->cp->tcps[0];
1632*3ac0a46fSAndroid Build Coastguard Worker             opj_tccp_t *tccp = &tcp->tccps[compno];
1633*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_tilecomp_t *tilec_idx = &p_tcd->tcd_image->tiles->comps[compno];
1634*3ac0a46fSAndroid Build Coastguard Worker             for (resno = 0; resno < tilec_idx->numresolutions; resno++) {
1635*3ac0a46fSAndroid Build Coastguard Worker                 opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[resno];
1636*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_info->tile[p_tile_no].pw[resno] = res_idx->pw;
1637*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_info->tile[p_tile_no].ph[resno] = res_idx->ph;
1638*3ac0a46fSAndroid Build Coastguard Worker                 numprec += res_idx->pw * res_idx->ph;
1639*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_info->tile[p_tile_no].pdx[resno] = tccp->prcw[resno];
1640*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_info->tile[p_tile_no].pdy[resno] = tccp->prch[resno];
1641*3ac0a46fSAndroid Build Coastguard Worker             }
1642*3ac0a46fSAndroid Build Coastguard Worker         }
1643*3ac0a46fSAndroid Build Coastguard Worker         p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t *) opj_malloc(
1644*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_info->numlayers * numprec * sizeof(opj_packet_info_t));
1645*3ac0a46fSAndroid Build Coastguard Worker         p_cstr_info->packno = 0;
1646*3ac0a46fSAndroid Build Coastguard Worker     }
1647*3ac0a46fSAndroid Build Coastguard Worker     /* << INDEX */
1648*3ac0a46fSAndroid Build Coastguard Worker #endif
1649*3ac0a46fSAndroid Build Coastguard Worker 
1650*3ac0a46fSAndroid Build Coastguard Worker     /*--------------TIER2------------------*/
1651*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStart(PGROUP_T2); */
1652*3ac0a46fSAndroid Build Coastguard Worker     l_data_read = 0;
1653*3ac0a46fSAndroid Build Coastguard Worker     if (! opj_tcd_t2_decode(p_tcd, p_src, &l_data_read, p_max_length, p_cstr_index,
1654*3ac0a46fSAndroid Build Coastguard Worker                             p_manager)) {
1655*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
1656*3ac0a46fSAndroid Build Coastguard Worker     }
1657*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStop(PGROUP_T2); */
1658*3ac0a46fSAndroid Build Coastguard Worker 
1659*3ac0a46fSAndroid Build Coastguard Worker     /*------------------TIER1-----------------*/
1660*3ac0a46fSAndroid Build Coastguard Worker 
1661*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStart(PGROUP_T1); */
1662*3ac0a46fSAndroid Build Coastguard Worker     if (! opj_tcd_t1_decode(p_tcd, p_manager)) {
1663*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
1664*3ac0a46fSAndroid Build Coastguard Worker     }
1665*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStop(PGROUP_T1); */
1666*3ac0a46fSAndroid Build Coastguard Worker 
1667*3ac0a46fSAndroid Build Coastguard Worker 
1668*3ac0a46fSAndroid Build Coastguard Worker     /* For subtile decoding, now we know the resno_decoded, we can allocate */
1669*3ac0a46fSAndroid Build Coastguard Worker     /* the tile data buffer */
1670*3ac0a46fSAndroid Build Coastguard Worker     if (!p_tcd->whole_tile_decoding) {
1671*3ac0a46fSAndroid Build Coastguard Worker         for (compno = 0; compno < p_tcd->image->numcomps; compno++) {
1672*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_tilecomp_t* tilec = &(p_tcd->tcd_image->tiles->comps[compno]);
1673*3ac0a46fSAndroid Build Coastguard Worker             opj_image_comp_t* image_comp = &(p_tcd->image->comps[compno]);
1674*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_resolution_t *res = tilec->resolutions + image_comp->resno_decoded;
1675*3ac0a46fSAndroid Build Coastguard Worker             OPJ_SIZE_T w = res->win_x1 - res->win_x0;
1676*3ac0a46fSAndroid Build Coastguard Worker             OPJ_SIZE_T h = res->win_y1 - res->win_y0;
1677*3ac0a46fSAndroid Build Coastguard Worker             OPJ_SIZE_T l_data_size;
1678*3ac0a46fSAndroid Build Coastguard Worker 
1679*3ac0a46fSAndroid Build Coastguard Worker             opj_image_data_free(tilec->data_win);
1680*3ac0a46fSAndroid Build Coastguard Worker             tilec->data_win = NULL;
1681*3ac0a46fSAndroid Build Coastguard Worker 
1682*3ac0a46fSAndroid Build Coastguard Worker             if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) {
1683*3ac0a46fSAndroid Build Coastguard Worker                 continue;
1684*3ac0a46fSAndroid Build Coastguard Worker             }
1685*3ac0a46fSAndroid Build Coastguard Worker 
1686*3ac0a46fSAndroid Build Coastguard Worker             if (w > 0 && h > 0) {
1687*3ac0a46fSAndroid Build Coastguard Worker                 if (w > SIZE_MAX / h) {
1688*3ac0a46fSAndroid Build Coastguard Worker                     opj_event_msg(p_manager, EVT_ERROR,
1689*3ac0a46fSAndroid Build Coastguard Worker                                   "Size of tile data exceeds system limits\n");
1690*3ac0a46fSAndroid Build Coastguard Worker                     return OPJ_FALSE;
1691*3ac0a46fSAndroid Build Coastguard Worker                 }
1692*3ac0a46fSAndroid Build Coastguard Worker                 l_data_size = w * h;
1693*3ac0a46fSAndroid Build Coastguard Worker                 if (l_data_size > SIZE_MAX / sizeof(OPJ_INT32)) {
1694*3ac0a46fSAndroid Build Coastguard Worker                     opj_event_msg(p_manager, EVT_ERROR,
1695*3ac0a46fSAndroid Build Coastguard Worker                                   "Size of tile data exceeds system limits\n");
1696*3ac0a46fSAndroid Build Coastguard Worker                     return OPJ_FALSE;
1697*3ac0a46fSAndroid Build Coastguard Worker                 }
1698*3ac0a46fSAndroid Build Coastguard Worker                 l_data_size *= sizeof(OPJ_INT32);
1699*3ac0a46fSAndroid Build Coastguard Worker 
1700*3ac0a46fSAndroid Build Coastguard Worker                 tilec->data_win = (OPJ_INT32*) opj_image_data_alloc(l_data_size);
1701*3ac0a46fSAndroid Build Coastguard Worker                 if (tilec->data_win == NULL) {
1702*3ac0a46fSAndroid Build Coastguard Worker                     opj_event_msg(p_manager, EVT_ERROR,
1703*3ac0a46fSAndroid Build Coastguard Worker                                   "Size of tile data exceeds system limits\n");
1704*3ac0a46fSAndroid Build Coastguard Worker                     return OPJ_FALSE;
1705*3ac0a46fSAndroid Build Coastguard Worker                 }
1706*3ac0a46fSAndroid Build Coastguard Worker             }
1707*3ac0a46fSAndroid Build Coastguard Worker         }
1708*3ac0a46fSAndroid Build Coastguard Worker     }
1709*3ac0a46fSAndroid Build Coastguard Worker 
1710*3ac0a46fSAndroid Build Coastguard Worker     /*----------------DWT---------------------*/
1711*3ac0a46fSAndroid Build Coastguard Worker 
1712*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStart(PGROUP_DWT); */
1713*3ac0a46fSAndroid Build Coastguard Worker     if
1714*3ac0a46fSAndroid Build Coastguard Worker     (! opj_tcd_dwt_decode(p_tcd)) {
1715*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
1716*3ac0a46fSAndroid Build Coastguard Worker     }
1717*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStop(PGROUP_DWT); */
1718*3ac0a46fSAndroid Build Coastguard Worker 
1719*3ac0a46fSAndroid Build Coastguard Worker     /*----------------MCT-------------------*/
1720*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStart(PGROUP_MCT); */
1721*3ac0a46fSAndroid Build Coastguard Worker     if
1722*3ac0a46fSAndroid Build Coastguard Worker     (! opj_tcd_mct_decode(p_tcd, p_manager)) {
1723*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
1724*3ac0a46fSAndroid Build Coastguard Worker     }
1725*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStop(PGROUP_MCT); */
1726*3ac0a46fSAndroid Build Coastguard Worker 
1727*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStart(PGROUP_DC_SHIFT); */
1728*3ac0a46fSAndroid Build Coastguard Worker     if
1729*3ac0a46fSAndroid Build Coastguard Worker     (! opj_tcd_dc_level_shift_decode(p_tcd)) {
1730*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
1731*3ac0a46fSAndroid Build Coastguard Worker     }
1732*3ac0a46fSAndroid Build Coastguard Worker     /* FIXME _ProfStop(PGROUP_DC_SHIFT); */
1733*3ac0a46fSAndroid Build Coastguard Worker 
1734*3ac0a46fSAndroid Build Coastguard Worker 
1735*3ac0a46fSAndroid Build Coastguard Worker     /*---------------TILE-------------------*/
1736*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
1737*3ac0a46fSAndroid Build Coastguard Worker }
1738*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_update_tile_data(opj_tcd_t * p_tcd,OPJ_BYTE * p_dest,OPJ_UINT32 p_dest_length)1739*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_tcd_update_tile_data(opj_tcd_t *p_tcd,
1740*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_BYTE * p_dest,
1741*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_UINT32 p_dest_length
1742*3ac0a46fSAndroid Build Coastguard Worker                                  )
1743*3ac0a46fSAndroid Build Coastguard Worker {
1744*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 i, j, k, l_data_size = 0;
1745*3ac0a46fSAndroid Build Coastguard Worker     opj_image_comp_t * l_img_comp = 00;
1746*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t * l_tilec = 00;
1747*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_resolution_t * l_res;
1748*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_size_comp, l_remaining;
1749*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_stride, l_width, l_height;
1750*3ac0a46fSAndroid Build Coastguard Worker 
1751*3ac0a46fSAndroid Build Coastguard Worker     l_data_size = opj_tcd_get_decoded_tile_size(p_tcd, OPJ_TRUE);
1752*3ac0a46fSAndroid Build Coastguard Worker     if (l_data_size == UINT_MAX || l_data_size > p_dest_length) {
1753*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
1754*3ac0a46fSAndroid Build Coastguard Worker     }
1755*3ac0a46fSAndroid Build Coastguard Worker 
1756*3ac0a46fSAndroid Build Coastguard Worker     l_tilec = p_tcd->tcd_image->tiles->comps;
1757*3ac0a46fSAndroid Build Coastguard Worker     l_img_comp = p_tcd->image->comps;
1758*3ac0a46fSAndroid Build Coastguard Worker 
1759*3ac0a46fSAndroid Build Coastguard Worker     for (i = 0; i < p_tcd->image->numcomps; ++i) {
1760*3ac0a46fSAndroid Build Coastguard Worker         const OPJ_INT32* l_src_data;
1761*3ac0a46fSAndroid Build Coastguard Worker         l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
1762*3ac0a46fSAndroid Build Coastguard Worker         l_remaining = l_img_comp->prec & 7;  /* (%8) */
1763*3ac0a46fSAndroid Build Coastguard Worker         l_res = l_tilec->resolutions + l_img_comp->resno_decoded;
1764*3ac0a46fSAndroid Build Coastguard Worker         if (p_tcd->whole_tile_decoding) {
1765*3ac0a46fSAndroid Build Coastguard Worker             l_width = (OPJ_UINT32)(l_res->x1 - l_res->x0);
1766*3ac0a46fSAndroid Build Coastguard Worker             l_height = (OPJ_UINT32)(l_res->y1 - l_res->y0);
1767*3ac0a46fSAndroid Build Coastguard Worker             l_stride = (OPJ_UINT32)(l_tilec->resolutions[l_tilec->minimum_num_resolutions -
1768*3ac0a46fSAndroid Build Coastguard Worker                                                                      1].x1 -
1769*3ac0a46fSAndroid Build Coastguard Worker                                     l_tilec->resolutions[l_tilec->minimum_num_resolutions - 1].x0) - l_width;
1770*3ac0a46fSAndroid Build Coastguard Worker             l_src_data = l_tilec->data;
1771*3ac0a46fSAndroid Build Coastguard Worker         } else {
1772*3ac0a46fSAndroid Build Coastguard Worker             l_width = l_res->win_x1 - l_res->win_x0;
1773*3ac0a46fSAndroid Build Coastguard Worker             l_height = l_res->win_y1 - l_res->win_y0;
1774*3ac0a46fSAndroid Build Coastguard Worker             l_stride = 0;
1775*3ac0a46fSAndroid Build Coastguard Worker             l_src_data = l_tilec->data_win;
1776*3ac0a46fSAndroid Build Coastguard Worker         }
1777*3ac0a46fSAndroid Build Coastguard Worker 
1778*3ac0a46fSAndroid Build Coastguard Worker         if (l_remaining) {
1779*3ac0a46fSAndroid Build Coastguard Worker             ++l_size_comp;
1780*3ac0a46fSAndroid Build Coastguard Worker         }
1781*3ac0a46fSAndroid Build Coastguard Worker 
1782*3ac0a46fSAndroid Build Coastguard Worker         if (l_size_comp == 3) {
1783*3ac0a46fSAndroid Build Coastguard Worker             l_size_comp = 4;
1784*3ac0a46fSAndroid Build Coastguard Worker         }
1785*3ac0a46fSAndroid Build Coastguard Worker 
1786*3ac0a46fSAndroid Build Coastguard Worker         switch (l_size_comp) {
1787*3ac0a46fSAndroid Build Coastguard Worker         case 1: {
1788*3ac0a46fSAndroid Build Coastguard Worker             OPJ_CHAR * l_dest_ptr = (OPJ_CHAR *) p_dest;
1789*3ac0a46fSAndroid Build Coastguard Worker             const OPJ_INT32 * l_src_ptr = l_src_data;
1790*3ac0a46fSAndroid Build Coastguard Worker 
1791*3ac0a46fSAndroid Build Coastguard Worker             if (l_img_comp->sgnd) {
1792*3ac0a46fSAndroid Build Coastguard Worker                 for (j = 0; j < l_height; ++j) {
1793*3ac0a46fSAndroid Build Coastguard Worker                     for (k = 0; k < l_width; ++k) {
1794*3ac0a46fSAndroid Build Coastguard Worker                         *(l_dest_ptr++) = (OPJ_CHAR)(*(l_src_ptr++));
1795*3ac0a46fSAndroid Build Coastguard Worker                     }
1796*3ac0a46fSAndroid Build Coastguard Worker                     l_src_ptr += l_stride;
1797*3ac0a46fSAndroid Build Coastguard Worker                 }
1798*3ac0a46fSAndroid Build Coastguard Worker             } else {
1799*3ac0a46fSAndroid Build Coastguard Worker                 for (j = 0; j < l_height; ++j) {
1800*3ac0a46fSAndroid Build Coastguard Worker                     for (k = 0; k < l_width; ++k) {
1801*3ac0a46fSAndroid Build Coastguard Worker                         *(l_dest_ptr++) = (OPJ_CHAR)((*(l_src_ptr++)) & 0xff);
1802*3ac0a46fSAndroid Build Coastguard Worker                     }
1803*3ac0a46fSAndroid Build Coastguard Worker                     l_src_ptr += l_stride;
1804*3ac0a46fSAndroid Build Coastguard Worker                 }
1805*3ac0a46fSAndroid Build Coastguard Worker             }
1806*3ac0a46fSAndroid Build Coastguard Worker 
1807*3ac0a46fSAndroid Build Coastguard Worker             p_dest = (OPJ_BYTE *)l_dest_ptr;
1808*3ac0a46fSAndroid Build Coastguard Worker         }
1809*3ac0a46fSAndroid Build Coastguard Worker         break;
1810*3ac0a46fSAndroid Build Coastguard Worker         case 2: {
1811*3ac0a46fSAndroid Build Coastguard Worker             const OPJ_INT32 * l_src_ptr = l_src_data;
1812*3ac0a46fSAndroid Build Coastguard Worker             OPJ_INT16 * l_dest_ptr = (OPJ_INT16 *) p_dest;
1813*3ac0a46fSAndroid Build Coastguard Worker 
1814*3ac0a46fSAndroid Build Coastguard Worker             if (l_img_comp->sgnd) {
1815*3ac0a46fSAndroid Build Coastguard Worker                 for (j = 0; j < l_height; ++j) {
1816*3ac0a46fSAndroid Build Coastguard Worker                     for (k = 0; k < l_width; ++k) {
1817*3ac0a46fSAndroid Build Coastguard Worker                         OPJ_INT16 val = (OPJ_INT16)(*(l_src_ptr++));
1818*3ac0a46fSAndroid Build Coastguard Worker                         memcpy(l_dest_ptr, &val, sizeof(val));
1819*3ac0a46fSAndroid Build Coastguard Worker                         l_dest_ptr ++;
1820*3ac0a46fSAndroid Build Coastguard Worker                     }
1821*3ac0a46fSAndroid Build Coastguard Worker                     l_src_ptr += l_stride;
1822*3ac0a46fSAndroid Build Coastguard Worker                 }
1823*3ac0a46fSAndroid Build Coastguard Worker             } else {
1824*3ac0a46fSAndroid Build Coastguard Worker                 for (j = 0; j < l_height; ++j) {
1825*3ac0a46fSAndroid Build Coastguard Worker                     for (k = 0; k < l_width; ++k) {
1826*3ac0a46fSAndroid Build Coastguard Worker                         OPJ_INT16 val = (OPJ_INT16)((*(l_src_ptr++)) & 0xffff);
1827*3ac0a46fSAndroid Build Coastguard Worker                         memcpy(l_dest_ptr, &val, sizeof(val));
1828*3ac0a46fSAndroid Build Coastguard Worker                         l_dest_ptr ++;
1829*3ac0a46fSAndroid Build Coastguard Worker                     }
1830*3ac0a46fSAndroid Build Coastguard Worker                     l_src_ptr += l_stride;
1831*3ac0a46fSAndroid Build Coastguard Worker                 }
1832*3ac0a46fSAndroid Build Coastguard Worker             }
1833*3ac0a46fSAndroid Build Coastguard Worker 
1834*3ac0a46fSAndroid Build Coastguard Worker             p_dest = (OPJ_BYTE*) l_dest_ptr;
1835*3ac0a46fSAndroid Build Coastguard Worker         }
1836*3ac0a46fSAndroid Build Coastguard Worker         break;
1837*3ac0a46fSAndroid Build Coastguard Worker         case 4: {
1838*3ac0a46fSAndroid Build Coastguard Worker             OPJ_INT32 * l_dest_ptr = (OPJ_INT32 *) p_dest;
1839*3ac0a46fSAndroid Build Coastguard Worker             const OPJ_INT32 * l_src_ptr = l_src_data;
1840*3ac0a46fSAndroid Build Coastguard Worker 
1841*3ac0a46fSAndroid Build Coastguard Worker             for (j = 0; j < l_height; ++j) {
1842*3ac0a46fSAndroid Build Coastguard Worker                 memcpy(l_dest_ptr, l_src_ptr, l_width * sizeof(OPJ_INT32));
1843*3ac0a46fSAndroid Build Coastguard Worker                 l_dest_ptr += l_width;
1844*3ac0a46fSAndroid Build Coastguard Worker                 l_src_ptr += l_width + l_stride;
1845*3ac0a46fSAndroid Build Coastguard Worker             }
1846*3ac0a46fSAndroid Build Coastguard Worker 
1847*3ac0a46fSAndroid Build Coastguard Worker             p_dest = (OPJ_BYTE*) l_dest_ptr;
1848*3ac0a46fSAndroid Build Coastguard Worker         }
1849*3ac0a46fSAndroid Build Coastguard Worker         break;
1850*3ac0a46fSAndroid Build Coastguard Worker         }
1851*3ac0a46fSAndroid Build Coastguard Worker 
1852*3ac0a46fSAndroid Build Coastguard Worker         ++l_img_comp;
1853*3ac0a46fSAndroid Build Coastguard Worker         ++l_tilec;
1854*3ac0a46fSAndroid Build Coastguard Worker     }
1855*3ac0a46fSAndroid Build Coastguard Worker 
1856*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
1857*3ac0a46fSAndroid Build Coastguard Worker }
1858*3ac0a46fSAndroid Build Coastguard Worker 
1859*3ac0a46fSAndroid Build Coastguard Worker 
1860*3ac0a46fSAndroid Build Coastguard Worker 
1861*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_free_tile(opj_tcd_t * p_tcd)1862*3ac0a46fSAndroid Build Coastguard Worker static void opj_tcd_free_tile(opj_tcd_t *p_tcd)
1863*3ac0a46fSAndroid Build Coastguard Worker {
1864*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno, resno, bandno, precno;
1865*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t *l_tile = 00;
1866*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t *l_tile_comp = 00;
1867*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_resolution_t *l_res = 00;
1868*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_band_t *l_band = 00;
1869*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_precinct_t *l_precinct = 00;
1870*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_nb_resolutions, l_nb_precincts;
1871*3ac0a46fSAndroid Build Coastguard Worker     void (* l_tcd_code_block_deallocate)(opj_tcd_precinct_t *) = 00;
1872*3ac0a46fSAndroid Build Coastguard Worker 
1873*3ac0a46fSAndroid Build Coastguard Worker     if (! p_tcd) {
1874*3ac0a46fSAndroid Build Coastguard Worker         return;
1875*3ac0a46fSAndroid Build Coastguard Worker     }
1876*3ac0a46fSAndroid Build Coastguard Worker 
1877*3ac0a46fSAndroid Build Coastguard Worker     if (! p_tcd->tcd_image) {
1878*3ac0a46fSAndroid Build Coastguard Worker         return;
1879*3ac0a46fSAndroid Build Coastguard Worker     }
1880*3ac0a46fSAndroid Build Coastguard Worker 
1881*3ac0a46fSAndroid Build Coastguard Worker     if (p_tcd->m_is_decoder) {
1882*3ac0a46fSAndroid Build Coastguard Worker         l_tcd_code_block_deallocate = opj_tcd_code_block_dec_deallocate;
1883*3ac0a46fSAndroid Build Coastguard Worker     } else {
1884*3ac0a46fSAndroid Build Coastguard Worker         l_tcd_code_block_deallocate = opj_tcd_code_block_enc_deallocate;
1885*3ac0a46fSAndroid Build Coastguard Worker     }
1886*3ac0a46fSAndroid Build Coastguard Worker 
1887*3ac0a46fSAndroid Build Coastguard Worker     l_tile = p_tcd->tcd_image->tiles;
1888*3ac0a46fSAndroid Build Coastguard Worker     if (! l_tile) {
1889*3ac0a46fSAndroid Build Coastguard Worker         return;
1890*3ac0a46fSAndroid Build Coastguard Worker     }
1891*3ac0a46fSAndroid Build Coastguard Worker 
1892*3ac0a46fSAndroid Build Coastguard Worker     l_tile_comp = l_tile->comps;
1893*3ac0a46fSAndroid Build Coastguard Worker 
1894*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < l_tile->numcomps; ++compno) {
1895*3ac0a46fSAndroid Build Coastguard Worker         l_res = l_tile_comp->resolutions;
1896*3ac0a46fSAndroid Build Coastguard Worker         if (l_res) {
1897*3ac0a46fSAndroid Build Coastguard Worker 
1898*3ac0a46fSAndroid Build Coastguard Worker             l_nb_resolutions = l_tile_comp->resolutions_size / (OPJ_UINT32)sizeof(
1899*3ac0a46fSAndroid Build Coastguard Worker                                    opj_tcd_resolution_t);
1900*3ac0a46fSAndroid Build Coastguard Worker             for (resno = 0; resno < l_nb_resolutions; ++resno) {
1901*3ac0a46fSAndroid Build Coastguard Worker                 l_band = l_res->bands;
1902*3ac0a46fSAndroid Build Coastguard Worker                 for (bandno = 0; bandno < 3; ++bandno) {
1903*3ac0a46fSAndroid Build Coastguard Worker                     l_precinct = l_band->precincts;
1904*3ac0a46fSAndroid Build Coastguard Worker                     if (l_precinct) {
1905*3ac0a46fSAndroid Build Coastguard Worker 
1906*3ac0a46fSAndroid Build Coastguard Worker                         l_nb_precincts = l_band->precincts_data_size / (OPJ_UINT32)sizeof(
1907*3ac0a46fSAndroid Build Coastguard Worker                                              opj_tcd_precinct_t);
1908*3ac0a46fSAndroid Build Coastguard Worker                         for (precno = 0; precno < l_nb_precincts; ++precno) {
1909*3ac0a46fSAndroid Build Coastguard Worker                             opj_tgt_destroy(l_precinct->incltree);
1910*3ac0a46fSAndroid Build Coastguard Worker                             l_precinct->incltree = 00;
1911*3ac0a46fSAndroid Build Coastguard Worker                             opj_tgt_destroy(l_precinct->imsbtree);
1912*3ac0a46fSAndroid Build Coastguard Worker                             l_precinct->imsbtree = 00;
1913*3ac0a46fSAndroid Build Coastguard Worker                             (*l_tcd_code_block_deallocate)(l_precinct);
1914*3ac0a46fSAndroid Build Coastguard Worker                             ++l_precinct;
1915*3ac0a46fSAndroid Build Coastguard Worker                         }
1916*3ac0a46fSAndroid Build Coastguard Worker 
1917*3ac0a46fSAndroid Build Coastguard Worker                         opj_free(l_band->precincts);
1918*3ac0a46fSAndroid Build Coastguard Worker                         l_band->precincts = 00;
1919*3ac0a46fSAndroid Build Coastguard Worker                     }
1920*3ac0a46fSAndroid Build Coastguard Worker                     ++l_band;
1921*3ac0a46fSAndroid Build Coastguard Worker                 } /* for (resno */
1922*3ac0a46fSAndroid Build Coastguard Worker                 ++l_res;
1923*3ac0a46fSAndroid Build Coastguard Worker             }
1924*3ac0a46fSAndroid Build Coastguard Worker 
1925*3ac0a46fSAndroid Build Coastguard Worker             opj_free(l_tile_comp->resolutions);
1926*3ac0a46fSAndroid Build Coastguard Worker             l_tile_comp->resolutions = 00;
1927*3ac0a46fSAndroid Build Coastguard Worker         }
1928*3ac0a46fSAndroid Build Coastguard Worker 
1929*3ac0a46fSAndroid Build Coastguard Worker         if (l_tile_comp->ownsData && l_tile_comp->data) {
1930*3ac0a46fSAndroid Build Coastguard Worker             opj_image_data_free(l_tile_comp->data);
1931*3ac0a46fSAndroid Build Coastguard Worker             l_tile_comp->data = 00;
1932*3ac0a46fSAndroid Build Coastguard Worker             l_tile_comp->ownsData = 0;
1933*3ac0a46fSAndroid Build Coastguard Worker             l_tile_comp->data_size = 0;
1934*3ac0a46fSAndroid Build Coastguard Worker             l_tile_comp->data_size_needed = 0;
1935*3ac0a46fSAndroid Build Coastguard Worker         }
1936*3ac0a46fSAndroid Build Coastguard Worker 
1937*3ac0a46fSAndroid Build Coastguard Worker         opj_image_data_free(l_tile_comp->data_win);
1938*3ac0a46fSAndroid Build Coastguard Worker 
1939*3ac0a46fSAndroid Build Coastguard Worker         ++l_tile_comp;
1940*3ac0a46fSAndroid Build Coastguard Worker     }
1941*3ac0a46fSAndroid Build Coastguard Worker 
1942*3ac0a46fSAndroid Build Coastguard Worker     opj_free(l_tile->comps);
1943*3ac0a46fSAndroid Build Coastguard Worker     l_tile->comps = 00;
1944*3ac0a46fSAndroid Build Coastguard Worker     opj_free(p_tcd->tcd_image->tiles);
1945*3ac0a46fSAndroid Build Coastguard Worker     p_tcd->tcd_image->tiles = 00;
1946*3ac0a46fSAndroid Build Coastguard Worker }
1947*3ac0a46fSAndroid Build Coastguard Worker 
1948*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_t2_decode(opj_tcd_t * p_tcd,OPJ_BYTE * p_src_data,OPJ_UINT32 * p_data_read,OPJ_UINT32 p_max_src_size,opj_codestream_index_t * p_cstr_index,opj_event_mgr_t * p_manager)1949*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_t2_decode(opj_tcd_t *p_tcd,
1950*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_BYTE * p_src_data,
1951*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_UINT32 * p_data_read,
1952*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_UINT32 p_max_src_size,
1953*3ac0a46fSAndroid Build Coastguard Worker                                   opj_codestream_index_t *p_cstr_index,
1954*3ac0a46fSAndroid Build Coastguard Worker                                   opj_event_mgr_t *p_manager
1955*3ac0a46fSAndroid Build Coastguard Worker                                  )
1956*3ac0a46fSAndroid Build Coastguard Worker {
1957*3ac0a46fSAndroid Build Coastguard Worker     opj_t2_t * l_t2;
1958*3ac0a46fSAndroid Build Coastguard Worker 
1959*3ac0a46fSAndroid Build Coastguard Worker     l_t2 = opj_t2_create(p_tcd->image, p_tcd->cp);
1960*3ac0a46fSAndroid Build Coastguard Worker     if (l_t2 == 00) {
1961*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
1962*3ac0a46fSAndroid Build Coastguard Worker     }
1963*3ac0a46fSAndroid Build Coastguard Worker 
1964*3ac0a46fSAndroid Build Coastguard Worker     if (! opj_t2_decode_packets(
1965*3ac0a46fSAndroid Build Coastguard Worker                 p_tcd,
1966*3ac0a46fSAndroid Build Coastguard Worker                 l_t2,
1967*3ac0a46fSAndroid Build Coastguard Worker                 p_tcd->tcd_tileno,
1968*3ac0a46fSAndroid Build Coastguard Worker                 p_tcd->tcd_image->tiles,
1969*3ac0a46fSAndroid Build Coastguard Worker                 p_src_data,
1970*3ac0a46fSAndroid Build Coastguard Worker                 p_data_read,
1971*3ac0a46fSAndroid Build Coastguard Worker                 p_max_src_size,
1972*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_index,
1973*3ac0a46fSAndroid Build Coastguard Worker                 p_manager)) {
1974*3ac0a46fSAndroid Build Coastguard Worker         opj_t2_destroy(l_t2);
1975*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
1976*3ac0a46fSAndroid Build Coastguard Worker     }
1977*3ac0a46fSAndroid Build Coastguard Worker 
1978*3ac0a46fSAndroid Build Coastguard Worker     opj_t2_destroy(l_t2);
1979*3ac0a46fSAndroid Build Coastguard Worker 
1980*3ac0a46fSAndroid Build Coastguard Worker     /*---------------CLEAN-------------------*/
1981*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
1982*3ac0a46fSAndroid Build Coastguard Worker }
1983*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_t1_decode(opj_tcd_t * p_tcd,opj_event_mgr_t * p_manager)1984*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_t1_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
1985*3ac0a46fSAndroid Build Coastguard Worker {
1986*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno;
1987*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
1988*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t* l_tile_comp = l_tile->comps;
1989*3ac0a46fSAndroid Build Coastguard Worker     opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
1990*3ac0a46fSAndroid Build Coastguard Worker     volatile OPJ_BOOL ret = OPJ_TRUE;
1991*3ac0a46fSAndroid Build Coastguard Worker     OPJ_BOOL check_pterm = OPJ_FALSE;
1992*3ac0a46fSAndroid Build Coastguard Worker     opj_mutex_t* p_manager_mutex = NULL;
1993*3ac0a46fSAndroid Build Coastguard Worker 
1994*3ac0a46fSAndroid Build Coastguard Worker     p_manager_mutex = opj_mutex_create();
1995*3ac0a46fSAndroid Build Coastguard Worker 
1996*3ac0a46fSAndroid Build Coastguard Worker     /* Only enable PTERM check if we decode all layers */
1997*3ac0a46fSAndroid Build Coastguard Worker     if (p_tcd->tcp->num_layers_to_decode == p_tcd->tcp->numlayers &&
1998*3ac0a46fSAndroid Build Coastguard Worker             (l_tccp->cblksty & J2K_CCP_CBLKSTY_PTERM) != 0) {
1999*3ac0a46fSAndroid Build Coastguard Worker         check_pterm = OPJ_TRUE;
2000*3ac0a46fSAndroid Build Coastguard Worker     }
2001*3ac0a46fSAndroid Build Coastguard Worker 
2002*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < l_tile->numcomps;
2003*3ac0a46fSAndroid Build Coastguard Worker             ++compno, ++l_tile_comp, ++l_tccp) {
2004*3ac0a46fSAndroid Build Coastguard Worker         if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) {
2005*3ac0a46fSAndroid Build Coastguard Worker             continue;
2006*3ac0a46fSAndroid Build Coastguard Worker         }
2007*3ac0a46fSAndroid Build Coastguard Worker 
2008*3ac0a46fSAndroid Build Coastguard Worker         opj_t1_decode_cblks(p_tcd, &ret, l_tile_comp, l_tccp,
2009*3ac0a46fSAndroid Build Coastguard Worker                             p_manager, p_manager_mutex, check_pterm);
2010*3ac0a46fSAndroid Build Coastguard Worker         if (!ret) {
2011*3ac0a46fSAndroid Build Coastguard Worker             break;
2012*3ac0a46fSAndroid Build Coastguard Worker         }
2013*3ac0a46fSAndroid Build Coastguard Worker     }
2014*3ac0a46fSAndroid Build Coastguard Worker 
2015*3ac0a46fSAndroid Build Coastguard Worker     opj_thread_pool_wait_completion(p_tcd->thread_pool, 0);
2016*3ac0a46fSAndroid Build Coastguard Worker     if (p_manager_mutex) {
2017*3ac0a46fSAndroid Build Coastguard Worker         opj_mutex_destroy(p_manager_mutex);
2018*3ac0a46fSAndroid Build Coastguard Worker     }
2019*3ac0a46fSAndroid Build Coastguard Worker     return ret;
2020*3ac0a46fSAndroid Build Coastguard Worker }
2021*3ac0a46fSAndroid Build Coastguard Worker 
2022*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_dwt_decode(opj_tcd_t * p_tcd)2023*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_dwt_decode(opj_tcd_t *p_tcd)
2024*3ac0a46fSAndroid Build Coastguard Worker {
2025*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno;
2026*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
2027*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps;
2028*3ac0a46fSAndroid Build Coastguard Worker     opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
2029*3ac0a46fSAndroid Build Coastguard Worker     opj_image_comp_t * l_img_comp = p_tcd->image->comps;
2030*3ac0a46fSAndroid Build Coastguard Worker 
2031*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < l_tile->numcomps;
2032*3ac0a46fSAndroid Build Coastguard Worker             compno++, ++l_tile_comp, ++l_img_comp, ++l_tccp) {
2033*3ac0a46fSAndroid Build Coastguard Worker         if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) {
2034*3ac0a46fSAndroid Build Coastguard Worker             continue;
2035*3ac0a46fSAndroid Build Coastguard Worker         }
2036*3ac0a46fSAndroid Build Coastguard Worker 
2037*3ac0a46fSAndroid Build Coastguard Worker         if (l_tccp->qmfbid == 1) {
2038*3ac0a46fSAndroid Build Coastguard Worker             if (! opj_dwt_decode(p_tcd, l_tile_comp,
2039*3ac0a46fSAndroid Build Coastguard Worker                                  l_img_comp->resno_decoded + 1)) {
2040*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
2041*3ac0a46fSAndroid Build Coastguard Worker             }
2042*3ac0a46fSAndroid Build Coastguard Worker         } else {
2043*3ac0a46fSAndroid Build Coastguard Worker             if (! opj_dwt_decode_real(p_tcd, l_tile_comp,
2044*3ac0a46fSAndroid Build Coastguard Worker                                       l_img_comp->resno_decoded + 1)) {
2045*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
2046*3ac0a46fSAndroid Build Coastguard Worker             }
2047*3ac0a46fSAndroid Build Coastguard Worker         }
2048*3ac0a46fSAndroid Build Coastguard Worker 
2049*3ac0a46fSAndroid Build Coastguard Worker     }
2050*3ac0a46fSAndroid Build Coastguard Worker 
2051*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
2052*3ac0a46fSAndroid Build Coastguard Worker }
2053*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_mct_decode(opj_tcd_t * p_tcd,opj_event_mgr_t * p_manager)2054*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_mct_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
2055*3ac0a46fSAndroid Build Coastguard Worker {
2056*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
2057*3ac0a46fSAndroid Build Coastguard Worker     opj_tcp_t * l_tcp = p_tcd->tcp;
2058*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps;
2059*3ac0a46fSAndroid Build Coastguard Worker     OPJ_SIZE_T l_samples;
2060*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 i;
2061*3ac0a46fSAndroid Build Coastguard Worker 
2062*3ac0a46fSAndroid Build Coastguard Worker     if (l_tcp->mct == 0 || p_tcd->used_component != NULL) {
2063*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_TRUE;
2064*3ac0a46fSAndroid Build Coastguard Worker     }
2065*3ac0a46fSAndroid Build Coastguard Worker 
2066*3ac0a46fSAndroid Build Coastguard Worker     if (p_tcd->whole_tile_decoding) {
2067*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_resolution_t* res_comp0 = l_tile->comps[0].resolutions +
2068*3ac0a46fSAndroid Build Coastguard Worker                                           l_tile_comp->minimum_num_resolutions - 1;
2069*3ac0a46fSAndroid Build Coastguard Worker 
2070*3ac0a46fSAndroid Build Coastguard Worker         /* A bit inefficient: we process more data than needed if */
2071*3ac0a46fSAndroid Build Coastguard Worker         /* resno_decoded < l_tile_comp->minimum_num_resolutions-1, */
2072*3ac0a46fSAndroid Build Coastguard Worker         /* but we would need to take into account a stride then */
2073*3ac0a46fSAndroid Build Coastguard Worker         l_samples = (OPJ_SIZE_T)(res_comp0->x1 - res_comp0->x0) *
2074*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(res_comp0->y1 - res_comp0->y0);
2075*3ac0a46fSAndroid Build Coastguard Worker         if (l_tile->numcomps >= 3) {
2076*3ac0a46fSAndroid Build Coastguard Worker             if (l_tile_comp->minimum_num_resolutions !=
2077*3ac0a46fSAndroid Build Coastguard Worker                     l_tile->comps[1].minimum_num_resolutions ||
2078*3ac0a46fSAndroid Build Coastguard Worker                     l_tile_comp->minimum_num_resolutions !=
2079*3ac0a46fSAndroid Build Coastguard Worker                     l_tile->comps[2].minimum_num_resolutions) {
2080*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(p_manager, EVT_ERROR,
2081*3ac0a46fSAndroid Build Coastguard Worker                               "Tiles don't all have the same dimension. Skip the MCT step.\n");
2082*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
2083*3ac0a46fSAndroid Build Coastguard Worker             }
2084*3ac0a46fSAndroid Build Coastguard Worker         }
2085*3ac0a46fSAndroid Build Coastguard Worker         if (l_tile->numcomps >= 3) {
2086*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_resolution_t* res_comp1 = l_tile->comps[1].resolutions +
2087*3ac0a46fSAndroid Build Coastguard Worker                                               l_tile_comp->minimum_num_resolutions - 1;
2088*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_resolution_t* res_comp2 = l_tile->comps[2].resolutions +
2089*3ac0a46fSAndroid Build Coastguard Worker                                               l_tile_comp->minimum_num_resolutions - 1;
2090*3ac0a46fSAndroid Build Coastguard Worker             /* testcase 1336.pdf.asan.47.376 */
2091*3ac0a46fSAndroid Build Coastguard Worker             if (p_tcd->image->comps[0].resno_decoded !=
2092*3ac0a46fSAndroid Build Coastguard Worker                     p_tcd->image->comps[1].resno_decoded ||
2093*3ac0a46fSAndroid Build Coastguard Worker                     p_tcd->image->comps[0].resno_decoded !=
2094*3ac0a46fSAndroid Build Coastguard Worker                     p_tcd->image->comps[2].resno_decoded ||
2095*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(res_comp1->x1 - res_comp1->x0) *
2096*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(res_comp1->y1 - res_comp1->y0) != l_samples ||
2097*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(res_comp2->x1 - res_comp2->x0) *
2098*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(res_comp2->y1 - res_comp2->y0) != l_samples) {
2099*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(p_manager, EVT_ERROR,
2100*3ac0a46fSAndroid Build Coastguard Worker                               "Tiles don't all have the same dimension. Skip the MCT step.\n");
2101*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
2102*3ac0a46fSAndroid Build Coastguard Worker             }
2103*3ac0a46fSAndroid Build Coastguard Worker         }
2104*3ac0a46fSAndroid Build Coastguard Worker     } else {
2105*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_resolution_t* res_comp0 = l_tile->comps[0].resolutions +
2106*3ac0a46fSAndroid Build Coastguard Worker                                           p_tcd->image->comps[0].resno_decoded;
2107*3ac0a46fSAndroid Build Coastguard Worker 
2108*3ac0a46fSAndroid Build Coastguard Worker         l_samples = (OPJ_SIZE_T)(res_comp0->win_x1 - res_comp0->win_x0) *
2109*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(res_comp0->win_y1 - res_comp0->win_y0);
2110*3ac0a46fSAndroid Build Coastguard Worker         if (l_tile->numcomps >= 3) {
2111*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_resolution_t* res_comp1 = l_tile->comps[1].resolutions +
2112*3ac0a46fSAndroid Build Coastguard Worker                                               p_tcd->image->comps[1].resno_decoded;
2113*3ac0a46fSAndroid Build Coastguard Worker             opj_tcd_resolution_t* res_comp2 = l_tile->comps[2].resolutions +
2114*3ac0a46fSAndroid Build Coastguard Worker                                               p_tcd->image->comps[2].resno_decoded;
2115*3ac0a46fSAndroid Build Coastguard Worker             /* testcase 1336.pdf.asan.47.376 */
2116*3ac0a46fSAndroid Build Coastguard Worker             if (p_tcd->image->comps[0].resno_decoded !=
2117*3ac0a46fSAndroid Build Coastguard Worker                     p_tcd->image->comps[1].resno_decoded ||
2118*3ac0a46fSAndroid Build Coastguard Worker                     p_tcd->image->comps[0].resno_decoded !=
2119*3ac0a46fSAndroid Build Coastguard Worker                     p_tcd->image->comps[2].resno_decoded ||
2120*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(res_comp1->win_x1 - res_comp1->win_x0) *
2121*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(res_comp1->win_y1 - res_comp1->win_y0) != l_samples ||
2122*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(res_comp2->win_x1 - res_comp2->win_x0) *
2123*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(res_comp2->win_y1 - res_comp2->win_y0) != l_samples) {
2124*3ac0a46fSAndroid Build Coastguard Worker                 opj_event_msg(p_manager, EVT_ERROR,
2125*3ac0a46fSAndroid Build Coastguard Worker                               "Tiles don't all have the same dimension. Skip the MCT step.\n");
2126*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
2127*3ac0a46fSAndroid Build Coastguard Worker             }
2128*3ac0a46fSAndroid Build Coastguard Worker         }
2129*3ac0a46fSAndroid Build Coastguard Worker     }
2130*3ac0a46fSAndroid Build Coastguard Worker 
2131*3ac0a46fSAndroid Build Coastguard Worker     if (l_tile->numcomps >= 3) {
2132*3ac0a46fSAndroid Build Coastguard Worker         if (l_tcp->mct == 2) {
2133*3ac0a46fSAndroid Build Coastguard Worker             OPJ_BYTE ** l_data;
2134*3ac0a46fSAndroid Build Coastguard Worker 
2135*3ac0a46fSAndroid Build Coastguard Worker             if (! l_tcp->m_mct_decoding_matrix) {
2136*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_TRUE;
2137*3ac0a46fSAndroid Build Coastguard Worker             }
2138*3ac0a46fSAndroid Build Coastguard Worker 
2139*3ac0a46fSAndroid Build Coastguard Worker             l_data = (OPJ_BYTE **) opj_malloc(l_tile->numcomps * sizeof(OPJ_BYTE*));
2140*3ac0a46fSAndroid Build Coastguard Worker             if (! l_data) {
2141*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
2142*3ac0a46fSAndroid Build Coastguard Worker             }
2143*3ac0a46fSAndroid Build Coastguard Worker 
2144*3ac0a46fSAndroid Build Coastguard Worker             for (i = 0; i < l_tile->numcomps; ++i) {
2145*3ac0a46fSAndroid Build Coastguard Worker                 if (p_tcd->whole_tile_decoding) {
2146*3ac0a46fSAndroid Build Coastguard Worker                     l_data[i] = (OPJ_BYTE*) l_tile_comp->data;
2147*3ac0a46fSAndroid Build Coastguard Worker                 } else {
2148*3ac0a46fSAndroid Build Coastguard Worker                     l_data[i] = (OPJ_BYTE*) l_tile_comp->data_win;
2149*3ac0a46fSAndroid Build Coastguard Worker                 }
2150*3ac0a46fSAndroid Build Coastguard Worker                 ++l_tile_comp;
2151*3ac0a46fSAndroid Build Coastguard Worker             }
2152*3ac0a46fSAndroid Build Coastguard Worker 
2153*3ac0a46fSAndroid Build Coastguard Worker             if (! opj_mct_decode_custom(/* MCT data */
2154*3ac0a46fSAndroid Build Coastguard Worker                         (OPJ_BYTE*) l_tcp->m_mct_decoding_matrix,
2155*3ac0a46fSAndroid Build Coastguard Worker                         /* size of components */
2156*3ac0a46fSAndroid Build Coastguard Worker                         l_samples,
2157*3ac0a46fSAndroid Build Coastguard Worker                         /* components */
2158*3ac0a46fSAndroid Build Coastguard Worker                         l_data,
2159*3ac0a46fSAndroid Build Coastguard Worker                         /* nb of components (i.e. size of pData) */
2160*3ac0a46fSAndroid Build Coastguard Worker                         l_tile->numcomps,
2161*3ac0a46fSAndroid Build Coastguard Worker                         /* tells if the data is signed */
2162*3ac0a46fSAndroid Build Coastguard Worker                         p_tcd->image->comps->sgnd)) {
2163*3ac0a46fSAndroid Build Coastguard Worker                 opj_free(l_data);
2164*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
2165*3ac0a46fSAndroid Build Coastguard Worker             }
2166*3ac0a46fSAndroid Build Coastguard Worker 
2167*3ac0a46fSAndroid Build Coastguard Worker             opj_free(l_data);
2168*3ac0a46fSAndroid Build Coastguard Worker         } else {
2169*3ac0a46fSAndroid Build Coastguard Worker             if (l_tcp->tccps->qmfbid == 1) {
2170*3ac0a46fSAndroid Build Coastguard Worker                 if (p_tcd->whole_tile_decoding) {
2171*3ac0a46fSAndroid Build Coastguard Worker                     opj_mct_decode(l_tile->comps[0].data,
2172*3ac0a46fSAndroid Build Coastguard Worker                                    l_tile->comps[1].data,
2173*3ac0a46fSAndroid Build Coastguard Worker                                    l_tile->comps[2].data,
2174*3ac0a46fSAndroid Build Coastguard Worker                                    l_samples);
2175*3ac0a46fSAndroid Build Coastguard Worker                 } else {
2176*3ac0a46fSAndroid Build Coastguard Worker                     opj_mct_decode(l_tile->comps[0].data_win,
2177*3ac0a46fSAndroid Build Coastguard Worker                                    l_tile->comps[1].data_win,
2178*3ac0a46fSAndroid Build Coastguard Worker                                    l_tile->comps[2].data_win,
2179*3ac0a46fSAndroid Build Coastguard Worker                                    l_samples);
2180*3ac0a46fSAndroid Build Coastguard Worker                 }
2181*3ac0a46fSAndroid Build Coastguard Worker             } else {
2182*3ac0a46fSAndroid Build Coastguard Worker                 if (p_tcd->whole_tile_decoding) {
2183*3ac0a46fSAndroid Build Coastguard Worker                     opj_mct_decode_real((OPJ_FLOAT32*)l_tile->comps[0].data,
2184*3ac0a46fSAndroid Build Coastguard Worker                                         (OPJ_FLOAT32*)l_tile->comps[1].data,
2185*3ac0a46fSAndroid Build Coastguard Worker                                         (OPJ_FLOAT32*)l_tile->comps[2].data,
2186*3ac0a46fSAndroid Build Coastguard Worker                                         l_samples);
2187*3ac0a46fSAndroid Build Coastguard Worker                 } else {
2188*3ac0a46fSAndroid Build Coastguard Worker                     opj_mct_decode_real((OPJ_FLOAT32*)l_tile->comps[0].data_win,
2189*3ac0a46fSAndroid Build Coastguard Worker                                         (OPJ_FLOAT32*)l_tile->comps[1].data_win,
2190*3ac0a46fSAndroid Build Coastguard Worker                                         (OPJ_FLOAT32*)l_tile->comps[2].data_win,
2191*3ac0a46fSAndroid Build Coastguard Worker                                         l_samples);
2192*3ac0a46fSAndroid Build Coastguard Worker                 }
2193*3ac0a46fSAndroid Build Coastguard Worker             }
2194*3ac0a46fSAndroid Build Coastguard Worker         }
2195*3ac0a46fSAndroid Build Coastguard Worker     } else {
2196*3ac0a46fSAndroid Build Coastguard Worker         opj_event_msg(p_manager, EVT_ERROR,
2197*3ac0a46fSAndroid Build Coastguard Worker                       "Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",
2198*3ac0a46fSAndroid Build Coastguard Worker                       l_tile->numcomps);
2199*3ac0a46fSAndroid Build Coastguard Worker     }
2200*3ac0a46fSAndroid Build Coastguard Worker 
2201*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
2202*3ac0a46fSAndroid Build Coastguard Worker }
2203*3ac0a46fSAndroid Build Coastguard Worker 
2204*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_dc_level_shift_decode(opj_tcd_t * p_tcd)2205*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_dc_level_shift_decode(opj_tcd_t *p_tcd)
2206*3ac0a46fSAndroid Build Coastguard Worker {
2207*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno;
2208*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t * l_tile_comp = 00;
2209*3ac0a46fSAndroid Build Coastguard Worker     opj_tccp_t * l_tccp = 00;
2210*3ac0a46fSAndroid Build Coastguard Worker     opj_image_comp_t * l_img_comp = 00;
2211*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_resolution_t* l_res = 00;
2212*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t * l_tile;
2213*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_width, l_height, i, j;
2214*3ac0a46fSAndroid Build Coastguard Worker     OPJ_INT32 * l_current_ptr;
2215*3ac0a46fSAndroid Build Coastguard Worker     OPJ_INT32 l_min, l_max;
2216*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_stride;
2217*3ac0a46fSAndroid Build Coastguard Worker 
2218*3ac0a46fSAndroid Build Coastguard Worker     l_tile = p_tcd->tcd_image->tiles;
2219*3ac0a46fSAndroid Build Coastguard Worker     l_tile_comp = l_tile->comps;
2220*3ac0a46fSAndroid Build Coastguard Worker     l_tccp = p_tcd->tcp->tccps;
2221*3ac0a46fSAndroid Build Coastguard Worker     l_img_comp = p_tcd->image->comps;
2222*3ac0a46fSAndroid Build Coastguard Worker 
2223*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < l_tile->numcomps;
2224*3ac0a46fSAndroid Build Coastguard Worker             compno++, ++l_img_comp, ++l_tccp, ++l_tile_comp) {
2225*3ac0a46fSAndroid Build Coastguard Worker 
2226*3ac0a46fSAndroid Build Coastguard Worker         if (p_tcd->used_component != NULL && !p_tcd->used_component[compno]) {
2227*3ac0a46fSAndroid Build Coastguard Worker             continue;
2228*3ac0a46fSAndroid Build Coastguard Worker         }
2229*3ac0a46fSAndroid Build Coastguard Worker 
2230*3ac0a46fSAndroid Build Coastguard Worker         l_res = l_tile_comp->resolutions + l_img_comp->resno_decoded;
2231*3ac0a46fSAndroid Build Coastguard Worker 
2232*3ac0a46fSAndroid Build Coastguard Worker         if (!p_tcd->whole_tile_decoding) {
2233*3ac0a46fSAndroid Build Coastguard Worker             l_width = l_res->win_x1 - l_res->win_x0;
2234*3ac0a46fSAndroid Build Coastguard Worker             l_height = l_res->win_y1 - l_res->win_y0;
2235*3ac0a46fSAndroid Build Coastguard Worker             l_stride = 0;
2236*3ac0a46fSAndroid Build Coastguard Worker             l_current_ptr = l_tile_comp->data_win;
2237*3ac0a46fSAndroid Build Coastguard Worker         } else {
2238*3ac0a46fSAndroid Build Coastguard Worker             l_width = (OPJ_UINT32)(l_res->x1 - l_res->x0);
2239*3ac0a46fSAndroid Build Coastguard Worker             l_height = (OPJ_UINT32)(l_res->y1 - l_res->y0);
2240*3ac0a46fSAndroid Build Coastguard Worker             l_stride = (OPJ_UINT32)(
2241*3ac0a46fSAndroid Build Coastguard Worker                            l_tile_comp->resolutions[l_tile_comp->minimum_num_resolutions - 1].x1 -
2242*3ac0a46fSAndroid Build Coastguard Worker                            l_tile_comp->resolutions[l_tile_comp->minimum_num_resolutions - 1].x0)
2243*3ac0a46fSAndroid Build Coastguard Worker                        - l_width;
2244*3ac0a46fSAndroid Build Coastguard Worker             l_current_ptr = l_tile_comp->data;
2245*3ac0a46fSAndroid Build Coastguard Worker 
2246*3ac0a46fSAndroid Build Coastguard Worker             assert(l_height == 0 ||
2247*3ac0a46fSAndroid Build Coastguard Worker                    l_width + l_stride <= l_tile_comp->data_size / l_height); /*MUPDF*/
2248*3ac0a46fSAndroid Build Coastguard Worker         }
2249*3ac0a46fSAndroid Build Coastguard Worker 
2250*3ac0a46fSAndroid Build Coastguard Worker         if (l_img_comp->sgnd) {
2251*3ac0a46fSAndroid Build Coastguard Worker             l_min = -(1 << (l_img_comp->prec - 1));
2252*3ac0a46fSAndroid Build Coastguard Worker             l_max = (1 << (l_img_comp->prec - 1)) - 1;
2253*3ac0a46fSAndroid Build Coastguard Worker         } else {
2254*3ac0a46fSAndroid Build Coastguard Worker             l_min = 0;
2255*3ac0a46fSAndroid Build Coastguard Worker             l_max = (OPJ_INT32)((1U << l_img_comp->prec) - 1);
2256*3ac0a46fSAndroid Build Coastguard Worker         }
2257*3ac0a46fSAndroid Build Coastguard Worker 
2258*3ac0a46fSAndroid Build Coastguard Worker 
2259*3ac0a46fSAndroid Build Coastguard Worker         if (l_tccp->qmfbid == 1) {
2260*3ac0a46fSAndroid Build Coastguard Worker             for (j = 0; j < l_height; ++j) {
2261*3ac0a46fSAndroid Build Coastguard Worker                 for (i = 0; i < l_width; ++i) {
2262*3ac0a46fSAndroid Build Coastguard Worker                     /* TODO: do addition on int64 ? */
2263*3ac0a46fSAndroid Build Coastguard Worker                     *l_current_ptr = opj_int_clamp(*l_current_ptr + l_tccp->m_dc_level_shift, l_min,
2264*3ac0a46fSAndroid Build Coastguard Worker                                                    l_max);
2265*3ac0a46fSAndroid Build Coastguard Worker                     ++l_current_ptr;
2266*3ac0a46fSAndroid Build Coastguard Worker                 }
2267*3ac0a46fSAndroid Build Coastguard Worker                 l_current_ptr += l_stride;
2268*3ac0a46fSAndroid Build Coastguard Worker             }
2269*3ac0a46fSAndroid Build Coastguard Worker         } else {
2270*3ac0a46fSAndroid Build Coastguard Worker             for (j = 0; j < l_height; ++j) {
2271*3ac0a46fSAndroid Build Coastguard Worker                 for (i = 0; i < l_width; ++i) {
2272*3ac0a46fSAndroid Build Coastguard Worker                     OPJ_FLOAT32 l_value = *((OPJ_FLOAT32 *) l_current_ptr);
2273*3ac0a46fSAndroid Build Coastguard Worker                     if (l_value > INT_MAX) {
2274*3ac0a46fSAndroid Build Coastguard Worker                         *l_current_ptr = l_max;
2275*3ac0a46fSAndroid Build Coastguard Worker                     } else if (l_value < INT_MIN) {
2276*3ac0a46fSAndroid Build Coastguard Worker                         *l_current_ptr = l_min;
2277*3ac0a46fSAndroid Build Coastguard Worker                     } else {
2278*3ac0a46fSAndroid Build Coastguard Worker                         /* Do addition on int64 to avoid overflows */
2279*3ac0a46fSAndroid Build Coastguard Worker                         OPJ_INT64 l_value_int = (OPJ_INT64)opj_lrintf(l_value);
2280*3ac0a46fSAndroid Build Coastguard Worker                         *l_current_ptr = (OPJ_INT32)opj_int64_clamp(
2281*3ac0a46fSAndroid Build Coastguard Worker                                              l_value_int + l_tccp->m_dc_level_shift, l_min, l_max);
2282*3ac0a46fSAndroid Build Coastguard Worker                     }
2283*3ac0a46fSAndroid Build Coastguard Worker                     ++l_current_ptr;
2284*3ac0a46fSAndroid Build Coastguard Worker                 }
2285*3ac0a46fSAndroid Build Coastguard Worker                 l_current_ptr += l_stride;
2286*3ac0a46fSAndroid Build Coastguard Worker             }
2287*3ac0a46fSAndroid Build Coastguard Worker         }
2288*3ac0a46fSAndroid Build Coastguard Worker     }
2289*3ac0a46fSAndroid Build Coastguard Worker 
2290*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
2291*3ac0a46fSAndroid Build Coastguard Worker }
2292*3ac0a46fSAndroid Build Coastguard Worker 
2293*3ac0a46fSAndroid Build Coastguard Worker 
2294*3ac0a46fSAndroid Build Coastguard Worker 
2295*3ac0a46fSAndroid Build Coastguard Worker /**
2296*3ac0a46fSAndroid Build Coastguard Worker  * Deallocates the encoding data of the given precinct.
2297*3ac0a46fSAndroid Build Coastguard Worker  */
opj_tcd_code_block_dec_deallocate(opj_tcd_precinct_t * p_precinct)2298*3ac0a46fSAndroid Build Coastguard Worker static void opj_tcd_code_block_dec_deallocate(opj_tcd_precinct_t * p_precinct)
2299*3ac0a46fSAndroid Build Coastguard Worker {
2300*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 cblkno, l_nb_code_blocks;
2301*3ac0a46fSAndroid Build Coastguard Worker 
2302*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_cblk_dec_t * l_code_block = p_precinct->cblks.dec;
2303*3ac0a46fSAndroid Build Coastguard Worker     if (l_code_block) {
2304*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr,"deallocate codeblock:{\n");*/
2305*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr,"\t x0=%d, y0=%d, x1=%d, y1=%d\n",l_code_block->x0, l_code_block->y0, l_code_block->x1, l_code_block->y1);*/
2306*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr,"\t numbps=%d, numlenbits=%d, len=%d, numnewpasses=%d, real_num_segs=%d, m_current_max_segs=%d\n ",
2307*3ac0a46fSAndroid Build Coastguard Worker                         l_code_block->numbps, l_code_block->numlenbits, l_code_block->len, l_code_block->numnewpasses, l_code_block->real_num_segs, l_code_block->m_current_max_segs );*/
2308*3ac0a46fSAndroid Build Coastguard Worker 
2309*3ac0a46fSAndroid Build Coastguard Worker 
2310*3ac0a46fSAndroid Build Coastguard Worker         l_nb_code_blocks = p_precinct->block_size / (OPJ_UINT32)sizeof(
2311*3ac0a46fSAndroid Build Coastguard Worker                                opj_tcd_cblk_dec_t);
2312*3ac0a46fSAndroid Build Coastguard Worker         /*fprintf(stderr,"nb_code_blocks =%d\t}\n", l_nb_code_blocks);*/
2313*3ac0a46fSAndroid Build Coastguard Worker 
2314*3ac0a46fSAndroid Build Coastguard Worker         for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
2315*3ac0a46fSAndroid Build Coastguard Worker 
2316*3ac0a46fSAndroid Build Coastguard Worker             if (l_code_block->segs) {
2317*3ac0a46fSAndroid Build Coastguard Worker                 opj_free(l_code_block->segs);
2318*3ac0a46fSAndroid Build Coastguard Worker                 l_code_block->segs = 00;
2319*3ac0a46fSAndroid Build Coastguard Worker             }
2320*3ac0a46fSAndroid Build Coastguard Worker 
2321*3ac0a46fSAndroid Build Coastguard Worker             if (l_code_block->chunks) {
2322*3ac0a46fSAndroid Build Coastguard Worker                 opj_free(l_code_block->chunks);
2323*3ac0a46fSAndroid Build Coastguard Worker                 l_code_block->chunks = 00;
2324*3ac0a46fSAndroid Build Coastguard Worker             }
2325*3ac0a46fSAndroid Build Coastguard Worker 
2326*3ac0a46fSAndroid Build Coastguard Worker             opj_aligned_free(l_code_block->decoded_data);
2327*3ac0a46fSAndroid Build Coastguard Worker             l_code_block->decoded_data = NULL;
2328*3ac0a46fSAndroid Build Coastguard Worker 
2329*3ac0a46fSAndroid Build Coastguard Worker             ++l_code_block;
2330*3ac0a46fSAndroid Build Coastguard Worker         }
2331*3ac0a46fSAndroid Build Coastguard Worker 
2332*3ac0a46fSAndroid Build Coastguard Worker         opj_free(p_precinct->cblks.dec);
2333*3ac0a46fSAndroid Build Coastguard Worker         p_precinct->cblks.dec = 00;
2334*3ac0a46fSAndroid Build Coastguard Worker     }
2335*3ac0a46fSAndroid Build Coastguard Worker }
2336*3ac0a46fSAndroid Build Coastguard Worker 
2337*3ac0a46fSAndroid Build Coastguard Worker /**
2338*3ac0a46fSAndroid Build Coastguard Worker  * Deallocates the encoding data of the given precinct.
2339*3ac0a46fSAndroid Build Coastguard Worker  */
opj_tcd_code_block_enc_deallocate(opj_tcd_precinct_t * p_precinct)2340*3ac0a46fSAndroid Build Coastguard Worker static void opj_tcd_code_block_enc_deallocate(opj_tcd_precinct_t * p_precinct)
2341*3ac0a46fSAndroid Build Coastguard Worker {
2342*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 cblkno, l_nb_code_blocks;
2343*3ac0a46fSAndroid Build Coastguard Worker 
2344*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_cblk_enc_t * l_code_block = p_precinct->cblks.enc;
2345*3ac0a46fSAndroid Build Coastguard Worker     if (l_code_block) {
2346*3ac0a46fSAndroid Build Coastguard Worker         l_nb_code_blocks = p_precinct->block_size / (OPJ_UINT32)sizeof(
2347*3ac0a46fSAndroid Build Coastguard Worker                                opj_tcd_cblk_enc_t);
2348*3ac0a46fSAndroid Build Coastguard Worker 
2349*3ac0a46fSAndroid Build Coastguard Worker         for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno)  {
2350*3ac0a46fSAndroid Build Coastguard Worker             if (l_code_block->data) {
2351*3ac0a46fSAndroid Build Coastguard Worker                 /* We refer to data - 1 since below we incremented it */
2352*3ac0a46fSAndroid Build Coastguard Worker                 /* in opj_tcd_code_block_enc_allocate_data() */
2353*3ac0a46fSAndroid Build Coastguard Worker                 opj_free(l_code_block->data - 1);
2354*3ac0a46fSAndroid Build Coastguard Worker                 l_code_block->data = 00;
2355*3ac0a46fSAndroid Build Coastguard Worker             }
2356*3ac0a46fSAndroid Build Coastguard Worker 
2357*3ac0a46fSAndroid Build Coastguard Worker             if (l_code_block->layers) {
2358*3ac0a46fSAndroid Build Coastguard Worker                 opj_free(l_code_block->layers);
2359*3ac0a46fSAndroid Build Coastguard Worker                 l_code_block->layers = 00;
2360*3ac0a46fSAndroid Build Coastguard Worker             }
2361*3ac0a46fSAndroid Build Coastguard Worker 
2362*3ac0a46fSAndroid Build Coastguard Worker             if (l_code_block->passes) {
2363*3ac0a46fSAndroid Build Coastguard Worker                 opj_free(l_code_block->passes);
2364*3ac0a46fSAndroid Build Coastguard Worker                 l_code_block->passes = 00;
2365*3ac0a46fSAndroid Build Coastguard Worker             }
2366*3ac0a46fSAndroid Build Coastguard Worker             ++l_code_block;
2367*3ac0a46fSAndroid Build Coastguard Worker         }
2368*3ac0a46fSAndroid Build Coastguard Worker 
2369*3ac0a46fSAndroid Build Coastguard Worker         opj_free(p_precinct->cblks.enc);
2370*3ac0a46fSAndroid Build Coastguard Worker 
2371*3ac0a46fSAndroid Build Coastguard Worker         p_precinct->cblks.enc = 00;
2372*3ac0a46fSAndroid Build Coastguard Worker     }
2373*3ac0a46fSAndroid Build Coastguard Worker }
2374*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_get_encoder_input_buffer_size(opj_tcd_t * p_tcd)2375*3ac0a46fSAndroid Build Coastguard Worker OPJ_SIZE_T opj_tcd_get_encoder_input_buffer_size(opj_tcd_t *p_tcd)
2376*3ac0a46fSAndroid Build Coastguard Worker {
2377*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 i;
2378*3ac0a46fSAndroid Build Coastguard Worker     OPJ_SIZE_T l_data_size = 0;
2379*3ac0a46fSAndroid Build Coastguard Worker     opj_image_comp_t * l_img_comp = 00;
2380*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t * l_tilec = 00;
2381*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_size_comp, l_remaining;
2382*3ac0a46fSAndroid Build Coastguard Worker 
2383*3ac0a46fSAndroid Build Coastguard Worker     l_tilec = p_tcd->tcd_image->tiles->comps;
2384*3ac0a46fSAndroid Build Coastguard Worker     l_img_comp = p_tcd->image->comps;
2385*3ac0a46fSAndroid Build Coastguard Worker     for (i = 0; i < p_tcd->image->numcomps; ++i) {
2386*3ac0a46fSAndroid Build Coastguard Worker         l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
2387*3ac0a46fSAndroid Build Coastguard Worker         l_remaining = l_img_comp->prec & 7;  /* (%8) */
2388*3ac0a46fSAndroid Build Coastguard Worker 
2389*3ac0a46fSAndroid Build Coastguard Worker         if (l_remaining) {
2390*3ac0a46fSAndroid Build Coastguard Worker             ++l_size_comp;
2391*3ac0a46fSAndroid Build Coastguard Worker         }
2392*3ac0a46fSAndroid Build Coastguard Worker 
2393*3ac0a46fSAndroid Build Coastguard Worker         if (l_size_comp == 3) {
2394*3ac0a46fSAndroid Build Coastguard Worker             l_size_comp = 4;
2395*3ac0a46fSAndroid Build Coastguard Worker         }
2396*3ac0a46fSAndroid Build Coastguard Worker 
2397*3ac0a46fSAndroid Build Coastguard Worker         l_data_size += l_size_comp * ((OPJ_SIZE_T)(l_tilec->x1 - l_tilec->x0) *
2398*3ac0a46fSAndroid Build Coastguard Worker                                       (OPJ_SIZE_T)(l_tilec->y1 - l_tilec->y0));
2399*3ac0a46fSAndroid Build Coastguard Worker         ++l_img_comp;
2400*3ac0a46fSAndroid Build Coastguard Worker         ++l_tilec;
2401*3ac0a46fSAndroid Build Coastguard Worker     }
2402*3ac0a46fSAndroid Build Coastguard Worker 
2403*3ac0a46fSAndroid Build Coastguard Worker     return l_data_size;
2404*3ac0a46fSAndroid Build Coastguard Worker }
2405*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_dc_level_shift_encode(opj_tcd_t * p_tcd)2406*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_dc_level_shift_encode(opj_tcd_t *p_tcd)
2407*3ac0a46fSAndroid Build Coastguard Worker {
2408*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno;
2409*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t * l_tile_comp = 00;
2410*3ac0a46fSAndroid Build Coastguard Worker     opj_tccp_t * l_tccp = 00;
2411*3ac0a46fSAndroid Build Coastguard Worker     opj_image_comp_t * l_img_comp = 00;
2412*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t * l_tile;
2413*3ac0a46fSAndroid Build Coastguard Worker     OPJ_SIZE_T l_nb_elem, i;
2414*3ac0a46fSAndroid Build Coastguard Worker     OPJ_INT32 * l_current_ptr;
2415*3ac0a46fSAndroid Build Coastguard Worker 
2416*3ac0a46fSAndroid Build Coastguard Worker     l_tile = p_tcd->tcd_image->tiles;
2417*3ac0a46fSAndroid Build Coastguard Worker     l_tile_comp = l_tile->comps;
2418*3ac0a46fSAndroid Build Coastguard Worker     l_tccp = p_tcd->tcp->tccps;
2419*3ac0a46fSAndroid Build Coastguard Worker     l_img_comp = p_tcd->image->comps;
2420*3ac0a46fSAndroid Build Coastguard Worker 
2421*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < l_tile->numcomps; compno++) {
2422*3ac0a46fSAndroid Build Coastguard Worker         l_current_ptr = l_tile_comp->data;
2423*3ac0a46fSAndroid Build Coastguard Worker         l_nb_elem = (OPJ_SIZE_T)(l_tile_comp->x1 - l_tile_comp->x0) *
2424*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(l_tile_comp->y1 - l_tile_comp->y0);
2425*3ac0a46fSAndroid Build Coastguard Worker 
2426*3ac0a46fSAndroid Build Coastguard Worker         if (l_tccp->qmfbid == 1) {
2427*3ac0a46fSAndroid Build Coastguard Worker             for (i = 0; i < l_nb_elem; ++i) {
2428*3ac0a46fSAndroid Build Coastguard Worker                 *l_current_ptr -= l_tccp->m_dc_level_shift ;
2429*3ac0a46fSAndroid Build Coastguard Worker                 ++l_current_ptr;
2430*3ac0a46fSAndroid Build Coastguard Worker             }
2431*3ac0a46fSAndroid Build Coastguard Worker         } else {
2432*3ac0a46fSAndroid Build Coastguard Worker             for (i = 0; i < l_nb_elem; ++i) {
2433*3ac0a46fSAndroid Build Coastguard Worker                 *((OPJ_FLOAT32 *) l_current_ptr) = (OPJ_FLOAT32)(*l_current_ptr -
2434*3ac0a46fSAndroid Build Coastguard Worker                                                    l_tccp->m_dc_level_shift);
2435*3ac0a46fSAndroid Build Coastguard Worker                 ++l_current_ptr;
2436*3ac0a46fSAndroid Build Coastguard Worker             }
2437*3ac0a46fSAndroid Build Coastguard Worker         }
2438*3ac0a46fSAndroid Build Coastguard Worker 
2439*3ac0a46fSAndroid Build Coastguard Worker         ++l_img_comp;
2440*3ac0a46fSAndroid Build Coastguard Worker         ++l_tccp;
2441*3ac0a46fSAndroid Build Coastguard Worker         ++l_tile_comp;
2442*3ac0a46fSAndroid Build Coastguard Worker     }
2443*3ac0a46fSAndroid Build Coastguard Worker 
2444*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
2445*3ac0a46fSAndroid Build Coastguard Worker }
2446*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_mct_encode(opj_tcd_t * p_tcd)2447*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_mct_encode(opj_tcd_t *p_tcd)
2448*3ac0a46fSAndroid Build Coastguard Worker {
2449*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
2450*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t * l_tile_comp = p_tcd->tcd_image->tiles->comps;
2451*3ac0a46fSAndroid Build Coastguard Worker     OPJ_SIZE_T samples = (OPJ_SIZE_T)(l_tile_comp->x1 - l_tile_comp->x0) *
2452*3ac0a46fSAndroid Build Coastguard Worker                          (OPJ_SIZE_T)(l_tile_comp->y1 - l_tile_comp->y0);
2453*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 i;
2454*3ac0a46fSAndroid Build Coastguard Worker     OPJ_BYTE ** l_data = 00;
2455*3ac0a46fSAndroid Build Coastguard Worker     opj_tcp_t * l_tcp = p_tcd->tcp;
2456*3ac0a46fSAndroid Build Coastguard Worker 
2457*3ac0a46fSAndroid Build Coastguard Worker     if (!p_tcd->tcp->mct) {
2458*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_TRUE;
2459*3ac0a46fSAndroid Build Coastguard Worker     }
2460*3ac0a46fSAndroid Build Coastguard Worker 
2461*3ac0a46fSAndroid Build Coastguard Worker     if (p_tcd->tcp->mct == 2) {
2462*3ac0a46fSAndroid Build Coastguard Worker         if (! p_tcd->tcp->m_mct_coding_matrix) {
2463*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_TRUE;
2464*3ac0a46fSAndroid Build Coastguard Worker         }
2465*3ac0a46fSAndroid Build Coastguard Worker 
2466*3ac0a46fSAndroid Build Coastguard Worker         l_data = (OPJ_BYTE **) opj_malloc(l_tile->numcomps * sizeof(OPJ_BYTE*));
2467*3ac0a46fSAndroid Build Coastguard Worker         if (! l_data) {
2468*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
2469*3ac0a46fSAndroid Build Coastguard Worker         }
2470*3ac0a46fSAndroid Build Coastguard Worker 
2471*3ac0a46fSAndroid Build Coastguard Worker         for (i = 0; i < l_tile->numcomps; ++i) {
2472*3ac0a46fSAndroid Build Coastguard Worker             l_data[i] = (OPJ_BYTE*) l_tile_comp->data;
2473*3ac0a46fSAndroid Build Coastguard Worker             ++l_tile_comp;
2474*3ac0a46fSAndroid Build Coastguard Worker         }
2475*3ac0a46fSAndroid Build Coastguard Worker 
2476*3ac0a46fSAndroid Build Coastguard Worker         if (! opj_mct_encode_custom(/* MCT data */
2477*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_BYTE*) p_tcd->tcp->m_mct_coding_matrix,
2478*3ac0a46fSAndroid Build Coastguard Worker                     /* size of components */
2479*3ac0a46fSAndroid Build Coastguard Worker                     samples,
2480*3ac0a46fSAndroid Build Coastguard Worker                     /* components */
2481*3ac0a46fSAndroid Build Coastguard Worker                     l_data,
2482*3ac0a46fSAndroid Build Coastguard Worker                     /* nb of components (i.e. size of pData) */
2483*3ac0a46fSAndroid Build Coastguard Worker                     l_tile->numcomps,
2484*3ac0a46fSAndroid Build Coastguard Worker                     /* tells if the data is signed */
2485*3ac0a46fSAndroid Build Coastguard Worker                     p_tcd->image->comps->sgnd)) {
2486*3ac0a46fSAndroid Build Coastguard Worker             opj_free(l_data);
2487*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
2488*3ac0a46fSAndroid Build Coastguard Worker         }
2489*3ac0a46fSAndroid Build Coastguard Worker 
2490*3ac0a46fSAndroid Build Coastguard Worker         opj_free(l_data);
2491*3ac0a46fSAndroid Build Coastguard Worker     } else if (l_tcp->tccps->qmfbid == 0) {
2492*3ac0a46fSAndroid Build Coastguard Worker         opj_mct_encode_real(
2493*3ac0a46fSAndroid Build Coastguard Worker             (OPJ_FLOAT32*)l_tile->comps[0].data,
2494*3ac0a46fSAndroid Build Coastguard Worker             (OPJ_FLOAT32*)l_tile->comps[1].data,
2495*3ac0a46fSAndroid Build Coastguard Worker             (OPJ_FLOAT32*)l_tile->comps[2].data,
2496*3ac0a46fSAndroid Build Coastguard Worker             samples);
2497*3ac0a46fSAndroid Build Coastguard Worker     } else {
2498*3ac0a46fSAndroid Build Coastguard Worker         opj_mct_encode(l_tile->comps[0].data, l_tile->comps[1].data,
2499*3ac0a46fSAndroid Build Coastguard Worker                        l_tile->comps[2].data, samples);
2500*3ac0a46fSAndroid Build Coastguard Worker     }
2501*3ac0a46fSAndroid Build Coastguard Worker 
2502*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
2503*3ac0a46fSAndroid Build Coastguard Worker }
2504*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_dwt_encode(opj_tcd_t * p_tcd)2505*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_dwt_encode(opj_tcd_t *p_tcd)
2506*3ac0a46fSAndroid Build Coastguard Worker {
2507*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
2508*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t * l_tile_comp = p_tcd->tcd_image->tiles->comps;
2509*3ac0a46fSAndroid Build Coastguard Worker     opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
2510*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 compno;
2511*3ac0a46fSAndroid Build Coastguard Worker 
2512*3ac0a46fSAndroid Build Coastguard Worker     for (compno = 0; compno < l_tile->numcomps; ++compno) {
2513*3ac0a46fSAndroid Build Coastguard Worker         if (l_tccp->qmfbid == 1) {
2514*3ac0a46fSAndroid Build Coastguard Worker             if (! opj_dwt_encode(p_tcd, l_tile_comp)) {
2515*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
2516*3ac0a46fSAndroid Build Coastguard Worker             }
2517*3ac0a46fSAndroid Build Coastguard Worker         } else if (l_tccp->qmfbid == 0) {
2518*3ac0a46fSAndroid Build Coastguard Worker             if (! opj_dwt_encode_real(p_tcd, l_tile_comp)) {
2519*3ac0a46fSAndroid Build Coastguard Worker                 return OPJ_FALSE;
2520*3ac0a46fSAndroid Build Coastguard Worker             }
2521*3ac0a46fSAndroid Build Coastguard Worker         }
2522*3ac0a46fSAndroid Build Coastguard Worker 
2523*3ac0a46fSAndroid Build Coastguard Worker         ++l_tile_comp;
2524*3ac0a46fSAndroid Build Coastguard Worker         ++l_tccp;
2525*3ac0a46fSAndroid Build Coastguard Worker     }
2526*3ac0a46fSAndroid Build Coastguard Worker 
2527*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
2528*3ac0a46fSAndroid Build Coastguard Worker }
2529*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_t1_encode(opj_tcd_t * p_tcd)2530*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_t1_encode(opj_tcd_t *p_tcd)
2531*3ac0a46fSAndroid Build Coastguard Worker {
2532*3ac0a46fSAndroid Build Coastguard Worker     const OPJ_FLOAT64 * l_mct_norms;
2533*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_mct_numcomps = 0U;
2534*3ac0a46fSAndroid Build Coastguard Worker     opj_tcp_t * l_tcp = p_tcd->tcp;
2535*3ac0a46fSAndroid Build Coastguard Worker 
2536*3ac0a46fSAndroid Build Coastguard Worker     if (l_tcp->mct == 1) {
2537*3ac0a46fSAndroid Build Coastguard Worker         l_mct_numcomps = 3U;
2538*3ac0a46fSAndroid Build Coastguard Worker         /* irreversible encoding */
2539*3ac0a46fSAndroid Build Coastguard Worker         if (l_tcp->tccps->qmfbid == 0) {
2540*3ac0a46fSAndroid Build Coastguard Worker             l_mct_norms = opj_mct_get_mct_norms_real();
2541*3ac0a46fSAndroid Build Coastguard Worker         } else {
2542*3ac0a46fSAndroid Build Coastguard Worker             l_mct_norms = opj_mct_get_mct_norms();
2543*3ac0a46fSAndroid Build Coastguard Worker         }
2544*3ac0a46fSAndroid Build Coastguard Worker     } else {
2545*3ac0a46fSAndroid Build Coastguard Worker         l_mct_numcomps = p_tcd->image->numcomps;
2546*3ac0a46fSAndroid Build Coastguard Worker         l_mct_norms = (const OPJ_FLOAT64 *)(l_tcp->mct_norms);
2547*3ac0a46fSAndroid Build Coastguard Worker     }
2548*3ac0a46fSAndroid Build Coastguard Worker 
2549*3ac0a46fSAndroid Build Coastguard Worker     return opj_t1_encode_cblks(p_tcd,
2550*3ac0a46fSAndroid Build Coastguard Worker                                p_tcd->tcd_image->tiles, l_tcp, l_mct_norms,
2551*3ac0a46fSAndroid Build Coastguard Worker                                l_mct_numcomps);
2552*3ac0a46fSAndroid Build Coastguard Worker 
2553*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
2554*3ac0a46fSAndroid Build Coastguard Worker }
2555*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_t2_encode(opj_tcd_t * p_tcd,OPJ_BYTE * p_dest_data,OPJ_UINT32 * p_data_written,OPJ_UINT32 p_max_dest_size,opj_codestream_info_t * p_cstr_info,opj_tcd_marker_info_t * p_marker_info,opj_event_mgr_t * p_manager)2556*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd,
2557*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_BYTE * p_dest_data,
2558*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_UINT32 * p_data_written,
2559*3ac0a46fSAndroid Build Coastguard Worker                                   OPJ_UINT32 p_max_dest_size,
2560*3ac0a46fSAndroid Build Coastguard Worker                                   opj_codestream_info_t *p_cstr_info,
2561*3ac0a46fSAndroid Build Coastguard Worker                                   opj_tcd_marker_info_t* p_marker_info,
2562*3ac0a46fSAndroid Build Coastguard Worker                                   opj_event_mgr_t *p_manager)
2563*3ac0a46fSAndroid Build Coastguard Worker {
2564*3ac0a46fSAndroid Build Coastguard Worker     opj_t2_t * l_t2;
2565*3ac0a46fSAndroid Build Coastguard Worker 
2566*3ac0a46fSAndroid Build Coastguard Worker     l_t2 = opj_t2_create(p_tcd->image, p_tcd->cp);
2567*3ac0a46fSAndroid Build Coastguard Worker     if (l_t2 == 00) {
2568*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
2569*3ac0a46fSAndroid Build Coastguard Worker     }
2570*3ac0a46fSAndroid Build Coastguard Worker 
2571*3ac0a46fSAndroid Build Coastguard Worker     if (! opj_t2_encode_packets(
2572*3ac0a46fSAndroid Build Coastguard Worker                 l_t2,
2573*3ac0a46fSAndroid Build Coastguard Worker                 p_tcd->tcd_tileno,
2574*3ac0a46fSAndroid Build Coastguard Worker                 p_tcd->tcd_image->tiles,
2575*3ac0a46fSAndroid Build Coastguard Worker                 p_tcd->tcp->numlayers,
2576*3ac0a46fSAndroid Build Coastguard Worker                 p_dest_data,
2577*3ac0a46fSAndroid Build Coastguard Worker                 p_data_written,
2578*3ac0a46fSAndroid Build Coastguard Worker                 p_max_dest_size,
2579*3ac0a46fSAndroid Build Coastguard Worker                 p_cstr_info,
2580*3ac0a46fSAndroid Build Coastguard Worker                 p_marker_info,
2581*3ac0a46fSAndroid Build Coastguard Worker                 p_tcd->tp_num,
2582*3ac0a46fSAndroid Build Coastguard Worker                 p_tcd->tp_pos,
2583*3ac0a46fSAndroid Build Coastguard Worker                 p_tcd->cur_pino,
2584*3ac0a46fSAndroid Build Coastguard Worker                 FINAL_PASS,
2585*3ac0a46fSAndroid Build Coastguard Worker                 p_manager)) {
2586*3ac0a46fSAndroid Build Coastguard Worker         opj_t2_destroy(l_t2);
2587*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
2588*3ac0a46fSAndroid Build Coastguard Worker     }
2589*3ac0a46fSAndroid Build Coastguard Worker 
2590*3ac0a46fSAndroid Build Coastguard Worker     opj_t2_destroy(l_t2);
2591*3ac0a46fSAndroid Build Coastguard Worker 
2592*3ac0a46fSAndroid Build Coastguard Worker     /*---------------CLEAN-------------------*/
2593*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
2594*3ac0a46fSAndroid Build Coastguard Worker }
2595*3ac0a46fSAndroid Build Coastguard Worker 
2596*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_rate_allocate_encode(opj_tcd_t * p_tcd,OPJ_BYTE * p_dest_data,OPJ_UINT32 p_max_dest_size,opj_codestream_info_t * p_cstr_info,opj_event_mgr_t * p_manager)2597*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_rate_allocate_encode(opj_tcd_t *p_tcd,
2598*3ac0a46fSAndroid Build Coastguard Worker         OPJ_BYTE * p_dest_data,
2599*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 p_max_dest_size,
2600*3ac0a46fSAndroid Build Coastguard Worker         opj_codestream_info_t *p_cstr_info,
2601*3ac0a46fSAndroid Build Coastguard Worker         opj_event_mgr_t *p_manager)
2602*3ac0a46fSAndroid Build Coastguard Worker {
2603*3ac0a46fSAndroid Build Coastguard Worker     opj_cp_t * l_cp = p_tcd->cp;
2604*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_nb_written = 0;
2605*3ac0a46fSAndroid Build Coastguard Worker 
2606*3ac0a46fSAndroid Build Coastguard Worker     if (p_cstr_info)  {
2607*3ac0a46fSAndroid Build Coastguard Worker         p_cstr_info->index_write = 0;
2608*3ac0a46fSAndroid Build Coastguard Worker     }
2609*3ac0a46fSAndroid Build Coastguard Worker 
2610*3ac0a46fSAndroid Build Coastguard Worker     if (l_cp->m_specific_param.m_enc.m_disto_alloc ||
2611*3ac0a46fSAndroid Build Coastguard Worker             l_cp->m_specific_param.m_enc.m_fixed_quality)  {
2612*3ac0a46fSAndroid Build Coastguard Worker         /* fixed_quality */
2613*3ac0a46fSAndroid Build Coastguard Worker         /* Normal Rate/distortion allocation */
2614*3ac0a46fSAndroid Build Coastguard Worker         if (! opj_tcd_rateallocate(p_tcd, p_dest_data, &l_nb_written, p_max_dest_size,
2615*3ac0a46fSAndroid Build Coastguard Worker                                    p_cstr_info, p_manager)) {
2616*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
2617*3ac0a46fSAndroid Build Coastguard Worker         }
2618*3ac0a46fSAndroid Build Coastguard Worker     } else {
2619*3ac0a46fSAndroid Build Coastguard Worker         /* Fixed layer allocation */
2620*3ac0a46fSAndroid Build Coastguard Worker         opj_tcd_rateallocate_fixed(p_tcd);
2621*3ac0a46fSAndroid Build Coastguard Worker     }
2622*3ac0a46fSAndroid Build Coastguard Worker 
2623*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
2624*3ac0a46fSAndroid Build Coastguard Worker }
2625*3ac0a46fSAndroid Build Coastguard Worker 
2626*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_copy_tile_data(opj_tcd_t * p_tcd,OPJ_BYTE * p_src,OPJ_SIZE_T p_src_length)2627*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_tcd_copy_tile_data(opj_tcd_t *p_tcd,
2628*3ac0a46fSAndroid Build Coastguard Worker                                 OPJ_BYTE * p_src,
2629*3ac0a46fSAndroid Build Coastguard Worker                                 OPJ_SIZE_T p_src_length)
2630*3ac0a46fSAndroid Build Coastguard Worker {
2631*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 i;
2632*3ac0a46fSAndroid Build Coastguard Worker     OPJ_SIZE_T j;
2633*3ac0a46fSAndroid Build Coastguard Worker     OPJ_SIZE_T l_data_size = 0;
2634*3ac0a46fSAndroid Build Coastguard Worker     opj_image_comp_t * l_img_comp = 00;
2635*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t * l_tilec = 00;
2636*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_size_comp, l_remaining;
2637*3ac0a46fSAndroid Build Coastguard Worker     OPJ_SIZE_T l_nb_elem;
2638*3ac0a46fSAndroid Build Coastguard Worker 
2639*3ac0a46fSAndroid Build Coastguard Worker     l_data_size = opj_tcd_get_encoder_input_buffer_size(p_tcd);
2640*3ac0a46fSAndroid Build Coastguard Worker     if (l_data_size != p_src_length) {
2641*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
2642*3ac0a46fSAndroid Build Coastguard Worker     }
2643*3ac0a46fSAndroid Build Coastguard Worker 
2644*3ac0a46fSAndroid Build Coastguard Worker     l_tilec = p_tcd->tcd_image->tiles->comps;
2645*3ac0a46fSAndroid Build Coastguard Worker     l_img_comp = p_tcd->image->comps;
2646*3ac0a46fSAndroid Build Coastguard Worker     for (i = 0; i < p_tcd->image->numcomps; ++i) {
2647*3ac0a46fSAndroid Build Coastguard Worker         l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
2648*3ac0a46fSAndroid Build Coastguard Worker         l_remaining = l_img_comp->prec & 7;  /* (%8) */
2649*3ac0a46fSAndroid Build Coastguard Worker         l_nb_elem = (OPJ_SIZE_T)(l_tilec->x1 - l_tilec->x0) *
2650*3ac0a46fSAndroid Build Coastguard Worker                     (OPJ_SIZE_T)(l_tilec->y1 - l_tilec->y0);
2651*3ac0a46fSAndroid Build Coastguard Worker 
2652*3ac0a46fSAndroid Build Coastguard Worker         if (l_remaining) {
2653*3ac0a46fSAndroid Build Coastguard Worker             ++l_size_comp;
2654*3ac0a46fSAndroid Build Coastguard Worker         }
2655*3ac0a46fSAndroid Build Coastguard Worker 
2656*3ac0a46fSAndroid Build Coastguard Worker         if (l_size_comp == 3) {
2657*3ac0a46fSAndroid Build Coastguard Worker             l_size_comp = 4;
2658*3ac0a46fSAndroid Build Coastguard Worker         }
2659*3ac0a46fSAndroid Build Coastguard Worker 
2660*3ac0a46fSAndroid Build Coastguard Worker         switch (l_size_comp) {
2661*3ac0a46fSAndroid Build Coastguard Worker         case 1: {
2662*3ac0a46fSAndroid Build Coastguard Worker             OPJ_CHAR * l_src_ptr = (OPJ_CHAR *) p_src;
2663*3ac0a46fSAndroid Build Coastguard Worker             OPJ_INT32 * l_dest_ptr = l_tilec->data;
2664*3ac0a46fSAndroid Build Coastguard Worker 
2665*3ac0a46fSAndroid Build Coastguard Worker             if (l_img_comp->sgnd) {
2666*3ac0a46fSAndroid Build Coastguard Worker                 for (j = 0; j < l_nb_elem; ++j) {
2667*3ac0a46fSAndroid Build Coastguard Worker                     *(l_dest_ptr++) = (OPJ_INT32)(*(l_src_ptr++));
2668*3ac0a46fSAndroid Build Coastguard Worker                 }
2669*3ac0a46fSAndroid Build Coastguard Worker             } else {
2670*3ac0a46fSAndroid Build Coastguard Worker                 for (j = 0; j < l_nb_elem; ++j) {
2671*3ac0a46fSAndroid Build Coastguard Worker                     *(l_dest_ptr++) = (*(l_src_ptr++)) & 0xff;
2672*3ac0a46fSAndroid Build Coastguard Worker                 }
2673*3ac0a46fSAndroid Build Coastguard Worker             }
2674*3ac0a46fSAndroid Build Coastguard Worker 
2675*3ac0a46fSAndroid Build Coastguard Worker             p_src = (OPJ_BYTE*) l_src_ptr;
2676*3ac0a46fSAndroid Build Coastguard Worker         }
2677*3ac0a46fSAndroid Build Coastguard Worker         break;
2678*3ac0a46fSAndroid Build Coastguard Worker         case 2: {
2679*3ac0a46fSAndroid Build Coastguard Worker             OPJ_INT32 * l_dest_ptr = l_tilec->data;
2680*3ac0a46fSAndroid Build Coastguard Worker             OPJ_INT16 * l_src_ptr = (OPJ_INT16 *) p_src;
2681*3ac0a46fSAndroid Build Coastguard Worker 
2682*3ac0a46fSAndroid Build Coastguard Worker             if (l_img_comp->sgnd) {
2683*3ac0a46fSAndroid Build Coastguard Worker                 for (j = 0; j < l_nb_elem; ++j) {
2684*3ac0a46fSAndroid Build Coastguard Worker                     *(l_dest_ptr++) = (OPJ_INT32)(*(l_src_ptr++));
2685*3ac0a46fSAndroid Build Coastguard Worker                 }
2686*3ac0a46fSAndroid Build Coastguard Worker             } else {
2687*3ac0a46fSAndroid Build Coastguard Worker                 for (j = 0; j < l_nb_elem; ++j) {
2688*3ac0a46fSAndroid Build Coastguard Worker                     *(l_dest_ptr++) = (*(l_src_ptr++)) & 0xffff;
2689*3ac0a46fSAndroid Build Coastguard Worker                 }
2690*3ac0a46fSAndroid Build Coastguard Worker             }
2691*3ac0a46fSAndroid Build Coastguard Worker 
2692*3ac0a46fSAndroid Build Coastguard Worker             p_src = (OPJ_BYTE*) l_src_ptr;
2693*3ac0a46fSAndroid Build Coastguard Worker         }
2694*3ac0a46fSAndroid Build Coastguard Worker         break;
2695*3ac0a46fSAndroid Build Coastguard Worker         case 4: {
2696*3ac0a46fSAndroid Build Coastguard Worker             OPJ_INT32 * l_src_ptr = (OPJ_INT32 *) p_src;
2697*3ac0a46fSAndroid Build Coastguard Worker             OPJ_INT32 * l_dest_ptr = l_tilec->data;
2698*3ac0a46fSAndroid Build Coastguard Worker 
2699*3ac0a46fSAndroid Build Coastguard Worker             for (j = 0; j < l_nb_elem; ++j) {
2700*3ac0a46fSAndroid Build Coastguard Worker                 *(l_dest_ptr++) = (OPJ_INT32)(*(l_src_ptr++));
2701*3ac0a46fSAndroid Build Coastguard Worker             }
2702*3ac0a46fSAndroid Build Coastguard Worker 
2703*3ac0a46fSAndroid Build Coastguard Worker             p_src = (OPJ_BYTE*) l_src_ptr;
2704*3ac0a46fSAndroid Build Coastguard Worker         }
2705*3ac0a46fSAndroid Build Coastguard Worker         break;
2706*3ac0a46fSAndroid Build Coastguard Worker         }
2707*3ac0a46fSAndroid Build Coastguard Worker 
2708*3ac0a46fSAndroid Build Coastguard Worker         ++l_img_comp;
2709*3ac0a46fSAndroid Build Coastguard Worker         ++l_tilec;
2710*3ac0a46fSAndroid Build Coastguard Worker     }
2711*3ac0a46fSAndroid Build Coastguard Worker 
2712*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
2713*3ac0a46fSAndroid Build Coastguard Worker }
2714*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_is_band_empty(opj_tcd_band_t * band)2715*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_tcd_is_band_empty(opj_tcd_band_t* band)
2716*3ac0a46fSAndroid Build Coastguard Worker {
2717*3ac0a46fSAndroid Build Coastguard Worker     return (band->x1 - band->x0 == 0) || (band->y1 - band->y0 == 0);
2718*3ac0a46fSAndroid Build Coastguard Worker }
2719*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_is_subband_area_of_interest(opj_tcd_t * tcd,OPJ_UINT32 compno,OPJ_UINT32 resno,OPJ_UINT32 bandno,OPJ_UINT32 band_x0,OPJ_UINT32 band_y0,OPJ_UINT32 band_x1,OPJ_UINT32 band_y1)2720*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_tcd_is_subband_area_of_interest(opj_tcd_t *tcd,
2721*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 compno,
2722*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 resno,
2723*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 bandno,
2724*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 band_x0,
2725*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 band_y0,
2726*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 band_x1,
2727*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 band_y1)
2728*3ac0a46fSAndroid Build Coastguard Worker {
2729*3ac0a46fSAndroid Build Coastguard Worker     /* Note: those values for filter_margin are in part the result of */
2730*3ac0a46fSAndroid Build Coastguard Worker     /* experimentation. The value 2 for QMFBID=1 (5x3 filter) can be linked */
2731*3ac0a46fSAndroid Build Coastguard Worker     /* to the maximum left/right extension given in tables F.2 and F.3 of the */
2732*3ac0a46fSAndroid Build Coastguard Worker     /* standard. The value 3 for QMFBID=0 (9x7 filter) is more suspicious, */
2733*3ac0a46fSAndroid Build Coastguard Worker     /* since F.2 and F.3 would lead to 4 instead, so the current 3 might be */
2734*3ac0a46fSAndroid Build Coastguard Worker     /* needed to be bumped to 4, in case inconsistencies are found while */
2735*3ac0a46fSAndroid Build Coastguard Worker     /* decoding parts of irreversible coded images. */
2736*3ac0a46fSAndroid Build Coastguard Worker     /* See opj_dwt_decode_partial_53 and opj_dwt_decode_partial_97 as well */
2737*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 filter_margin = (tcd->tcp->tccps[compno].qmfbid == 1) ? 2 : 3;
2738*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t *tilec = &(tcd->tcd_image->tiles->comps[compno]);
2739*3ac0a46fSAndroid Build Coastguard Worker     opj_image_comp_t* image_comp = &(tcd->image->comps[compno]);
2740*3ac0a46fSAndroid Build Coastguard Worker     /* Compute the intersection of the area of interest, expressed in tile coordinates */
2741*3ac0a46fSAndroid Build Coastguard Worker     /* with the tile coordinates */
2742*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tcx0 = opj_uint_max(
2743*3ac0a46fSAndroid Build Coastguard Worker                           (OPJ_UINT32)tilec->x0,
2744*3ac0a46fSAndroid Build Coastguard Worker                           opj_uint_ceildiv(tcd->win_x0, image_comp->dx));
2745*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tcy0 = opj_uint_max(
2746*3ac0a46fSAndroid Build Coastguard Worker                           (OPJ_UINT32)tilec->y0,
2747*3ac0a46fSAndroid Build Coastguard Worker                           opj_uint_ceildiv(tcd->win_y0, image_comp->dy));
2748*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tcx1 = opj_uint_min(
2749*3ac0a46fSAndroid Build Coastguard Worker                           (OPJ_UINT32)tilec->x1,
2750*3ac0a46fSAndroid Build Coastguard Worker                           opj_uint_ceildiv(tcd->win_x1, image_comp->dx));
2751*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tcy1 = opj_uint_min(
2752*3ac0a46fSAndroid Build Coastguard Worker                           (OPJ_UINT32)tilec->y1,
2753*3ac0a46fSAndroid Build Coastguard Worker                           opj_uint_ceildiv(tcd->win_y1, image_comp->dy));
2754*3ac0a46fSAndroid Build Coastguard Worker     /* Compute number of decomposition for this band. See table F-1 */
2755*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 nb = (resno == 0) ?
2756*3ac0a46fSAndroid Build Coastguard Worker                     tilec->numresolutions - 1 :
2757*3ac0a46fSAndroid Build Coastguard Worker                     tilec->numresolutions - resno;
2758*3ac0a46fSAndroid Build Coastguard Worker     /* Map above tile-based coordinates to sub-band-based coordinates per */
2759*3ac0a46fSAndroid Build Coastguard Worker     /* equation B-15 of the standard */
2760*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 x0b = bandno & 1;
2761*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 y0b = bandno >> 1;
2762*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tbx0 = (nb == 0) ? tcx0 :
2763*3ac0a46fSAndroid Build Coastguard Worker                       (tcx0 <= (1U << (nb - 1)) * x0b) ? 0 :
2764*3ac0a46fSAndroid Build Coastguard Worker                       opj_uint_ceildivpow2(tcx0 - (1U << (nb - 1)) * x0b, nb);
2765*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tby0 = (nb == 0) ? tcy0 :
2766*3ac0a46fSAndroid Build Coastguard Worker                       (tcy0 <= (1U << (nb - 1)) * y0b) ? 0 :
2767*3ac0a46fSAndroid Build Coastguard Worker                       opj_uint_ceildivpow2(tcy0 - (1U << (nb - 1)) * y0b, nb);
2768*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tbx1 = (nb == 0) ? tcx1 :
2769*3ac0a46fSAndroid Build Coastguard Worker                       (tcx1 <= (1U << (nb - 1)) * x0b) ? 0 :
2770*3ac0a46fSAndroid Build Coastguard Worker                       opj_uint_ceildivpow2(tcx1 - (1U << (nb - 1)) * x0b, nb);
2771*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tby1 = (nb == 0) ? tcy1 :
2772*3ac0a46fSAndroid Build Coastguard Worker                       (tcy1 <= (1U << (nb - 1)) * y0b) ? 0 :
2773*3ac0a46fSAndroid Build Coastguard Worker                       opj_uint_ceildivpow2(tcy1 - (1U << (nb - 1)) * y0b, nb);
2774*3ac0a46fSAndroid Build Coastguard Worker     OPJ_BOOL intersects;
2775*3ac0a46fSAndroid Build Coastguard Worker 
2776*3ac0a46fSAndroid Build Coastguard Worker     if (tbx0 < filter_margin) {
2777*3ac0a46fSAndroid Build Coastguard Worker         tbx0 = 0;
2778*3ac0a46fSAndroid Build Coastguard Worker     } else {
2779*3ac0a46fSAndroid Build Coastguard Worker         tbx0 -= filter_margin;
2780*3ac0a46fSAndroid Build Coastguard Worker     }
2781*3ac0a46fSAndroid Build Coastguard Worker     if (tby0 < filter_margin) {
2782*3ac0a46fSAndroid Build Coastguard Worker         tby0 = 0;
2783*3ac0a46fSAndroid Build Coastguard Worker     } else {
2784*3ac0a46fSAndroid Build Coastguard Worker         tby0 -= filter_margin;
2785*3ac0a46fSAndroid Build Coastguard Worker     }
2786*3ac0a46fSAndroid Build Coastguard Worker     tbx1 = opj_uint_adds(tbx1, filter_margin);
2787*3ac0a46fSAndroid Build Coastguard Worker     tby1 = opj_uint_adds(tby1, filter_margin);
2788*3ac0a46fSAndroid Build Coastguard Worker 
2789*3ac0a46fSAndroid Build Coastguard Worker     intersects = band_x0 < tbx1 && band_y0 < tby1 && band_x1 > tbx0 &&
2790*3ac0a46fSAndroid Build Coastguard Worker                  band_y1 > tby0;
2791*3ac0a46fSAndroid Build Coastguard Worker 
2792*3ac0a46fSAndroid Build Coastguard Worker #ifdef DEBUG_VERBOSE
2793*3ac0a46fSAndroid Build Coastguard Worker     printf("compno=%u resno=%u nb=%u bandno=%u x0b=%u y0b=%u band=%u,%u,%u,%u tb=%u,%u,%u,%u -> %u\n",
2794*3ac0a46fSAndroid Build Coastguard Worker            compno, resno, nb, bandno, x0b, y0b,
2795*3ac0a46fSAndroid Build Coastguard Worker            band_x0, band_y0, band_x1, band_y1,
2796*3ac0a46fSAndroid Build Coastguard Worker            tbx0, tby0, tbx1, tby1, intersects);
2797*3ac0a46fSAndroid Build Coastguard Worker #endif
2798*3ac0a46fSAndroid Build Coastguard Worker     return intersects;
2799*3ac0a46fSAndroid Build Coastguard Worker }
2800*3ac0a46fSAndroid Build Coastguard Worker 
2801*3ac0a46fSAndroid Build Coastguard Worker /** Returns whether a tile componenent is fully decoded, taking into account
2802*3ac0a46fSAndroid Build Coastguard Worker  * p_tcd->win_* members.
2803*3ac0a46fSAndroid Build Coastguard Worker  *
2804*3ac0a46fSAndroid Build Coastguard Worker  * @param p_tcd    TCD handle.
2805*3ac0a46fSAndroid Build Coastguard Worker  * @param compno Component number
2806*3ac0a46fSAndroid Build Coastguard Worker  * @return OPJ_TRUE whether the tile componenent is fully decoded
2807*3ac0a46fSAndroid Build Coastguard Worker  */
opj_tcd_is_whole_tilecomp_decoding(opj_tcd_t * p_tcd,OPJ_UINT32 compno)2808*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_tcd_is_whole_tilecomp_decoding(opj_tcd_t *p_tcd,
2809*3ac0a46fSAndroid Build Coastguard Worker         OPJ_UINT32 compno)
2810*3ac0a46fSAndroid Build Coastguard Worker {
2811*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_tilecomp_t* tilec = &(p_tcd->tcd_image->tiles->comps[compno]);
2812*3ac0a46fSAndroid Build Coastguard Worker     opj_image_comp_t* image_comp = &(p_tcd->image->comps[compno]);
2813*3ac0a46fSAndroid Build Coastguard Worker     /* Compute the intersection of the area of interest, expressed in tile coordinates */
2814*3ac0a46fSAndroid Build Coastguard Worker     /* with the tile coordinates */
2815*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tcx0 = opj_uint_max(
2816*3ac0a46fSAndroid Build Coastguard Worker                           (OPJ_UINT32)tilec->x0,
2817*3ac0a46fSAndroid Build Coastguard Worker                           opj_uint_ceildiv(p_tcd->win_x0, image_comp->dx));
2818*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tcy0 = opj_uint_max(
2819*3ac0a46fSAndroid Build Coastguard Worker                           (OPJ_UINT32)tilec->y0,
2820*3ac0a46fSAndroid Build Coastguard Worker                           opj_uint_ceildiv(p_tcd->win_y0, image_comp->dy));
2821*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tcx1 = opj_uint_min(
2822*3ac0a46fSAndroid Build Coastguard Worker                           (OPJ_UINT32)tilec->x1,
2823*3ac0a46fSAndroid Build Coastguard Worker                           opj_uint_ceildiv(p_tcd->win_x1, image_comp->dx));
2824*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 tcy1 = opj_uint_min(
2825*3ac0a46fSAndroid Build Coastguard Worker                           (OPJ_UINT32)tilec->y1,
2826*3ac0a46fSAndroid Build Coastguard Worker                           opj_uint_ceildiv(p_tcd->win_y1, image_comp->dy));
2827*3ac0a46fSAndroid Build Coastguard Worker 
2828*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 shift = tilec->numresolutions - tilec->minimum_num_resolutions;
2829*3ac0a46fSAndroid Build Coastguard Worker     /* Tolerate small margin within the reduced resolution factor to consider if */
2830*3ac0a46fSAndroid Build Coastguard Worker     /* the whole tile path must be taken */
2831*3ac0a46fSAndroid Build Coastguard Worker     return (tcx0 >= (OPJ_UINT32)tilec->x0 &&
2832*3ac0a46fSAndroid Build Coastguard Worker             tcy0 >= (OPJ_UINT32)tilec->y0 &&
2833*3ac0a46fSAndroid Build Coastguard Worker             tcx1 <= (OPJ_UINT32)tilec->x1 &&
2834*3ac0a46fSAndroid Build Coastguard Worker             tcy1 <= (OPJ_UINT32)tilec->y1 &&
2835*3ac0a46fSAndroid Build Coastguard Worker             (shift >= 32 ||
2836*3ac0a46fSAndroid Build Coastguard Worker              (((tcx0 - (OPJ_UINT32)tilec->x0) >> shift) == 0 &&
2837*3ac0a46fSAndroid Build Coastguard Worker               ((tcy0 - (OPJ_UINT32)tilec->y0) >> shift) == 0 &&
2838*3ac0a46fSAndroid Build Coastguard Worker               (((OPJ_UINT32)tilec->x1 - tcx1) >> shift) == 0 &&
2839*3ac0a46fSAndroid Build Coastguard Worker               (((OPJ_UINT32)tilec->y1 - tcy1) >> shift) == 0)));
2840*3ac0a46fSAndroid Build Coastguard Worker }
2841*3ac0a46fSAndroid Build Coastguard Worker 
2842*3ac0a46fSAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
2843*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_marker_info_create(OPJ_BOOL need_PLT)2844*3ac0a46fSAndroid Build Coastguard Worker opj_tcd_marker_info_t* opj_tcd_marker_info_create(OPJ_BOOL need_PLT)
2845*3ac0a46fSAndroid Build Coastguard Worker {
2846*3ac0a46fSAndroid Build Coastguard Worker     opj_tcd_marker_info_t *l_tcd_marker_info =
2847*3ac0a46fSAndroid Build Coastguard Worker         (opj_tcd_marker_info_t*) opj_calloc(1, sizeof(opj_tcd_marker_info_t));
2848*3ac0a46fSAndroid Build Coastguard Worker     if (!l_tcd_marker_info) {
2849*3ac0a46fSAndroid Build Coastguard Worker         return NULL;
2850*3ac0a46fSAndroid Build Coastguard Worker     }
2851*3ac0a46fSAndroid Build Coastguard Worker 
2852*3ac0a46fSAndroid Build Coastguard Worker     l_tcd_marker_info->need_PLT = need_PLT;
2853*3ac0a46fSAndroid Build Coastguard Worker 
2854*3ac0a46fSAndroid Build Coastguard Worker     return l_tcd_marker_info;
2855*3ac0a46fSAndroid Build Coastguard Worker }
2856*3ac0a46fSAndroid Build Coastguard Worker 
2857*3ac0a46fSAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
2858*3ac0a46fSAndroid Build Coastguard Worker 
opj_tcd_marker_info_destroy(opj_tcd_marker_info_t * p_tcd_marker_info)2859*3ac0a46fSAndroid Build Coastguard Worker void opj_tcd_marker_info_destroy(opj_tcd_marker_info_t *p_tcd_marker_info)
2860*3ac0a46fSAndroid Build Coastguard Worker {
2861*3ac0a46fSAndroid Build Coastguard Worker     if (p_tcd_marker_info) {
2862*3ac0a46fSAndroid Build Coastguard Worker         opj_free(p_tcd_marker_info->p_packet_size);
2863*3ac0a46fSAndroid Build Coastguard Worker         opj_free(p_tcd_marker_info);
2864*3ac0a46fSAndroid Build Coastguard Worker     }
2865*3ac0a46fSAndroid Build Coastguard Worker }
2866*3ac0a46fSAndroid Build Coastguard Worker 
2867*3ac0a46fSAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
2868