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