~ubuntu-branches/ubuntu/precise/jasper/precise-updates

« back to all changes in this revision

Viewing changes to .pc/01-misc-fixes.patch/src/libjasper/base/jas_image.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2011-10-24 12:33:36 UTC
  • mfrom: (7.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20111024123336-fyqahayo6mm0q7ke
Tags: 1.900.1-10ubuntu1
* Resynchronise with Debian.  Remaining changes (revised for dh(1)):
  - Enable multiarch build.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
 
3
 *   British Columbia.
 
4
 * Copyright (c) 2001-2003 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
 * Image Library
 
66
 *
 
67
 * $Id$
 
68
 */
 
69
 
 
70
/******************************************************************************\
 
71
* Includes.
 
72
\******************************************************************************/
 
73
 
 
74
#include <stdlib.h>
 
75
#include <stdio.h>
 
76
#include <string.h>
 
77
#include <assert.h>
 
78
#include <ctype.h>
 
79
 
 
80
#include "jasper/jas_math.h"
 
81
#include "jasper/jas_image.h"
 
82
#include "jasper/jas_malloc.h"
 
83
#include "jasper/jas_string.h"
 
84
 
 
85
/******************************************************************************\
 
86
* Types.
 
87
\******************************************************************************/
 
88
 
 
89
#define FLOORDIV(x, y) ((x) / (y))
 
90
 
 
91
/******************************************************************************\
 
92
* Local prototypes.
 
93
\******************************************************************************/
 
94
 
 
95
static jas_image_cmpt_t *jas_image_cmpt_create0(void);
 
96
static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt);
 
97
static jas_image_cmpt_t *jas_image_cmpt_create(uint_fast32_t tlx, uint_fast32_t tly,
 
98
  uint_fast32_t hstep, uint_fast32_t vstep, uint_fast32_t width, uint_fast32_t
 
99
  height, uint_fast16_t depth, bool sgnd, uint_fast32_t inmem);
 
100
static void jas_image_setbbox(jas_image_t *image);
 
101
static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt);
 
102
static int jas_image_growcmpts(jas_image_t *image, int maxcmpts);
 
103
static uint_fast32_t inttobits(jas_seqent_t v, int prec, bool sgnd);
 
104
static jas_seqent_t bitstoint(uint_fast32_t v, int prec, bool sgnd);
 
105
static int putint(jas_stream_t *out, int sgnd, int prec, long val);
 
106
static int getint(jas_stream_t *in, int sgnd, int prec, long *val);
 
107
static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx,
 
108
  jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry);
 
109
static long uptomult(long x, long y);
 
110
static long downtomult(long x, long y);
 
111
static long convert(long val, int oldsgnd, int oldprec, int newsgnd,
 
112
  int newprec);
 
113
static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx,
 
114
  jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry);
 
115
 
 
116
/******************************************************************************\
 
117
* Global data.
 
118
\******************************************************************************/
 
119
 
 
120
static int jas_image_numfmts = 0;
 
121
static jas_image_fmtinfo_t jas_image_fmtinfos[JAS_IMAGE_MAXFMTS];
 
122
 
 
123
/******************************************************************************\
 
124
* Create and destroy operations.
 
125
\******************************************************************************/
 
126
 
 
127
jas_image_t *jas_image_create(int numcmpts, jas_image_cmptparm_t *cmptparms,
 
128
  int clrspc)
 
129
{
 
130
        jas_image_t *image;
 
131
        uint_fast32_t rawsize;
 
132
        uint_fast32_t inmem;
 
133
        int cmptno;
 
134
        jas_image_cmptparm_t *cmptparm;
 
135
 
 
136
        if (!(image = jas_image_create0())) {
 
137
                return 0;
 
138
        }
 
139
 
 
140
        image->clrspc_ = clrspc;
 
141
        image->maxcmpts_ = numcmpts;
 
142
        image->inmem_ = true;
 
143
 
 
144
        /* Allocate memory for the per-component information. */
 
145
        if (!(image->cmpts_ = jas_malloc(image->maxcmpts_ *
 
146
          sizeof(jas_image_cmpt_t *)))) {
 
147
                jas_image_destroy(image);
 
148
                return 0;
 
149
        }
 
150
        /* Initialize in case of failure. */
 
151
        for (cmptno = 0; cmptno < image->maxcmpts_; ++cmptno) {
 
152
                image->cmpts_[cmptno] = 0;
 
153
        }
 
154
 
 
155
        /* Compute the approximate raw size of the image. */
 
156
        rawsize = 0;
 
157
        for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno,
 
158
          ++cmptparm) {
 
159
                rawsize += cmptparm->width * cmptparm->height *
 
160
                  (cmptparm->prec + 7) / 8;
 
161
        }
 
162
        /* Decide whether to buffer the image data in memory, based on the
 
163
          raw size of the image. */
 
164
        inmem = (rawsize < JAS_IMAGE_INMEMTHRESH);
 
165
 
 
166
        /* Create the individual image components. */
 
167
        for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno,
 
168
          ++cmptparm) {
 
169
                if (!(image->cmpts_[cmptno] = jas_image_cmpt_create(cmptparm->tlx,
 
170
                  cmptparm->tly, cmptparm->hstep, cmptparm->vstep,
 
171
                  cmptparm->width, cmptparm->height, cmptparm->prec,
 
172
                  cmptparm->sgnd, inmem))) {
 
173
                        jas_image_destroy(image);
 
174
                        return 0;
 
175
                }
 
176
                ++image->numcmpts_;
 
177
        }
 
178
 
 
179
        /* Determine the bounding box for all of the components on the
 
180
          reference grid (i.e., the image area) */
 
181
        jas_image_setbbox(image);
 
182
 
 
183
        return image;
 
184
}
 
185
 
 
186
jas_image_t *jas_image_create0()
 
187
{
 
188
        jas_image_t *image;
 
189
 
 
190
        if (!(image = jas_malloc(sizeof(jas_image_t)))) {
 
191
                return 0;
 
192
        }
 
193
 
 
194
        image->tlx_ = 0;
 
195
        image->tly_ = 0;
 
196
        image->brx_ = 0;
 
197
        image->bry_ = 0;
 
198
        image->clrspc_ = JAS_CLRSPC_UNKNOWN;
 
199
        image->numcmpts_ = 0;
 
200
        image->maxcmpts_ = 0;
 
201
        image->cmpts_ = 0;
 
202
        image->inmem_ = true;
 
203
        image->cmprof_ = 0;
 
204
 
 
205
        return image;
 
206
}
 
207
 
 
208
jas_image_t *jas_image_copy(jas_image_t *image)
 
209
{
 
210
        jas_image_t *newimage;
 
211
        int cmptno;
 
212
 
 
213
        newimage = jas_image_create0();
 
214
        if (jas_image_growcmpts(newimage, image->numcmpts_)) {
 
215
                goto error;
 
216
        }
 
217
        for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
 
218
                if (!(newimage->cmpts_[cmptno] = jas_image_cmpt_copy(image->cmpts_[cmptno]))) {
 
219
                        goto error;
 
220
                }
 
221
                ++newimage->numcmpts_;
 
222
        }
 
223
 
 
224
        jas_image_setbbox(newimage);
 
225
 
 
226
        if (image->cmprof_) {
 
227
                if (!(newimage->cmprof_ = jas_cmprof_copy(image->cmprof_)))
 
228
                        goto error;
 
229
        }
 
230
 
 
231
        return newimage;
 
232
error:
 
233
        if (newimage) {
 
234
                jas_image_destroy(newimage);
 
235
        }
 
