1 /*
2  * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3  *   British Columbia.
4  * Copyright (c) 2001-2002 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  * Sequence/Matrix Library
66  *
67  * $Id$
68  */
69 
70 /******************************************************************************\
71 * Includes.
72 \******************************************************************************/
73 
74 #include "jasper/jas_seq.h"
75 #include "jasper/jas_malloc.h"
76 #include "jasper/jas_math.h"
77 
78 #include <assert.h>
79 
80 /******************************************************************************\
81 * Constructors and destructors.
82 \******************************************************************************/
83 
jas_seq2d_create(jas_matind_t xstart,jas_matind_t ystart,jas_matind_t xend,jas_matind_t yend)84 jas_matrix_t *jas_seq2d_create(jas_matind_t xstart, jas_matind_t ystart,
85   jas_matind_t xend, jas_matind_t yend)
86 {
87 	jas_matrix_t *matrix;
88 	assert(xstart <= xend && ystart <= yend);
89 	if (!(matrix = jas_matrix_create(yend - ystart, xend - xstart))) {
90 		return 0;
91 	}
92 	matrix->xstart_ = xstart;
93 	matrix->ystart_ = ystart;
94 	matrix->xend_ = xend;
95 	matrix->yend_ = yend;
96 	return matrix;
97 }
98 
jas_matrix_create(jas_matind_t numrows,jas_matind_t numcols)99 jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols)
100 {
101 	jas_matrix_t *matrix;
102 	jas_matind_t i;
103 	size_t size;
104 
105 	matrix = 0;
106 
107 	if (numrows < 0 || numcols < 0) {
108 		return NULL;
109 	}
110 
111 	// matrix->datasize_ = numrows * numcols;
112 	if (!jas_safe_size_mul(numrows, numcols, &size) ||
113 	    size > UINT_FAST32_MAX) {
114 		return NULL;
115 	}
116 
117 	if (!(matrix = jas_malloc(sizeof(jas_matrix_t)))) {
118 		return NULL;
119 	}
120 	matrix->flags_ = 0;
121 	matrix->numrows_ = numrows;
122 	matrix->numcols_ = numcols;
123 	matrix->rows_ = 0;
124 	matrix->maxrows_ = numrows;
125 	matrix->data_ = 0;
126 	matrix->datasize_ = size;
127 
128 	if (matrix->maxrows_ > 0) {
129 		if (!(matrix->rows_ = jas_alloc2(matrix->maxrows_,
130 		  sizeof(jas_seqent_t *)))) {
131 			goto error;
132 		}
133 	}
134 
135 	if (matrix->datasize_ > 0) {
136 		if (!(matrix->data_ = jas_alloc2(matrix->datasize_,
137 		  sizeof(jas_seqent_t)))) {
138 			goto error;
139 		}
140 
141 		memset(matrix->data_, 0,
142 		       matrix->datasize_ * sizeof(jas_seqent_t));
143 	}
144 
145 	for (i = 0; i < numrows; ++i) {
146 		matrix->rows_[i] = &matrix->data_[i * matrix->numcols_];
147 	}
148 
149 	matrix->xstart_ = 0;
150 	matrix->ystart_ = 0;
151 	matrix->xend_ = matrix->numcols_;
152 	matrix->yend_ = matrix->numrows_;
153 
154 	return matrix;
155 
156 error:
157 	jas_matrix_destroy(matrix);
158 	return 0;
159 }
160 
jas_matrix_destroy(jas_matrix_t * matrix)161 void jas_matrix_destroy(jas_matrix_t *matrix)
162 {
163 	if (matrix->data_) {
164 		assert(!(matrix->flags_ & JAS_MATRIX_REF));
165 	}
166 	jas_free(matrix->data_);
167 	jas_free(matrix->rows_);
168 	jas_free(matrix);
169 }
170 
jas_seq2d_copy(jas_seq2d_t * x)171 jas_seq2d_t *jas_seq2d_copy(jas_seq2d_t *x)
172 {
173 	jas_matrix_t *y;
174 	jas_matind_t i;
175 	jas_matind_t j;
176 	y = jas_seq2d_create(jas_seq2d_xstart(x), jas_seq2d_ystart(x),
177 	  jas_seq2d_xend(x), jas_seq2d_yend(x));
178 	assert(y);
179 	for (i = 0; i < x->numrows_; ++i) {
180 		for (j = 0; j < x->numcols_; ++j) {
181 			*jas_matrix_getref(y, i, j) = jas_matrix_get(x, i, j);
182 		}
183 	}
184 	return y;
185 }
186 
jas_matrix_copy(jas_matrix_t * x)187 jas_matrix_t *jas_matrix_copy(jas_matrix_t *x)
188 {
189 	jas_matrix_t *y;
190 	jas_matind_t i;
191 	jas_matind_t j;
192 	y = jas_matrix_create(x->numrows_, x->numcols_);
193 	for (i = 0; i < x->numrows_; ++i) {
194 		for (j = 0; j < x->numcols_; ++j) {
195 			*jas_matrix_getref(y, i, j) = jas_matrix_get(x, i, j);
196 		}
197 	}
198 	return y;
199 }
200 
201 /******************************************************************************\
202 * Bind operations.
203 \******************************************************************************/
204 
jas_seq2d_bindsub(jas_matrix_t * s,jas_matrix_t * s1,jas_matind_t xstart,jas_matind_t ystart,jas_matind_t xend,jas_matind_t yend)205 int jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, jas_matind_t xstart,
206   jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend)
207 {
208 	if (xstart < s1->xstart_ || ystart < s1->ystart_ ||
209 	    xend > s1->xend_ || yend > s1->yend_)
210 		return -1;
211 
212 	return jas_matrix_bindsub(s, s1, ystart - s1->ystart_, xstart - s1->xstart_,
213 				  yend - s1->ystart_ - 1, xend - s1->xstart_ - 1);
214 }
215 
jas_matrix_bindsub(jas_matrix_t * mat0,jas_matrix_t * mat1,jas_matind_t r0,jas_matind_t c0,jas_matind_t r1,jas_matind_t c1)216 int jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1,
217   jas_matind_t r0, jas_matind_t c0, jas_matind_t r1, jas_matind_t c1)
218 {
219 	jas_matind_t i;
220 
221 	if (mat0->data_) {
222 		if (!(mat0->flags_ & JAS_MATRIX_REF)) {
223 			jas_free(mat0->data_);
224 		}
225 		mat0->data_ = 0;
226 		mat0->datasize_ = 0;
227 	}
228 	if (mat0->rows_) {
229 		jas_free(mat0->rows_);
230 		mat0->rows_ = 0;
231 	}
232 	mat0->flags_ |= JAS_MATRIX_REF;
233 	mat0->numrows_ = r1 - r0 + 1;
234 	mat0->numcols_ = c1 - c0 + 1;
235 	mat0->maxrows_ = mat0->numrows_;
236 	if (!(mat0->rows_ = jas_alloc2(mat0->maxrows_, sizeof(jas_seqent_t *)))) {
237 		return -1;
238 	}
239 
240 	for (i = 0; i < mat0->numrows_; ++i) {
241 		mat0->rows_[i] = mat1->rows_[r0 + i] + c0;
242 	}
243 
244 	mat0->xstart_ = mat1->xstart_ + c0;
245 	mat0->ystart_ = mat1->ystart_ + r0;
246 	mat0->xend_ = mat0->xstart_ + mat0->numcols_;
247 	mat0->yend_ = mat0->ystart_ + mat0->numrows_;
248 
249 	return 0;
250 }
251 
252 /******************************************************************************\
253 * Arithmetic operations.
254 \******************************************************************************/
255 
jas_matrix_cmp(jas_matrix_t * mat0,jas_matrix_t * mat1)256 int jas_matrix_cmp(jas_matrix_t *mat0, jas_matrix_t *mat1)
257 {
258 	jas_matind_t i;
259 	jas_matind_t j;
260 
261 	if (mat0->numrows_ != mat1->numrows_ || mat0->numcols_ !=
262 	  mat1->numcols_) {
263 		return 1;
264 	}
265 	for (i = 0; i < mat0->numrows_; i++) {
266 		for (j = 0; j < mat0->numcols_; j++) {
267 			if (jas_matrix_get(mat0, i, j) != jas_matrix_get(mat1, i, j)) {
268 				return 1;
269 			}
270 		}
271 	}
272 	return 0;
273 }
274 
jas_matrix_divpow2(jas_matrix_t * matrix,unsigned n)275 void jas_matrix_divpow2(jas_matrix_t *matrix, unsigned n)
276 {
277 	jas_matind_t i;
278 	jas_matind_t j;
279 	jas_seqent_t *rowstart;
280 	jas_matind_t rowstep;
281 	jas_seqent_t *data;
282 
283 	if (jas_matrix_numrows(matrix) > 0 && jas_matrix_numcols(matrix) > 0) {
284 		assert(matrix->rows_);
285 		rowstep = jas_matrix_rowstep(matrix);
286 		for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
287 		  rowstart += rowstep) {
288 			for (j = matrix->numcols_, data = rowstart; j > 0; --j,
289 			  ++data) {
290 				*data = (*data >= 0) ? ((*data) >> n) :
291 				  (-((-(*data)) >> n));
292 			}
293 		}
294 	}
295 }
296 
jas_matrix_clip(jas_matrix_t * matrix,jas_seqent_t minval,jas_seqent_t maxval)297 void jas_matrix_clip(jas_matrix_t *matrix, jas_seqent_t minval,
298   jas_seqent_t maxval)
299 {
300 	jas_matind_t i;
301 	jas_matind_t j;
302 	jas_seqent_t v;
303 	jas_seqent_t *rowstart;
304 	jas_seqent_t *data;
305 	jas_matind_t rowstep;
306 
307 	if (jas_matrix_numrows(matrix) > 0 && jas_matrix_numcols(matrix) > 0) {
308 		assert(matrix->rows_);
309 		rowstep = jas_matrix_rowstep(matrix);
310 		for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
311 		  rowstart += rowstep) {
312 			data = rowstart;
313 			for (j = matrix->numcols_, data = rowstart; j > 0; --j,
314 			  ++data) {
315 				v = *data;
316 				if (v < minval) {
317 					*data = minval;
318 				} else if (v > maxval) {
319 					*data = maxval;
320 				}
321 			}
322 		}
323 	}
324 }
325 
jas_matrix_asr(jas_matrix_t * matrix,unsigned n)326 void jas_matrix_asr(jas_matrix_t *matrix, unsigned n)
327 {
328 	jas_matind_t i;
329 	jas_matind_t j;
330 	jas_seqent_t *rowstart;
331 	jas_matind_t rowstep;
332 	jas_seqent_t *data;
333 
334 	if (jas_matrix_numrows(matrix) > 0 && jas_matrix_numcols(matrix) > 0) {
335 		assert(matrix->rows_);
336 		rowstep = jas_matrix_rowstep(matrix);
337 		for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
338 		  rowstart += rowstep) {
339 			for (j = matrix->numcols_, data = rowstart; j > 0; --j,
340 			  ++data) {
341 				//*data >>= n;
342 				*data = jas_seqent_asr(*data, n);
343 			}
344 		}
345 	}
346 }
347 
jas_matrix_asl(jas_matrix_t * matrix,unsigned n)348 void jas_matrix_asl(jas_matrix_t *matrix, unsigned n)
349 {
350 	jas_matind_t i;
351 	jas_matind_t j;
352 	jas_seqent_t *rowstart;
353 	jas_matind_t rowstep;
354 	jas_seqent_t *data;
355 
356 	if (jas_matrix_numrows(matrix) > 0 && jas_matrix_numcols(matrix) > 0) {
357 		assert(matrix->rows_);
358 		rowstep = jas_matrix_rowstep(matrix);
359 		for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
360 		  rowstart += rowstep) {
361 			for (j = matrix->numcols_, data = rowstart; j > 0; --j,
362 			  ++data) {
363 				//*data <<= n;
364 				*data = jas_seqent_asl(*data, n);
365 			}
366 		}
367 	}
368 }
369 
370 /******************************************************************************\
371 * Code.
372 \******************************************************************************/
373 
jas_matrix_resize(jas_matrix_t * matrix,jas_matind_t numrows,jas_matind_t numcols)374 int jas_matrix_resize(jas_matrix_t *matrix, jas_matind_t numrows,
375   jas_matind_t numcols)
376 {
377 	jas_matind_t size;
378 	jas_matind_t i;
379 
380 	size = numrows * numcols;
381 	if (size > matrix->datasize_ || numrows > matrix->maxrows_) {
382 		return -1;
383 	}
384 
385 	matrix->numrows_ = numrows;
386 	matrix->numcols_ = numcols;
387 
388 	for (i = 0; i < numrows; ++i) {
389 		matrix->rows_[i] = &matrix->data_[numcols * i];
390 	}
391 
392 	return 0;
393 }
394 
jas_matrix_setall(jas_matrix_t * matrix,jas_seqent_t val)395 void jas_matrix_setall(jas_matrix_t *matrix, jas_seqent_t val)
396 {
397 	jas_matind_t i;
398 	jas_matind_t j;
399 	jas_seqent_t *rowstart;
400 	jas_matind_t rowstep;
401 	jas_seqent_t *data;
402 
403 	if (jas_matrix_numrows(matrix) > 0 && jas_matrix_numcols(matrix) > 0) {
404 		assert(matrix->rows_);
405 		rowstep = jas_matrix_rowstep(matrix);
406 		for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
407 		  rowstart += rowstep) {
408 			for (j = matrix->numcols_, data = rowstart; j > 0; --j,
409 			  ++data) {
410 				*data = val;
411 			}
412 		}
413 	}
414 }
415