openjp2/
tcd.rs

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