236
        return 0;
 
237
}
 
238
 
 
239
static jas_image_cmpt_t *jas_image_cmpt_create0()
 
240
{
 
241
        jas_image_cmpt_t *cmpt;
 
242
        if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) {
 
243
                return 0;
 
244
        }
 
245
        memset(cmpt, 0, sizeof(jas_image_cmpt_t));
 
246
        cmpt->type_ = JAS_IMAGE_CT_UNKNOWN;
 
247
        return cmpt;
 
248
}
 
249
 
 
250
static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt)
 
251
{
 
252
        jas_image_cmpt_t *newcmpt;
 
253
 
 
254
        if (!(newcmpt = jas_image_cmpt_create0())) {
 
255
                return 0;
 
256
        }
 
257
        newcmpt->tlx_ = cmpt->tlx_;
 
258
        newcmpt->tly_ = cmpt->tly_;
 
259
        newcmpt->hstep_ = cmpt->hstep_;
 
260
        newcmpt->vstep_ = cmpt->vstep_;
 
261
        newcmpt->width_ = cmpt->width_;
 
262
        newcmpt->height_ = cmpt->height_;
 
263
        newcmpt->prec_ = cmpt->prec_;
 
264
        newcmpt->sgnd_ = cmpt->sgnd_;
 
265
        newcmpt->cps_ = cmpt->cps_;
 
266
        newcmpt->type_ = cmpt->type_;
 
267
        if (!(newcmpt->stream_ = jas_stream_memopen(0, 0))) {
 
268
                return 0;
 
269
        }
 
270
        if (jas_stream_seek(cmpt->stream_, 0, SEEK_SET)) {
 
271
                return 0;
 
272
        }
 
273
        if (jas_stream_copy(newcmpt->stream_, cmpt->stream_, -1)) {
 
274
                return 0;
 
275
        }
 
276
        if (jas_stream_seek(newcmpt->stream_, 0, SEEK_SET)) {
 
277
                return 0;
 
278
        }
 
279
        return newcmpt;
 
280
}
 
281
 
 
282
void jas_image_destroy(jas_image_t *image)
 
283
{
 
284
        int i;
 
285
 
 
286
        if (image->cmpts_) {
 
287
                for (i = 0; i < image->numcmpts_; ++i) {
 
288
                        jas_image_cmpt_destroy(image->cmpts_[i]);
 
289
                        image->cmpts_[i] = 0;
 
290
                }
 
291
                jas_free(image->cmpts_);
 
292
        }
 
293
        if (image->cmprof_)
 
294
                jas_cmprof_destroy(image->cmprof_);
 
295
        jas_free(image);
 
296
}
 
297
 
 
298
static jas_image_cmpt_t *jas_image_cmpt_create(uint_fast32_t tlx, uint_fast32_t tly,
 
299
  uint_fast32_t hstep, uint_fast32_t vstep, uint_fast32_t width, uint_fast32_t
 
300
  height, uint_fast16_t depth, bool sgnd, uint_fast32_t inmem)
 
301
{
 
302
        jas_image_cmpt_t *cmpt;
 
303
        long size;
 
304
 
 
305
        if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) {
 
306
                return 0;
 
307
        }
 
308
 
 
309
        cmpt->type_ = JAS_IMAGE_CT_UNKNOWN;
 
310
        cmpt->tlx_ = tlx;
 
311
        cmpt->tly_ = tly;
 
312
        cmpt->hstep_ = hstep;
 
313
        cmpt->vstep_ = vstep;
 
314
        cmpt->width_ = width;
 
315
        cmpt->height_ = height;
 
316
        cmpt->prec_ = depth;
 
317
        cmpt->sgnd_ = sgnd;
 
318
        cmpt->stream_ = 0;
 
319
        cmpt->cps_ = (depth + 7) / 8;
 
320
 
 
321
        size = cmpt->width_ * cmpt->height_ * cmpt->cps_;
 
322
        cmpt->stream_ = (inmem) ? jas_stream_memopen(0, size) : jas_stream_tmpfile();
 
323
        if (!cmpt->stream_) {
 
324
                jas_image_cmpt_destroy(cmpt);
 
325
                return 0;
 
326
        }
 
327
 
 
328
        /* Zero the component data.  This isn't necessary, but it is
 
329
        convenient for debugging purposes. */
 
330
        if (jas_stream_seek(cmpt->stream_, size - 1, SEEK_SET) < 0 ||
 
331
          jas_stream_putc(cmpt->stream_, 0) == EOF ||
 
332
          jas_stream_seek(cmpt->stream_, 0, SEEK_SET) < 0) {
 
333
                jas_image_cmpt_destroy(cmpt);
 
334
                return 0;
 
335
        }
 
336
 
 
337
        return cmpt;
 
338
}
 
339
 
 
340
static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt)
 
341
{
 
342
        if (cmpt->stream_) {
 
343
                jas_stream_close(cmpt->stream_);
 
344
        }
 
345
        jas_free(cmpt);
 
346
}
 
347
 
 
348
/******************************************************************************\
 
349
* Load and save operations.
 
350
\******************************************************************************/
 
351
 
 
352
jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, char *optstr)
 
353
{
 
354
        jas_image_fmtinfo_t *fmtinfo;
 
355
        jas_image_t *image;
 
356
 
 
357
        image = 0;
 
358
 
 
359
        /* If possible, try to determine the format of the input data. */
 
360
        if (fmt < 0) {
 
361
                if ((fmt = jas_image_getfmt(in)) < 0)
 
362
                        goto error;
 
363
        }
 
364
 
 
365
        /* Is it possible to decode an image represented in this format? */
 
366
        if (!(fmtinfo = jas_image_lookupfmtbyid(fmt)))
 
367
                goto error;
 
368
        if (!fmtinfo->ops.decode)
 
369
                goto error;
 
370
 
 
371
        /* Decode the image. */
 
372
        if (!(image = (*fmtinfo->ops.decode)(in, optstr)))
 
373
                goto error;
 
374
 
 
375
        /* Create a color profile if needed. */
 
376
        if (!jas_clrspc_isunknown(image->clrspc_) &&
 
377
          !jas_clrspc_isgeneric(image->clrspc_) && !image->cmprof_) {
 
378
                if (!(image->cmprof_ =
 
379
                  jas_cmprof_createfromclrspc(jas_image_clrspc(image))))
 
380
                        goto error;
 
381
        }
 
382
 
 
383
        return image;
 
384
error:
 
385
        if (image)
 
386
                jas_image_destroy(image);
 
387
        return 0;
 
388
}
 
389
 
 
390
int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt, char *optstr)
 
391
{
 
392
        jas_image_fmtinfo_t *fmtinfo;
 
393
        if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) {
 
394
                return -1;
 
395
        }
 
396
        return (fmtinfo->ops.encode) ? (*fmtinfo->ops.encode)(image, out,
 
397
          optstr) : (-1);
 
398
}
 
399
 
 
400
/******************************************************************************\
 
401
* Component read and write operations.
 
402
\******************************************************************************/
 
403
 
 
404
int jas_image_readcmpt(jas_image_t *image, int cmptno, jas_image_coord_t x,
 
405
  jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,
 
406
  jas_matrix_t *data)
 
