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