Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/3rdparty/libjasper/jas_image.c
16337 views
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: jas_image.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 <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_alloc2(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 = jas_realloc2(image->cmpts_, maxcmpts, sizeof(jas_image_cmpt_t *));
778
if (!newcmpts) {
779
return -1;
780
}
781
image->cmpts_ = newcmpts;
782
image->maxcmpts_ = maxcmpts;
783
for (cmptno = image->numcmpts_; cmptno < image->maxcmpts_; ++cmptno) {
784
image->cmpts_[cmptno] = 0;
785
}
786
return 0;
787
}
788
789
int jas_image_copycmpt(jas_image_t *dstimage, int dstcmptno, jas_image_t *srcimage,
790
int srccmptno)
791
{
792
jas_image_cmpt_t *newcmpt;
793
if (dstimage->numcmpts_ >= dstimage->maxcmpts_) {
794
if (jas_image_growcmpts(dstimage, dstimage->maxcmpts_ + 128)) {
795
return -1;
796
}
797
}
798
if (!(newcmpt = jas_image_cmpt_copy(srcimage->cmpts_[srccmptno]))) {
799
return -1;
800
}
801
if (dstcmptno < dstimage->numcmpts_) {
802
memmove(&dstimage->cmpts_[dstcmptno + 1], &dstimage->cmpts_[dstcmptno],
803
(dstimage->numcmpts_ - dstcmptno) * sizeof(jas_image_cmpt_t *));
804
}
805
dstimage->cmpts_[dstcmptno] = newcmpt;
806
++dstimage->numcmpts_;
807
808
jas_image_setbbox(dstimage);
809
return 0;
810
}
811
812
void jas_image_dump(jas_image_t *image, FILE *out)
813
{
814
long buf[1024];
815
int cmptno;
816
int n;
817
int i;
818
int width;
819
int height;
820
jas_image_cmpt_t *cmpt;
821
for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
822
cmpt = image->cmpts_[cmptno];
823
fprintf(out, "prec=%d, sgnd=%d, cmpttype=%d\n", cmpt->prec_,
824
cmpt->sgnd_, (int)cmpt->type_);
825
width = jas_image_cmptwidth(image, cmptno);
826
height = jas_image_cmptheight(image, cmptno);
827
n = JAS_MIN(16, width);
828
if (jas_image_readcmpt2(image, cmptno, 0, 0, n, 1, buf)) {
829
abort();
830
}
831
for (i = 0; i < n; ++i) {
832
fprintf(out, " f(%d,%d)=%ld", i, 0, buf[i]);
833
}
834
fprintf(out, "\n");
835
if (jas_image_readcmpt2(image, cmptno, width - n, height - 1, n, 1, buf)) {
836
abort();
837
}
838
for (i = 0; i < n; ++i) {
839
fprintf(out, " f(%d,%d)=%ld", width - n + i, height - 1, buf[i]);
840
}
841
fprintf(out, "\n");
842
}
843
}
844
845
int jas_image_depalettize(jas_image_t *image, int cmptno, int numlutents,
846
int_fast32_t *lutents, int dtype, int newcmptno)
847
{
848
jas_image_cmptparm_t cmptparms;
849
int_fast32_t v;
850
int i;
851
int j;
852
jas_image_cmpt_t *cmpt;
853
854
cmpt = image->cmpts_[cmptno];
855
cmptparms.tlx = cmpt->tlx_;
856
cmptparms.tly = cmpt->tly_;
857
cmptparms.hstep = cmpt->hstep_;
858
cmptparms.vstep = cmpt->vstep_;
859
cmptparms.width = cmpt->width_;
860
cmptparms.height = cmpt->height_;
861
cmptparms.prec = JAS_IMAGE_CDT_GETPREC(dtype);
862
cmptparms.sgnd = JAS_IMAGE_CDT_GETSGND(dtype);
863
864
if (jas_image_addcmpt(image, newcmptno, &cmptparms)) {
865
return -1;
866
}
867
if (newcmptno <= cmptno) {
868
++cmptno;
869
cmpt = image->cmpts_[cmptno];
870
}
871
872
for (j = 0; j < cmpt->height_; ++j) {
873
for (i = 0; i < cmpt->width_; ++i) {
874
v = jas_image_readcmptsample(image, cmptno, i, j);
875
if (v < 0) {
876
v = 0;
877
} else if (v >= numlutents) {
878
v = numlutents - 1;
879
}
880
jas_image_writecmptsample(image, newcmptno, i, j,
881
lutents[v]);
882
}
883
}
884
return 0;
885
}
886
887
int jas_image_readcmptsample(jas_image_t *image, int cmptno, int x, int y)
888
{
889
jas_image_cmpt_t *cmpt;
890
uint_fast32_t v;
891
int k;
892
int c;
893
894
cmpt = image->cmpts_[cmptno];
895
896
if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_,
897
SEEK_SET) < 0) {
898
return -1;
899
}
900
v = 0;
901
for (k = cmpt->cps_; k > 0; --k) {
902
if ((c = jas_stream_getc(cmpt->stream_)) == EOF) {
903
return -1;
904
}
905
v = (v << 8) | (c & 0xff);
906
}
907
return bitstoint(v, cmpt->prec_, cmpt->sgnd_);
908
}
909
910
void jas_image_writecmptsample(jas_image_t *image, int cmptno, int x, int y,
911
int_fast32_t v)
912
{
913
jas_image_cmpt_t *cmpt;
914
uint_fast32_t t;
915
int k;
916
int c;
917
918
cmpt = image->cmpts_[cmptno];
919
920
if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_,
921
SEEK_SET) < 0) {
922
return;
923
}
924
t = inttobits(v, cmpt->prec_, cmpt->sgnd_);
925
for (k = cmpt->cps_; k > 0; --k) {
926
c = (t >> (8 * (cmpt->cps_ - 1))) & 0xff;
927
if (jas_stream_putc(cmpt->stream_, (unsigned char) c) == EOF) {
928
return;
929
}
930
t <<= 8;
931
}
932
}
933
934
int jas_image_getcmptbytype(jas_image_t *image, int ctype)
935
{
936
int cmptno;
937
938
for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
939
if (image->cmpts_[cmptno]->type_ == ctype) {
940
return cmptno;
941
}
942
}
943
return -1;
944
}
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
/***********************************************/
962
/***********************************************/
963
/***********************************************/
964
/***********************************************/
965
966
int jas_image_readcmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x,
967
jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,
968
long *buf)
969
{
970
jas_image_cmpt_t *cmpt;
971
jas_image_coord_t i;
972
jas_image_coord_t j;
973
long v;
974
long *bufptr;
975
976
if (cmptno < 0 || cmptno >= image->numcmpts_)
977
goto error;
978
cmpt = image->cmpts_[cmptno];
979
if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ ||
980
width < 0 || height < 0 || x + width > cmpt->width_ ||
981
y + height > cmpt->height_)
982
goto error;
983
984
bufptr = buf;
985
for (i = 0; i < height; ++i) {
986
if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x)
987
* cmpt->cps_, SEEK_SET) < 0)
988
goto error;
989
for (j = 0; j < width; ++j) {
990
if (getint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, &v))
991
goto error;
992
*bufptr++ = v;
993
}
994
}
995
996
return 0;
997
error:
998
return -1;
999
}
1000
1001
int jas_image_writecmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x,
1002
jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,
1003
long *buf)
1004
{
1005
jas_image_cmpt_t *cmpt;
1006
jas_image_coord_t i;
1007
jas_image_coord_t j;
1008
long v;
1009
long *bufptr;
1010
1011
if (cmptno < 0 || cmptno >= image->numcmpts_)
1012
goto error;
1013
cmpt = image->cmpts_[cmptno];
1014
if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ ||
1015
width < 0 || height < 0 || x + width > cmpt->width_ ||
1016
y + height > cmpt->height_)
1017
goto error;
1018
1019
bufptr = buf;
1020
for (i = 0; i < height; ++i) {
1021
if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x)
1022
* cmpt->cps_, SEEK_SET) < 0)
1023
goto error;
1024
for (j = 0; j < width; ++j) {
1025
v = *bufptr++;
1026
if (putint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, v))
1027
goto error;
1028
}
1029
}
1030
1031
return 0;
1032
error:
1033
return -1;
1034
}
1035
1036
int jas_image_sampcmpt(jas_image_t *image, int cmptno, int newcmptno,
1037
jas_image_coord_t ho, jas_image_coord_t vo, jas_image_coord_t hs,
1038
jas_image_coord_t vs, int sgnd, int prec)
1039
{
1040
jas_image_cmpt_t *oldcmpt;
1041
jas_image_cmpt_t *newcmpt;
1042
int width;
1043
int height;
1044
jas_image_coord_t tlx;
1045
jas_image_coord_t tly;
1046
jas_image_coord_t brx;
1047
jas_image_coord_t bry;
1048
int i;
1049
int j;
1050
jas_image_cmptparm_t cmptparm;
1051
jas_image_coord_t ax;
1052
jas_image_coord_t ay;
1053
jas_image_coord_t bx;
1054
jas_image_coord_t by;
1055
jas_image_coord_t d0;
1056
jas_image_coord_t d1;
1057
jas_image_coord_t d2;
1058
jas_image_coord_t d3;
1059
jas_image_coord_t oldx;
1060
jas_image_coord_t oldy;
1061
jas_image_coord_t x;
1062
jas_image_coord_t y;
1063
long v;
1064
jas_image_coord_t cmptbrx;
1065
jas_image_coord_t cmptbry;
1066
1067
assert(cmptno >= 0 && cmptno < image->numcmpts_);
1068
oldcmpt = image->cmpts_[cmptno];
1069
assert(oldcmpt->tlx_ == 0 && oldcmpt->tly_ == 0);
1070
jas_image_calcbbox2(image, &tlx, &tly, &brx, &bry);
1071
width = FLOORDIV(brx - ho + hs, hs);
1072
height = FLOORDIV(bry - vo + vs, vs);
1073
cmptparm.tlx = ho;
1074
cmptparm.tly = vo;
1075
cmptparm.hstep = hs;
1076
cmptparm.vstep = vs;
1077
cmptparm.width = width;
1078
cmptparm.height = height;
1079
cmptparm.prec = prec;
1080
cmptparm.sgnd = sgnd;
1081
if (jas_image_addcmpt(image, newcmptno, &cmptparm))
1082
goto error;
1083
cmptbrx = oldcmpt->tlx_ + (oldcmpt->width_ - 1) * oldcmpt->hstep_;
1084
cmptbry = oldcmpt->tly_ + (oldcmpt->height_ - 1) * oldcmpt->vstep_;
1085
newcmpt = image->cmpts_[newcmptno];
1086
jas_stream_rewind(newcmpt->stream_);
1087
for (i = 0; i < height; ++i) {
1088
y = newcmpt->tly_ + newcmpt->vstep_ * i;
1089
for (j = 0; j < width; ++j) {
1090
x = newcmpt->tlx_ + newcmpt->hstep_ * j;
1091
ax = downtomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_;
1092
ay = downtomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_;
1093
bx = uptomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_;
1094
if (bx > cmptbrx)
1095
bx = cmptbrx;
1096
by = uptomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_;
1097
if (by > cmptbry)
1098
by = cmptbry;
1099
d0 = (ax - x) * (ax - x) + (ay - y) * (ay - y);
1100
d1 = (bx - x) * (bx - x) + (ay - y) * (ay - y);
1101
d2 = (bx - x) * (bx - x) + (by - y) * (by - y);
1102
d3 = (ax - x) * (ax - x) + (by - y) * (by - y);
1103
if (d0 <= d1 && d0 <= d2 && d0 <= d3) {
1104
oldx = (ax - oldcmpt->tlx_) / oldcmpt->hstep_;
1105
oldy = (ay - oldcmpt->tly_) / oldcmpt->vstep_;
1106
} else if (d1 <= d0 && d1 <= d2 && d1 <= d3) {
1107
oldx = (bx - oldcmpt->tlx_) / oldcmpt->hstep_;
1108
oldy = (ay - oldcmpt->tly_) / oldcmpt->vstep_;
1109
} else if (d2 <= d0 && d2 <= d1 && d1 <= d3) {
1110
oldx = (bx - oldcmpt->tlx_) / oldcmpt->hstep_;
1111
oldy = (by - oldcmpt->tly_) / oldcmpt->vstep_;
1112
} else {
1113
oldx = (ax - oldcmpt->tlx_) / oldcmpt->hstep_;
1114
oldy = (by - oldcmpt->tly_) / oldcmpt->vstep_;
1115
}
1116
assert(oldx >= 0 && oldx < oldcmpt->width_ &&
1117
oldy >= 0 && oldy < oldcmpt->height_);
1118
if (jas_stream_seek(oldcmpt->stream_, oldcmpt->cps_ *
1119
(oldy * oldcmpt->width_ + oldx), SEEK_SET) < 0)
1120
goto error;
1121
if (getint(oldcmpt->stream_, oldcmpt->sgnd_,
1122
oldcmpt->prec_, &v))
1123
goto error;
1124
if (newcmpt->prec_ != oldcmpt->prec_ ||
1125
newcmpt->sgnd_ != oldcmpt->sgnd_) {
1126
v = convert(v, oldcmpt->sgnd_, oldcmpt->prec_,
1127
newcmpt->sgnd_, newcmpt->prec_);
1128
}
1129
if (putint(newcmpt->stream_, newcmpt->sgnd_,
1130
newcmpt->prec_, v))
1131
goto error;
1132
}
1133
}
1134
return 0;
1135
error:
1136
return -1;
1137
}
1138
1139
int jas_image_ishomosamp(jas_image_t *image)
1140
{
1141
jas_image_coord_t hstep;
1142
jas_image_coord_t vstep;
1143
int result;
1144
int i;
1145
hstep = jas_image_cmpthstep(image, 0);
1146
vstep = jas_image_cmptvstep(image, 0);
1147
result = 1;
1148
for (i = 0; i < image->numcmpts_; ++i) {
1149
if (jas_image_cmpthstep(image, i) != hstep ||
1150
jas_image_cmptvstep(image, i) != vstep) {
1151
result = 0;
1152
break;
1153
}
1154
}
1155
return result;
1156
}
1157
1158
/* Note: This function defines a bounding box differently. */
1159
static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx,
1160
jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry)
1161
{
1162
jas_image_cmpt_t *cmpt;
1163
jas_image_coord_t tmptlx;
1164
jas_image_coord_t tmptly;
1165
jas_image_coord_t tmpbrx;
1166
jas_image_coord_t tmpbry;
1167
jas_image_coord_t t;
1168
int i;
1169
if (image->numcmpts_ > 0) {
1170
cmpt = image->cmpts_[0];
1171
tmptlx = cmpt->tlx_;
1172
tmptly = cmpt->tly_;
1173
tmpbrx = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1);
1174
tmpbry = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1);
1175
for (i = 0; i < image->numcmpts_; ++i) {
1176
cmpt = image->cmpts_[i];
1177
if (cmpt->tlx_ < tmptlx)
1178
tmptlx = cmpt->tlx_;
1179
if (cmpt->tly_ < tmptly)
1180
tmptly = cmpt->tly_;
1181
t = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1);
1182
if (t > tmpbrx)
1183
tmpbrx = t;
1184
t = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1);
1185
if (t > tmpbry)
1186
tmpbry = t;
1187
}
1188
} else {
1189
tmptlx = 0;
1190
tmptly = 0;
1191
tmpbrx = -1;
1192
tmpbry = -1;
1193
}
1194
*tlx = tmptlx;
1195
*tly = tmptly;
1196
*brx = tmpbrx;
1197
*bry = tmpbry;
1198
}
1199
1200
1201
1202
static int getint(jas_stream_t *in, int sgnd, int prec, long *val)
1203
{
1204
long v;
1205
int n;
1206
int c;
1207
n = (prec + 7) / 8;
1208
v = 0;
1209
while (--n >= 0) {
1210
if ((c = jas_stream_getc(in)) == EOF)
1211
return -1;
1212
v = (v << 8) | c;
1213
}
1214
v &= ((1 << prec) - 1);
1215
if (sgnd) {
1216
/* XXX - Do something here. */
1217
abort();
1218
} else {
1219
*val = v;
1220
}
1221
return 0;
1222
}
1223
1224
static int putint(jas_stream_t *out, int sgnd, int prec, long val)
1225
{
1226
int n;
1227
int c;
1228
if (sgnd) {
1229
/* XXX - Do something here. */
1230
abort();
1231
}
1232
val &= (1 << prec) - 1;
1233
n = (prec + 7) / 8;
1234
while (--n >= 0) {
1235
c = (val >> (n * 8)) & 0xff;
1236
if (jas_stream_putc(out, c) != c)
1237
return -1;
1238
}
1239
return 0;
1240
}
1241
1242
static long convert(long val, int oldsgnd, int oldprec, int newsgnd,
1243
int newprec)
1244
{
1245
if (newsgnd != oldsgnd) {
1246
}
1247
if (newprec != oldprec) {
1248
if (newprec > oldprec) {
1249
val <<= newprec - oldprec;
1250
} else if (oldprec > newprec) {
1251
val >>= oldprec - newprec;
1252
}
1253
}
1254
return val;
1255
}
1256
1257
static long downtomult(long x, long y)
1258
{
1259
assert(x >= 0);
1260
return (x / y) * y;
1261
}
1262
1263
static long uptomult(long x, long y)
1264
{
1265
assert(x >= 0);
1266
return ((x + y - 1) / y) * y;
1267
}
1268
1269
jas_image_t *jas_image_chclrspc(jas_image_t *image, jas_cmprof_t *outprof,
1270
int intent)
1271
{
1272
jas_image_t *inimage;
1273
int minhstep;
1274
int minvstep;
1275
int i;
1276
int j;
1277
int k;
1278
int n;
1279
int hstep;
1280
int vstep;
1281
int numinauxchans;
1282
int numoutauxchans;
1283
int numinclrchans;
1284
int numoutclrchans;
1285
int prec;
1286
jas_image_t *outimage;
1287
int cmpttype;
1288
int numoutchans;
1289
jas_cmprof_t *inprof;
1290
jas_cmprof_t *tmpprof;
1291
jas_image_cmptparm_t cmptparm;
1292
int width;
1293
int height;
1294
jas_cmxform_t *xform;
1295
jas_cmpixmap_t inpixmap;
1296
jas_cmpixmap_t outpixmap;
1297
jas_cmcmptfmt_t *incmptfmts;
1298
jas_cmcmptfmt_t *outcmptfmts;
1299
1300
#if 0
1301
jas_eprintf("IMAGE\n");
1302
jas_image_dump(image, stderr);
1303
#endif
1304
1305
if (!(inimage = jas_image_copy(image)))
1306
goto error;
1307
image = 0;
1308
1309
if (!jas_image_ishomosamp(inimage)) {
1310
minhstep = jas_image_cmpthstep(inimage, 0);
1311
minvstep = jas_image_cmptvstep(inimage, 0);
1312
for (i = 1; i < jas_image_numcmpts(inimage); ++i) {
1313
hstep = jas_image_cmpthstep(inimage, i);
1314
vstep = jas_image_cmptvstep(inimage, i);
1315
if (hstep < minhstep)
1316
minhstep = hstep;
1317
if (vstep < minvstep)
1318
minvstep = vstep;
1319
}
1320
n = jas_image_numcmpts(inimage);
1321
for (i = 0; i < n; ++i) {
1322
cmpttype = jas_image_cmpttype(inimage, i);
1323
if (jas_image_sampcmpt(inimage, i, i + 1, 0, 0, minhstep, minvstep, jas_image_cmptsgnd(inimage, i), jas_image_cmptprec(inimage, i)))
1324
goto error;
1325
jas_image_setcmpttype(inimage, i + 1, cmpttype);
1326
jas_image_delcmpt(inimage, i);
1327
}
1328
}
1329
1330
width = jas_image_cmptwidth(inimage, 0);
1331
height = jas_image_cmptheight(inimage, 0);
1332
hstep = jas_image_cmpthstep(inimage, 0);
1333
vstep = jas_image_cmptvstep(inimage, 0);
1334
1335
inprof = jas_image_cmprof(inimage);
1336
assert(inprof);
1337
numinclrchans = jas_clrspc_numchans(jas_cmprof_clrspc(inprof));
1338
numinauxchans = jas_image_numcmpts(inimage) - numinclrchans;
1339
numoutclrchans = jas_clrspc_numchans(jas_cmprof_clrspc(outprof));
1340
numoutauxchans = 0;
1341
numoutchans = numoutclrchans + numoutauxchans;
1342
prec = 8;
1343
1344
if (!(outimage = jas_image_create0()))
1345
goto error;
1346
1347
/* Create a component for each of the colorants. */
1348
for (i = 0; i < numoutclrchans; ++i) {
1349
cmptparm.tlx = 0;
1350
cmptparm.tly = 0;
1351
cmptparm.hstep = hstep;
1352
cmptparm.vstep = vstep;
1353
cmptparm.width = width;
1354
cmptparm.height = height;
1355
cmptparm.prec = prec;
1356
cmptparm.sgnd = 0;
1357
if (jas_image_addcmpt(outimage, -1, &cmptparm))
1358
goto error;
1359
jas_image_setcmpttype(outimage, i, JAS_IMAGE_CT_COLOR(i));
1360
}
1361
#if 0
1362
/* Copy the auxiliary components without modification. */
1363
for (i = 0; i < jas_image_numcmpts(inimage); ++i) {
1364
if (!ISCOLOR(jas_image_cmpttype(inimage, i))) {
1365
jas_image_copycmpt(outimage, -1, inimage, i);
1366
/* XXX - need to specify laydown of component on ref. grid */
1367
}
1368
}
1369
#endif
1370
1371
if (!(tmpprof = jas_cmprof_copy(outprof)))
1372
goto error;
1373
assert(!jas_image_cmprof(outimage));
1374
jas_image_setcmprof(outimage, tmpprof);
1375
tmpprof = 0;
1376
jas_image_setclrspc(outimage, jas_cmprof_clrspc(outprof));
1377
1378
if (!(xform = jas_cmxform_create(inprof, outprof, 0, JAS_CMXFORM_OP_FWD, intent, 0)))
1379
goto error;
1380
1381
inpixmap.numcmpts = numinclrchans;
1382
incmptfmts = malloc(numinclrchans * sizeof(jas_cmcmptfmt_t));
1383
assert(incmptfmts);
1384
inpixmap.cmptfmts = incmptfmts;
1385
for (i = 0; i < numinclrchans; ++i) {
1386
j = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(i));
1387
assert(j >= 0);
1388
if (!(incmptfmts[i].buf = malloc(width * sizeof(long))))
1389
goto error;
1390
incmptfmts[i].prec = jas_image_cmptprec(inimage, j);
1391
incmptfmts[i].sgnd = jas_image_cmptsgnd(inimage, j);
1392
incmptfmts[i].width = width;
1393
incmptfmts[i].height = 1;
1394
}
1395
1396
outpixmap.numcmpts = numoutclrchans;
1397
outcmptfmts = malloc(numoutclrchans * sizeof(jas_cmcmptfmt_t));
1398
assert(outcmptfmts);
1399
outpixmap.cmptfmts = outcmptfmts;
1400
1401
for (i = 0; i < numoutclrchans; ++i) {
1402
j = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(i));
1403
assert(j >= 0);
1404
if (!(outcmptfmts[i].buf = malloc(width * sizeof(long))))
1405
goto error;
1406
outcmptfmts[i].prec = jas_image_cmptprec(outimage, j);
1407
outcmptfmts[i].sgnd = jas_image_cmptsgnd(outimage, j);
1408
outcmptfmts[i].width = width;
1409
outcmptfmts[i].height = 1;
1410
}
1411
1412
for (i = 0; i < height; ++i) {
1413
for (j = 0; j < numinclrchans; ++j) {
1414
k = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(j));
1415
if (jas_image_readcmpt2(inimage, k, 0, i, width, 1, incmptfmts[j].buf))
1416
goto error;
1417
}
1418
jas_cmxform_apply(xform, &inpixmap, &outpixmap);
1419
for (j = 0; j < numoutclrchans; ++j) {
1420
k = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(j));
1421
if (jas_image_writecmpt2(outimage, k, 0, i, width, 1, outcmptfmts[j].buf))
1422
goto error;
1423
}
1424
}
1425
1426
for (i = 0; i < numoutclrchans; ++i)
1427
jas_free(outcmptfmts[i].buf);
1428
jas_free(outcmptfmts);
1429
for (i = 0; i < numinclrchans; ++i)
1430
jas_free(incmptfmts[i].buf);
1431
jas_free(incmptfmts);
1432
jas_cmxform_destroy(xform);
1433
jas_image_destroy(inimage);
1434
1435
#if 0
1436
jas_eprintf("INIMAGE\n");
1437
jas_image_dump(inimage, stderr);
1438
jas_eprintf("OUTIMAGE\n");
1439
jas_image_dump(outimage, stderr);
1440
#endif
1441
return outimage;
1442
error:
1443
return 0;
1444
}
1445
1446