407
{
 
408
        jas_image_cmpt_t *cmpt;
 
409
        jas_image_coord_t i;
 
410
        jas_image_coord_t j;
 
411
        int k;
 
412
        jas_seqent_t v;
 
413
        int c;
 
414
        jas_seqent_t *dr;
 
415
        jas_seqent_t *d;
 
416
        int drs;
 
417
 
 
418
        if (cmptno < 0 || cmptno >= image->numcmpts_) {
 
419
                return -1;
 
420
        }
 
421
 
 
422
        cmpt = image->cmpts_[cmptno];
 
423
        if (x >= cmpt->width_ || y >= cmpt->height_ ||
 
424
          x + width > cmpt->width_ ||
 
425
          y + height > cmpt->height_) {
 
426
                return -1;
 
427
        }
 
428
 
 
429
        if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) != width) {
 
430
                if (jas_matrix_resize(data, height, width)) {
 
431
                        return -1;
 
432
                }
 
433
        }
 
434
 
 
435
        dr = jas_matrix_getref(data, 0, 0);
 
436
        drs = jas_matrix_rowstep(data);
 
437
        for (i = 0; i < height; ++i, dr += drs) {
 
438
                d = dr;
 
439
                if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x)
 
440
                  * cmpt->cps_, SEEK_SET) < 0) {
 
441
                        return -1;
 
442
                }
 
443
                for (j = width; j > 0; --j, ++d) {
 
444
                        v = 0;
 
445
                        for (k = cmpt->cps_; k > 0; --k) {
 
446
                                if ((c = jas_stream_getc(cmpt->stream_)) == EOF) {
 
447
                                        return -1;
 
448
                                }
 
449
                                v = (v << 8) | (c & 0xff);
 
450
                        }
 
451
                        *d = bitstoint(v, cmpt->prec_, cmpt->sgnd_);
 
452
                }
 
453
        }
 
454
 
 
455
        return 0;
 
456
}
 
457
 
 
458
int jas_image_writecmpt(jas_image_t *image, int cmptno, jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,
 
459
  jas_image_coord_t height, jas_matrix_t *data)
 
460
{
 
461
        jas_image_cmpt_t *cmpt;
 
462
        jas_image_coord_t i;
 
463
        jas_image_coord_t j;
 
464
        jas_seqent_t *d;
 
465
        jas_seqent_t *dr;
 
466
        int drs;
 
467
        jas_seqent_t v;
 
468
        int k;
 
469
        int c;
 
470
 
 
471
        if (cmptno < 0 || cmptno >= image->numcmpts_) {
 
472
                return -1;
 
473
        }
 
474
 
 
475
        cmpt = image->cmpts_[cmptno];
 
476
        if (x >= cmpt->width_ || y >= cmpt->height_ ||
 
477
          x + width > cmpt->width_ ||
 
478
          y + height > cmpt->height_) {
 
479
                return -1;
 
480
        }
 
481
 
 
482
        if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) != width) {
 
483
                return -1;
 
484
        }
 
485
 
 
486
        dr = jas_matrix_getref(data, 0, 0);
 
487
        drs = jas_matrix_rowstep(data);
 
488
        for (i = 0; i < height; ++i, dr += drs) {
 
489
                d = dr;
 
490
                if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x)
 
491
                  * cmpt->cps_, SEEK_SET) < 0) {
 
492
                        return -1;
 
493
                }
 
494
                for (j = width; j > 0; --j, ++d) {
 
495
                        v = inttobits(*d, cmpt->prec_, cmpt->sgnd_);
 
496
                        for (k = cmpt->cps_; k > 0; --k) {
 
497
                                c = (v >> (8 * (cmpt->cps_ - 1))) & 0xff;
 
498
                                if (jas_stream_putc(cmpt->stream_,
 
499
                                  (unsigned char) c) == EOF) {
 
500
                                        return -1;
 
501
                                }
 
502
                                v <<= 8;
 
503
                        }
 
504
                }
 
505
        }
 
506
 
 
507
        return 0;
 
508
}
 
509
 
 
510
/******************************************************************************\
 
511
* File format operations.
 
512
\******************************************************************************/
 
513
 
 
514
void jas_image_clearfmts()
 
515
{
 
516
        int i;
 
517
        jas_image_fmtinfo_t *fmtinfo;
 
518
        for (i = 0; i < jas_image_numfmts; ++i) {
 
519
                fmtinfo = &jas_image_fmtinfos[i];
 
520
                if (fmtinfo->name) {
 
521
                        jas_free(fmtinfo->name);
 
522
                        fmtinfo->name = 0;
 
523
                }
 
524
                if (fmtinfo->ext) {
 
525
                        jas_free(fmtinfo->ext);
 
526
                        fmtinfo->ext = 0;
 
527
                }
 
528
                if (fmtinfo->desc) {
 
529
                        jas_free(fmtinfo->desc);
 
530
                        fmtinfo->desc = 0;
 
531
                }
 
532
        }
 
533
        jas_image_numfmts = 0;
 
534
}
 
535
 
 
536
int jas_image_addfmt(int id, char *name, char *ext, char *desc,
 
537
  jas_image_fmtops_t *ops)
 
538
{
 
539
        jas_image_fmtinfo_t *fmtinfo;
 
540
        assert(id >= 0 && name && ext && ops);
 
541
        if (jas_image_numfmts >= JAS_IMAGE_MAXFMTS) {
 
542
                return -1;
 
543
        }
 
544
        fmtinfo = &jas_image_fmtinfos[jas_image_numfmts];
 
545
        fmtinfo->id = id;
 
546
        if (!(fmtinfo->name = jas_strdup(name))) {
 
547
                return -1;
 
548
        }
 
549
        if (!(fmtinfo->ext = jas_strdup(ext))) {
 
550
                jas_free(fmtinfo->name);
 
551
                return -1;
 
552
        }
 
553
        if (!(fmtinfo->desc = jas_strdup(desc))) {
 
554
                jas_free(fmtinfo->name);
 
555
                jas_free(fmtinfo->ext);
 
556
                return -1;
 
557
        }
 
558
        fmtinfo->ops = *ops;
 
559
        ++jas_image_numfmts;
 
560
        return 0;
 
561
}
 
562
 
 
563
int jas_image_strtofmt(char *name)
 
564
{
 
565
        jas_image_fmtinfo_t *fmtinfo;
 
566
        if (!(fmtinfo = jas_image_lookupfmtbyname(name))) {
 
567
                return -1;
 
568
        }
 
569
        return fmtinfo->id;
 
570
}
 
571
 
 
572
char *jas_image_fmttostr(int fmt)
 
573
{
 
574
        jas_image_fmtinfo_t *fmtinfo;
 
575
        if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) {
 
576
                return 0;
 
577
        }
 
578
        return fmtinfo->name;
 
579
}
 
580
 
 
581
int jas_image_getfmt(jas_stream_t *in)
 
582
{
 
583
        jas_image_fmtinfo_t *fmtinfo;
 
584
        int found;
 
585
        int i;
 
586
 
 
587
        /* Check for data in each of the supported formats. */
 
588
        found = 0;
 
589
        for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i,
 
590
          ++fmtinfo) {
 
591
                if (fmtinfo->ops.validate) {
 
592
                        /* Is the input data valid for this format? */
 
593
                        if (!(*fmtinfo->ops.validate)(in)) {
 
594
                                found = 1;
 
595
                                break;
 
596
                        }
 
597
                }
 
598
        }
 
599
        return found ? fmtinfo->id : (-1);
 
600
}
 
601
 
 
602
int jas_image_fmtfromname(char *name)
 
