1 /*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2004 Michael David Adams.
5 * All rights reserved.
6 */
7
8 /* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64 /*
65 * Tree-Structured Filter Bank (TSFB) Library
66 *
67 * $Id$
68 */
69
70 /******************************************************************************\
71 * Includes.
72 \******************************************************************************/
73
74 #include "jpc_tsfb.h"
75 #include "jpc_cs.h"
76 #include "jpc_math.h"
77 #include "jpc_fix.h"
78
79 #include "jasper/jas_seq.h"
80
81 #include <stdlib.h>
82
83 static int jpc_tsfb_analyze2(jpc_tsfb_t *tsfb, jpc_fix_t *a, int xstart, int ystart,
84 unsigned width, unsigned height, unsigned stride, unsigned numlvls);
85
86 static int jpc_tsfb_synthesize2(jpc_tsfb_t *tsfb, jpc_fix_t *a, int xstart, int ystart,
87 unsigned width, unsigned height, unsigned stride, unsigned numlvls);
88
89 static void jpc_tsfb_getbands2(jpc_tsfb_t *tsfb, int locxstart, int locystart,
90 int xstart, int ystart, int xend, int yend, jpc_tsfb_band_t **bands,
91 unsigned numlvls);
92
93 /******************************************************************************\
94 *
95 \******************************************************************************/
96
jpc_cod_gettsfb(unsigned qmfbid,unsigned numlvls)97 jpc_tsfb_t *jpc_cod_gettsfb(unsigned qmfbid, unsigned numlvls)
98 {
99 jpc_tsfb_t *tsfb;
100
101 if (!(tsfb = malloc(sizeof(jpc_tsfb_t))))
102 return 0;
103
104 if (numlvls > 0) {
105 switch (qmfbid) {
106 case JPC_COX_INS:
107 tsfb->qmfb = &jpc_ns_qmfb2d;
108 break;
109 default:
110 case JPC_COX_RFT:
111 tsfb->qmfb = &jpc_ft_qmfb2d;
112 break;
113 }
114 } else {
115 tsfb->qmfb = 0;
116 }
117 tsfb->numlvls = numlvls;
118 return tsfb;
119 }
120
jpc_tsfb_destroy(jpc_tsfb_t * tsfb)121 void jpc_tsfb_destroy(jpc_tsfb_t *tsfb)
122 {
123 free(tsfb);
124 }
125
jpc_tsfb_analyze(jpc_tsfb_t * tsfb,jas_seq2d_t * a)126 int jpc_tsfb_analyze(jpc_tsfb_t *tsfb, jas_seq2d_t *a)
127 {
128 if (tsfb->numlvls == 0)
129 return 0;
130
131 return jpc_tsfb_analyze2(tsfb,
132 jas_seq2d_getref(a, jas_seq2d_xstart(a), jas_seq2d_ystart(a)),
133 jas_seq2d_xstart(a), jas_seq2d_ystart(a),
134 jas_seq2d_width(a), jas_seq2d_height(a),
135 jas_seq2d_rowstep(a), tsfb->numlvls - 1);
136 }
137
jpc_tsfb_analyze2(jpc_tsfb_t * tsfb,jpc_fix_t * a,int xstart,int ystart,unsigned width,unsigned height,unsigned stride,unsigned numlvls)138 static int jpc_tsfb_analyze2(jpc_tsfb_t *tsfb, jpc_fix_t *a, int xstart, int ystart,
139 unsigned width, unsigned height, unsigned stride, unsigned numlvls)
140 {
141 if (width == 0 || height == 0)
142 return 0;
143
144 if ((*tsfb->qmfb->analyze)(a, xstart, ystart, width, height, stride))
145 return -1;
146
147 if (numlvls == 0)
148 return 0;
149
150 return jpc_tsfb_analyze2(tsfb, a,
151 JPC_CEILDIVPOW2(xstart, 1),
152 JPC_CEILDIVPOW2(ystart, 1),
153 JPC_CEILDIVPOW2(xstart + width, 1) - JPC_CEILDIVPOW2(xstart, 1),
154 JPC_CEILDIVPOW2(ystart + height, 1) - JPC_CEILDIVPOW2(ystart, 1),
155 stride, numlvls - 1);
156 }
157
jpc_tsfb_synthesize(jpc_tsfb_t * tsfb,jas_seq2d_t * a)158 int jpc_tsfb_synthesize(jpc_tsfb_t *tsfb, jas_seq2d_t *a)
159 {
160 if (tsfb->numlvls == 0 || jas_seq2d_empty(a))
161 return 0;
162
163 return jpc_tsfb_synthesize2(tsfb,
164 jas_seq2d_getref(a, jas_seq2d_xstart(a), jas_seq2d_ystart(a)),
165 jas_seq2d_xstart(a), jas_seq2d_ystart(a),
166 jas_seq2d_width(a), jas_seq2d_height(a),
167 jas_seq2d_rowstep(a),
168 tsfb->numlvls - 1);
169 }
170
jpc_tsfb_synthesize2(jpc_tsfb_t * tsfb,jpc_fix_t * a,int xstart,int ystart,unsigned width,unsigned height,unsigned stride,unsigned numlvls)171 static int jpc_tsfb_synthesize2(jpc_tsfb_t *tsfb, jpc_fix_t *a, int xstart, int ystart,
172 unsigned width, unsigned height, unsigned stride, unsigned numlvls)
173 {
174 if (numlvls > 0) {
175 if (jpc_tsfb_synthesize2(tsfb, a, JPC_CEILDIVPOW2(xstart, 1),
176 JPC_CEILDIVPOW2(ystart, 1), JPC_CEILDIVPOW2(xstart + width,
177 1) - JPC_CEILDIVPOW2(xstart, 1), JPC_CEILDIVPOW2(ystart +
178 height, 1) - JPC_CEILDIVPOW2(ystart, 1), stride, numlvls -
179 1)) {
180 return -1;
181 }
182 }
183
184 if (width == 0 || height == 0)
185 return 0;
186
187 return tsfb->qmfb->synthesize(a, xstart, ystart, width, height, stride);
188 }
189
jpc_tsfb_getbands(jpc_tsfb_t * tsfb,uint_fast32_t xstart,uint_fast32_t ystart,uint_fast32_t xend,uint_fast32_t yend,jpc_tsfb_band_t * bands)190 int jpc_tsfb_getbands(jpc_tsfb_t *tsfb, uint_fast32_t xstart,
191 uint_fast32_t ystart, uint_fast32_t xend, uint_fast32_t yend,
192 jpc_tsfb_band_t *bands)
193 {
194 jpc_tsfb_band_t *band;
195
196 band = bands;
197 if (tsfb->numlvls > 0) {
198 jpc_tsfb_getbands2(tsfb, xstart, ystart, xstart, ystart, xend, yend,
199 &band, tsfb->numlvls);
200 } else {
201
202 band->xstart = xstart;
203 band->ystart = ystart;
204 band->xend = xend;
205 band->yend = yend;
206 band->locxstart = xstart;
207 band->locystart = ystart;
208 band->locxend = band->locxstart + band->xend - band->xstart;
209 band->locyend = band->locystart + band->yend - band->ystart;
210 band->orient = JPC_TSFB_LL;
211 band->synenergywt = JPC_FIX_ONE;
212 ++band;
213 }
214 return band - bands;
215 }
216
jpc_tsfb_getbands2(jpc_tsfb_t * tsfb,int locxstart,int locystart,int xstart,int ystart,int xend,int yend,jpc_tsfb_band_t ** bands,unsigned numlvls)217 void jpc_tsfb_getbands2(jpc_tsfb_t *tsfb, int locxstart, int locystart,
218 int xstart, int ystart, int xend, int yend, jpc_tsfb_band_t **bands,
219 unsigned numlvls)
220 {
221 int newxstart;
222 int newystart;
223 int newxend;
224 int newyend;
225 jpc_tsfb_band_t *band;
226
227 newxstart = JPC_CEILDIVPOW2(xstart, 1);
228 newystart = JPC_CEILDIVPOW2(ystart, 1);
229 newxend = JPC_CEILDIVPOW2(xend, 1);
230 newyend = JPC_CEILDIVPOW2(yend, 1);
231
232 if (numlvls > 0) {
233
234 jpc_tsfb_getbands2(tsfb, locxstart, locystart, newxstart, newystart,
235 newxend, newyend, bands, numlvls - 1);
236
237 band = *bands;
238 band->xstart = JPC_FLOORDIVPOW2(xstart, 1);
239 band->ystart = newystart;
240 band->xend = JPC_FLOORDIVPOW2(xend, 1);
241 band->yend = newyend;
242 band->locxstart = locxstart + newxend - newxstart;
243 band->locystart = locystart;
244 band->locxend = band->locxstart + band->xend - band->xstart;
245 band->locyend = band->locystart + band->yend - band->ystart;
246 band->orient = JPC_TSFB_HL;
247 band->synenergywt = jpc_dbltofix(tsfb->qmfb->hpenergywts[
248 tsfb->numlvls - numlvls] * tsfb->qmfb->lpenergywts[
249 tsfb->numlvls - numlvls]);
250 ++(*bands);
251
252 band = *bands;
253 band->xstart = newxstart;
254 band->ystart = JPC_FLOORDIVPOW2(ystart, 1);
255 band->xend = newxend;
256 band->yend = JPC_FLOORDIVPOW2(yend, 1);
257 band->locxstart = locxstart;
258 band->locystart = locystart + newyend - newystart;
259 band->locxend = band->locxstart + band->xend - band->xstart;
260 band->locyend = band->locystart + band->yend - band->ystart;
261 band->orient = JPC_TSFB_LH;
262 band->synenergywt = jpc_dbltofix(tsfb->qmfb->lpenergywts[
263 tsfb->numlvls - numlvls] * tsfb->qmfb->hpenergywts[
264 tsfb->numlvls - numlvls]);
265 ++(*bands);
266
267 band = *bands;
268 band->xstart = JPC_FLOORDIVPOW2(xstart, 1);
269 band->ystart = JPC_FLOORDIVPOW2(ystart, 1);
270 band->xend = JPC_FLOORDIVPOW2(xend, 1);
271 band->yend = JPC_FLOORDIVPOW2(yend, 1);
272 band->locxstart = locxstart + newxend - newxstart;
273 band->locystart = locystart + newyend - newystart;
274 band->locxend = band->locxstart + band->xend - band->xstart;
275 band->locyend = band->locystart + band->yend - band->ystart;
276 band->orient = JPC_TSFB_HH;
277 band->synenergywt = jpc_dbltofix(tsfb->qmfb->hpenergywts[
278 tsfb->numlvls - numlvls] * tsfb->qmfb->hpenergywts[
279 tsfb->numlvls - numlvls]);
280 ++(*bands);
281
282 } else {
283
284 band = *bands;
285 band->xstart = xstart;
286 band->ystart = ystart;
287 band->xend = xend;
288 band->yend = yend;
289 band->locxstart = locxstart;
290 band->locystart = locystart;
291 band->locxend = band->locxstart + band->xend - band->xstart;
292 band->locyend = band->locystart + band->yend - band->ystart;
293 band->orient = JPC_TSFB_LL;
294 band->synenergywt = jpc_dbltofix(tsfb->qmfb->lpenergywts[
295 tsfb->numlvls - numlvls - 1] * tsfb->qmfb->lpenergywts[
296 tsfb->numlvls - numlvls - 1]);
297 ++(*bands);
298
299 }
300
301 }
302