603
{
 
604
        int i;
 
605
        char *ext;
 
606
        jas_image_fmtinfo_t *fmtinfo;
 
607
        /* Get the file name extension. */
 
608
        if (!(ext = strrchr(name, '.'))) {
 
609
                return -1;
 
610
        }
 
611
        ++ext;
 
612
        /* Try to find a format that uses this extension. */    
 
613
        for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i,
 
614
          ++fmtinfo) {
 
615
                /* Do we have a match? */
 
616
                if (!strcmp(ext, fmtinfo->ext)) {
 
617
                        return fmtinfo->id;
 
618
                }
 
619
        }
 
620
        return -1;
 
621
}
 
622
 
 
623
/******************************************************************************\
 
624
* Miscellaneous operations.
 
625
\******************************************************************************/
 
626
 
 
627
uint_fast32_t jas_image_rawsize(jas_image_t *image)
 
628
{
 
629
        uint_fast32_t rawsize;
 
630
        int cmptno;
 
631
        jas_image_cmpt_t *cmpt;
 
632
 
 
633
        rawsize = 0;
 
634
        for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
 
635
                cmpt = image->cmpts_[cmptno];
 
636
                rawsize += (cmpt->width_ * cmpt->height_ * cmpt->prec_ +
 
637
                  7) / 8;
 
638
        }
 
639
        return rawsize;
 
640
}
 
641
 
 
642
void jas_image_delcmpt(jas_image_t *image, int cmptno)
 
643
{
 
644
        if (cmptno >= image->numcmpts_) {
 
645
                return;
 
646
        }
 
647
        jas_image_cmpt_destroy(image->cmpts_[cmptno]);
 
648
        if (cmptno < image->numcmpts_) {
 
649
                memmove(&image->cmpts_[cmptno], &image->cmpts_[cmptno + 1],
 
650
                  (image->numcmpts_ - 1 - cmptno) * sizeof(jas_image_cmpt_t *));
 
651
        }
 
652
        --image->numcmpts_;
 
653
 
 
654
        jas_image_setbbox(image);
 
655
}
 
656
 
 
657
int jas_image_addcmpt(jas_image_t *image, int cmptno,
 
658
  jas_image_cmptparm_t *cmptparm)
 
659
{
 
660
        jas_image_cmpt_t *newcmpt;
 
661
        if (cmptno < 0)
 
662
                cmptno = image->numcmpts_;
 
663
        assert(cmptno >= 0 && cmptno <= image->numcmpts_);
 
664
        if (image->numcmpts_ >= image->maxcmpts_) {
 
665
                if (jas_image_growcmpts(image, image->maxcmpts_ + 128)) {
 
666
                        return -1;
 
667
                }
 
668
        }
 
669
        if (!(newcmpt = jas_image_cmpt_create(cmptparm->tlx,
 
670
          cmptparm->tly, cmptparm->hstep, cmptparm->vstep,
 
671
          cmptparm->width, cmptparm->height, cmptparm->prec,
 
672
          cmptparm->sgnd, 1))) {
 
673
                return -1;
 
674
        }
 
675
        if (cmptno < image->numcmpts_) {
 
676
                memmove(&image->cmpts_[cmptno + 1], &image->cmpts_[cmptno],
 
677
                  (image->numcmpts_ - cmptno) * sizeof(jas_image_cmpt_t *));
 
678
        }
 
679
        image->cmpts_[cmptno] = newcmpt;
 
680
        ++image->numcmpts_;
 
681
 
 
682
        jas_image_setbbox(image);
 
683
 
 
684
        return 0;
 
685
}
 
686
 
 
687
jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id)
 
688
{
 
689
        int i;
 
690
        jas_image_fmtinfo_t *fmtinfo;
 
691
 
 
692
        for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, ++fmtinfo) {
 
693
                if (fmtinfo->id == id) {
 
694
                        return fmtinfo;
 
695
                }
 
696
        }
 
697
        return 0;
 
698
}
 
699
 
 
700
jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name)
 
701
{
 
702
        int i;
 
703
        jas_image_fmtinfo_t *fmtinfo;
 
704
 
 
705
        for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, ++fmtinfo) {
 
706
                if (!strcmp(fmtinfo->name, name)) {
 
707
                        return fmtinfo;
 
708
                }
 
709
        }
 
710
        return 0;
 
711
}
 
712
 
 
713
 
 
714
 
 
715
 
 
716
 
 
717
static uint_fast32_t inttobits(jas_seqent_t v, int prec, bool sgnd)
 
718
{
 
719
        uint_fast32_t ret;
 
720
        ret = ((sgnd && v < 0) ? ((1 << prec) + v) : v) & JAS_ONES(prec);
 
721
        return ret;
 
722
}
 
723
 
 
724
static jas_seqent_t bitstoint(uint_fast32_t v, int prec, bool sgnd)
 
725
{
 
726
        jas_seqent_t ret;
 
727
        v &= JAS_ONES(prec);
 
728
        ret = (sgnd && (v & (1 << (prec - 1)))) ? (v - (1 << prec)) : v;
 
729
        return ret;
 
730
}
 
731
 
 
732
static void jas_image_setbbox(jas_image_t *image)
 
733
{
 
734
        jas_image_cmpt_t *cmpt;
 
735
        int cmptno;
 
736
        int_fast32_t x;
 
737
        int_fast32_t y;
 
738
 
 
739
        if (image->numcmpts_ > 0) {
 
740
                /* Determine the bounding box for all of the components on the
 
741
                  reference grid (i.e., the image area) */
 
742
                cmpt = image->cmpts_[0];
 
743
                image->tlx_ = cmpt->tlx_;
 
744
                image->tly_ = cmpt->tly_;
 
745
                image->brx_ = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1) + 1;
 
746
                image->bry_ = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1) + 1;
 
747
                for (cmptno = 1; cmptno < image->numcmpts_; ++cmptno) {
 
748
                        cmpt = image->cmpts_[cmptno];
 
749
                        if (image->tlx_ > cmpt->tlx_) {
 
750
                                image->tlx_ = cmpt->tlx_;
 
751
                        }
 
752
                        if (image->tly_ > cmpt->tly_) {
 
753
                                image->tly_ = cmpt->tly_;
 
754
                        }
 
755
                        x = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1) + 1;
 
756
                        if (image->brx_ < x) {
 
757
                                image->brx_ = x;
 
758
                        }
 
759
                        y = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1) + 1;
 
760
                        if (image->bry_ < y) {
 
761
                                image->bry_ = y;
 
762
                        }
 
763
                }
 
764
        } else {
 
765
                image->tlx_ = 0;
 
766
                image->tly_ = 0;
 
767
                image->brx_ = 0;
 
768
                image->bry_ = 0;
 
769
        }
 
770
}
 
771
 
 
772
static int jas_image_growcmpts(jas_image_t *image, int maxcmpts)
 
773
{
 
774
        jas_image_cmpt_t **newcmpts;
 
775
        int cmptno;
 
776
 
 
777
        newcmpts = (!image->cmpts_) ? jas_malloc(maxcmpts * sizeof(jas_image_cmpt_t *)) :
 
778
          jas_realloc(image->cmpts_, maxcmpts * sizeof(jas_image_cmpt_t *));
 
779
        if (!newcmpts) {
 
780
                return -1;
 
781
        }
 
782
        image->cmpts_ = newcmpts;
 
783
        image->maxcmpts_ = maxcmpts;
 
784
        for (cmptno = image->numcmpts_; cmptno < image->maxcmpts_; ++cmptno) {
 
785
                image->cmpts_[cmptno] = 0;
 
786
        }
 
787
        return 0;
 
788
}
 
789
 
 
790
int jas_image_copycmpt(jas_image_t *dstimage, int dstcmptno, jas_image_t *srcimage,
 
791
  int srccmptno)
 
792
{
 
793
        jas_image_cmpt_t *newcmpt;
 
794
        if (dstimage->numcmpts_ >= dstimage->maxcmpts_) {
 
795
                if (jas_image_growcmpts(dstimage, dstimage->maxcmpts_ + 128)) {
 
796
                        return -1;
 
797
                }
 
798
        }
 
799
        if (!(newcmpt = jas_image_cmpt_copy(srcimage->cmpts_[srccmptno]))) {
 
800
                return -1;
 
801
        }
 
802
        if (dstcmptno < dstimage->numcmpts_) {
 
803
                memmove(&dstimage->cmpts_[dstcmptno + 1], &dstimage->cmpts_[dstcmptno],
 
804
                  (dstimage->numcmpts_ - dstcmptno) * sizeof(jas_image_cmpt_t *));
 
805
        }
 
806
        dstimage->cmpts_[dstcmptno] = newcmpt;
 
807
        ++dstimage->numcmpts_;
 
808
 
 
809
        jas_image_setbbox(dstimage);
 
810
        return 0;
 
811
}
 
812
 
 
813
void jas_image_dump(jas_image_t *image, FILE *out)
 
814
{
 
815
        long buf[1024];
 
816
        int cmptno;
 
817
        int n;
 
818
        int i;
 
819
        int width;
 
820
        int height;
 
821
        jas_image_cmpt_t *cmpt;
 
822
        for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
 
823
                cmpt = image->cmpts_[cmptno];
 
824
                fprintf(out, "prec=%d, sgnd=%d, cmpttype=%d\n", cmpt->prec_,
 
825
                  cmpt->sgnd_, cmpt->type_);
 
826
                width = jas_image_cmptwidth(image, cmptno);
 
827
                height = jas_image_cmptheight(image, cmptno);
 
828
                n = JAS_MIN(16, width);
 
829
                if (jas_image_readcmpt2(image, cmptno, 0, 0, n, 1, buf)) {
 
830
                        abort();
 
831
                }
 
832
                for (i = 0; i < n; ++i) {
 
833
                        fprintf(out, " f(%d,%d)=%ld", i, 0, buf[i]);
 
834
                }
 
835
                fprintf(out, "\n");
 
836
                if (jas_image_readcmpt2(image, cmptno, width - n, height - 1, n, 1, buf)) {
 
837
                        abort();
 
838
                }
 
839
                for (i = 0; i < n; ++i) {
 
840
                        fprintf(out, " f(%d,%d)=%ld", width - n + i, height - 1, buf[i]);
 
841
                }
 
842
                fprintf(out, "\n");
 
843
        }
 
844
}
 
845
 
 
846
int jas_image_depalettize(jas_image_t *image, int cmptno, int numlutents,
 
847
  int_fast32_t *lutents, int dtype, int newcmptno)
 
848
{
 
849
        jas_image_cmptparm_t cmptparms;
 
850
        int_fast32_t v;
 
851
        int i;
 
852
        int j;
 
853
        jas_image_cmpt_t *cmpt;
 
854
 
 
855
        cmpt = image->cmpts_[cmptno];
 
856
        cmptparms.tlx = cmpt->tlx_;
 
857
        cmptparms.tly = cmpt->tly_;
 
858
        cmptparms.hstep = cmpt->hstep_;
 
859
        cmptparms.vstep = cmpt->vstep_;
 
860
        cmptparms.width = cmpt->width_;
 
861
        cmptparms.height = cmpt->height_;
 
862
        cmptparms.prec = JAS_IMAGE_CDT_GETPREC(dtype);
 
863
        cmptparms.sgnd = JAS_IMAGE_CDT_GETSGND(dtype);
 
864
 
 
865
        if (jas_image_addcmpt(image, newcmptno, &cmptparms)) {
 
866
                return -1;
 
867
        }
 
868
        if (newcmptno <= cmptno) {
 
869
                ++cmptno;
 
870
                cmpt = image->cmpts_[cmptno];
 
871
        }
 
872
 
 
873
        for (j = 0; j < cmpt->height_; ++j) {
 
874
                for (i = 0; i < cmpt->width_; ++i) {
 
875
                        v = jas_image_readcmptsample(image, cmptno, i, j);
 
876
                        if (v < 0) {
 
877
                                v = 0;
 
878
                        } else if (v >= numlutents) {
 
879
                                v = numlutents - 1;
 
880
                        }
 
881
                        jas_image_writecmptsample(image, newcmptno, i, j,
 
882
                          lutents[v]);
 
883
                }
 
884
        }
 
885
        return 0;
 
886
}
 
887
 
 
888
int jas_image_readcmptsample(jas_image_t *image, int cmptno, int x, int y)
 
889
{
 
890
        jas_image_cmpt_t *cmpt;
 
891
        uint_fast32_t v;
 
892
        int k;
 
893
        int c;
 
894
 
 
895
        cmpt = image->cmpts_[cmptno];
 
896
 
 
897
        if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_,
 
898
          SEEK_SET) < 0) {
 
899
                return -1;
 
900
        }
 
901
        v = 0;
 
902
        for (k = cmpt->cps_; k > 0; --k) {
 
903
                if ((c = jas_stream_getc(cmpt->stream_)) == EOF) {
 
904
                        return -1;
 
905
                }
 
906
                v = (v << 8) | (c & 0xff);
 
907
        }
 
908
        return bitstoint(v, cmpt->prec_, cmpt->sgnd_);
 
909
}
 
910
 
 
911
void jas_image_writecmptsample(jas_image_t *image, int cmptno, int x, int y,
 
912
  int_fast32_t v)
 
913
{
 
914
        jas_image_cmpt_t *cmpt;
 
915
        uint_fast32_t t;
 
916
        int k;
 
917
        int c;
 
918
 
 
919
        cmpt = image->cmpts_[cmptno];
 
920
 
 
921
        if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_,
 
922
          SEEK_SET) < 0) {
 
923
                return;
 
924
        }
 
925
        t = inttobits(v, cmpt->prec_, cmpt->sgnd_);
 
926
        for (k = cmpt->cps_; k > 0; --k) {
 
927
                c = (t >> (8 * (cmpt->cps_ - 1))) & 0xff;
 
928
                if (jas_stream_putc(cmpt->stream_, (unsigned char) c) == EOF) {
 
929
                        return;
 
930
                }
 
931
                t <<= 8;
 
932
        }
 
933
}
 
934
 
 
935
int jas_image_getcmptbytype(jas_image_t *image, int ctype)
 
936
{
 
937
        int cmptno;
 
938
 
 
939
        for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
 
940
                if (image->cmpts_[cmptno]->type_ == ctype) {
 
941
                        return cmptno;
 
942
                }
 
943
        }
 
944
        return -1;
 
945
}
 
946
 
 
947
 
 
948
 
 
949
 
 
950
 
 
951
 
 
952
 
 
953
 
 
954
 
 
955
 
 
956
 
 
957
 
 
958
 
 
959
 
 
960
 
 
961
 
 
962
/***********************************************/
 
963
/***********************************************/
 
964
/***********************************************/
 
965
/***********************************************/
 
966
 
 
967
int jas_image_readcmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x,
 
968
  jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,
 
969
  long *buf)
 
970
{
 
971
        jas_image_cmpt_t *cmpt;
 
972
        jas_image_coord_t i;
 
973
        jas_image_coord_t j;
 
974
        long v;
 
975
        long *bufptr;
 
976
 
 
977
        if (cmptno < 0 || cmptno >= image->numcmpts_)
 
978
                goto error;
 
979
        cmpt = image->cmpts_[cmptno];
 
980
        if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ ||
 
981
          width < 0 || height < 0 || x + width > cmpt->width_ ||
 
982
          y + height > cmpt->height_)
 
983
                goto error;
 
984
 
 
985
        bufptr = buf;
 
986
        for (i = 0; i < height; ++i) {
 
987
                if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x)
 
988
                  * cmpt->cps_, SEEK_SET) < 0)
 
989
                        goto error;
 
990
                for (j = 0; j < width; ++j) {
 
991
                        if (getint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, &v))
 
992
                                goto error;
 
993
                        *bufptr++ = v;
 
994
                }
 
995
        }
 
996
 
 
997
        return 0;
 
998
error:
 
999
        return -1;
 
1000
}
 
1001
 
 
1002
int jas_image_writecmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x,
 
1003
  jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,
 
1004
  long *buf)
 
1005
{
 
1006
        jas_image_cmpt_t *cmpt;
 
1007
        jas_image_coord_t i;
 
1008
        jas_image_coord_t j;
 
1009
        long v;
 
1010
        long *bufptr;
 
1011
 
 
1012
        if (cmptno < 0 || cmptno >= image->numcmpts_)
 
1013
                goto error;
 
1014
        cmpt = image->cmpts_[cmptno];
 
1015
        if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ ||
 
1016
          width < 0 || height < 0 || x + width > cmpt->width_ ||
 
1017
          y + height > cmpt->height_)
 
1018
                goto error;
 
1019
 
 
1020
        bufptr = buf;
 
1021
        for (i = 0; i < height; ++i) {
 
1022
                if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x)
 
1023
                  * cmpt->cps_, SEEK_SET) < 0)
 
1024
                        goto error;
 
1025
                for (j = 0; j < width; ++j) {
 
1026
                        v = *bufptr++;
 
1027
                        if (putint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, v))
 
1028
                                goto error;
 
1029
                }
 
1030
        }
 
1031
 
 
1032
        return 0;
 
1033
error:
 
1034
        return -1;
 
1035
}
 
1036
 
 
1037
int jas_image_sampcmpt(jas_image_t *image, int cmptno, int newcmptno,
 
1038
  jas_image_coord_t ho, jas_image_coord_t vo, jas_image_coord_t hs,
 
1039
  jas_image_coord_t vs, int sgnd, int prec)
 
1040
{
 
1041
        jas_image_cmpt_t *oldcmpt;
 
1042
        jas_image_cmpt_t *newcmpt;
 
1043
        int width;
 
1044
        int height;
 
1045
        jas_image_coord_t tlx;
 
1046
        jas_image_coord_t tly;
 
1047
        jas_image_coord_t brx;
 
1048
        jas_image_coord_t bry;
 
1049
        int i;
 
1050
        int j;
 
1051
        jas_image_cmptparm_t cmptparm;
 
1052
        jas_image_coord_t ax;
 
1053
        jas_image_coord_t ay;
 
1054
        jas_image_coord_t bx;
 
1055
        jas_image_coord_t by;
 
1056
        jas_image_coord_t d0;
 
1057
        jas_image_coord_t d1;
 
1058
        jas_image_coord_t d2;
 
1059
        jas_image_coord_t d3;
 
1060
        jas_image_coord_t oldx;
 
1061
        jas_image_coord_t oldy;
 
1062
        jas_image_coord_t x;
 
1063
        jas_image_coord_t y;
 
1064
        long v;
 
1065
        jas_image_coord_t cmptbrx;
 
1066
        jas_image_coord_t cmptbry;
 
1067
 
 
1068
        assert(cmptno >= 0 && cmptno < image->numcmpts_);
 
1069
        oldcmpt = image->cmpts_[cmptno];
 
1070
        assert(oldcmpt->tlx_ == 0 && oldcmpt->tly_ == 0);
 
1071
        jas_image_calcbbox2(image, &tlx, &tly, &brx, &bry);
 
1072
        width = FLOORDIV(brx - ho + hs, hs);
 
1073
        height = FLOORDIV(bry - vo + vs, vs);
 
1074
        cmptparm.tlx = ho;
 
1075
        cmptparm.tly = vo;
 
1076
        cmptparm.hstep = hs;
 
1077
        cmptparm.vstep = vs;
 
1078
        cmptparm.width = width;
 
1079
        cmptparm.height = height;
 
1080
        cmptparm.prec = prec;
 
1081
        cmptparm.sgnd = sgnd;
 
1082
        if (jas_image_addcmpt(image, newcmptno, &cmptparm))
 
1083
                goto error;
 
1084
cmptbrx = oldcmpt->tlx_ + (oldcmpt->width_ - 1) * oldcmpt->hstep_;
 
1085
cmptbry = oldcmpt->tly_ + (oldcmpt->height_ - 1) * oldcmpt->vstep_;
 
1086
        newcmpt = image->cmpts_[newcmptno];
 
1087
        jas_stream_rewind(newcmpt->stream_);
 
1088
        for (i = 0; i < height; ++i) {
 
1089
                y = newcmpt->tly_ + newcmpt->vstep_ * i;
 
1090
                for (j = 0; j < width; ++j) {
 
1091
                        x = newcmpt->tlx_ + newcmpt->hstep_ * j;
 
1092
                        ax = downtomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_;
 
1093
                        ay = downtomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_;
 
1094
                        bx = uptomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_;
 
1095
                        if (bx > cmptbrx)
 
1096
                                bx = cmptbrx;
 
1097
                        by = uptomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_;
 
1098
                        if (by > cmptbry)
 
1099
                                by = cmptbry;
 
1100
                        d0 = (ax - x) * (ax - x) + (ay - y) * (ay - y);
 
1101
                        d1 = (bx - x) * (bx - x) + (ay - y) * (ay - y);
 
1102
                        d2 = (bx - x) * (bx - x) + (by - y) * (by - y);
 
1103
                        d3 = (ax - x) * (ax - x) + (by - y) * (by - y);
 
1104
                        if (d0 <= d1 && d0 <= d2 && d0 <= d3) {
 
1105
                                oldx = (ax - oldcmpt->tlx_) / oldcmpt->hstep_;
 
1106
                                oldy = (ay - oldcmpt->tly_) / oldcmpt->vstep_;
 
1107
                        } else if (d1 <= d0 && d1 <= d2 && d1 <= d3) {
 
1108
                                oldx = (bx - oldcmpt->tlx_) / oldcmpt->hstep_;
 
1109
                                oldy = (ay - oldcmpt->tly_) / oldcmpt->vstep_;
 
1110
                        } else if (d2 <= d0 && d2 <= d1 && d1 <= d3) {
 
1111
                                oldx = (bx - oldcmpt->tlx_) / oldcmpt->hstep_;
 
1112
                                oldy = (by - oldcmpt->tly_) / oldcmpt->vstep_;
 
1113
                        } else {
 
1114
                                oldx = (ax - oldcmpt->tlx_) / oldcmpt->hstep_;
 
1115
                                oldy = (by - oldcmpt->tly_) / oldcmpt->vstep_;
 
1116
                        }
 
1117
                        assert(oldx >= 0 && oldx < oldcmpt->width_ &&
 
1118
                          oldy >= 0 && oldy < oldcmpt->height_);
 
1119
                        if (jas_stream_seek(oldcmpt->stream_, oldcmpt->cps_ *
 
1120
                          (oldy * oldcmpt->width_ + oldx), SEEK_SET) < 0)
 
1121
                                goto error;
 
1122
                        if (getint(oldcmpt->stream_, oldcmpt->sgnd_,
 
1123
                          oldcmpt->prec_, &v))
 
1124
                                goto error;
 
1125
                        if (newcmpt->prec_ != oldcmpt->prec_ ||
 
1126
                          newcmpt->sgnd_ != oldcmpt->sgnd_) {
 
1127
                                v = convert(v, oldcmpt->sgnd_, oldcmpt->prec_,
 
1128
                                  newcmpt->sgnd_, newcmpt->prec_);
 
1129
                        }
 
1130
                        if (putint(newcmpt->stream_, newcmpt->sgnd_,
 
1131
                          newcmpt->prec_, v))
 
1132
                                goto error;
 
1133
                }
 
1134
        }
 
1135
        return 0;
 
1136
error:
 
1137
        return -1;
 
1138
}
 
1139
 
 
1140
int jas_image_ishomosamp(jas_image_t *image)
 
1141
{
 
1142
        jas_image_coord_t hstep;
 
1143
        jas_image_coord_t vstep;
 
1144
        int result;
 
1145
        int i;
 
1146
        hstep = jas_image_cmpthstep(image, 0);
 
1147
        vstep = jas_image_cmptvstep(image, 0);
 
1148
        result = 1;
 
1149
        for (i = 0; i < image->numcmpts_; ++i) {
 
1150
                if (jas_image_cmpthstep(image, i) != hstep ||
 
1151
                  jas_image_cmptvstep(image, i) != vstep) {
 
1152
                        result = 0;
 
1153
                        break;
 
1154
                }
 
1155
        }
 
1156
        return result;
 
1157
}
 
1158
 
 
1159
/* Note: This function defines a bounding box differently. */
 
1160
static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx,
 
1161
  jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry)
 
1162
{
 
1163
        jas_image_cmpt_t *cmpt;
 
1164
        jas_image_coord_t tmptlx;
 
1165
        jas_image_coord_t tmptly;
 
1166
        jas_image_coord_t tmpbrx;
 
1167
        jas_image_coord_t tmpbry;
 
1168
        jas_image_coord_t t;
 
1169
        int i;
 
1170
        if (image->numcmpts_ > 0) {
 
1171
                cmpt = image->cmpts_[0];
 
1172
                tmptlx = cmpt->tlx_;
 
1173
                tmptly = cmpt->tly_;
 
1174
                tmpbrx = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1);
 
1175
                tmpbry = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1);
 
1176
                for (i = 0; i < image->numcmpts_; ++i) {
 
1177
                        cmpt = image->cmpts_[i];
 
1178
                        if (cmpt->tlx_ < tmptlx)
 
1179
                                tmptlx = cmpt->tlx_;
 
1180
                        if (cmpt->tly_ < tmptly)
 
1181
                                tmptly = cmpt->tly_;
 
1182
                        t = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1);
 
1183
                        if (t > tmpbrx)
 
1184
                                tmpbrx = t;
 
1185
                        t = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1);
 
1186
                        if (t > tmpbry)
 
1187
                                tmpbry = t;
 
1188
                }
 
1189
        } else {
 
1190
                tmptlx = 0;
 
1191
                tmptly = 0;
 
1192
                tmpbrx = -1;
 
1193
                tmpbry = -1;
 
1194
        }
 
1195
        *tlx = tmptlx;
 
1196
        *tly = tmptly;
 
1197
        *brx = tmpbrx;
 
1198
        *bry = tmpbry;
 
1199
}
 
1200
 
 
1201
 
 
1202
 
 
1203
static int getint(jas_stream_t *in, int sgnd, int prec, long *val)
 
1204
{
 
1205
        long v;
 
1206
        int n;
 
1207
        int c;
 
1208
        n = (prec + 7) / 8;
 
1209
        v = 0;
 
1210
        while (--n >= 0) {
 
1211
                if ((c = jas_stream_getc(in)) == EOF)
 
1212
                        return -1;
 
1213
                v = (v << 8) | c;
 
1214
        }
 
1215
        v &= ((1 << prec) - 1);
 
1216
        if (sgnd) {
 
1217
                /* XXX - Do something here. */
 
1218
                abort();
 
1219
        } else {
 
1220
                *val = v;
 
1221
        }
 
1222
        return 0;
 
1223
}
 
1224
 
 
1225
static int putint(jas_stream_t *out, int sgnd, int prec, long val)
 
1226
{
 
1227
        int n;
 
1228
        int c;
 
1229
        if (sgnd) {
 
1230
                /* XXX - Do something here. */
 
1231
                abort();
 
1232
        }
 
1233
        val &= (1 << prec) - 1;
 
1234
        n = (prec + 7) / 8;
 
1235
        while (--n >= 0) {
 
1236
                c = (val >> (n * 8)) & 0xff;
 
1237
                if (jas_stream_putc(out, c) != c)
 
1238
                        return -1;
 
1239
        }
 
1240
        return 0;
 
1241
}
 
1242
 
 
1243
static long convert(long val, int oldsgnd, int oldprec, int newsgnd,
 
1244
  int newprec)
 
1245
{
 
1246
        if (newsgnd != oldsgnd) {
 
1247
        }
 
1248
        if (newprec != oldprec) {
 
1249
                if (newprec > oldprec) {
 
1250
                        val <<= newprec - oldprec;
 
1251
                } else if (oldprec > newprec) {
 
1252
                        val >>= oldprec - newprec;
 
1253
                }
 
1254
        }
 
1255
        return val;
 
1256
}
 
1257
 
 
1258
static long downtomult(long x, long y)
 
1259
{
 
1260
        assert(x >= 0);
 
1261
        return (x / y) * y;
 
1262
}
 
1263
 
 
1264
static long uptomult(long x, long y)
 
1265
{
 
1266
        assert(x >= 0);
 
1267
        return ((x + y - 1) / y) * y;
 
1268
}
 
1269
 
 
1270
jas_image_t *jas_image_chclrspc(jas_image_t *image, jas_cmprof_t *outprof,
 
1271
  int intent)
 
1272
{
 
1273
        jas_image_t *inimage;
 
1274
        int minhstep;
 
1275
        int minvstep;
 
1276
        int i;
 
1277
        int j;
 
1278
        int k;
 
1279
        int n;
 
1280
        int hstep;
 
1281
        int vstep;
 
1282
        int numinauxchans;
 
1283
        int numoutauxchans;
 
1284
        int numinclrchans;
 
1285
        int numoutclrchans;
 
1286
        int prec;
 
1287
        jas_image_t *outimage;
 
1288
        int cmpttype;
 
1289
        int numoutchans;
 
1290
        jas_cmprof_t *inprof;
 
1291
        jas_cmprof_t *tmpprof;
 
1292
        jas_image_cmptparm_t cmptparm;
 
1293
        int width;
 
1294
        int height;
 
1295
        jas_cmxform_t *xform;
 
1296
        jas_cmpixmap_t inpixmap;
 
1297
        jas_cmpixmap_t outpixmap;
 
1298
        jas_cmcmptfmt_t *incmptfmts;
 
1299
        jas_cmcmptfmt_t *outcmptfmts;
 
1300
 
 
1301
#if 0
 
1302
jas_eprintf("IMAGE\n");
 
1303
jas_image_dump(image, stderr);
 
1304
#endif
 
1305
 
 
1306
        if (!(inimage = jas_image_copy(image)))
 
1307
                goto error;
 
1308
        image = 0;
 
1309
 
 
1310
        if (!jas_image_ishomosamp(inimage)) {
 
1311
                minhstep = jas_image_cmpthstep(inimage, 0);
 
1312
                minvstep = jas_image_cmptvstep(inimage, 0);
 
1313
                for (i = 1; i < jas_image_numcmpts(inimage); ++i) {
 
1314
                        hstep = jas_image_cmpthstep(inimage, i);
 
1315
                        vstep = jas_image_cmptvstep(inimage, i);
 
1316
                        if (hstep < minhstep)
 
1317
                                minhstep = hstep;
 
1318
                        if (vstep < minvstep)
 
1319
                                minvstep = vstep;
 
1320
                }
 
1321
                n = jas_image_numcmpts(inimage);
 
1322
                for (i = 0; i < n; ++i) {
 
1323
                        cmpttype = jas_image_cmpttype(inimage, i);
 
1324
                        if (jas_image_sampcmpt(inimage, i, i + 1, 0, 0, minhstep, minvstep, jas_image_cmptsgnd(inimage, i), jas_image_cmptprec(inimage, i)))
 
1325
                                goto error;
 
1326
                        jas_image_setcmpttype(inimage, i + 1, cmpttype);
 
1327
                        jas_image_delcmpt(inimage, i);
 
1328
                }
 
1329
        }
 
1330
 
 
1331
        width = jas_image_cmptwidth(inimage, 0);
 
1332
        height = jas_image_cmptheight(inimage, 0);
 
1333
        hstep = jas_image_cmpthstep(inimage, 0);
 
1334
        vstep = jas_image_cmptvstep(inimage, 0);
 
1335
 
 
1336
        inprof = jas_image_cmprof(inimage);
 
1337
        assert(inprof);
 
1338
        numinclrchans = jas_clrspc_numchans(jas_cmprof_clrspc(inprof));
 
1339
        numinauxchans = jas_image_numcmpts(inimage) - numinclrchans;
 
1340
        numoutclrchans = jas_clrspc_numchans(jas_cmprof_clrspc(outprof));
 
1341
        numoutauxchans = 0;
 
1342
        numoutchans = numoutclrchans + numoutauxchans;
 
1343
        prec = 8;
 
1344
 
 
1345
        if (!(outimage = jas_image_create0()))
 
1346
                goto error;
 
1347
 
 
1348
        /* Create a component for each of the colorants. */
 
1349
        for (i = 0; i < numoutclrchans; ++i) {
 
1350
                cmptparm.tlx = 0;
 
1351
                cmptparm.tly = 0;
 
1352
                cmptparm.hstep = hstep;
 
1353
                cmptparm.vstep = vstep;
 
1354
                cmptparm.width = width;
 
1355
                cmptparm.height = height;
 
1356
                cmptparm.prec = prec;
 
1357
                cmptparm.sgnd = 0;
 
1358
                if (jas_image_addcmpt(outimage, -1, &cmptparm))
 
1359
                        goto error;
 
1360
                jas_image_setcmpttype(outimage, i, JAS_IMAGE_CT_COLOR(i));
 
1361
        }
 
1362
#if 0
 
1363
        /* Copy the auxiliary components without modification. */
 
1364
        for (i = 0; i < jas_image_numcmpts(inimage); ++i) {
 
1365
                if (!ISCOLOR(jas_image_cmpttype(inimage, i))) {
 
1366
                        jas_image_copycmpt(outimage, -1, inimage, i);
 
1367
/* XXX - need to specify laydown of component on ref. grid */
 
1368
                }
 
1369
        }
 
1370
#endif
 
1371
 
 
1372
        if (!(tmpprof = jas_cmprof_copy(outprof)))
 
1373
                goto error;
 
1374
        assert(!jas_image_cmprof(outimage));
 
1375
        jas_image_setcmprof(outimage, tmpprof);
 
1376
        tmpprof = 0;
 
1377
        jas_image_setclrspc(outimage, jas_cmprof_clrspc(outprof));
 
1378
 
 
1379
        if (!(xform = jas_cmxform_create(inprof, outprof, 0, JAS_CMXFORM_OP_FWD, intent, 0)))
 
1380
                goto error;
 
1381
 
 
1382
        inpixmap.numcmpts = numinclrchans;
 
1383
        incmptfmts = malloc(numinclrchans * sizeof(jas_cmcmptfmt_t));
 
1384
        assert(incmptfmts);
 
1385
        inpixmap.cmptfmts = incmptfmts;
 
1386
        for (i = 0; i < numinclrchans; ++i) {
 
1387
                j = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(i));
 
1388
                assert(j >= 0);
 
1389
                if (!(incmptfmts[i].buf = malloc(width * sizeof(long))))
 
1390
                        goto error;
 
1391
                incmptfmts[i].prec = jas_image_cmptprec(inimage, j);
 
1392
                incmptfmts[i].sgnd = jas_image_cmptsgnd(inimage, j);
 
1393
                incmptfmts[i].width = width;
 
1394
                incmptfmts[i].height = 1;
 
1395
        }
 
1396
 
 
1397
        outpixmap.numcmpts = numoutclrchans;
 
1398
        outcmptfmts = malloc(numoutclrchans * sizeof(jas_cmcmptfmt_t));
 
1399
        assert(outcmptfmts);
 
1400
        outpixmap.cmptfmts = outcmptfmts;
 
1401
 
 
1402
        for (i = 0; i < numoutclrchans; ++i) {
 
1403
                j = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(i));
 
1404
                assert(j >= 0);
 
1405
                if (!(outcmptfmts[i].buf = malloc(width * sizeof(long))))
 
1406
                        goto error;
 
1407
                outcmptfmts[i].prec = jas_image_cmptprec(outimage, j);
 
1408
                outcmptfmts[i].sgnd = jas_image_cmptsgnd(outimage, j);
 
1409
                outcmptfmts[i].width = width;
 
1410
                outcmptfmts[i].height = 1;
 
1411
        }
 
1412
 
 
1413
        for (i = 0; i < height; ++i) {
 
1414
                for (j = 0; j < numinclrchans; ++j) {
 
1415
                        k = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(j));
 
1416
                        if (jas_image_readcmpt2(inimage, k, 0, i, width, 1, incmptfmts[j].buf))
 
1417
                                goto error;
 
1418
                }
 
1419
                jas_cmxform_apply(xform, &inpixmap, &outpixmap);
 
1420
                for (j = 0; j < numoutclrchans; ++j) {
 
1421
                        k = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(j));
 
1422
                        if (jas_image_writecmpt2(outimage, k, 0, i, width, 1, outcmptfmts[j].buf))
 
1423
                                goto error;
 
1424
                }
 
1425
        }
 
1426
 
 
1427
        for (i = 0; i < numoutclrchans; ++i)
 
1428
                jas_free(outcmptfmts[i].buf);
 
1429
        jas_free(outcmptfmts);
 
1430
        for (i = 0; i < numinclrchans; ++i)
 
1431
                jas_free(incmptfmts[i].buf);
 
1432
        jas_free(incmptfmts);
 
1433
        jas_cmxform_destroy(xform);
 
1434
        jas_image_destroy(inimage);
 
1435
 
 
1436
#if 0
 
1437
jas_eprintf("INIMAGE\n");
 
1438
jas_image_dump(inimage, stderr);
 
1439
jas_eprintf("OUTIMAGE\n");
 
1440
jas_image_dump(outimage, stderr);
 
1441
#endif
 
1442
        return outimage;
 
1443
error:
 
1444
        return 0;
 
1445
}